summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp7
-rw-r--r--BAL_OWNERS2
-rw-r--r--apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java265
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java6
-rw-r--r--api/Android.bp2
-rw-r--r--api/coverage/tools/ExtractFlaggedApis.kt24
-rw-r--r--boot/boot-image-profile.txt2817
-rw-r--r--config/boot-image-profile.txt2930
-rw-r--r--core/api/current.txt18
-rw-r--r--core/api/module-lib-current.txt2
-rw-r--r--core/api/system-current.txt3
-rw-r--r--core/api/test-current.txt23
-rw-r--r--core/java/android/app/Activity.java32
-rw-r--r--core/java/android/app/ActivityThread.java12
-rw-r--r--core/java/android/app/ContextImpl.java27
-rw-r--r--core/java/android/app/Instrumentation.java2
-rw-r--r--core/java/android/app/Notification.java77
-rw-r--r--core/java/android/app/ResourcesManager.java15
-rw-r--r--core/java/android/app/TaskInfo.java32
-rw-r--r--core/java/android/app/WallpaperManager.java7
-rw-r--r--core/java/android/app/admin/OWNERS1
-rw-r--r--core/java/android/app/assist/OWNERS3
-rw-r--r--core/java/android/app/servertransaction/ClientTransactionListenerController.java11
-rw-r--r--core/java/android/audio/policy/configuration/V7_0/package-info.java23
-rw-r--r--core/java/android/companion/virtual/flags/flags.aconfig28
-rw-r--r--core/java/android/content/ClipDescription.java8
-rw-r--r--core/java/android/content/ContentProvider.java13
-rw-r--r--core/java/android/content/Context.java32
-rw-r--r--core/java/android/content/ContextWrapper.java21
-rw-r--r--core/java/android/content/Intent.java2
-rw-r--r--core/java/android/content/IntentSender.java83
-rw-r--r--core/java/android/content/pm/ActivityInfo.java31
-rw-r--r--core/java/android/content/pm/LauncherApps.java3
-rw-r--r--core/java/android/content/pm/ShortcutServiceInternal.java3
-rw-r--r--core/java/android/content/pm/multiuser.aconfig41
-rw-r--r--core/java/android/content/res/flags.aconfig10
-rw-r--r--core/java/android/database/CursorWindow.java4
-rw-r--r--core/java/android/hardware/Camera.java2
-rw-r--r--core/java/android/hardware/OWNERS2
-rw-r--r--core/java/android/hardware/camera2/CameraDevice.java18
-rw-r--r--core/java/android/hardware/camera2/CameraManager.java24
-rw-r--r--core/java/android/hardware/camera2/params/StreamConfigurationMap.java8
-rw-r--r--core/java/android/hardware/devicestate/DeviceStateManager.java8
-rw-r--r--core/java/android/hardware/display/DisplayManager.java42
-rw-r--r--core/java/android/hardware/display/DisplayManagerGlobal.java48
-rw-r--r--core/java/android/hardware/display/DisplayManagerInternal.java6
-rw-r--r--core/java/android/hardware/display/IDisplayManager.aidl15
-rw-r--r--core/java/android/hardware/display/VirtualDisplay.java23
-rw-r--r--core/java/android/hardware/display/VirtualDisplayConfig.java48
-rw-r--r--core/java/android/hardware/fingerprint/FingerprintManager.java19
-rw-r--r--core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java8
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintService.aidl3
-rw-r--r--core/java/android/hardware/input/IInputManager.aidl3
-rw-r--r--core/java/android/hardware/input/InputManager.java64
-rw-r--r--core/java/android/hardware/input/InputSettings.java62
-rw-r--r--core/java/android/hardware/input/KeyGlyphMap.aidl19
-rw-r--r--core/java/android/hardware/input/KeyGlyphMap.java187
-rw-r--r--core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.java3
-rw-r--r--core/java/android/hardware/input/input_framework.aconfig23
-rw-r--r--core/java/android/hardware/location/ContextHubInfo.java65
-rw-r--r--core/java/android/hardware/location/ContextHubIntentEvent.java11
-rw-r--r--core/java/android/hardware/location/MemoryRegion.java13
-rw-r--r--core/java/android/hardware/location/NanoAppMessage.java45
-rw-r--r--core/java/android/inputmethodservice/AbstractInputMethodService.java5
-rw-r--r--core/java/android/inputmethodservice/ImsConfigurationTracker.java8
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java12
-rw-r--r--core/java/android/inputmethodservice/NavigationBarController.java16
-rw-r--r--core/java/android/inputmethodservice/navigationbar/KeyButtonView.java37
-rw-r--r--core/java/android/inputmethodservice/navigationbar/NavigationBarView.java46
-rw-r--r--core/java/android/os/IVibratorManagerService.aidl2
-rw-r--r--core/java/android/os/PowerManager.java9
-rw-r--r--core/java/android/os/SystemVibrator.java5
-rw-r--r--core/java/android/os/SystemVibratorManager.java12
-rw-r--r--core/java/android/os/UserManager.java41
-rw-r--r--core/java/android/os/Vibrator.java23
-rw-r--r--core/java/android/os/VibratorManager.java12
-rw-r--r--core/java/android/os/flags.aconfig16
-rw-r--r--core/java/android/os/vibrator/VibrationConfig.java26
-rw-r--r--core/java/android/os/vibrator/flags.aconfig1
-rw-r--r--core/java/android/os/vibrator/persistence/ParsedVibration.java17
-rw-r--r--core/java/android/os/vibrator/persistence/VibrationXmlParser.java3
-rw-r--r--core/java/android/permission/flags.aconfig8
-rw-r--r--core/java/android/provider/Settings.java22
-rw-r--r--core/java/android/security/flags.aconfig7
-rw-r--r--core/java/android/service/chooser/flags.aconfig8
-rw-r--r--core/java/android/service/dreams/DreamService.java27
-rw-r--r--core/java/android/service/notification/StatusBarNotification.java6
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java4
-rw-r--r--core/java/android/service/notification/flags.aconfig14
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java38
-rw-r--r--core/java/android/tracing/flags.aconfig8
-rw-r--r--core/java/android/util/FeatureFlagUtils.java7
-rw-r--r--core/java/android/util/SequenceUtils.java23
-rw-r--r--core/java/android/util/StateSet.java3
-rw-r--r--core/java/android/view/DisplayInfo.java2
-rw-r--r--core/java/android/view/HapticFeedbackConstants.java29
-rw-r--r--core/java/android/view/IWindowManager.aidl8
-rw-r--r--core/java/android/view/IWindowSession.aidl4
-rw-r--r--core/java/android/view/InputMonitor.java13
-rw-r--r--core/java/android/view/InsetsFrameProvider.java6
-rw-r--r--core/java/android/view/KeyboardShortcutGroup.aidl3
-rw-r--r--core/java/android/view/KeyboardShortcutInfo.java19
-rw-r--r--core/java/android/view/PointerIcon.java36
-rw-r--r--core/java/android/view/SurfaceControlRegistry.java32
-rw-r--r--core/java/android/view/View.java126
-rw-r--r--core/java/android/view/ViewRootImpl.java71
-rw-r--r--core/java/android/view/ViewTraversalTracingStrings.java2
-rw-r--r--core/java/android/view/WindowManager.java9
-rw-r--r--core/java/android/view/WindowManagerImpl.java10
-rw-r--r--core/java/android/view/WindowlessWindowManager.java6
-rw-r--r--core/java/android/view/accessibility/a11ychecker/Android.bp7
-rw-r--r--core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java14
-rw-r--r--core/java/android/view/inputmethod/InputMethodInfo.java6
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java13
-rw-r--r--core/java/android/view/inputmethod/flags.aconfig9
-rw-r--r--core/java/android/webkit/WebViewFactory.java9
-rw-r--r--core/java/android/webkit/WebViewUpdateManager.java2
-rw-r--r--core/java/android/window/ActivityWindowInfo.java13
-rw-r--r--core/java/android/window/BackProgressAnimator.java6
-rw-r--r--core/java/android/window/ITaskFragmentOrganizerController.aidl19
-rw-r--r--core/java/android/window/TaskFragmentAnimationParams.java2
-rw-r--r--core/java/android/window/TaskFragmentOrganizer.java46
-rw-r--r--core/java/android/window/TransitionInfo.java2
-rw-r--r--core/java/android/window/TransitionRequestInfo.java2
-rw-r--r--core/java/android/window/WindowContainerTransaction.java61
-rw-r--r--core/java/android/window/WindowMetricsController.java4
-rw-r--r--core/java/android/window/WindowOnBackInvokedDispatcher.java1
-rw-r--r--core/java/android/window/flags/large_screen_experiences_app_compat.aconfig15
-rw-r--r--core/java/android/window/flags/lse_desktop_experience.aconfig60
-rw-r--r--core/java/android/window/flags/responsible_apis.aconfig7
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig47
-rw-r--r--core/java/android/window/flags/windowing_sdk.aconfig10
-rw-r--r--core/java/com/android/internal/app/SuspendedAppActivity.java4
-rw-r--r--core/java/com/android/internal/display/RefreshRateSettingsUtils.java28
-rw-r--r--core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl1
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java16
-rw-r--r--core/java/com/android/internal/jank/Cuj.java61
-rw-r--r--core/java/com/android/internal/jank/InteractionJankMonitor.java42
-rw-r--r--core/java/com/android/internal/os/BinderTransactionNameResolver.java12
-rw-r--r--core/java/com/android/internal/os/flags.aconfig11
-rw-r--r--core/java/com/android/internal/pm/pkg/component/AconfigFlags.java23
-rw-r--r--core/java/com/android/internal/policy/DecorView.java19
-rw-r--r--core/java/com/android/internal/protolog/LegacyProtoLogImpl.java40
-rw-r--r--core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java87
-rw-r--r--core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java642
-rw-r--r--core/java/com/android/internal/protolog/ProtoLog.java97
-rw-r--r--core/java/com/android/internal/protolog/ProtoLogDataSource.java3
-rw-r--r--core/java/com/android/internal/protolog/ProtoLogImpl.java54
-rw-r--r--core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java122
-rw-r--r--core/java/com/android/internal/protolog/common/IProtoLog.java18
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl13
-rw-r--r--core/java/com/android/internal/widget/ILockSettings.aidl1
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java25
-rw-r--r--core/java/com/android/internal/widget/LockPatternView.java113
-rw-r--r--core/java/com/android/internal/widget/NotificationRowIconView.java11
-rw-r--r--core/java/com/android/internal/widget/OWNERS24
-rw-r--r--core/jni/android_hardware_Camera.cpp16
-rw-r--r--core/jni/android_media_AudioSystem.cpp5
-rw-r--r--core/jni/android_util_Process.cpp57
-rw-r--r--core/jni/android_view_InputChannel.cpp19
-rw-r--r--core/jni/platform/host/HostRuntime.cpp2
-rw-r--r--core/proto/android/providers/settings/system.proto1
-rw-r--r--core/proto/android/server/inputmethod/inputmethodmanagerservice.proto3
-rw-r--r--core/proto/android/view/displayinfo.proto1
-rw-r--r--core/res/AndroidManifest.xml1
-rw-r--r--core/res/res/drawable/pointer_alias_vector.xml4
-rw-r--r--core/res/res/drawable/pointer_all_scroll_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_arrow_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_cell_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_context_menu_vector.xml6
-rw-r--r--core/res/res/drawable/pointer_copy_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_crosshair_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_grab_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_grabbing_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_hand_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_handwriting_vector.xml4
-rw-r--r--core/res/res/drawable/pointer_help_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_horizontal_double_arrow_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_nodrop_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_text_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_top_left_diagonal_double_arrow_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_top_right_diagonal_double_arrow_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_vertical_double_arrow_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_vertical_text_vector.xml2
-rw-r--r--core/res/res/drawable/pointer_zoom_in_vector.xml4
-rw-r--r--core/res/res/drawable/pointer_zoom_out_vector.xml4
-rw-r--r--core/res/res/layout/notification_template_conversation_icon_container.xml2
-rw-r--r--core/res/res/values-af/strings.xml59
-rw-r--r--core/res/res/values-am/strings.xml77
-rw-r--r--core/res/res/values-ar/strings.xml61
-rw-r--r--core/res/res/values-as/strings.xml50
-rw-r--r--core/res/res/values-az/strings.xml61
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml65
-rw-r--r--core/res/res/values-be/strings.xml77
-rw-r--r--core/res/res/values-bg/strings.xml59
-rw-r--r--core/res/res/values-bn/strings.xml59
-rw-r--r--core/res/res/values-bs/strings.xml65
-rw-r--r--core/res/res/values-ca/strings.xml79
-rw-r--r--core/res/res/values-cs/strings.xml79
-rw-r--r--core/res/res/values-da/strings.xml79
-rw-r--r--core/res/res/values-de/strings.xml85
-rw-r--r--core/res/res/values-el/strings.xml81
-rw-r--r--core/res/res/values-en-rAU/strings.xml59
-rw-r--r--core/res/res/values-en-rCA/strings.xml29
-rw-r--r--core/res/res/values-en-rGB/strings.xml59
-rw-r--r--core/res/res/values-en-rIN/strings.xml59
-rw-r--r--core/res/res/values-en-rXC/strings.xml29
-rw-r--r--core/res/res/values-es-rUS/strings.xml77
-rw-r--r--core/res/res/values-es/strings.xml83
-rw-r--r--core/res/res/values-et/strings.xml61
-rw-r--r--core/res/res/values-eu/strings.xml79
-rw-r--r--core/res/res/values-fa/strings.xml63
-rw-r--r--core/res/res/values-fi/strings.xml77
-rw-r--r--core/res/res/values-fr-rCA/strings.xml709
-rw-r--r--core/res/res/values-fr/strings.xml79
-rw-r--r--core/res/res/values-gl/strings.xml43
-rw-r--r--core/res/res/values-gu/strings.xml50
-rw-r--r--core/res/res/values-hi/strings.xml58
-rw-r--r--core/res/res/values-hr/strings.xml59
-rw-r--r--core/res/res/values-hu/strings.xml79
-rw-r--r--core/res/res/values-hy/strings.xml79
-rw-r--r--core/res/res/values-in/strings.xml61
-rw-r--r--core/res/res/values-is/strings.xml77
-rw-r--r--core/res/res/values-it/strings.xml81
-rw-r--r--core/res/res/values-iw/strings.xml77
-rw-r--r--core/res/res/values-ja/strings.xml61
-rw-r--r--core/res/res/values-ka/strings.xml52
-rw-r--r--core/res/res/values-kk/strings.xml77
-rw-r--r--core/res/res/values-km/strings.xml59
-rw-r--r--core/res/res/values-kn/strings.xml50
-rw-r--r--core/res/res/values-ko/strings.xml79
-rw-r--r--core/res/res/values-ky/strings.xml77
-rw-r--r--core/res/res/values-lo/strings.xml59
-rw-r--r--core/res/res/values-lt/strings.xml59
-rw-r--r--core/res/res/values-lv/strings.xml41
-rw-r--r--core/res/res/values-mk/strings.xml63
-rw-r--r--core/res/res/values-ml/strings.xml61
-rw-r--r--core/res/res/values-mn/strings.xml79
-rw-r--r--core/res/res/values-mr/strings.xml50
-rw-r--r--core/res/res/values-ms/strings.xml52
-rw-r--r--core/res/res/values-my/strings.xml79
-rw-r--r--core/res/res/values-nb/strings.xml81
-rw-r--r--core/res/res/values-ne/strings.xml77
-rw-r--r--core/res/res/values-nl/strings.xml61
-rw-r--r--core/res/res/values-or/strings.xml65
-rw-r--r--core/res/res/values-pa/strings.xml59
-rw-r--r--core/res/res/values-pl/strings.xml68
-rw-r--r--core/res/res/values-pt-rBR/strings.xml61
-rw-r--r--core/res/res/values-pt-rPT/strings.xml54
-rw-r--r--core/res/res/values-pt/strings.xml61
-rw-r--r--core/res/res/values-ro/strings.xml59
-rw-r--r--core/res/res/values-ru/strings.xml79
-rw-r--r--core/res/res/values-si/strings.xml59
-rw-r--r--core/res/res/values-sk/strings.xml65
-rw-r--r--core/res/res/values-sl/strings.xml68
-rw-r--r--core/res/res/values-sq/strings.xml77
-rw-r--r--core/res/res/values-sr/strings.xml65
-rw-r--r--core/res/res/values-sv/strings.xml59
-rw-r--r--core/res/res/values-sw/strings.xml59
-rw-r--r--core/res/res/values-ta/strings.xml81
-rw-r--r--core/res/res/values-te/strings.xml59
-rw-r--r--core/res/res/values-th/strings.xml70
-rw-r--r--core/res/res/values-tl/strings.xml68
-rw-r--r--core/res/res/values-tr/strings.xml59
-rw-r--r--core/res/res/values-uk/strings.xml77
-rw-r--r--core/res/res/values-ur/strings.xml50
-rw-r--r--core/res/res/values-uz/strings.xml77
-rw-r--r--core/res/res/values-vi/strings.xml79
-rw-r--r--core/res/res/values-watch/colors.xml43
-rw-r--r--core/res/res/values-zh-rCN/strings.xml79
-rw-r--r--core/res/res/values-zh-rHK/strings.xml77
-rw-r--r--core/res/res/values-zh-rTW/strings.xml83
-rw-r--r--core/res/res/values-zu/strings.xml59
-rw-r--r--core/res/res/values/attrs.xml399
-rw-r--r--core/res/res/values/attrs_manifest.xml13
-rw-r--r--core/res/res/values/config.xml7
-rw-r--r--core/res/res/values/locale_config.xml38
-rw-r--r--core/res/res/values/public-staging.xml2
-rw-r--r--core/res/res/values/strings.xml19
-rw-r--r--core/res/res/values/styles.xml18
-rw-r--r--core/res/res/values/symbols.xml19
-rw-r--r--core/res/res/xml/power_profile.xml6
-rw-r--r--core/tests/InputMethodCoreTests/src/android/view/inputmethod/InputMethodInfoTest.java2
-rw-r--r--core/tests/coretests/Android.bp1
-rw-r--r--core/tests/coretests/src/android/app/NotificationTest.java18
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityThreadTest.java5
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java4
-rw-r--r--core/tests/coretests/src/android/inputmethodservice/ImsConfigurationTrackerTest.java30
-rw-r--r--core/tests/coretests/src/android/util/SequenceUtilsTest.java47
-rw-r--r--core/tests/coretests/src/android/view/ViewFrameRateTest.java117
-rw-r--r--core/tests/coretests/src/android/view/ViewRootImplTest.java10
-rw-r--r--core/tests/coretests/src/android/view/accessibility/a11ychecker/OWNERS5
-rw-r--r--core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java4
-rw-r--r--core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java23
-rw-r--r--core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java35
-rw-r--r--core/tests/overlaytests/handle_config_change/Android.bp45
-rw-r--r--core/tests/overlaytests/handle_config_change/AndroidTest.xml35
-rw-r--r--core/tests/overlaytests/handle_config_change/src/com/android/overlaytest/HandleConfigChangeHostTests.java47
-rw-r--r--core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/Android.bp43
-rw-r--r--core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/AndroidManifest.xml33
-rw-r--r--core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/res/values/integers.xml20
-rw-r--r--core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/res/values/strings.xml21
-rw-r--r--core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/src/com/android/overlaytest/overlayresapp/OverlayResActivity.java50
-rw-r--r--core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/src/com/android/overlaytest/overlayresapp/OverlayResTest.java148
-rw-r--r--core/tests/resourceflaggingtests/Android.bp75
-rw-r--r--core/tests/resourceflaggingtests/AndroidManifest.xml31
-rw-r--r--core/tests/resourceflaggingtests/OWNERS1
-rw-r--r--core/tests/resourceflaggingtests/TestAppAndroidManifest.xml4
-rw-r--r--core/tests/resourceflaggingtests/flagged_resources_res/values/bools.xml8
-rw-r--r--core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java81
-rw-r--r--data/etc/OWNERS1
-rw-r--r--keystore/java/android/security/KeyChain.java8
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java4
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java46
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java38
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java5
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationAdapter.java224
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java79
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java309
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java267
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java9
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java20
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java14
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java88
-rw-r--r--libs/WindowManager/Shell/Android.bp10
-rw-r--r--libs/WindowManager/Shell/OWNERS2
-rw-r--r--libs/WindowManager/Shell/aconfig/multitasking.aconfig10
-rw-r--r--libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp34
-rw-r--r--libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml1
-rw-r--r--libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/dark_portrait_bubbles_education.pngbin0 -> 56741 bytes
-rw-r--r--libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/light_portrait_bubbles_education.pngbin0 -> 56741 bytes
-rw-r--r--libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties1
-rw-r--r--libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_open_in_browser.xml19
-rw-r--r--libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml29
-rw-r--r--libs/WindowManager/Shell/res/values-af/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-am/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-ar/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-as/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-az/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-be/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-bg/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-bn/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-bs/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-da/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-en-rCA/strings.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-en-rXC/strings.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-es-rUS/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-es/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-et/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-eu/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-fa/strings.xml12
-rw-r--r--libs/WindowManager/Shell/res/values-fi/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-fr-rCA/strings.xml36
-rw-r--r--libs/WindowManager/Shell/res/values-fr/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-gl/strings.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-gu/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-hr/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-hu/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-hy/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-in/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-is/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-iw/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-ka/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-kk/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-km/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-kn/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-ko/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-ky/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-lo/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-lt/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-lv/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-mk/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-ml/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-mn/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-mr/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-ms/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-my/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-nb/strings.xml10
-rw-r--r--libs/WindowManager/Shell/res/values-ne/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-or/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-pa/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-pl/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rBR/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-pt/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-ro/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-ru/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-si/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-sk/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-sq/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-sr/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-sv/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-sw/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-ta/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-te/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-th/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-tr/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-uk/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-ur/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-uz/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values-vi/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rCN/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rHK/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rTW/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-zu/strings.xml7
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml19
-rw-r--r--libs/WindowManager/Shell/res/values/strings.xml2
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt154
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java (renamed from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java)33
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/OWNERS1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java108
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/DefaultCrossActivityBackAnimation.kt6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java84
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java32
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java44
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java30
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIEvent.kt34
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIHandler.kt34
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIInfo.kt25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIRepository.kt39
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt44
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt40
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepository.kt41
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java29
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java31
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/PipModule.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt79
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt206
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt48
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt31
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java32
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java48
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java35
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java47
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java33
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java91
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java37
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java32
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java74
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java32
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java43
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java92
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt74
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java106
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java68
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java75
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java107
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java37
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java516
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt484
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuAnimator.kt93
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java34
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt9
-rw-r--r--libs/WindowManager/Shell/tests/OWNERS2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt78
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt52
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt48
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowMultiWindow.kt66
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowScenarioTestBase.kt55
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowSingleWindow.kt53
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ExitDesktopWithDragToTopDragZone.kt68
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt65
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt14
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/Android.bp1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java46
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomCrossActivityBackAnimationTest.kt7
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt43
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java91
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java53
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java53
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java15
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java22
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java14
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java13
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogLayoutTest.java18
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java12
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java12
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java23
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt89
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIRepository.kt39
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt64
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt669
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt43
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java21
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt456
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/OWNERS1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java33
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java74
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java3
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TransitionAnimationHelperTest.kt126
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt107
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt36
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java80
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java38
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt83
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java55
-rw-r--r--libs/androidfw/StringPool.cpp28
-rw-r--r--libs/androidfw/include/androidfw/StringPool.h5
-rw-r--r--libs/hwui/Android.bp10
-rw-r--r--libs/hwui/apex/LayoutlibLoader.cpp21
-rw-r--r--libs/hwui/hwui/DrawTextFunctor.h13
-rw-r--r--libs/hwui/jni/MeshSpecification.cpp2
-rw-r--r--libs/hwui/jni/android_graphics_HardwareBufferRenderer.cpp2
-rw-r--r--location/Android.bp3
-rw-r--r--location/java/com/android/internal/location/package-info.java22
-rw-r--r--media/java/android/media/AudioManager.java15
-rw-r--r--media/java/android/media/AudioTrack.java1
-rw-r--r--media/java/android/media/IAudioService.aidl10
-rw-r--r--media/java/android/media/VolumePolicy.java19
-rw-r--r--media/java/android/media/projection/MediaProjection.java4
-rw-r--r--media/java/android/media/projection/MediaProjectionManager.java45
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java2
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java7
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java4
-rw-r--r--media/tests/mediatestutils/java/com/android/media/mediatestutils/TestUtils.java77
-rw-r--r--nfc/Android.bp3
-rw-r--r--nfc/java/android/nfc/AvailableNfcAntenna.java8
-rw-r--r--nfc/java/android/nfc/INfcAdapter.aidl1
-rw-r--r--nfc/java/android/nfc/NfcAdapter.java465
-rw-r--r--nfc/java/android/nfc/NfcAntennaInfo.java4
-rw-r--r--packages/BackupRestoreConfirmation/res/values-el/strings.xml2
-rw-r--r--packages/CarrierDefaultApp/res/values-fa/strings.xml2
-rw-r--r--packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml34
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java18
-rw-r--r--packages/CrashRecovery/aconfig/flags.aconfig8
-rw-r--r--packages/CredentialManager/res/values-el/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-fa/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-fr-rCA/strings.xml4
-rw-r--r--packages/CredentialManager/res/values-iw/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-pa/strings.xml2
-rw-r--r--packages/CredentialManager/wear/res/values-af/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-am/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ar/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-as/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-az/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-b+sr+Latn/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-be/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-bg/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-bn/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-bs/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ca/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-cs/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-da/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-de/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-el/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-en-rAU/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-en-rCA/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-en-rGB/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-en-rIN/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-en-rXC/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-es-rUS/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-es/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-et/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-eu/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-fa/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-fi/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-fr-rCA/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-fr/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-gl/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-gu/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-hi/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-hr/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-hu/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-hy/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-in/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-is/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-it/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-iw/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ja/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ka/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-kk/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-km/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-kn/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ko/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ky/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-lo/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-lt/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-lv/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-mk/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ml/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-mn/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-mr/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ms/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-my/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-nb/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ne/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-nl/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-or/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-pa/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-pl/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-pt-rPT/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-pt/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ro/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ru/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-si/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-sk/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-sl/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-sq/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-sr/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-sv/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-sw/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ta/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-te/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-th/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-tl/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-tr/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-uk/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-ur/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-uz/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-vi/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-zh-rCN/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-zh-rHK/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-zh-rTW/strings.xml34
-rw-r--r--packages/CredentialManager/wear/res/values-zu/strings.xml34
-rw-r--r--packages/InputDevices/AndroidManifest.xml18
-rw-r--r--packages/InputDevices/res/values-am/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ar/strings.xml6
-rw-r--r--packages/InputDevices/res/values-as/strings.xml6
-rw-r--r--packages/InputDevices/res/values-az/strings.xml6
-rw-r--r--packages/InputDevices/res/values-b+sr+Latn/strings.xml6
-rw-r--r--packages/InputDevices/res/values-be/strings.xml6
-rw-r--r--packages/InputDevices/res/values-bg/strings.xml6
-rw-r--r--packages/InputDevices/res/values-bn/strings.xml6
-rw-r--r--packages/InputDevices/res/values-bs/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ca/strings.xml6
-rw-r--r--packages/InputDevices/res/values-cs/strings.xml6
-rw-r--r--packages/InputDevices/res/values-da/strings.xml6
-rw-r--r--packages/InputDevices/res/values-de/strings.xml6
-rw-r--r--packages/InputDevices/res/values-el/strings.xml6
-rw-r--r--packages/InputDevices/res/values-en-rAU/strings.xml6
-rw-r--r--packages/InputDevices/res/values-en-rGB/strings.xml6
-rw-r--r--packages/InputDevices/res/values-en-rIN/strings.xml6
-rw-r--r--packages/InputDevices/res/values-es-rUS/strings.xml6
-rw-r--r--packages/InputDevices/res/values-es/strings.xml6
-rw-r--r--packages/InputDevices/res/values-et/strings.xml6
-rw-r--r--packages/InputDevices/res/values-eu/strings.xml6
-rw-r--r--packages/InputDevices/res/values-fa/strings.xml6
-rw-r--r--packages/InputDevices/res/values-fi/strings.xml6
-rw-r--r--packages/InputDevices/res/values-fr-rCA/strings.xml6
-rw-r--r--packages/InputDevices/res/values-fr/strings.xml6
-rw-r--r--packages/InputDevices/res/values-gu/strings.xml6
-rw-r--r--packages/InputDevices/res/values-hi/strings.xml6
-rw-r--r--packages/InputDevices/res/values-hr/strings.xml6
-rw-r--r--packages/InputDevices/res/values-hu/strings.xml6
-rw-r--r--packages/InputDevices/res/values-hy/strings.xml6
-rw-r--r--packages/InputDevices/res/values-in/strings.xml6
-rw-r--r--packages/InputDevices/res/values-is/strings.xml6
-rw-r--r--packages/InputDevices/res/values-it/strings.xml6
-rw-r--r--packages/InputDevices/res/values-iw/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ja/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ka/strings.xml6
-rw-r--r--packages/InputDevices/res/values-kk/strings.xml6
-rw-r--r--packages/InputDevices/res/values-km/strings.xml6
-rw-r--r--packages/InputDevices/res/values-kn/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ko/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ky/strings.xml6
-rw-r--r--packages/InputDevices/res/values-lo/strings.xml6
-rw-r--r--packages/InputDevices/res/values-lt/strings.xml6
-rw-r--r--packages/InputDevices/res/values-lv/strings.xml6
-rw-r--r--packages/InputDevices/res/values-mk/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ml/strings.xml6
-rw-r--r--packages/InputDevices/res/values-mn/strings.xml6
-rw-r--r--packages/InputDevices/res/values-mr/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ms/strings.xml6
-rw-r--r--packages/InputDevices/res/values-my/strings.xml6
-rw-r--r--packages/InputDevices/res/values-nb/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ne/strings.xml6
-rw-r--r--packages/InputDevices/res/values-nl/strings.xml6
-rw-r--r--packages/InputDevices/res/values-or/strings.xml6
-rw-r--r--packages/InputDevices/res/values-pa/strings.xml6
-rw-r--r--packages/InputDevices/res/values-pl/strings.xml6
-rw-r--r--packages/InputDevices/res/values-pt-rBR/strings.xml6
-rw-r--r--packages/InputDevices/res/values-pt-rPT/strings.xml6
-rw-r--r--packages/InputDevices/res/values-pt/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ro/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ru/strings.xml6
-rw-r--r--packages/InputDevices/res/values-si/strings.xml6
-rw-r--r--packages/InputDevices/res/values-sk/strings.xml6
-rw-r--r--packages/InputDevices/res/values-sl/strings.xml6
-rw-r--r--packages/InputDevices/res/values-sq/strings.xml6
-rw-r--r--packages/InputDevices/res/values-sr/strings.xml6
-rw-r--r--packages/InputDevices/res/values-sv/strings.xml6
-rw-r--r--packages/InputDevices/res/values-sw/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ta/strings.xml6
-rw-r--r--packages/InputDevices/res/values-te/strings.xml6
-rw-r--r--packages/InputDevices/res/values-th/strings.xml6
-rw-r--r--packages/InputDevices/res/values-tl/strings.xml6
-rw-r--r--packages/InputDevices/res/values-tr/strings.xml6
-rw-r--r--packages/InputDevices/res/values-uk/strings.xml6
-rw-r--r--packages/InputDevices/res/values-ur/strings.xml6
-rw-r--r--packages/InputDevices/res/values-uz/strings.xml6
-rw-r--r--packages/InputDevices/res/values-vi/strings.xml6
-rw-r--r--packages/InputDevices/res/values-zh-rCN/strings.xml6
-rw-r--r--packages/InputDevices/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/InputDevices/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/InputDevices/res/values-zu/strings.xml6
-rw-r--r--packages/InputDevices/res/xml/keyboard_glyph_maps.xml22
-rw-r--r--packages/InputDevices/res/xml/keyboard_glyph_maps_overlay.xml20
-rw-r--r--packages/InputDevices/src/com/android/inputdevices/KeyGlyphMapProvider.java28
-rw-r--r--packages/InputDevices/src/com/android/inputdevices/OverlayKeyGlyphMapProvider.java28
-rw-r--r--packages/PackageInstaller/Android.bp3
-rw-r--r--packages/PackageInstaller/AndroidManifest.xml11
-rw-r--r--packages/PackageInstaller/res/values-fr-rCA/strings.xml110
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java3
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt165
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt5
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt49
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java2
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java9
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java173
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java59
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java36
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java327
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java100
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java202
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java621
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java133
-rw-r--r--packages/PrintSpooler/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/SettingsLib/ActionButtonsPreference/Android.bp1
-rw-r--r--packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java8
-rw-r--r--packages/SettingsLib/ActivityEmbedding/Android.bp1
-rw-r--r--packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java8
-rw-r--r--packages/SettingsLib/Android.bp1
-rw-r--r--packages/SettingsLib/AppPreference/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/SettingsLib/BannerMessagePreference/Android.bp1
-rw-r--r--packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java3
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp2
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java6
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java8
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java7
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/EdgeToEdgeUtils.java62
-rw-r--r--packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java10
-rw-r--r--packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml27
-rw-r--r--packages/SettingsLib/LayoutPreference/res/values/styles.xml35
-rw-r--r--packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java4
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml3
-rw-r--r--packages/SettingsLib/Spa/gallery/AndroidManifest.xml14
-rw-r--r--packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt3
-rw-r--r--packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt93
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugActivity.kt23
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugFormat.kt1
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt6
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchContract.kt5
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchProvider.kt12
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SettingsSliceDataRepository.kt57
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SliceUtil.kt101
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceBroadcastReceiver.kt31
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceProvider.kt77
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/presenter/Demo.kt47
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/provider/Demo.kt60
-rw-r--r--packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SettingsSliceDataRepositoryTest.kt97
-rw-r--r--packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SliceUtilTest.kt64
-rw-r--r--packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/SpaEnvironmentForTest.kt2
-rw-r--r--packages/SettingsLib/SpaPrivileged/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt2
-rw-r--r--packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java39
-rw-r--r--packages/SettingsLib/Utils/src/com/android/settingslib/utils/BuildCompatUtils.java60
-rw-r--r--packages/SettingsLib/aconfig/settingslib.aconfig20
-rw-r--r--packages/SettingsLib/res/layout/zen_mode_duration_dialog.xml4
-rw-r--r--packages/SettingsLib/res/layout/zen_mode_turn_on_dialog_container.xml4
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-da/arrays.xml4
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-en-rXC/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml28
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml24
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml102
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml24
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml24
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml24
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml22
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java9
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java5
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/Utils.java3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManagerExt.kt39
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java44
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java8
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistantCallbackExt.kt85
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/ProfileConnectionState.kt23
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreference.java326
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceState.java136
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.aidl19
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.java137
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.aidl19
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.java160
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingId.java113
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItem.kt72
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreference.java62
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreferenceState.java62
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.aidl19
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.java165
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingType.java41
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.aidl19
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.kt74
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsListener.aidl23
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsProviderService.aidl27
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreference.java232
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceState.java126
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfo.java167
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java5
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java6
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java39
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java23
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExt.kt100
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java88
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoDao.java9
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoEntity.java136
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt (renamed from packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/FakeZenModeRepository.kt)31
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/data/repository/ZenModeRepository.kt (renamed from packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/ZenModeRepository.kt)107
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt (renamed from packages/SettingsLib/src/com/android/settingslib/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt)4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableZenModeDialog.java (renamed from packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java)28
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java176
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenDurationDialog.java (renamed from packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java)51
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java11
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java62
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModeDialogMetricsLogger.java (renamed from packages/SettingsLib/src/com/android/settingslib/notification/ZenModeDialogMetricsLogger.java)2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java15
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenRadioLayout.java (renamed from packages/SettingsLib/src/com/android/settingslib/notification/ZenRadioLayout.java)16
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt169
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt6
-rw-r--r--packages/SettingsLib/tests/integ/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExtTest.kt95
-rw-r--r--packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt324
-rw-r--r--packages/SettingsLib/tests/robotests/Android.bp1
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java78
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceStateTest.java94
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceTest.java163
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfoTest.java98
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItemTest.kt55
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingStateTest.java170
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingTest.java169
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfigTest.kt84
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceStateTest.java79
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceTest.java152
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfoTest.java125
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java63
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java17
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/data/repository/ZenModeRepositoryTest.kt (renamed from packages/SettingsLib/tests/integ/src/com/android/settingslib/statusbar/notification/data/repository/ZenModeRepositoryTest.kt)120
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/EnableZenModeDialogTest.java (renamed from packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java)10
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenDurationDialogTest.java (renamed from packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java)4
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java30
-rw-r--r--packages/SettingsProvider/res/values/defaults.xml2
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java5
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java28
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java3
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java20
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java16
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig11
-rw-r--r--packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java17
-rw-r--r--packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java35
-rw-r--r--packages/Shell/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/Shell/res/values-nb/strings.xml2
-rw-r--r--packages/SimAppDialog/res/values-fr-rCA/strings.xml6
-rw-r--r--packages/SystemUI/Android.bp20
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml2
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml2
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml4
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml2
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml2
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml4
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig97
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt24
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt48
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt136
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt126
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalPopupSection.kt24
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt2
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt11
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt7
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt7
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt20
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt38
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt25
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt75
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaScenePicker.kt72
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt16
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt153
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt40
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt30
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt2
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt27
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/statusbar/ui/composable/StatusBar.kt43
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt3
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt6
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt101
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/EdgeDetector.kt24
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt185
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt6
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt127
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PunchHole.kt178
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt6
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt122
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt29
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt107
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt4
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt10
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/systemui/communal/ui/compose/CommunalSwipeDetector.kt (renamed from packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/CommunalSwipeDetector.kt)12
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt46
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt126
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt76
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ObservableTransitionStateTest.kt19
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt159
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt1
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt102
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt152
-rw-r--r--packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestSceneScope.kt10
-rw-r--r--packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt56
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt9
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt13
-rw-r--r--packages/SystemUI/lint-baseline.xml67
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.java187
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.kt180
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt20
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalBackupRestoreStartableTest.kt81
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalOngoingContentStartableTest.kt89
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt51
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationTest.kt157
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalMediaRepositoryImplTest.kt35
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt34
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryImplTest.kt319
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt259
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt71
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt126
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/smartspace/SmartspaceInteractionHandlerTest.kt60
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt41
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt172
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalTransitionAnimatorControllerTest.kt115
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt61
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt25
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt213
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt258
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java21
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt22
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt107
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt107
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt64
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt39
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt41
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt192
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/shared/model/KeyguardStateTest.kt52
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt123
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt67
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/SettingObserverTest.kt117
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryTest.kt78
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryTest.kt62
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt27
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorTest.kt86
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt26
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt12
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayoutTest.kt12
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt98
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt162
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt)3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt)5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt93
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt49
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt72
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt21
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt10
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModelTest.kt5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt45
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt18
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt15
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinatorTest.kt104
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorTest.kt5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt21
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt104
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java246
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt439
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.kt236
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt100
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorTest.kt23
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialog.java1
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt26
-rw-r--r--packages/SystemUI/res-product/values-fr-rCA/strings.xml6
-rw-r--r--packages/SystemUI/res-product/values-or/strings.xml2
-rw-r--r--packages/SystemUI/res/layout/alert_dialog_systemui.xml1
-rw-r--r--packages/SystemUI/res/layout/app_clips_screenshot.xml6
-rw-r--r--packages/SystemUI/res/layout/back.xml2
-rw-r--r--packages/SystemUI/res/layout/clipboard_overlay.xml32
-rw-r--r--packages/SystemUI/res/layout/clipboard_overlay2.xml202
-rw-r--r--packages/SystemUI/res/layout/contextual.xml4
-rw-r--r--packages/SystemUI/res/layout/custom_key.xml2
-rw-r--r--packages/SystemUI/res/layout/dream_overlay_container.xml13
-rw-r--r--packages/SystemUI/res/layout/home.xml2
-rw-r--r--packages/SystemUI/res/layout/ime_switcher.xml2
-rw-r--r--packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml2
-rw-r--r--packages/SystemUI/res/layout/menu_ime.xml6
-rw-r--r--packages/SystemUI/res/layout/navigation_bar.xml6
-rw-r--r--packages/SystemUI/res/layout/navigation_bar_window.xml4
-rw-r--r--packages/SystemUI/res/layout/navigation_layout.xml4
-rw-r--r--packages/SystemUI/res/layout/navigation_layout_vertical.xml8
-rw-r--r--packages/SystemUI/res/layout/recent_apps.xml2
-rw-r--r--packages/SystemUI/res/layout/screen_share_dialog.xml2
-rw-r--r--packages/SystemUI/res/layout/screenshot.xml40
-rw-r--r--packages/SystemUI/res/layout/window_magnification_settings_view.xml8
-rw-r--r--packages/SystemUI/res/values-af/strings.xml76
-rw-r--r--packages/SystemUI/res/values-af/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-am/strings.xml104
-rw-r--r--packages/SystemUI/res/values-am/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml84
-rw-r--r--packages/SystemUI/res/values-ar/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-as/strings.xml90
-rw-r--r--packages/SystemUI/res/values-as/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-az/strings.xml83
-rw-r--r--packages/SystemUI/res/values-az/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml90
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-be/strings.xml112
-rw-r--r--packages/SystemUI/res/values-be/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml83
-rw-r--r--packages/SystemUI/res/values-bg/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml82
-rw-r--r--packages/SystemUI/res/values-bn/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml102
-rw-r--r--packages/SystemUI/res/values-bs/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml112
-rw-r--r--packages/SystemUI/res/values-ca/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml108
-rw-r--r--packages/SystemUI/res/values-cs/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-da/strings.xml104
-rw-r--r--packages/SystemUI/res/values-da/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-de/strings.xml116
-rw-r--r--packages/SystemUI/res/values-de/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-el/strings.xml104
-rw-r--r--packages/SystemUI/res/values-el/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml83
-rw-r--r--packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml41
-rw-r--r--packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml83
-rw-r--r--packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml83
-rw-r--r--packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml41
-rw-r--r--packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml106
-rw-r--r--packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-es/strings.xml108
-rw-r--r--packages/SystemUI/res/values-es/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-et/strings.xml83
-rw-r--r--packages/SystemUI/res/values-et/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml106
-rw-r--r--packages/SystemUI/res/values-eu/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml82
-rw-r--r--packages/SystemUI/res/values-fa/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml104
-rw-r--r--packages/SystemUI/res/values-fi/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-fr-rCA-ldrtl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml300
-rw-r--r--packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml104
-rw-r--r--packages/SystemUI/res/values-fr/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml48
-rw-r--r--packages/SystemUI/res/values-gl/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml80
-rw-r--r--packages/SystemUI/res/values-gu/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml80
-rw-r--r--packages/SystemUI/res/values-hi/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml91
-rw-r--r--packages/SystemUI/res/values-hr/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml104
-rw-r--r--packages/SystemUI/res/values-hu/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml112
-rw-r--r--packages/SystemUI/res/values-hy/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-in/strings.xml83
-rw-r--r--packages/SystemUI/res/values-in/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-is/strings.xml104
-rw-r--r--packages/SystemUI/res/values-is/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-it/strings.xml105
-rw-r--r--packages/SystemUI/res/values-it/tiles_states_strings.xml7
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml107
-rw-r--r--packages/SystemUI/res/values-iw/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml91
-rw-r--r--packages/SystemUI/res/values-ja/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml88
-rw-r--r--packages/SystemUI/res/values-ka/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml104
-rw-r--r--packages/SystemUI/res/values-kk/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-km/strings.xml91
-rw-r--r--packages/SystemUI/res/values-km/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml88
-rw-r--r--packages/SystemUI/res/values-kn/tiles_states_strings.xml7
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml104
-rw-r--r--packages/SystemUI/res/values-ko/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml112
-rw-r--r--packages/SystemUI/res/values-ky/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml91
-rw-r--r--packages/SystemUI/res/values-lo/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml83
-rw-r--r--packages/SystemUI/res/values-lt/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml85
-rw-r--r--packages/SystemUI/res/values-lv/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml104
-rw-r--r--packages/SystemUI/res/values-mk/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml90
-rw-r--r--packages/SystemUI/res/values-ml/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml106
-rw-r--r--packages/SystemUI/res/values-mn/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml88
-rw-r--r--packages/SystemUI/res/values-mr/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml88
-rw-r--r--packages/SystemUI/res/values-ms/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-my/strings.xml103
-rw-r--r--packages/SystemUI/res/values-my/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml110
-rw-r--r--packages/SystemUI/res/values-nb/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml111
-rw-r--r--packages/SystemUI/res/values-ne/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml92
-rw-r--r--packages/SystemUI/res/values-nl/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-or/strings.xml85
-rw-r--r--packages/SystemUI/res/values-or/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml83
-rw-r--r--packages/SystemUI/res/values-pa/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml110
-rw-r--r--packages/SystemUI/res/values-pl/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml92
-rw-r--r--packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml88
-rw-r--r--packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml92
-rw-r--r--packages/SystemUI/res/values-pt/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml83
-rw-r--r--packages/SystemUI/res/values-ro/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml112
-rw-r--r--packages/SystemUI/res/values-ru/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-si/strings.xml83
-rw-r--r--packages/SystemUI/res/values-si/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml83
-rw-r--r--packages/SystemUI/res/values-sk/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml109
-rw-r--r--packages/SystemUI/res/values-sl/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml104
-rw-r--r--packages/SystemUI/res/values-sq/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml90
-rw-r--r--packages/SystemUI/res/values-sr/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml83
-rw-r--r--packages/SystemUI/res/values-sv/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml83
-rw-r--r--packages/SystemUI/res/values-sw/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml112
-rw-r--r--packages/SystemUI/res/values-ta/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-te/strings.xml90
-rw-r--r--packages/SystemUI/res/values-te/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-th/strings.xml110
-rw-r--r--packages/SystemUI/res/values-th/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml110
-rw-r--r--packages/SystemUI/res/values-tl/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml83
-rw-r--r--packages/SystemUI/res/values-tr/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml104
-rw-r--r--packages/SystemUI/res/values-uk/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml88
-rw-r--r--packages/SystemUI/res/values-ur/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml112
-rw-r--r--packages/SystemUI/res/values-uz/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml104
-rw-r--r--packages/SystemUI/res/values-vi/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml104
-rw-r--r--packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml5
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml104
-rw-r--r--packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml104
-rw-r--r--packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml91
-rw-r--r--packages/SystemUI/res/values-zu/tiles_states_strings.xml3
-rw-r--r--packages/SystemUI/res/values/config.xml5
-rw-r--r--packages/SystemUI/res/values/dimens.xml1
-rw-r--r--packages/SystemUI/res/values/strings.xml62
-rw-r--r--packages/SystemUI/res/values/styles.xml1
-rw-r--r--packages/SystemUI/res/values/tiles_states_strings.xml10
-rw-r--r--packages/SystemUI/res/xml/large_screen_shade_header.xml1
-rw-r--r--packages/SystemUI/schemas/com.android.systemui.communal.data.db.CommunalDatabase/2.json81
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/education/GestureType.kt21
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl9
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java13
-rw-r--r--packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt2
-rw-r--r--packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt1
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/data/repository/AccessibilityRepository.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/ambient/touch/ShadeTouchHandler.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDebouncer.kt125
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt61
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java106
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalBackupRestoreStartable.kt58
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalOngoingContentStartable.kt58
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalStartableModule.kt62
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/backup/CommunalBackupUtils.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalDatabase.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalEntities.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt106
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalSmartspaceTimer.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalMediaRepository.kt53
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepository.kt123
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryModule.kt (renamed from packages/SystemUI/src/com/android/systemui/smartspace/data/repository/SmartspaceRepositoryModule.kt)11
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt85
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt71
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/proto/communal_hub_state.proto3
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/smartspace/SmartspaceInteractionHandler.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/util/InteractionHandlerDelegate.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalTransitionAnimatorController.kt50
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalWidgetModule.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt98
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt36
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractor.kt95
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt106
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt124
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeHost.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeUi.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/homecontrols/TaskFragmentComponent.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt57
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/data/model/GestureEduModel.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt66
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt142
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt52
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/data/repository/InputDeviceRepository.kt95
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt54
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/KeyboardShortcutInfo.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt252
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSource.kt44
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/CurrentAppShortcutsSource.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt66
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt52
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/extensions/KeyboardShortcutGroupExtensions.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/AppCategoriesShortcuts.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/CurrentAppShortcuts.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/InputShortcuts.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/MultitaskingShortcuts.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/SystemShortcuts.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCommand.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutIcon.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutKey.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutSubCategory.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt237
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelperTemporaryData.kt251
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/IconSource.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutsUiState.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java72
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt176
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt156
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt61
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt71
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt36
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt36
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt123
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt372
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt69
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt192
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt133
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt61
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/SideFpsProgressBar.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AccessibilityActionsSection.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt58
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/SessionTracker.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/MediaLog.kt (renamed from packages/SystemUI/src/com/android/systemui/log/dagger/MediaLoadingLog.kt)7
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/shared/MediaLogger.kt (renamed from packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLogger.kt)44
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionLog.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionModule.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/data/model/MediaProjectionState.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt106
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediarouter/MediaRouterLog.kt (renamed from packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/IconLabelVisibilityLog.kt)5
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediarouter/MediaRouterModule.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepository.kt77
-rw-r--r--packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java)45
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarFrame.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java)11
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarTransitions.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java)26
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonDispatcher.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonInterface.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButton.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButtonGroup.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/DeadZone.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java)6
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavBarButtonClickLogger.kt (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/NavBarButtonClickLogger.kt)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/NavbarOrientationTrackingLogger.kt)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ReverseLinearLayout.java (renamed from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java)16
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleBackupHelper.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java74
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsControllerImpl.java62
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/SettingObserver.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/DefaultLargeTilesRepository.kt (renamed from packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconTilesRepository.kt)29
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepository.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepository.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/StockTilesRepository.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractor.kt50
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSPreferencesInteractor.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractor.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/PanelsLog.kt (renamed from packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/GridConsistencyLog.kt)5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt51
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt60
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt316
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt100
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconTilesViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt100
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddable.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt117
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSZenModeDialogMetricsLogger.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt51
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt47
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesTileModel.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt63
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt54
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingState.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/RecordingControllerLog.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/RecordingControllerLogger.kt77
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ActionExecutor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt242
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java223
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt70
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java1126
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt76
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/smartspace/data/repository/SmartspaceRepository.kt77
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java168
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java140
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsLog.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsModule.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt73
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/model/MediaRouterCastModel.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegate.kt90
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegate.kt (renamed from packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegate.kt)31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt162
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelper.kt54
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegate.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationClassificationFlag.kt53
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinator.kt95
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt108
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt80
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/FullScreenIntentDecisionProvider.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RichOngoingNotificationContentExtractor.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/TransparentHeaderFix.kt53
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt57
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java72
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java59
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java42
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpNotificationViewControllerEmptyImpl.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt51
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java54
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerLogger.kt141
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/CastDevice.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt58
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/CastControllerLog.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/GestureViewModelFactory.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt (renamed from packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/BackGestureTutorialScreen.kt)68
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialComponents.kt (renamed from packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialComponents.kt)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt (renamed from packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialSelectionScreen.kt)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt64
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGesture.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt50
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialViewModel.kt (renamed from packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModel.kt)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java104
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/icons/AppCategoryIconProvider.kt95
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/kotlin/ReduceBrightColorsControllerExt.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/kotlin/SettingsSingleThreadBackground.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java84
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt251
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt213
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java149
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeControllerCollector.kt59
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dagger/AudioSharingEmptyImplModule.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dagger/AudioSharingModule.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractor.kt90
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/TestableWindowManager.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java133
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt359
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDebouncerTest.kt221
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt68
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupHelperTest.kt23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupUtilsTest.kt35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/data/db/CommunalDatabaseMigrationsTest.kt149
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/data/db/CommunalWidgetDaoTest.kt38
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorTest.kt160
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt63
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt126
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperStateRepositoryTest.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSourceTest.kt81
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt290
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt312
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperActivityStarterTest.kt59
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt68
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt86
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt169
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt378
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt54
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt29
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/log/SessionTrackerTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt103
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt125
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/FakeTasksRepository.kt46
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt105
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarButtonTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java)3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarInflaterViewTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java)6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java)62
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTransitionsTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java)4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/KeyButtonViewTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java)14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NavigationBarContextTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java)2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrameTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java)2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt291
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ModesTileTest.kt167
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt64
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt45
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt700
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt222
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt)141
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt153
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt207
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt107
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt46
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt82
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt39
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt175
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt219
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt144
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java65
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java37
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java62
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java114
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java63
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt32
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java63
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitorTest.kt160
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/FakeMotionEvent.kt88
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt124
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModelTest.kt)2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java126
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/icons/AppCategoryIconProviderTest.kt154
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java178
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt216
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt391
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/volume/CsdWarningDialogTest.java106
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/volume/VolumeControllerCollectorTest.kt100
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java2
-rw-r--r--packages/SystemUI/tests/utils/src/android/app/admin/AlarmManagerKosmos.kt (renamed from packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/data/repository/SmartspaceRepositoryKosmos.kt)9
-rw-r--r--packages/SystemUI/tests/utils/src/android/content/PackageManagerKosmos.kt9
-rw-r--r--packages/SystemUI/tests/utils/src/android/hardware/display/DisplayManagerKosmos.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/android/hardware/input/FakeInputManager.kt19
-rw-r--r--packages/SystemUI/tests/utils/src/android/view/WindowManagerKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/app/admin/DevicePolicyManagerKosmos.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/internal/widget/LockPatternUtilsKosmos.kt9
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt8
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/accessibility/FakeReduceBrightColorsController.kt18
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/assist/AssistManagerKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationKosmos.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryKosmos.kt24
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalMediaRepository.kt14
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSmartspaceRepository.kt45
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt14
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorKosmos.kt34
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryKosmos.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt53
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeEduClock.kt37
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsClassicKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/haptics/qs/QSLongPressEffectKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt44
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt17
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt30
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractorKosmos.kt11
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractorKosmos.kt27
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorKosmos.kt5
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorKosmos.kt45
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModelKosmos.kt32
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt2
-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/media/controls/domain/pipeline/MediaDataFilterKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/shared/MediaLoggerKosmos.kt (renamed from packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLoggerKosmos.kt)7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepositoryKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/FakeMediaRouterRepository.kt31
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryKosmos.kt33
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/DefaultLargeTilesRepositoryKosmos.kt (renamed from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/IconTilesRepositoryKosmos.kt)3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryKosmos.kt9
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryKosmos.kt27
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorKosmos.kt14
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractorKosmos.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt33
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt33
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt (renamed from packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt)17
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt49
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/data/repository/FakeSmartspaceRepository.kt21
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/StatusBarChipsLogKosmos.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt10
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractorKosmos.kt31
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt8
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelKosmos.kt6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardOcclusionInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt5
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/CastControllerKosmos.kt21
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeCastController.kt61
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelKosmos.kt37
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/AppCategoryIconProviderKosmos.kt35
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/FakeAppCategoryIconProvider.kt42
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java15
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java17
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckerCastController.java (renamed from packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java)18
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/VolumeControllerCollectorKosmos.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt24
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorKosmos.kt29
-rw-r--r--packages/VpnDialogs/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/overlays/AvoidAppsInCutoutOverlay/res/values-fr-rCA/strings.xml2
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java13
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/android/system/StructStat.java121
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/android/system/StructTimespec.java79
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/common/RavenwoodRuntimeNative.java (renamed from ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodRuntimeNative.java)31
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/libcore/util/Objects.java85
-rw-r--r--ravenwood/runtime-jni/ravenwood_runtime.cpp96
-rw-r--r--ravenwood/runtime-test/test/com/android/ravenwood/runtimetest/OsTest.java123
-rw-r--r--services/Android.bp26
-rw-r--r--services/accessibility/Android.bp13
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java22
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java28
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java12
-rw-r--r--services/accessibility/java/com/android/server/accessibility/MouseKeysInterceptor.java499
-rw-r--r--services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerUtils.java218
-rw-r--r--services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityNodePathBuilder.java (renamed from core/java/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilder.java)2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/a11ychecker/OWNERS (renamed from core/java/android/view/accessibility/a11ychecker/OWNERS)0
-rw-r--r--services/accessibility/java/com/android/server/accessibility/a11ychecker/proto/a11ychecker.proto73
-rw-r--r--services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java4
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java8
-rw-r--r--services/backup/java/com/android/server/backup/utils/TarBackupReader.java3
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java6
-rw-r--r--services/core/Android.bp1
-rw-r--r--services/core/java/com/android/server/CertBlocklister.java (renamed from services/core/java/com/android/server/CertBlacklister.java)106
-rw-r--r--services/core/java/com/android/server/ExplicitHealthCheckController.java42
-rw-r--r--services/core/java/com/android/server/OWNERS3
-rw-r--r--services/core/java/com/android/server/PackageWatchdog.java30
-rw-r--r--services/core/java/com/android/server/RescueParty.java451
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java5
-rw-r--r--services/core/java/com/android/server/Watchdog.java1
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java110
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java10
-rw-r--r--services/core/java/com/android/server/am/ApplicationThreadDeferred.java173
-rw-r--r--services/core/java/com/android/server/am/ApplicationThreadFilter.java603
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java308
-rw-r--r--services/core/java/com/android/server/am/CachedAppOptimizer.java5
-rw-r--r--services/core/java/com/android/server/am/LmkdConnection.java63
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java5
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java13
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java2
-rw-r--r--services/core/java/com/android/server/am/flags.aconfig12
-rw-r--r--services/core/java/com/android/server/appop/DiscreteRegistry.java8
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java17
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java28
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java134
-rw-r--r--services/core/java/com/android/server/audio/BtHelper.java25
-rw-r--r--services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java34
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java11
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java45
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java13
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java1
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java23
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java13
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java13
-rw-r--r--services/core/java/com/android/server/crashrecovery/CrashRecoveryModule.java55
-rw-r--r--services/core/java/com/android/server/crashrecovery/TEST_MAPPING3
-rw-r--r--services/core/java/com/android/server/display/BrightnessRangeController.java3
-rw-r--r--services/core/java/com/android/server/display/DisplayBrightnessState.java37
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java280
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java104
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerShellCommand.java35
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java22
-rw-r--r--services/core/java/com/android/server/display/HighBrightnessModeController.java2
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplayMapper.java115
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java8
-rw-r--r--services/core/java/com/android/server/display/brightness/BrightnessUtils.java8
-rw-r--r--services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java3
-rw-r--r--services/core/java/com/android/server/display/brightness/clamper/HdrBrightnessModifier.java51
-rw-r--r--services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java16
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategy.java1
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java1
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java1
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java1
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/FallbackBrightnessStrategy.java1
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java2
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java3
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java1
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java3
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java1
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java1
-rw-r--r--services/core/java/com/android/server/display/color/ColorDisplayService.java69
-rw-r--r--services/core/java/com/android/server/display/config/DisplayDeviceConfigUtils.java63
-rw-r--r--services/core/java/com/android/server/display/config/HdrBrightnessData.java160
-rw-r--r--services/core/java/com/android/server/display/config/HighBrightnessModeData.java157
-rw-r--r--services/core/java/com/android/server/display/feature/DisplayManagerFlags.java22
-rw-r--r--services/core/java/com/android/server/display/feature/display_flags.aconfig16
-rw-r--r--services/core/java/com/android/server/flags/services.aconfig10
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java6
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecNetwork.java6
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java16
-rw-r--r--services/core/java/com/android/server/input/InputSettingsObserver.java14
-rw-r--r--services/core/java/com/android/server/input/KeyboardGlyphManager.java382
-rw-r--r--services/core/java/com/android/server/input/PointerIconCache.java25
-rw-r--r--services/core/java/com/android/server/inputmethod/AdditionalSubtypeMapRepository.java56
-rw-r--r--services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java11
-rw-r--r--services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java11
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodBindingController.java33
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodDrawsNavBarResourceMonitor.java89
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java1004
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodMenuController.java6
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodSettings.java51
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodSettingsRepository.java40
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java422
-rw-r--r--services/core/java/com/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper.java159
-rw-r--r--services/core/java/com/android/server/inputmethod/SecureSettingsChangeCallback.java78
-rw-r--r--services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java40
-rw-r--r--services/core/java/com/android/server/inputmethod/UserData.java147
-rw-r--r--services/core/java/com/android/server/inputmethod/UserDataRepository.java175
-rw-r--r--services/core/java/com/android/server/inputmethod/ZeroJankProxy.java6
-rw-r--r--services/core/java/com/android/server/locales/LocaleManagerService.java2
-rw-r--r--services/core/java/com/android/server/location/altitude/AltitudeService.java5
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubEventLogger.java36
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubService.java2
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java18
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java25
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java6
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java14
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java7
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java52
-rw-r--r--services/core/java/com/android/server/notification/GroupHelper.java1053
-rw-r--r--services/core/java/com/android/server/notification/NotificationAttentionHelper.java13
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java494
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecord.java11
-rw-r--r--services/core/java/com/android/server/notification/PreferencesHelper.java225
-rw-r--r--services/core/java/com/android/server/notification/ShortcutHelper.java162
-rw-r--r--services/core/java/com/android/server/notification/TimeToLiveHelper.java15
-rw-r--r--services/core/java/com/android/server/notification/ZenModeEventLogger.java50
-rw-r--r--services/core/java/com/android/server/notification/flags.aconfig9
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerService.java2
-rw-r--r--services/core/java/com/android/server/pdb/PersistentDataBlockService.java23
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java61
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java9
-rw-r--r--services/core/java/com/android/server/pm/OWNERS1
-rw-r--r--services/core/java/com/android/server/pm/PackageArchiver.java10
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java15
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java25
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java20
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceUtils.java42
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java93
-rw-r--r--services/core/java/com/android/server/pm/RemovePackageHelper.java7
-rw-r--r--services/core/java/com/android/server/pm/ScanPackageUtils.java4
-rw-r--r--services/core/java/com/android/server/pm/Settings.java54
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java13
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java132
-rw-r--r--services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java8
-rw-r--r--services/core/java/com/android/server/pm/pkg/PackageState.java8
-rw-r--r--services/core/java/com/android/server/policy/ModifierShortcutManager.java149
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java82
-rw-r--r--services/core/java/com/android/server/policy/WindowManagerPolicy.java14
-rw-r--r--services/core/java/com/android/server/power/LowPowerStandbyController.java5
-rw-r--r--services/core/java/com/android/server/power/Notifier.java4
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java16
-rw-r--r--services/core/java/com/android/server/power/WakefulnessSessionObserver.java285
-rw-r--r--services/core/java/com/android/server/power/hint/HintManagerService.java335
-rw-r--r--services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java26
-rw-r--r--services/core/java/com/android/server/power/stats/flags.aconfig7
-rw-r--r--services/core/java/com/android/server/rollback/Rollback.java8
-rw-r--r--services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java14
-rw-r--r--services/core/java/com/android/server/stats/pull/RawSettingsTelemetryUtil.java83
-rw-r--r--services/core/java/com/android/server/stats/pull/SettingsStatsUtil.java4
-rw-r--r--services/core/java/com/android/server/stats/pull/StatsPullAtomService.java15
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java23
-rw-r--r--services/core/java/com/android/server/updates/Android.bp11
-rw-r--r--services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java116
-rw-r--r--services/core/java/com/android/server/updates/flags.aconfig10
-rw-r--r--services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java39
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationSettings.java14
-rw-r--r--services/core/java/com/android/server/vibrator/VibratorManagerService.java21
-rw-r--r--services/core/java/com/android/server/wm/AbsAppSnapshotController.java6
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java591
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java7
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java16
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java36
-rw-r--r--services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java304
-rw-r--r--services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java379
-rw-r--r--services/core/java/com/android/server/wm/AppCompatCameraOverrides.java12
-rw-r--r--services/core/java/com/android/server/wm/AppCompatCameraPolicy.java156
-rw-r--r--services/core/java/com/android/server/wm/AppCompatController.java36
-rw-r--r--services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java83
-rw-r--r--services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java103
-rw-r--r--services/core/java/com/android/server/wm/AppCompatOverrides.java96
-rw-r--r--services/core/java/com/android/server/wm/AppCompatUtils.java25
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java69
-rw-r--r--services/core/java/com/android/server/wm/BackNavigationController.java34
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartController.java58
-rw-r--r--services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java10
-rw-r--r--services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java40
-rw-r--r--services/core/java/com/android/server/wm/CameraStateMonitor.java73
-rw-r--r--services/core/java/com/android/server/wm/ConfigurationContainer.java117
-rw-r--r--services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java11
-rw-r--r--services/core/java/com/android/server/wm/DeviceStateController.java100
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java188
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java1
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java7
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java50
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotationReversionController.java2
-rw-r--r--services/core/java/com/android/server/wm/DragDropController.java23
-rw-r--r--services/core/java/com/android/server/wm/DragState.java112
-rw-r--r--services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java3
-rw-r--r--services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java5
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java4
-rw-r--r--services/core/java/com/android/server/wm/LetterboxConfiguration.java31
-rw-r--r--services/core/java/com/android/server/wm/LetterboxUiController.java205
-rw-r--r--services/core/java/com/android/server/wm/RecentTasks.java7
-rw-r--r--services/core/java/com/android/server/wm/RemoteAnimationController.java7
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java33
-rw-r--r--services/core/java/com/android/server/wm/SafeActivityOptions.java5
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java8
-rw-r--r--services/core/java/com/android/server/wm/Session.java61
-rw-r--r--services/core/java/com/android/server/wm/Task.java120
-rw-r--r--services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java83
-rw-r--r--services/core/java/com/android/server/wm/Transition.java161
-rw-r--r--services/core/java/com/android/server/wm/TransparentPolicy.java10
-rw-r--r--services/core/java/com/android/server/wm/UnknownAppVisibilityController.java4
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java52
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java49
-rw-r--r--services/core/java/com/android/server/wm/WindowList.java38
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerFlags.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java11
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java156
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java54
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java16
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java64
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java185
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java237
-rw-r--r--services/core/java/com/android/server/wm/WindowTracing.java299
-rw-r--r--services/core/java/com/android/server/wm/WindowTracingLegacy.java276
-rw-r--r--services/core/java/com/android/server/wm/utils/DimenPxIntSupplier.java54
-rw-r--r--services/core/jni/Android.bp3
-rw-r--r--services/core/jni/com_android_server_companion_virtual_InputController.cpp10
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp11
-rw-r--r--services/core/jni/com_android_server_vibrator_VibratorController.cpp81
-rw-r--r--services/core/xsd/display-device-config/display-device-config.xsd55
-rw-r--r--services/core/xsd/display-device-config/schema/current.txt17
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java10
-rw-r--r--services/java/com/android/server/SystemServer.java64
-rw-r--r--services/java/com/android/server/flags.aconfig7
-rw-r--r--services/manifest_services.xml5
-rw-r--r--services/manifest_services_android.frameworks.vibrator.xml7
-rw-r--r--services/net/Android.bp1
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/PermissionService.kt2
-rw-r--r--services/permission/java/com/android/server/permission/access/util/AtomicFileExtensions.kt3
-rw-r--r--services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java13
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java192
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java3
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java75
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceWindowGainedFocusTest.java4
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java767
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java87
-rw-r--r--services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/src/com/android/apps/inputmethod/simpleime/ims/InputMethodServiceWrapper.java15
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java90
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java12
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java74
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java15
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java72
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java7
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeMetadataMapperTest.java4
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java47
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java16
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategyTest.java1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java4
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/BoostBrightnessStrategyTest.java1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/DozeBrightnessStrategyTest.java1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FallbackBrightnessStrategyTest.java1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FollowerBrightnessStrategyTest.java1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OffloadBrightnessStrategyTest.java1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OverrideBrightnessStrategyTest.java1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategyTest.java1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/config/DisplayDeviceConfigTestUtils.kt173
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/config/HdrBrightnessDataTest.kt158
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/mode/SettingsObserverTest.kt1
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/mode/TestUtils.kt15
-rw-r--r--services/tests/dreamservicetests/AndroidManifest.xml29
-rw-r--r--services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml20
-rw-r--r--services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml20
-rw-r--r--services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java22
-rw-r--r--services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java20
-rw-r--r--services/tests/mockingservicestests/Android.bp1
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java288
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java5
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ApplicationThreadDeferredTest.java99
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java6
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ProcessObserverTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ServiceTimeoutTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java47
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp58
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/crashrecovery/AndroidManifest.xml32
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/crashrecovery/AndroidTest.xml34
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/crashrecovery/CrashRecoveryModuleTest.java105
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/crashrecovery/OWNERS1
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java11
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java59
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java2
-rw-r--r--services/tests/servicestests/Android.bp2
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/MouseKeysInterceptorTest.kt295
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/AccessibilityCheckerUtilsTest.java187
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/AccessibilityNodePathBuilderTest.java (renamed from core/tests/coretests/src/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilderTest.java)32
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/MockAccessibilityNodeInfoBuilder.java (renamed from core/tests/coretests/src/android/view/accessibility/a11ychecker/MockAccessibilityNodeInfoBuilder.java)18
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/OWNERS1
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/TestUtils.java74
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java113
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java30
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEventLoggerTest.java70
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockscreenRepairModeTest.java23
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java86
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java36
-rw-r--r--services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java222
-rw-r--r--services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java7
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java1919
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java74
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java515
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java66
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java212
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/TimeToLiveHelperTest.java47
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java96
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java5
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java117
-rw-r--r--services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java29
-rw-r--r--services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java12
-rw-r--r--services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java7
-rw-r--r--services/tests/wmtests/AndroidManifest.xml1
-rw-r--r--services/tests/wmtests/res/xml/bookmarks.xml41
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java167
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java11
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java28
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java79
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java30
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java149
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java106
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java123
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java371
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java69
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java30
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java143
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java48
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java36
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java139
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java28
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java7
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java22
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java365
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskTests.java16
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java11
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TransitionTests.java226
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java32
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java16
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java71
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTracingLegacyTest.java (renamed from services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java)4
-rw-r--r--telecomm/java/android/telecom/CallAudioState.java2
-rw-r--r--telephony/common/android/telephony/LocationAccessPolicy.java18
-rw-r--r--telephony/common/com/android/internal/telephony/TelephonyPermissions.java32
-rw-r--r--telephony/java/android/telephony/satellite/ProvisionSubscriberId.java28
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteManager.java19
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl2
-rw-r--r--test-mock/src/android/test/mock/MockContext.java9
-rw-r--r--tests/FlickerTests/IME/Android.bp19
-rw-r--r--tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt47
-rw-r--r--tests/Input/AndroidTest.xml2
-rw-r--r--tests/Input/assets/testPointerStrokeStyle.pngbin0 -> 378 bytes
-rw-r--r--tests/Input/res/drawable/test_key_drawable.xml (renamed from packages/SystemUI/res/drawable/hub_handle.xml)7
-rw-r--r--tests/Input/res/drawable/test_modifier_drawable.xml21
-rw-r--r--tests/Input/res/xml/keyboard_glyph_maps.xml22
-rw-r--r--tests/Input/res/xml/test_glyph_map.xml33
-rw-r--r--tests/Input/src/com/android/server/input/KeyboardGlyphManagerTests.kt197
-rw-r--r--tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt2
-rw-r--r--tests/Input/src/com/android/test/input/PointerIconLoadingTest.kt46
-rw-r--r--tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java19
-rw-r--r--tests/Internal/src/com/android/internal/protolog/LegacyProtoLogViewerConfigReaderTest.java114
-rw-r--r--tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java173
-rw-r--r--tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java25
-rw-r--r--tests/Internal/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java137
-rw-r--r--tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java55
-rw-r--r--tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java18
-rw-r--r--tests/TrustTests/src/android/trust/test/UnlockAttemptTest.kt9
-rw-r--r--tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java111
-rw-r--r--tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java93
-rw-r--r--tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/TestRequestConstants.java10
-rw-r--r--tools/aapt2/Debug.cpp27
-rw-r--r--tools/aapt2/Resource.h2
-rw-r--r--tools/aapt2/ResourceParser.cpp28
-rw-r--r--tools/aapt2/ResourceParser.h3
-rw-r--r--tools/aapt2/ResourceTable.cpp55
-rw-r--r--tools/aapt2/ResourceTable.h7
-rw-r--r--tools/aapt2/ResourceValues_test.cpp29
-rw-r--r--tools/aapt2/Resources.proto1
-rw-r--r--tools/aapt2/cmd/Compile.cpp1
-rw-r--r--tools/aapt2/cmd/Diff.cpp2
-rw-r--r--tools/aapt2/cmd/Optimize.h4
-rw-r--r--tools/aapt2/format/proto/ProtoDeserialize.cpp3
-rw-r--r--tools/aapt2/format/proto/ProtoSerialize.cpp1
-rw-r--r--tools/aapt2/link/ManifestFixer.cpp64
-rw-r--r--tools/aapt2/link/ManifestFixer.h2
-rw-r--r--tools/aapt2/link/ManifestFixer_test.cpp113
-rw-r--r--tools/aapt2/test/Fixture.h2
-rw-r--r--tools/aapt2/util/Files.cpp2
-rw-r--r--tools/aapt2/util/Files.h2
-rw-r--r--tools/aapt2/xml/XmlPullParser.cpp28
-rw-r--r--tools/aapt2/xml/XmlPullParser.h35
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java14
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java24
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java96
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java168
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java227
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java9
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java10
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java10
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java8
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java13
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java10
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java7
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java3
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java167
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java89
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java42
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java105
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java12
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java12
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java35
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java63
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java12
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java12
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java32
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java69
-rw-r--r--tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java173
-rw-r--r--tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java12
-rw-r--r--tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java72
-rw-r--r--tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java153
-rw-r--r--tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java58
-rw-r--r--tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java66
-rw-r--r--tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java66
-rw-r--r--tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java37
-rw-r--r--tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java114
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml16
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml18
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml17
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-system-app-safety-label.xml4
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml15
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/missing-version.xml18
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml20
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml23
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-system-app-safety-label.xml6
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml16
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml2
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid-v1.xml24
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml4
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/unrecognized-v1.xml25
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml2
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml11
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml4
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml13
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general-v1/od.xml70
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml17
-rw-r--r--tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml6
-rw-r--r--tools/lint/fix/README.md4
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt2
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt4
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt19
-rw-r--r--tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt2
-rw-r--r--tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt54
2467 files changed, 78588 insertions, 36429 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 5e9af6adfb88..a16aa2dea25b 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -411,6 +411,13 @@ cc_aconfig_library {
host_supported: true,
}
+cc_aconfig_library {
+ name: "android.companion.virtualdevice.flags-aconfig-cc-test",
+ aconfig_declarations: "android.companion.virtualdevice.flags-aconfig",
+ host_supported: true,
+ mode: "test",
+}
+
java_aconfig_library {
name: "android.companion.virtualdevice.flags-aconfig-java",
aconfig_declarations: "android.companion.virtualdevice.flags-aconfig",
diff --git a/BAL_OWNERS b/BAL_OWNERS
index d56a1d4634df..ec779e76fa3b 100644
--- a/BAL_OWNERS
+++ b/BAL_OWNERS
@@ -2,4 +2,6 @@ brufino@google.com
achim@google.com
topjohnwu@google.com
lus@google.com
+haok@google.com
+wnan@google.com
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 762e2af09cd3..0750c8dfea74 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -145,7 +145,9 @@ public class UserLifecycleTests {
Intent.ACTION_USER_STARTED,
Intent.ACTION_MEDIA_MOUNTED,
Intent.ACTION_USER_UNLOCKED,
- Intent.ACTION_USER_STOPPED);
+ Intent.ACTION_USER_STOPPED,
+ Intent.ACTION_PROFILE_AVAILABLE,
+ Intent.ACTION_PROFILE_UNAVAILABLE);
mUserSwitchWaiter = new UserSwitchWaiter(TAG, TIMEOUT_IN_SECOND);
removeAnyPreviousTestUsers();
if (mAm.getCurrentUser() != UserHandle.USER_SYSTEM) {
@@ -1230,6 +1232,255 @@ public class UserLifecycleTests {
}
}
+ /** Tests creating a private profile. */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void createPrivateProfile() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ Log.i(TAG, "Starting timer");
+
+ final int userId = createPrivateProfileUser();
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ waitCoolDownPeriod();
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests creating and starting a newly created private profile. This test waits for the
+ * {@link Intent.ACTION_USER_STARTED} to be received.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void createAndStartPrivateProfile_realistic() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ Log.i(TAG, "Starting timer");
+ final int userId = createPrivateProfileUser();
+
+ // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until
+ // ACTION_USER_STARTED.
+ runThenWaitForBroadcasts(userId, () -> {
+ mIam.startUserInBackground(userId);
+ }, Intent.ACTION_USER_STARTED);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ waitCoolDownPeriod();
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /** Tests for stopping the private profile. */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileStopped() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ runThenWaitForBroadcasts(userId, () -> {
+ startUserInBackgroundAndWaitForUnlock(userId);
+ }, Intent.ACTION_MEDIA_MOUNTED);
+
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ stopUser(userId);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests unlocking a newly-created private profile using the
+ * {@link UserManager#requestQuietModeEnabled} api.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileUnlock() throws RemoteException {
+
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+ waitCoolDownPeriod();
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ mUm.requestQuietModeEnabled(false, UserHandle.of(userId));
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests unlocking a newly-created private profile using the
+ * {@link UserManager#requestQuietModeEnabled} api and waiting for the
+ * {@link Intent.ACTION_PROFILE_AVAILABLE} to be received.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileUnlock_realistic() throws RemoteException {
+
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+ waitCoolDownPeriod();
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ runThenWaitForBroadcasts(userId, () -> {
+ mUm.requestQuietModeEnabled(false, UserHandle.of(userId));
+ }, Intent.ACTION_PROFILE_AVAILABLE);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests locking a newly-created private profile using the
+ * {@link UserManager#requestQuietModeEnabled} api.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileLock() throws RemoteException {
+
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests locking a newly-created private profile using the
+ * {@link UserManager#requestQuietModeEnabled} api and waiting for the
+ * {@link Intent.ACTION_PROFILE_UNAVAILABLE} to be received.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileLock_realistic() throws RemoteException {
+
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ runThenWaitForBroadcasts(userId, () -> {
+ mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+ }, Intent.ACTION_PROFILE_UNAVAILABLE);
+
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /** Tests removing a newly-created private profile */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileRemove() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+ removeUser(userId);
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /** Tests installing a pre-existing app in a private profile. */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileInstall() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ waitCoolDownPeriod();
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests creating a new private profile, starting it, installing an app, and launching that app
+ * in it.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileCreateStartInstallAndLaunchApp() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
+ startApp(userId, DUMMY_PACKAGE_NAME);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ waitCoolDownPeriod();
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests starting & launching an already-installed app in a private profile.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileStartAndLaunchApp() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
+ installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ startUserInBackgroundAndWaitForUnlock(userId);
+ startApp(userId, DUMMY_PACKAGE_NAME);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ waitCoolDownPeriod();
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
/** Creates a new user, returning its userId. */
private int createUserNoFlags() {
return createUserWithFlags(/* flags= */ 0);
@@ -1252,6 +1503,18 @@ public class UserLifecycleTests {
return userInfo.id;
}
+ /** Creates a private profile under the current user, returning its userId. */
+ private int createPrivateProfileUser() {
+ final UserInfo userInfo = mUm.createProfileForUser(TEST_USER_NAME,
+ UserManager.USER_TYPE_PROFILE_PRIVATE, /* flags */ 0, mAm.getCurrentUser());
+ attestFalse(
+ "Creating a private profile failed. Most likely there is already a pre-existing "
+ + "private profile on the device.",
+ userInfo == null);
+ mUsersToRemove.add(userInfo.id);
+ return userInfo.id;
+ }
+
/**
* Start user in background and wait for it to unlock by waiting for
* UserState.mUnlockProgress.finish().
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index dfa72069c28a..ee03e4b2ccd1 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -120,6 +120,7 @@ import android.os.SystemProperties;
import android.os.ThreadLocalWorkSource;
import android.os.Trace;
import android.os.UserHandle;
+import android.os.UserManager;
import android.os.WorkSource;
import android.provider.DeviceConfig;
import android.provider.Settings;
@@ -1794,7 +1795,8 @@ public class AlarmManagerService extends SystemService {
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mUseFrozenStateToDropListenerAlarms = Flags.useFrozenStateToDropListenerAlarms();
- mStartUserBeforeScheduledAlarms = Flags.startUserBeforeScheduledAlarms();
+ mStartUserBeforeScheduledAlarms = Flags.startUserBeforeScheduledAlarms()
+ && UserManager.supportsMultipleUsers();
if (mStartUserBeforeScheduledAlarms) {
mUserWakeupStore = new UserWakeupStore();
mUserWakeupStore.init();
@@ -3015,7 +3017,7 @@ public class AlarmManagerService extends SystemService {
mUseFrozenStateToDropListenerAlarms);
pw.println();
pw.print(Flags.FLAG_START_USER_BEFORE_SCHEDULED_ALARMS,
- mStartUserBeforeScheduledAlarms);
+ Flags.startUserBeforeScheduledAlarms());
pw.decreaseIndent();
pw.println();
pw.println();
diff --git a/api/Android.bp b/api/Android.bp
index cd1997c8bf97..6a04f0d76bf9 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -368,8 +368,6 @@ stubs_defaults {
"--hide CallbackInterface",
// Disable HiddenSuperclass, as Metalava handles this fine (it should be hidden by default)
"--hide HiddenSuperclass",
- "--hide-package android.audio.policy.configuration.V7_0",
- "--hide-package com.android.server",
"--manifest $(location :frameworks-base-core-AndroidManifest.xml)",
],
filter_packages: packages_to_document,
diff --git a/api/coverage/tools/ExtractFlaggedApis.kt b/api/coverage/tools/ExtractFlaggedApis.kt
index 5efda98a1518..0a3ae4f790b0 100644
--- a/api/coverage/tools/ExtractFlaggedApis.kt
+++ b/api/coverage/tools/ExtractFlaggedApis.kt
@@ -16,9 +16,9 @@
package android.platform.coverage
+import com.android.tools.metalava.model.CallableItem
import com.android.tools.metalava.model.ClassItem
import com.android.tools.metalava.model.Item
-import com.android.tools.metalava.model.MethodItem
import com.android.tools.metalava.model.text.ApiFile
import java.io.File
import java.io.FileWriter
@@ -40,24 +40,24 @@ fun main(args: Array<String>) {
fun extractFlaggedApisFromClass(
classItem: ClassItem,
- methods: List<MethodItem>,
+ callables: List<CallableItem>,
packageName: String,
builder: FlagApiMap.Builder
) {
- if (methods.isEmpty()) return
+ if (callables.isEmpty()) return
val classFlag = getClassFlag(classItem)
- for (method in methods) {
- val methodFlag = getFlagAnnotation(method) ?: classFlag
+ for (callable in callables) {
+ val callableFlag = getFlagAnnotation(callable) ?: classFlag
val api =
JavaMethod.newBuilder()
.setPackageName(packageName)
.setClassName(classItem.fullName())
- .setMethodName(method.name())
- for (param in method.parameters()) {
+ .setMethodName(callable.name())
+ for (param in callable.parameters()) {
api.addParameters(param.type().toTypeString())
}
- if (methodFlag != null) {
- addFlaggedApi(builder, api, methodFlag)
+ if (callableFlag != null) {
+ addFlaggedApi(builder, api, callableFlag)
}
}
}
@@ -75,10 +75,10 @@ fun addFlaggedApi(builder: FlagApiMap.Builder, api: JavaMethod.Builder, flag: St
fun getClassFlag(classItem: ClassItem): String? {
var classFlag = getFlagAnnotation(classItem)
var cur = classItem
- // If a class is not an inner class, use its @FlaggedApi annotation value.
+ // If a class is not a nested class, use its @FlaggedApi annotation value.
// Otherwise, use the flag value of the closest outer class that is annotated by @FlaggedApi.
- while (cur.isInnerClass() && classFlag == null) {
- cur = cur.parent() as ClassItem
+ while (classFlag == null) {
+ cur = cur.containingClass() ?: break
classFlag = getFlagAnnotation(cur)
}
return classFlag
diff --git a/boot/boot-image-profile.txt b/boot/boot-image-profile.txt
index 1a316120a816..854d4ee3dd9c 100644
--- a/boot/boot-image-profile.txt
+++ b/boot/boot-image-profile.txt
@@ -26,6 +26,7 @@ HSPLandroid/accounts/Account;-><init>(Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/accounts/Account;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/accounts/Account;->equals(Ljava/lang/Object;)Z
HSPLandroid/accounts/Account;->hashCode()I
+HSPLandroid/accounts/Account;->onAccountAccessed(Ljava/lang/String;)V
HSPLandroid/accounts/Account;->toString()Ljava/lang/String;
HSPLandroid/accounts/Account;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/accounts/AccountManager$10;-><init>(Landroid/accounts/AccountManager;Landroid/app/Activity;Landroid/os/Handler;Landroid/accounts/AccountManagerCallback;Landroid/accounts/Account;Ljava/lang/String;ZLandroid/os/Bundle;)V
@@ -125,13 +126,13 @@ HSPLandroid/animation/AnimationHandler$$ExternalSyntheticLambda0;->doFrame(J)V
HSPLandroid/animation/AnimationHandler$1;-><init>(Landroid/animation/AnimationHandler;)V
HSPLandroid/animation/AnimationHandler$1;->doFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;Landroid/animation/AnimationHandler$MyFrameCallbackProvider;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;-><init>(Landroid/animation/AnimationHandler;)V
-HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->getFrameTime()J
-HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V
+HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->getFrameTime()J+]Landroid/view/Choreographer;Landroid/view/Choreographer;
+HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/animation/AnimationHandler;-><init>()V
-HSPLandroid/animation/AnimationHandler;->addAnimationFrameCallback(Landroid/animation/AnimationHandler$AnimationFrameCallback;J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;Landroid/animation/AnimationHandler$MyFrameCallbackProvider;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/animation/AnimationHandler;->autoCancelBasedOn(Landroid/animation/ObjectAnimator;)V
-HSPLandroid/animation/AnimationHandler;->cleanUpList()V
-HSPLandroid/animation/AnimationHandler;->doAnimationFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallback;Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;,Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->addAnimationFrameCallback(Landroid/animation/AnimationHandler$AnimationFrameCallback;J)V
+HSPLandroid/animation/AnimationHandler;->autoCancelBasedOn(Landroid/animation/ObjectAnimator;)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->cleanUpList()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->doAnimationFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallback;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;,Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/AnimationHandler;->getAnimationCount()I
HSPLandroid/animation/AnimationHandler;->getInstance()Landroid/animation/AnimationHandler;
HSPLandroid/animation/AnimationHandler;->getProvider()Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;
@@ -156,18 +157,18 @@ HSPLandroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda6;-><init>
HSPLandroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda6;->call(Ljava/lang/Object;Ljava/lang/Object;Z)V
HSPLandroid/animation/Animator$AnimatorCaller;-><clinit>()V
HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$0(Landroid/animation/Animator$AnimatorListener;Landroid/animation/Animator;Z)V
-HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$4(Landroid/animation/ValueAnimator$AnimatorUpdateListener;Landroid/animation/ValueAnimator;Z)V
+HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$4(Landroid/animation/ValueAnimator$AnimatorUpdateListener;Landroid/animation/ValueAnimator;Z)V+]Landroid/animation/ValueAnimator$AnimatorUpdateListener;missing_types
HSPLandroid/animation/Animator$AnimatorConstantState;-><init>(Landroid/animation/Animator;)V
HSPLandroid/animation/Animator$AnimatorConstantState;->getChangingConfigurations()I
HSPLandroid/animation/Animator$AnimatorConstantState;->newInstance()Landroid/animation/Animator;
HSPLandroid/animation/Animator$AnimatorConstantState;->newInstance()Ljava/lang/Object;
-HSPLandroid/animation/Animator$AnimatorListener;->onAnimationEnd(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;megamorphic_types
-HSPLandroid/animation/Animator$AnimatorListener;->onAnimationStart(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;megamorphic_types
+HSPLandroid/animation/Animator$AnimatorListener;->onAnimationEnd(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;missing_types
+HSPLandroid/animation/Animator$AnimatorListener;->onAnimationStart(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;missing_types
HSPLandroid/animation/Animator;-><init>()V
-HSPLandroid/animation/Animator;->addListener(Landroid/animation/Animator$AnimatorListener;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/Animator;->addListener(Landroid/animation/Animator$AnimatorListener;)V
HSPLandroid/animation/Animator;->addPauseListener(Landroid/animation/Animator$AnimatorPauseListener;)V
HSPLandroid/animation/Animator;->appendChangingConfigurations(I)V
-HSPLandroid/animation/Animator;->callOnList(Ljava/util/ArrayList;Landroid/animation/Animator$AnimatorCaller;Ljava/lang/Object;Z)V+]Landroid/animation/Animator$AnimatorCaller;megamorphic_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/atomic/AtomicReference;
+HSPLandroid/animation/Animator;->callOnList(Ljava/util/ArrayList;Landroid/animation/Animator$AnimatorCaller;Ljava/lang/Object;Z)V+]Landroid/animation/Animator$AnimatorCaller;Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda1;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda0;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda6;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda2;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/atomic/AtomicReference;
HSPLandroid/animation/Animator;->clone()Landroid/animation/Animator;
HSPLandroid/animation/Animator;->createConstantState()Landroid/content/res/ConstantState;
HSPLandroid/animation/Animator;->getBackgroundPauseDelay()J
@@ -176,10 +177,10 @@ HSPLandroid/animation/Animator;->getListeners()Ljava/util/ArrayList;
HSPLandroid/animation/Animator;->getStartAndEndTimes(Landroid/util/LongArray;J)V
HSPLandroid/animation/Animator;->notifyEndListeners(Z)V
HSPLandroid/animation/Animator;->notifyListeners(Landroid/animation/Animator$AnimatorCaller;Z)V
-HSPLandroid/animation/Animator;->notifyStartListeners(Z)V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/Animator;->notifyStartListeners(Z)V
HSPLandroid/animation/Animator;->pause()V
HSPLandroid/animation/Animator;->removeAllListeners()V
-HSPLandroid/animation/Animator;->removeListener(Landroid/animation/Animator$AnimatorListener;)V
+HSPLandroid/animation/Animator;->removeListener(Landroid/animation/Animator$AnimatorListener;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/Animator;->setAllowRunningAsynchronously(Z)V
HSPLandroid/animation/AnimatorInflater$PathDataEvaluator;->evaluate(FLandroid/util/PathParser$PathData;Landroid/util/PathParser$PathData;)Landroid/util/PathParser$PathData;
HSPLandroid/animation/AnimatorInflater$PathDataEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
@@ -201,53 +202,53 @@ HSPLandroid/animation/AnimatorListenerAdapter;->onAnimationCancel(Landroid/anima
HSPLandroid/animation/AnimatorListenerAdapter;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorListenerAdapter;->onAnimationStart(Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorSet$1;-><init>(Landroid/animation/AnimatorSet;)V
-HSPLandroid/animation/AnimatorSet$1;->onAnimationEnd(Landroid/animation/Animator;)V
+HSPLandroid/animation/AnimatorSet$1;->onAnimationEnd(Landroid/animation/Animator;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
HSPLandroid/animation/AnimatorSet$2;-><init>(Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;)V
HSPLandroid/animation/AnimatorSet$2;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorSet$3;-><init>(Landroid/animation/AnimatorSet;)V
-HSPLandroid/animation/AnimatorSet$3;->compare(Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;)I
+HSPLandroid/animation/AnimatorSet$3;->compare(Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;)I+]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;
HSPLandroid/animation/AnimatorSet$3;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/animation/AnimatorSet$AnimationEvent;-><init>(Landroid/animation/AnimatorSet$Node;I)V
-HSPLandroid/animation/AnimatorSet$AnimationEvent;->getTime()J
+HSPLandroid/animation/AnimatorSet$AnimationEvent;->getTime()J+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
HSPLandroid/animation/AnimatorSet$Builder;-><init>(Landroid/animation/AnimatorSet;Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorSet$Builder;->after(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
HSPLandroid/animation/AnimatorSet$Builder;->before(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
HSPLandroid/animation/AnimatorSet$Builder;->with(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
HSPLandroid/animation/AnimatorSet$Node;-><init>(Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorSet$Node;->addChild(Landroid/animation/AnimatorSet$Node;)V
-HSPLandroid/animation/AnimatorSet$Node;->addParent(Landroid/animation/AnimatorSet$Node;)V
+HSPLandroid/animation/AnimatorSet$Node;->addParent(Landroid/animation/AnimatorSet$Node;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;
HSPLandroid/animation/AnimatorSet$Node;->addParents(Ljava/util/ArrayList;)V
-HSPLandroid/animation/AnimatorSet$Node;->addSibling(Landroid/animation/AnimatorSet$Node;)V
-HSPLandroid/animation/AnimatorSet$Node;->clone()Landroid/animation/AnimatorSet$Node;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet$Node;->addSibling(Landroid/animation/AnimatorSet$Node;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;
+HSPLandroid/animation/AnimatorSet$Node;->clone()Landroid/animation/AnimatorSet$Node;+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet$SeekState;-><init>(Landroid/animation/AnimatorSet;)V
HSPLandroid/animation/AnimatorSet$SeekState;->getPlayTimeNormalized()J
HSPLandroid/animation/AnimatorSet$SeekState;->isActive()Z
HSPLandroid/animation/AnimatorSet$SeekState;->reset()V
-HSPLandroid/animation/AnimatorSet;-><init>()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;-><init>()V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->addAnimationCallback(J)V
-HSPLandroid/animation/AnimatorSet;->addAnimationEndListener()V
+HSPLandroid/animation/AnimatorSet;->addAnimationEndListener()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->cancel()V
HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/Animator;
-HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/AnimatorSet;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/AnimatorSet;->createDependencyGraph()V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/AnimatorSet;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->createDependencyGraph()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->doAnimationFrame(J)Z+]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/animation/AnimatorSet;->end()V
-HSPLandroid/animation/AnimatorSet;->endAnimation()V
+HSPLandroid/animation/AnimatorSet;->end()V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
+HSPLandroid/animation/AnimatorSet;->endAnimation()V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/AnimatorSet;->ensureChildStartAndEndTimes()[J
HSPLandroid/animation/AnimatorSet;->findLatestEventIdForTime(J)I
HSPLandroid/animation/AnimatorSet;->findNextIndex(J[J)I
HSPLandroid/animation/AnimatorSet;->findSiblings(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V
HSPLandroid/animation/AnimatorSet;->getChangingConfigurations()I
-HSPLandroid/animation/AnimatorSet;->getChildAnimations()Ljava/util/ArrayList;
-HSPLandroid/animation/AnimatorSet;->getNodeForAnimation(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Node;
+HSPLandroid/animation/AnimatorSet;->getChildAnimations()Ljava/util/ArrayList;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->getNodeForAnimation(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Node;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/AnimatorSet;->getStartAndEndTimes(Landroid/util/LongArray;J)V
HSPLandroid/animation/AnimatorSet;->getStartDelay()J
HSPLandroid/animation/AnimatorSet;->getTotalDuration()J
-HSPLandroid/animation/AnimatorSet;->handleAnimationEvents(IIJ)V
-HSPLandroid/animation/AnimatorSet;->initAnimation()V
+HSPLandroid/animation/AnimatorSet;->handleAnimationEvents(IIJ)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->initAnimation()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->initChildren()V
-HSPLandroid/animation/AnimatorSet;->isEmptySet(Landroid/animation/AnimatorSet;)Z
-HSPLandroid/animation/AnimatorSet;->isInitialized()Z
+HSPLandroid/animation/AnimatorSet;->isEmptySet(Landroid/animation/AnimatorSet;)Z+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->isInitialized()Z+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->isRunning()Z
HSPLandroid/animation/AnimatorSet;->isStarted()Z
HSPLandroid/animation/AnimatorSet;->play(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
@@ -257,46 +258,46 @@ HSPLandroid/animation/AnimatorSet;->playTogether([Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorSet;->pulseAnimationFrame(J)Z
HSPLandroid/animation/AnimatorSet;->pulseFrame(Landroid/animation/AnimatorSet$Node;J)V
HSPLandroid/animation/AnimatorSet;->removeAnimationCallback()V
-HSPLandroid/animation/AnimatorSet;->removeAnimationEndListener()V
+HSPLandroid/animation/AnimatorSet;->removeAnimationEndListener()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->setDuration(J)Landroid/animation/Animator;
HSPLandroid/animation/AnimatorSet;->setDuration(J)Landroid/animation/AnimatorSet;
HSPLandroid/animation/AnimatorSet;->setInterpolator(Landroid/animation/TimeInterpolator;)V
HSPLandroid/animation/AnimatorSet;->setStartDelay(J)V
-HSPLandroid/animation/AnimatorSet;->setTarget(Ljava/lang/Object;)V
+HSPLandroid/animation/AnimatorSet;->setTarget(Ljava/lang/Object;)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/AnimatorSet;->shouldPlayTogether()Z
HSPLandroid/animation/AnimatorSet;->skipToEndValue(Z)V
-HSPLandroid/animation/AnimatorSet;->sortAnimationEvents()V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->sortAnimationEvents()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->start()V
-HSPLandroid/animation/AnimatorSet;->start(ZZ)V
-HSPLandroid/animation/AnimatorSet;->startAnimation()V
+HSPLandroid/animation/AnimatorSet;->start(ZZ)V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->startAnimation()V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->startWithoutPulsing(Z)V
-HSPLandroid/animation/AnimatorSet;->updateAnimatorsDuration()V
-HSPLandroid/animation/AnimatorSet;->updatePlayTime(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V
+HSPLandroid/animation/AnimatorSet;->updateAnimatorsDuration()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->updatePlayTime(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/ArgbEvaluator;-><init>()V
-HSPLandroid/animation/ArgbEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/lang/Integer;Ljava/lang/Integer;
+HSPLandroid/animation/ArgbEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/animation/ArgbEvaluator;->getInstance()Landroid/animation/ArgbEvaluator;
HSPLandroid/animation/FloatKeyframeSet;-><init>([Landroid/animation/Keyframe$FloatKeyframe;)V
HSPLandroid/animation/FloatKeyframeSet;->clone()Landroid/animation/FloatKeyframeSet;
HSPLandroid/animation/FloatKeyframeSet;->clone()Landroid/animation/Keyframes;
-HSPLandroid/animation/FloatKeyframeSet;->getFloatValue(F)F+]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/FloatKeyframeSet;->getFloatValue(F)F+]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;
HSPLandroid/animation/FloatKeyframeSet;->getValue(F)Ljava/lang/Object;
HSPLandroid/animation/IntKeyframeSet;-><init>([Landroid/animation/Keyframe$IntKeyframe;)V
-HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/IntKeyframeSet;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/IntKeyframeSet;+]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;
HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/Keyframes;
-HSPLandroid/animation/IntKeyframeSet;->getIntValue(F)I+]Landroid/animation/Keyframe$IntKeyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/IntKeyframeSet;->getIntValue(F)I
HSPLandroid/animation/Keyframe$FloatKeyframe;-><init>(F)V
HSPLandroid/animation/Keyframe$FloatKeyframe;-><init>(FF)V
HSPLandroid/animation/Keyframe$FloatKeyframe;->clone()Landroid/animation/Keyframe$FloatKeyframe;+]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;
HSPLandroid/animation/Keyframe$FloatKeyframe;->clone()Landroid/animation/Keyframe;
HSPLandroid/animation/Keyframe$FloatKeyframe;->getFloatValue()F
HSPLandroid/animation/Keyframe$FloatKeyframe;->getValue()Ljava/lang/Object;
-HSPLandroid/animation/Keyframe$FloatKeyframe;->setValue(Ljava/lang/Object;)V
+HSPLandroid/animation/Keyframe$FloatKeyframe;->setValue(Ljava/lang/Object;)V+]Ljava/lang/Object;Ljava/lang/Float;]Ljava/lang/Float;Ljava/lang/Float;
HSPLandroid/animation/Keyframe$IntKeyframe;-><init>(FI)V
-HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe$IntKeyframe;+]Landroid/animation/Keyframe$IntKeyframe;Landroid/animation/Keyframe$IntKeyframe;
+HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe$IntKeyframe;
HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe;
HSPLandroid/animation/Keyframe$IntKeyframe;->getIntValue()I
HSPLandroid/animation/Keyframe$IntKeyframe;->getValue()Ljava/lang/Object;
-HSPLandroid/animation/Keyframe$IntKeyframe;->setValue(Ljava/lang/Object;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Object;Ljava/lang/Integer;
+HSPLandroid/animation/Keyframe$IntKeyframe;->setValue(Ljava/lang/Object;)V
HSPLandroid/animation/Keyframe$ObjectKeyframe;-><init>(FLjava/lang/Object;)V
HSPLandroid/animation/Keyframe$ObjectKeyframe;->clone()Landroid/animation/Keyframe$ObjectKeyframe;
HSPLandroid/animation/Keyframe$ObjectKeyframe;->clone()Landroid/animation/Keyframe;
@@ -312,17 +313,17 @@ HSPLandroid/animation/Keyframe;->ofObject(FLjava/lang/Object;)Landroid/animation
HSPLandroid/animation/Keyframe;->setInterpolator(Landroid/animation/TimeInterpolator;)V
HSPLandroid/animation/Keyframe;->setValueWasSetOnStart(Z)V
HSPLandroid/animation/Keyframe;->valueWasSetOnStart()Z
-HSPLandroid/animation/KeyframeSet;-><init>([Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;
+HSPLandroid/animation/KeyframeSet;-><init>([Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$FloatKeyframe;
HSPLandroid/animation/KeyframeSet;->clone()Landroid/animation/KeyframeSet;
HSPLandroid/animation/KeyframeSet;->clone()Landroid/animation/Keyframes;
HSPLandroid/animation/KeyframeSet;->getKeyframes()Ljava/util/List;
-HSPLandroid/animation/KeyframeSet;->getValue(F)Ljava/lang/Object;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/TypeEvaluator;Landroid/animation/ArgbEvaluator;
+HSPLandroid/animation/KeyframeSet;->getValue(F)Ljava/lang/Object;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;
HSPLandroid/animation/KeyframeSet;->ofFloat([F)Landroid/animation/KeyframeSet;
HSPLandroid/animation/KeyframeSet;->ofInt([I)Landroid/animation/KeyframeSet;
HSPLandroid/animation/KeyframeSet;->ofObject([Ljava/lang/Object;)Landroid/animation/KeyframeSet;
HSPLandroid/animation/KeyframeSet;->setEvaluator(Landroid/animation/TypeEvaluator;)V
HSPLandroid/animation/LayoutTransition$1;->onAnimationEnd(Landroid/animation/Animator;)V
-HSPLandroid/animation/LayoutTransition$2;->onLayoutChange(Landroid/view/View;IIIIIIII)V+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/lang/Object;Ljava/lang/Integer;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;
+HSPLandroid/animation/LayoutTransition$2;->onLayoutChange(Landroid/view/View;IIIIIIII)V
HSPLandroid/animation/LayoutTransition$3;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/animation/LayoutTransition$3;->onAnimationStart(Landroid/animation/Animator;)V
HSPLandroid/animation/LayoutTransition$4;->onAnimationEnd(Landroid/animation/Animator;)V
@@ -350,20 +351,20 @@ HSPLandroid/animation/LayoutTransition;->setAnimator(ILandroid/animation/Animato
HSPLandroid/animation/LayoutTransition;->setDuration(J)V
HSPLandroid/animation/LayoutTransition;->setInterpolator(ILandroid/animation/TimeInterpolator;)V
HSPLandroid/animation/LayoutTransition;->setStartDelay(IJ)V
-HSPLandroid/animation/LayoutTransition;->setupChangeAnimation(Landroid/view/ViewGroup;ILandroid/animation/Animator;JLandroid/view/View;)V+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/view/View;missing_types]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/LayoutTransition;->setupChangeAnimation(Landroid/view/ViewGroup;ILandroid/animation/Animator;JLandroid/view/View;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/view/View;missing_types]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
HSPLandroid/animation/LayoutTransition;->showChild(Landroid/view/ViewGroup;Landroid/view/View;I)V
HSPLandroid/animation/LayoutTransition;->startChangingAnimations()V
HSPLandroid/animation/ObjectAnimator;-><init>()V
HSPLandroid/animation/ObjectAnimator;-><init>(Ljava/lang/Object;Landroid/util/Property;)V
HSPLandroid/animation/ObjectAnimator;-><init>(Ljava/lang/Object;Ljava/lang/String;)V
-HSPLandroid/animation/ObjectAnimator;->animateValue(F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ObjectAnimator;->animateValue(F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/ObjectAnimator;->clone()Landroid/animation/Animator;
HSPLandroid/animation/ObjectAnimator;->clone()Landroid/animation/ObjectAnimator;
-HSPLandroid/animation/ObjectAnimator;->getNameForTrace()Ljava/lang/String;+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/animation/ObjectAnimator;->getPropertyName()Ljava/lang/String;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/animation/ObjectAnimator;->getTarget()Ljava/lang/Object;+]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/animation/ObjectAnimator;->getNameForTrace()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;
+HSPLandroid/animation/ObjectAnimator;->getPropertyName()Ljava/lang/String;+]Landroid/util/Property;missing_types
+HSPLandroid/animation/ObjectAnimator;->getTarget()Ljava/lang/Object;
HSPLandroid/animation/ObjectAnimator;->hasSameTargetAndProperties(Landroid/animation/Animator;)Z
-HSPLandroid/animation/ObjectAnimator;->initAnimation()V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ObjectAnimator;->initAnimation()V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/ObjectAnimator;->isInitialized()Z
HSPLandroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Landroid/util/Property;[F)Landroid/animation/ObjectAnimator;
HSPLandroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Ljava/lang/String;[F)Landroid/animation/ObjectAnimator;
@@ -376,7 +377,7 @@ HSPLandroid/animation/ObjectAnimator;->setAutoCancel(Z)V
HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/Animator;
HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/ObjectAnimator;
HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ObjectAnimator;->setFloatValues([F)V
+HSPLandroid/animation/ObjectAnimator;->setFloatValues([F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;
HSPLandroid/animation/ObjectAnimator;->setIntValues([I)V
HSPLandroid/animation/ObjectAnimator;->setObjectValues([Ljava/lang/Object;)V
HSPLandroid/animation/ObjectAnimator;->setProperty(Landroid/util/Property;)V
@@ -402,50 +403,50 @@ HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->calculate
HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
-HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/util/FloatProperty;Landroid/view/View$12;,Landroid/view/View$13;]Landroid/util/Property;missing_types
+HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/util/FloatProperty;Landroid/view/View$2;,Landroid/view/View$12;,Landroid/view/View$13;,Landroid/view/View$5;
HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setFloatValues([F)V
HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setProperty(Landroid/util/Property;)V
-HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V
+HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Long;Ljava/lang/Long;
HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;-><init>(Ljava/lang/String;[I)V
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->calculateValue(F)V
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->calculateValue(F)V+]Landroid/animation/Keyframes$IntKeyframes;Landroid/animation/IntKeyframeSet;
HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V
HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setIntValues([I)V
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/lang/Long;Ljava/lang/Long;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Long;Ljava/lang/Long;
HSPLandroid/animation/PropertyValuesHolder$PropertyValues;-><init>()V
-HSPLandroid/animation/PropertyValuesHolder;-><init>(Landroid/util/Property;)V
+HSPLandroid/animation/PropertyValuesHolder;-><init>(Landroid/util/Property;)V+]Landroid/util/Property;missing_types
HSPLandroid/animation/PropertyValuesHolder;-><init>(Ljava/lang/String;)V
HSPLandroid/animation/PropertyValuesHolder;-><init>(Ljava/lang/String;Landroid/animation/PropertyValuesHolder-IA;)V
-HSPLandroid/animation/PropertyValuesHolder;->calculateValue(F)V
-HSPLandroid/animation/PropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->calculateValue(F)V+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/FloatKeyframeSet;
HSPLandroid/animation/PropertyValuesHolder;->convertBack(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/animation/PropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
HSPLandroid/animation/PropertyValuesHolder;->getMethodName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/animation/PropertyValuesHolder;->getPropertyFunction(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;
HSPLandroid/animation/PropertyValuesHolder;->getPropertyName()Ljava/lang/String;
-HSPLandroid/animation/PropertyValuesHolder;->getPropertyValues(Landroid/animation/PropertyValuesHolder$PropertyValues;)V+]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/PropertyValuesHolder;->getPropertyValues(Landroid/animation/PropertyValuesHolder$PropertyValues;)V
HSPLandroid/animation/PropertyValuesHolder;->getValueType()Ljava/lang/Class;
-HSPLandroid/animation/PropertyValuesHolder;->init()V+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->init()V
HSPLandroid/animation/PropertyValuesHolder;->ofFloat(Landroid/util/Property;[F)Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder;->ofFloat(Ljava/lang/String;[F)Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder;->ofInt(Ljava/lang/String;[I)Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder;->ofKeyframes(Ljava/lang/String;Landroid/animation/Keyframes;)Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder;->ofObject(Ljava/lang/String;Landroid/animation/TypeEvaluator;[Ljava/lang/Object;)Landroid/animation/PropertyValuesHolder;
-HSPLandroid/animation/PropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V
+HSPLandroid/animation/PropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder;->setEvaluator(Landroid/animation/TypeEvaluator;)V
HSPLandroid/animation/PropertyValuesHolder;->setFloatValues([F)V
HSPLandroid/animation/PropertyValuesHolder;->setIntValues([I)V
HSPLandroid/animation/PropertyValuesHolder;->setObjectValues([Ljava/lang/Object;)V
HSPLandroid/animation/PropertyValuesHolder;->setProperty(Landroid/util/Property;)V
HSPLandroid/animation/PropertyValuesHolder;->setPropertyName(Ljava/lang/String;)V
-HSPLandroid/animation/PropertyValuesHolder;->setupEndValue(Ljava/lang/Object;)V+]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/PropertyValuesHolder;->setupEndValue(Ljava/lang/Object;)V
HSPLandroid/animation/PropertyValuesHolder;->setupGetter(Ljava/lang/Class;)V
-HSPLandroid/animation/PropertyValuesHolder;->setupSetterAndGetter(Ljava/lang/Object;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/KeyframeSet;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
-HSPLandroid/animation/PropertyValuesHolder;->setupSetterOrGetter(Ljava/lang/Class;Ljava/util/HashMap;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;+]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/PropertyValuesHolder;->setupStartValue(Ljava/lang/Object;)V+]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
-HSPLandroid/animation/PropertyValuesHolder;->setupValue(Ljava/lang/Object;Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupSetterAndGetter(Ljava/lang/Object;)V+]Ljava/lang/Object;missing_types]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;,Landroid/animation/FloatKeyframeSet;,Landroid/animation/KeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;]Landroid/util/Property;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupSetterOrGetter(Ljava/lang/Class;Ljava/util/HashMap;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupStartValue(Ljava/lang/Object;)V
+HSPLandroid/animation/PropertyValuesHolder;->setupValue(Ljava/lang/Object;Landroid/animation/Keyframe;)V+]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;
HSPLandroid/animation/StateListAnimator$1;-><init>(Landroid/animation/StateListAnimator;)V
HSPLandroid/animation/StateListAnimator$1;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;-><init>(Landroid/animation/StateListAnimator;)V
@@ -453,10 +454,10 @@ HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;->newInst
HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;->newInstance()Ljava/lang/Object;
HSPLandroid/animation/StateListAnimator$Tuple;-><init>([ILandroid/animation/Animator;)V
HSPLandroid/animation/StateListAnimator;-><init>()V
-HSPLandroid/animation/StateListAnimator;->addState([ILandroid/animation/Animator;)V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/StateListAnimator;->addState([ILandroid/animation/Animator;)V
HSPLandroid/animation/StateListAnimator;->appendChangingConfigurations(I)V
HSPLandroid/animation/StateListAnimator;->clearTarget()V
-HSPLandroid/animation/StateListAnimator;->clone()Landroid/animation/StateListAnimator;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/StateListAnimator;->clone()Landroid/animation/StateListAnimator;
HSPLandroid/animation/StateListAnimator;->createConstantState()Landroid/content/res/ConstantState;
HSPLandroid/animation/StateListAnimator;->getChangingConfigurations()I
HSPLandroid/animation/StateListAnimator;->getTarget()Landroid/view/View;
@@ -472,17 +473,17 @@ HSPLandroid/animation/ValueAnimator;-><init>()V
HSPLandroid/animation/ValueAnimator;->addAnimationCallback(J)V
HSPLandroid/animation/ValueAnimator;->addUpdateListener(Landroid/animation/ValueAnimator$AnimatorUpdateListener;)V
HSPLandroid/animation/ValueAnimator;->animateBasedOnTime(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ValueAnimator;->animateValue(F)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Landroid/animation/TimeInterpolator;missing_types]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->animateValue(F)V+]Landroid/animation/TimeInterpolator;missing_types]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;,Landroid/animation/ObjectAnimator;
HSPLandroid/animation/ValueAnimator;->areAnimatorsEnabled()Z
HSPLandroid/animation/ValueAnimator;->cancel()V
HSPLandroid/animation/ValueAnimator;->clampFraction(F)F
HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/Animator;
-HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/ValueAnimator;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/ValueAnimator;->doAnimationFrame(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/ValueAnimator;+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ValueAnimator;->doAnimationFrame(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;,Landroid/animation/ObjectAnimator;
HSPLandroid/animation/ValueAnimator;->end()V
-HSPLandroid/animation/ValueAnimator;->endAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->endAnimation()V
HSPLandroid/animation/ValueAnimator;->getAnimatedFraction()F
-HSPLandroid/animation/ValueAnimator;->getAnimatedValue()Ljava/lang/Object;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ValueAnimator;->getAnimatedValue()Ljava/lang/Object;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;
HSPLandroid/animation/ValueAnimator;->getAnimationHandler()Landroid/animation/AnimationHandler;
HSPLandroid/animation/ValueAnimator;->getCurrentAnimationsCount()I
HSPLandroid/animation/ValueAnimator;->getCurrentIteration(F)I
@@ -513,25 +514,25 @@ HSPLandroid/animation/ValueAnimator;->removeAnimationCallback()V
HSPLandroid/animation/ValueAnimator;->resolveDurationScale()F
HSPLandroid/animation/ValueAnimator;->setAllowRunningAsynchronously(Z)V
HSPLandroid/animation/ValueAnimator;->setAnimationHandler(Landroid/animation/AnimationHandler;)V
-HSPLandroid/animation/ValueAnimator;->setCurrentFraction(F)V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->setCurrentFraction(F)V
HSPLandroid/animation/ValueAnimator;->setCurrentPlayTime(J)V
HSPLandroid/animation/ValueAnimator;->setDuration(J)Landroid/animation/Animator;
HSPLandroid/animation/ValueAnimator;->setDuration(J)Landroid/animation/ValueAnimator;
HSPLandroid/animation/ValueAnimator;->setDurationScale(F)V
HSPLandroid/animation/ValueAnimator;->setEvaluator(Landroid/animation/TypeEvaluator;)V
-HSPLandroid/animation/ValueAnimator;->setFloatValues([F)V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->setFloatValues([F)V
HSPLandroid/animation/ValueAnimator;->setIntValues([I)V
HSPLandroid/animation/ValueAnimator;->setInterpolator(Landroid/animation/TimeInterpolator;)V
HSPLandroid/animation/ValueAnimator;->setObjectValues([Ljava/lang/Object;)V
HSPLandroid/animation/ValueAnimator;->setRepeatCount(I)V
HSPLandroid/animation/ValueAnimator;->setRepeatMode(I)V
HSPLandroid/animation/ValueAnimator;->setStartDelay(J)V
-HSPLandroid/animation/ValueAnimator;->setValues([Landroid/animation/PropertyValuesHolder;)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/ValueAnimator;->setValues([Landroid/animation/PropertyValuesHolder;)V
HSPLandroid/animation/ValueAnimator;->shouldPlayBackward(IZ)Z
HSPLandroid/animation/ValueAnimator;->skipToEndValue(Z)V
HSPLandroid/animation/ValueAnimator;->start()V
-HSPLandroid/animation/ValueAnimator;->start(Z)V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ValueAnimator;->startAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->start(Z)V
+HSPLandroid/animation/ValueAnimator;->startAnimation()V
HSPLandroid/animation/ValueAnimator;->startWithoutPulsing(Z)V
HSPLandroid/app/Activity$1;-><init>(Landroid/app/Activity;)V
HSPLandroid/app/Activity$1;->isTaskRoot()Z
@@ -545,7 +546,7 @@ HSPLandroid/app/Activity;-><init>()V
HSPLandroid/app/Activity;->attach(Landroid/content/Context;Landroid/app/ActivityThread;Landroid/app/Instrumentation;Landroid/os/IBinder;ILandroid/app/Application;Landroid/content/Intent;Landroid/content/pm/ActivityInfo;Ljava/lang/CharSequence;Landroid/app/Activity;Ljava/lang/String;Landroid/app/Activity$NonConfigurationInstances;Landroid/content/res/Configuration;Ljava/lang/String;Lcom/android/internal/app/IVoiceInteractor;Landroid/view/Window;Landroid/view/ViewRootImpl$ActivityConfigCallback;Landroid/os/IBinder;Landroid/os/IBinder;)V
HSPLandroid/app/Activity;->attachBaseContext(Landroid/content/Context;)V
HSPLandroid/app/Activity;->cancelInputsAndStartExitTransition(Landroid/os/Bundle;)V
-HSPLandroid/app/Activity;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/Activity;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;
HSPLandroid/app/Activity;->dispatchActivityCreated(Landroid/os/Bundle;)V
HSPLandroid/app/Activity;->dispatchActivityPostCreated(Landroid/os/Bundle;)V
HSPLandroid/app/Activity;->dispatchActivityPostResumed()V
@@ -608,7 +609,7 @@ HSPLandroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
HSPLandroid/app/Activity;->onCreateDescription()Ljava/lang/CharSequence;
HSPLandroid/app/Activity;->onCreateOptionsMenu(Landroid/view/Menu;)Z
HSPLandroid/app/Activity;->onCreatePanelMenu(ILandroid/view/Menu;)Z
-HSPLandroid/app/Activity;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;+]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/app/Activity;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/app/Activity;->onCreateView(Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/app/Activity;->onDestroy()V
HSPLandroid/app/Activity;->onDetachedFromWindow()V
@@ -639,7 +640,7 @@ HSPLandroid/app/Activity;->onTouchEvent(Landroid/view/MotionEvent;)Z
HSPLandroid/app/Activity;->onTrimMemory(I)V
HSPLandroid/app/Activity;->onUserInteraction()V
HSPLandroid/app/Activity;->onUserLeaveHint()V
-HSPLandroid/app/Activity;->onWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V
+HSPLandroid/app/Activity;->onWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/WindowManager;Landroid/view/WindowManagerImpl;
HSPLandroid/app/Activity;->onWindowFocusChanged(Z)V
HSPLandroid/app/Activity;->overridePendingTransition(II)V
HSPLandroid/app/Activity;->overridePendingTransition(III)V
@@ -689,10 +690,10 @@ HSPLandroid/app/ActivityClient;->activityResumed(Landroid/os/IBinder;Z)V
HSPLandroid/app/ActivityClient;->activityStopped(Landroid/os/IBinder;Landroid/os/Bundle;Landroid/os/PersistableBundle;Ljava/lang/CharSequence;)V
HSPLandroid/app/ActivityClient;->activityTopResumedStateLost()V
HSPLandroid/app/ActivityClient;->finishActivity(Landroid/os/IBinder;ILandroid/content/Intent;I)Z
-HSPLandroid/app/ActivityClient;->getActivityClientController()Landroid/app/IActivityClientController;+]Landroid/app/ActivityClient$ActivityClientControllerSingleton;Landroid/app/ActivityClient$ActivityClientControllerSingleton;
+HSPLandroid/app/ActivityClient;->getActivityClientController()Landroid/app/IActivityClientController;
HSPLandroid/app/ActivityClient;->getCallingActivity(Landroid/os/IBinder;)Landroid/content/ComponentName;
HSPLandroid/app/ActivityClient;->getDisplayId(Landroid/os/IBinder;)I
-HSPLandroid/app/ActivityClient;->getInstance()Landroid/app/ActivityClient;+]Landroid/util/Singleton;Landroid/app/ActivityClient$1;
+HSPLandroid/app/ActivityClient;->getInstance()Landroid/app/ActivityClient;
HSPLandroid/app/ActivityClient;->getTaskForActivity(Landroid/os/IBinder;Z)I
HSPLandroid/app/ActivityClient;->overridePendingTransition(Landroid/os/IBinder;Ljava/lang/String;III)V
HSPLandroid/app/ActivityClient;->reportActivityFullyDrawn(Landroid/os/IBinder;Z)V
@@ -868,7 +869,7 @@ HSPLandroid/app/ActivityThread$DumpResourcesData;-><init>()V
HSPLandroid/app/ActivityThread$GcIdler;-><init>(Landroid/app/ActivityThread;)V
HSPLandroid/app/ActivityThread$GcIdler;->queueIdle()Z
HSPLandroid/app/ActivityThread$H;-><init>(Landroid/app/ActivityThread;)V
-HSPLandroid/app/ActivityThread$H;->handleMessage(Landroid/os/Message;)V
+HSPLandroid/app/ActivityThread$H;->handleMessage(Landroid/os/Message;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/servertransaction/TransactionExecutor;Landroid/app/servertransaction/TransactionExecutor;
HSPLandroid/app/ActivityThread$Idler;-><init>(Landroid/app/ActivityThread;)V
HSPLandroid/app/ActivityThread$Idler;-><init>(Landroid/app/ActivityThread;Landroid/app/ActivityThread$Idler-IA;)V
HSPLandroid/app/ActivityThread$Idler;->queueIdle()Z
@@ -924,8 +925,8 @@ HSPLandroid/app/ActivityThread;->deliverNewIntents(Landroid/app/ActivityThread$A
HSPLandroid/app/ActivityThread;->deliverResults(Landroid/app/ActivityThread$ActivityClientRecord;Ljava/util/List;Ljava/lang/String;)V
HSPLandroid/app/ActivityThread;->dumpMemoryInfo(Landroid/util/proto/ProtoOutputStream;JLjava/lang/String;IIIIIIZIII)V
HSPLandroid/app/ActivityThread;->getActivitiesToBeDestroyed()Ljava/util/Map;
-HSPLandroid/app/ActivityThread;->getActivity(Landroid/os/IBinder;)Landroid/app/Activity;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
-HSPLandroid/app/ActivityThread;->getActivityClient(Landroid/os/IBinder;)Landroid/app/ActivityThread$ActivityClientRecord;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/app/ActivityThread;->getActivity(Landroid/os/IBinder;)Landroid/app/Activity;
+HSPLandroid/app/ActivityThread;->getActivityClient(Landroid/os/IBinder;)Landroid/app/ActivityThread$ActivityClientRecord;
HSPLandroid/app/ActivityThread;->getApplication()Landroid/app/Application;
HSPLandroid/app/ActivityThread;->getApplicationThread()Landroid/app/ActivityThread$ApplicationThread;
HSPLandroid/app/ActivityThread;->getBackupAgentName(Landroid/app/ActivityThread$CreateBackupAgentData;)Ljava/lang/String;
@@ -935,7 +936,7 @@ HSPLandroid/app/ActivityThread;->getFloatCoreSetting(Ljava/lang/String;F)F
HSPLandroid/app/ActivityThread;->getGetProviderKey(Ljava/lang/String;I)Landroid/app/ActivityThread$ProviderKey;
HSPLandroid/app/ActivityThread;->getHandler()Landroid/os/Handler;
HSPLandroid/app/ActivityThread;->getInstrumentation()Landroid/app/Instrumentation;
-HSPLandroid/app/ActivityThread;->getIntCoreSetting(Ljava/lang/String;I)I
+HSPLandroid/app/ActivityThread;->getIntCoreSetting(Ljava/lang/String;I)I+]Landroid/os/Bundle;Landroid/os/Bundle;
HSPLandroid/app/ActivityThread;->getIntentBeingBroadcast()Landroid/content/Intent;
HSPLandroid/app/ActivityThread;->getLooper()Landroid/os/Looper;
HSPLandroid/app/ActivityThread;->getOperationTypeFromBackupMode(I)I
@@ -957,7 +958,7 @@ HSPLandroid/app/ActivityThread;->handleBindApplication(Landroid/app/ActivityThre
HSPLandroid/app/ActivityThread;->handleBindService(Landroid/app/ActivityThread$BindServiceData;)V
HSPLandroid/app/ActivityThread;->handleConfigurationChanged(Landroid/content/res/Configuration;I)V
HSPLandroid/app/ActivityThread;->handleCreateBackupAgent(Landroid/app/ActivityThread$CreateBackupAgentData;)V
-HSPLandroid/app/ActivityThread;->handleCreateService(Landroid/app/ActivityThread$CreateServiceData;)V
+HSPLandroid/app/ActivityThread;->handleCreateService(Landroid/app/ActivityThread$CreateServiceData;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Ljava/util/List;Ljava/util/Collections$EmptyList;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;
HSPLandroid/app/ActivityThread;->handleDestroyBackupAgent(Landroid/app/ActivityThread$CreateBackupAgentData;)V
HSPLandroid/app/ActivityThread;->handleDispatchPackageBroadcast(I[Ljava/lang/String;)V
HSPLandroid/app/ActivityThread;->handleDumpGfxInfo(Landroid/app/ActivityThread$DumpComponentInfo;)V
@@ -997,10 +998,11 @@ HSPLandroid/app/ActivityThread;->isProtectedComponent(Landroid/content/pm/Activi
HSPLandroid/app/ActivityThread;->isProtectedComponent(Landroid/content/pm/ComponentInfo;Ljava/lang/String;)Z
HSPLandroid/app/ActivityThread;->isProtectedComponent(Landroid/content/pm/ServiceInfo;)Z
HSPLandroid/app/ActivityThread;->isSystem()Z
+HSPLandroid/app/ActivityThread;->lambda$getGetProviderKey$3(Landroid/app/ActivityThread$ProviderKey;)Landroid/app/ActivityThread$ProviderKey;
HSPLandroid/app/ActivityThread;->main([Ljava/lang/String;)V
HSPLandroid/app/ActivityThread;->onCoreSettingsChange()V
HSPLandroid/app/ActivityThread;->peekPackageInfo(Ljava/lang/String;Z)Landroid/app/LoadedApk;
-HSPLandroid/app/ActivityThread;->performLaunchActivity(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/content/Intent;)Landroid/app/Activity;+]Landroid/app/ActivityThread$ActivityClientRecord;Landroid/app/ActivityThread$ActivityClientRecord;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ConfigurationController;Landroid/app/ConfigurationController;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/Instrumentation;Landroid/app/Instrumentation;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/ComponentName;Landroid/content/ComponentName;]Landroid/content/Intent;Landroid/content/Intent;]Landroid/content/pm/ActivityInfo;Landroid/content/pm/ActivityInfo;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/app/ActivityThread;->performLaunchActivity(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/content/Intent;)Landroid/app/Activity;
HSPLandroid/app/ActivityThread;->performPauseActivity(Landroid/app/ActivityThread$ActivityClientRecord;ZLjava/lang/String;Landroid/app/servertransaction/PendingTransactionActions;)Landroid/os/Bundle;
HSPLandroid/app/ActivityThread;->performPauseActivityIfNeeded(Landroid/app/ActivityThread$ActivityClientRecord;Ljava/lang/String;)V
HSPLandroid/app/ActivityThread;->performRestartActivity(Landroid/app/ActivityThread$ActivityClientRecord;Z)V
@@ -1071,7 +1073,7 @@ HSPLandroid/app/AppComponentFactory;->instantiateProvider(Ljava/lang/ClassLoader
HSPLandroid/app/AppComponentFactory;->instantiateReceiver(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Intent;)Landroid/content/BroadcastReceiver;
HSPLandroid/app/AppComponentFactory;->instantiateService(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Intent;)Landroid/app/Service;
HSPLandroid/app/AppGlobals;->getInitialApplication()Landroid/app/Application;
-HSPLandroid/app/AppGlobals;->getIntCoreSetting(Ljava/lang/String;I)I
+HSPLandroid/app/AppGlobals;->getIntCoreSetting(Ljava/lang/String;I)I+]Landroid/app/ActivityThread;Landroid/app/ActivityThread;
HSPLandroid/app/AppGlobals;->getPackageManager()Landroid/content/pm/IPackageManager;
HSPLandroid/app/AppOpsManager$1;->onNoted(Landroid/app/SyncNotedAppOp;)V
HSPLandroid/app/AppOpsManager$1;->onSelfNoted(Landroid/app/SyncNotedAppOp;)V
@@ -1164,7 +1166,7 @@ HSPLandroid/app/Application$ActivityLifecycleCallbacks;->onActivityPreStarted(La
HSPLandroid/app/Application$ActivityLifecycleCallbacks;->onActivityPreStopped(Landroid/app/Activity;)V
HSPLandroid/app/Application;-><init>()V
HSPLandroid/app/Application;->attach(Landroid/content/Context;)V
-HSPLandroid/app/Application;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/Application;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;
HSPLandroid/app/Application;->dispatchActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
HSPLandroid/app/Application;->dispatchActivityDestroyed(Landroid/app/Activity;)V
HSPLandroid/app/Application;->dispatchActivityPaused(Landroid/app/Activity;)V
@@ -1264,7 +1266,7 @@ HSPLandroid/app/ApplicationPackageManager;->getInstalledPackages(Landroid/conten
HSPLandroid/app/ApplicationPackageManager;->getInstalledPackagesAsUser(II)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->getInstalledPackagesAsUser(Landroid/content/pm/PackageManager$PackageInfoFlags;I)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/app/ApplicationPackageManager;->getLaunchIntentForPackage(Ljava/lang/String;)Landroid/content/Intent;+]Landroid/app/ApplicationPackageManager;Landroid/app/ApplicationPackageManager;]Landroid/content/Intent;Landroid/content/Intent;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/ApplicationPackageManager;->getLaunchIntentForPackage(Ljava/lang/String;)Landroid/content/Intent;+]Ljava/util/List;Ljava/util/ArrayList;]Landroid/app/ApplicationPackageManager;Landroid/app/ApplicationPackageManager;]Landroid/content/Intent;Landroid/content/Intent;
HSPLandroid/app/ApplicationPackageManager;->getModuleInfo(Ljava/lang/String;I)Landroid/content/pm/ModuleInfo;
HSPLandroid/app/ApplicationPackageManager;->getNameForUid(I)Ljava/lang/String;
HSPLandroid/app/ApplicationPackageManager;->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;
@@ -1288,7 +1290,7 @@ HSPLandroid/app/ApplicationPackageManager;->getProviderInfo(Landroid/content/Com
HSPLandroid/app/ApplicationPackageManager;->getReceiverInfo(Landroid/content/ComponentName;I)Landroid/content/pm/ActivityInfo;
HSPLandroid/app/ApplicationPackageManager;->getReceiverInfo(Landroid/content/ComponentName;Landroid/content/pm/PackageManager$ComponentInfoFlags;)Landroid/content/pm/ActivityInfo;
HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;)Landroid/content/res/Resources;
-HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;Landroid/content/res/Configuration;)Landroid/content/res/Resources;
+HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;Landroid/content/res/Configuration;)Landroid/content/res/Resources;+]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Ljava/lang/Object;Ljava/lang/String;
HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Ljava/lang/String;)Landroid/content/res/Resources;
HSPLandroid/app/ApplicationPackageManager;->getServiceInfo(Landroid/content/ComponentName;I)Landroid/content/pm/ServiceInfo;
HSPLandroid/app/ApplicationPackageManager;->getServiceInfo(Landroid/content/ComponentName;Landroid/content/pm/PackageManager$ComponentInfoFlags;)Landroid/content/pm/ServiceInfo;
@@ -1298,7 +1300,7 @@ HSPLandroid/app/ApplicationPackageManager;->getSystemSharedLibraryNames()[Ljava/
HSPLandroid/app/ApplicationPackageManager;->getText(Ljava/lang/String;ILandroid/content/pm/ApplicationInfo;)Ljava/lang/CharSequence;
HSPLandroid/app/ApplicationPackageManager;->getUserBadgeColor(Landroid/os/UserHandle;Z)I
HSPLandroid/app/ApplicationPackageManager;->getUserBadgedIcon(Landroid/graphics/drawable/Drawable;Landroid/os/UserHandle;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/app/ApplicationPackageManager;->getUserId()I
+HSPLandroid/app/ApplicationPackageManager;->getUserId()I+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
HSPLandroid/app/ApplicationPackageManager;->getUserManager()Landroid/os/UserManager;
HSPLandroid/app/ApplicationPackageManager;->getXml(Ljava/lang/String;ILandroid/content/pm/ApplicationInfo;)Landroid/content/res/XmlResourceParser;
HSPLandroid/app/ApplicationPackageManager;->handlePackageBroadcast(I[Ljava/lang/String;Z)V
@@ -1323,7 +1325,7 @@ HSPLandroid/app/ApplicationPackageManager;->queryBroadcastReceiversAsUser(Landro
HSPLandroid/app/ApplicationPackageManager;->queryIntentActivities(Landroid/content/Intent;I)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->queryIntentActivities(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;II)Ljava/util/List;
-HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;I)Ljava/util/List;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/Intent;Landroid/content/Intent;]Landroid/content/pm/IPackageManager;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/content/pm/PackageManager$ResolveInfoFlags;Landroid/content/pm/PackageManager$ResolveInfoFlags;]Landroid/content/pm/ParceledListSlice;Landroid/content/pm/ParceledListSlice;
+HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;I)Ljava/util/List;+]Landroid/content/pm/IPackageManager;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/pm/PackageManager$ResolveInfoFlags;Landroid/content/pm/PackageManager$ResolveInfoFlags;]Landroid/content/pm/ParceledListSlice;Landroid/content/pm/ParceledListSlice;]Landroid/content/Intent;Landroid/content/Intent;
HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProviders(Landroid/content/Intent;I)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProviders(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProvidersAsUser(Landroid/content/Intent;II)Ljava/util/List;
@@ -1411,7 +1413,7 @@ HSPLandroid/app/ContextImpl$ApplicationContentResolver;->releaseProvider(Landroi
HSPLandroid/app/ContextImpl$ApplicationContentResolver;->releaseUnstableProvider(Landroid/content/IContentProvider;)Z
HSPLandroid/app/ContextImpl$ApplicationContentResolver;->resolveUserIdFromAuthority(Ljava/lang/String;)I
HSPLandroid/app/ContextImpl$ApplicationContentResolver;->unstableProviderDied(Landroid/content/IContentProvider;)V
-HSPLandroid/app/ContextImpl;-><init>(Landroid/app/ContextImpl;Landroid/app/ActivityThread;Landroid/app/LoadedApk;Landroid/content/ContextParams;Ljava/lang/String;Landroid/content/AttributionSource;Ljava/lang/String;Landroid/os/IBinder;Landroid/os/UserHandle;ILjava/lang/ClassLoader;Ljava/lang/String;IZ)V+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/content/ContextParams;Landroid/content/ContextParams;
+HSPLandroid/app/ContextImpl;-><init>(Landroid/app/ContextImpl;Landroid/app/ActivityThread;Landroid/app/LoadedApk;Landroid/content/ContextParams;Ljava/lang/String;Landroid/content/AttributionSource;Ljava/lang/String;Landroid/os/IBinder;Landroid/os/UserHandle;ILjava/lang/ClassLoader;Ljava/lang/String;IZ)V+]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/ContextParams;Landroid/content/ContextParams;
HSPLandroid/app/ContextImpl;->bindIsolatedService(Landroid/content/Intent;ILjava/lang/String;Ljava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z
HSPLandroid/app/ContextImpl;->bindService(Landroid/content/Intent;Landroid/content/ServiceConnection;I)Z
HSPLandroid/app/ContextImpl;->bindServiceAsUser(Landroid/content/Intent;Landroid/content/ServiceConnection;ILandroid/os/Handler;Landroid/os/UserHandle;)Z
@@ -1431,7 +1433,7 @@ HSPLandroid/app/ContextImpl;->createAppContext(Landroid/app/ActivityThread;Landr
HSPLandroid/app/ContextImpl;->createAppContext(Landroid/app/ActivityThread;Landroid/app/LoadedApk;Ljava/lang/String;)Landroid/app/ContextImpl;
HSPLandroid/app/ContextImpl;->createApplicationContext(Landroid/content/pm/ApplicationInfo;I)Landroid/content/Context;
HSPLandroid/app/ContextImpl;->createAttributionContext(Ljava/lang/String;)Landroid/content/Context;
-HSPLandroid/app/ContextImpl;->createAttributionSource(Ljava/lang/String;Landroid/content/AttributionSource;Ljava/util/Set;ZI)Landroid/content/AttributionSource;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/permission/PermissionManager;Landroid/permission/PermissionManager;]Ljava/util/Set;missing_types
+HSPLandroid/app/ContextImpl;->createAttributionSource(Ljava/lang/String;Landroid/content/AttributionSource;Ljava/util/Set;ZI)Landroid/content/AttributionSource;+]Ljava/util/Set;missing_types]Landroid/permission/PermissionManager;Landroid/permission/PermissionManager;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
HSPLandroid/app/ContextImpl;->createConfigurationContext(Landroid/content/res/Configuration;)Landroid/content/Context;
HSPLandroid/app/ContextImpl;->createContext(Landroid/content/ContextParams;)Landroid/content/Context;
HSPLandroid/app/ContextImpl;->createContextAsUser(Landroid/os/UserHandle;I)Landroid/content/Context;
@@ -1510,11 +1512,11 @@ HSPLandroid/app/ContextImpl;->getPackageResourcePath()Ljava/lang/String;
HSPLandroid/app/ContextImpl;->getPreferencesDir()Ljava/io/File;
HSPLandroid/app/ContextImpl;->getReceiverRestrictedContext()Landroid/content/Context;
HSPLandroid/app/ContextImpl;->getResources()Landroid/content/res/Resources;
-HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/io/File;I)Landroid/content/SharedPreferences;
-HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
-HSPLandroid/app/ContextImpl;->getSharedPreferencesCacheLocked()Landroid/util/ArrayMap;
+HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/io/File;I)Landroid/content/SharedPreferences;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
+HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
+HSPLandroid/app/ContextImpl;->getSharedPreferencesCacheLocked()Landroid/util/ArrayMap;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
HSPLandroid/app/ContextImpl;->getSharedPreferencesPath(Ljava/lang/String;)Ljava/io/File;
-HSPLandroid/app/ContextImpl;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/app/ContextImpl;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
HSPLandroid/app/ContextImpl;->getSystemServiceName(Ljava/lang/Class;)Ljava/lang/String;
HSPLandroid/app/ContextImpl;->getTheme()Landroid/content/res/Resources$Theme;
HSPLandroid/app/ContextImpl;->getThemeResId()I
@@ -1733,13 +1735,13 @@ HSPLandroid/app/FragmentManagerImpl;->addAddedFragments(Landroid/util/ArraySet;)
HSPLandroid/app/FragmentManagerImpl;->addFragment(Landroid/app/Fragment;Z)V
HSPLandroid/app/FragmentManagerImpl;->attachController(Landroid/app/FragmentHostCallback;Landroid/app/FragmentContainer;Landroid/app/Fragment;)V
HSPLandroid/app/FragmentManagerImpl;->beginTransaction()Landroid/app/FragmentTransaction;
-HSPLandroid/app/FragmentManagerImpl;->burpActive()V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/app/FragmentManagerImpl;->burpActive()V
HSPLandroid/app/FragmentManagerImpl;->checkStateLoss()V
HSPLandroid/app/FragmentManagerImpl;->cleanupExec()V
HSPLandroid/app/FragmentManagerImpl;->dispatchActivityCreated()V
HSPLandroid/app/FragmentManagerImpl;->dispatchCreate()V
HSPLandroid/app/FragmentManagerImpl;->dispatchCreateOptionsMenu(Landroid/view/Menu;Landroid/view/MenuInflater;)Z
-HSPLandroid/app/FragmentManagerImpl;->dispatchMoveToState(I)V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;
+HSPLandroid/app/FragmentManagerImpl;->dispatchMoveToState(I)V
HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentActivityCreated(Landroid/app/Fragment;Landroid/os/Bundle;Z)V
HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentAttached(Landroid/app/Fragment;Landroid/content/Context;Z)V
HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentCreated(Landroid/app/Fragment;Landroid/os/Bundle;Z)V
@@ -1762,9 +1764,9 @@ HSPLandroid/app/FragmentManagerImpl;->dispatchStop()V
HSPLandroid/app/FragmentManagerImpl;->doPendingDeferredStart()V
HSPLandroid/app/FragmentManagerImpl;->endAnimatingAwayFragments()V
HSPLandroid/app/FragmentManagerImpl;->enqueueAction(Landroid/app/FragmentManagerImpl$OpGenerator;Z)V
-HSPLandroid/app/FragmentManagerImpl;->ensureExecReady(Z)V+]Landroid/app/FragmentHostCallback;Landroid/app/Activity$HostCallbacks;]Landroid/os/Handler;Landroid/os/Handler;
+HSPLandroid/app/FragmentManagerImpl;->ensureExecReady(Z)V
HSPLandroid/app/FragmentManagerImpl;->ensureInflatedFragmentView(Landroid/app/Fragment;)V
-HSPLandroid/app/FragmentManagerImpl;->execPendingActions()Z+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;
+HSPLandroid/app/FragmentManagerImpl;->execPendingActions()Z
HSPLandroid/app/FragmentManagerImpl;->executeOps(Ljava/util/ArrayList;Ljava/util/ArrayList;II)V
HSPLandroid/app/FragmentManagerImpl;->executeOpsTogether(Ljava/util/ArrayList;Ljava/util/ArrayList;II)V
HSPLandroid/app/FragmentManagerImpl;->executePendingTransactions()Z
@@ -1782,9 +1784,9 @@ HSPLandroid/app/FragmentManagerImpl;->makeActive(Landroid/app/Fragment;)V
HSPLandroid/app/FragmentManagerImpl;->makeInactive(Landroid/app/Fragment;)V
HSPLandroid/app/FragmentManagerImpl;->makeRemovedFragmentsInvisible(Landroid/util/ArraySet;)V
HSPLandroid/app/FragmentManagerImpl;->moveFragmentToExpectedState(Landroid/app/Fragment;)V
-HSPLandroid/app/FragmentManagerImpl;->moveToState(IZ)V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/FragmentManagerImpl;->moveToState(IZ)V
HSPLandroid/app/FragmentManagerImpl;->moveToState(Landroid/app/Fragment;IIIZ)V
-HSPLandroid/app/FragmentManagerImpl;->noteStateNotSaved()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/FragmentManagerImpl;->noteStateNotSaved()V
HSPLandroid/app/FragmentManagerImpl;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/app/FragmentManagerImpl;->performPendingDeferredStart(Landroid/app/Fragment;)V
HSPLandroid/app/FragmentManagerImpl;->popBackStackImmediate()Z
@@ -1798,7 +1800,7 @@ HSPLandroid/app/FragmentManagerImpl;->saveFragmentBasicState(Landroid/app/Fragme
HSPLandroid/app/FragmentManagerImpl;->saveNonConfig()V
HSPLandroid/app/FragmentManagerImpl;->scheduleCommit()V
HSPLandroid/app/FragmentManagerImpl;->setRetaining(Landroid/app/FragmentManagerNonConfig;)V
-HSPLandroid/app/FragmentManagerImpl;->startPendingDeferredFragments()V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/app/FragmentManagerImpl;->startPendingDeferredFragments()V
HSPLandroid/app/FragmentManagerState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/FragmentManagerState;
HSPLandroid/app/FragmentManagerState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/app/FragmentManagerState;-><init>(Landroid/os/Parcel;)V
@@ -1841,11 +1843,12 @@ HSPLandroid/app/IActivityManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/app/IActivityManager$Stub$Proxy;->attachApplication(Landroid/app/IApplicationThread;J)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->backupAgentCreated(Ljava/lang/String;Landroid/os/IBinder;I)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->bindServiceInstance(Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/content/Intent;Ljava/lang/String;Landroid/app/IServiceConnection;JLjava/lang/String;Ljava/lang/String;I)I
-HSPLandroid/app/IActivityManager$Stub$Proxy;->broadcastIntentWithFeature(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->broadcastIntentWithFeature(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I
HSPLandroid/app/IActivityManager$Stub$Proxy;->cancelIntentSender(Landroid/content/IIntentSender;)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermission(Ljava/lang/String;II)I
-HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermissionForDevice(Ljava/lang/String;III)I+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermissionForDevice(Ljava/lang/String;III)I+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/IActivityManager$Stub$Proxy;->checkUriPermission(Landroid/net/Uri;IIIILandroid/os/IBinder;)I
+HSPLandroid/app/IActivityManager$Stub$Proxy;->finishAttachApplication(J)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->finishReceiver(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/Bundle;ZI)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->getContentProvider(Landroid/app/IApplicationThread;Ljava/lang/String;Ljava/lang/String;IZ)Landroid/app/ContentProviderHolder;
HSPLandroid/app/IActivityManager$Stub$Proxy;->getCurrentUser()Landroid/content/pm/UserInfo;
@@ -1872,7 +1875,7 @@ HSPLandroid/app/IActivityManager$Stub$Proxy;->registerStrictModeCallback(Landroi
HSPLandroid/app/IActivityManager$Stub$Proxy;->registerUidObserver(Landroid/app/IUidObserver;IILjava/lang/String;)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->removeContentProvider(Landroid/os/IBinder;Z)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->revokeUriPermission(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/net/Uri;II)V
-HSPLandroid/app/IActivityManager$Stub$Proxy;->serviceDoneExecuting(Landroid/os/IBinder;IIILandroid/content/Intent;)V+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->serviceDoneExecuting(Landroid/os/IBinder;IIILandroid/content/Intent;)V+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/IActivityManager$Stub$Proxy;->setRenderThread(I)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->setServiceForeground(Landroid/content/ComponentName;Landroid/os/IBinder;ILandroid/app/Notification;II)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->startService(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;I)Landroid/content/ComponentName;
@@ -1931,7 +1934,7 @@ HSPLandroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
HSPLandroid/app/INotificationManager$Stub$Proxy;->areNotificationsEnabled(Ljava/lang/String;)Z
HSPLandroid/app/INotificationManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelAllNotifications(Ljava/lang/String;I)V
-HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V+]Landroid/app/INotificationManager$Stub$Proxy;Landroid/app/INotificationManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V
HSPLandroid/app/INotificationManager$Stub$Proxy;->createNotificationChannelGroups(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
HSPLandroid/app/INotificationManager$Stub$Proxy;->createNotificationChannels(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
HSPLandroid/app/INotificationManager$Stub$Proxy;->deleteNotificationChannel(Ljava/lang/String;Ljava/lang/String;)V
@@ -2035,7 +2038,7 @@ HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0;-><i
HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0;->run()V
HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;-><init>(Landroid/app/LoadedApk$ReceiverDispatcher;Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZZIILjava/lang/String;)V
HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->getRunnable()Ljava/lang/Runnable;
-HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->lambda$getRunnable$0()V+]Landroid/app/LoadedApk$ReceiverDispatcher$Args;Landroid/app/LoadedApk$ReceiverDispatcher$Args;]Landroid/content/Intent;Landroid/content/Intent;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->lambda$getRunnable$0()V
HSPLandroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZI)V
HSPLandroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZZIILjava/lang/String;)V
HSPLandroid/app/LoadedApk$ReceiverDispatcher;-><init>(Landroid/app/IApplicationThread;Landroid/content/BroadcastReceiver;Landroid/content/Context;Landroid/os/Handler;Landroid/app/Instrumentation;Z)V
@@ -2263,7 +2266,7 @@ HSPLandroid/app/Notification$Style;->restoreFromExtras(Landroid/os/Bundle;)V
HSPLandroid/app/Notification$Style;->setBuilder(Landroid/app/Notification$Builder;)V
HSPLandroid/app/Notification$Style;->validate(Landroid/content/Context;)V
HSPLandroid/app/Notification;-><init>()V
-HSPLandroid/app/Notification;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/Notification;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/Notification;->addFieldsFromContext(Landroid/content/Context;Landroid/app/Notification;)V
HSPLandroid/app/Notification;->addFieldsFromContext(Landroid/content/pm/ApplicationInfo;Landroid/app/Notification;)V
HSPLandroid/app/Notification;->areStyledNotificationsVisiblyDifferent(Landroid/app/Notification$Builder;Landroid/app/Notification$Builder;)Z
@@ -2288,7 +2291,7 @@ HSPLandroid/app/Notification;->isForegroundService()Z
HSPLandroid/app/Notification;->isGroupChild()Z
HSPLandroid/app/Notification;->isGroupSummary()Z
HSPLandroid/app/Notification;->isMediaNotification()Z
-HSPLandroid/app/Notification;->readFromParcelImpl(Landroid/os/Parcel;)V
+HSPLandroid/app/Notification;->readFromParcelImpl(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/graphics/drawable/Icon$1;,Landroid/app/PendingIntent$1;,Landroid/media/AudioAttributes$1;]Landroid/graphics/drawable/Icon;Landroid/graphics/drawable/Icon;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/Notification;->reduceImageSizes(Landroid/content/Context;)V
HSPLandroid/app/Notification;->reduceImageSizesForRemoteView(Landroid/widget/RemoteViews;Landroid/content/Context;Z)V
HSPLandroid/app/Notification;->removeTextSizeSpans(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
@@ -2298,10 +2301,10 @@ HSPLandroid/app/Notification;->suppressAlertingDueToGrouping()Z
HSPLandroid/app/Notification;->toString()Ljava/lang/String;
HSPLandroid/app/Notification;->visibilityToString(I)Ljava/lang/String;
HSPLandroid/app/Notification;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/app/Notification;->writeToParcelImpl(Landroid/os/Parcel;I)V
+HSPLandroid/app/Notification;->writeToParcelImpl(Landroid/os/Parcel;I)V+]Landroid/app/PendingIntent;Landroid/app/PendingIntent;]Landroid/media/AudioAttributes;Landroid/media/AudioAttributes;]Landroid/graphics/drawable/Icon;Landroid/graphics/drawable/Icon;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/NotificationChannel;
-HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/app/NotificationChannel;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/app/NotificationChannel$1;Landroid/app/NotificationChannel$1;
+HSPLandroid/app/NotificationChannel;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/net/Uri$1;,Landroid/media/AudioAttributes$1;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
HSPLandroid/app/NotificationChannel;-><init>(Ljava/lang/String;Ljava/lang/CharSequence;I)V
HSPLandroid/app/NotificationChannel;->canBubble()Z
HSPLandroid/app/NotificationChannel;->canBypassDnd()Z
@@ -2320,7 +2323,7 @@ HSPLandroid/app/NotificationChannel;->getLockscreenVisibility()I
HSPLandroid/app/NotificationChannel;->getName()Ljava/lang/CharSequence;
HSPLandroid/app/NotificationChannel;->getOriginalImportance()I
HSPLandroid/app/NotificationChannel;->getSound()Landroid/net/Uri;
-HSPLandroid/app/NotificationChannel;->getTrimmedString(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/app/NotificationChannel;->getTrimmedString(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/app/NotificationChannel;->getUserLockedFields()I
HSPLandroid/app/NotificationChannel;->getVibrationPattern()[J
HSPLandroid/app/NotificationChannel;->hasUserSetImportance()Z
@@ -2363,7 +2366,7 @@ HSPLandroid/app/NotificationManager;->areNotificationsEnabled()Z
HSPLandroid/app/NotificationManager;->cancel(I)V
HSPLandroid/app/NotificationManager;->cancel(Ljava/lang/String;I)V
HSPLandroid/app/NotificationManager;->cancelAll()V
-HSPLandroid/app/NotificationManager;->cancelAsUser(Ljava/lang/String;ILandroid/os/UserHandle;)V+]Landroid/app/INotificationManager;Landroid/app/INotificationManager$Stub$Proxy;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;]Landroid/os/UserHandle;Landroid/os/UserHandle;
+HSPLandroid/app/NotificationManager;->cancelAsUser(Ljava/lang/String;ILandroid/os/UserHandle;)V
HSPLandroid/app/NotificationManager;->createNotificationChannel(Landroid/app/NotificationChannel;)V
HSPLandroid/app/NotificationManager;->createNotificationChannelGroup(Landroid/app/NotificationChannelGroup;)V
HSPLandroid/app/NotificationManager;->createNotificationChannelGroups(Ljava/util/List;)V
@@ -2386,6 +2389,7 @@ HSPLandroid/app/NotificationManager;->notify(ILandroid/app/Notification;)V
HSPLandroid/app/NotificationManager;->notify(Ljava/lang/String;ILandroid/app/Notification;)V
HSPLandroid/app/NotificationManager;->notifyAsUser(Ljava/lang/String;ILandroid/app/Notification;Landroid/os/UserHandle;)V
HSPLandroid/app/NotificationManager;->zenModeToInterruptionFilter(I)I
+HSPLandroid/app/PendingIntent$$ExternalSyntheticLambda3;->get()Ljava/lang/Object;
HSPLandroid/app/PendingIntent$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/PendingIntent;
HSPLandroid/app/PendingIntent$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/app/PendingIntent$FinishedDispatcher;-><init>(Landroid/app/PendingIntent;Landroid/app/PendingIntent$OnFinished;Landroid/os/Handler;)V
@@ -2443,7 +2447,7 @@ HSPLandroid/app/PictureInPictureParams$1;->createFromParcel(Landroid/os/Parcel;)
HSPLandroid/app/PictureInPictureParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/app/PictureInPictureParams;-><init>(Landroid/os/Parcel;)V
HSPLandroid/app/PropertyInvalidatedCache$1;-><init>(Landroid/app/PropertyInvalidatedCache;IFZ)V
-HSPLandroid/app/PropertyInvalidatedCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z+]Landroid/app/PropertyInvalidatedCache$1;Landroid/app/PropertyInvalidatedCache$1;
+HSPLandroid/app/PropertyInvalidatedCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z
HSPLandroid/app/PropertyInvalidatedCache$DefaultComputer;-><init>(Landroid/app/PropertyInvalidatedCache;)V
HSPLandroid/app/PropertyInvalidatedCache$NoPreloadHolder;-><clinit>()V
HSPLandroid/app/PropertyInvalidatedCache$NoPreloadHolder;->next()J
@@ -2470,7 +2474,7 @@ HSPLandroid/app/PropertyInvalidatedCache;->invalidateCacheLocked(Ljava/lang/Stri
HSPLandroid/app/PropertyInvalidatedCache;->isDisabled()Z
HSPLandroid/app/PropertyInvalidatedCache;->isReservedNonce(J)Z
HSPLandroid/app/PropertyInvalidatedCache;->maybeCheckConsistency(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/app/PropertyInvalidatedCache;->query(Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/app/PropertyInvalidatedCache;megamorphic_types]Ljava/util/LinkedHashMap;Landroid/app/PropertyInvalidatedCache$1;
+HSPLandroid/app/PropertyInvalidatedCache;->query(Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Landroid/app/PropertyInvalidatedCache$1;]Landroid/app/PropertyInvalidatedCache;megamorphic_types
HSPLandroid/app/PropertyInvalidatedCache;->recompute(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/app/PropertyInvalidatedCache;->refresh(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/app/PropertyInvalidatedCache;->registerCache()V
@@ -2539,7 +2543,7 @@ HSPLandroid/app/ResourcesManager;->createResources(Landroid/content/res/Resource
HSPLandroid/app/ResourcesManager;->createResourcesForActivity(Landroid/os/IBinder;Landroid/content/res/ResourcesKey;Landroid/content/res/Configuration;Ljava/lang/Integer;Ljava/lang/ClassLoader;Landroid/app/ResourcesManager$ApkAssetsSupplier;)Landroid/content/res/Resources;
HSPLandroid/app/ResourcesManager;->createResourcesForActivityLocked(Landroid/os/IBinder;Landroid/content/res/Configuration;Ljava/lang/Integer;Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;
HSPLandroid/app/ResourcesManager;->createResourcesImpl(Landroid/content/res/ResourcesKey;Landroid/app/ResourcesManager$ApkAssetsSupplier;)Landroid/content/res/ResourcesImpl;
-HSPLandroid/app/ResourcesManager;->createResourcesLocked(Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;
+HSPLandroid/app/ResourcesManager;->createResourcesLocked(Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/app/ResourcesManager;->extractApkKeys(Landroid/content/res/ResourcesKey;)Ljava/util/ArrayList;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/app/ResourcesManager;->findKeyForResourceImplLocked(Landroid/content/res/ResourcesImpl;)Landroid/content/res/ResourcesKey;
HSPLandroid/app/ResourcesManager;->findOrCreateResourcesImplForKeyLocked(Landroid/content/res/ResourcesKey;)Landroid/content/res/ResourcesImpl;
@@ -2561,7 +2565,7 @@ HSPLandroid/app/ResourcesManager;->initializeApplicationPaths(Ljava/lang/String;
HSPLandroid/app/ResourcesManager;->isSameResourcesOverrideConfig(Landroid/os/IBinder;Landroid/content/res/Configuration;)Z
HSPLandroid/app/ResourcesManager;->lambda$cleanupReferences$1(Ljava/util/function/Function;Ljava/util/HashSet;Ljava/lang/Object;)Z
HSPLandroid/app/ResourcesManager;->lambda$createResourcesForActivityLocked$0(Landroid/app/ResourcesManager$ActivityResource;)Ljava/lang/ref/WeakReference;
-HSPLandroid/app/ResourcesManager;->loadApkAssets(Landroid/app/ResourcesManager$ApkKey;)Landroid/content/res/ApkAssets;+]Landroid/content/res/ApkAssets;Landroid/content/res/ApkAssets;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/app/ResourcesManager;->loadApkAssets(Landroid/app/ResourcesManager$ApkKey;)Landroid/content/res/ApkAssets;
HSPLandroid/app/ResourcesManager;->overlayPathToIdmapPath(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/app/ResourcesManager;->rebaseActivityOverrideConfig(Landroid/app/ResourcesManager$ActivityResource;Landroid/content/res/Configuration;I)Landroid/content/res/ResourcesKey;
HSPLandroid/app/ResourcesManager;->rebaseKeyForActivity(Landroid/os/IBinder;Landroid/content/res/ResourcesKey;Z)V
@@ -2613,7 +2617,7 @@ HSPLandroid/app/SharedPreferencesImpl$EditorImpl;-><init>(Landroid/app/SharedPre
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->apply()V
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->clear()Landroid/content/SharedPreferences$Editor;
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commit()Z
-HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commitToMemory()Landroid/app/SharedPreferencesImpl$MemoryCommitResult;
+HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commitToMemory()Landroid/app/SharedPreferencesImpl$MemoryCommitResult;+]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/lang/Object;Ljava/lang/String;,Ljava/lang/Boolean;,Ljava/lang/Long;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/Map;Ljava/util/HashMap;]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->notifyListeners(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;)V
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->putBoolean(Ljava/lang/String;Z)Landroid/content/SharedPreferences$Editor;
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->putFloat(Ljava/lang/String;F)Landroid/content/SharedPreferences$Editor;
@@ -2658,7 +2662,7 @@ HSPLandroid/app/SharedPreferencesImpl;->registerOnSharedPreferenceChangeListener
HSPLandroid/app/SharedPreferencesImpl;->startLoadFromDisk()V
HSPLandroid/app/SharedPreferencesImpl;->startReloadIfChangedUnexpectedly()V
HSPLandroid/app/SharedPreferencesImpl;->unregisterOnSharedPreferenceChangeListener(Landroid/content/SharedPreferences$OnSharedPreferenceChangeListener;)V
-HSPLandroid/app/SharedPreferencesImpl;->writeToFile(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Z)V
+HSPLandroid/app/SharedPreferencesImpl;->writeToFile(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Z)V+]Ljava/io/File;Ljava/io/File;]Lcom/android/internal/util/ExponentiallyBucketedHistogram;Lcom/android/internal/util/ExponentiallyBucketedHistogram;]Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Landroid/app/SharedPreferencesImpl$MemoryCommitResult;]Ljava/io/FileOutputStream;Ljava/io/FileOutputStream;
HSPLandroid/app/StackTrace;-><init>(Ljava/lang/String;)V
HSPLandroid/app/StatusBarManager;-><init>(Landroid/content/Context;)V
HSPLandroid/app/SyncNotedAppOp$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/SyncNotedAppOp;
@@ -2743,9 +2747,11 @@ HSPLandroid/app/SystemServiceRegistry$3;->createService(Landroid/app/ContextImpl
HSPLandroid/app/SystemServiceRegistry$3;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$40;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$41;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$42;->createService(Landroid/app/ContextImpl;)Landroid/hardware/SensorManager;
HSPLandroid/app/SystemServiceRegistry$42;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$43;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$44;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$45;->createService(Landroid/app/ContextImpl;)Landroid/os/storage/StorageManager;
HSPLandroid/app/SystemServiceRegistry$45;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$46;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$47;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2764,6 +2770,7 @@ HSPLandroid/app/SystemServiceRegistry$56;->createService(Landroid/app/ContextImp
HSPLandroid/app/SystemServiceRegistry$57;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$58;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$59;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$60;->createService(Landroid/app/ContextImpl;)Landroid/view/WindowManager;
HSPLandroid/app/SystemServiceRegistry$60;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$61;->createService(Landroid/app/ContextImpl;)Landroid/os/UserManager;
HSPLandroid/app/SystemServiceRegistry$61;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2774,6 +2781,7 @@ HSPLandroid/app/SystemServiceRegistry$64;->createService(Landroid/app/ContextImp
HSPLandroid/app/SystemServiceRegistry$65;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$66;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$67;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$68;->createService(Landroid/app/ContextImpl;)Landroid/companion/virtual/VirtualDeviceManager;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLandroid/app/SystemServiceRegistry$68;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$71;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$74;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2802,7 +2810,7 @@ HSPLandroid/app/SystemServiceRegistry$97;->createService(Landroid/app/ContextImp
HSPLandroid/app/SystemServiceRegistry$98;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$99;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$9;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
-HSPLandroid/app/SystemServiceRegistry$CachedServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$CachedServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;+]Landroid/app/SystemServiceRegistry$CachedServiceFetcher;megamorphic_types]Ljava/lang/Object;[Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$StaticServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry;->createServiceCache()[Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry;->getSystemService(Landroid/app/ContextImpl;Ljava/lang/String;)Ljava/lang/Object;+]Landroid/app/SystemServiceRegistry$ServiceFetcher;megamorphic_types
@@ -2857,6 +2865,7 @@ HSPLandroid/app/WindowConfiguration$1;->createFromParcel(Landroid/os/Parcel;)Lja
HSPLandroid/app/WindowConfiguration;-><init>()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/app/WindowConfiguration;-><init>(Landroid/os/Parcel;)V
HSPLandroid/app/WindowConfiguration;->activityTypeToString(I)Ljava/lang/String;
+HSPLandroid/app/WindowConfiguration;->areConfigurationsEqualForDisplay(Landroid/content/res/Configuration;Landroid/content/res/Configuration;)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/app/WindowConfiguration;->canReceiveKeys()Z
HSPLandroid/app/WindowConfiguration;->compareTo(Landroid/app/WindowConfiguration;)I
HSPLandroid/app/WindowConfiguration;->diff(Landroid/app/WindowConfiguration;Z)J+]Landroid/graphics/Rect;Landroid/graphics/Rect;
@@ -2868,17 +2877,19 @@ HSPLandroid/app/WindowConfiguration;->getDisplayRotation()I
HSPLandroid/app/WindowConfiguration;->getMaxBounds()Landroid/graphics/Rect;
HSPLandroid/app/WindowConfiguration;->getRotation()I
HSPLandroid/app/WindowConfiguration;->getWindowingMode()I
+HSPLandroid/app/WindowConfiguration;->hasWindowDecorCaption()Z
HSPLandroid/app/WindowConfiguration;->hasWindowShadow()Z
HSPLandroid/app/WindowConfiguration;->inMultiWindowMode(I)Z
HSPLandroid/app/WindowConfiguration;->isFloating(I)Z
-HSPLandroid/app/WindowConfiguration;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/WindowConfiguration;->readFromParcel(Landroid/os/Parcel;)V
HSPLandroid/app/WindowConfiguration;->setActivityType(I)V
HSPLandroid/app/WindowConfiguration;->setAlwaysOnTop(I)V
-HSPLandroid/app/WindowConfiguration;->setAppBounds(IIII)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/app/WindowConfiguration;->setAppBounds(Landroid/graphics/Rect;)V
-HSPLandroid/app/WindowConfiguration;->setBounds(Landroid/graphics/Rect;)V
+HSPLandroid/app/WindowConfiguration;->setAppBounds(IIII)V
+HSPLandroid/app/WindowConfiguration;->setAppBounds(Landroid/graphics/Rect;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLandroid/app/WindowConfiguration;->setBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/app/WindowConfiguration;->setDisplayRotation(I)V
-HSPLandroid/app/WindowConfiguration;->setMaxBounds(Landroid/graphics/Rect;)V
+HSPLandroid/app/WindowConfiguration;->setDisplayWindowingMode(I)V
+HSPLandroid/app/WindowConfiguration;->setMaxBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/app/WindowConfiguration;->setRotation(I)V
HSPLandroid/app/WindowConfiguration;->setTo(Landroid/app/WindowConfiguration;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/app/WindowConfiguration;->setTo(Landroid/app/WindowConfiguration;I)V
@@ -2887,7 +2898,7 @@ HSPLandroid/app/WindowConfiguration;->setWindowingMode(I)V
HSPLandroid/app/WindowConfiguration;->tasksAreFloating()Z
HSPLandroid/app/WindowConfiguration;->toString()Ljava/lang/String;
HSPLandroid/app/WindowConfiguration;->unset()V
-HSPLandroid/app/WindowConfiguration;->updateFrom(Landroid/app/WindowConfiguration;)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/app/WindowConfiguration;->updateFrom(Landroid/app/WindowConfiguration;)I+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/app/WindowConfiguration;->windowingModeToString(I)Ljava/lang/String;
HSPLandroid/app/WindowConfiguration;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/app/admin/DevicePolicyManager$$ExternalSyntheticLambda5;-><init>(Landroid/app/admin/DevicePolicyManager;)V
@@ -3153,10 +3164,10 @@ HSPLandroid/app/job/JobInfo$TriggerContentUri$1;->newArray(I)[Landroid/app/job/J
HSPLandroid/app/job/JobInfo$TriggerContentUri$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/app/job/JobInfo$TriggerContentUri;-><init>(Landroid/net/Uri;I)V
HSPLandroid/app/job/JobInfo$TriggerContentUri;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;)V
+HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;)V+]Landroid/os/PersistableBundle;Landroid/os/PersistableBundle;]Landroid/os/Bundle;Landroid/os/Bundle;
HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;Landroid/app/job/JobInfo-IA;)V
-HSPLandroid/app/job/JobInfo;-><init>(Landroid/os/Parcel;)V
-HSPLandroid/app/job/JobInfo;->enforceValidity(ZZZZ)V+]Landroid/content/ComponentName;Landroid/content/ComponentName;]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/app/job/JobInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/net/NetworkRequest$1;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/job/JobInfo;->enforceValidity(ZZZZ)V+]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/content/ComponentName;Landroid/content/ComponentName;
HSPLandroid/app/job/JobInfo;->getExtras()Landroid/os/PersistableBundle;
HSPLandroid/app/job/JobInfo;->getFlags()I
HSPLandroid/app/job/JobInfo;->getFlexMillis()J
@@ -3175,7 +3186,7 @@ HSPLandroid/app/job/JobInfo;->isPersisted()Z
HSPLandroid/app/job/JobInfo;->isRequireCharging()Z
HSPLandroid/app/job/JobInfo;->isRequireDeviceIdle()Z
HSPLandroid/app/job/JobInfo;->validateTraceTag(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/app/job/JobInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/app/job/JobInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/job/JobParameters$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/job/JobParameters;
HSPLandroid/app/job/JobParameters$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/app/job/JobParameters;-><init>(Landroid/os/Parcel;)V
@@ -3263,13 +3274,14 @@ HSPLandroid/app/servertransaction/ActivityResultItem;->getPostExecutionState()I
HSPLandroid/app/servertransaction/ActivityTransactionItem;-><init>()V
HSPLandroid/app/servertransaction/ClientTransaction$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/servertransaction/ClientTransaction;
HSPLandroid/app/servertransaction/ClientTransaction$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;)V+]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/app/servertransaction/ClientTransaction;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;)V
HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;Landroid/app/servertransaction/ClientTransaction-IA;)V
HSPLandroid/app/servertransaction/ClientTransaction;->getCallbacks()Ljava/util/List;
HSPLandroid/app/servertransaction/ClientTransaction;->getLifecycleStateRequest()Landroid/app/servertransaction/ActivityLifecycleItem;
-HSPLandroid/app/servertransaction/ClientTransaction;->preExecute(Landroid/app/ClientTransactionHandler;)V+]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/servertransaction/ClientTransaction;->preExecute(Landroid/app/ClientTransactionHandler;)V
HSPLandroid/app/servertransaction/ClientTransactionItem;-><init>()V
HSPLandroid/app/servertransaction/ClientTransactionItem;->getPostExecutionState()I
+HSPLandroid/app/servertransaction/ClientTransactionItem;->isActivityLifecycleItem()Z
HSPLandroid/app/servertransaction/ClientTransactionItem;->shouldHaveDefinedPreExecutionState()Z
HSPLandroid/app/servertransaction/ConfigurationChangeItem$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/servertransaction/ConfigurationChangeItem;
HSPLandroid/app/servertransaction/ConfigurationChangeItem$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -3330,11 +3342,13 @@ HSPLandroid/app/servertransaction/TransactionExecutor;->cycleToPath(Landroid/app
HSPLandroid/app/servertransaction/TransactionExecutor;->execute(Landroid/app/servertransaction/ClientTransaction;)V
HSPLandroid/app/servertransaction/TransactionExecutor;->executeCallbacks(Landroid/app/servertransaction/ClientTransaction;)V
HSPLandroid/app/servertransaction/TransactionExecutor;->executeLifecycleState(Landroid/app/servertransaction/ClientTransaction;)V
-HSPLandroid/app/servertransaction/TransactionExecutor;->performLifecycleSequence(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/util/IntArray;Landroid/app/servertransaction/ClientTransaction;)V+]Landroid/app/ClientTransactionHandler;Landroid/app/ActivityThread;]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/app/servertransaction/TransactionExecutor;->executeNonLifecycleItem(Landroid/app/servertransaction/ClientTransaction;Landroid/app/servertransaction/ClientTransactionItem;Z)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/servertransaction/TransactionExecutorHelper;Landroid/app/servertransaction/TransactionExecutorHelper;]Landroid/app/ClientTransactionHandler;Landroid/app/ActivityThread;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Landroid/content/Context;missing_types]Ljava/util/Map;Ljava/util/Collections$SynchronizedMap;]Landroid/app/servertransaction/TransactionExecutor;Landroid/app/servertransaction/TransactionExecutor;
+HSPLandroid/app/servertransaction/TransactionExecutor;->executeTransactionItems(Landroid/app/servertransaction/ClientTransaction;)V+]Landroid/app/servertransaction/ClientTransaction;Landroid/app/servertransaction/ClientTransaction;]Ljava/util/List;Ljava/util/ArrayList;]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types
+HSPLandroid/app/servertransaction/TransactionExecutor;->performLifecycleSequence(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/util/IntArray;Landroid/app/servertransaction/ClientTransaction;)V
HSPLandroid/app/servertransaction/TransactionExecutorHelper;-><init>()V
HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getClosestOfStates(Landroid/app/ActivityThread$ActivityClientRecord;[I)I
HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getClosestPreExecutionState(Landroid/app/ActivityThread$ActivityClientRecord;I)I
-HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getLifecyclePath(IIZ)Landroid/util/IntArray;+]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getLifecyclePath(IIZ)Landroid/util/IntArray;
HSPLandroid/app/servertransaction/TransactionExecutorHelper;->lastCallbackRequestingState(Landroid/app/servertransaction/ClientTransaction;)I
HSPLandroid/app/slice/ISliceManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
HSPLandroid/app/slice/ISliceManager$Stub$Proxy;->getPinnedSlices(Ljava/lang/String;)[Landroid/net/Uri;
@@ -3426,10 +3440,10 @@ HSPLandroid/app/usage/UsageEvents$Event;->getTimeStamp()J
HSPLandroid/app/usage/UsageEvents;-><init>(Landroid/os/Parcel;)V
HSPLandroid/app/usage/UsageEvents;->getNextEvent(Landroid/app/usage/UsageEvents$Event;)Z
HSPLandroid/app/usage/UsageEvents;->hasNextEvent()Z
-HSPLandroid/app/usage/UsageEvents;->readEventFromParcel(Landroid/os/Parcel;Landroid/app/usage/UsageEvents$Event;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/content/res/Configuration$1;
-HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/usage/UsageStats;+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
-HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/app/usage/UsageStats$1;Landroid/app/usage/UsageStats$1;
-HSPLandroid/app/usage/UsageStats$1;->readBundleToEventMap(Landroid/os/Bundle;Landroid/util/ArrayMap;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/app/usage/UsageEvents;->readEventFromParcel(Landroid/os/Parcel;Landroid/app/usage/UsageEvents$Event;)V
+HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/usage/UsageStats;+]Landroid/os/Bundle;Landroid/os/Bundle;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/usage/UsageStats$1;->readBundleToEventMap(Landroid/os/Bundle;Landroid/util/ArrayMap;)V
HSPLandroid/app/usage/UsageStats;-><init>()V
HSPLandroid/app/usage/UsageStats;->getPackageName()Ljava/lang/String;
HSPLandroid/app/usage/UsageStats;->update(Ljava/lang/String;JII)V
@@ -3452,7 +3466,7 @@ HSPLandroid/appwidget/AppWidgetProvider;-><init>()V
HSPLandroid/appwidget/AppWidgetProvider;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
HSPLandroid/appwidget/AppWidgetProviderInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/appwidget/AppWidgetProviderInfo;
HSPLandroid/appwidget/AppWidgetProviderInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/appwidget/AppWidgetProviderInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/appwidget/AppWidgetProviderInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/appwidget/AppWidgetProviderInfo;->getProfile()Landroid/os/UserHandle;
HSPLandroid/appwidget/AppWidgetProviderInfo;->updateDimensions(Landroid/util/DisplayMetrics;)V
HSPLandroid/appwidget/AppWidgetProviderInfo;->writeToParcel(Landroid/os/Parcel;I)V
@@ -3463,6 +3477,10 @@ HSPLandroid/companion/virtual/IVirtualDeviceManager$Stub$Proxy;->getDeviceIdForD
HSPLandroid/companion/virtual/IVirtualDeviceManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/companion/virtual/IVirtualDeviceManager;
HSPLandroid/companion/virtual/VirtualDeviceManager;-><init>(Landroid/companion/virtual/IVirtualDeviceManager;Landroid/content/Context;)V
HSPLandroid/companion/virtual/VirtualDeviceManager;->getDeviceIdForDisplayId(I)I
+HSPLandroid/companion/virtual/flags/FeatureFlagsImpl;-><init>()V
+HSPLandroid/companion/virtual/flags/FeatureFlagsImpl;->enableNativeVdm()Z
+HSPLandroid/companion/virtual/flags/Flags;-><clinit>()V
+HSPLandroid/companion/virtual/flags/Flags;->enableNativeVdm()Z+]Landroid/companion/virtual/flags/FeatureFlags;Landroid/companion/virtual/flags/FeatureFlagsImpl;
HSPLandroid/content/AbstractThreadedSyncAdapter$ISyncAdapterImpl;->cancelSync(Landroid/content/ISyncContext;)V
HSPLandroid/content/AbstractThreadedSyncAdapter$ISyncAdapterImpl;->isCallerSystem()Z
HSPLandroid/content/AbstractThreadedSyncAdapter$ISyncAdapterImpl;->startSync(Landroid/content/ISyncContext;Ljava/lang/String;Landroid/accounts/Account;Landroid/os/Bundle;)V
@@ -3489,6 +3507,7 @@ HSPLandroid/content/AttributionSource$ScopedParcelState;->close()V
HSPLandroid/content/AttributionSource$ScopedParcelState;->getParcel()Landroid/os/Parcel;
HSPLandroid/content/AttributionSource;-><clinit>()V
HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;[Ljava/lang/String;ILandroid/content/AttributionSource;)V
+HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;[Ljava/lang/String;Landroid/content/AttributionSource;)V
HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;ILandroid/content/AttributionSource;)V
HSPLandroid/content/AttributionSource;-><init>(ILjava/lang/String;Ljava/lang/String;)V
HSPLandroid/content/AttributionSource;-><init>(ILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;)V
@@ -3600,20 +3619,22 @@ HSPLandroid/content/ComponentName;->getClassName()Ljava/lang/String;
HSPLandroid/content/ComponentName;->getPackageName()Ljava/lang/String;
HSPLandroid/content/ComponentName;->getShortClassName()Ljava/lang/String;
HSPLandroid/content/ComponentName;->hashCode()I
-HSPLandroid/content/ComponentName;->readFromParcel(Landroid/os/Parcel;)Landroid/content/ComponentName;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/ComponentName;->readFromParcel(Landroid/os/Parcel;)Landroid/content/ComponentName;
HSPLandroid/content/ComponentName;->toShortString()Ljava/lang/String;
HSPLandroid/content/ComponentName;->toString()Ljava/lang/String;
-HSPLandroid/content/ComponentName;->unflattenFromString(Ljava/lang/String;)Landroid/content/ComponentName;
+HSPLandroid/content/ComponentName;->unflattenFromString(Ljava/lang/String;)Landroid/content/ComponentName;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/content/ComponentName;->writeToParcel(Landroid/content/ComponentName;Landroid/os/Parcel;)V
HSPLandroid/content/ComponentName;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/ContentCaptureOptions$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions;
HSPLandroid/content/ContentCaptureOptions$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;-><init>()V
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;->apply(I)Ljava/lang/Object;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;->accept(Ljava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->-$$Nest$smcreateFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;-><init>(ZILjava/util/List;Ljava/util/List;I)V
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
-HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createGroupsFromParcel(Landroid/os/Parcel;)Ljava/util/List;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$11;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createGroupsFromParcel(Landroid/os/Parcel;)Ljava/util/List;+]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$11;,Ljava/util/stream/ReferencePipeline$15;,Ljava/util/stream/IntPipeline$1;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->lambda$createGroupsFromParcel$0(I)Ljava/util/ArrayList;
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->writeToParcel(Landroid/os/Parcel;)V
HSPLandroid/content/ContentCaptureOptions;-><init>(IIIIILandroid/util/ArraySet;)V
@@ -3648,6 +3669,7 @@ HSPLandroid/content/ContentProvider;->checkUser(IILandroid/content/Context;)Z
HSPLandroid/content/ContentProvider;->clearCallingIdentity()Landroid/content/ContentProvider$CallingIdentity;
HSPLandroid/content/ContentProvider;->coerceToLocalContentProvider(Landroid/content/IContentProvider;)Landroid/content/ContentProvider;
HSPLandroid/content/ContentProvider;->delete(Landroid/net/Uri;Landroid/os/Bundle;)I
+HSPLandroid/content/ContentProvider;->deniedAccessSystemUserOnlyProvider(IZ)Z
HSPLandroid/content/ContentProvider;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
HSPLandroid/content/ContentProvider;->enforceReadPermissionInner(Landroid/net/Uri;Landroid/content/AttributionSource;)I
HSPLandroid/content/ContentProvider;->enforceWritePermissionInner(Landroid/net/Uri;Landroid/content/AttributionSource;)I
@@ -3724,7 +3746,7 @@ HSPLandroid/content/ContentProviderOperation$Builder;->withValue(Ljava/lang/Stri
HSPLandroid/content/ContentProviderOperation$Builder;->withValues(Landroid/content/ContentValues;)Landroid/content/ContentProviderOperation$Builder;
HSPLandroid/content/ContentProviderOperation;-><init>(Landroid/content/ContentProviderOperation$Builder;)V
HSPLandroid/content/ContentProviderOperation;->apply(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;
-HSPLandroid/content/ContentProviderOperation;->applyInternal(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;
+HSPLandroid/content/ContentProviderOperation;->applyInternal(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;+]Landroid/content/ContentProviderOperation;Landroid/content/ContentProviderOperation;
HSPLandroid/content/ContentProviderOperation;->getUri()Landroid/net/Uri;
HSPLandroid/content/ContentProviderOperation;->isInsert()Z
HSPLandroid/content/ContentProviderOperation;->isReadOperation()Z
@@ -3736,7 +3758,7 @@ HSPLandroid/content/ContentProviderOperation;->newInsert(Landroid/net/Uri;)Landr
HSPLandroid/content/ContentProviderOperation;->newUpdate(Landroid/net/Uri;)Landroid/content/ContentProviderOperation$Builder;
HSPLandroid/content/ContentProviderOperation;->resolveExtrasBackReferences([Landroid/content/ContentProviderResult;I)Landroid/os/Bundle;
HSPLandroid/content/ContentProviderOperation;->resolveSelectionArgsBackReferences([Landroid/content/ContentProviderResult;I)[Ljava/lang/String;
-HSPLandroid/content/ContentProviderOperation;->resolveValueBackReferences([Landroid/content/ContentProviderResult;I)Landroid/content/ContentValues;
+HSPLandroid/content/ContentProviderOperation;->resolveValueBackReferences([Landroid/content/ContentProviderResult;I)Landroid/content/ContentValues;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/content/ContentValues;Landroid/content/ContentValues;
HSPLandroid/content/ContentProviderOperation;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/ContentProviderProxy;-><init>(Landroid/os/IBinder;)V
HSPLandroid/content/ContentProviderProxy;->asBinder()Landroid/os/IBinder;
@@ -3745,7 +3767,7 @@ HSPLandroid/content/ContentProviderProxy;->createCancellationSignal()Landroid/os
HSPLandroid/content/ContentProviderProxy;->delete(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/os/Bundle;)I
HSPLandroid/content/ContentProviderProxy;->insert(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/content/ContentValues;Landroid/os/Bundle;)Landroid/net/Uri;
HSPLandroid/content/ContentProviderProxy;->openTypedAssetFile(Landroid/content/AttributionSource;Landroid/net/Uri;Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/content/res/AssetFileDescriptor;
-HSPLandroid/content/ContentProviderProxy;->query(Landroid/content/AttributionSource;Landroid/net/Uri;[Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/content/ContentProviderProxy;->query(Landroid/content/AttributionSource;Landroid/net/Uri;[Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/database/Cursor;+]Landroid/content/AttributionSource;Landroid/content/AttributionSource;]Landroid/os/Parcelable$Creator;Landroid/database/BulkCursorDescriptor$1;]Landroid/database/IBulkCursor;Landroid/database/BulkCursorProxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/ICancellationSignal;Landroid/os/ICancellationSignal$Stub$Proxy;]Landroid/database/BulkCursorToCursorAdaptor;Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/IContentObserver;Landroid/database/ContentObserver$Transport;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;,Landroid/net/Uri$StringUri;
HSPLandroid/content/ContentProviderProxy;->update(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/content/ContentValues;Landroid/os/Bundle;)I
HSPLandroid/content/ContentProviderResult$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentProviderResult;
HSPLandroid/content/ContentProviderResult$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -3862,7 +3884,7 @@ HSPLandroid/content/ContentValues;->putNull(Ljava/lang/String;)V
HSPLandroid/content/ContentValues;->putObject(Ljava/lang/String;Ljava/lang/Object;)V
HSPLandroid/content/ContentValues;->remove(Ljava/lang/String;)V
HSPLandroid/content/ContentValues;->size()I
-HSPLandroid/content/ContentValues;->toString()Ljava/lang/String;+]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/content/ContentValues;->toString()Ljava/lang/String;
HSPLandroid/content/ContentValues;->valueSet()Ljava/util/Set;
HSPLandroid/content/ContentValues;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/Context;-><init>()V
@@ -3876,11 +3898,11 @@ HSPLandroid/content/Context;->getString(I[Ljava/lang/Object;)Ljava/lang/String;
HSPLandroid/content/Context;->getSystemService(Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/content/Context;->getText(I)Ljava/lang/CharSequence;
HSPLandroid/content/Context;->getToken(Landroid/content/Context;)Landroid/os/IBinder;
-HSPLandroid/content/Context;->isAutofillCompatibilityEnabled()Z+]Landroid/content/Context;missing_types
-HSPLandroid/content/Context;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/Context;->isAutofillCompatibilityEnabled()Z
+HSPLandroid/content/Context;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;
+HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;
+HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/Context;missing_types
+HSPLandroid/content/Context;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;
HSPLandroid/content/Context;->registerComponentCallbacks(Landroid/content/ComponentCallbacks;)V
HSPLandroid/content/Context;->unregisterComponentCallbacks(Landroid/content/ComponentCallbacks;)V
HSPLandroid/content/ContextParams$Builder;-><init>()V
@@ -3927,25 +3949,25 @@ HSPLandroid/content/ContextWrapper;->enforceCallingPermission(Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->enforcePermission(Ljava/lang/String;IILjava/lang/String;)V
HSPLandroid/content/ContextWrapper;->fileList()[Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getActivityToken()Landroid/os/IBinder;
-HSPLandroid/content/ContextWrapper;->getApplicationContext()Landroid/content/Context;+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->getApplicationContext()Landroid/content/Context;
HSPLandroid/content/ContextWrapper;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getAssets()Landroid/content/res/AssetManager;
HSPLandroid/content/ContextWrapper;->getAttributionSource()Landroid/content/AttributionSource;
HSPLandroid/content/ContextWrapper;->getAttributionTag()Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getAutofillClient()Landroid/view/autofill/AutofillManager$AutofillClient;
-HSPLandroid/content/ContextWrapper;->getAutofillOptions()Landroid/content/AutofillOptions;+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->getAutofillOptions()Landroid/content/AutofillOptions;
HSPLandroid/content/ContextWrapper;->getBaseContext()Landroid/content/Context;
HSPLandroid/content/ContextWrapper;->getBasePackageName()Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getCacheDir()Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getClassLoader()Ljava/lang/ClassLoader;
HSPLandroid/content/ContextWrapper;->getContentCaptureOptions()Landroid/content/ContentCaptureOptions;
-HSPLandroid/content/ContextWrapper;->getContentResolver()Landroid/content/ContentResolver;
+HSPLandroid/content/ContextWrapper;->getContentResolver()Landroid/content/ContentResolver;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getDataDir()Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getDatabasePath(Ljava/lang/String;)Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getDeviceId()I
HSPLandroid/content/ContextWrapper;->getDir(Ljava/lang/String;I)Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getDisplay()Landroid/view/Display;
-HSPLandroid/content/ContextWrapper;->getDisplayId()I
+HSPLandroid/content/ContextWrapper;->getDisplayId()I+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getDisplayNoVerify()Landroid/view/Display;
HSPLandroid/content/ContextWrapper;->getExternalCacheDir()Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getExternalCacheDirs()[Ljava/io/File;
@@ -3961,21 +3983,21 @@ HSPLandroid/content/ContextWrapper;->getNextAutofillId()I
HSPLandroid/content/ContextWrapper;->getNoBackupFilesDir()Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getOpPackageName()Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getPackageCodePath()Ljava/lang/String;
-HSPLandroid/content/ContextWrapper;->getPackageManager()Landroid/content/pm/PackageManager;
+HSPLandroid/content/ContextWrapper;->getPackageManager()Landroid/content/pm/PackageManager;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getPackageName()Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getPackageResourcePath()Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getResources()Landroid/content/res/Resources;
-HSPLandroid/content/ContextWrapper;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
+HSPLandroid/content/ContextWrapper;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getSharedPreferencesPath(Ljava/lang/String;)Ljava/io/File;
-HSPLandroid/content/ContextWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/content/ContextWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getSystemServiceName(Ljava/lang/Class;)Ljava/lang/String;+]Landroid/content/Context;missing_types
-HSPLandroid/content/ContextWrapper;->getTheme()Landroid/content/res/Resources$Theme;
+HSPLandroid/content/ContextWrapper;->getTheme()Landroid/content/res/Resources$Theme;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getUser()Landroid/os/UserHandle;
HSPLandroid/content/ContextWrapper;->getUserId()I
HSPLandroid/content/ContextWrapper;->getWindowContextToken()Landroid/os/IBinder;
HSPLandroid/content/ContextWrapper;->grantUriPermission(Ljava/lang/String;Landroid/net/Uri;I)V
HSPLandroid/content/ContextWrapper;->isDeviceProtectedStorage()Z
-HSPLandroid/content/ContextWrapper;->isRestricted()Z+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->isRestricted()Z
HSPLandroid/content/ContextWrapper;->isUiContext()Z
HSPLandroid/content/ContextWrapper;->openFileInput(Ljava/lang/String;)Ljava/io/FileInputStream;
HSPLandroid/content/ContextWrapper;->openFileOutput(Ljava/lang/String;I)Ljava/io/FileOutputStream;
@@ -4061,7 +4083,7 @@ HSPLandroid/content/Intent;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/Intent;-><init>(Ljava/lang/String;)V
HSPLandroid/content/Intent;-><init>(Ljava/lang/String;Landroid/net/Uri;)V
HSPLandroid/content/Intent;-><init>(Ljava/lang/String;Landroid/net/Uri;Landroid/content/Context;Ljava/lang/Class;)V
-HSPLandroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;+]Ljava/lang/String;Ljava/lang/String;]Landroid/util/ArraySet;Landroid/util/ArraySet;
HSPLandroid/content/Intent;->addFlags(I)Landroid/content/Intent;
HSPLandroid/content/Intent;->cloneFilter()Landroid/content/Intent;
HSPLandroid/content/Intent;->filterEquals(Landroid/content/Intent;)Z
@@ -4126,8 +4148,8 @@ HSPLandroid/content/Intent;->putExtras(Landroid/content/Intent;)Landroid/content
HSPLandroid/content/Intent;->putExtras(Landroid/os/Bundle;)Landroid/content/Intent;
HSPLandroid/content/Intent;->putParcelableArrayListExtra(Ljava/lang/String;Ljava/util/ArrayList;)Landroid/content/Intent;
HSPLandroid/content/Intent;->putStringArrayListExtra(Ljava/lang/String;Ljava/util/ArrayList;)Landroid/content/Intent;
-HSPLandroid/content/Intent;->readFromParcel(Landroid/os/Parcel;)V
-HSPLandroid/content/Intent;->removeCategory(Ljava/lang/String;)V
+HSPLandroid/content/Intent;->readFromParcel(Landroid/os/Parcel;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/os/Parcelable$Creator;Landroid/net/Uri$1;,Landroid/graphics/Rect$1;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/content/Intent;Landroid/content/Intent;
+HSPLandroid/content/Intent;->removeCategory(Ljava/lang/String;)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;
HSPLandroid/content/Intent;->removeExtra(Ljava/lang/String;)V
HSPLandroid/content/Intent;->replaceExtras(Landroid/os/Bundle;)Landroid/content/Intent;
HSPLandroid/content/Intent;->resolveActivity(Landroid/content/pm/PackageManager;)Landroid/content/ComponentName;
@@ -4152,13 +4174,13 @@ HSPLandroid/content/Intent;->setPackage(Ljava/lang/String;)Landroid/content/Inte
HSPLandroid/content/Intent;->setSelector(Landroid/content/Intent;)V
HSPLandroid/content/Intent;->setSourceBounds(Landroid/graphics/Rect;)V
HSPLandroid/content/Intent;->setType(Ljava/lang/String;)Landroid/content/Intent;
-HSPLandroid/content/Intent;->toShortString(Ljava/lang/StringBuilder;ZZZZ)V
+HSPLandroid/content/Intent;->toShortString(Ljava/lang/StringBuilder;ZZZZ)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ComponentName;Landroid/content/ComponentName;
HSPLandroid/content/Intent;->toString()Ljava/lang/String;
HSPLandroid/content/Intent;->toString(Ljava/lang/StringBuilder;)V
HSPLandroid/content/Intent;->toUri(I)Ljava/lang/String;
HSPLandroid/content/Intent;->toUriFragment(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
HSPLandroid/content/Intent;->toUriInner(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
-HSPLandroid/content/Intent;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/Intent;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/IntentFilter$$ExternalSyntheticLambda0;->accept(Ljava/lang/Object;Ljava/lang/Object;)V
HSPLandroid/content/IntentFilter$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/IntentFilter;
HSPLandroid/content/IntentFilter$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4222,7 +4244,7 @@ HSPLandroid/content/IntentFilter;->setOrder(I)V
HSPLandroid/content/IntentFilter;->setPriority(I)V
HSPLandroid/content/IntentFilter;->setVisibilityToInstantApp(I)V
HSPLandroid/content/IntentFilter;->typesIterator()Ljava/util/Iterator;
-HSPLandroid/content/IntentFilter;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/IntentFilter;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/content/IntentFilter;Landroid/content/IntentFilter;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/IntentSender;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/LocusId$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/LocusId;
HSPLandroid/content/LocusId$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4298,7 +4320,7 @@ HSPLandroid/content/UriMatcher;-><init>(I)V
HSPLandroid/content/UriMatcher;-><init>(ILjava/lang/String;)V
HSPLandroid/content/UriMatcher;->addURI(Ljava/lang/String;Ljava/lang/String;I)V
HSPLandroid/content/UriMatcher;->createChild(Ljava/lang/String;)Landroid/content/UriMatcher;
-HSPLandroid/content/UriMatcher;->match(Landroid/net/Uri;)I
+HSPLandroid/content/UriMatcher;->match(Landroid/net/Uri;)I+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/List;Landroid/net/Uri$PathSegments;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;
HSPLandroid/content/om/OverlayInfo;->ensureValidState()V
HSPLandroid/content/om/OverlayInfo;->isEnabled()Z
HSPLandroid/content/pm/ActivityInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ActivityInfo;
@@ -4306,7 +4328,7 @@ HSPLandroid/content/pm/ActivityInfo$1;->createFromParcel(Landroid/os/Parcel;)Lja
HSPLandroid/content/pm/ActivityInfo$1;->newArray(I)[Landroid/content/pm/ActivityInfo;
HSPLandroid/content/pm/ActivityInfo$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/content/pm/ActivityInfo$WindowLayout;-><init>(Landroid/os/Parcel;)V
-HSPLandroid/content/pm/ActivityInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Ljava/util/Set;Landroid/util/ArraySet;
+HSPLandroid/content/pm/ActivityInfo;-><init>(Landroid/os/Parcel;)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Landroid/util/ArraySet;
HSPLandroid/content/pm/ActivityInfo;->activityInfoConfigNativeToJava(I)I
HSPLandroid/content/pm/ActivityInfo;->getRealConfigChanged()I
HSPLandroid/content/pm/ActivityInfo;->getThemeResource()I
@@ -4325,7 +4347,7 @@ HSPLandroid/content/pm/ApplicationInfo$1;->createFromParcel(Landroid/os/Parcel;)
HSPLandroid/content/pm/ApplicationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/ApplicationInfo;-><init>()V
HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/content/pm/ApplicationInfo;)V
-HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/os/Parcel;Landroid/os/Parcel;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
+HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/ApplicationInfo-IA;)V
HSPLandroid/content/pm/ApplicationInfo;->getAllApkPaths()[Ljava/lang/String;
HSPLandroid/content/pm/ApplicationInfo;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;
@@ -4362,16 +4384,16 @@ HSPLandroid/content/pm/ApplicationInfo;->setSplitCodePaths([Ljava/lang/String;)V
HSPLandroid/content/pm/ApplicationInfo;->setSplitResourcePaths([Ljava/lang/String;)V
HSPLandroid/content/pm/ApplicationInfo;->setVersionCode(J)V
HSPLandroid/content/pm/ApplicationInfo;->toString()Ljava/lang/String;
-HSPLandroid/content/pm/ApplicationInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/pm/ApplicationInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/UUID;Ljava/util/UUID;
HSPLandroid/content/pm/Attribution$1;-><init>()V
HSPLandroid/content/pm/Attribution;-><clinit>()V
HSPLandroid/content/pm/BaseParceledListSlice$1;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
-HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Landroid/os/Parcel;Ljava/lang/ClassLoader;)V
+HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Landroid/os/Parcel;Ljava/lang/ClassLoader;)V+]Landroid/content/pm/BaseParceledListSlice;Landroid/content/pm/ParceledListSlice;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Ljava/util/List;)V
HSPLandroid/content/pm/BaseParceledListSlice;->getList()Ljava/util/List;
HSPLandroid/content/pm/BaseParceledListSlice;->readCreator(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;)Ljava/lang/Object;
-HSPLandroid/content/pm/BaseParceledListSlice;->readVerifyAndAddElement(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;
-HSPLandroid/content/pm/BaseParceledListSlice;->verifySameType(Ljava/lang/Class;Ljava/lang/Class;)V+]Ljava/lang/Object;Ljava/lang/Class;
+HSPLandroid/content/pm/BaseParceledListSlice;->readVerifyAndAddElement(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;+]Ljava/lang/Object;megamorphic_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/content/pm/BaseParceledListSlice;->verifySameType(Ljava/lang/Class;Ljava/lang/Class;)V
HSPLandroid/content/pm/BaseParceledListSlice;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/pm/Checksum$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/Checksum;
HSPLandroid/content/pm/Checksum$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4380,12 +4402,12 @@ HSPLandroid/content/pm/Checksum;->getType()I
HSPLandroid/content/pm/Checksum;->getValue()[B
HSPLandroid/content/pm/ComponentInfo;-><init>()V
HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/content/pm/ComponentInfo;)V
-HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/ComponentInfo;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;
HSPLandroid/content/pm/ComponentInfo;->getComponentName()Landroid/content/ComponentName;
HSPLandroid/content/pm/ComponentInfo;->getIconResource()I
HSPLandroid/content/pm/ComponentInfo;->isEnabled()Z
-HSPLandroid/content/pm/ComponentInfo;->loadUnsafeLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;
+HSPLandroid/content/pm/ComponentInfo;->loadUnsafeLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;+]Landroid/content/pm/PackageManager;Landroid/app/ApplicationPackageManager;
HSPLandroid/content/pm/ComponentInfo;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/pm/ConfigurationInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ConfigurationInfo;
HSPLandroid/content/pm/ConfigurationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4394,9 +4416,13 @@ HSPLandroid/content/pm/CrossProfileApps;-><init>(Landroid/content/Context;Landro
HSPLandroid/content/pm/CrossProfileApps;->getTargetUserProfiles()Ljava/util/List;
HSPLandroid/content/pm/FallbackCategoryProvider;->getFallbackCategory(Ljava/lang/String;)I
HSPLandroid/content/pm/FallbackCategoryProvider;->loadFallbacks()V
+HSPLandroid/content/pm/FeatureFlagsImpl;-><init>()V
+HSPLandroid/content/pm/FeatureFlagsImpl;->relativeReferenceIntentFilters()Z
HSPLandroid/content/pm/FeatureInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/FeatureInfo;
HSPLandroid/content/pm/FeatureInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/FeatureInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/Flags;-><clinit>()V
+HSPLandroid/content/pm/Flags;->relativeReferenceIntentFilters()Z+]Landroid/content/pm/FeatureFlags;Landroid/content/pm/FeatureFlagsImpl;
HSPLandroid/content/pm/ICrossProfileApps$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/content/pm/ICrossProfileApps$Stub$Proxy;->getTargetUserProfiles(Ljava/lang/String;)Ljava/util/List;
HSPLandroid/content/pm/ICrossProfileApps$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/ICrossProfileApps;
@@ -4418,15 +4444,15 @@ HSPLandroid/content/pm/IPackageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->checkPermission(Ljava/lang/String;Ljava/lang/String;I)I
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getActivityInfo(Landroid/content/ComponentName;JI)Landroid/content/pm/ActivityInfo;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationEnabledSetting(Ljava/lang/String;I)I+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationInfo(Ljava/lang/String;JI)Landroid/content/pm/ApplicationInfo;+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationEnabledSetting(Ljava/lang/String;I)I+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationInfo(Ljava/lang/String;JI)Landroid/content/pm/ApplicationInfo;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getComponentEnabledSetting(Landroid/content/ComponentName;I)I
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledApplications(JI)Landroid/content/pm/ParceledListSlice;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledPackages(JI)Landroid/content/pm/ParceledListSlice;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getNameForUid(I)Ljava/lang/String;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;JI)Landroid/content/pm/PackageInfo;+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;JI)Landroid/content/pm/PackageInfo;+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInstaller()Landroid/content/pm/IPackageInstaller;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageUid(Ljava/lang/String;JI)I
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
@@ -4444,7 +4470,7 @@ HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->lambda$notifyDexLoad$1(Landr
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyDexLoad(Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)V
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyPackageUse(Ljava/lang/String;I)V
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyPackagesReplacedReceived([Ljava/lang/String;)V
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentActivities(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentActivities(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentContentProviders(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentReceivers(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentServices(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
@@ -4496,7 +4522,7 @@ HSPLandroid/content/pm/ModuleInfo;->getPackageName()Ljava/lang/String;
HSPLandroid/content/pm/PackageInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/PackageInfo;
HSPLandroid/content/pm/PackageInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/PackageInfo;-><init>()V
-HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;,Landroid/content/pm/SigningInfo$1;
+HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;,Landroid/content/pm/SigningInfo$1;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/PackageInfo-IA;)V
HSPLandroid/content/pm/PackageInfo;->composeLongVersionCode(II)J
HSPLandroid/content/pm/PackageInfo;->getLongVersionCode()J
@@ -4520,7 +4546,7 @@ HSPLandroid/content/pm/PackageInstaller;->getSessionInfo(I)Landroid/content/pm/P
HSPLandroid/content/pm/PackageInstaller;->registerSessionCallback(Landroid/content/pm/PackageInstaller$SessionCallback;Landroid/os/Handler;)V
HSPLandroid/content/pm/PackageItemInfo;-><init>()V
HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/content/pm/PackageItemInfo;)V
-HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/PackageItemInfo;->forceSafeLabels()V
HSPLandroid/content/pm/PackageItemInfo;->loadIcon(Landroid/content/pm/PackageManager;)Landroid/graphics/drawable/Drawable;
HSPLandroid/content/pm/PackageItemInfo;->loadLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;
@@ -4678,7 +4704,7 @@ HSPLandroid/content/pm/RegisteredServicesCache;->containsType(Ljava/util/ArrayLi
HSPLandroid/content/pm/ResolveInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ResolveInfo;
HSPLandroid/content/pm/ResolveInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/ResolveInfo;-><init>()V
-HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ServiceInfo$1;,Landroid/content/pm/ActivityInfo$1;,Landroid/text/TextUtils$1;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/ResolveInfo-IA;)V
HSPLandroid/content/pm/ResolveInfo;->getComponentInfo()Landroid/content/pm/ComponentInfo;
HSPLandroid/content/pm/ResolveInfo;->loadIcon(Landroid/content/pm/PackageManager;)Landroid/graphics/drawable/Drawable;
@@ -4691,8 +4717,8 @@ HSPLandroid/content/pm/ServiceInfo$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/content/pm/ServiceInfo;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/pm/ServiceInfo;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SharedLibraryInfo;
-HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/content/pm/SharedLibraryInfo$1;Landroid/content/pm/SharedLibraryInfo$1;
+HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/SharedLibraryInfo-IA;)V
HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;JILandroid/content/pm/VersionedPackage;Ljava/util/List;Ljava/util/List;Z)V
HSPLandroid/content/pm/SharedLibraryInfo;->addDependency(Landroid/content/pm/SharedLibraryInfo;)V
@@ -4702,7 +4728,7 @@ HSPLandroid/content/pm/SharedLibraryInfo;->getName()Ljava/lang/String;
HSPLandroid/content/pm/SharedLibraryInfo;->getPath()Ljava/lang/String;
HSPLandroid/content/pm/SharedLibraryInfo;->isNative()Z
HSPLandroid/content/pm/SharedLibraryInfo;->isSdk()Z
-HSPLandroid/content/pm/SharedLibraryInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/pm/SharedLibraryInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/ShortcutInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ShortcutInfo;
HSPLandroid/content/pm/ShortcutInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/ShortcutInfo$Builder;-><init>(Landroid/content/Context;Ljava/lang/String;)V
@@ -4715,7 +4741,7 @@ HSPLandroid/content/pm/ShortcutInfo$Builder;->setLongLabel(Ljava/lang/CharSequen
HSPLandroid/content/pm/ShortcutInfo$Builder;->setLongLived(Z)Landroid/content/pm/ShortcutInfo$Builder;
HSPLandroid/content/pm/ShortcutInfo$Builder;->setRank(I)Landroid/content/pm/ShortcutInfo$Builder;
HSPLandroid/content/pm/ShortcutInfo$Builder;->setShortLabel(Ljava/lang/CharSequence;)Landroid/content/pm/ShortcutInfo$Builder;
-HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/content/pm/ShortcutInfo$Builder;)V
+HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/content/pm/ShortcutInfo$Builder;)V+]Landroid/content/pm/ShortcutInfo;Landroid/content/pm/ShortcutInfo;
HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/pm/ShortcutInfo;->addFlags(I)V
HSPLandroid/content/pm/ShortcutInfo;->cloneCapabilityBindings(Ljava/util/Map;)Ljava/util/Map;
@@ -4766,7 +4792,7 @@ HSPLandroid/content/pm/Signature$1;->createFromParcel(Landroid/os/Parcel;)Landro
HSPLandroid/content/pm/Signature$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/Signature$1;->newArray(I)[Landroid/content/pm/Signature;
HSPLandroid/content/pm/Signature$1;->newArray(I)[Ljava/lang/Object;
-HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;Landroid/content/pm/Signature-IA;)V
HSPLandroid/content/pm/Signature;-><init>(Ljava/lang/String;)V
HSPLandroid/content/pm/Signature;-><init>([B)V
@@ -4779,11 +4805,11 @@ HSPLandroid/content/pm/Signature;->toChars([C[I)[C
HSPLandroid/content/pm/Signature;->toCharsString()Ljava/lang/String;
HSPLandroid/content/pm/SigningDetails$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SigningDetails;
HSPLandroid/content/pm/SigningDetails$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SigningDetails;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/content/pm/SigningDetails;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/SigningDetails;->getSignatures()[Landroid/content/pm/Signature;
HSPLandroid/content/pm/SigningInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SigningInfo;
HSPLandroid/content/pm/SigningInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SigningInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/SigningDetails$1;
+HSPLandroid/content/pm/SigningInfo;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/pm/SigningInfo;->getApkContentsSigners()[Landroid/content/pm/Signature;
HSPLandroid/content/pm/SigningInfo;->getSigningCertificateHistory()[Landroid/content/pm/Signature;
HSPLandroid/content/pm/SigningInfo;->hasMultipleSigners()Z
@@ -4793,7 +4819,7 @@ HSPLandroid/content/pm/StringParceledListSlice$1;->createFromParcel(Landroid/os/
HSPLandroid/content/pm/StringParceledListSlice;->getList()Ljava/util/List;
HSPLandroid/content/pm/UserInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/UserInfo;
HSPLandroid/content/pm/UserInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/UserInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/UserInfo;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/pm/UserInfo;->getUserHandle()Landroid/os/UserHandle;
HSPLandroid/content/pm/UserInfo;->isAdmin()Z
HSPLandroid/content/pm/UserInfo;->isEnabled()Z
@@ -4812,8 +4838,8 @@ HSPLandroid/content/pm/UserPackage;->hashCode()I
HSPLandroid/content/pm/UserPackage;->of(ILjava/lang/String;)Landroid/content/pm/UserPackage;
HSPLandroid/content/pm/UserProperties;->isPresent(J)Z
HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/VersionedPackage;
-HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/content/pm/VersionedPackage$1;Landroid/content/pm/VersionedPackage$1;
+HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;Landroid/content/pm/VersionedPackage-IA;)V
HSPLandroid/content/pm/VersionedPackage;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/pm/dex/ArtManager;->getCurrentProfilePath(Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;
@@ -4930,7 +4956,7 @@ HSPLandroid/content/res/AssetManager;->getResourceTypeName(I)Ljava/lang/String;
HSPLandroid/content/res/AssetManager;->getResourceValue(IILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
HSPLandroid/content/res/AssetManager;->getSizeConfigurations()[Landroid/content/res/Configuration;
HSPLandroid/content/res/AssetManager;->getSystem()Landroid/content/res/AssetManager;
-HSPLandroid/content/res/AssetManager;->getThemeValue(JILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/AssetManager;->getThemeValue(JILandroid/util/TypedValue;Z)Z
HSPLandroid/content/res/AssetManager;->incRefsLocked(J)V
HSPLandroid/content/res/AssetManager;->isUpToDate()Z
HSPLandroid/content/res/AssetManager;->list(Ljava/lang/String;)[Ljava/lang/String;
@@ -4969,13 +4995,13 @@ HSPLandroid/content/res/ColorStateList;->getChangingConfigurations()I
HSPLandroid/content/res/ColorStateList;->getColorForState([II)I
HSPLandroid/content/res/ColorStateList;->getConstantState()Landroid/content/res/ConstantState;
HSPLandroid/content/res/ColorStateList;->getDefaultColor()I
-HSPLandroid/content/res/ColorStateList;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/ColorStateList;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/content/res/ColorStateList;->isStateful()Z
HSPLandroid/content/res/ColorStateList;->modulateColor(IFF)I
HSPLandroid/content/res/ColorStateList;->obtainForTheme(Landroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/ColorStateList;->obtainForTheme(Landroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
HSPLandroid/content/res/ColorStateList;->onColorsChanged()V
-HSPLandroid/content/res/ColorStateList;->valueOf(I)Landroid/content/res/ColorStateList;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/content/res/ColorStateList;->valueOf(I)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/ColorStateList;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/res/CompatibilityInfo$2;->createFromParcel(Landroid/os/Parcel;)Landroid/content/res/CompatibilityInfo;
HSPLandroid/content/res/CompatibilityInfo$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -5007,11 +5033,11 @@ HSPLandroid/content/res/Configuration;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/res/Configuration;-><init>(Landroid/os/Parcel;Landroid/content/res/Configuration-IA;)V
HSPLandroid/content/res/Configuration;->compareTo(Landroid/content/res/Configuration;)I
HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;)I
-HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;ZZ)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/os/LocaleList;Landroid/os/LocaleList;
+HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;ZZ)I
HSPLandroid/content/res/Configuration;->diffPublicOnly(Landroid/content/res/Configuration;)I
HSPLandroid/content/res/Configuration;->equals(Landroid/content/res/Configuration;)Z
HSPLandroid/content/res/Configuration;->equals(Ljava/lang/Object;)Z
-HSPLandroid/content/res/Configuration;->fixUpLocaleList()V+]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Object;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->fixUpLocaleList()V
HSPLandroid/content/res/Configuration;->generateDelta(Landroid/content/res/Configuration;Landroid/content/res/Configuration;)Landroid/content/res/Configuration;
HSPLandroid/content/res/Configuration;->getGrammaticalGender()I
HSPLandroid/content/res/Configuration;->getLayoutDirection()I
@@ -5023,19 +5049,19 @@ HSPLandroid/content/res/Configuration;->isOtherSeqNewer(Landroid/content/res/Con
HSPLandroid/content/res/Configuration;->isScreenRound()Z
HSPLandroid/content/res/Configuration;->isScreenWideColorGamut()Z
HSPLandroid/content/res/Configuration;->needNewResources(II)Z
-HSPLandroid/content/res/Configuration;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/res/Configuration;->readFromParcel(Landroid/os/Parcel;)V
HSPLandroid/content/res/Configuration;->readFromProto(Landroid/util/proto/ProtoInputStream;J)V
HSPLandroid/content/res/Configuration;->reduceScreenLayout(III)I
HSPLandroid/content/res/Configuration;->resetScreenLayout(I)I
HSPLandroid/content/res/Configuration;->setLayoutDirection(Ljava/util/Locale;)V
HSPLandroid/content/res/Configuration;->setLocale(Ljava/util/Locale;)V
HSPLandroid/content/res/Configuration;->setLocales(Landroid/os/LocaleList;)V
-HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;)V+]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;II)V
HSPLandroid/content/res/Configuration;->setToDefaults()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/content/res/Configuration;->toString()Ljava/lang/String;
HSPLandroid/content/res/Configuration;->unset()V
-HSPLandroid/content/res/Configuration;->updateFrom(Landroid/content/res/Configuration;)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->updateFrom(Landroid/content/res/Configuration;)I+]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/content/res/Configuration;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/res/ConfigurationBoundResourceCache;-><init>()V
HSPLandroid/content/res/ConfigurationBoundResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;
@@ -5054,10 +5080,10 @@ HSPLandroid/content/res/DrawableCache;->getInstance(JLandroid/content/res/Resour
HSPLandroid/content/res/DrawableCache;->shouldInvalidateEntry(Landroid/graphics/drawable/Drawable$ConstantState;I)Z
HSPLandroid/content/res/DrawableCache;->shouldInvalidateEntry(Ljava/lang/Object;I)Z
HSPLandroid/content/res/FeatureFlagsImpl;->defaultLocale()Z
-HSPLandroid/content/res/Flags;->defaultLocale()Z
+HSPLandroid/content/res/Flags;->defaultLocale()Z+]Landroid/content/res/FeatureFlags;Landroid/content/res/FeatureFlagsImpl;
HSPLandroid/content/res/FontResourcesParser;->parse(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
-HSPLandroid/content/res/FontResourcesParser;->readFamilies(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;+]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
-HSPLandroid/content/res/FontResourcesParser;->readFamily(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/util/List;Ljava/util/ArrayList;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/FontResourcesParser;->readFamilies(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
+HSPLandroid/content/res/FontResourcesParser;->readFamily(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
HSPLandroid/content/res/FontScaleConverterFactory;->forScale(F)Landroid/content/res/FontScaleConverter;
HSPLandroid/content/res/FontScaleConverterFactory;->isNonLinearFontScalingActive(F)Z
HSPLandroid/content/res/GradientColor;-><init>()V
@@ -5076,28 +5102,28 @@ HSPLandroid/content/res/Resources$NotFoundException;-><init>(Ljava/lang/String;)
HSPLandroid/content/res/Resources$Theme;-><init>(Landroid/content/res/Resources;)V
HSPLandroid/content/res/Resources$Theme;-><init>(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme-IA;)V
HSPLandroid/content/res/Resources$Theme;->applyStyle(IZ)V
-HSPLandroid/content/res/Resources$Theme;->equals(Ljava/lang/Object;)Z+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Ljava/lang/Object;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/res/Resources$Theme;->equals(Ljava/lang/Object;)Z
HSPLandroid/content/res/Resources$Theme;->getAppliedStyleResId()I
HSPLandroid/content/res/Resources$Theme;->getChangingConfigurations()I
-HSPLandroid/content/res/Resources$Theme;->getKey()Landroid/content/res/Resources$ThemeKey;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->getKey()Landroid/content/res/Resources$ThemeKey;
HSPLandroid/content/res/Resources$Theme;->getParentThemeIdentifier(I)I
HSPLandroid/content/res/Resources$Theme;->getResources()Landroid/content/res/Resources;
HSPLandroid/content/res/Resources$Theme;->getTheme()[Ljava/lang/String;
HSPLandroid/content/res/Resources$Theme;->hashCode()I
-HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;
HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;
HSPLandroid/content/res/Resources$Theme;->rebase()V
HSPLandroid/content/res/Resources$Theme;->rebase(Landroid/content/res/ResourcesImpl;)V
-HSPLandroid/content/res/Resources$Theme;->resolveAttribute(ILandroid/util/TypedValue;Z)Z+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->resolveAttribute(ILandroid/util/TypedValue;Z)Z
HSPLandroid/content/res/Resources$Theme;->resolveAttributes([I[I)Landroid/content/res/TypedArray;
HSPLandroid/content/res/Resources$Theme;->setImpl(Landroid/content/res/ResourcesImpl$ThemeImpl;)V
HSPLandroid/content/res/Resources$Theme;->setTo(Landroid/content/res/Resources$Theme;)V
-HSPLandroid/content/res/Resources$Theme;->toString()Ljava/lang/String;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/content/res/Resources$Theme;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLandroid/content/res/Resources$ThemeKey;-><init>()V
HSPLandroid/content/res/Resources$ThemeKey;->append(IZ)V
HSPLandroid/content/res/Resources$ThemeKey;->clone()Landroid/content/res/Resources$ThemeKey;
-HSPLandroid/content/res/Resources$ThemeKey;->equals(Ljava/lang/Object;)Z+]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Ljava/lang/Object;Landroid/content/res/Resources$ThemeKey;
+HSPLandroid/content/res/Resources$ThemeKey;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Landroid/content/res/Resources$ThemeKey;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;
HSPLandroid/content/res/Resources$ThemeKey;->hashCode()I
HSPLandroid/content/res/Resources$ThemeKey;->moveToLast(I)V
HSPLandroid/content/res/Resources$ThemeKey;->setTo(Landroid/content/res/Resources$ThemeKey;)V+][I[I][Z[Z
@@ -5116,12 +5142,12 @@ HSPLandroid/content/res/Resources;->getAttributeSetSourceResId(Landroid/util/Att
HSPLandroid/content/res/Resources;->getBoolean(I)Z
HSPLandroid/content/res/Resources;->getClassLoader()Ljava/lang/ClassLoader;
HSPLandroid/content/res/Resources;->getColor(I)I
-HSPLandroid/content/res/Resources;->getColor(ILandroid/content/res/Resources$Theme;)I+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getColor(ILandroid/content/res/Resources$Theme;)I
HSPLandroid/content/res/Resources;->getColorStateList(I)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/Resources;->getColorStateList(ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/Resources;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo;
HSPLandroid/content/res/Resources;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
-HSPLandroid/content/res/Resources;->getDimension(I)F+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getDimension(I)F
HSPLandroid/content/res/Resources;->getDimensionPixelOffset(I)I
HSPLandroid/content/res/Resources;->getDimensionPixelSize(I)I
HSPLandroid/content/res/Resources;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -5129,7 +5155,7 @@ HSPLandroid/content/res/Resources;->getDisplayMetrics()Landroid/util/DisplayMetr
HSPLandroid/content/res/Resources;->getDrawable(I)Landroid/graphics/drawable/Drawable;
HSPLandroid/content/res/Resources;->getDrawable(ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
HSPLandroid/content/res/Resources;->getDrawableForDensity(II)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/Resources;->getDrawableForDensity(IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getDrawableForDensity(IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
HSPLandroid/content/res/Resources;->getDrawableInflater()Landroid/graphics/drawable/DrawableInflater;
HSPLandroid/content/res/Resources;->getFloat(I)F
HSPLandroid/content/res/Resources;->getFont(Landroid/util/TypedValue;I)Landroid/graphics/Typeface;
@@ -5143,7 +5169,7 @@ HSPLandroid/content/res/Resources;->getLoaders()Ljava/util/List;
HSPLandroid/content/res/Resources;->getQuantityString(II)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getQuantityString(II[Ljava/lang/Object;)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getQuantityText(II)Ljava/lang/CharSequence;
-HSPLandroid/content/res/Resources;->getResourceEntryName(I)Ljava/lang/String;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getResourceEntryName(I)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getResourceName(I)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getResourcePackageName(I)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getResourceTypeName(I)Ljava/lang/String;
@@ -5151,24 +5177,24 @@ HSPLandroid/content/res/Resources;->getSizeConfigurations()[Landroid/content/res
HSPLandroid/content/res/Resources;->getStateListAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
HSPLandroid/content/res/Resources;->getString(I)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getString(I[Ljava/lang/Object;)Ljava/lang/String;
-HSPLandroid/content/res/Resources;->getStringArray(I)[Ljava/lang/String;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getStringArray(I)[Ljava/lang/String;
HSPLandroid/content/res/Resources;->getSystem()Landroid/content/res/Resources;
HSPLandroid/content/res/Resources;->getText(I)Ljava/lang/CharSequence;
HSPLandroid/content/res/Resources;->getTextArray(I)[Ljava/lang/CharSequence;
-HSPLandroid/content/res/Resources;->getValue(ILandroid/util/TypedValue;Z)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getValue(ILandroid/util/TypedValue;Z)V
HSPLandroid/content/res/Resources;->getValueForDensity(IILandroid/util/TypedValue;Z)V
HSPLandroid/content/res/Resources;->getXml(I)Landroid/content/res/XmlResourceParser;
HSPLandroid/content/res/Resources;->hasOverrideDisplayAdjustments()Z
-HSPLandroid/content/res/Resources;->loadColorStateList(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->loadColorStateList(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/Resources;->loadComplexColor(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
HSPLandroid/content/res/Resources;->loadDrawable(Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/Resources;->loadXmlResourceParser(ILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/content/res/Resources;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
-HSPLandroid/content/res/Resources;->newTheme()Landroid/content/res/Resources$Theme;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/content/res/Resources;->loadXmlResourceParser(ILjava/lang/String;)Landroid/content/res/XmlResourceParser;
+HSPLandroid/content/res/Resources;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;
+HSPLandroid/content/res/Resources;->newTheme()Landroid/content/res/Resources$Theme;
HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;
-HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
HSPLandroid/content/res/Resources;->obtainTempTypedValue()Landroid/util/TypedValue;
-HSPLandroid/content/res/Resources;->obtainTypedArray(I)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->obtainTypedArray(I)Landroid/content/res/TypedArray;
HSPLandroid/content/res/Resources;->openRawResource(I)Ljava/io/InputStream;
HSPLandroid/content/res/Resources;->openRawResource(ILandroid/util/TypedValue;)Ljava/io/InputStream;
HSPLandroid/content/res/Resources;->openRawResourceFd(I)Landroid/content/res/AssetFileDescriptor;
@@ -5198,26 +5224,26 @@ HSPLandroid/content/res/ResourcesImpl$LookupStack;-><init>(Landroid/content/res/
HSPLandroid/content/res/ResourcesImpl$LookupStack;->contains(I)Z
HSPLandroid/content/res/ResourcesImpl$LookupStack;->pop()V
HSPLandroid/content/res/ResourcesImpl$LookupStack;->push(I)V
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;-><init>(Landroid/content/res/ResourcesImpl;)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->applyStyle(IZ)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;-><init>(Landroid/content/res/ResourcesImpl;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->applyStyle(IZ)V
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->finalize()V
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getAppliedStyleResId()I
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getChangingConfigurations()I
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getKey()Landroid/content/res/Resources$ThemeKey;
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getParentThemeIdentifier(I)I
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getTheme()[Ljava/lang/String;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->obtainStyledAttributes(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->obtainStyledAttributes(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->rebase()V
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->rebase(Landroid/content/res/AssetManager;)V
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttribute(ILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttribute(ILandroid/util/TypedValue;Z)Z
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttributes(Landroid/content/res/Resources$Theme;[I[I)Landroid/content/res/TypedArray;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->setTo(Landroid/content/res/ResourcesImpl$ThemeImpl;)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->setTo(Landroid/content/res/ResourcesImpl$ThemeImpl;)V
HSPLandroid/content/res/ResourcesImpl;->-$$Nest$sfgetsThemeRegistry()Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/content/res/ResourcesImpl;-><init>(Landroid/content/res/AssetManager;Landroid/util/DisplayMetrics;Landroid/content/res/Configuration;Landroid/view/DisplayAdjustments;)V+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;
+HSPLandroid/content/res/ResourcesImpl;-><init>(Landroid/content/res/AssetManager;Landroid/util/DisplayMetrics;Landroid/content/res/Configuration;Landroid/view/DisplayAdjustments;)V+]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
HSPLandroid/content/res/ResourcesImpl;->adjustLanguageTag(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/content/res/ResourcesImpl;->attrForQuantityCode(Ljava/lang/String;)I
-HSPLandroid/content/res/ResourcesImpl;->cacheDrawable(Landroid/util/TypedValue;ZLandroid/content/res/DrawableCache;Landroid/content/res/Resources$Theme;ZJLandroid/graphics/drawable/Drawable;I)V
-HSPLandroid/content/res/ResourcesImpl;->calcConfigChanges(Landroid/content/res/Configuration;)I+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;
+HSPLandroid/content/res/ResourcesImpl;->cacheDrawable(Landroid/util/TypedValue;ZLandroid/content/res/DrawableCache;Landroid/content/res/Resources$Theme;ZJLandroid/graphics/drawable/Drawable;I)V+]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/content/res/ResourcesImpl;->calcConfigChanges(Landroid/content/res/Configuration;)I
HSPLandroid/content/res/ResourcesImpl;->decodeImageDrawable(Landroid/content/res/AssetManager$AssetInputStream;Landroid/content/res/Resources;Landroid/util/TypedValue;)Landroid/graphics/drawable/Drawable;
HSPLandroid/content/res/ResourcesImpl;->dump(Ljava/io/PrintWriter;Ljava/lang/String;)V
HSPLandroid/content/res/ResourcesImpl;->finishPreloading()V
@@ -5225,7 +5251,7 @@ HSPLandroid/content/res/ResourcesImpl;->flushLayoutCache()V
HSPLandroid/content/res/ResourcesImpl;->getAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
HSPLandroid/content/res/ResourcesImpl;->getAssets()Landroid/content/res/AssetManager;
HSPLandroid/content/res/ResourcesImpl;->getAttributeSetSourceResId(Landroid/util/AttributeSet;)I
-HSPLandroid/content/res/ResourcesImpl;->getColorStateListFromInt(Landroid/util/TypedValue;J)Landroid/content/res/ColorStateList;+]Landroid/content/res/ConstantState;Landroid/content/res/ColorStateList$ColorStateListFactory;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
+HSPLandroid/content/res/ResourcesImpl;->getColorStateListFromInt(Landroid/util/TypedValue;J)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/ResourcesImpl;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo;
HSPLandroid/content/res/ResourcesImpl;->getConfiguration()Landroid/content/res/Configuration;
HSPLandroid/content/res/ResourcesImpl;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -5239,7 +5265,7 @@ HSPLandroid/content/res/ResourcesImpl;->getResourcePackageName(I)Ljava/lang/Stri
HSPLandroid/content/res/ResourcesImpl;->getResourceTypeName(I)Ljava/lang/String;
HSPLandroid/content/res/ResourcesImpl;->getSizeConfigurations()[Landroid/content/res/Configuration;
HSPLandroid/content/res/ResourcesImpl;->getStateListAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
-HSPLandroid/content/res/ResourcesImpl;->getValue(ILandroid/util/TypedValue;Z)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl;->getValue(ILandroid/util/TypedValue;Z)V
HSPLandroid/content/res/ResourcesImpl;->getValueForDensity(IILandroid/util/TypedValue;Z)V
HSPLandroid/content/res/ResourcesImpl;->isIntLike(Ljava/lang/String;)Z
HSPLandroid/content/res/ResourcesImpl;->lambda$decodeImageDrawable$1(Landroid/graphics/ImageDecoder;Landroid/graphics/ImageDecoder$ImageInfo;Landroid/graphics/ImageDecoder$Source;)V
@@ -5247,18 +5273,18 @@ HSPLandroid/content/res/ResourcesImpl;->lambda$new$0()Landroid/content/res/Resou
HSPLandroid/content/res/ResourcesImpl;->loadColorStateList(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/ResourcesImpl;->loadComplexColor(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
HSPLandroid/content/res/ResourcesImpl;->loadComplexColorForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
-HSPLandroid/content/res/ResourcesImpl;->loadComplexColorFromName(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/TypedValue;I)Landroid/content/res/ComplexColor;+]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;,Landroid/content/res/GradientColor;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/ConstantState;Landroid/content/res/ColorStateList$ColorStateListFactory;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
-HSPLandroid/content/res/ResourcesImpl;->loadDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
-HSPLandroid/content/res/ResourcesImpl;->loadDrawableForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;II)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl$LookupStack;Landroid/content/res/ResourcesImpl$LookupStack;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
-HSPLandroid/content/res/ResourcesImpl;->loadFont(Landroid/content/res/Resources;Landroid/util/TypedValue;I)Landroid/graphics/Typeface;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/content/res/ResourcesImpl;->loadComplexColorFromName(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/TypedValue;I)Landroid/content/res/ComplexColor;+]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;
+HSPLandroid/content/res/ResourcesImpl;->loadDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/content/res/ResourcesImpl;->loadDrawableForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;II)Landroid/graphics/drawable/Drawable;
+HSPLandroid/content/res/ResourcesImpl;->loadFont(Landroid/content/res/Resources;Landroid/util/TypedValue;I)Landroid/graphics/Typeface;
HSPLandroid/content/res/ResourcesImpl;->loadXmlDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILjava/lang/String;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/ResourcesImpl;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock;Landroid/content/res/XmlBlock;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/content/res/ResourcesImpl;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Ljava/lang/Object;Ljava/lang/String;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock;Landroid/content/res/XmlBlock;
HSPLandroid/content/res/ResourcesImpl;->newThemeImpl()Landroid/content/res/ResourcesImpl$ThemeImpl;
HSPLandroid/content/res/ResourcesImpl;->openRawResource(ILandroid/util/TypedValue;)Ljava/io/InputStream;
HSPLandroid/content/res/ResourcesImpl;->openRawResourceFd(ILandroid/util/TypedValue;)Landroid/content/res/AssetFileDescriptor;
HSPLandroid/content/res/ResourcesImpl;->startPreloading()V
-HSPLandroid/content/res/ResourcesImpl;->updateConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V+]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Ljava/util/Locale;Ljava/util/Locale;
-HSPLandroid/content/res/ResourcesImpl;->updateConfigurationImpl(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Z)V+]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/ResourcesImpl;->updateConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;
+HSPLandroid/content/res/ResourcesImpl;->updateConfigurationImpl(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Z)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Ljava/lang/Object;Ljava/util/Locale;
HSPLandroid/content/res/ResourcesImpl;->verifyPreloadConfig(IIILjava/lang/String;)Z
HSPLandroid/content/res/ResourcesKey;-><init>(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/content/res/Configuration;Landroid/content/res/CompatibilityInfo;[Landroid/content/res/loader/ResourcesLoader;)V
HSPLandroid/content/res/ResourcesKey;->equals(Ljava/lang/Object;)Z
@@ -5271,9 +5297,9 @@ HSPLandroid/content/res/StringBlock;->finalize()V
HSPLandroid/content/res/StringBlock;->get(I)Ljava/lang/CharSequence;
HSPLandroid/content/res/StringBlock;->getSequence(I)Ljava/lang/CharSequence;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
HSPLandroid/content/res/ThemedResourceCache;-><init>()V
-HSPLandroid/content/res/ThemedResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;+]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/content/res/ThemedResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;
HSPLandroid/content/res/ThemedResourceCache;->getGeneration()I
-HSPLandroid/content/res/ThemedResourceCache;->getThemedLocked(Landroid/content/res/Resources$Theme;Z)Landroid/util/LongSparseArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/content/res/ThemedResourceCache;->getThemedLocked(Landroid/content/res/Resources$Theme;Z)Landroid/util/LongSparseArray;
HSPLandroid/content/res/ThemedResourceCache;->getUnthemedLocked(Z)Landroid/util/LongSparseArray;
HSPLandroid/content/res/ThemedResourceCache;->onConfigurationChange(I)V
HSPLandroid/content/res/ThemedResourceCache;->pruneEntriesLocked(Landroid/util/LongSparseArray;I)Z
@@ -5285,24 +5311,24 @@ HSPLandroid/content/res/TypedArray;->extractThemeAttrs()[I
HSPLandroid/content/res/TypedArray;->extractThemeAttrs([I)[I
HSPLandroid/content/res/TypedArray;->getBoolean(IZ)Z
HSPLandroid/content/res/TypedArray;->getChangingConfigurations()I+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
-HSPLandroid/content/res/TypedArray;->getColor(II)I+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/content/res/TypedArray;->getColor(II)I
HSPLandroid/content/res/TypedArray;->getColorStateList(I)Landroid/content/res/ColorStateList;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLandroid/content/res/TypedArray;->getComplexColor(I)Landroid/content/res/ComplexColor;
HSPLandroid/content/res/TypedArray;->getDimension(IF)F
HSPLandroid/content/res/TypedArray;->getDimensionPixelOffset(II)I
HSPLandroid/content/res/TypedArray;->getDimensionPixelSize(II)I
-HSPLandroid/content/res/TypedArray;->getDrawable(I)Landroid/graphics/drawable/Drawable;
+HSPLandroid/content/res/TypedArray;->getDrawable(I)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/content/res/TypedArray;->getDrawableForDensity(II)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLandroid/content/res/TypedArray;->getFloat(IF)F
-HSPLandroid/content/res/TypedArray;->getFont(I)Landroid/graphics/Typeface;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/content/res/TypedArray;->getFont(I)Landroid/graphics/Typeface;
HSPLandroid/content/res/TypedArray;->getFraction(IIIF)F
HSPLandroid/content/res/TypedArray;->getIndex(I)I
HSPLandroid/content/res/TypedArray;->getIndexCount()I
HSPLandroid/content/res/TypedArray;->getInt(II)I
HSPLandroid/content/res/TypedArray;->getInteger(II)I
HSPLandroid/content/res/TypedArray;->getLayoutDimension(II)I
-HSPLandroid/content/res/TypedArray;->getLayoutDimension(ILjava/lang/String;)I+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/content/res/TypedArray;->getNonConfigurationString(II)Ljava/lang/String;
+HSPLandroid/content/res/TypedArray;->getLayoutDimension(ILjava/lang/String;)I
+HSPLandroid/content/res/TypedArray;->getNonConfigurationString(II)Ljava/lang/String;+]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/content/res/TypedArray;->getNonResourceString(I)Ljava/lang/String;
HSPLandroid/content/res/TypedArray;->getPositionDescription()Ljava/lang/String;
HSPLandroid/content/res/TypedArray;->getResourceId(II)I
@@ -5316,7 +5342,7 @@ HSPLandroid/content/res/TypedArray;->getValueAt(ILandroid/util/TypedValue;)Z
HSPLandroid/content/res/TypedArray;->hasValue(I)Z
HSPLandroid/content/res/TypedArray;->hasValueOrEmpty(I)Z
HSPLandroid/content/res/TypedArray;->length()I
-HSPLandroid/content/res/TypedArray;->loadStringValueAt(I)Ljava/lang/CharSequence;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/TypedArray;->loadStringValueAt(I)Ljava/lang/CharSequence;+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Validator;Landroid/content/res/Validator;
HSPLandroid/content/res/TypedArray;->obtain(Landroid/content/res/Resources;I)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
HSPLandroid/content/res/TypedArray;->peekValue(I)Landroid/util/TypedValue;
HSPLandroid/content/res/TypedArray;->recycle()V+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
@@ -5333,7 +5359,7 @@ HSPLandroid/content/res/XmlBlock$Parser;->getAttributeName(I)Ljava/lang/String;
HSPLandroid/content/res/XmlBlock$Parser;->getAttributeNameResource(I)I
HSPLandroid/content/res/XmlBlock$Parser;->getAttributeResourceValue(II)I
HSPLandroid/content/res/XmlBlock$Parser;->getAttributeResourceValue(Ljava/lang/String;Ljava/lang/String;I)I
-HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(I)Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(I)Ljava/lang/String;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/content/res/XmlBlock$Parser;->getClassAttribute()Ljava/lang/String;
HSPLandroid/content/res/XmlBlock$Parser;->getDepth()I
@@ -5342,14 +5368,14 @@ HSPLandroid/content/res/XmlBlock$Parser;->getLineNumber()I
HSPLandroid/content/res/XmlBlock$Parser;->getName()Ljava/lang/String;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
HSPLandroid/content/res/XmlBlock$Parser;->getPooledString(I)Ljava/lang/CharSequence;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
HSPLandroid/content/res/XmlBlock$Parser;->getPositionDescription()Ljava/lang/String;
-HSPLandroid/content/res/XmlBlock$Parser;->getSequenceString(Ljava/lang/CharSequence;)Ljava/lang/String;+]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->getSequenceString(Ljava/lang/CharSequence;)Ljava/lang/String;
HSPLandroid/content/res/XmlBlock$Parser;->getSourceResId()I
HSPLandroid/content/res/XmlBlock$Parser;->getText()Ljava/lang/String;
HSPLandroid/content/res/XmlBlock$Parser;->isEmptyElementTag()Z
-HSPLandroid/content/res/XmlBlock$Parser;->next()I+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/XmlBlock$Parser;->next()I+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Landroid/content/res/Validator;Landroid/content/res/Validator;
HSPLandroid/content/res/XmlBlock$Parser;->nextTag()I
HSPLandroid/content/res/XmlBlock$Parser;->nextText()Ljava/lang/String;
-HSPLandroid/content/res/XmlBlock$Parser;->require(ILjava/lang/String;Ljava/lang/String;)V+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->require(ILjava/lang/String;Ljava/lang/String;)V
HSPLandroid/content/res/XmlBlock;->-$$Nest$fgetmOpenCount(Landroid/content/res/XmlBlock;)I
HSPLandroid/content/res/XmlBlock;->-$$Nest$fputmOpenCount(Landroid/content/res/XmlBlock;I)V
HSPLandroid/content/res/XmlBlock;->-$$Nest$smnativeGetAttributeCount(J)I
@@ -5363,7 +5389,7 @@ HSPLandroid/content/res/XmlBlock;->-$$Nest$smnativeGetLineNumber(J)I
HSPLandroid/content/res/XmlBlock;->-$$Nest$smnativeGetText(J)I
HSPLandroid/content/res/XmlBlock;-><init>(Landroid/content/res/AssetManager;J)V
HSPLandroid/content/res/XmlBlock;->close()V
-HSPLandroid/content/res/XmlBlock;->decOpenCountLocked()V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;]Ljava/lang/Object;Landroid/content/res/XmlBlock;
+HSPLandroid/content/res/XmlBlock;->decOpenCountLocked()V
HSPLandroid/content/res/XmlBlock;->finalize()V
HSPLandroid/content/res/XmlBlock;->newParser()Landroid/content/res/XmlResourceParser;
HSPLandroid/content/res/XmlBlock;->newParser(I)Landroid/content/res/XmlResourceParser;
@@ -5373,29 +5399,29 @@ HSPLandroid/content/type/DefaultMimeMapFactory;->lambda$create$0(Ljava/lang/Clas
HSPLandroid/content/type/DefaultMimeMapFactory;->parseTypes(Llibcore/content/type/MimeMap$Builder;Ljava/util/function/Function;Ljava/lang/String;)V
HSPLandroid/database/AbstractCursor$SelfContentObserver;-><init>(Landroid/database/AbstractCursor;)V
HSPLandroid/database/AbstractCursor$SelfContentObserver;->onChange(Z)V
-HSPLandroid/database/AbstractCursor;-><init>()V
-HSPLandroid/database/AbstractCursor;->checkPosition()V+]Landroid/database/AbstractCursor;Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/sqlite/SQLiteCursor;
-HSPLandroid/database/AbstractCursor;->close()V
+HSPLandroid/database/AbstractCursor;-><init>()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/AbstractCursor;->checkPosition()V+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
+HSPLandroid/database/AbstractCursor;->close()V+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/MatrixCursor;]Landroid/database/ContentObservable;Landroid/database/ContentObservable;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
HSPLandroid/database/AbstractCursor;->fillWindow(ILandroid/database/CursorWindow;)V
HSPLandroid/database/AbstractCursor;->finalize()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
-HSPLandroid/database/AbstractCursor;->getColumnCount()I
+HSPLandroid/database/AbstractCursor;->getColumnCount()I+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;
HSPLandroid/database/AbstractCursor;->getColumnIndex(Ljava/lang/String;)I
HSPLandroid/database/AbstractCursor;->getColumnIndexOrThrow(Ljava/lang/String;)I
-HSPLandroid/database/AbstractCursor;->getColumnName(I)Ljava/lang/String;
+HSPLandroid/database/AbstractCursor;->getColumnName(I)Ljava/lang/String;+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;
HSPLandroid/database/AbstractCursor;->getExtras()Landroid/os/Bundle;
HSPLandroid/database/AbstractCursor;->getPosition()I
HSPLandroid/database/AbstractCursor;->getWantsAllOnMoveCalls()Z
HSPLandroid/database/AbstractCursor;->getWindow()Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractCursor;->isAfterLast()Z
+HSPLandroid/database/AbstractCursor;->isAfterLast()Z+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/AbstractCursor;->isClosed()Z
HSPLandroid/database/AbstractCursor;->isLast()Z
HSPLandroid/database/AbstractCursor;->move(I)Z
HSPLandroid/database/AbstractCursor;->moveToFirst()Z
HSPLandroid/database/AbstractCursor;->moveToLast()Z
-HSPLandroid/database/AbstractCursor;->moveToNext()Z
-HSPLandroid/database/AbstractCursor;->moveToPosition(I)Z
+HSPLandroid/database/AbstractCursor;->moveToNext()Z+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/MatrixCursor;,Landroid/database/BulkCursorToCursorAdaptor;
+HSPLandroid/database/AbstractCursor;->moveToPosition(I)Z+]Landroid/database/AbstractCursor;missing_types
HSPLandroid/database/AbstractCursor;->onChange(Z)V
-HSPLandroid/database/AbstractCursor;->onDeactivateOrClose()V
+HSPLandroid/database/AbstractCursor;->onDeactivateOrClose()V+]Landroid/database/DataSetObservable;Landroid/database/DataSetObservable;
HSPLandroid/database/AbstractCursor;->onMove(II)Z
HSPLandroid/database/AbstractCursor;->registerContentObserver(Landroid/database/ContentObserver;)V
HSPLandroid/database/AbstractCursor;->registerDataSetObserver(Landroid/database/DataSetObserver;)V
@@ -5406,18 +5432,18 @@ HSPLandroid/database/AbstractCursor;->unregisterContentObserver(Landroid/databas
HSPLandroid/database/AbstractWindowedCursor;-><init>()V
HSPLandroid/database/AbstractWindowedCursor;->checkPosition()V
HSPLandroid/database/AbstractWindowedCursor;->clearOrCreateWindow(Ljava/lang/String;)V
-HSPLandroid/database/AbstractWindowedCursor;->closeWindow()V
+HSPLandroid/database/AbstractWindowedCursor;->closeWindow()V+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/AbstractWindowedCursor;->getBlob(I)[B
-HSPLandroid/database/AbstractWindowedCursor;->getDouble(I)D
+HSPLandroid/database/AbstractWindowedCursor;->getDouble(I)D+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/AbstractWindowedCursor;->getFloat(I)F
-HSPLandroid/database/AbstractWindowedCursor;->getInt(I)I+]Landroid/database/AbstractWindowedCursor;Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->getLong(I)J+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->getString(I)Ljava/lang/String;+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getInt(I)I+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getLong(I)J+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getString(I)Ljava/lang/String;+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/AbstractWindowedCursor;->getType(I)I
HSPLandroid/database/AbstractWindowedCursor;->getWindow()Landroid/database/CursorWindow;
HSPLandroid/database/AbstractWindowedCursor;->hasWindow()Z
HSPLandroid/database/AbstractWindowedCursor;->isNull(I)Z+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->onDeactivateOrClose()V
+HSPLandroid/database/AbstractWindowedCursor;->onDeactivateOrClose()V+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/AbstractWindowedCursor;->setWindow(Landroid/database/CursorWindow;)V
HSPLandroid/database/BulkCursorDescriptor$1;->createFromParcel(Landroid/os/Parcel;)Landroid/database/BulkCursorDescriptor;
HSPLandroid/database/BulkCursorDescriptor$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -5438,7 +5464,7 @@ HSPLandroid/database/BulkCursorToCursorAdaptor;->getColumnNames()[Ljava/lang/Str
HSPLandroid/database/BulkCursorToCursorAdaptor;->getCount()I
HSPLandroid/database/BulkCursorToCursorAdaptor;->getObserver()Landroid/database/IContentObserver;
HSPLandroid/database/BulkCursorToCursorAdaptor;->initialize(Landroid/database/BulkCursorDescriptor;)V
-HSPLandroid/database/BulkCursorToCursorAdaptor;->onMove(II)Z
+HSPLandroid/database/BulkCursorToCursorAdaptor;->onMove(II)Z+]Landroid/database/IBulkCursor;Landroid/database/BulkCursorProxy;]Landroid/database/BulkCursorToCursorAdaptor;Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/BulkCursorToCursorAdaptor;->throwIfCursorIsClosed()V
HSPLandroid/database/ContentObservable;-><init>()V
HSPLandroid/database/ContentObservable;->dispatchChange(ZLandroid/net/Uri;)V
@@ -5477,18 +5503,18 @@ HSPLandroid/database/CursorWindow$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/database/CursorWindow;-><init>(Landroid/os/Parcel;)V
HSPLandroid/database/CursorWindow;-><init>(Landroid/os/Parcel;Landroid/database/CursorWindow-IA;)V
HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;)V
-HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;J)V
+HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;J)V+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/database/CursorWindow;->allocRow()Z
HSPLandroid/database/CursorWindow;->clear()V
-HSPLandroid/database/CursorWindow;->dispose()V
-HSPLandroid/database/CursorWindow;->finalize()V
-HSPLandroid/database/CursorWindow;->getBlob(II)[B+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/CursorWindow;->dispose()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/CursorWindow;->finalize()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/CursorWindow;->getBlob(II)[B
HSPLandroid/database/CursorWindow;->getCursorWindowSize()I
-HSPLandroid/database/CursorWindow;->getDouble(II)D
+HSPLandroid/database/CursorWindow;->getDouble(II)D+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/CursorWindow;->getFloat(II)F
-HSPLandroid/database/CursorWindow;->getInt(II)I
+HSPLandroid/database/CursorWindow;->getInt(II)I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/CursorWindow;->getLong(II)J+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/CursorWindow;->getNumRows()I
+HSPLandroid/database/CursorWindow;->getNumRows()I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/CursorWindow;->getStartPosition()I
HSPLandroid/database/CursorWindow;->getString(II)Ljava/lang/String;+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/CursorWindow;->getType(II)I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
@@ -5510,16 +5536,16 @@ HSPLandroid/database/CursorWrapper;->getColumnName(I)Ljava/lang/String;
HSPLandroid/database/CursorWrapper;->getColumnNames()[Ljava/lang/String;
HSPLandroid/database/CursorWrapper;->getCount()I
HSPLandroid/database/CursorWrapper;->getExtras()Landroid/os/Bundle;
-HSPLandroid/database/CursorWrapper;->getInt(I)I
+HSPLandroid/database/CursorWrapper;->getInt(I)I+]Landroid/database/Cursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/content/ContentProviderClient$CursorWrapperInner;,Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/CursorWrapper;->getLong(I)J
HSPLandroid/database/CursorWrapper;->getPosition()I
HSPLandroid/database/CursorWrapper;->getString(I)Ljava/lang/String;
HSPLandroid/database/CursorWrapper;->getType(I)I
HSPLandroid/database/CursorWrapper;->getWrappedCursor()Landroid/database/Cursor;
-HSPLandroid/database/CursorWrapper;->isAfterLast()Z
+HSPLandroid/database/CursorWrapper;->isAfterLast()Z+]Landroid/database/Cursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/content/ContentProviderClient$CursorWrapperInner;,Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/CursorWrapper;->isClosed()Z
HSPLandroid/database/CursorWrapper;->isLast()Z
-HSPLandroid/database/CursorWrapper;->isNull(I)Z
+HSPLandroid/database/CursorWrapper;->isNull(I)Z+]Landroid/database/Cursor;Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/CursorWrapper;->moveToFirst()Z
HSPLandroid/database/CursorWrapper;->moveToLast()Z
HSPLandroid/database/CursorWrapper;->moveToNext()Z
@@ -5527,9 +5553,9 @@ HSPLandroid/database/CursorWrapper;->moveToPosition(I)Z
HSPLandroid/database/CursorWrapper;->registerContentObserver(Landroid/database/ContentObserver;)V
HSPLandroid/database/DataSetObservable;-><init>()V
HSPLandroid/database/DataSetObservable;->notifyChanged()V
-HSPLandroid/database/DataSetObservable;->notifyInvalidated()V
+HSPLandroid/database/DataSetObservable;->notifyInvalidated()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/database/DataSetObserver;-><init>()V
-HSPLandroid/database/DatabaseUtils;->appendEscapedSQLString(Ljava/lang/StringBuilder;Ljava/lang/String;)V
+HSPLandroid/database/DatabaseUtils;->appendEscapedSQLString(Ljava/lang/StringBuilder;Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/database/DatabaseUtils;->categorizeStatement(Ljava/lang/String;Ljava/lang/String;)I+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/database/DatabaseUtils;->cursorFillWindow(Landroid/database/Cursor;ILandroid/database/CursorWindow;)V
HSPLandroid/database/DatabaseUtils;->getSqlStatementPrefixSimple(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
@@ -5584,16 +5610,16 @@ HSPLandroid/database/MergeCursor;->getString(I)Ljava/lang/String;
HSPLandroid/database/MergeCursor;->onMove(II)Z
HSPLandroid/database/Observable;-><init>()V
HSPLandroid/database/Observable;->registerObserver(Ljava/lang/Object;)V
-HSPLandroid/database/Observable;->unregisterAll()V
+HSPLandroid/database/Observable;->unregisterAll()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/database/Observable;->unregisterObserver(Ljava/lang/Object;)V
HSPLandroid/database/sqlite/FeatureFlagsImpl;-><init>()V
HSPLandroid/database/sqlite/FeatureFlagsImpl;->sqliteAllowTempTables()Z
HSPLandroid/database/sqlite/Flags;-><clinit>()V
-HSPLandroid/database/sqlite/Flags;->sqliteAllowTempTables()Z
+HSPLandroid/database/sqlite/Flags;->sqliteAllowTempTables()Z+]Landroid/database/sqlite/FeatureFlags;Landroid/database/sqlite/FeatureFlagsImpl;
HSPLandroid/database/sqlite/SQLiteClosable;-><init>()V
HSPLandroid/database/sqlite/SQLiteClosable;->acquireReference()V
-HSPLandroid/database/sqlite/SQLiteClosable;->close()V
-HSPLandroid/database/sqlite/SQLiteClosable;->releaseReference()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;,Landroid/database/sqlite/SQLiteStatement;
+HSPLandroid/database/sqlite/SQLiteClosable;->close()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteClosable;->releaseReference()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;
HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->getTruncateSize()J
HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->init(Ljava/lang/String;)V
HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->initIfNeeded()V
@@ -5607,7 +5633,7 @@ HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->beginOperation(Ljava
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->dump(Landroid/util/Printer;)V
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperation(I)V
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLog(I)Z
-HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLogLocked(I)Z
+HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLogLocked(I)Z+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->failOperation(ILjava/lang/Exception;)V
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->getOperationLocked(I)Landroid/database/sqlite/SQLiteConnection$Operation;
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->newOperationCookieLocked(I)I
@@ -5623,38 +5649,38 @@ HSPLandroid/database/sqlite/SQLiteConnection$PreparedStatementCache;->getStateme
HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$fgetmConnectionPtr(Landroid/database/sqlite/SQLiteConnection;)J
HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$mfinalizePreparedStatement(Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$smnativePrepareStatement(JLjava/lang/String;)J
-HSPLandroid/database/sqlite/SQLiteConnection;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)V
+HSPLandroid/database/sqlite/SQLiteConnection;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
HSPLandroid/database/sqlite/SQLiteConnection;->acquirePreparedStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;
HSPLandroid/database/sqlite/SQLiteConnection;->acquirePreparedStatementLI(Ljava/lang/String;)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;+]Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
-HSPLandroid/database/sqlite/SQLiteConnection;->applyBlockGuardPolicy(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->attachCancellationSignal(Landroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->bindArguments(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;[Ljava/lang/Object;)V+]Ljava/lang/Number;Ljava/lang/Double;,Ljava/lang/Integer;,Ljava/lang/Long;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteConnection;->applyBlockGuardPolicy(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;]Ldalvik/system/BlockGuard$Policy;Ldalvik/system/BlockGuard$1;,Landroid/os/StrictMode$AndroidBlockGuardPolicy;
+HSPLandroid/database/sqlite/SQLiteConnection;->attachCancellationSignal(Landroid/os/CancellationSignal;)V+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
+HSPLandroid/database/sqlite/SQLiteConnection;->bindArguments(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;[Ljava/lang/Object;)V+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/Number;Ljava/lang/Integer;,Ljava/lang/Double;,Ljava/lang/Long;
HSPLandroid/database/sqlite/SQLiteConnection;->canonicalizeSyncMode(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteConnection;->checkDatabaseWiped()V
HSPLandroid/database/sqlite/SQLiteConnection;->close()V
HSPLandroid/database/sqlite/SQLiteConnection;->collectDbStats(Ljava/util/ArrayList;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->detachCancellationSignal(Landroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteConnection;->detachCancellationSignal(Landroid/os/CancellationSignal;)V+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
HSPLandroid/database/sqlite/SQLiteConnection;->dispose(Z)V
HSPLandroid/database/sqlite/SQLiteConnection;->dumpUnsafe(Landroid/util/Printer;Z)V
-HSPLandroid/database/sqlite/SQLiteConnection;->execute(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)I
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZLandroid/os/CancellationSignal;)I
+HSPLandroid/database/sqlite/SQLiteConnection;->execute(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZLandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
HSPLandroid/database/sqlite/SQLiteConnection;->executeForLastInsertedRowId(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForString(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForString(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)Ljava/lang/String;+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
HSPLandroid/database/sqlite/SQLiteConnection;->executePerConnectionSqlFromConfiguration(I)V
HSPLandroid/database/sqlite/SQLiteConnection;->finalize()V
HSPLandroid/database/sqlite/SQLiteConnection;->finalizePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
HSPLandroid/database/sqlite/SQLiteConnection;->getConnectionId()I
HSPLandroid/database/sqlite/SQLiteConnection;->getMainDbStatsUnsafe(IJJ)Landroid/database/sqlite/SQLiteDebug$DbStats;
HSPLandroid/database/sqlite/SQLiteConnection;->isCacheable(I)Z
-HSPLandroid/database/sqlite/SQLiteConnection;->isPreparedStatementInCache(Ljava/lang/String;)Z
+HSPLandroid/database/sqlite/SQLiteConnection;->isPreparedStatementInCache(Ljava/lang/String;)Z+]Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
HSPLandroid/database/sqlite/SQLiteConnection;->isPrimaryConnection()Z
HSPLandroid/database/sqlite/SQLiteConnection;->maybeTruncateWalFile()V
HSPLandroid/database/sqlite/SQLiteConnection;->obtainPreparedStatement(Ljava/lang/String;JIIZJ)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;
-HSPLandroid/database/sqlite/SQLiteConnection;->open()V
+HSPLandroid/database/sqlite/SQLiteConnection;->open()V+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
HSPLandroid/database/sqlite/SQLiteConnection;->open(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->prepare(Ljava/lang/String;Landroid/database/sqlite/SQLiteStatementInfo;)V
+HSPLandroid/database/sqlite/SQLiteConnection;->prepare(Ljava/lang/String;Landroid/database/sqlite/SQLiteStatementInfo;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
HSPLandroid/database/sqlite/SQLiteConnection;->reconfigure(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
HSPLandroid/database/sqlite/SQLiteConnection;->recyclePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
HSPLandroid/database/sqlite/SQLiteConnection;->releasePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
@@ -5679,6 +5705,7 @@ HSPLandroid/database/sqlite/SQLiteConnectionPool$IdleConnectionHandler;->connect
HSPLandroid/database/sqlite/SQLiteConnectionPool$IdleConnectionHandler;->handleMessage(Landroid/os/Message;)V
HSPLandroid/database/sqlite/SQLiteConnectionPool;-><init>(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->clearAcquiredConnectionsPreparedStatementCache()V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/Iterator;Ljava/util/WeakHashMap$KeyIterator;]Ljava/util/Set;Ljava/util/WeakHashMap$KeySet;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->close()V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->closeAvailableConnectionLocked(I)Z
HSPLandroid/database/sqlite/SQLiteConnectionPool;->closeAvailableConnectionsAndLogExceptionsLocked()V
@@ -5692,13 +5719,13 @@ HSPLandroid/database/sqlite/SQLiteConnectionPool;->discardAcquiredConnectionsLoc
HSPLandroid/database/sqlite/SQLiteConnectionPool;->dispose(Z)V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->dump(Landroid/util/Printer;ZLandroid/util/ArraySet;)V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->finalize()V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->finishAcquireConnectionLocked(Landroid/database/sqlite/SQLiteConnection;I)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->finishAcquireConnectionLocked(Landroid/database/sqlite/SQLiteConnection;I)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->getPath()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->getPriority(I)I
HSPLandroid/database/sqlite/SQLiteConnectionPool;->isSessionBlockingImportantConnectionWaitersLocked(ZI)Z
HSPLandroid/database/sqlite/SQLiteConnectionPool;->markAcquiredConnectionsLocked(Landroid/database/sqlite/SQLiteConnectionPool$AcquiredConnectionStatus;)V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->obtainConnectionWaiterLocked(Ljava/lang/Thread;JIZLjava/lang/String;I)Landroid/database/sqlite/SQLiteConnectionPool$ConnectionWaiter;
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->onStatementExecuted(J)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->onStatementExecuted(J)V+]Ljava/util/concurrent/atomic/AtomicLong;Ljava/util/concurrent/atomic/AtomicLong;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->open()V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->open(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)Landroid/database/sqlite/SQLiteConnectionPool;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->openConnectionLocked(Landroid/database/sqlite/SQLiteDatabaseConfiguration;Z)Landroid/database/sqlite/SQLiteConnection;
@@ -5706,23 +5733,23 @@ HSPLandroid/database/sqlite/SQLiteConnectionPool;->reconfigure(Landroid/database
HSPLandroid/database/sqlite/SQLiteConnectionPool;->reconfigureAllConnectionsLocked()V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->recycleConnectionLocked(Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnectionPool$AcquiredConnectionStatus;)Z
HSPLandroid/database/sqlite/SQLiteConnectionPool;->recycleConnectionWaiterLocked(Landroid/database/sqlite/SQLiteConnectionPool$ConnectionWaiter;)V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->releaseConnection(Landroid/database/sqlite/SQLiteConnection;)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->releaseConnection(Landroid/database/sqlite/SQLiteConnection;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->setMaxConnectionPoolSizeLocked()V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->shouldYieldConnection(Landroid/database/sqlite/SQLiteConnection;I)Z
HSPLandroid/database/sqlite/SQLiteConnectionPool;->throwIfClosedLocked()V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquireNonPrimaryConnectionLocked(Ljava/lang/String;I)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquireNonPrimaryConnectionLocked(Ljava/lang/String;I)Landroid/database/sqlite/SQLiteConnection;+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquirePrimaryConnectionLocked(I)Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->waitForConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->waitForConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;+]Ljava/util/concurrent/atomic/AtomicBoolean;Ljava/util/concurrent/atomic/AtomicBoolean;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->wakeConnectionWaitersLocked()V
HSPLandroid/database/sqlite/SQLiteConstraintException;-><init>(Ljava/lang/String;)V
-HSPLandroid/database/sqlite/SQLiteCursor;-><init>(Landroid/database/sqlite/SQLiteCursorDriver;Ljava/lang/String;Landroid/database/sqlite/SQLiteQuery;)V
-HSPLandroid/database/sqlite/SQLiteCursor;->close()V
-HSPLandroid/database/sqlite/SQLiteCursor;->fillWindow(I)V
+HSPLandroid/database/sqlite/SQLiteCursor;-><init>(Landroid/database/sqlite/SQLiteCursorDriver;Ljava/lang/String;Landroid/database/sqlite/SQLiteQuery;)V+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteCursor;->close()V+]Landroid/database/sqlite/SQLiteCursorDriver;Landroid/database/sqlite/SQLiteDirectCursorDriver;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteCursor;->fillWindow(I)V+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteCursor;->finalize()V
-HSPLandroid/database/sqlite/SQLiteCursor;->getColumnIndex(Ljava/lang/String;)I
+HSPLandroid/database/sqlite/SQLiteCursor;->getColumnIndex(Ljava/lang/String;)I+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/Map;Ljava/util/HashMap;
HSPLandroid/database/sqlite/SQLiteCursor;->getColumnNames()[Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteCursor;->getCount()I
-HSPLandroid/database/sqlite/SQLiteCursor;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteCursor;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
HSPLandroid/database/sqlite/SQLiteCursor;->onMove(II)Z+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;-><init>(Landroid/database/sqlite/SQLiteDatabase;)V
HSPLandroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;->get()Ljava/lang/Object;
@@ -5749,13 +5776,13 @@ HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->-$$Nest$fgetmOpenFlags(L
HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->-$$Nest$fgetmSyncMode(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;-><init>(ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V
HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;-><init>(ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$OpenParams-IA;)V
-HSPLandroid/database/sqlite/SQLiteDatabase;-><init>(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteDatabase;-><init>(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;
HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransaction()V
HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransaction(Landroid/database/sqlite/SQLiteTransactionListener;Z)V
HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransactionNonExclusive()V
HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransactionWithListener(Landroid/database/sqlite/SQLiteTransactionListener;)V
HSPLandroid/database/sqlite/SQLiteDatabase;->collectDbStats(Ljava/util/ArrayList;)V
-HSPLandroid/database/sqlite/SQLiteDatabase;->compileStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteStatement;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteDatabase;->compileStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteStatement;
HSPLandroid/database/sqlite/SQLiteDatabase;->createSession()Landroid/database/sqlite/SQLiteSession;
HSPLandroid/database/sqlite/SQLiteDatabase;->delete(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)I
HSPLandroid/database/sqlite/SQLiteDatabase;->deleteDatabase(Ljava/io/File;)Z
@@ -5770,7 +5797,7 @@ HSPLandroid/database/sqlite/SQLiteDatabase;->execSQL(Ljava/lang/String;)V
HSPLandroid/database/sqlite/SQLiteDatabase;->execSQL(Ljava/lang/String;[Ljava/lang/Object;)V
HSPLandroid/database/sqlite/SQLiteDatabase;->executeSql(Ljava/lang/String;[Ljava/lang/Object;)I
HSPLandroid/database/sqlite/SQLiteDatabase;->finalize()V
-HSPLandroid/database/sqlite/SQLiteDatabase;->findEditTable(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteDatabase;->findEditTable(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabase;->getActiveDatabasePools()Ljava/util/ArrayList;
HSPLandroid/database/sqlite/SQLiteDatabase;->getActiveDatabases()Ljava/util/ArrayList;
HSPLandroid/database/sqlite/SQLiteDatabase;->getFileTimestamps(Ljava/lang/String;)Ljava/lang/String;
@@ -5778,12 +5805,12 @@ HSPLandroid/database/sqlite/SQLiteDatabase;->getMaximumSize()J
HSPLandroid/database/sqlite/SQLiteDatabase;->getPageSize()J
HSPLandroid/database/sqlite/SQLiteDatabase;->getPath()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadDefaultConnectionFlags(Z)I
-HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadSession()Landroid/database/sqlite/SQLiteSession;
+HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadSession()Landroid/database/sqlite/SQLiteSession;+]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
HSPLandroid/database/sqlite/SQLiteDatabase;->getVersion()I
-HSPLandroid/database/sqlite/SQLiteDatabase;->inTransaction()Z
+HSPLandroid/database/sqlite/SQLiteDatabase;->inTransaction()Z+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteDatabase;->insert(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
HSPLandroid/database/sqlite/SQLiteDatabase;->insertOrThrow(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
-HSPLandroid/database/sqlite/SQLiteDatabase;->insertWithOnConflict(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;I)J+]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/database/sqlite/SQLiteDatabase;->insertWithOnConflict(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;I)J
HSPLandroid/database/sqlite/SQLiteDatabase;->isMainThread()Z
HSPLandroid/database/sqlite/SQLiteDatabase;->isOpen()Z
HSPLandroid/database/sqlite/SQLiteDatabase;->isReadOnly()Z
@@ -5801,11 +5828,11 @@ HSPLandroid/database/sqlite/SQLiteDatabase;->query(Ljava/lang/String;[Ljava/lang
HSPLandroid/database/sqlite/SQLiteDatabase;->query(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
HSPLandroid/database/sqlite/SQLiteDatabase;->query(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
HSPLandroid/database/sqlite/SQLiteDatabase;->query(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->queryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDatabase;->queryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteDatabase;->rawQuery(Ljava/lang/String;[Ljava/lang/String;)Landroid/database/Cursor;
HSPLandroid/database/sqlite/SQLiteDatabase;->rawQuery(Ljava/lang/String;[Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteCursorDriver;Landroid/database/sqlite/SQLiteDirectCursorDriver;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteDatabase;->releaseMemory()I
HSPLandroid/database/sqlite/SQLiteDatabase;->replace(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
HSPLandroid/database/sqlite/SQLiteDatabase;->replaceOrThrow(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
@@ -5813,26 +5840,26 @@ HSPLandroid/database/sqlite/SQLiteDatabase;->setForeignKeyConstraintsEnabled(Z)V
HSPLandroid/database/sqlite/SQLiteDatabase;->setTransactionSuccessful()V
HSPLandroid/database/sqlite/SQLiteDatabase;->throwIfNotOpenLocked()V
HSPLandroid/database/sqlite/SQLiteDatabase;->update(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
-HSPLandroid/database/sqlite/SQLiteDatabase;->updateWithOnConflict(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;I)I
+HSPLandroid/database/sqlite/SQLiteDatabase;->updateWithOnConflict(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;I)I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
HSPLandroid/database/sqlite/SQLiteDatabase;->validateSql(Ljava/lang/String;Landroid/os/CancellationSignal;)V
HSPLandroid/database/sqlite/SQLiteDatabase;->yieldIfContendedHelper(ZJ)Z
HSPLandroid/database/sqlite/SQLiteDatabase;->yieldIfContendedSafely(J)Z
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;-><init>(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;-><init>(Ljava/lang/String;I)V
-HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isInMemoryDb()Z
+HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isInMemoryDb()Z+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isLegacyCompatibilityWalEnabled()Z
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isReadOnlyDatabase()Z
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isWalEnabledInternal()Z
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->resolveJournalMode()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->resolveSyncMode()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->stripPathForLogs(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->updateParametersFrom(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
+HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->updateParametersFrom(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/database/sqlite/SQLiteDebug$NoPreloadHolder;-><clinit>()V
HSPLandroid/database/sqlite/SQLiteDebug;->getDatabaseInfo()Landroid/database/sqlite/SQLiteDebug$PagerStats;
HSPLandroid/database/sqlite/SQLiteDebug;->shouldLogSlowQuery(J)Z
HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)V
HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->cursorClosed()V
-HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->query(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;[Ljava/lang/String;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->query(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;[Ljava/lang/String;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
HSPLandroid/database/sqlite/SQLiteException;-><init>(Ljava/lang/String;)V
HSPLandroid/database/sqlite/SQLiteGlobal;->checkDbWipe()Z
HSPLandroid/database/sqlite/SQLiteGlobal;->getDefaultJournalMode()Ljava/lang/String;
@@ -5849,7 +5876,7 @@ HSPLandroid/database/sqlite/SQLiteOpenHelper;-><init>(Landroid/content/Context;L
HSPLandroid/database/sqlite/SQLiteOpenHelper;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$CursorFactory;IILandroid/database/DatabaseErrorHandler;)V
HSPLandroid/database/sqlite/SQLiteOpenHelper;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ILandroid/database/DatabaseErrorHandler;)V
HSPLandroid/database/sqlite/SQLiteOpenHelper;->close()V
-HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseLocked(Z)Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseLocked(Z)Landroid/database/sqlite/SQLiteDatabase;+]Ljava/io/File;Ljava/io/File;]Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseName()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteOpenHelper;->getReadableDatabase()Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteOpenHelper;->getWritableDatabase()Landroid/database/sqlite/SQLiteDatabase;
@@ -5859,9 +5886,9 @@ HSPLandroid/database/sqlite/SQLiteOpenHelper;->setFilePermissionsForDb(Ljava/lan
HSPLandroid/database/sqlite/SQLiteOpenHelper;->setIdleConnectionTimeout(J)V
HSPLandroid/database/sqlite/SQLiteOpenHelper;->setOpenParamsBuilder(Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;)V
HSPLandroid/database/sqlite/SQLiteOpenHelper;->setWriteAheadLoggingEnabled(Z)V
-HSPLandroid/database/sqlite/SQLiteProgram;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteProgram;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteProgram;->bind(ILjava/lang/Object;)V
-HSPLandroid/database/sqlite/SQLiteProgram;->bindAllArgsAsStrings([Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteProgram;->bindAllArgsAsStrings([Ljava/lang/String;)V+]Landroid/database/sqlite/SQLiteProgram;Landroid/database/sqlite/SQLiteQuery;,Landroid/database/sqlite/SQLiteStatement;
HSPLandroid/database/sqlite/SQLiteProgram;->bindBlob(I[B)V
HSPLandroid/database/sqlite/SQLiteProgram;->bindDouble(ID)V
HSPLandroid/database/sqlite/SQLiteProgram;->bindLong(IJ)V
@@ -5870,19 +5897,19 @@ HSPLandroid/database/sqlite/SQLiteProgram;->bindString(ILjava/lang/String;)V
HSPLandroid/database/sqlite/SQLiteProgram;->clearBindings()V
HSPLandroid/database/sqlite/SQLiteProgram;->getBindArgs()[Ljava/lang/Object;
HSPLandroid/database/sqlite/SQLiteProgram;->getColumnNames()[Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteProgram;->getConnectionFlags()I
+HSPLandroid/database/sqlite/SQLiteProgram;->getConnectionFlags()I+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteProgram;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;
-HSPLandroid/database/sqlite/SQLiteProgram;->getSession()Landroid/database/sqlite/SQLiteSession;
+HSPLandroid/database/sqlite/SQLiteProgram;->getSession()Landroid/database/sqlite/SQLiteSession;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteProgram;->getSql()Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteProgram;->onAllReferencesReleased()V
+HSPLandroid/database/sqlite/SQLiteProgram;->onAllReferencesReleased()V+]Landroid/database/sqlite/SQLiteProgram;Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteQuery;
HSPLandroid/database/sqlite/SQLiteQuery;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;Landroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteQuery;->fillWindow(Landroid/database/CursorWindow;IIZ)I
+HSPLandroid/database/sqlite/SQLiteQuery;->fillWindow(Landroid/database/CursorWindow;IIZ)I+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
HSPLandroid/database/sqlite/SQLiteQueryBuilder;-><init>()V
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendClause(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;)V
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendColumns(Ljava/lang/StringBuilder;[Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendClause(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendColumns(Ljava/lang/StringBuilder;[Ljava/lang/String;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendWhere(Ljava/lang/CharSequence;)V
HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQuery([Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQueryString(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQueryString(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeProjection([Ljava/lang/String;)[Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeSingleProjection(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeSingleProjectionOrThrow(Ljava/lang/String;)Ljava/lang/String;
@@ -5902,25 +5929,25 @@ HSPLandroid/database/sqlite/SQLiteQueryBuilder;->wrap(Ljava/lang/String;)Ljava/l
HSPLandroid/database/sqlite/SQLiteSession$Transaction;-><init>()V
HSPLandroid/database/sqlite/SQLiteSession$Transaction;-><init>(Landroid/database/sqlite/SQLiteSession$Transaction-IA;)V
HSPLandroid/database/sqlite/SQLiteSession;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;)V
-HSPLandroid/database/sqlite/SQLiteSession;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteSession;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
HSPLandroid/database/sqlite/SQLiteSession;->beginTransaction(ILandroid/database/sqlite/SQLiteTransactionListener;ILandroid/os/CancellationSignal;)V
HSPLandroid/database/sqlite/SQLiteSession;->beginTransactionUnchecked(ILandroid/database/sqlite/SQLiteTransactionListener;ILandroid/os/CancellationSignal;)V
HSPLandroid/database/sqlite/SQLiteSession;->closeOpenDependents()V+]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;
HSPLandroid/database/sqlite/SQLiteSession;->endTransaction(Landroid/os/CancellationSignal;)V
HSPLandroid/database/sqlite/SQLiteSession;->endTransactionUnchecked(Landroid/os/CancellationSignal;Z)V
-HSPLandroid/database/sqlite/SQLiteSession;->execute(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteSession;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)I
-HSPLandroid/database/sqlite/SQLiteSession;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZILandroid/os/CancellationSignal;)I
+HSPLandroid/database/sqlite/SQLiteSession;->execute(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteSession;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteSession;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZILandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
HSPLandroid/database/sqlite/SQLiteSession;->executeForLastInsertedRowId(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)J
HSPLandroid/database/sqlite/SQLiteSession;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)J
HSPLandroid/database/sqlite/SQLiteSession;->executeForString(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteSession;->executeSpecial(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Z
+HSPLandroid/database/sqlite/SQLiteSession;->executeSpecial(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Z+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
HSPLandroid/database/sqlite/SQLiteSession;->hasNestedTransaction()Z
HSPLandroid/database/sqlite/SQLiteSession;->hasTransaction()Z
HSPLandroid/database/sqlite/SQLiteSession;->obtainTransaction(ILandroid/database/sqlite/SQLiteTransactionListener;)Landroid/database/sqlite/SQLiteSession$Transaction;
-HSPLandroid/database/sqlite/SQLiteSession;->prepare(Ljava/lang/String;ILandroid/os/CancellationSignal;Landroid/database/sqlite/SQLiteStatementInfo;)V
+HSPLandroid/database/sqlite/SQLiteSession;->prepare(Ljava/lang/String;ILandroid/os/CancellationSignal;Landroid/database/sqlite/SQLiteStatementInfo;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
HSPLandroid/database/sqlite/SQLiteSession;->recycleTransaction(Landroid/database/sqlite/SQLiteSession$Transaction;)V
-HSPLandroid/database/sqlite/SQLiteSession;->releaseConnection()V
+HSPLandroid/database/sqlite/SQLiteSession;->releaseConnection()V+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
HSPLandroid/database/sqlite/SQLiteSession;->setTransactionSuccessful()V
HSPLandroid/database/sqlite/SQLiteSession;->throwIfNestedTransaction()V
HSPLandroid/database/sqlite/SQLiteSession;->throwIfNoTransaction()V
@@ -5930,7 +5957,7 @@ HSPLandroid/database/sqlite/SQLiteSession;->yieldTransactionUnchecked(JLandroid/
HSPLandroid/database/sqlite/SQLiteStatement;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;)V
HSPLandroid/database/sqlite/SQLiteStatement;->execute()V+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;
HSPLandroid/database/sqlite/SQLiteStatement;->executeInsert()J
-HSPLandroid/database/sqlite/SQLiteStatement;->executeUpdateDelete()I
+HSPLandroid/database/sqlite/SQLiteStatement;->executeUpdateDelete()I+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;
HSPLandroid/database/sqlite/SQLiteStatement;->simpleQueryForLong()J
HSPLandroid/database/sqlite/SQLiteStatement;->simpleQueryForString()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteStatementInfo;-><init>()V
@@ -5965,33 +5992,33 @@ HSPLandroid/graphics/BaseCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/g
HSPLandroid/graphics/BaseCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Rect;Landroid/graphics/RectF;Landroid/graphics/Paint;)V
HSPLandroid/graphics/BaseCanvas;->drawColor(I)V
HSPLandroid/graphics/BaseCanvas;->drawLine(FFFFLandroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/BaseCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V
HSPLandroid/graphics/BaseCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V
HSPLandroid/graphics/BaseCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V
HSPLandroid/graphics/BaseCanvas;->throwIfCannotDraw(Landroid/graphics/Bitmap;)V
-HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Paint;)V+]Landroid/graphics/BaseCanvas;Landroid/graphics/Canvas;
+HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Paint;)V
HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Shader;)V
HSPLandroid/graphics/BaseCanvas;->throwIfHwBitmapInSwMode(Landroid/graphics/Bitmap;)V
HSPLandroid/graphics/BaseRecordingCanvas;-><init>(J)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawArc(Landroid/graphics/RectF;FFZLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawArc(Landroid/graphics/RectF;FFZLandroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/graphics/BaseRecordingCanvas;->drawBitmap(Landroid/graphics/Bitmap;FFLandroid/graphics/Paint;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawCircle(FFFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawCircle(FFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
HSPLandroid/graphics/BaseRecordingCanvas;->drawColor(I)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawColor(ILandroid/graphics/PorterDuff$Mode;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawLine(FFFFLandroid/graphics/Paint;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawOval(FFFFLandroid/graphics/Paint;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawOval(Landroid/graphics/RectF;Landroid/graphics/Paint;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawPatch(Landroid/graphics/NinePatch;Landroid/graphics/Rect;Landroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;missing_types]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/BaseRecordingCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/Path;Landroid/graphics/Path;
HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(FFFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/Rect;Landroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/RectF;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
+HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/RectF;Landroid/graphics/Paint;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(FFFFFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/Layout$Ellipsizer;
HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/String;FFLandroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun([CIIIIFFZLandroid/graphics/Paint;)V
HSPLandroid/graphics/Bitmap$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Bitmap;
HSPLandroid/graphics/Bitmap$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -6072,7 +6099,7 @@ HSPLandroid/graphics/BitmapShader;-><init>(Landroid/graphics/Bitmap;II)V
HSPLandroid/graphics/BitmapShader;-><init>(Landroid/graphics/Bitmap;Landroid/graphics/Shader$TileMode;Landroid/graphics/Shader$TileMode;)V
HSPLandroid/graphics/BitmapShader;->createNativeInstance(JZ)J
HSPLandroid/graphics/BitmapShader;->shouldDiscardNativeInstance(Z)Z
-HSPLandroid/graphics/BlendMode;->blendModeToPorterDuffMode(Landroid/graphics/BlendMode;)Landroid/graphics/PorterDuff$Mode;+]Landroid/graphics/BlendMode;Landroid/graphics/BlendMode;
+HSPLandroid/graphics/BlendMode;->blendModeToPorterDuffMode(Landroid/graphics/BlendMode;)Landroid/graphics/PorterDuff$Mode;
HSPLandroid/graphics/BlendMode;->fromValue(I)Landroid/graphics/BlendMode;
HSPLandroid/graphics/BlendMode;->getXfermode()Landroid/graphics/Xfermode;
HSPLandroid/graphics/BlendMode;->toValue(Landroid/graphics/BlendMode;)I
@@ -6136,8 +6163,8 @@ HSPLandroid/graphics/Canvas;->rotate(FFF)V
HSPLandroid/graphics/Canvas;->save()I
HSPLandroid/graphics/Canvas;->save(I)I
HSPLandroid/graphics/Canvas;->saveLayer(FFFFLandroid/graphics/Paint;I)I
-HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;)I+]Landroid/graphics/Canvas;Landroid/graphics/Canvas;,Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;I)I+]Landroid/graphics/Canvas;Landroid/graphics/Canvas;,Landroid/graphics/RecordingCanvas;
+HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;)I
+HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;I)I
HSPLandroid/graphics/Canvas;->saveLayerAlpha(FFFFI)I
HSPLandroid/graphics/Canvas;->saveLayerAlpha(FFFFII)I
HSPLandroid/graphics/Canvas;->saveUnclippedLayer(IIII)I
@@ -6170,7 +6197,7 @@ HSPLandroid/graphics/Color;->green()F
HSPLandroid/graphics/Color;->green(I)I
HSPLandroid/graphics/Color;->green(J)F
HSPLandroid/graphics/Color;->luminance()F
-HSPLandroid/graphics/Color;->pack(FFFFLandroid/graphics/ColorSpace;)J+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;
+HSPLandroid/graphics/Color;->pack(FFFFLandroid/graphics/ColorSpace;)J
HSPLandroid/graphics/Color;->pack(I)J
HSPLandroid/graphics/Color;->parseColor(Ljava/lang/String;)I
HSPLandroid/graphics/Color;->red()F
@@ -6296,8 +6323,8 @@ HSPLandroid/graphics/HardwareRendererObserver$$ExternalSyntheticLambda0;-><init>
HSPLandroid/graphics/HardwareRendererObserver$$ExternalSyntheticLambda0;->run()V
HSPLandroid/graphics/HardwareRendererObserver;-><init>(Landroid/graphics/HardwareRendererObserver$OnFrameMetricsAvailableListener;[JLandroid/os/Handler;Z)V
HSPLandroid/graphics/HardwareRendererObserver;->getNativeInstance()J
-HSPLandroid/graphics/HardwareRendererObserver;->invokeDataAvailable(Ljava/lang/ref/WeakReference;)Z
-HSPLandroid/graphics/HardwareRendererObserver;->notifyDataAvailable()V
+HSPLandroid/graphics/HardwareRendererObserver;->invokeDataAvailable(Ljava/lang/ref/WeakReference;)Z+]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/graphics/HardwareRendererObserver;->notifyDataAvailable()V+]Landroid/os/Handler;Landroid/os/Handler;,Landroid/view/ViewRootImpl$ViewRootHandler;
HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;-><init>(Landroid/content/res/AssetManager$AssetInputStream;Landroid/content/res/Resources;Landroid/util/TypedValue;)V
HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;->createImageDecoder(Z)Landroid/graphics/ImageDecoder;
HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;->getDensity()I
@@ -6362,18 +6389,18 @@ HSPLandroid/graphics/LeakyTypefaceStorage;->writeTypefaceToParcel(Landroid/graph
HSPLandroid/graphics/LinearGradient;-><init>(FFFFIILandroid/graphics/Shader$TileMode;)V
HSPLandroid/graphics/LinearGradient;-><init>(FFFFJJLandroid/graphics/Shader$TileMode;)V
HSPLandroid/graphics/LinearGradient;-><init>(FFFF[I[FLandroid/graphics/Shader$TileMode;)V
-HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;)V
+HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;)V+][J[J
HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;Landroid/graphics/ColorSpace;)V
-HSPLandroid/graphics/LinearGradient;->createNativeInstance(JZ)J+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;]Landroid/graphics/LinearGradient;Landroid/graphics/LinearGradient;
+HSPLandroid/graphics/LinearGradient;->createNativeInstance(JZ)J
HSPLandroid/graphics/MaskFilter;->finalize()V
HSPLandroid/graphics/Matrix;-><init>()V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/graphics/Matrix;-><init>(Landroid/graphics/Matrix;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Matrix;-><init>(Landroid/graphics/Matrix;)V
HSPLandroid/graphics/Matrix;->checkPointArrays([FI[FII)V
HSPLandroid/graphics/Matrix;->equals(Ljava/lang/Object;)Z
HSPLandroid/graphics/Matrix;->getValues([F)V
HSPLandroid/graphics/Matrix;->invert(Landroid/graphics/Matrix;)Z
HSPLandroid/graphics/Matrix;->isIdentity()Z
-HSPLandroid/graphics/Matrix;->mapPoints([F)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/graphics/Matrix;->mapPoints([F)V
HSPLandroid/graphics/Matrix;->mapPoints([FI[FII)V
HSPLandroid/graphics/Matrix;->mapRect(Landroid/graphics/RectF;)Z+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
HSPLandroid/graphics/Matrix;->mapRect(Landroid/graphics/RectF;Landroid/graphics/RectF;)Z
@@ -6411,18 +6438,18 @@ HSPLandroid/graphics/Outline;-><init>()V
HSPLandroid/graphics/Outline;->isEmpty()Z
HSPLandroid/graphics/Outline;->setAlpha(F)V
HSPLandroid/graphics/Outline;->setConvexPath(Landroid/graphics/Path;)V
-HSPLandroid/graphics/Outline;->setEmpty()V+]Landroid/graphics/Path;Landroid/graphics/Path;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/Outline;->setEmpty()V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/graphics/Outline;->setOval(IIII)V
HSPLandroid/graphics/Outline;->setOval(Landroid/graphics/Rect;)V
HSPLandroid/graphics/Outline;->setPath(Landroid/graphics/Path;)V
-HSPLandroid/graphics/Outline;->setRect(IIII)V
+HSPLandroid/graphics/Outline;->setRect(IIII)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
HSPLandroid/graphics/Outline;->setRect(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/Outline;->setRoundRect(IIIIF)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/graphics/Outline;->setRoundRect(Landroid/graphics/Rect;F)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
+HSPLandroid/graphics/Outline;->setRoundRect(IIIIF)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/Outline;Landroid/graphics/Outline;
+HSPLandroid/graphics/Outline;->setRoundRect(Landroid/graphics/Rect;F)V
HSPLandroid/graphics/Paint$FontMetrics;-><init>()V
HSPLandroid/graphics/Paint$FontMetricsInt;-><init>()V
HSPLandroid/graphics/Paint;-><init>()V
-HSPLandroid/graphics/Paint;-><init>(I)V+]Landroid/graphics/Paint;missing_types]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Paint;-><init>(I)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;,Landroid/text/TextPaint;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
HSPLandroid/graphics/Paint;-><init>(Landroid/graphics/Paint;)V
HSPLandroid/graphics/Paint;->ascent()F
HSPLandroid/graphics/Paint;->descent()F
@@ -6434,17 +6461,18 @@ HSPLandroid/graphics/Paint;->getFlags()I
HSPLandroid/graphics/Paint;->getFontFeatureSettings()Ljava/lang/String;
HSPLandroid/graphics/Paint;->getFontMetrics()Landroid/graphics/Paint$FontMetrics;
HSPLandroid/graphics/Paint;->getFontMetrics(Landroid/graphics/Paint$FontMetrics;)F
-HSPLandroid/graphics/Paint;->getFontMetricsInt()Landroid/graphics/Paint$FontMetricsInt;
+HSPLandroid/graphics/Paint;->getFontMetricsInt()Landroid/graphics/Paint$FontMetricsInt;+]Landroid/graphics/Paint;Landroid/text/TextPaint;
HSPLandroid/graphics/Paint;->getFontMetricsInt(Landroid/graphics/Paint$FontMetricsInt;)I
-HSPLandroid/graphics/Paint;->getFontMetricsInt(Ljava/lang/CharSequence;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V+]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/graphics/Paint;->getFontMetricsInt(Ljava/lang/CharSequence;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V
HSPLandroid/graphics/Paint;->getFontVariationSettings()Ljava/lang/String;
HSPLandroid/graphics/Paint;->getHinting()I
HSPLandroid/graphics/Paint;->getLetterSpacing()F
HSPLandroid/graphics/Paint;->getMaskFilter()Landroid/graphics/MaskFilter;
-HSPLandroid/graphics/Paint;->getNativeInstance()J+]Landroid/graphics/ColorFilter;Landroid/graphics/BlendModeColorFilter;,Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Paint;missing_types]Landroid/graphics/Shader;Landroid/graphics/BitmapShader;,Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;
+HSPLandroid/graphics/Paint;->getNativeInstance()J+]Landroid/graphics/ColorFilter;Landroid/graphics/PorterDuffColorFilter;,Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/Paint;missing_types]Landroid/graphics/Shader;Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;,Landroid/graphics/BitmapShader;,Landroid/graphics/RadialGradient;
HSPLandroid/graphics/Paint;->getRunAdvance(Ljava/lang/CharSequence;IIIIZI)F
HSPLandroid/graphics/Paint;->getRunAdvance([CIIIIZI)F
HSPLandroid/graphics/Paint;->getRunCharacterAdvance(Ljava/lang/CharSequence;IIIIZI[FI)F
+HSPLandroid/graphics/Paint;->getRunCharacterAdvance(Ljava/lang/CharSequence;IIIIZI[FILandroid/graphics/RectF;Landroid/graphics/Paint$RunInfo;)F+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;megamorphic_types
HSPLandroid/graphics/Paint;->getRunCharacterAdvance([CIIIIZI[FI)F
HSPLandroid/graphics/Paint;->getShader()Landroid/graphics/Shader;
HSPLandroid/graphics/Paint;->getShadowLayerColor()I
@@ -6458,7 +6486,7 @@ HSPLandroid/graphics/Paint;->getStrokeMiter()F
HSPLandroid/graphics/Paint;->getStrokeWidth()F
HSPLandroid/graphics/Paint;->getStyle()Landroid/graphics/Paint$Style;
HSPLandroid/graphics/Paint;->getTextAlign()Landroid/graphics/Paint$Align;
-HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/CharSequence;IILandroid/graphics/Rect;)V
+HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/CharSequence;IILandroid/graphics/Rect;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/String;IILandroid/graphics/Rect;)V
HSPLandroid/graphics/Paint;->getTextBounds([CIILandroid/graphics/Rect;)V
HSPLandroid/graphics/Paint;->getTextLocale()Ljava/util/Locale;
@@ -6504,7 +6532,7 @@ HSPLandroid/graphics/Paint;->setMaskFilter(Landroid/graphics/MaskFilter;)Landroi
HSPLandroid/graphics/Paint;->setPathEffect(Landroid/graphics/PathEffect;)Landroid/graphics/PathEffect;
HSPLandroid/graphics/Paint;->setShader(Landroid/graphics/Shader;)Landroid/graphics/Shader;
HSPLandroid/graphics/Paint;->setShadowLayer(FFFI)V
-HSPLandroid/graphics/Paint;->setShadowLayer(FFFJ)V+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;
+HSPLandroid/graphics/Paint;->setShadowLayer(FFFJ)V
HSPLandroid/graphics/Paint;->setStartHyphenEdit(I)V
HSPLandroid/graphics/Paint;->setStrokeCap(Landroid/graphics/Paint$Cap;)V
HSPLandroid/graphics/Paint;->setStrokeJoin(Landroid/graphics/Paint$Join;)V
@@ -6519,9 +6547,9 @@ HSPLandroid/graphics/Paint;->setTextSkewX(F)V
HSPLandroid/graphics/Paint;->setTypeface(Landroid/graphics/Typeface;)Landroid/graphics/Typeface;
HSPLandroid/graphics/Paint;->setUnderlineText(Z)V
HSPLandroid/graphics/Paint;->setXfermode(Landroid/graphics/Xfermode;)Landroid/graphics/Xfermode;
-HSPLandroid/graphics/Paint;->syncTextLocalesWithMinikin()V+]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/graphics/Paint;->syncTextLocalesWithMinikin()V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/os/LocaleList;Landroid/os/LocaleList;
HSPLandroid/graphics/PaintFlagsDrawFilter;-><init>(II)V
-HSPLandroid/graphics/Path;-><init>()V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Path;-><init>()V
HSPLandroid/graphics/Path;-><init>(Landroid/graphics/Path;)V
HSPLandroid/graphics/Path;->addArc(FFFFFF)V
HSPLandroid/graphics/Path;->addArc(Landroid/graphics/RectF;FF)V
@@ -6530,7 +6558,7 @@ HSPLandroid/graphics/Path;->addOval(FFFFLandroid/graphics/Path$Direction;)V
HSPLandroid/graphics/Path;->addOval(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V
HSPLandroid/graphics/Path;->addPath(Landroid/graphics/Path;Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
HSPLandroid/graphics/Path;->addRect(FFFFLandroid/graphics/Path$Direction;)V
-HSPLandroid/graphics/Path;->addRect(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/Path;->addRect(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V
HSPLandroid/graphics/Path;->addRoundRect(FFFFFFLandroid/graphics/Path$Direction;)V
HSPLandroid/graphics/Path;->addRoundRect(FFFF[FLandroid/graphics/Path$Direction;)V
HSPLandroid/graphics/Path;->addRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Path$Direction;)V
@@ -6548,8 +6576,8 @@ HSPLandroid/graphics/Path;->isEmpty()Z
HSPLandroid/graphics/Path;->lineTo(FF)V
HSPLandroid/graphics/Path;->moveTo(FF)V
HSPLandroid/graphics/Path;->offset(FF)V
-HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z+]Landroid/graphics/Path;Landroid/graphics/Path;
-HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z+]Landroid/graphics/Path$Op;Landroid/graphics/Path$Op;
+HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z
+HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z
HSPLandroid/graphics/Path;->rLineTo(FF)V
HSPLandroid/graphics/Path;->readOnlyNI()J
HSPLandroid/graphics/Path;->reset()V+]Landroid/graphics/Path;Landroid/graphics/Path;
@@ -6589,7 +6617,7 @@ HSPLandroid/graphics/Point;->toString()Ljava/lang/String;
HSPLandroid/graphics/PointF;-><init>()V
HSPLandroid/graphics/PointF;-><init>(FF)V
HSPLandroid/graphics/PointF;->equals(FF)Z
-HSPLandroid/graphics/PointF;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Landroid/graphics/PointF;
+HSPLandroid/graphics/PointF;->equals(Ljava/lang/Object;)Z
HSPLandroid/graphics/PointF;->length()F
HSPLandroid/graphics/PointF;->length(FF)F
HSPLandroid/graphics/PointF;->set(FF)V
@@ -6616,8 +6644,8 @@ HSPLandroid/graphics/RecordingCanvas;->isHardwareAccelerated()Z
HSPLandroid/graphics/RecordingCanvas;->obtain(Landroid/graphics/RenderNode;II)Landroid/graphics/RecordingCanvas;+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
HSPLandroid/graphics/RecordingCanvas;->recycle()V+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
HSPLandroid/graphics/RecordingCanvas;->throwIfCannotDraw(Landroid/graphics/Bitmap;)V
-HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/graphics/Rect$1;Landroid/graphics/Rect$1;
+HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Rect;
+HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/graphics/Rect$1;->newArray(I)[Landroid/graphics/Rect;
HSPLandroid/graphics/Rect$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/graphics/Rect;-><init>()V
@@ -6644,7 +6672,7 @@ HSPLandroid/graphics/Rect;->isEmpty()Z
HSPLandroid/graphics/Rect;->isValid()Z
HSPLandroid/graphics/Rect;->offset(II)V
HSPLandroid/graphics/Rect;->offsetTo(II)V
-HSPLandroid/graphics/Rect;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/graphics/Rect;->readFromParcel(Landroid/os/Parcel;)V
HSPLandroid/graphics/Rect;->scale(F)V
HSPLandroid/graphics/Rect;->set(IIII)V
HSPLandroid/graphics/Rect;->set(Landroid/graphics/Rect;)V
@@ -6653,7 +6681,7 @@ HSPLandroid/graphics/Rect;->setIntersect(Landroid/graphics/Rect;Landroid/graphic
HSPLandroid/graphics/Rect;->toShortString(Ljava/lang/StringBuilder;)Ljava/lang/String;
HSPLandroid/graphics/Rect;->toString()Ljava/lang/String;
HSPLandroid/graphics/Rect;->union(IIII)V
-HSPLandroid/graphics/Rect;->union(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/Rect;->union(Landroid/graphics/Rect;)V
HSPLandroid/graphics/Rect;->width()I
HSPLandroid/graphics/Rect;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/graphics/RectF;-><init>()V
@@ -6707,7 +6735,7 @@ HSPLandroid/graphics/RenderNode$CompositePositionUpdateListener;->without(Landro
HSPLandroid/graphics/RenderNode$PositionUpdateListener;->callPositionChanged(Ljava/lang/ref/WeakReference;JIIII)Z
HSPLandroid/graphics/RenderNode$PositionUpdateListener;->callPositionLost(Ljava/lang/ref/WeakReference;J)Z
HSPLandroid/graphics/RenderNode;-><init>(J)V
-HSPLandroid/graphics/RenderNode;-><init>(Ljava/lang/String;Landroid/graphics/RenderNode$AnimationHost;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/RenderNode;-><init>(Ljava/lang/String;Landroid/graphics/RenderNode$AnimationHost;)V
HSPLandroid/graphics/RenderNode;->addPositionUpdateListener(Landroid/graphics/RenderNode$PositionUpdateListener;)V
HSPLandroid/graphics/RenderNode;->adopt(J)Landroid/graphics/RenderNode;
HSPLandroid/graphics/RenderNode;->beginRecording(II)Landroid/graphics/RecordingCanvas;
@@ -6717,7 +6745,7 @@ HSPLandroid/graphics/RenderNode;->discardDisplayList()V
HSPLandroid/graphics/RenderNode;->endRecording()V+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/graphics/RenderNode;->getClipToOutline()Z
HSPLandroid/graphics/RenderNode;->getElevation()F
-HSPLandroid/graphics/RenderNode;->getMatrix(Landroid/graphics/Matrix;)V
+HSPLandroid/graphics/RenderNode;->getMatrix(Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
HSPLandroid/graphics/RenderNode;->getPivotY()F
HSPLandroid/graphics/RenderNode;->getRotationX()F
HSPLandroid/graphics/RenderNode;->getRotationY()F
@@ -6734,7 +6762,7 @@ HSPLandroid/graphics/RenderNode;->offsetTopAndBottom(I)Z
HSPLandroid/graphics/RenderNode;->removePositionUpdateListener(Landroid/graphics/RenderNode$PositionUpdateListener;)V
HSPLandroid/graphics/RenderNode;->setAlpha(F)Z
HSPLandroid/graphics/RenderNode;->setAmbientShadowColor(I)Z
-HSPLandroid/graphics/RenderNode;->setAnimationMatrix(Landroid/graphics/Matrix;)Z+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/graphics/RenderNode;->setAnimationMatrix(Landroid/graphics/Matrix;)Z
HSPLandroid/graphics/RenderNode;->setClipToBounds(Z)Z
HSPLandroid/graphics/RenderNode;->setClipToOutline(Z)Z
HSPLandroid/graphics/RenderNode;->setElevation(F)Z
@@ -6771,7 +6799,7 @@ HSPLandroid/graphics/Shader;->detectColorSpace([J)Landroid/graphics/ColorSpace;
HSPLandroid/graphics/Shader;->discardNativeInstance()V
HSPLandroid/graphics/Shader;->discardNativeInstanceLocked()V
HSPLandroid/graphics/Shader;->getNativeInstance()J
-HSPLandroid/graphics/Shader;->getNativeInstance(Z)J+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Shader;Landroid/graphics/BitmapShader;,Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Shader;->getNativeInstance(Z)J
HSPLandroid/graphics/Shader;->setLocalMatrix(Landroid/graphics/Matrix;)V
HSPLandroid/graphics/Shader;->shouldDiscardNativeInstance(Z)Z
HSPLandroid/graphics/SurfaceTexture$1;->handleMessage(Landroid/os/Message;)V
@@ -6789,7 +6817,7 @@ HSPLandroid/graphics/TextureLayer;-><init>(Landroid/graphics/HardwareRenderer;J)
HSPLandroid/graphics/TextureLayer;->close()V
HSPLandroid/graphics/TextureLayer;->detachSurfaceTexture()V
HSPLandroid/graphics/Typeface$Builder;->build()Landroid/graphics/Typeface;
-HSPLandroid/graphics/Typeface$Builder;->createAssetUid(Landroid/content/res/AssetManager;Ljava/lang/String;I[Landroid/graphics/fonts/FontVariationAxis;IILjava/lang/String;)Ljava/lang/String;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/graphics/Typeface$Builder;->createAssetUid(Landroid/content/res/AssetManager;Ljava/lang/String;I[Landroid/graphics/fonts/FontVariationAxis;IILjava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
HSPLandroid/graphics/Typeface$CustomFallbackBuilder;-><init>(Landroid/graphics/fonts/FontFamily;)V
HSPLandroid/graphics/Typeface$CustomFallbackBuilder;->build()Landroid/graphics/Typeface;
HSPLandroid/graphics/Typeface$CustomFallbackBuilder;->setStyle(Landroid/graphics/fonts/FontStyle;)Landroid/graphics/Typeface$CustomFallbackBuilder;
@@ -6803,9 +6831,9 @@ HSPLandroid/graphics/Typeface;->createWeightStyle(Landroid/graphics/Typeface;IZ)
HSPLandroid/graphics/Typeface;->defaultFromStyle(I)Landroid/graphics/Typeface;
HSPLandroid/graphics/Typeface;->deserializeFontMap(Ljava/nio/ByteBuffer;Ljava/util/Map;)[J
HSPLandroid/graphics/Typeface;->equals(Ljava/lang/Object;)Z
-HSPLandroid/graphics/Typeface;->findFromCache(Landroid/content/res/AssetManager;Ljava/lang/String;)Landroid/graphics/Typeface;+]Landroid/util/LruCache;Landroid/util/LruCache;
+HSPLandroid/graphics/Typeface;->findFromCache(Landroid/content/res/AssetManager;Ljava/lang/String;)Landroid/graphics/Typeface;
HSPLandroid/graphics/Typeface;->getStyle()I
-HSPLandroid/graphics/Typeface;->getSystemDefaultTypeface(Ljava/lang/String;)Landroid/graphics/Typeface;+]Ljava/util/Map;Landroid/util/ArrayMap;
+HSPLandroid/graphics/Typeface;->getSystemDefaultTypeface(Ljava/lang/String;)Landroid/graphics/Typeface;
HSPLandroid/graphics/Typeface;->getSystemFontFamilyName()Ljava/lang/String;
HSPLandroid/graphics/Typeface;->hasFontFamily(Ljava/lang/String;)Z
HSPLandroid/graphics/Typeface;->readString(Ljava/nio/ByteBuffer;)Ljava/lang/String;
@@ -6914,7 +6942,7 @@ HSPLandroid/graphics/drawable/AnimatedVectorDrawable$2;->onAnimationEnd(Landroid
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$2;->onAnimationStart(Landroid/animation/Animator;)V
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator;-><init>(IFLjava/lang/String;)V
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator;->newInstance(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;)Landroid/animation/Animator;
-HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;-><init>(Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;Landroid/graphics/drawable/Drawable$Callback;Landroid/content/res/Resources;)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;-><init>(Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;Landroid/graphics/drawable/Drawable$Callback;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->addPendingAnimator(IFLjava/lang/String;)V
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->addTargetAnimator(Ljava/lang/String;Landroid/animation/Animator;)V
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->canApplyTheme()Z
@@ -7068,7 +7096,7 @@ HSPLandroid/graphics/drawable/ColorDrawable;-><init>(Landroid/graphics/drawable/
HSPLandroid/graphics/drawable/ColorDrawable;-><init>(Landroid/graphics/drawable/ColorDrawable$ColorState;Landroid/content/res/Resources;Landroid/graphics/drawable/ColorDrawable-IA;)V
HSPLandroid/graphics/drawable/ColorDrawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/ColorDrawable;->clearMutated()V
-HSPLandroid/graphics/drawable/ColorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;
+HSPLandroid/graphics/drawable/ColorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/graphics/drawable/ColorDrawable;->getAlpha()I
HSPLandroid/graphics/drawable/ColorDrawable;->getChangingConfigurations()I
HSPLandroid/graphics/drawable/ColorDrawable;->getColor()I
@@ -7083,7 +7111,7 @@ HSPLandroid/graphics/drawable/ColorDrawable;->setAlpha(I)V
HSPLandroid/graphics/drawable/ColorDrawable;->setColor(I)V
HSPLandroid/graphics/drawable/ColorDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
HSPLandroid/graphics/drawable/ColorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/graphics/drawable/ColorDrawable;->updateLocalState(Landroid/content/res/Resources;)V
+HSPLandroid/graphics/drawable/ColorDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;
HSPLandroid/graphics/drawable/ColorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/Drawable$ConstantState;-><init>()V
HSPLandroid/graphics/drawable/Drawable$ConstantState;->canApplyTheme()Z
@@ -7094,7 +7122,7 @@ HSPLandroid/graphics/drawable/Drawable;->applyTheme(Landroid/content/res/Resourc
HSPLandroid/graphics/drawable/Drawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/Drawable;->clearColorFilter()V
HSPLandroid/graphics/drawable/Drawable;->clearMutated()V
-HSPLandroid/graphics/drawable/Drawable;->copyBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/drawable/Drawable;->copyBounds(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/Drawable;->createFromXmlForDensity(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/Drawable;->createFromXmlInner(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/Drawable;->createFromXmlInnerForDensity(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
@@ -7110,7 +7138,7 @@ HSPLandroid/graphics/drawable/Drawable;->getIntrinsicWidth()I
HSPLandroid/graphics/drawable/Drawable;->getLayoutDirection()I
HSPLandroid/graphics/drawable/Drawable;->getLevel()I
HSPLandroid/graphics/drawable/Drawable;->getMinimumHeight()I+]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/graphics/drawable/Drawable;->getMinimumWidth()I+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/Drawable;->getMinimumWidth()I+]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/graphics/drawable/Drawable;->getOutline(Landroid/graphics/Outline;)V
HSPLandroid/graphics/drawable/Drawable;->getPadding(Landroid/graphics/Rect;)Z
HSPLandroid/graphics/drawable/Drawable;->getState()[I
@@ -7127,13 +7155,13 @@ HSPLandroid/graphics/drawable/Drawable;->onBoundsChange(Landroid/graphics/Rect;)
HSPLandroid/graphics/drawable/Drawable;->onLevelChange(I)Z
HSPLandroid/graphics/drawable/Drawable;->onStateChange([I)Z
HSPLandroid/graphics/drawable/Drawable;->parseBlendMode(ILandroid/graphics/BlendMode;)Landroid/graphics/BlendMode;
-HSPLandroid/graphics/drawable/Drawable;->resolveDensity(Landroid/content/res/Resources;I)I+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/graphics/drawable/Drawable;->resolveDensity(Landroid/content/res/Resources;I)I
HSPLandroid/graphics/drawable/Drawable;->resolveOpacity(II)I
HSPLandroid/graphics/drawable/Drawable;->scaleFromDensity(FII)F
HSPLandroid/graphics/drawable/Drawable;->scaleFromDensity(IIIZ)I
HSPLandroid/graphics/drawable/Drawable;->scheduleSelf(Ljava/lang/Runnable;J)V
HSPLandroid/graphics/drawable/Drawable;->setAutoMirrored(Z)V
-HSPLandroid/graphics/drawable/Drawable;->setBounds(IIII)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/Drawable;->setBounds(IIII)V
HSPLandroid/graphics/drawable/Drawable;->setBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/Drawable;megamorphic_types
HSPLandroid/graphics/drawable/Drawable;->setCallback(Landroid/graphics/drawable/Drawable$Callback;)V
HSPLandroid/graphics/drawable/Drawable;->setChangingConfigurations(I)V
@@ -7143,20 +7171,20 @@ HSPLandroid/graphics/drawable/Drawable;->setHotspot(FF)V
HSPLandroid/graphics/drawable/Drawable;->setLayoutDirection(I)Z
HSPLandroid/graphics/drawable/Drawable;->setLevel(I)Z
HSPLandroid/graphics/drawable/Drawable;->setSrcDensityOverride(I)V
-HSPLandroid/graphics/drawable/Drawable;->setState([I)Z+]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/graphics/drawable/Drawable;->setState([I)Z+]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/graphics/drawable/Drawable;->setTint(I)V
HSPLandroid/graphics/drawable/Drawable;->setTintList(Landroid/content/res/ColorStateList;)V
HSPLandroid/graphics/drawable/Drawable;->setTintMode(Landroid/graphics/PorterDuff$Mode;)V
-HSPLandroid/graphics/drawable/Drawable;->setVisible(ZZ)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/Drawable;->setVisible(ZZ)Z
HSPLandroid/graphics/drawable/Drawable;->unscheduleSelf(Ljava/lang/Runnable;)V
-HSPLandroid/graphics/drawable/Drawable;->updateBlendModeFilter(Landroid/graphics/BlendModeColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/BlendMode;)Landroid/graphics/BlendModeColorFilter;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BlendModeColorFilter;Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/ShapeDrawable;,Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/Drawable;->updateBlendModeFilter(Landroid/graphics/BlendModeColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/BlendMode;)Landroid/graphics/BlendModeColorFilter;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BlendModeColorFilter;Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/drawable/Drawable;megamorphic_types
HSPLandroid/graphics/drawable/Drawable;->updateTintFilter(Landroid/graphics/PorterDuffColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuffColorFilter;
HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;-><init>()V
HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;-><init>(Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback-IA;)V
HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->unwrap()Landroid/graphics/drawable/Drawable$Callback;
HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->wrap(Landroid/graphics/drawable/Drawable$Callback;)Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;
-HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;-><init>(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;Landroid/graphics/drawable/DrawableContainer;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;-><init>(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;Landroid/graphics/drawable/DrawableContainer;Landroid/content/res/Resources;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/graphics/drawable/Drawable;megamorphic_types
HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->addChild(Landroid/graphics/drawable/Drawable;)I
HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->canApplyTheme()Z
@@ -7199,11 +7227,11 @@ HSPLandroid/graphics/drawable/DrawableContainer;->getOpacity()I
HSPLandroid/graphics/drawable/DrawableContainer;->getOpticalInsets()Landroid/graphics/Insets;
HSPLandroid/graphics/drawable/DrawableContainer;->getOutline(Landroid/graphics/Outline;)V
HSPLandroid/graphics/drawable/DrawableContainer;->getPadding(Landroid/graphics/Rect;)Z
-HSPLandroid/graphics/drawable/DrawableContainer;->initializeDrawableForDisplay(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;]Landroid/graphics/drawable/DrawableContainer;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/StateListDrawable;,Lcom/android/internal/graphics/drawable/AnimationScaleListDrawable;
+HSPLandroid/graphics/drawable/DrawableContainer;->initializeDrawableForDisplay(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;]Landroid/graphics/drawable/DrawableContainer;Landroid/graphics/drawable/AnimatedStateListDrawable;,Lcom/android/internal/graphics/drawable/AnimationScaleListDrawable;,Landroid/graphics/drawable/StateListDrawable;]Landroid/graphics/drawable/Drawable;megamorphic_types
HSPLandroid/graphics/drawable/DrawableContainer;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/DrawableContainer;->isAutoMirrored()Z
HSPLandroid/graphics/drawable/DrawableContainer;->isStateful()Z
-HSPLandroid/graphics/drawable/DrawableContainer;->jumpToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/DrawableContainer;->jumpToCurrentState()V
HSPLandroid/graphics/drawable/DrawableContainer;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/DrawableContainer;->needsMirroring()Z
HSPLandroid/graphics/drawable/DrawableContainer;->onBoundsChange(Landroid/graphics/Rect;)V
@@ -7237,27 +7265,27 @@ HSPLandroid/graphics/drawable/DrawableWrapper;->applyTheme(Landroid/content/res/
HSPLandroid/graphics/drawable/DrawableWrapper;->canApplyTheme()Z
HSPLandroid/graphics/drawable/DrawableWrapper;->clearMutated()V
HSPLandroid/graphics/drawable/DrawableWrapper;->draw(Landroid/graphics/Canvas;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->getChangingConfigurations()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;Landroid/graphics/drawable/InsetDrawable$InsetState;
+HSPLandroid/graphics/drawable/DrawableWrapper;->getChangingConfigurations()I
HSPLandroid/graphics/drawable/DrawableWrapper;->getColorFilter()Landroid/graphics/ColorFilter;
HSPLandroid/graphics/drawable/DrawableWrapper;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
HSPLandroid/graphics/drawable/DrawableWrapper;->getDrawable()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/DrawableWrapper;->getIntrinsicHeight()I
HSPLandroid/graphics/drawable/DrawableWrapper;->getIntrinsicWidth()I
HSPLandroid/graphics/drawable/DrawableWrapper;->getOpacity()I
-HSPLandroid/graphics/drawable/DrawableWrapper;->getPadding(Landroid/graphics/Rect;)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->getPadding(Landroid/graphics/Rect;)Z
HSPLandroid/graphics/drawable/DrawableWrapper;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/DrawableWrapper;->inflateChildDrawable(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable$Callback;Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/drawable/DrawableWrapper;Landroid/graphics/drawable/InsetDrawable;
+HSPLandroid/graphics/drawable/DrawableWrapper;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/DrawableWrapper;->isStateful()Z
HSPLandroid/graphics/drawable/DrawableWrapper;->jumpToCurrentState()V
HSPLandroid/graphics/drawable/DrawableWrapper;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/DrawableWrapper;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
HSPLandroid/graphics/drawable/DrawableWrapper;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/DrawableWrapper;->onLevelChange(I)Z
-HSPLandroid/graphics/drawable/DrawableWrapper;->onStateChange([I)Z+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->onStateChange([I)Z
HSPLandroid/graphics/drawable/DrawableWrapper;->setAlpha(I)V
HSPLandroid/graphics/drawable/DrawableWrapper;->setColorFilter(Landroid/graphics/ColorFilter;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->setDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->setDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/DrawableWrapper;->setHotspot(FF)V
HSPLandroid/graphics/drawable/DrawableWrapper;->setTintBlendMode(Landroid/graphics/BlendMode;)V
HSPLandroid/graphics/drawable/DrawableWrapper;->setTintList(Landroid/content/res/ColorStateList;)V
@@ -7266,7 +7294,7 @@ HSPLandroid/graphics/drawable/DrawableWrapper;->updateLocalState(Landroid/conten
HSPLandroid/graphics/drawable/DrawableWrapper;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->-$$Nest$mcomputeOpacity(Landroid/graphics/drawable/GradientDrawable$GradientState;)V
HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$GradientState;Landroid/content/res/Resources;)V
-HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$Orientation;[I)V
+HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$Orientation;[I)V+]Landroid/graphics/drawable/GradientDrawable$GradientState;Landroid/graphics/drawable/GradientDrawable$GradientState;
HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->applyDensityScaling(II)V
HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->canApplyTheme()Z
HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->computeOpacity()V
@@ -7287,8 +7315,8 @@ HSPLandroid/graphics/drawable/GradientDrawable;->applyTheme(Landroid/content/res
HSPLandroid/graphics/drawable/GradientDrawable;->applyThemeChildElements(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/GradientDrawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/GradientDrawable;->clearMutated()V
-HSPLandroid/graphics/drawable/GradientDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Paint;Landroid/graphics/Paint;
-HSPLandroid/graphics/drawable/GradientDrawable;->ensureValidRect()Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/GradientDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;,Landroid/graphics/Canvas;
+HSPLandroid/graphics/drawable/GradientDrawable;->ensureValidRect()Z
HSPLandroid/graphics/drawable/GradientDrawable;->getChangingConfigurations()I
HSPLandroid/graphics/drawable/GradientDrawable;->getColorFilter()Landroid/graphics/ColorFilter;
HSPLandroid/graphics/drawable/GradientDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
@@ -7308,7 +7336,7 @@ HSPLandroid/graphics/drawable/GradientDrawable;->mutate()Landroid/graphics/drawa
HSPLandroid/graphics/drawable/GradientDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/GradientDrawable;->onLevelChange(I)Z
HSPLandroid/graphics/drawable/GradientDrawable;->onStateChange([I)Z
-HSPLandroid/graphics/drawable/GradientDrawable;->setAlpha(I)V
+HSPLandroid/graphics/drawable/GradientDrawable;->setAlpha(I)V+]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
HSPLandroid/graphics/drawable/GradientDrawable;->setColor(I)V
HSPLandroid/graphics/drawable/GradientDrawable;->setColor(Landroid/content/res/ColorStateList;)V
HSPLandroid/graphics/drawable/GradientDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
@@ -7329,7 +7357,7 @@ HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawablePadding(L
HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableSize(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableSolid(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableStroke(Landroid/content/res/TypedArray;)V
-HSPLandroid/graphics/drawable/GradientDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/GradientDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/Paint;Landroid/graphics/Paint;
HSPLandroid/graphics/drawable/GradientDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/Icon$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/drawable/Icon;
HSPLandroid/graphics/drawable/Icon$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -7354,7 +7382,7 @@ HSPLandroid/graphics/drawable/Icon;->setBitmap(Landroid/graphics/Bitmap;)V
HSPLandroid/graphics/drawable/Icon;->setTint(I)Landroid/graphics/drawable/Icon;
HSPLandroid/graphics/drawable/Icon;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->-$$Nest$fputmThemeAttrs(Landroid/graphics/drawable/InsetDrawable$InsetState;[I)V
-HSPLandroid/graphics/drawable/InsetDrawable$InsetState;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable$InsetState;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;)V
HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->applyDensityScaling(II)V
HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->onDensityChanged(II)V
@@ -7370,19 +7398,19 @@ HSPLandroid/graphics/drawable/InsetDrawable;-><init>(Landroid/graphics/drawable/
HSPLandroid/graphics/drawable/InsetDrawable;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;Landroid/graphics/drawable/InsetDrawable-IA;)V
HSPLandroid/graphics/drawable/InsetDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/InsetDrawable;->getInset(Landroid/content/res/TypedArray;ILandroid/graphics/drawable/InsetDrawable$InsetValue;)Landroid/graphics/drawable/InsetDrawable$InsetValue;
-HSPLandroid/graphics/drawable/InsetDrawable;->getInsets(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;]Landroid/graphics/drawable/InsetDrawable;missing_types
-HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicHeight()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
-HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
+HSPLandroid/graphics/drawable/InsetDrawable;->getInsets(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/InsetDrawable;Landroid/graphics/drawable/InsetDrawable;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicHeight()I
+HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicWidth()I
HSPLandroid/graphics/drawable/InsetDrawable;->getOpacity()I
-HSPLandroid/graphics/drawable/InsetDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
+HSPLandroid/graphics/drawable/InsetDrawable;->getOutline(Landroid/graphics/Outline;)V
HSPLandroid/graphics/drawable/InsetDrawable;->getPadding(Landroid/graphics/Rect;)Z
HSPLandroid/graphics/drawable/InsetDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/InsetDrawable;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
-HSPLandroid/graphics/drawable/InsetDrawable;->onBoundsChange(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/InsetDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/InsetDrawable;->verifyRequiredAttributes(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(I)V
-HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/graphics/drawable/LayerDrawable;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/graphics/drawable/LayerDrawable;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;missing_types]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->applyDensityScaling(II)V
HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->setDensity(I)V
@@ -7402,11 +7430,11 @@ HSPLandroid/graphics/drawable/LayerDrawable$LayerState;->newDrawable(Landroid/co
HSPLandroid/graphics/drawable/LayerDrawable$LayerState;->onDensityChanged(II)V
HSPLandroid/graphics/drawable/LayerDrawable$LayerState;->setDensity(I)V
HSPLandroid/graphics/drawable/LayerDrawable;-><init>()V
-HSPLandroid/graphics/drawable/LayerDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/content/res/Resources;)V
HSPLandroid/graphics/drawable/LayerDrawable;-><init>([Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/LayerDrawable;-><init>([Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/LayerDrawable$LayerState;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/Drawable;[IIIIII)Landroid/graphics/drawable/LayerDrawable$ChildDrawable;+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;missing_types
-HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;)I+]Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/graphics/drawable/RippleDrawable$RippleState;
+HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/Drawable;[IIIIII)Landroid/graphics/drawable/LayerDrawable$ChildDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;)I
HSPLandroid/graphics/drawable/LayerDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/LayerDrawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/LayerDrawable;->clearMutated()V
@@ -7420,23 +7448,23 @@ HSPLandroid/graphics/drawable/LayerDrawable;->findIndexByLayerId(I)I
HSPLandroid/graphics/drawable/LayerDrawable;->getChangingConfigurations()I
HSPLandroid/graphics/drawable/LayerDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
HSPLandroid/graphics/drawable/LayerDrawable;->getDrawable(I)Landroid/graphics/drawable/Drawable;
-HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicHeight()I+]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicHeight()I
+HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicWidth()I
HSPLandroid/graphics/drawable/LayerDrawable;->getNumberOfLayers()I
HSPLandroid/graphics/drawable/LayerDrawable;->getOpacity()I
-HSPLandroid/graphics/drawable/LayerDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
-HSPLandroid/graphics/drawable/LayerDrawable;->getPadding(Landroid/graphics/Rect;)Z+]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->getOutline(Landroid/graphics/Outline;)V
+HSPLandroid/graphics/drawable/LayerDrawable;->getPadding(Landroid/graphics/Rect;)Z
HSPLandroid/graphics/drawable/LayerDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/LayerDrawable;->inflateLayers(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/graphics/drawable/LayerDrawable$LayerState;,Landroid/graphics/drawable/RippleDrawable$RippleState;]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/LayerDrawable;->isAutoMirrored()Z
HSPLandroid/graphics/drawable/LayerDrawable;->isProjected()Z
HSPLandroid/graphics/drawable/LayerDrawable;->isStateful()Z
-HSPLandroid/graphics/drawable/LayerDrawable;->jumpToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->jumpToCurrentState()V
HSPLandroid/graphics/drawable/LayerDrawable;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/LayerDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
-HSPLandroid/graphics/drawable/LayerDrawable;->refreshChildPadding(ILandroid/graphics/drawable/LayerDrawable$ChildDrawable;)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/LayerDrawable;->refreshChildPadding(ILandroid/graphics/drawable/LayerDrawable$ChildDrawable;)Z
HSPLandroid/graphics/drawable/LayerDrawable;->refreshPadding()V
HSPLandroid/graphics/drawable/LayerDrawable;->resolveGravity(IIIII)I
HSPLandroid/graphics/drawable/LayerDrawable;->resumeChildInvalidation()V
@@ -7452,10 +7480,10 @@ HSPLandroid/graphics/drawable/LayerDrawable;->setLayerInset(IIIII)V
HSPLandroid/graphics/drawable/LayerDrawable;->setPaddingMode(I)V
HSPLandroid/graphics/drawable/LayerDrawable;->setTintBlendMode(Landroid/graphics/BlendMode;)V
HSPLandroid/graphics/drawable/LayerDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->setVisible(ZZ)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->setVisible(ZZ)Z
HSPLandroid/graphics/drawable/LayerDrawable;->suspendChildInvalidation()V
HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBounds(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBoundsInternal(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBoundsInternal(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerFromTypedArray(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/LayerDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/NinePatchDrawable$$ExternalSyntheticLambda0;->onHeaderDecoded(Landroid/graphics/ImageDecoder;Landroid/graphics/ImageDecoder$ImageInfo;Landroid/graphics/ImageDecoder$Source;)V
@@ -7552,12 +7580,12 @@ HSPLandroid/graphics/drawable/RippleDrawable$RippleState;->newDrawable()Landroid
HSPLandroid/graphics/drawable/RippleDrawable$RippleState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/RippleDrawable$RippleState;->onDensityChanged(II)V
HSPLandroid/graphics/drawable/RippleDrawable;-><init>()V
-HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/content/res/ColorStateList;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/RippleDrawable;missing_types
-HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/content/res/ColorStateList;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;)V
HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;Landroid/graphics/drawable/RippleDrawable-IA;)V
HSPLandroid/graphics/drawable/RippleDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/RippleDrawable;->canApplyTheme()Z
-HSPLandroid/graphics/drawable/RippleDrawable;->cancelExitingRipples()V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->cancelExitingRipples()V
HSPLandroid/graphics/drawable/RippleDrawable;->clearHotspots()V
HSPLandroid/graphics/drawable/RippleDrawable;->computeRadius()F
HSPLandroid/graphics/drawable/RippleDrawable;->createAnimationProperties(FFFFFF)Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;
@@ -7566,27 +7594,27 @@ HSPLandroid/graphics/drawable/RippleDrawable;->createConstantState(Landroid/grap
HSPLandroid/graphics/drawable/RippleDrawable;->draw(Landroid/graphics/Canvas;)V
HSPLandroid/graphics/drawable/RippleDrawable;->drawBackgroundAndRipples(Landroid/graphics/Canvas;)V
HSPLandroid/graphics/drawable/RippleDrawable;->drawContent(Landroid/graphics/Canvas;)V
-HSPLandroid/graphics/drawable/RippleDrawable;->drawPatterned(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;]Landroid/graphics/drawable/RippleDrawable;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/RippleDrawable;->drawPatterned(Landroid/graphics/Canvas;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;
HSPLandroid/graphics/drawable/RippleDrawable;->drawPatternedBackground(Landroid/graphics/Canvas;FF)V
HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedAnimation()V
-HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedBackgroundAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedBackgroundAnimation()V
HSPLandroid/graphics/drawable/RippleDrawable;->getComputedRadius()I
HSPLandroid/graphics/drawable/RippleDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
-HSPLandroid/graphics/drawable/RippleDrawable;->getDirtyBounds()Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->getDirtyBounds()Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
HSPLandroid/graphics/drawable/RippleDrawable;->getMaskType()I
HSPLandroid/graphics/drawable/RippleDrawable;->getOpacity()I
HSPLandroid/graphics/drawable/RippleDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/StateListDrawable;
HSPLandroid/graphics/drawable/RippleDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf()V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf()V
HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf(Z)V
-HSPLandroid/graphics/drawable/RippleDrawable;->isBounded()Z+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->isBounded()Z
HSPLandroid/graphics/drawable/RippleDrawable;->isProjected()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
HSPLandroid/graphics/drawable/RippleDrawable;->isStateful()Z
HSPLandroid/graphics/drawable/RippleDrawable;->jumpToCurrentState()V
HSPLandroid/graphics/drawable/RippleDrawable;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/RippleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/RippleDrawable;->onHotspotBoundsChanged()V
-HSPLandroid/graphics/drawable/RippleDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->onStateChange([I)Z
HSPLandroid/graphics/drawable/RippleDrawable;->pruneRipples()V
HSPLandroid/graphics/drawable/RippleDrawable;->setBackgroundActive(ZZZZ)V
HSPLandroid/graphics/drawable/RippleDrawable;->setColor(Landroid/content/res/ColorStateList;)V
@@ -7595,11 +7623,11 @@ HSPLandroid/graphics/drawable/RippleDrawable;->setHotspotBounds(IIII)V
HSPLandroid/graphics/drawable/RippleDrawable;->setPaddingMode(I)V
HSPLandroid/graphics/drawable/RippleDrawable;->setRippleActive(Z)V
HSPLandroid/graphics/drawable/RippleDrawable;->setVisible(ZZ)Z
-HSPLandroid/graphics/drawable/RippleDrawable;->startBackgroundAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/graphics/drawable/RippleDrawable;->startBackgroundAnimation()V
HSPLandroid/graphics/drawable/RippleDrawable;->tryRippleEnter()V
HSPLandroid/graphics/drawable/RippleDrawable;->updateLocalState()V
HSPLandroid/graphics/drawable/RippleDrawable;->updateMaskShaderIfNeeded()V
-HSPLandroid/graphics/drawable/RippleDrawable;->updateRipplePaint()Landroid/graphics/Paint;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BitmapShader;Landroid/graphics/BitmapShader;]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/PorterDuffColorFilter;Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/drawable/RippleShader;Landroid/graphics/drawable/RippleShader;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/RippleDrawable;->updateRipplePaint()Landroid/graphics/Paint;
HSPLandroid/graphics/drawable/RippleDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/RippleDrawable;->verifyRequiredAttributes(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/RippleForeground$1;->onAnimationEnd(Landroid/animation/Animator;)V
@@ -7659,7 +7687,7 @@ HSPLandroid/graphics/drawable/ScaleDrawable;->draw(Landroid/graphics/Canvas;)V
HSPLandroid/graphics/drawable/ScaleDrawable;->getPercent(Landroid/content/res/TypedArray;IF)F
HSPLandroid/graphics/drawable/ScaleDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/ScaleDrawable;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
-HSPLandroid/graphics/drawable/ScaleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
+HSPLandroid/graphics/drawable/ScaleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/ScaleDrawable;Landroid/graphics/drawable/ScaleDrawable;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/StateListDrawable;
HSPLandroid/graphics/drawable/ScaleDrawable;->onLevelChange(I)Z
HSPLandroid/graphics/drawable/ScaleDrawable;->updateLocalState()V
HSPLandroid/graphics/drawable/ScaleDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
@@ -7677,7 +7705,7 @@ HSPLandroid/graphics/drawable/ShapeDrawable;->getOpacity()I
HSPLandroid/graphics/drawable/ShapeDrawable;->getOutline(Landroid/graphics/Outline;)V
HSPLandroid/graphics/drawable/ShapeDrawable;->getPadding(Landroid/graphics/Rect;)Z
HSPLandroid/graphics/drawable/ShapeDrawable;->getPaint()Landroid/graphics/Paint;
-HSPLandroid/graphics/drawable/ShapeDrawable;->isStateful()Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;
+HSPLandroid/graphics/drawable/ShapeDrawable;->isStateful()Z
HSPLandroid/graphics/drawable/ShapeDrawable;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/ShapeDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/ShapeDrawable;->onDraw(Landroid/graphics/drawable/shapes/Shape;Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
@@ -7687,7 +7715,7 @@ HSPLandroid/graphics/drawable/ShapeDrawable;->setIntrinsicWidth(I)V
HSPLandroid/graphics/drawable/ShapeDrawable;->setShape(Landroid/graphics/drawable/shapes/Shape;)V
HSPLandroid/graphics/drawable/ShapeDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
HSPLandroid/graphics/drawable/ShapeDrawable;->updateLocalState()V
-HSPLandroid/graphics/drawable/ShapeDrawable;->updateShape()V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/ShapeDrawable;Landroid/graphics/drawable/PaintDrawable;]Landroid/graphics/drawable/shapes/Shape;Landroid/graphics/drawable/shapes/OvalShape;,Landroid/graphics/drawable/shapes/RoundRectShape;
+HSPLandroid/graphics/drawable/ShapeDrawable;->updateShape()V
HSPLandroid/graphics/drawable/StateListDrawable$StateListState;-><init>(Landroid/graphics/drawable/StateListDrawable$StateListState;Landroid/graphics/drawable/StateListDrawable;Landroid/content/res/Resources;)V
HSPLandroid/graphics/drawable/StateListDrawable$StateListState;->addStateSet([ILandroid/graphics/drawable/Drawable;)I
HSPLandroid/graphics/drawable/StateListDrawable$StateListState;->canApplyTheme()Z
@@ -7736,23 +7764,23 @@ HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->getProperty(Ljava/lang/
HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->getPropertyIndex(Ljava/lang/String;)I
HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->inflate(Landroid/content/res/Resources;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->isStateful()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->onStateChange([I)Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;
-HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;,Landroid/content/res/GradientColor;]Landroid/content/res/GradientColor;Landroid/content/res/GradientColor;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/Shader;Landroid/graphics/LinearGradient;]Ljava/lang/String;Ljava/lang/String;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->-$$Nest$fgetmChangingConfigurations(Landroid/graphics/drawable/VectorDrawable$VGroup;)I
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->-$$Nest$fgetmNativePtr(Landroid/graphics/drawable/VectorDrawable$VGroup;)J
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>()V
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>(Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/util/ArrayMap;)V+]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->addChild(Landroid/graphics/drawable/VectorDrawable$VObject;)V+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>(Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->addChild(Landroid/graphics/drawable/VectorDrawable$VObject;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VGroup;,Landroid/graphics/drawable/VectorDrawable$VFullPath;
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->canApplyTheme()Z
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getGroupName()Ljava/lang/String;
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativePtr()J
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativeSize()I+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativeSize()I
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getProperty(Ljava/lang/String;)Landroid/util/Property;
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->inflate(Landroid/content/res/Resources;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->isStateful()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->onStateChange([I)Z+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setTree(Lcom/android/internal/util/VirtualRefBasePtr;)V+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setTree(Lcom/android/internal/util/VirtualRefBasePtr;)V
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/VectorDrawable$VObject;-><init>()V
HSPLandroid/graphics/drawable/VectorDrawable$VObject;->isTreeValid()Z
@@ -7766,21 +7794,21 @@ HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;-><init>(Landro
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->applyDensityScaling(II)V
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canApplyTheme()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canReuseCache()Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canReuseCache()Z
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTree(Landroid/graphics/drawable/VectorDrawable$VGroup;)V
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTreeFromCopy(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VGroup;)V+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTreeFromCopy(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VGroup;)V
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->finalize()V
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getAlpha()F+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getAlpha()F
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getChangingConfigurations()I
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getNativeRenderer()J+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->isStateful()Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getNativeRenderer()J
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->isStateful()Z
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->newDrawable()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onStateChange([I)Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onTreeConstructionFinished()V+]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onTreeConstructionFinished()V+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setAlpha(F)Z
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setDensity(I)Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setViewportSize(FF)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setViewportSize(FF)V
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->updateCacheStates()V
HSPLandroid/graphics/drawable/VectorDrawable;->-$$Nest$smnAddChild(JJ)V
HSPLandroid/graphics/drawable/VectorDrawable;->-$$Nest$smnCreateFullPath()J
@@ -7803,37 +7831,37 @@ HSPLandroid/graphics/drawable/VectorDrawable;->-$$Nest$smnUpdateGroupProperties(
HSPLandroid/graphics/drawable/VectorDrawable;-><init>()V
HSPLandroid/graphics/drawable/VectorDrawable;-><init>(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/content/res/Resources;)V
HSPLandroid/graphics/drawable/VectorDrawable;-><init>(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/content/res/Resources;Landroid/graphics/drawable/VectorDrawable-IA;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/graphics/drawable/VectorDrawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/VectorDrawable;->clearMutated()V
HSPLandroid/graphics/drawable/VectorDrawable;->computeVectorSize()V
-HSPLandroid/graphics/drawable/VectorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/ColorFilter;Landroid/graphics/BlendModeColorFilter;,Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
-HSPLandroid/graphics/drawable/VectorDrawable;->getAlpha()I+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->draw(Landroid/graphics/Canvas;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->getAlpha()I
HSPLandroid/graphics/drawable/VectorDrawable;->getChangingConfigurations()I
HSPLandroid/graphics/drawable/VectorDrawable;->getColorFilter()Landroid/graphics/ColorFilter;
HSPLandroid/graphics/drawable/VectorDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicHeight()I
-HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicWidth()I
HSPLandroid/graphics/drawable/VectorDrawable;->getNativeTree()J
HSPLandroid/graphics/drawable/VectorDrawable;->getOpacity()I
HSPLandroid/graphics/drawable/VectorDrawable;->getPixelSize()F
HSPLandroid/graphics/drawable/VectorDrawable;->getTargetByName(Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/graphics/drawable/VectorDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
-HSPLandroid/graphics/drawable/VectorDrawable;->inflateChildElements(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VClipPath;Landroid/graphics/drawable/VectorDrawable$VClipPath;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/Stack;Ljava/util/Stack;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/graphics/drawable/VectorDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
+HSPLandroid/graphics/drawable/VectorDrawable;->inflateChildElements(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/Stack;Ljava/util/Stack;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;
HSPLandroid/graphics/drawable/VectorDrawable;->isAutoMirrored()Z
-HSPLandroid/graphics/drawable/VectorDrawable;->isStateful()Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->isStateful()Z
HSPLandroid/graphics/drawable/VectorDrawable;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/VectorDrawable;->needMirroring()Z
-HSPLandroid/graphics/drawable/VectorDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->onStateChange([I)Z
HSPLandroid/graphics/drawable/VectorDrawable;->setAllowCaching(Z)V
HSPLandroid/graphics/drawable/VectorDrawable;->setAlpha(I)V
HSPLandroid/graphics/drawable/VectorDrawable;->setAutoMirrored(Z)V
HSPLandroid/graphics/drawable/VectorDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
HSPLandroid/graphics/drawable/VectorDrawable;->setTintBlendMode(Landroid/graphics/BlendMode;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
-HSPLandroid/graphics/drawable/VectorDrawable;->updateColorFilters(Landroid/graphics/BlendMode;Landroid/content/res/ColorStateList;)V+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->updateColorFilters(Landroid/graphics/BlendMode;Landroid/content/res/ColorStateList;)V
HSPLandroid/graphics/drawable/VectorDrawable;->updateLocalState(Landroid/content/res/Resources;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/graphics/drawable/shapes/OvalShape;-><init>()V
HSPLandroid/graphics/drawable/shapes/OvalShape;->draw(Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
HSPLandroid/graphics/drawable/shapes/OvalShape;->getOutline(Landroid/graphics/Outline;)V
@@ -7910,13 +7938,13 @@ HSPLandroid/graphics/text/LineBreaker;->computeLineBreaks(Landroid/graphics/text
HSPLandroid/graphics/text/MeasuredText$Builder;-><init>([C)V
HSPLandroid/graphics/text/MeasuredText$Builder;->appendReplacementRun(Landroid/graphics/Paint;IF)Landroid/graphics/text/MeasuredText$Builder;
HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;IZ)Landroid/graphics/text/MeasuredText$Builder;
-HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;Landroid/graphics/text/LineBreakConfig;IZ)Landroid/graphics/text/MeasuredText$Builder;+]Landroid/graphics/Paint;Landroid/text/TextPaint;
+HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;Landroid/graphics/text/LineBreakConfig;IZ)Landroid/graphics/text/MeasuredText$Builder;
HSPLandroid/graphics/text/MeasuredText$Builder;->build()Landroid/graphics/text/MeasuredText;
HSPLandroid/graphics/text/MeasuredText$Builder;->ensureNativePtrNoReuse()V
HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeHyphenation(I)Landroid/graphics/text/MeasuredText$Builder;
HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeHyphenation(Z)Landroid/graphics/text/MeasuredText$Builder;
HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeLayout(Z)Landroid/graphics/text/MeasuredText$Builder;
-HSPLandroid/graphics/text/MeasuredText;->getCharWidthAt(I)F+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/graphics/text/MeasuredText;->getCharWidthAt(I)F
HSPLandroid/graphics/text/MeasuredText;->getChars()[C
HSPLandroid/graphics/text/MeasuredText;->getNativePtr()J
HSPLandroid/hardware/Camera$CameraInfo;-><init>()V
@@ -7939,6 +7967,7 @@ HSPLandroid/hardware/HardwareBuffer;->isClosed()Z
HSPLandroid/hardware/ICameraService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
HSPLandroid/hardware/ICameraService$Stub$Proxy;->addListener(Landroid/hardware/ICameraServiceListener;)[Landroid/hardware/CameraStatus;
HSPLandroid/hardware/ICameraService$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/ICameraService$Stub$Proxy;->getCameraCharacteristics(Ljava/lang/String;IZ)Landroid/hardware/camera2/impl/CameraMetadataNative;
HSPLandroid/hardware/ICameraService$Stub$Proxy;->getConcurrentCameraIds()[Landroid/hardware/camera2/utils/ConcurrentCameraIdCombination;
HSPLandroid/hardware/ICameraService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/ICameraService;
HSPLandroid/hardware/ICameraServiceListener$Stub;->getMaxTransactionId()I
@@ -7986,7 +8015,7 @@ HSPLandroid/hardware/SystemSensorManager$BaseEventQueue;->removeSensor(Landroid/
HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;-><init>(Landroid/hardware/SensorEventListener;Landroid/os/Looper;Landroid/hardware/SystemSensorManager;Ljava/lang/String;)V
HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->addSensorEvent(Landroid/hardware/Sensor;)V
HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchAdditionalInfoEvent(III[F[I)V
-HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchSensorEvent(I[FIJ)V+]Landroid/hardware/Sensor;Landroid/hardware/Sensor;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchSensorEvent(I[FIJ)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/hardware/Sensor;Landroid/hardware/Sensor;]Landroid/util/SparseArray;Landroid/util/SparseArray;
HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->removeSensorEvent(Landroid/hardware/Sensor;)V
HSPLandroid/hardware/SystemSensorManager$TriggerEventQueue;->addSensorEvent(Landroid/hardware/Sensor;)V
HSPLandroid/hardware/SystemSensorManager$TriggerEventQueue;->dispatchSensorEvent(I[FIJ)V
@@ -8021,11 +8050,19 @@ HSPLandroid/hardware/camera2/CameraCharacteristics;->overrideProperty(Landroid/h
HSPLandroid/hardware/camera2/CameraManager$AvailabilityCallback;-><init>()V
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;->compare(Ljava/lang/String;Ljava/lang/String;)I
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$3;-><init>(Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;Landroid/hardware/camera2/CameraManager$AvailabilityCallback;)V
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->cameraIdHasConcurrentStreamsLocked(Ljava/lang/String;)Z
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->connectCameraServiceLocked()V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->extractCameraIdListLocked()[Ljava/lang/String;
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->get()Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->getCameraIdList()[Ljava/lang/String;
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->getCameraService()Landroid/hardware/ICameraService;
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onCameraAccessPrioritiesChanged()V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onStatusChanged(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onStatusChangedLocked(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onTorchStatusChanged(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onTorchStatusChangedLocked(ILjava/lang/String;)V
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->postSingleAccessPriorityChangeUpdate(Landroid/hardware/camera2/CameraManager$AvailabilityCallback;Ljava/util/concurrent/Executor;)V
HSPLandroid/hardware/camera2/CameraManager$FoldStateListener;->addDeviceStateListener(Landroid/hardware/camera2/CameraManager$DeviceStateListener;)V
HSPLandroid/hardware/camera2/CameraManager$FoldStateListener;->handleStateChange(I)V
@@ -8035,6 +8072,7 @@ HSPLandroid/hardware/camera2/CameraManager;->getCameraIdList()[Ljava/lang/String
HSPLandroid/hardware/camera2/CameraManager;->getDisplaySize()Landroid/util/Size;
HSPLandroid/hardware/camera2/CameraManager;->getPhysicalCameraMultiResolutionConfigs(Ljava/lang/String;Landroid/hardware/camera2/impl/CameraMetadataNative;Landroid/hardware/ICameraService;)Ljava/util/Map;
HSPLandroid/hardware/camera2/CameraManager;->registerDeviceStateListener(Landroid/hardware/camera2/CameraCharacteristics;)V
+HSPLandroid/hardware/camera2/CameraManager;->shouldOverrideToPortrait(Landroid/content/Context;)Z
HSPLandroid/hardware/camera2/CameraMetadata;-><init>()V
HSPLandroid/hardware/camera2/CameraMetadata;->setNativeInstance(Landroid/hardware/camera2/impl/CameraMetadataNative;)V
HSPLandroid/hardware/camera2/impl/CameraDeviceImpl$CameraHandlerExecutor;->execute(Ljava/lang/Runnable;)V
@@ -8181,7 +8219,9 @@ HSPLandroid/hardware/display/DisplayManagerGlobal$1;-><init>(Landroid/hardware/d
HSPLandroid/hardware/display/DisplayManagerGlobal$1;->recompute(Ljava/lang/Integer;)Landroid/view/DisplayInfo;
HSPLandroid/hardware/display/DisplayManagerGlobal$1;->recompute(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate$$ExternalSyntheticLambda0;->run()V
+HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;-><init>(Landroid/hardware/display/DisplayManager$DisplayListener;Ljava/util/concurrent/Executor;JLjava/lang/String;)V
HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;->clearEvents()V
+HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;->handleDisplayEventInner(IILandroid/view/DisplayInfo;Z)V+]Landroid/view/DisplayInfo;Landroid/view/DisplayInfo;]Landroid/hardware/display/DisplayManager$DisplayListener;missing_types
HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;-><init>(Landroid/hardware/display/DisplayManagerGlobal;)V
HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;-><init>(Landroid/hardware/display/DisplayManagerGlobal;Landroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback-IA;)V
HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;->onDisplayEvent(II)V
@@ -8202,6 +8242,7 @@ HSPLandroid/hardware/display/DisplayManagerGlobal;->getPreferredWideGamutColorSp
HSPLandroid/hardware/display/DisplayManagerGlobal;->getStableDisplaySize()Landroid/graphics/Point;
HSPLandroid/hardware/display/DisplayManagerGlobal;->getWifiDisplayStatus()Landroid/hardware/display/WifiDisplayStatus;
HSPLandroid/hardware/display/DisplayManagerGlobal;->initExtraLogging()Z
+HSPLandroid/hardware/display/DisplayManagerGlobal;->maybeLogAllDisplayListeners()V
HSPLandroid/hardware/display/DisplayManagerGlobal;->registerCallbackIfNeededLocked()V
HSPLandroid/hardware/display/DisplayManagerGlobal;->registerDisplayListener(Landroid/hardware/display/DisplayManager$DisplayListener;Ljava/util/concurrent/Executor;JLjava/lang/String;)V+]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
HSPLandroid/hardware/display/DisplayManagerGlobal;->registerNativeChoreographerForRefreshRateCallbacks()V
@@ -8321,7 +8362,7 @@ HSPLandroid/hardware/location/NanoAppMessage;->getNanoAppId()J
HSPLandroid/hardware/location/NanoAppMessage;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/hardware/location/NanoAppState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/location/NanoAppState;
HSPLandroid/hardware/location/NanoAppState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/hardware/location/NanoAppState;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/hardware/location/NanoAppState;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/hardware/location/NanoAppState;->getNanoAppId()J
HSPLandroid/hardware/security/keymint/KeyParameter$1;-><init>()V
HSPLandroid/hardware/security/keymint/KeyParameter$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/security/keymint/KeyParameter;
@@ -8434,7 +8475,7 @@ HSPLandroid/icu/impl/FormattedStringBuilder;->copyFrom(Landroid/icu/impl/Formatt
HSPLandroid/icu/impl/FormattedStringBuilder;->fieldAt(I)Ljava/lang/Object;
HSPLandroid/icu/impl/FormattedStringBuilder;->getCapacity()I
HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;IILjava/lang/Object;)I
-HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;Ljava/lang/Object;)I
+HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;Ljava/lang/Object;)I+]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/icu/impl/FormattedStringBuilder;->insert(I[C[Ljava/lang/Object;)I
HSPLandroid/icu/impl/FormattedStringBuilder;->insertCodePoint(IILjava/lang/Object;)I
HSPLandroid/icu/impl/FormattedStringBuilder;->length()I
@@ -8445,7 +8486,7 @@ HSPLandroid/icu/impl/FormattedStringBuilder;->toFieldArray()[Ljava/lang/Object;
HSPLandroid/icu/impl/FormattedStringBuilder;->toString()Ljava/lang/String;
HSPLandroid/icu/impl/FormattedStringBuilder;->unwrapField(Ljava/lang/Object;)Ljava/text/Format$Field;
HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->isIntOrGroup(Ljava/lang/Object;)Z
-HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextFieldPosition(Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;)Z
+HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextFieldPosition(Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;)Z+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;]Ljava/text/FieldPosition;Ljava/text/DontCareFieldPosition;
HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextPosition(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/text/ConstrainedFieldPosition;Ljava/text/Format$Field;)Z+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;
HSPLandroid/icu/impl/Grego;->dayOfWeek(J)I
HSPLandroid/icu/impl/Grego;->dayToFields(J[I)[I
@@ -8466,7 +8507,7 @@ HSPLandroid/icu/impl/ICUBinary$PackageDataFile;->addBaseNamesInFolder(Ljava/lang
HSPLandroid/icu/impl/ICUBinary$PackageDataFile;->getData(Ljava/lang/String;)Ljava/nio/ByteBuffer;
HSPLandroid/icu/impl/ICUBinary;->addBaseNamesInFileFolder(Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;Ljava/nio/ByteBuffer;I)I
-HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;[BI)I
+HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;[BI)I+]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/icu/impl/ICUBinary;->getBytes(Ljava/nio/ByteBuffer;II)[B
HSPLandroid/icu/impl/ICUBinary;->getChars(Ljava/nio/ByteBuffer;II)[C
HSPLandroid/icu/impl/ICUBinary;->getData(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)Ljava/nio/ByteBuffer;
@@ -8502,7 +8543,7 @@ HSPLandroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;->add(Ljava/lang/Object;)V
HSPLandroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;->create()Landroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;
HSPLandroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;->list()Ljava/util/List;
HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collect(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;)Ljava/util/List;
-HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collectRegion(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;ILandroid/icu/impl/ICUResourceBundle;)V
+HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collectRegion(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;ILandroid/icu/impl/ICUResourceBundle;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundle;Landroid/icu/impl/ICUResourceBundleImpl$ResourceString;,Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;,Landroid/icu/impl/ICUResourceBundleImpl$ResourceArray;]Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/impl/ICUCurrencyMetaInfo$CurrencyCollector;
HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->currencies(Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;)Ljava/util/List;
HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->currencyDigits(Ljava/lang/String;Landroid/icu/util/Currency$CurrencyUsage;)Landroid/icu/text/CurrencyMetaInfo$CurrencyDigits;
HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->getDate(Landroid/icu/impl/ICUResourceBundle;JZ)J
@@ -8510,9 +8551,9 @@ HSPLandroid/icu/impl/ICUData;->checkStreamForBinaryData(Ljava/io/InputStream;Lja
HSPLandroid/icu/impl/ICUData;->getStream(Ljava/lang/ClassLoader;Ljava/lang/String;Z)Ljava/io/InputStream;
HSPLandroid/icu/impl/ICULocaleService$ICUResourceBundleFactory;->getSupportedIDs()Ljava/util/Set;
HSPLandroid/icu/impl/ICULocaleService$ICUResourceBundleFactory;->loader()Ljava/lang/ClassLoader;
-HSPLandroid/icu/impl/ICULocaleService$LocaleKey;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICULocaleService$LocaleKey;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->createWithCanonical(Landroid/icu/util/ULocale;Ljava/lang/String;I)Landroid/icu/impl/ICULocaleService$LocaleKey;
-HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentDescriptor()Ljava/lang/String;
+HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentDescriptor()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/ICULocaleService$LocaleKey;Landroid/icu/impl/ICULocaleService$LocaleKey;
HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentID()Ljava/lang/String;
HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentLocale()Landroid/icu/util/ULocale;
HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->fallback()Z
@@ -8544,20 +8585,21 @@ HSPLandroid/icu/impl/ICUResourceBundle$Loader;-><init>(Landroid/icu/impl/ICUReso
HSPLandroid/icu/impl/ICUResourceBundle$WholeBundle;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundleReader;)V
HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$mgetNoFallback(Landroid/icu/impl/ICUResourceBundle;)Z
HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$sfgetDEBUG()Z
+HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$smgetParentLocaleID(Ljava/lang/String;Ljava/lang/String;Landroid/icu/impl/ICUResourceBundle$OpenType;)Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$sminstantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
HSPLandroid/icu/impl/ICUResourceBundle;-><init>(Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;)V
HSPLandroid/icu/impl/ICUResourceBundle;->addBundleBaseNamesFromClassLoader(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/util/Set;)V
HSPLandroid/icu/impl/ICUResourceBundle;->at(I)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->at(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundle;->countPathKeys(Ljava/lang/String;)I
+HSPLandroid/icu/impl/ICUResourceBundle;->countPathKeys(Ljava/lang/String;)I+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundle;->createBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->createFullLocaleNameSet(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/util/Set;
HSPLandroid/icu/impl/ICUResourceBundle;->equals(Ljava/lang/Object;)Z
HSPLandroid/icu/impl/ICUResourceBundle;->findResourceWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->findResourceWithFallback([Ljava/lang/String;ILandroid/icu/impl/ICUResourceBundle;Landroid/icu/util/UResourceBundle;)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Ljava/lang/String;
+HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Ljava/lang/String;+]Landroid/icu/impl/ICUResourceBundleReader$Container;Landroid/icu/impl/ICUResourceBundleReader$Table;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundle;Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
HSPLandroid/icu/impl/ICUResourceBundle;->findTopLevel(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->findTopLevel(Ljava/lang/String;)Landroid/icu/util/UResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->findWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
@@ -8590,7 +8632,7 @@ HSPLandroid/icu/impl/ICUResourceBundle;->getResPathKeys([Ljava/lang/String;I)V
HSPLandroid/icu/impl/ICUResourceBundle;->getStringWithFallback(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundle;->getULocale()Landroid/icu/util/ULocale;
HSPLandroid/icu/impl/ICUResourceBundle;->getWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundle;->instantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;
+HSPLandroid/icu/impl/ICUResourceBundle;->instantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/ICUResourceBundle$OpenType;Landroid/icu/impl/ICUResourceBundle$OpenType;]Landroid/icu/impl/CacheBase;Landroid/icu/impl/ICUResourceBundle$1;
HSPLandroid/icu/impl/ICUResourceBundle;->setParent(Ljava/util/ResourceBundle;)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceArray;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceArray;->getStringArray()[Ljava/lang/String;
@@ -8602,22 +8644,22 @@ HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceBinary;->getBinary([B)[B
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->createBundleObject(ILjava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getContainerResource(I)I
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getContainerResource(I)I+]Landroid/icu/impl/ICUResourceBundleReader$Container;Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getSize()I
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getString(I)Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceInt;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceInt;->getInt()I
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceIntVector;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceIntVector;->getIntVector()[I
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;->getString()Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;->getType()I
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;I)V
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V+]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->findString(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->getType()I
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(ILjava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(Ljava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(Ljava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;+]Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGetObject(Ljava/lang/String;)Ljava/lang/Object;
HSPLandroid/icu/impl/ICUResourceBundleImpl;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
HSPLandroid/icu/impl/ICUResourceBundleImpl;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
@@ -8648,13 +8690,13 @@ HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getStringArray()[Ljav
HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getStringArray(Landroid/icu/impl/ICUResourceBundleReader$Array;)[Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getTable()Landroid/icu/impl/UResource$Table;
HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getType()I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->get(I)Ljava/lang/Object;
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->get(I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;-><init>(I)V
HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->findSimple(I)I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->get(I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->get(I)Ljava/lang/Object;+]Ljava/lang/ref/SoftReference;Ljava/lang/ref/SoftReference;]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->makeKey(I)I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfCleared([Ljava/lang/Object;ILjava/lang/Object;I)Ljava/lang/Object;
HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->storeDirectly(I)Z
HSPLandroid/icu/impl/ICUResourceBundleReader$Table1632;-><init>(Landroid/icu/impl/ICUResourceBundleReader;I)V
@@ -8664,7 +8706,7 @@ HSPLandroid/icu/impl/ICUResourceBundleReader$Table;-><init>()V
HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->findTableItem(Landroid/icu/impl/ICUResourceBundleReader;Ljava/lang/CharSequence;)I
HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->findValue(Ljava/lang/CharSequence;Landroid/icu/impl/UResource$Value;)Z
HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKey(Landroid/icu/impl/ICUResourceBundleReader;I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKeyAndValue(ILandroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)Z
+HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKeyAndValue(ILandroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)Z+]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getResource(Landroid/icu/impl/ICUResourceBundleReader;Ljava/lang/String;)I
HSPLandroid/icu/impl/ICUResourceBundleReader;->-$$Nest$fgetb16BitUnits(Landroid/icu/impl/ICUResourceBundleReader;)Ljava/nio/CharBuffer;
HSPLandroid/icu/impl/ICUResourceBundleReader;->-$$Nest$fgetpoolStringIndex16Limit(Landroid/icu/impl/ICUResourceBundleReader;)I
@@ -8688,7 +8730,7 @@ HSPLandroid/icu/impl/ICUResourceBundleReader;->getAlias(I)Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundleReader;->getArray(I)Landroid/icu/impl/ICUResourceBundleReader$Array;
HSPLandroid/icu/impl/ICUResourceBundleReader;->getBinary(I[B)[B
HSPLandroid/icu/impl/ICUResourceBundleReader;->getChars(II)[C
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getFullName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getFullName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/icu/impl/ICUResourceBundleReader;->getIndexesInt(I)I
HSPLandroid/icu/impl/ICUResourceBundleReader;->getInt(I)I
HSPLandroid/icu/impl/ICUResourceBundleReader;->getIntVector(I)[I
@@ -8698,10 +8740,10 @@ HSPLandroid/icu/impl/ICUResourceBundleReader;->getNoFallback()Z
HSPLandroid/icu/impl/ICUResourceBundleReader;->getReader(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)Landroid/icu/impl/ICUResourceBundleReader;
HSPLandroid/icu/impl/ICUResourceBundleReader;->getResourceByteOffset(I)I
HSPLandroid/icu/impl/ICUResourceBundleReader;->getRootResource()I
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getString(I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getStringV2(I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable(I)Landroid/icu/impl/ICUResourceBundleReader$Table;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable16KeyOffsets(I)[C
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getString(I)Ljava/lang/String;+]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getStringV2(I)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;]Ljava/nio/CharBuffer;Ljava/nio/ByteBufferAsCharBuffer;]Ljava/lang/CharSequence;Ljava/nio/ByteBufferAsCharBuffer;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable(I)Landroid/icu/impl/ICUResourceBundleReader$Table;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table16;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable16KeyOffsets(I)[C+]Ljava/nio/CharBuffer;Ljava/nio/ByteBufferAsCharBuffer;
HSPLandroid/icu/impl/ICUResourceBundleReader;->getTableKeyOffsets(I)[C
HSPLandroid/icu/impl/ICUResourceBundleReader;->init(Ljava/nio/ByteBuffer;)V
HSPLandroid/icu/impl/ICUResourceBundleReader;->makeKeyStringFromBytes([BI)Ljava/lang/String;
@@ -8711,10 +8753,10 @@ HSPLandroid/icu/impl/ICUService$CacheEntry;-><init>(Ljava/lang/String;Ljava/lang
HSPLandroid/icu/impl/ICUService$Key;-><init>(Ljava/lang/String;)V
HSPLandroid/icu/impl/ICUService;->clearServiceCache()V
HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;Landroid/icu/impl/ICUService$Factory;)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;Landroid/icu/impl/ICUService$Factory;)Ljava/lang/Object;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/Map;Ljava/util/concurrent/ConcurrentHashMap;]Landroid/icu/impl/ICURWLock;Landroid/icu/impl/ICURWLock;]Landroid/icu/impl/ICUService$Key;Landroid/icu/impl/ICULocaleService$LocaleKey;
HSPLandroid/icu/impl/ICUService;->isDefault()Z
-HSPLandroid/icu/impl/IDNA2003;->convertIDNToASCII(Ljava/lang/String;I)Ljava/lang/StringBuffer;
-HSPLandroid/icu/impl/IDNA2003;->convertToASCII(Landroid/icu/text/UCharacterIterator;I)Ljava/lang/StringBuffer;
+HSPLandroid/icu/impl/IDNA2003;->convertIDNToASCII(Ljava/lang/String;I)Ljava/lang/StringBuffer;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
+HSPLandroid/icu/impl/IDNA2003;->convertToASCII(Landroid/icu/text/UCharacterIterator;I)Ljava/lang/StringBuffer;+]Landroid/icu/text/UCharacterIterator;Landroid/icu/impl/ReplaceableUCharacterIterator;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
HSPLandroid/icu/impl/IDNA2003;->getSeparatorIndex([CII)I
HSPLandroid/icu/impl/IDNA2003;->isLDHChar(I)Z
HSPLandroid/icu/impl/IDNA2003;->isLabelSeparator(I)Z
@@ -8722,9 +8764,9 @@ HSPLandroid/icu/impl/LocaleIDParser$1;-><init>(Landroid/icu/impl/LocaleIDParser;
HSPLandroid/icu/impl/LocaleIDParser$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/icu/impl/LocaleIDParser$1;->compare(Ljava/lang/String;Ljava/lang/String;)I
HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;)V
-HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;Z)V
+HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;Z)V+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/LocaleIDParser;->addSeparator()V
-HSPLandroid/icu/impl/LocaleIDParser;->append(C)V
+HSPLandroid/icu/impl/LocaleIDParser;->append(C)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/icu/impl/LocaleIDParser;->append(Ljava/lang/String;)V
HSPLandroid/icu/impl/LocaleIDParser;->atTerminator()Z
HSPLandroid/icu/impl/LocaleIDParser;->getBaseName()Ljava/lang/String;
@@ -8748,10 +8790,10 @@ HSPLandroid/icu/impl/LocaleIDParser;->isTerminator(C)Z
HSPLandroid/icu/impl/LocaleIDParser;->isTerminatorOrIDSeparator(C)Z
HSPLandroid/icu/impl/LocaleIDParser;->next()C
HSPLandroid/icu/impl/LocaleIDParser;->parseBaseName()V
-HSPLandroid/icu/impl/LocaleIDParser;->parseCountry()I
+HSPLandroid/icu/impl/LocaleIDParser;->parseCountry()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/icu/impl/LocaleIDParser;->parseKeywords()I
-HSPLandroid/icu/impl/LocaleIDParser;->parseLanguage()I
-HSPLandroid/icu/impl/LocaleIDParser;->parseScript()I
+HSPLandroid/icu/impl/LocaleIDParser;->parseLanguage()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/icu/impl/LocaleIDParser;->parseScript()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/icu/impl/LocaleIDParser;->parseVariant()I
HSPLandroid/icu/impl/LocaleIDParser;->reset()V
HSPLandroid/icu/impl/LocaleIDParser;->setKeywordValue(Ljava/lang/String;Ljava/lang/String;)V
@@ -8780,7 +8822,7 @@ HSPLandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;->flushAndAppendZeroCC(Lja
HSPLandroid/icu/impl/Normalizer2Impl;->addToStartSet(Landroid/icu/util/MutableCodePointTrie;II)V
HSPLandroid/icu/impl/Normalizer2Impl;->composeQuickCheck(Ljava/lang/CharSequence;IIZZ)I
HSPLandroid/icu/impl/Normalizer2Impl;->decompose(IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)V
-HSPLandroid/icu/impl/Normalizer2Impl;->decompose(Ljava/lang/CharSequence;IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)I
+HSPLandroid/icu/impl/Normalizer2Impl;->decompose(Ljava/lang/CharSequence;IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)I+]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/icu/impl/Normalizer2Impl;->decomposeAndAppend(Ljava/lang/CharSequence;ZLandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)V
HSPLandroid/icu/impl/Normalizer2Impl;->ensureCanonIterData()Landroid/icu/impl/Normalizer2Impl;
HSPLandroid/icu/impl/Normalizer2Impl;->getRawNorm16(I)I
@@ -8810,11 +8852,11 @@ HSPLandroid/icu/impl/OlsonTimeZone;->initialDstOffset()I
HSPLandroid/icu/impl/OlsonTimeZone;->initialRawOffset()I
HSPLandroid/icu/impl/OlsonTimeZone;->isFrozen()Z
HSPLandroid/icu/impl/OlsonTimeZone;->loadRule(Landroid/icu/util/UResourceBundle;Ljava/lang/String;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/OlsonTimeZone;->toString()Ljava/lang/String;
+HSPLandroid/icu/impl/OlsonTimeZone;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/icu/impl/PatternProps;->isWhiteSpace(I)Z
HSPLandroid/icu/impl/PatternProps;->skipWhiteSpace(Ljava/lang/CharSequence;I)I
HSPLandroid/icu/impl/PatternTokenizer;-><init>()V
-HSPLandroid/icu/impl/PatternTokenizer;->next(Ljava/lang/StringBuffer;)I
+HSPLandroid/icu/impl/PatternTokenizer;->next(Ljava/lang/StringBuffer;)I+]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
HSPLandroid/icu/impl/PatternTokenizer;->quoteLiteral(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/impl/PatternTokenizer;->setExtraQuotingCharacters(Landroid/icu/text/UnicodeSet;)Landroid/icu/impl/PatternTokenizer;
HSPLandroid/icu/impl/PatternTokenizer;->setPattern(Ljava/lang/String;)Landroid/icu/impl/PatternTokenizer;
@@ -8835,7 +8877,7 @@ HSPLandroid/icu/impl/RBBIDataWrapper;->get(Ljava/nio/ByteBuffer;)Landroid/icu/im
HSPLandroid/icu/impl/ReplaceableUCharacterIterator;-><init>(Ljava/lang/String;)V
HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->getLength()I
HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->getText([CI)I
-HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->next()I
+HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->next()I+]Landroid/icu/text/Replaceable;Landroid/icu/text/ReplaceableString;
HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->setIndex(I)V
HSPLandroid/icu/impl/RuleCharacterIterator;->_advance(I)V
HSPLandroid/icu/impl/RuleCharacterIterator;->_current()I
@@ -8862,14 +8904,14 @@ HSPLandroid/icu/impl/StaticUnicodeSets;->chooseFrom(Ljava/lang/String;Landroid/i
HSPLandroid/icu/impl/StaticUnicodeSets;->get(Landroid/icu/impl/StaticUnicodeSets$Key;)Landroid/icu/text/UnicodeSet;
HSPLandroid/icu/impl/StringSegment;-><init>(Ljava/lang/String;Z)V
HSPLandroid/icu/impl/StringSegment;->adjustOffset(I)V
-HSPLandroid/icu/impl/StringSegment;->charAt(I)C+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->charAt(I)C
HSPLandroid/icu/impl/StringSegment;->codePointsEqual(IIZ)Z
-HSPLandroid/icu/impl/StringSegment;->getCodePoint()I+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->getCodePoint()I
HSPLandroid/icu/impl/StringSegment;->getCommonPrefixLength(Ljava/lang/CharSequence;)I
HSPLandroid/icu/impl/StringSegment;->getOffset()I
-HSPLandroid/icu/impl/StringSegment;->getPrefixLengthInternal(Ljava/lang/CharSequence;Z)I+]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->getPrefixLengthInternal(Ljava/lang/CharSequence;Z)I
HSPLandroid/icu/impl/StringSegment;->length()I
-HSPLandroid/icu/impl/StringSegment;->startsWith(Landroid/icu/text/UnicodeSet;)Z+]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
+HSPLandroid/icu/impl/StringSegment;->startsWith(Landroid/icu/text/UnicodeSet;)Z
HSPLandroid/icu/impl/StringSegment;->startsWith(Ljava/lang/CharSequence;)Z
HSPLandroid/icu/impl/TextTrieMap$Node;-><init>(Landroid/icu/impl/TextTrieMap;)V
HSPLandroid/icu/impl/TextTrieMap;-><init>(Z)V
@@ -8927,7 +8969,7 @@ HSPLandroid/icu/impl/Trie2_32;->get(I)I
HSPLandroid/icu/impl/Trie2_32;->getFromU16SingleLead(C)I
HSPLandroid/icu/impl/UBiDiProps;->getClass(I)I
HSPLandroid/icu/impl/UBiDiProps;->getClassFromProps(I)I
-HSPLandroid/icu/impl/UCaseProps;->fold(II)I+]Landroid/icu/impl/Trie2_16;Landroid/icu/impl/Trie2_16;
+HSPLandroid/icu/impl/UCaseProps;->fold(II)I
HSPLandroid/icu/impl/UCaseProps;->getCaseLocale(Ljava/lang/String;)I
HSPLandroid/icu/impl/UCaseProps;->getCaseLocale(Ljava/util/Locale;)I
HSPLandroid/icu/impl/UCaseProps;->getDelta(I)I
@@ -8959,7 +9001,7 @@ HSPLandroid/icu/impl/UResource$Sink;-><init>()V
HSPLandroid/icu/impl/UResource$Value;-><init>()V
HSPLandroid/icu/impl/UResource$Value;->toString()Ljava/lang/String;
HSPLandroid/icu/impl/Utility;->addExact(II)I
-HSPLandroid/icu/impl/Utility;->appendTo(Ljava/lang/CharSequence;Ljava/lang/Appendable;)Ljava/lang/Appendable;
+HSPLandroid/icu/impl/Utility;->appendTo(Ljava/lang/CharSequence;Ljava/lang/Appendable;)Ljava/lang/Appendable;+]Ljava/lang/Appendable;Ljava/lang/StringBuffer;
HSPLandroid/icu/impl/Utility;->arrayEquals([BLjava/lang/Object;)Z
HSPLandroid/icu/impl/Utility;->arrayRegionMatches([BI[BII)Z
HSPLandroid/icu/impl/Utility;->sameObjects(Ljava/lang/Object;Ljava/lang/Object;)Z
@@ -9090,9 +9132,9 @@ HSPLandroid/icu/impl/locale/BaseLocale$Key;->-$$Nest$fget_scrt(Landroid/icu/impl
HSPLandroid/icu/impl/locale/BaseLocale$Key;->-$$Nest$fget_vart(Landroid/icu/impl/locale/BaseLocale$Key;)Ljava/lang/String;
HSPLandroid/icu/impl/locale/BaseLocale$Key;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/icu/impl/locale/BaseLocale$Key;->equals(Ljava/lang/Object;)Z
-HSPLandroid/icu/impl/locale/BaseLocale$Key;->hashCode()I
+HSPLandroid/icu/impl/locale/BaseLocale$Key;->hashCode()I+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/locale/BaseLocale$Key;->normalize(Landroid/icu/impl/locale/BaseLocale$Key;)Landroid/icu/impl/locale/BaseLocale$Key;
-HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/icu/impl/locale/BaseLocale-IA;)V
HSPLandroid/icu/impl/locale/BaseLocale;->getInstance(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/icu/impl/locale/BaseLocale;
HSPLandroid/icu/impl/locale/BaseLocale;->getLanguage()Ljava/lang/String;
@@ -9113,7 +9155,7 @@ HSPLandroid/icu/impl/locale/LocaleObjectCache;->cleanStaleEntries()V
HSPLandroid/icu/impl/locale/LocaleObjectCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/icu/impl/number/AdoptingModifierStore$1;-><clinit>()V
HSPLandroid/icu/impl/number/AdoptingModifierStore;-><init>(Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;)V
-HSPLandroid/icu/impl/number/AdoptingModifierStore;->getModifierWithoutPlural(Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/Modifier;
+HSPLandroid/icu/impl/number/AdoptingModifierStore;->getModifierWithoutPlural(Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/Modifier;+]Landroid/icu/impl/number/Modifier$Signum;Landroid/icu/impl/number/Modifier$Signum;
HSPLandroid/icu/impl/number/AffixUtils;->containsType(Ljava/lang/CharSequence;I)Z
HSPLandroid/icu/impl/number/AffixUtils;->escape(Ljava/lang/CharSequence;)Ljava/lang/String;
HSPLandroid/icu/impl/number/AffixUtils;->getFieldForType(I)Landroid/icu/text/NumberFormat$Field;
@@ -9128,14 +9170,14 @@ HSPLandroid/icu/impl/number/AffixUtils;->makeTag(IIII)J
HSPLandroid/icu/impl/number/AffixUtils;->nextToken(JLjava/lang/CharSequence;)J
HSPLandroid/icu/impl/number/AffixUtils;->unescape(Ljava/lang/CharSequence;Landroid/icu/impl/FormattedStringBuilder;ILandroid/icu/impl/number/AffixUtils$SymbolProvider;Landroid/icu/text/NumberFormat$Field;)I
HSPLandroid/icu/impl/number/AffixUtils;->unescapedCount(Ljava/lang/CharSequence;ZLandroid/icu/impl/number/AffixUtils$SymbolProvider;)I
-HSPLandroid/icu/impl/number/ConstantAffixModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
+HSPLandroid/icu/impl/number/ConstantAffixModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;
HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;-><init>(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;ZZ)V
HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;-><init>(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;ZZLandroid/icu/impl/number/Modifier$Parameters;)V
-HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
+HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;
HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->getPrefixLength()I
HSPLandroid/icu/impl/number/CurrencySpacingEnabledModifier;->applyCurrencySpacing(Landroid/icu/impl/FormattedStringBuilder;IIIILandroid/icu/text/DecimalFormatSymbols;)I
HSPLandroid/icu/impl/number/CurrencySpacingEnabledModifier;->applyCurrencySpacingAffix(Landroid/icu/impl/FormattedStringBuilder;IBLandroid/icu/text/DecimalFormatSymbols;)I
-HSPLandroid/icu/impl/number/CustomSymbolCurrency;->resolve(Landroid/icu/util/Currency;Landroid/icu/util/ULocale;Landroid/icu/text/DecimalFormatSymbols;)Landroid/icu/util/Currency;
+HSPLandroid/icu/impl/number/CustomSymbolCurrency;->resolve(Landroid/icu/util/Currency;Landroid/icu/util/ULocale;Landroid/icu/text/DecimalFormatSymbols;)Landroid/icu/util/Currency;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/util/Currency;Landroid/icu/util/Currency;
HSPLandroid/icu/impl/number/DecimalFormatProperties;-><init>()V
HSPLandroid/icu/impl/number/DecimalFormatProperties;->_clear()Landroid/icu/impl/number/DecimalFormatProperties;
HSPLandroid/icu/impl/number/DecimalFormatProperties;->_copyFrom(Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/DecimalFormatProperties;
@@ -9215,14 +9257,14 @@ HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;-><init>()V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToBigDecimal(Ljava/math/BigDecimal;)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToBigInteger(Ljava/math/BigInteger;)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToDoubleFast(D)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToLong(J)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToLong(J)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->adjustMagnitude(I)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->appendDigit(BIZ)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->appendDigit(BIZ)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->applyMaxInteger(I)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->convertToAccurateDouble()V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->copyFrom(Landroid/icu/impl/number/DecimalQuantity;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->fitsInLong()Z+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getDigit(I)B
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->fitsInLong()Z
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getDigit(I)B+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getLowerDisplayMagnitude()I
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getMagnitude()I
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getPluralOperand(Landroid/icu/text/PluralRules$Operand;)D
@@ -9235,18 +9277,18 @@ HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->isZeroish()Z
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->negate()V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->populateUFieldPosition(Ljava/text/FieldPosition;)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;Z)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;Z)V+]Ljava/math/MathContext;Ljava/math/MathContext;]Ljava/math/RoundingMode;Ljava/math/RoundingMode;]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->safeSubtract(II)I
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setMinFraction(I)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setMinInteger(I)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToBigDecimal(Ljava/math/BigDecimal;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToDouble(D)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToDouble(D)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToInt(I)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToLong(J)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->signum()Landroid/icu/impl/number/Modifier$Signum;
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->toLong(Z)J+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>()V+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(D)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->signum()Landroid/icu/impl/number/Modifier$Signum;+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->toLong(Z)J
+HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>()V
+HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(D)V+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(I)V
HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(J)V
HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(Ljava/lang/Number;)V
@@ -9278,14 +9320,14 @@ HSPLandroid/icu/impl/number/MacroProps;-><init>()V
HSPLandroid/icu/impl/number/MacroProps;->fallback(Landroid/icu/impl/number/MacroProps;)V
HSPLandroid/icu/impl/number/MicroProps;-><init>(Z)V
HSPLandroid/icu/impl/number/MicroProps;->clone()Ljava/lang/Object;
-HSPLandroid/icu/impl/number/MicroProps;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/impl/number/MicroProps;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/MicroProps;
HSPLandroid/icu/impl/number/Modifier$Signum;->values()[Landroid/icu/impl/number/Modifier$Signum;
HSPLandroid/icu/impl/number/MultiplierFormatHandler;-><init>(Landroid/icu/number/Scale;Landroid/icu/impl/number/MicroPropsGenerator;)V
HSPLandroid/icu/impl/number/MultiplierFormatHandler;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;-><init>(Landroid/icu/impl/number/AdoptingModifierStore;Landroid/icu/text/PluralRules;)V
HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->addToChain(Landroid/icu/impl/number/MicroPropsGenerator;)Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;
-HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->applyToMicros(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;)V
-HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->applyToMicros(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;)V+]Landroid/icu/impl/number/AdoptingModifierStore;Landroid/icu/impl/number/AdoptingModifierStore;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroPropsGenerator;Landroid/icu/impl/number/MicroProps;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;
HSPLandroid/icu/impl/number/MutablePatternModifier;-><init>(Z)V
HSPLandroid/icu/impl/number/MutablePatternModifier;->addToChain(Landroid/icu/impl/number/MicroPropsGenerator;)Landroid/icu/impl/number/MicroPropsGenerator;
HSPLandroid/icu/impl/number/MutablePatternModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
@@ -9315,7 +9357,7 @@ HSPLandroid/icu/impl/number/PatternStringParser;->consumeAffix(Landroid/icu/impl
HSPLandroid/icu/impl/number/PatternStringParser;->consumeExponent(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
HSPLandroid/icu/impl/number/PatternStringParser;->consumeFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
HSPLandroid/icu/impl/number/PatternStringParser;->consumeFractionFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
-HSPLandroid/icu/impl/number/PatternStringParser;->consumeIntegerFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
+HSPLandroid/icu/impl/number/PatternStringParser;->consumeIntegerFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V+]Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParserState;
HSPLandroid/icu/impl/number/PatternStringParser;->consumeLiteral(Landroid/icu/impl/number/PatternStringParser$ParserState;)V
HSPLandroid/icu/impl/number/PatternStringParser;->consumePadding(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;Landroid/icu/impl/number/Padder$PadPosition;)V
HSPLandroid/icu/impl/number/PatternStringParser;->consumePattern(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedPatternInfo;)V
@@ -9328,9 +9370,9 @@ HSPLandroid/icu/impl/number/PatternStringUtils$PatternSignType;-><clinit>()V
HSPLandroid/icu/impl/number/PatternStringUtils$PatternSignType;-><init>(Ljava/lang/String;I)V
HSPLandroid/icu/impl/number/PatternStringUtils$PatternSignType;->values()[Landroid/icu/impl/number/PatternStringUtils$PatternSignType;
HSPLandroid/icu/impl/number/PatternStringUtils;->patternInfoToStringBuilder(Landroid/icu/impl/number/AffixPatternProvider;ZLandroid/icu/impl/number/PatternStringUtils$PatternSignType;ZLandroid/icu/impl/StandardPlural;ZLjava/lang/StringBuilder;)V
-HSPLandroid/icu/impl/number/PatternStringUtils;->propertiesToPatternString(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/lang/String;
+HSPLandroid/icu/impl/number/PatternStringUtils;->propertiesToPatternString(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
HSPLandroid/icu/impl/number/PatternStringUtils;->resolveSignDisplay(Landroid/icu/number/NumberFormatter$SignDisplay;Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/PatternStringUtils$PatternSignType;
-HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;-><init>(Landroid/icu/impl/number/DecimalFormatProperties;)V
+HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;-><init>(Landroid/icu/impl/number/DecimalFormatProperties;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->charAt(II)C
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->containsSymbolType(I)Z
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->currencyAsDecimal()Z
@@ -9338,7 +9380,7 @@ HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->forProperties(Landr
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->getString(I)Ljava/lang/String;
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasBody()Z
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasCurrencySign()Z
-HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasNegativeSubpattern()Z
+HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasNegativeSubpattern()Z+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->length(I)I
HSPLandroid/icu/impl/number/RoundingUtils;->getMathContextOr34Digits(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/math/MathContext;
HSPLandroid/icu/impl/number/RoundingUtils;->getMathContextOrUnlimited(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/math/MathContext;
@@ -9350,14 +9392,14 @@ HSPLandroid/icu/impl/number/SimpleModifier;->apply(Landroid/icu/impl/FormattedSt
HSPLandroid/icu/impl/number/parse/AffixMatcher$1;->compare(Landroid/icu/impl/number/parse/AffixMatcher;Landroid/icu/impl/number/parse/AffixMatcher;)I
HSPLandroid/icu/impl/number/parse/AffixMatcher$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/icu/impl/number/parse/AffixMatcher;-><init>(Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;I)V
-HSPLandroid/icu/impl/number/parse/AffixMatcher;->createMatchers(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/AffixTokenMatcherFactory;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)V+]Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/NumberParserImpl;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/icu/impl/number/parse/AffixMatcher;->createMatchers(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/AffixTokenMatcherFactory;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)V
HSPLandroid/icu/impl/number/parse/AffixMatcher;->getInstance(Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;I)Landroid/icu/impl/number/parse/AffixMatcher;
HSPLandroid/icu/impl/number/parse/AffixMatcher;->isInteresting(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)Z
HSPLandroid/icu/impl/number/parse/AffixMatcher;->length(Landroid/icu/impl/number/parse/AffixPatternMatcher;)I
HSPLandroid/icu/impl/number/parse/AffixMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)Z
HSPLandroid/icu/impl/number/parse/AffixMatcher;->matched(Landroid/icu/impl/number/parse/AffixPatternMatcher;Ljava/lang/String;)Z
HSPLandroid/icu/impl/number/parse/AffixMatcher;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
-HSPLandroid/icu/impl/number/parse/AffixMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z+]Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;
+HSPLandroid/icu/impl/number/parse/AffixMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z
HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;-><init>(Ljava/lang/String;)V
HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->consumeToken(I)V
HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->equals(Ljava/lang/Object;)Z
@@ -9365,10 +9407,10 @@ HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->fromAffixPattern(Ljava/l
HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->getPattern()Ljava/lang/String;
HSPLandroid/icu/impl/number/parse/AffixTokenMatcherFactory;-><init>()V
HSPLandroid/icu/impl/number/parse/AffixTokenMatcherFactory;->minusSign()Landroid/icu/impl/number/parse/MinusSignMatcher;
-HSPLandroid/icu/impl/number/parse/DecimalMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)V+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;
+HSPLandroid/icu/impl/number/parse/DecimalMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)V
HSPLandroid/icu/impl/number/parse/DecimalMatcher;->getInstance(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)Landroid/icu/impl/number/parse/DecimalMatcher;
HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)Z
-HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;I)Z
+HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;I)Z+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/number/parse/ParsedNumber;Landroid/icu/impl/number/parse/ParsedNumber;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;
HSPLandroid/icu/impl/number/parse/DecimalMatcher;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
HSPLandroid/icu/impl/number/parse/DecimalMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z
HSPLandroid/icu/impl/number/parse/DecimalMatcher;->validateGroup(IIZ)Z
@@ -9379,14 +9421,14 @@ HSPLandroid/icu/impl/number/parse/NanMatcher;->getInstance(Landroid/icu/text/Dec
HSPLandroid/icu/impl/number/parse/NumberParserImpl;-><init>(I)V
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->addMatcher(Landroid/icu/impl/number/parse/NumberParseMatcher;)V
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->addMatchers(Ljava/util/Collection;)V
-HSPLandroid/icu/impl/number/parse/NumberParserImpl;->createParserFromProperties(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Z)Landroid/icu/impl/number/parse/NumberParserImpl;
+HSPLandroid/icu/impl/number/parse/NumberParserImpl;->createParserFromProperties(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Z)Landroid/icu/impl/number/parse/NumberParserImpl;+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/NumberParserImpl;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->freeze()V
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->getParseFlags()I
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->parse(Ljava/lang/String;IZLandroid/icu/impl/number/parse/ParsedNumber;)V
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->parseGreedy(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)V
HSPLandroid/icu/impl/number/parse/ParsedNumber;-><init>()V
HSPLandroid/icu/impl/number/parse/ParsedNumber;->clear()V
-HSPLandroid/icu/impl/number/parse/ParsedNumber;->getNumber(I)Ljava/lang/Number;+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/parse/ParsedNumber;->getNumber(I)Ljava/lang/Number;
HSPLandroid/icu/impl/number/parse/ParsedNumber;->postProcess()V
HSPLandroid/icu/impl/number/parse/ParsedNumber;->seenNumber()Z
HSPLandroid/icu/impl/number/parse/ParsedNumber;->setCharsConsumed(Landroid/icu/impl/StringSegment;)V
@@ -9395,7 +9437,7 @@ HSPLandroid/icu/impl/number/parse/RequireAffixValidator;-><init>()V
HSPLandroid/icu/impl/number/parse/RequireAffixValidator;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
HSPLandroid/icu/impl/number/parse/RequireNumberValidator;-><init>()V
HSPLandroid/icu/impl/number/parse/RequireNumberValidator;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
-HSPLandroid/icu/impl/number/parse/ScientificMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)V+]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
+HSPLandroid/icu/impl/number/parse/ScientificMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)V
HSPLandroid/icu/impl/number/parse/ScientificMatcher;->getInstance(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)Landroid/icu/impl/number/parse/ScientificMatcher;
HSPLandroid/icu/impl/number/parse/ScientificMatcher;->minusSignSet()Landroid/icu/text/UnicodeSet;
HSPLandroid/icu/impl/number/parse/ScientificMatcher;->plusSignSet()Landroid/icu/text/UnicodeSet;
@@ -9423,7 +9465,7 @@ HSPLandroid/icu/impl/number/range/StandardPluralRanges;->getSetForLocale(Landroi
HSPLandroid/icu/impl/number/range/StandardPluralRanges;->setCapacity(I)V
HSPLandroid/icu/lang/UCharacter;->codePointAt(Ljava/lang/CharSequence;I)I
HSPLandroid/icu/lang/UCharacter;->digit(I)I
-HSPLandroid/icu/lang/UCharacter;->foldCase(II)I+]Landroid/icu/impl/UCaseProps;Landroid/icu/impl/UCaseProps;
+HSPLandroid/icu/lang/UCharacter;->foldCase(II)I
HSPLandroid/icu/lang/UCharacter;->foldCase(IZ)I
HSPLandroid/icu/lang/UCharacter;->getPropertyValueEnumNoThrow(ILjava/lang/CharSequence;)I
HSPLandroid/icu/lang/UCharacter;->getType(I)I
@@ -9439,33 +9481,33 @@ HSPLandroid/icu/number/IntegerWidth;-><init>(II)V
HSPLandroid/icu/number/IntegerWidth;->truncateAt(I)Landroid/icu/number/IntegerWidth;
HSPLandroid/icu/number/IntegerWidth;->zeroFillTo(I)Landroid/icu/number/IntegerWidth;
HSPLandroid/icu/number/LocalizedNumberFormatter;-><init>(Landroid/icu/number/NumberFormatterSettings;ILjava/lang/Object;)V
-HSPLandroid/icu/number/LocalizedNumberFormatter;->computeCompiled()Z
+HSPLandroid/icu/number/LocalizedNumberFormatter;->computeCompiled()Z+]Ljava/util/concurrent/atomic/AtomicLongFieldUpdater;Ljava/util/concurrent/atomic/AtomicLongFieldUpdater$CASUpdater;]Landroid/icu/number/LocalizedNumberFormatter;Landroid/icu/number/LocalizedNumberFormatter;]Ljava/lang/Long;Ljava/lang/Long;
HSPLandroid/icu/number/LocalizedNumberFormatter;->create(ILjava/lang/Object;)Landroid/icu/number/LocalizedNumberFormatter;
HSPLandroid/icu/number/LocalizedNumberFormatter;->create(ILjava/lang/Object;)Landroid/icu/number/NumberFormatterSettings;
HSPLandroid/icu/number/LocalizedNumberFormatter;->format(D)Landroid/icu/number/FormattedNumber;
HSPLandroid/icu/number/LocalizedNumberFormatter;->format(J)Landroid/icu/number/FormattedNumber;
HSPLandroid/icu/number/LocalizedNumberFormatter;->format(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/number/FormattedNumber;
-HSPLandroid/icu/number/LocalizedNumberFormatter;->formatImpl(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/LocalizedNumberFormatter;->formatImpl(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/number/NumberFormatterImpl;Landroid/icu/number/NumberFormatterImpl;
HSPLandroid/icu/number/LocalizedNumberFormatter;->getAffixImpl(ZZ)Ljava/lang/String;
HSPLandroid/icu/number/NumberFormatter;->fromDecimalFormat(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/number/UnlocalizedNumberFormatter;
HSPLandroid/icu/number/NumberFormatter;->with()Landroid/icu/number/UnlocalizedNumberFormatter;
HSPLandroid/icu/number/NumberFormatterImpl;-><init>(Landroid/icu/impl/number/MacroProps;)V
-HSPLandroid/icu/number/NumberFormatterImpl;->format(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/NumberFormatterImpl;->format(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/number/NumberFormatterImpl;Landroid/icu/number/NumberFormatterImpl;
HSPLandroid/icu/number/NumberFormatterImpl;->formatStatic(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffix(BLandroid/icu/impl/StandardPlural;Landroid/icu/impl/FormattedStringBuilder;)I
HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffixImpl(Landroid/icu/impl/number/MicroPropsGenerator;BLandroid/icu/impl/FormattedStringBuilder;)I
HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffixStatic(Landroid/icu/impl/number/MacroProps;BLandroid/icu/impl/StandardPlural;Landroid/icu/impl/FormattedStringBuilder;)I
-HSPLandroid/icu/number/NumberFormatterImpl;->macrosToMicroGenerator(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/MicroProps;Z)Landroid/icu/impl/number/MicroPropsGenerator;+]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/impl/number/MutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/text/NumberingSystem;Landroid/icu/text/NumberingSystem;
-HSPLandroid/icu/number/NumberFormatterImpl;->preProcess(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/NumberFormatterImpl;->macrosToMicroGenerator(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/MicroProps;Z)Landroid/icu/impl/number/MicroPropsGenerator;+]Landroid/icu/impl/number/MutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier;]Landroid/icu/text/NumberingSystem;Landroid/icu/text/NumberingSystem;]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;
+HSPLandroid/icu/number/NumberFormatterImpl;->preProcess(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroPropsGenerator;Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/number/NumberFormatterImpl;->preProcessUnsafe(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
HSPLandroid/icu/number/NumberFormatterImpl;->unitIsBaseUnit(Landroid/icu/util/MeasureUnit;)Z
HSPLandroid/icu/number/NumberFormatterImpl;->unitIsCurrency(Landroid/icu/util/MeasureUnit;)Z
HSPLandroid/icu/number/NumberFormatterImpl;->unitIsPercent(Landroid/icu/util/MeasureUnit;)Z
HSPLandroid/icu/number/NumberFormatterImpl;->unitIsPermille(Landroid/icu/util/MeasureUnit;)Z
-HSPLandroid/icu/number/NumberFormatterImpl;->writeAffixes(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/FormattedStringBuilder;II)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeFractionDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeIntegerDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeNumber(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
+HSPLandroid/icu/number/NumberFormatterImpl;->writeAffixes(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/number/Padder;Landroid/icu/impl/number/Padder;]Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/ConstantMultiFieldModifier;,Landroid/icu/impl/number/ConstantAffixModifier;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeFractionDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeIntegerDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeNumber(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/number/NumberFormatterSettings;-><init>(Landroid/icu/number/NumberFormatterSettings;ILjava/lang/Object;)V
HSPLandroid/icu/number/NumberFormatterSettings;->macros(Landroid/icu/impl/number/MacroProps;)Landroid/icu/number/NumberFormatterSettings;
HSPLandroid/icu/number/NumberFormatterSettings;->perUnit(Landroid/icu/util/MeasureUnit;)Landroid/icu/number/NumberFormatterSettings;
@@ -9473,9 +9515,9 @@ HSPLandroid/icu/number/NumberFormatterSettings;->resolve()Landroid/icu/impl/numb
HSPLandroid/icu/number/NumberFormatterSettings;->unit(Landroid/icu/util/MeasureUnit;)Landroid/icu/number/NumberFormatterSettings;
HSPLandroid/icu/number/NumberFormatterSettings;->unitWidth(Landroid/icu/number/NumberFormatter$UnitWidth;)Landroid/icu/number/NumberFormatterSettings;
HSPLandroid/icu/number/NumberPropertyMapper;->create(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/number/UnlocalizedNumberFormatter;
-HSPLandroid/icu/number/NumberPropertyMapper;->oldToNew(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/MacroProps;
+HSPLandroid/icu/number/NumberPropertyMapper;->oldToNew(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/MacroProps;+]Ljava/math/MathContext;Ljava/math/MathContext;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;,Landroid/icu/number/Precision$CurrencyRounderImpl;]Landroid/icu/number/IntegerWidth;Landroid/icu/number/IntegerWidth;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;]Landroid/icu/number/CurrencyPrecision;Landroid/icu/number/Precision$CurrencyRounderImpl;]Landroid/icu/util/Currency;Landroid/icu/util/Currency;
HSPLandroid/icu/number/Precision$FractionRounderImpl;-><init>(II)V
-HSPLandroid/icu/number/Precision$FractionRounderImpl;->apply(Landroid/icu/impl/number/DecimalQuantity;)V
+HSPLandroid/icu/number/Precision$FractionRounderImpl;->apply(Landroid/icu/impl/number/DecimalQuantity;)V+]Landroid/icu/number/Precision$FractionRounderImpl;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/number/Precision$FractionRounderImpl;->createCopy()Landroid/icu/number/Precision$FractionRounderImpl;
HSPLandroid/icu/number/Precision$FractionRounderImpl;->createCopy()Landroid/icu/number/Precision;
HSPLandroid/icu/number/Precision;->-$$Nest$smgetDisplayMagnitudeFraction(I)I
@@ -9486,7 +9528,7 @@ HSPLandroid/icu/number/Precision;->constructFraction(II)Landroid/icu/number/Frac
HSPLandroid/icu/number/Precision;->constructFromCurrency(Landroid/icu/number/CurrencyPrecision;Landroid/icu/util/Currency;)Landroid/icu/number/Precision;
HSPLandroid/icu/number/Precision;->getDisplayMagnitudeFraction(I)I
HSPLandroid/icu/number/Precision;->getRoundingMagnitudeFraction(I)I
-HSPLandroid/icu/number/Precision;->setResolvedMinFraction(Landroid/icu/impl/number/DecimalQuantity;I)V
+HSPLandroid/icu/number/Precision;->setResolvedMinFraction(Landroid/icu/impl/number/DecimalQuantity;I)V+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/number/Precision;->withLocaleData(Landroid/icu/util/Currency;)Landroid/icu/number/Precision;
HSPLandroid/icu/number/Precision;->withMode(Ljava/math/MathContext;)Landroid/icu/number/Precision;
HSPLandroid/icu/number/Scale;->applyTo(Landroid/icu/impl/number/DecimalQuantity;)V
@@ -9535,7 +9577,7 @@ HSPLandroid/icu/text/CollationKey;->toByteArray()[B
HSPLandroid/icu/text/Collator$ServiceShim;-><init>()V
HSPLandroid/icu/text/Collator;-><init>()V
HSPLandroid/icu/text/Collator;->clone()Ljava/lang/Object;
-HSPLandroid/icu/text/Collator;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
+HSPLandroid/icu/text/Collator;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;+]Landroid/icu/text/Collator$ServiceShim;Landroid/icu/text/CollatorServiceShim;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;
HSPLandroid/icu/text/Collator;->getInstance(Ljava/util/Locale;)Landroid/icu/text/Collator;
HSPLandroid/icu/text/Collator;->getShim()Landroid/icu/text/Collator$ServiceShim;
HSPLandroid/icu/text/CollatorServiceShim$CService$1CollatorFactory;->handleCreate(Landroid/icu/util/ULocale;ILandroid/icu/impl/ICUService;)Ljava/lang/Object;
@@ -9543,13 +9585,13 @@ HSPLandroid/icu/text/CollatorServiceShim$CService;->validateFallbackLocale()Ljav
HSPLandroid/icu/text/CollatorServiceShim;-><init>()V
HSPLandroid/icu/text/CollatorServiceShim;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
HSPLandroid/icu/text/CollatorServiceShim;->makeInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
-HSPLandroid/icu/text/ConstrainedFieldPosition;-><init>()V
+HSPLandroid/icu/text/ConstrainedFieldPosition;-><init>()V+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;
HSPLandroid/icu/text/ConstrainedFieldPosition;->constrainField(Ljava/text/Format$Field;)V
HSPLandroid/icu/text/ConstrainedFieldPosition;->getField()Ljava/text/Format$Field;
HSPLandroid/icu/text/ConstrainedFieldPosition;->getFieldValue()Ljava/lang/Object;
HSPLandroid/icu/text/ConstrainedFieldPosition;->getLimit()I
HSPLandroid/icu/text/ConstrainedFieldPosition;->getStart()I
-HSPLandroid/icu/text/ConstrainedFieldPosition;->matchesField(Ljava/text/Format$Field;Ljava/lang/Object;)Z
+HSPLandroid/icu/text/ConstrainedFieldPosition;->matchesField(Ljava/text/Format$Field;Ljava/lang/Object;)Z+]Landroid/icu/text/ConstrainedFieldPosition$ConstraintType;Landroid/icu/text/ConstrainedFieldPosition$ConstraintType;
HSPLandroid/icu/text/ConstrainedFieldPosition;->reset()V
HSPLandroid/icu/text/ConstrainedFieldPosition;->setState(Ljava/text/Format$Field;Ljava/lang/Object;II)V
HSPLandroid/icu/text/CurrencyDisplayNames;-><init>()V
@@ -9602,6 +9644,7 @@ HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/text/DateFo
HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;)V
HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;Landroid/icu/text/DateFormatSymbols$AospExtendedDateFormatSymbols;)V
HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Ljava/lang/String;)V
+HSPLandroid/icu/text/DateFormatSymbols;->loadDayPeriodStrings(Ljava/util/Map;)[Ljava/lang/String;
HSPLandroid/icu/text/DateFormatSymbols;->setLocale(Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;)V
HSPLandroid/icu/text/DateFormatSymbols;->setTimeSeparatorString(Ljava/lang/String;)V
HSPLandroid/icu/text/DateIntervalFormat;-><init>(Ljava/lang/String;Landroid/icu/util/ULocale;Landroid/icu/text/SimpleDateFormat;)V
@@ -9647,7 +9690,7 @@ HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->fieldIsNumeric(I
HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getBasePattern()Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getDistance(Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;ILandroid/icu/text/DateTimePatternGenerator$DistanceInfo;)I
HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getFieldMask()I
-HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->set(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$FormatParser;Z)Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;
+HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->set(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$FormatParser;Z)Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/text/DateTimePatternGenerator$VariableField;Landroid/icu/text/DateTimePatternGenerator$VariableField;]Landroid/icu/text/DateTimePatternGenerator$FormatParser;Landroid/icu/text/DateTimePatternGenerator$FormatParser;]Landroid/icu/text/DateTimePatternGenerator$SkeletonFields;Landroid/icu/text/DateTimePatternGenerator$SkeletonFields;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;
HSPLandroid/icu/text/DateTimePatternGenerator$DisplayWidth;->cldrKey()Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator$DistanceInfo;-><init>()V
HSPLandroid/icu/text/DateTimePatternGenerator$DistanceInfo;->addExtra(I)V
@@ -9659,7 +9702,7 @@ HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->addVariable(Ljava/l
HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->getItems()Ljava/util/List;
HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->quoteLiteral(Ljava/lang/String;)Ljava/lang/Object;
HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;)Landroid/icu/text/DateTimePatternGenerator$FormatParser;
-HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;Z)Landroid/icu/text/DateTimePatternGenerator$FormatParser;
+HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;Z)Landroid/icu/text/DateTimePatternGenerator$FormatParser;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;]Landroid/icu/impl/PatternTokenizer;Landroid/icu/impl/PatternTokenizer;
HSPLandroid/icu/text/DateTimePatternGenerator$PatternInfo;-><init>()V
HSPLandroid/icu/text/DateTimePatternGenerator$PatternWithMatcher;-><init>(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;)V
HSPLandroid/icu/text/DateTimePatternGenerator$PatternWithSkeletonFlag;-><init>(Ljava/lang/String;Z)V
@@ -9702,9 +9745,9 @@ HSPLandroid/icu/text/DateTimePatternGenerator;->getBestPattern(Ljava/lang/String
HSPLandroid/icu/text/DateTimePatternGenerator;->getBestPattern(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;I)Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator;->getBestPattern(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;IZ)Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator;->getBestRaw(Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;ILandroid/icu/text/DateTimePatternGenerator$DistanceInfo;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;)Landroid/icu/text/DateTimePatternGenerator$PatternWithMatcher;
-HSPLandroid/icu/text/DateTimePatternGenerator;->getCLDRFieldAndWidthNumber(Landroid/icu/impl/UResource$Key;)I
+HSPLandroid/icu/text/DateTimePatternGenerator;->getCLDRFieldAndWidthNumber(Landroid/icu/impl/UResource$Key;)I+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Key;
HSPLandroid/icu/text/DateTimePatternGenerator;->getCalendarTypeToUse(Landroid/icu/util/ULocale;)Ljava/lang/String;
-HSPLandroid/icu/text/DateTimePatternGenerator;->getCanonicalIndex(Ljava/lang/String;Z)I
+HSPLandroid/icu/text/DateTimePatternGenerator;->getCanonicalIndex(Ljava/lang/String;Z)I+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator;->getDateTimeFormat()Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator;->getFieldDisplayName(ILandroid/icu/text/DateTimePatternGenerator$DisplayWidth;)Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator;->getFilteredPattern(Landroid/icu/text/DateTimePatternGenerator$FormatParser;Ljava/util/BitSet;)Ljava/lang/String;
@@ -9727,8 +9770,8 @@ HSPLandroid/icu/text/DateTimePatternGenerator;->setFieldDisplayName(ILandroid/ic
HSPLandroid/icu/text/DecimalFormat;-><init>(Ljava/lang/String;Landroid/icu/text/DecimalFormatSymbols;)V
HSPLandroid/icu/text/DecimalFormat;-><init>(Ljava/lang/String;Landroid/icu/text/DecimalFormatSymbols;I)V
HSPLandroid/icu/text/DecimalFormat;->clone()Ljava/lang/Object;
-HSPLandroid/icu/text/DecimalFormat;->fieldPositionHelper(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;I)V
-HSPLandroid/icu/text/DecimalFormat;->format(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
+HSPLandroid/icu/text/DecimalFormat;->fieldPositionHelper(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;I)V+]Ljava/text/FieldPosition;Ljava/text/DontCareFieldPosition;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/text/DecimalFormat;->format(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;+]Landroid/icu/number/LocalizedNumberFormatter;Landroid/icu/number/LocalizedNumberFormatter;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
HSPLandroid/icu/text/DecimalFormat;->format(JLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
HSPLandroid/icu/text/DecimalFormat;->getDecimalFormatSymbols()Landroid/icu/text/DecimalFormatSymbols;
HSPLandroid/icu/text/DecimalFormat;->getMaximumFractionDigits()I
@@ -9743,7 +9786,7 @@ HSPLandroid/icu/text/DecimalFormat;->getPositiveSuffix()Ljava/lang/String;
HSPLandroid/icu/text/DecimalFormat;->isParseBigDecimal()Z
HSPLandroid/icu/text/DecimalFormat;->isParseIntegerOnly()Z
HSPLandroid/icu/text/DecimalFormat;->parse(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;
-HSPLandroid/icu/text/DecimalFormat;->refreshFormatter()V
+HSPLandroid/icu/text/DecimalFormat;->refreshFormatter()V+]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/number/UnlocalizedNumberFormatter;Landroid/icu/number/UnlocalizedNumberFormatter;]Landroid/icu/text/DecimalFormat;Landroid/icu/text/DecimalFormat;
HSPLandroid/icu/text/DecimalFormat;->setCurrency(Landroid/icu/util/Currency;)V
HSPLandroid/icu/text/DecimalFormat;->setDecimalSeparatorAlwaysShown(Z)V
HSPLandroid/icu/text/DecimalFormat;->setGroupingUsed(Z)V
@@ -9755,7 +9798,7 @@ HSPLandroid/icu/text/DecimalFormat;->setParseIntegerOnly(Z)V
HSPLandroid/icu/text/DecimalFormat;->setParseStrictMode(Landroid/icu/impl/number/DecimalFormatProperties$ParseMode;)V
HSPLandroid/icu/text/DecimalFormat;->setPropertiesFromPattern(Ljava/lang/String;I)V
HSPLandroid/icu/text/DecimalFormat;->toNumberFormatter()Landroid/icu/number/LocalizedNumberFormatter;
-HSPLandroid/icu/text/DecimalFormat;->toPattern()Ljava/lang/String;+]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
+HSPLandroid/icu/text/DecimalFormat;->toPattern()Ljava/lang/String;
HSPLandroid/icu/text/DecimalFormatSymbols$1;->createInstance(Landroid/icu/util/ULocale;Ljava/lang/Void;)Landroid/icu/text/DecimalFormatSymbols$CacheData;
HSPLandroid/icu/text/DecimalFormatSymbols$1;->createInstance(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/icu/text/DecimalFormatSymbols$CacheData;-><init>(Landroid/icu/util/ULocale;[Ljava/lang/String;[Ljava/lang/String;)V
@@ -9797,7 +9840,7 @@ HSPLandroid/icu/text/DecimalFormatSymbols;->getPlusSignString()Ljava/lang/String
HSPLandroid/icu/text/DecimalFormatSymbols;->getULocale()Landroid/icu/util/ULocale;
HSPLandroid/icu/text/DecimalFormatSymbols;->getZeroDigit()C
HSPLandroid/icu/text/DecimalFormatSymbols;->initSpacingInfo(Landroid/icu/impl/CurrencyData$CurrencySpacingInfo;)V
-HSPLandroid/icu/text/DecimalFormatSymbols;->initialize(Landroid/icu/util/ULocale;Landroid/icu/text/NumberingSystem;)V
+HSPLandroid/icu/text/DecimalFormatSymbols;->initialize(Landroid/icu/util/ULocale;Landroid/icu/text/NumberingSystem;)V+]Landroid/icu/impl/CurrencyData$CurrencyDisplayInfoProvider;Landroid/icu/impl/ICUCurrencyDisplayInfoProvider;]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/CurrencyData$CurrencyDisplayInfo;Landroid/icu/impl/ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo;
HSPLandroid/icu/text/DecimalFormatSymbols;->loadData(Landroid/icu/util/ULocale;)Landroid/icu/text/DecimalFormatSymbols$CacheData;
HSPLandroid/icu/text/DecimalFormatSymbols;->setApproximatelySignString(Ljava/lang/String;)V
HSPLandroid/icu/text/DecimalFormatSymbols;->setCurrency(Landroid/icu/util/Currency;)V
@@ -9993,7 +10036,7 @@ HSPLandroid/icu/text/RuleBasedCollator;->checkNotFrozen()V
HSPLandroid/icu/text/RuleBasedCollator;->clone()Ljava/lang/Object;
HSPLandroid/icu/text/RuleBasedCollator;->cloneAsThawed()Landroid/icu/text/RuleBasedCollator;
HSPLandroid/icu/text/RuleBasedCollator;->compare(Ljava/lang/String;Ljava/lang/String;)I
-HSPLandroid/icu/text/RuleBasedCollator;->doCompare(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
+HSPLandroid/icu/text/RuleBasedCollator;->doCompare(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I+]Landroid/icu/impl/coll/CollationData;Landroid/icu/impl/coll/CollationData;]Landroid/icu/impl/coll/SharedObject$Reference;Landroid/icu/impl/coll/SharedObject$Reference;]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/icu/impl/coll/CollationSettings;Landroid/icu/impl/coll/CollationSettings;
HSPLandroid/icu/text/RuleBasedCollator;->freeze()Landroid/icu/text/Collator;
HSPLandroid/icu/text/RuleBasedCollator;->getCollationBuffer()Landroid/icu/text/RuleBasedCollator$CollationBuffer;
HSPLandroid/icu/text/RuleBasedCollator;->getCollationKey(Ljava/lang/String;)Landroid/icu/text/CollationKey;
@@ -10071,7 +10114,7 @@ HSPLandroid/icu/text/UnicodeSet;->checkFrozen()V
HSPLandroid/icu/text/UnicodeSet;->clear()Landroid/icu/text/UnicodeSet;
HSPLandroid/icu/text/UnicodeSet;->clone()Ljava/lang/Object;
HSPLandroid/icu/text/UnicodeSet;->compact()Landroid/icu/text/UnicodeSet;
-HSPLandroid/icu/text/UnicodeSet;->contains(I)Z
+HSPLandroid/icu/text/UnicodeSet;->contains(I)Z+]Landroid/icu/impl/BMPSet;Landroid/icu/impl/BMPSet;
HSPLandroid/icu/text/UnicodeSet;->contains(Ljava/lang/CharSequence;)Z
HSPLandroid/icu/text/UnicodeSet;->containsAll(Ljava/lang/String;)Z
HSPLandroid/icu/text/UnicodeSet;->findCodePoint(I)I
@@ -10372,17 +10415,19 @@ HSPLandroid/icu/util/ULocale$Builder;->setLanguage(Ljava/lang/String;)Landroid/i
HSPLandroid/icu/util/ULocale$Builder;->setRegion(Ljava/lang/String;)Landroid/icu/util/ULocale$Builder;
HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->getDefault(Landroid/icu/util/ULocale$Category;)Ljava/util/Locale;
HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toLocale(Landroid/icu/util/ULocale;)Ljava/util/Locale;
-HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toULocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;
+HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toULocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Locale;Ljava/util/Locale;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
HSPLandroid/icu/util/ULocale;->-$$Nest$smgetInstance(Landroid/icu/impl/locale/BaseLocale;Landroid/icu/impl/locale/LocaleExtensions;)Landroid/icu/util/ULocale;
HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;)V
HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;Ljava/util/Locale;)V
HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;Ljava/util/Locale;Landroid/icu/util/ULocale-IA;)V
HSPLandroid/icu/util/ULocale;->addLikelySubtags(Landroid/icu/util/ULocale;)Landroid/icu/util/ULocale;
HSPLandroid/icu/util/ULocale;->appendTag(Ljava/lang/String;Ljava/lang/StringBuilder;)V
-HSPLandroid/icu/util/ULocale;->base()Landroid/icu/impl/locale/BaseLocale;
+HSPLandroid/icu/util/ULocale;->base()Landroid/icu/impl/locale/BaseLocale;+]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;]Landroid/icu/impl/LocaleIDParser;Landroid/icu/impl/LocaleIDParser;
HSPLandroid/icu/util/ULocale;->canonicalize(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->createCanonical(Ljava/lang/String;)Landroid/icu/util/ULocale;
+HSPLandroid/icu/util/ULocale;->createLikelySubtagsString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->createTagString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/util/ULocale;->createTagString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->equals(Ljava/lang/Object;)Z
HSPLandroid/icu/util/ULocale;->forLocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;
HSPLandroid/icu/util/ULocale;->getBaseName()Ljava/lang/String;
@@ -10397,7 +10442,7 @@ HSPLandroid/icu/util/ULocale;->getKeywords()Ljava/util/Iterator;
HSPLandroid/icu/util/ULocale;->getKeywords(Ljava/lang/String;)Ljava/util/Iterator;
HSPLandroid/icu/util/ULocale;->getLanguage()Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->getName()Ljava/lang/String;
-HSPLandroid/icu/util/ULocale;->getName(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/util/ULocale;->getName(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/CacheBase;Landroid/icu/util/ULocale$1;
HSPLandroid/icu/util/ULocale;->getRegionForSupplementalData(Landroid/icu/util/ULocale;Z)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->getScript()Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->getScript(Ljava/lang/String;)Ljava/lang/String;
@@ -10408,6 +10453,7 @@ HSPLandroid/icu/util/ULocale;->hashCode()I
HSPLandroid/icu/util/ULocale;->isEmptyString(Ljava/lang/String;)Z
HSPLandroid/icu/util/ULocale;->isKnownCanonicalizedLocale(Ljava/lang/String;)Z
HSPLandroid/icu/util/ULocale;->isRightToLeft()Z
+HSPLandroid/icu/util/ULocale;->lookupLikelySubtags(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->lscvToID(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->parseTagString(Ljava/lang/String;[Ljava/lang/String;)I
HSPLandroid/icu/util/ULocale;->setKeywordValue(Ljava/lang/String;Ljava/lang/String;)Landroid/icu/util/ULocale;
@@ -10480,7 +10526,7 @@ HSPLandroid/location/Location;->setVerticalAccuracyMeters(F)V
HSPLandroid/location/Location;->toString()Ljava/lang/String;
HSPLandroid/location/Location;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Landroid/media/AudioAttributes;
-HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/media/AudioAttributes$1;Landroid/media/AudioAttributes$1;
HSPLandroid/media/AudioAttributes$Builder;-><init>()V
HSPLandroid/media/AudioAttributes$Builder;-><init>(Landroid/media/AudioAttributes;)V
HSPLandroid/media/AudioAttributes$Builder;->addTag(Ljava/lang/String;)Landroid/media/AudioAttributes$Builder;
@@ -10506,7 +10552,7 @@ HSPLandroid/media/AudioAttributes;->-$$Nest$fputmTags(Landroid/media/AudioAttrib
HSPLandroid/media/AudioAttributes;->-$$Nest$fputmUsage(Landroid/media/AudioAttributes;I)V
HSPLandroid/media/AudioAttributes;-><init>()V
HSPLandroid/media/AudioAttributes;-><init>(Landroid/media/AudioAttributes-IA;)V
-HSPLandroid/media/AudioAttributes;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/media/AudioAttributes;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/media/AudioAttributes;->areHapticChannelsMuted()Z
HSPLandroid/media/AudioAttributes;->equals(Ljava/lang/Object;)Z
HSPLandroid/media/AudioAttributes;->getAllFlags()I
@@ -10642,7 +10688,7 @@ HSPLandroid/media/AudioPlaybackConfiguration$IPlayerShell;-><init>(Landroid/medi
HSPLandroid/media/AudioPlaybackConfiguration;->getAudioAttributes()Landroid/media/AudioAttributes;
HSPLandroid/media/AudioPlaybackConfiguration;->isActive()Z
HSPLandroid/media/AudioPort$$ExternalSyntheticLambda0;->applyAsInt(Ljava/lang/Object;)I
-HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;Ljava/util/List;[Landroid/media/AudioGain;Ljava/util/List;)V
+HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;Ljava/util/List;[Landroid/media/AudioGain;Ljava/util/List;)V+]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$Head;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;,Ljava/util/stream/ReferencePipeline$4;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;]Landroid/media/AudioProfile;Landroid/media/AudioProfile;]Ljava/util/Set;Ljava/util/HashSet;
HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V
HSPLandroid/media/AudioPort;->handle()Landroid/media/AudioHandle;
HSPLandroid/media/AudioPort;->id()I
@@ -10762,8 +10808,8 @@ HSPLandroid/media/MediaCodec$BufferMap$CodecBuffer;->setByteBuffer(Ljava/nio/Byt
HSPLandroid/media/MediaCodec$BufferMap;-><init>()V
HSPLandroid/media/MediaCodec$BufferMap;-><init>(Landroid/media/MediaCodec$BufferMap-IA;)V
HSPLandroid/media/MediaCodec$BufferMap;->clear()V
-HSPLandroid/media/MediaCodec$BufferMap;->put(ILjava/nio/ByteBuffer;)V
-HSPLandroid/media/MediaCodec$BufferMap;->remove(I)V
+HSPLandroid/media/MediaCodec$BufferMap;->put(ILjava/nio/ByteBuffer;)V+]Landroid/media/MediaCodec$BufferMap$CodecBuffer;Landroid/media/MediaCodec$BufferMap$CodecBuffer;]Ljava/util/Map;Ljava/util/HashMap;
+HSPLandroid/media/MediaCodec$BufferMap;->remove(I)V+]Landroid/media/MediaCodec$BufferMap$CodecBuffer;Landroid/media/MediaCodec$BufferMap$CodecBuffer;]Ljava/util/Map;Ljava/util/HashMap;
HSPLandroid/media/MediaCodec$CryptoInfo$Pattern;-><init>(II)V
HSPLandroid/media/MediaCodec$CryptoInfo$Pattern;->set(II)V
HSPLandroid/media/MediaCodec$CryptoInfo;-><init>()V
@@ -10775,18 +10821,18 @@ HSPLandroid/media/MediaCodec;->configure(Landroid/media/MediaFormat;Landroid/vie
HSPLandroid/media/MediaCodec;->configure(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;Landroid/os/IHwBinder;I)V
HSPLandroid/media/MediaCodec;->createByCodecName(Ljava/lang/String;)Landroid/media/MediaCodec;
HSPLandroid/media/MediaCodec;->dequeueInputBuffer(J)I
-HSPLandroid/media/MediaCodec;->dequeueOutputBuffer(Landroid/media/MediaCodec$BufferInfo;J)I
+HSPLandroid/media/MediaCodec;->dequeueOutputBuffer(Landroid/media/MediaCodec$BufferInfo;J)I+]Landroid/media/MediaCodec$BufferInfo;Landroid/media/MediaCodec$BufferInfo;]Ljava/util/Map;Ljava/util/HashMap;
HSPLandroid/media/MediaCodec;->finalize()V
HSPLandroid/media/MediaCodec;->freeAllTrackedBuffers()V
-HSPLandroid/media/MediaCodec;->getInputBuffer(I)Ljava/nio/ByteBuffer;
-HSPLandroid/media/MediaCodec;->getOutputBuffer(I)Ljava/nio/ByteBuffer;
+HSPLandroid/media/MediaCodec;->getInputBuffer(I)Ljava/nio/ByteBuffer;+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
+HSPLandroid/media/MediaCodec;->getOutputBuffer(I)Ljava/nio/ByteBuffer;+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
HSPLandroid/media/MediaCodec;->getOutputFormat()Landroid/media/MediaFormat;
-HSPLandroid/media/MediaCodec;->lockAndGetContext()J
-HSPLandroid/media/MediaCodec;->queueInputBuffer(IIIJI)V
+HSPLandroid/media/MediaCodec;->lockAndGetContext()J+]Ljava/util/concurrent/locks/Lock;Ljava/util/concurrent/locks/ReentrantLock;
+HSPLandroid/media/MediaCodec;->queueInputBuffer(IIIJI)V+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
HSPLandroid/media/MediaCodec;->release()V
HSPLandroid/media/MediaCodec;->releaseOutputBuffer(IZ)V
-HSPLandroid/media/MediaCodec;->releaseOutputBufferInternal(IZZJ)V
-HSPLandroid/media/MediaCodec;->setAndUnlockContext(J)V
+HSPLandroid/media/MediaCodec;->releaseOutputBufferInternal(IZZJ)V+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;]Ljava/util/Map;Ljava/util/HashMap;
+HSPLandroid/media/MediaCodec;->setAndUnlockContext(J)V+]Ljava/util/concurrent/locks/Lock;Ljava/util/concurrent/locks/ReentrantLock;
HSPLandroid/media/MediaCodec;->start()V
HSPLandroid/media/MediaCodec;->stop()V
HSPLandroid/media/MediaCodecInfo$AudioCapabilities;->applyLevelLimits()V
@@ -11281,6 +11327,10 @@ HSPLandroid/metrics/LogMaker;->setCategory(I)Landroid/metrics/LogMaker;
HSPLandroid/metrics/LogMaker;->setComponentName(Landroid/content/ComponentName;)Landroid/metrics/LogMaker;
HSPLandroid/metrics/LogMaker;->setSubtype(I)Landroid/metrics/LogMaker;
HSPLandroid/metrics/LogMaker;->setType(I)Landroid/metrics/LogMaker;
+HSPLandroid/multiuser/FeatureFlagsImpl;-><init>()V
+HSPLandroid/multiuser/FeatureFlagsImpl;->enableSystemUserOnlyForServicesAndProviders()Z
+HSPLandroid/multiuser/Flags;-><clinit>()V
+HSPLandroid/multiuser/Flags;->enableSystemUserOnlyForServicesAndProviders()Z+]Landroid/multiuser/FeatureFlags;Landroid/multiuser/FeatureFlagsImpl;
HSPLandroid/net/Credentials;-><init>(III)V
HSPLandroid/net/Credentials;->getPid()I
HSPLandroid/net/Credentials;->getUid()I
@@ -11373,8 +11423,8 @@ HSPLandroid/net/TelephonyNetworkSpecifier;->equals(Ljava/lang/Object;)Z
HSPLandroid/net/TelephonyNetworkSpecifier;->hashCode()I
HSPLandroid/net/TelephonyNetworkSpecifier;->toString()Ljava/lang/String;
HSPLandroid/net/TelephonyNetworkSpecifier;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/Uri;
-HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/Uri;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/net/Uri$1;Landroid/net/Uri$1;
HSPLandroid/net/Uri$1;->newArray(I)[Landroid/net/Uri;
HSPLandroid/net/Uri$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/net/Uri$AbstractHierarchicalUri;-><init>()V
@@ -11409,11 +11459,11 @@ HSPLandroid/net/Uri$Builder;->path(Landroid/net/Uri$PathPart;)Landroid/net/Uri$B
HSPLandroid/net/Uri$Builder;->path(Ljava/lang/String;)Landroid/net/Uri$Builder;
HSPLandroid/net/Uri$Builder;->query(Landroid/net/Uri$Part;)Landroid/net/Uri$Builder;
HSPLandroid/net/Uri$Builder;->scheme(Ljava/lang/String;)Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$Builder;->toString()Ljava/lang/String;
+HSPLandroid/net/Uri$Builder;->toString()Ljava/lang/String;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;
HSPLandroid/net/Uri$HierarchicalUri;-><init>(Ljava/lang/String;Landroid/net/Uri$Part;Landroid/net/Uri$PathPart;Landroid/net/Uri$Part;Landroid/net/Uri$Part;)V
-HSPLandroid/net/Uri$HierarchicalUri;->appendSspTo(Ljava/lang/StringBuilder;)V
-HSPLandroid/net/Uri$HierarchicalUri;->buildUpon()Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$HierarchicalUri;->generatePath(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;,Landroid/net/Uri$Part;
+HSPLandroid/net/Uri$HierarchicalUri;->appendSspTo(Ljava/lang/StringBuilder;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$Part;Landroid/net/Uri$Part;,Landroid/net/Uri$Part$EmptyPart;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$HierarchicalUri;->buildUpon()Landroid/net/Uri$Builder;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;
+HSPLandroid/net/Uri$HierarchicalUri;->generatePath(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;,Landroid/net/Uri$Part;]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->getAuthority()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->getEncodedAuthority()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->getEncodedFragment()Ljava/lang/String;
@@ -11426,7 +11476,7 @@ HSPLandroid/net/Uri$HierarchicalUri;->getQuery()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->getScheme()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->getSchemeSpecificPart()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->isHierarchical()Z
-HSPLandroid/net/Uri$HierarchicalUri;->makeUriString()Ljava/lang/String;
+HSPLandroid/net/Uri$HierarchicalUri;->makeUriString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;
HSPLandroid/net/Uri$HierarchicalUri;->readFrom(Landroid/os/Parcel;)Landroid/net/Uri;
HSPLandroid/net/Uri$HierarchicalUri;->toString()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->writeToParcel(Landroid/os/Parcel;I)V
@@ -11447,13 +11497,13 @@ HSPLandroid/net/Uri$Part;->isEmpty()Z
HSPLandroid/net/Uri$Part;->nonNull(Landroid/net/Uri$Part;)Landroid/net/Uri$Part;
HSPLandroid/net/Uri$PathPart;-><init>(Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/net/Uri$PathPart;->appendDecodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;
-HSPLandroid/net/Uri$PathPart;->appendEncodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->appendEncodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
HSPLandroid/net/Uri$PathPart;->from(Ljava/lang/String;Ljava/lang/String;)Landroid/net/Uri$PathPart;
HSPLandroid/net/Uri$PathPart;->fromDecoded(Ljava/lang/String;)Landroid/net/Uri$PathPart;
HSPLandroid/net/Uri$PathPart;->fromEncoded(Ljava/lang/String;)Landroid/net/Uri$PathPart;
HSPLandroid/net/Uri$PathPart;->getEncoded()Ljava/lang/String;
-HSPLandroid/net/Uri$PathPart;->getPathSegments()Landroid/net/Uri$PathSegments;
-HSPLandroid/net/Uri$PathPart;->makeAbsolute(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->getPathSegments()Landroid/net/Uri$PathSegments;+]Ljava/lang/String;Ljava/lang/String;]Landroid/net/Uri$PathSegmentsBuilder;Landroid/net/Uri$PathSegmentsBuilder;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->makeAbsolute(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$PathSegments;-><init>([Ljava/lang/String;I)V
HSPLandroid/net/Uri$PathSegments;->get(I)Ljava/lang/Object;
HSPLandroid/net/Uri$PathSegments;->get(I)Ljava/lang/String;
@@ -11462,9 +11512,9 @@ HSPLandroid/net/Uri$PathSegmentsBuilder;->add(Ljava/lang/String;)V
HSPLandroid/net/Uri$PathSegmentsBuilder;->build()Landroid/net/Uri$PathSegments;
HSPLandroid/net/Uri$StringUri;-><init>(Ljava/lang/String;)V
HSPLandroid/net/Uri$StringUri;-><init>(Ljava/lang/String;Landroid/net/Uri$StringUri-IA;)V
-HSPLandroid/net/Uri$StringUri;->buildUpon()Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$StringUri;->findFragmentSeparator()I
-HSPLandroid/net/Uri$StringUri;->findSchemeSeparator()I
+HSPLandroid/net/Uri$StringUri;->buildUpon()Landroid/net/Uri$Builder;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;]Landroid/net/Uri$StringUri;Landroid/net/Uri$StringUri;
+HSPLandroid/net/Uri$StringUri;->findFragmentSeparator()I+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->findSchemeSeparator()I+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->getAuthority()Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->getAuthorityPart()Landroid/net/Uri$Part;
HSPLandroid/net/Uri$StringUri;->getEncodedAuthority()Ljava/lang/String;
@@ -11482,11 +11532,11 @@ HSPLandroid/net/Uri$StringUri;->getScheme()Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->getSchemeSpecificPart()Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->isHierarchical()Z
HSPLandroid/net/Uri$StringUri;->isRelative()Z
-HSPLandroid/net/Uri$StringUri;->parseAuthority(Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parseAuthority(Ljava/lang/String;I)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->parseFragment()Ljava/lang/String;
-HSPLandroid/net/Uri$StringUri;->parsePath()Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parsePath()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->parsePath(Ljava/lang/String;I)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/net/Uri$StringUri;->parseQuery()Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parseQuery()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->parseScheme()Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->toString()Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->writeToParcel(Landroid/os/Parcel;I)V
@@ -11503,8 +11553,8 @@ HSPLandroid/net/Uri;->equals(Ljava/lang/Object;)Z
HSPLandroid/net/Uri;->fromFile(Ljava/io/File;)Landroid/net/Uri;
HSPLandroid/net/Uri;->fromParts(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/net/Uri;->getBooleanQueryParameter(Ljava/lang/String;Z)Z
-HSPLandroid/net/Uri;->getQueryParameter(Ljava/lang/String;)Ljava/lang/String;+]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/net/Uri;->getQueryParameterNames()Ljava/util/Set;+]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Set;Ljava/util/LinkedHashSet;
+HSPLandroid/net/Uri;->getQueryParameter(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
+HSPLandroid/net/Uri;->getQueryParameterNames()Ljava/util/Set;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Set;Ljava/util/LinkedHashSet;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
HSPLandroid/net/Uri;->hashCode()I
HSPLandroid/net/Uri;->isAbsolute()Z
HSPLandroid/net/Uri;->isAllowed(CLjava/lang/String;)Z+]Ljava/lang/String;Ljava/lang/String;
@@ -11514,9 +11564,9 @@ HSPLandroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/net/Uri;->toSafeString()Ljava/lang/String;
HSPLandroid/net/Uri;->withAppendedPath(Landroid/net/Uri;Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/net/Uri;->writeToParcel(Landroid/os/Parcel;Landroid/net/Uri;)V
-HSPLandroid/net/UriCodec;->appendDecoded(Ljava/lang/StringBuilder;Ljava/lang/String;ZLjava/nio/charset/Charset;Z)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/nio/charset/Charset;Lcom/android/icu/charset/CharsetICU;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
+HSPLandroid/net/UriCodec;->appendDecoded(Ljava/lang/StringBuilder;Ljava/lang/String;ZLjava/nio/charset/Charset;Z)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Ljava/nio/charset/Charset;Lcom/android/icu/charset/CharsetICU;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
HSPLandroid/net/UriCodec;->decode(Ljava/lang/String;ZLjava/nio/charset/Charset;Z)Ljava/lang/String;
-HSPLandroid/net/UriCodec;->flushDecodingByteAccumulator(Ljava/lang/StringBuilder;Ljava/nio/charset/CharsetDecoder;Ljava/nio/ByteBuffer;Z)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
+HSPLandroid/net/UriCodec;->flushDecodingByteAccumulator(Ljava/lang/StringBuilder;Ljava/nio/charset/CharsetDecoder;Ljava/nio/ByteBuffer;Z)V+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
HSPLandroid/net/UriCodec;->getNextCharacter(Ljava/lang/String;IILjava/lang/String;)C
HSPLandroid/net/UriCodec;->hexCharToValue(C)I
HSPLandroid/net/WebAddress;-><init>(Ljava/lang/String;)V
@@ -11533,6 +11583,7 @@ HSPLandroid/net/vcn/VcnTransportInfo$1;-><init>()V
HSPLandroid/net/vcn/VcnTransportInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/vcn/VcnTransportInfo;
HSPLandroid/net/vcn/VcnTransportInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/net/vcn/VcnTransportInfo;-><clinit>()V
+HSPLandroid/nfc/NfcFrameworkInitializer;->setNfcServiceManager(Landroid/nfc/NfcServiceManager;)V
HSPLandroid/nfc/NfcServiceManager;-><init>()V
HSPLandroid/nfc/cardemulation/AidGroup$1;->createFromParcel(Landroid/os/Parcel;)Landroid/nfc/cardemulation/AidGroup;
HSPLandroid/nfc/cardemulation/AidGroup$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -11584,13 +11635,13 @@ HSPLandroid/os/AsyncTask;->postResultIfNotInvoked(Ljava/lang/Object;)V
HSPLandroid/os/BaseBundle;-><init>()V
HSPLandroid/os/BaseBundle;-><init>(I)V
HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;)V
-HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;Z)V
+HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;Z)V+]Landroid/os/BaseBundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/BaseBundle;-><init>(Landroid/os/Parcel;I)V
-HSPLandroid/os/BaseBundle;-><init>(Ljava/lang/ClassLoader;I)V+]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;-><init>(Ljava/lang/ClassLoader;I)V+]Ljava/lang/Object;Landroid/os/Bundle;,Landroid/os/PersistableBundle;]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/os/BaseBundle;->clear()V
HSPLandroid/os/BaseBundle;->containsKey(Ljava/lang/String;)Z
HSPLandroid/os/BaseBundle;->deepCopyValue(Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/os/BaseBundle;->getArrayList(Ljava/lang/String;Ljava/lang/Class;)Ljava/util/ArrayList;
HSPLandroid/os/BaseBundle;->getBoolean(Ljava/lang/String;)Z
@@ -11599,9 +11650,9 @@ HSPLandroid/os/BaseBundle;->getBooleanArray(Ljava/lang/String;)[Z
HSPLandroid/os/BaseBundle;->getByteArray(Ljava/lang/String;)[B
HSPLandroid/os/BaseBundle;->getCharSequence(Ljava/lang/String;)Ljava/lang/CharSequence;
HSPLandroid/os/BaseBundle;->getCharSequenceArray(Ljava/lang/String;)[Ljava/lang/CharSequence;
-HSPLandroid/os/BaseBundle;->getFloat(Ljava/lang/String;F)F
+HSPLandroid/os/BaseBundle;->getFloat(Ljava/lang/String;F)F+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Float;Ljava/lang/Float;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;)I
-HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;I)I
+HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;I)I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->getIntArray(Ljava/lang/String;)[I
HSPLandroid/os/BaseBundle;->getIntegerArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
HSPLandroid/os/BaseBundle;->getLong(Ljava/lang/String;)J
@@ -11611,18 +11662,18 @@ HSPLandroid/os/BaseBundle;->getSerializable(Ljava/lang/String;)Ljava/io/Serializ
HSPLandroid/os/BaseBundle;->getSerializable(Ljava/lang/String;Ljava/lang/Class;)Ljava/io/Serializable;
HSPLandroid/os/BaseBundle;->getString(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/os/BaseBundle;->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/os/BaseBundle;->getStringArray(Ljava/lang/String;)[Ljava/lang/String;
+HSPLandroid/os/BaseBundle;->getStringArray(Ljava/lang/String;)[Ljava/lang/String;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->getStringArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValueAt(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->initializeFromParcelLocked(Landroid/os/Parcel;ZZ)V
-HSPLandroid/os/BaseBundle;->isEmpty()Z
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValueAt(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/os/BaseBundle;->initializeFromParcelLocked(Landroid/os/Parcel;ZZ)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/BaseBundle;->isEmpty()Z+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->isEmptyParcel()Z
HSPLandroid/os/BaseBundle;->isEmptyParcel(Landroid/os/Parcel;)Z
HSPLandroid/os/BaseBundle;->isParcelled()Z
-HSPLandroid/os/BaseBundle;->keySet()Ljava/util/Set;+]Landroid/os/BaseBundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/BaseBundle;->keySet()Ljava/util/Set;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->putAll(Landroid/os/PersistableBundle;)V
HSPLandroid/os/BaseBundle;->putAll(Landroid/util/ArrayMap;)V
HSPLandroid/os/BaseBundle;->putBoolean(Ljava/lang/String;Z)V
@@ -11631,7 +11682,7 @@ HSPLandroid/os/BaseBundle;->putByteArray(Ljava/lang/String;[B)V
HSPLandroid/os/BaseBundle;->putCharSequence(Ljava/lang/String;Ljava/lang/CharSequence;)V
HSPLandroid/os/BaseBundle;->putCharSequenceArray(Ljava/lang/String;[Ljava/lang/CharSequence;)V
HSPLandroid/os/BaseBundle;->putDouble(Ljava/lang/String;D)V
-HSPLandroid/os/BaseBundle;->putFloat(Ljava/lang/String;F)V
+HSPLandroid/os/BaseBundle;->putFloat(Ljava/lang/String;F)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->putInt(Ljava/lang/String;I)V
HSPLandroid/os/BaseBundle;->putIntArray(Ljava/lang/String;[I)V
HSPLandroid/os/BaseBundle;->putLong(Ljava/lang/String;J)V
@@ -11641,16 +11692,16 @@ HSPLandroid/os/BaseBundle;->putString(Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/os/BaseBundle;->putStringArray(Ljava/lang/String;[Ljava/lang/String;)V
HSPLandroid/os/BaseBundle;->putStringArrayList(Ljava/lang/String;Ljava/util/ArrayList;)V
HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;)V
-HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;I)V
-HSPLandroid/os/BaseBundle;->recycleParcel(Landroid/os/Parcel;)V
+HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/BaseBundle;->recycleParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/BaseBundle;->remove(Ljava/lang/String;)V
HSPLandroid/os/BaseBundle;->setClassLoader(Ljava/lang/ClassLoader;)V
HSPLandroid/os/BaseBundle;->setShouldDefuse(Z)V
-HSPLandroid/os/BaseBundle;->size()I
-HSPLandroid/os/BaseBundle;->unparcel()V+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->size()I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->unparcel()V+]Landroid/os/BaseBundle;Landroid/os/Bundle;,Landroid/os/PersistableBundle;
HSPLandroid/os/BaseBundle;->unparcel(Z)V
-HSPLandroid/os/BaseBundle;->unwrapLazyValueFromMapLocked(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;]Ljava/util/function/BiFunction;Landroid/os/Parcel$LazyValue;
-HSPLandroid/os/BaseBundle;->writeToParcelInner(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/BaseBundle;->unwrapLazyValueFromMapLocked(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/function/BiFunction;Landroid/os/Parcel$LazyValue;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/os/BaseBundle;->writeToParcelInner(Landroid/os/Parcel;I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/BatteryManager;-><init>(Landroid/content/Context;Lcom/android/internal/app/IBatteryStats;Landroid/os/IBatteryPropertiesRegistrar;)V
HSPLandroid/os/BatteryManager;->getIntProperty(I)I
HSPLandroid/os/BatteryManager;->getLongProperty(I)J
@@ -11717,12 +11768,12 @@ HSPLandroid/os/Binder;->setTransactionCallback(Landroid/os/IBinderCallback;)V
HSPLandroid/os/Binder;->transact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
HSPLandroid/os/Binder;->unlinkToDeath(Landroid/os/IBinder$DeathRecipient;I)Z
HSPLandroid/os/Binder;->withCleanCallingIdentity(Lcom/android/internal/util/FunctionalUtils$ThrowingRunnable;)V
-HSPLandroid/os/BinderProxy$ProxyMap;->get(J)Landroid/os/BinderProxy;+]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/BinderProxy$ProxyMap;->get(J)Landroid/os/BinderProxy;
HSPLandroid/os/BinderProxy$ProxyMap;->hash(J)I
HSPLandroid/os/BinderProxy$ProxyMap;->remove(II)V
HSPLandroid/os/BinderProxy$ProxyMap;->set(JLandroid/os/BinderProxy;)V
HSPLandroid/os/BinderProxy;-><init>(J)V
-HSPLandroid/os/BinderProxy;->getInstance(JJ)Landroid/os/BinderProxy;+]Landroid/os/BinderProxy$ProxyMap;Landroid/os/BinderProxy$ProxyMap;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/os/BinderProxy;->getInstance(JJ)Landroid/os/BinderProxy;
HSPLandroid/os/BinderProxy;->linkToDeath(Landroid/os/IBinder$DeathRecipient;I)V+]Ljava/util/List;Ljava/util/Collections$SynchronizedRandomAccessList;
HSPLandroid/os/BinderProxy;->queryLocalInterface(Ljava/lang/String;)Landroid/os/IInterface;
HSPLandroid/os/BinderProxy;->sendDeathNotice(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V
@@ -11761,7 +11812,7 @@ HSPLandroid/os/Bundle;->getFloat(Ljava/lang/String;F)F
HSPLandroid/os/Bundle;->getIntegerArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
HSPLandroid/os/Bundle;->getParcelable(Ljava/lang/String;)Landroid/os/Parcelable;
HSPLandroid/os/Bundle;->getParcelable(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;)[Landroid/os/Parcelable;
+HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;)[Landroid/os/Parcelable;+]Landroid/os/Bundle;Landroid/os/Bundle;
HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;Ljava/lang/Class;)[Ljava/lang/Object;
HSPLandroid/os/Bundle;->getParcelableArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
HSPLandroid/os/Bundle;->getSerializable(Ljava/lang/String;)Ljava/io/Serializable;
@@ -11769,10 +11820,10 @@ HSPLandroid/os/Bundle;->getSerializable(Ljava/lang/String;Ljava/lang/Class;)Ljav
HSPLandroid/os/Bundle;->getSparseParcelableArray(Ljava/lang/String;)Landroid/util/SparseArray;
HSPLandroid/os/Bundle;->getStringArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
HSPLandroid/os/Bundle;->hasFileDescriptors()Z
-HSPLandroid/os/Bundle;->maybePrefillHasFds()V
+HSPLandroid/os/Bundle;->maybePrefillHasFds()V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Bundle;->putAll(Landroid/os/Bundle;)V
HSPLandroid/os/Bundle;->putBinder(Ljava/lang/String;Landroid/os/IBinder;)V
-HSPLandroid/os/Bundle;->putBundle(Ljava/lang/String;Landroid/os/Bundle;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/Bundle;->putBundle(Ljava/lang/String;Landroid/os/Bundle;)V
HSPLandroid/os/Bundle;->putByteArray(Ljava/lang/String;[B)V
HSPLandroid/os/Bundle;->putCharSequence(Ljava/lang/String;Ljava/lang/CharSequence;)V
HSPLandroid/os/Bundle;->putCharSequenceArray(Ljava/lang/String;[Ljava/lang/CharSequence;)V
@@ -11939,7 +11990,7 @@ HSPLandroid/os/FileObserver;-><init>(Ljava/io/File;I)V
HSPLandroid/os/FileObserver;-><init>(Ljava/lang/String;I)V
HSPLandroid/os/FileObserver;-><init>(Ljava/util/List;I)V
HSPLandroid/os/FileObserver;->startWatching()V
-HSPLandroid/os/FileUtils;->buildValidExtFilename(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/os/FileUtils;->buildValidExtFilename(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;
HSPLandroid/os/FileUtils;->bytesToFile(Ljava/lang/String;[B)V
HSPLandroid/os/FileUtils;->closeQuietly(Ljava/lang/AutoCloseable;)V
HSPLandroid/os/FileUtils;->contains(Ljava/io/File;Ljava/io/File;)Z
@@ -12011,7 +12062,7 @@ HSPLandroid/os/Handler;->obtainMessage(IIILjava/lang/Object;)Landroid/os/Message
HSPLandroid/os/Handler;->obtainMessage(ILjava/lang/Object;)Landroid/os/Message;
HSPLandroid/os/Handler;->post(Ljava/lang/Runnable;)Z+]Landroid/os/Handler;missing_types
HSPLandroid/os/Handler;->postAtFrontOfQueue(Ljava/lang/Runnable;)Z
-HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;J)Z
+HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;J)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;
HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;Ljava/lang/Object;J)Z
HSPLandroid/os/Handler;->postDelayed(Ljava/lang/Runnable;IJ)Z
HSPLandroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z
@@ -12024,7 +12075,7 @@ HSPLandroid/os/Handler;->runWithScissors(Ljava/lang/Runnable;J)Z
HSPLandroid/os/Handler;->sendEmptyMessage(I)Z
HSPLandroid/os/Handler;->sendEmptyMessageAtTime(IJ)Z
HSPLandroid/os/Handler;->sendEmptyMessageDelayed(IJ)Z
-HSPLandroid/os/Handler;->sendMessage(Landroid/os/Message;)Z
+HSPLandroid/os/Handler;->sendMessage(Landroid/os/Message;)Z+]Landroid/os/Handler;missing_types
HSPLandroid/os/Handler;->sendMessageAtFrontOfQueue(Landroid/os/Message;)Z
HSPLandroid/os/Handler;->sendMessageAtTime(Landroid/os/Message;J)Z
HSPLandroid/os/Handler;->sendMessageDelayed(Landroid/os/Message;J)Z+]Landroid/os/Handler;missing_types
@@ -12070,6 +12121,7 @@ HSPLandroid/os/IDeviceIdentifiersPolicyService$Stub;->asInterface(Landroid/os/IB
HSPLandroid/os/IDeviceIdleController$Stub$Proxy;->isPowerSaveWhitelistApp(Ljava/lang/String;)Z
HSPLandroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController;
HSPLandroid/os/IHintManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/os/IHintManager$Stub$Proxy;->createHintSession(Landroid/os/IBinder;[IJ)Landroid/os/IHintSession;
HSPLandroid/os/IHintManager$Stub$Proxy;->getHintSessionPreferredRate()J
HSPLandroid/os/IHintManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IHintManager;
HSPLandroid/os/IHintSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IHintSession;
@@ -12164,14 +12216,14 @@ HSPLandroid/os/IpcDataCache;-><init>(ILjava/lang/String;Ljava/lang/String;Ljava/
HSPLandroid/os/IpcDataCache;-><init>(Landroid/os/IpcDataCache$Config;Landroid/os/IpcDataCache$QueryHandler;)V
HSPLandroid/os/IpcDataCache;-><init>(Landroid/os/IpcDataCache$Config;Landroid/os/IpcDataCache$RemoteCall;)V
HSPLandroid/os/IpcDataCache;->query(Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/LocaleList;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/os/LocaleList$1;Landroid/os/LocaleList$1;
-HSPLandroid/os/LocaleList;-><init>([Ljava/util/Locale;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashSet;Ljava/util/HashSet;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/LocaleList;
+HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/os/LocaleList;-><init>([Ljava/util/Locale;)V
HSPLandroid/os/LocaleList;->computeFirstMatch(Ljava/util/Collection;Z)Ljava/util/Locale;
HSPLandroid/os/LocaleList;->computeFirstMatchIndex(Ljava/util/Collection;Z)I
-HSPLandroid/os/LocaleList;->equals(Ljava/lang/Object;)Z
+HSPLandroid/os/LocaleList;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/util/Locale;
HSPLandroid/os/LocaleList;->findFirstMatchIndex(Ljava/util/Locale;)I
-HSPLandroid/os/LocaleList;->forLanguageTags(Ljava/lang/String;)Landroid/os/LocaleList;+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/os/LocaleList;->forLanguageTags(Ljava/lang/String;)Landroid/os/LocaleList;
HSPLandroid/os/LocaleList;->get(I)Ljava/util/Locale;
HSPLandroid/os/LocaleList;->getAdjustedDefault()Landroid/os/LocaleList;
HSPLandroid/os/LocaleList;->getDefault()Landroid/os/LocaleList;+]Ljava/lang/Object;Ljava/util/Locale;
@@ -12193,10 +12245,10 @@ HSPLandroid/os/Looper;-><init>(Z)V
HSPLandroid/os/Looper;->getMainLooper()Landroid/os/Looper;
HSPLandroid/os/Looper;->getQueue()Landroid/os/MessageQueue;
HSPLandroid/os/Looper;->getThread()Ljava/lang/Thread;
-HSPLandroid/os/Looper;->getThresholdOverride()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Thread;Landroid/os/HandlerThread;
+HSPLandroid/os/Looper;->getThresholdOverride()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Thread;missing_types
HSPLandroid/os/Looper;->isCurrentThread()Z
HSPLandroid/os/Looper;->loop()V
-HSPLandroid/os/Looper;->loopOnce(Landroid/os/Looper;JI)Z+]Landroid/os/Handler;missing_types]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
+HSPLandroid/os/Looper;->loopOnce(Landroid/os/Looper;JI)Z+]Landroid/os/Handler;megamorphic_types]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
HSPLandroid/os/Looper;->myLooper()Landroid/os/Looper;+]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal;
HSPLandroid/os/Looper;->myQueue()Landroid/os/MessageQueue;
HSPLandroid/os/Looper;->prepare()V
@@ -12230,7 +12282,7 @@ HSPLandroid/os/Message;->peekData()Landroid/os/Bundle;
HSPLandroid/os/Message;->readFromParcel(Landroid/os/Parcel;)V
HSPLandroid/os/Message;->recycle()V
HSPLandroid/os/Message;->recycleUnchecked()V
-HSPLandroid/os/Message;->sendToTarget()V
+HSPLandroid/os/Message;->sendToTarget()V+]Landroid/os/Handler;megamorphic_types
HSPLandroid/os/Message;->setAsynchronous(Z)V
HSPLandroid/os/Message;->setCallback(Ljava/lang/Runnable;)Landroid/os/Message;
HSPLandroid/os/Message;->setData(Landroid/os/Bundle;)V
@@ -12249,13 +12301,13 @@ HSPLandroid/os/MessageQueue;->enqueueMessage(Landroid/os/Message;J)Z+]Landroid/o
HSPLandroid/os/MessageQueue;->finalize()V
HSPLandroid/os/MessageQueue;->hasMessages(Landroid/os/Handler;ILjava/lang/Object;)Z
HSPLandroid/os/MessageQueue;->hasMessages(Landroid/os/Handler;Ljava/lang/Runnable;Ljava/lang/Object;)Z
-HSPLandroid/os/MessageQueue;->next()Landroid/os/Message;+]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue$IdleHandler;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/MessageQueue;->next()Landroid/os/Message;+]Landroid/os/MessageQueue$IdleHandler;missing_types]Landroid/os/Message;Landroid/os/Message;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/os/MessageQueue;->postSyncBarrier()I
HSPLandroid/os/MessageQueue;->postSyncBarrier(J)I+]Landroid/os/Message;Landroid/os/Message;
HSPLandroid/os/MessageQueue;->quit(Z)V
HSPLandroid/os/MessageQueue;->removeAllFutureMessagesLocked()V
HSPLandroid/os/MessageQueue;->removeAllMessagesLocked()V
-HSPLandroid/os/MessageQueue;->removeCallbacksAndMessages(Landroid/os/Handler;Ljava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
+HSPLandroid/os/MessageQueue;->removeCallbacksAndMessages(Landroid/os/Handler;Ljava/lang/Object;)V
HSPLandroid/os/MessageQueue;->removeIdleHandler(Landroid/os/MessageQueue$IdleHandler;)V
HSPLandroid/os/MessageQueue;->removeMessages(Landroid/os/Handler;ILjava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
HSPLandroid/os/MessageQueue;->removeMessages(Landroid/os/Handler;Ljava/lang/Runnable;Ljava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
@@ -12276,12 +12328,12 @@ HSPLandroid/os/Parcel$2;-><init>(Landroid/os/Parcel;Ljava/io/InputStream;Ljava/l
HSPLandroid/os/Parcel$2;->resolveClass(Ljava/io/ObjectStreamClass;)Ljava/lang/Class;+]Ljava/io/ObjectStreamClass;Ljava/io/ObjectStreamClass;
HSPLandroid/os/Parcel$LazyValue;-><init>(Landroid/os/Parcel;IIILjava/lang/ClassLoader;)V
HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/os/Parcel$LazyValue;Landroid/os/Parcel$LazyValue;
HSPLandroid/os/Parcel$LazyValue;->writeToParcel(Landroid/os/Parcel;)V
HSPLandroid/os/Parcel$ReadWriteHelper;->readString16(Landroid/os/Parcel;)Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel$ReadWriteHelper;->readString8(Landroid/os/Parcel;)Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel$ReadWriteHelper;->writeString16(Landroid/os/Parcel;Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel$ReadWriteHelper;->writeString8(Landroid/os/Parcel;Ljava/lang/String;)V
+HSPLandroid/os/Parcel$ReadWriteHelper;->writeString8(Landroid/os/Parcel;Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->-$$Nest$mreadValue(Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/os/Parcel;-><init>(J)V
HSPLandroid/os/Parcel;->adoptClassCookies(Landroid/os/Parcel;)V
@@ -12294,21 +12346,21 @@ HSPLandroid/os/Parcel;->createBooleanArray()[Z
HSPLandroid/os/Parcel;->createByteArray()[B
HSPLandroid/os/Parcel;->createException(ILjava/lang/String;)Ljava/lang/Exception;
HSPLandroid/os/Parcel;->createExceptionOrNull(ILjava/lang/String;)Ljava/lang/Exception;
-HSPLandroid/os/Parcel;->createFloatArray()[F+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createFloatArray()[F
HSPLandroid/os/Parcel;->createIntArray()[I+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel;->createLongArray()[J
+HSPLandroid/os/Parcel;->createLongArray()[J+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->createString16Array()[Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->createString8Array()[Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->createStringArray()[Ljava/lang/String;
-HSPLandroid/os/Parcel;->createStringArrayList()Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->createTypedArray(Landroid/os/Parcelable$Creator;)[Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;missing_types
-HSPLandroid/os/Parcel;->createTypedArrayList(Landroid/os/Parcelable$Creator;)Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->createStringArrayList()Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createTypedArray(Landroid/os/Parcelable$Creator;)[Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;missing_types]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createTypedArrayList(Landroid/os/Parcelable$Creator;)Ljava/util/ArrayList;+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->dataAvail()I
HSPLandroid/os/Parcel;->dataPosition()I
HSPLandroid/os/Parcel;->dataSize()I
HSPLandroid/os/Parcel;->destroy()V
HSPLandroid/os/Parcel;->enforceInterface(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->enforceNoDataAvail()V
+HSPLandroid/os/Parcel;->enforceNoDataAvail()V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->ensureReadSquashableParcelables()V
HSPLandroid/os/Parcel;->ensureWithinMemoryLimit(II)V
HSPLandroid/os/Parcel;->finalize()V
@@ -12330,33 +12382,33 @@ HSPLandroid/os/Parcel;->obtain(Landroid/os/IBinder;)Landroid/os/Parcel;
HSPLandroid/os/Parcel;->pushAllowFds(Z)Z
HSPLandroid/os/Parcel;->readArrayList(Ljava/lang/ClassLoader;)Ljava/util/ArrayList;
HSPLandroid/os/Parcel;->readArrayList(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->readArrayListInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;IZZLjava/lang/ClassLoader;)I
+HSPLandroid/os/Parcel;->readArrayListInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;IZZLjava/lang/ClassLoader;)I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;Ljava/lang/ClassLoader;)V
HSPLandroid/os/Parcel;->readArrayMapInternal(Landroid/util/ArrayMap;ILjava/lang/ClassLoader;)V
-HSPLandroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArraySet;Landroid/util/ArraySet;
+HSPLandroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet;
HSPLandroid/os/Parcel;->readBinderList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->readBlob()[B
HSPLandroid/os/Parcel;->readBoolean()Z+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readBooleanArray([Z)V
-HSPLandroid/os/Parcel;->readBundle()Landroid/os/Bundle;
-HSPLandroid/os/Parcel;->readBundle(Ljava/lang/ClassLoader;)Landroid/os/Bundle;
-HSPLandroid/os/Parcel;->readByte()B
+HSPLandroid/os/Parcel;->readBundle()Landroid/os/Bundle;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readBundle(Ljava/lang/ClassLoader;)Landroid/os/Bundle;+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readByte()B+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readByteArray([B)V
HSPLandroid/os/Parcel;->readCallingWorkSourceUid()I
-HSPLandroid/os/Parcel;->readCharSequence()Ljava/lang/CharSequence;
+HSPLandroid/os/Parcel;->readCharSequence()Ljava/lang/CharSequence;+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;
HSPLandroid/os/Parcel;->readCharSequenceArray()[Ljava/lang/CharSequence;
HSPLandroid/os/Parcel;->readDouble()D
-HSPLandroid/os/Parcel;->readException()V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readException()V
HSPLandroid/os/Parcel;->readException(ILjava/lang/String;)V
-HSPLandroid/os/Parcel;->readExceptionCode()I+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readExceptionCode()I
HSPLandroid/os/Parcel;->readFloat()F
HSPLandroid/os/Parcel;->readFloatArray([F)V
HSPLandroid/os/Parcel;->readHashMap(Ljava/lang/ClassLoader;)Ljava/util/HashMap;
HSPLandroid/os/Parcel;->readHashMapInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;Ljava/lang/Class;)Ljava/util/HashMap;
HSPLandroid/os/Parcel;->readInt()I
HSPLandroid/os/Parcel;->readIntArray([I)V
-HSPLandroid/os/Parcel;->readLazyValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;
+HSPLandroid/os/Parcel;->readLazyValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readList(Ljava/util/List;Ljava/lang/ClassLoader;)V
HSPLandroid/os/Parcel;->readList(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)V
HSPLandroid/os/Parcel;->readListInternal(Ljava/util/List;ILjava/lang/ClassLoader;)V
@@ -12370,25 +12422,25 @@ HSPLandroid/os/Parcel;->readParcelable(Ljava/lang/ClassLoader;)Landroid/os/Parce
HSPLandroid/os/Parcel;->readParcelable(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/os/Parcel;->readParcelableArray(Ljava/lang/ClassLoader;)[Landroid/os/Parcelable;
HSPLandroid/os/Parcel;->readParcelableArray(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;
-HSPLandroid/os/Parcel;->readParcelableArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/os/Parcel;->readParcelableArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readParcelableCreator(Ljava/lang/ClassLoader;)Landroid/os/Parcelable$Creator;
-HSPLandroid/os/Parcel;->readParcelableCreatorInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/os/Parcelable$Creator;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/reflect/Field;Ljava/lang/reflect/Field;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/os/Parcel;->readParcelableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types
+HSPLandroid/os/Parcel;->readParcelableCreatorInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/os/Parcelable$Creator;+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Object;Landroid/os/Parcel;]Ljava/lang/reflect/Field;Ljava/lang/reflect/Field;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readParcelableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types]Landroid/os/Parcelable$ClassLoaderCreator;Landroid/content/pm/ParceledListSlice$1;
HSPLandroid/os/Parcel;->readParcelableList(Ljava/util/List;Ljava/lang/ClassLoader;)Ljava/util/List;
HSPLandroid/os/Parcel;->readParcelableList(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;
-HSPLandroid/os/Parcel;->readParcelableListInternal(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->readParcelableListInternal(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;+]Ljava/util/List;Ljava/util/ArrayList;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readPersistableBundle()Landroid/os/PersistableBundle;
HSPLandroid/os/Parcel;->readPersistableBundle(Ljava/lang/ClassLoader;)Landroid/os/PersistableBundle;
HSPLandroid/os/Parcel;->readRawFileDescriptor()Ljava/io/FileDescriptor;
HSPLandroid/os/Parcel;->readSerializable()Ljava/io/Serializable;
-HSPLandroid/os/Parcel;->readSerializableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/io/ObjectInputStream;Landroid/os/Parcel$2;
+HSPLandroid/os/Parcel;->readSerializableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Ljava/io/ObjectInputStream;Landroid/os/Parcel$2;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readSize()Landroid/util/Size;
HSPLandroid/os/Parcel;->readSparseArray(Ljava/lang/ClassLoader;)Landroid/util/SparseArray;
HSPLandroid/os/Parcel;->readSparseArray(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/util/SparseArray;
HSPLandroid/os/Parcel;->readSparseArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/util/SparseArray;
HSPLandroid/os/Parcel;->readSparseIntArray()Landroid/util/SparseIntArray;
HSPLandroid/os/Parcel;->readSparseIntArrayInternal(Landroid/util/SparseIntArray;I)V
-HSPLandroid/os/Parcel;->readSquashed(Landroid/os/Parcel$SquashReadHelper;)Landroid/os/Parcelable;
+HSPLandroid/os/Parcel;->readSquashed(Landroid/os/Parcel$SquashReadHelper;)Landroid/os/Parcelable;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/os/Parcel$SquashReadHelper;Landroid/content/pm/ApplicationInfo$1$$ExternalSyntheticLambda0;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readString()Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readString16()Ljava/lang/String;+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
HSPLandroid/os/Parcel;->readString16Array([Ljava/lang/String;)V
@@ -12399,11 +12451,11 @@ HSPLandroid/os/Parcel;->readStringArray()[Ljava/lang/String;+]Landroid/os/Parcel
HSPLandroid/os/Parcel;->readStringArray([Ljava/lang/String;)V
HSPLandroid/os/Parcel;->readStringList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->readStrongBinder()Landroid/os/IBinder;
-HSPLandroid/os/Parcel;->readTypedArray([Ljava/lang/Object;Landroid/os/Parcelable$Creator;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readTypedArray([Ljava/lang/Object;Landroid/os/Parcelable$Creator;)V
HSPLandroid/os/Parcel;->readTypedList(Ljava/util/List;Landroid/os/Parcelable$Creator;)V
-HSPLandroid/os/Parcel;->readTypedObject(Landroid/os/Parcelable$Creator;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;megamorphic_types
+HSPLandroid/os/Parcel;->readTypedObject(Landroid/os/Parcelable$Creator;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;
HSPLandroid/os/Parcel;->readValue(Ljava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->recycle()V
@@ -12415,11 +12467,11 @@ HSPLandroid/os/Parcel;->setDataSize(I)V
HSPLandroid/os/Parcel;->setReadWriteHelper(Landroid/os/Parcel$ReadWriteHelper;)V
HSPLandroid/os/Parcel;->unmarshall([BII)V
HSPLandroid/os/Parcel;->writeArrayMap(Landroid/util/ArrayMap;)V
-HSPLandroid/os/Parcel;->writeArrayMapInternal(Landroid/util/ArrayMap;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/Parcel;->writeArrayMapInternal(Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeArraySet(Landroid/util/ArraySet;)V
HSPLandroid/os/Parcel;->writeBinderList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->writeBlob([B)V
-HSPLandroid/os/Parcel;->writeBoolean(Z)V
+HSPLandroid/os/Parcel;->writeBoolean(Z)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeBooleanArray([Z)V
HSPLandroid/os/Parcel;->writeBundle(Landroid/os/Bundle;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeByte(B)V
@@ -12434,38 +12486,38 @@ HSPLandroid/os/Parcel;->writeFloatArray([F)V
HSPLandroid/os/Parcel;->writeInt(I)V
HSPLandroid/os/Parcel;->writeIntArray([I)V
HSPLandroid/os/Parcel;->writeInterfaceToken(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeList(Ljava/util/List;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->writeList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->writeLong(J)V
HSPLandroid/os/Parcel;->writeLongArray([J)V
HSPLandroid/os/Parcel;->writeMap(Ljava/util/Map;)V
HSPLandroid/os/Parcel;->writeMapInternal(Ljava/util/Map;)V
HSPLandroid/os/Parcel;->writeNoException()V
-HSPLandroid/os/Parcel;->writeParcelable(Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable;missing_types
-HSPLandroid/os/Parcel;->writeParcelableArray([Landroid/os/Parcelable;I)V
-HSPLandroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/os/Parcel;->writeParcelable(Landroid/os/Parcelable;I)V+]Landroid/os/Parcelable;missing_types]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeParcelableArray([Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V+]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeParcelableList(Ljava/util/List;I)V
HSPLandroid/os/Parcel;->writePersistableBundle(Landroid/os/PersistableBundle;)V
HSPLandroid/os/Parcel;->writeSerializable(Ljava/io/Serializable;)V
-HSPLandroid/os/Parcel;->writeSparseArray(Landroid/util/SparseArray;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/os/Parcel;->writeSparseArray(Landroid/util/SparseArray;)V
HSPLandroid/os/Parcel;->writeSparseBooleanArray(Landroid/util/SparseBooleanArray;)V
HSPLandroid/os/Parcel;->writeSparseIntArray(Landroid/util/SparseIntArray;)V
HSPLandroid/os/Parcel;->writeString(Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeString16(Ljava/lang/String;)V+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
-HSPLandroid/os/Parcel;->writeString16Array([Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeString16Array([Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeString16NoHelper(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeString8(Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeString8(Ljava/lang/String;)V+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
HSPLandroid/os/Parcel;->writeString8Array([Ljava/lang/String;)V
HSPLandroid/os/Parcel;->writeString8NoHelper(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeStringArray([Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeStringArray([Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeStringList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->writeStrongBinder(Landroid/os/IBinder;)V
-HSPLandroid/os/Parcel;->writeStrongInterface(Landroid/os/IInterface;)V
-HSPLandroid/os/Parcel;->writeTypedArray([Landroid/os/Parcelable;I)V
+HSPLandroid/os/Parcel;->writeStrongInterface(Landroid/os/IInterface;)V+]Landroid/os/IInterface;Landroid/app/LoadedApk$ServiceDispatcher$InnerConnection;,Landroid/app/ActivityThread$ApplicationThread;,Landroid/view/ViewRootImpl$W;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeTypedArray([Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeTypedArrayMap(Landroid/util/ArrayMap;I)V
HSPLandroid/os/Parcel;->writeTypedList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->writeTypedList(Ljava/util/List;I)V
-HSPLandroid/os/Parcel;->writeTypedObject(Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable;Landroid/app/FragmentState;,Landroid/content/Intent;,Landroid/os/Bundle;,Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/os/Parcel;->writeValue(ILjava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Integer;Ljava/lang/Integer;
+HSPLandroid/os/Parcel;->writeTypedObject(Landroid/os/Parcelable;I)V+]Landroid/os/Parcelable;Landroid/view/WindowManager$LayoutParams;,Landroid/content/Intent;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeValue(ILjava/lang/Object;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Long;Ljava/lang/Long;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeValue(Ljava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/ParcelFileDescriptor$2;->createFromParcel(Landroid/os/Parcel;)Landroid/os/ParcelFileDescriptor;
HSPLandroid/os/ParcelFileDescriptor$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -12655,7 +12707,7 @@ HSPLandroid/os/ServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinde
HSPLandroid/os/ServiceManager;->getServiceOrThrow(Ljava/lang/String;)Landroid/os/IBinder;
HSPLandroid/os/ServiceManager;->initServiceCache(Ljava/util/Map;)V
HSPLandroid/os/ServiceManager;->isDeclared(Ljava/lang/String;)Z
-HSPLandroid/os/ServiceManager;->rawGetService(Ljava/lang/String;)Landroid/os/IBinder;+]Landroid/os/IServiceManager;Landroid/os/ServiceManagerProxy;]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;
+HSPLandroid/os/ServiceManager;->rawGetService(Ljava/lang/String;)Landroid/os/IBinder;+]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;]Landroid/os/IServiceManager;Landroid/os/ServiceManagerProxy;
HSPLandroid/os/ServiceManager;->waitForDeclaredService(Ljava/lang/String;)Landroid/os/IBinder;
HSPLandroid/os/ServiceManagerProxy;->addService(Ljava/lang/String;Landroid/os/IBinder;ZI)V
HSPLandroid/os/ServiceManagerProxy;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
@@ -12714,7 +12766,7 @@ HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->handleViolationWithTimingAtt
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->lambda$handleViolationWithTimingAttempt$0(Landroid/view/IWindowManager;Ljava/util/ArrayList;)V
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onCustomSlowCall(Ljava/lang/String;)V
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onNetwork()V
-HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onReadFromDisk()V
+HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onReadFromDisk()V+]Landroid/os/StrictMode$AndroidBlockGuardPolicy;Landroid/os/StrictMode$AndroidBlockGuardPolicy;
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onThreadPolicyViolation(Landroid/os/StrictMode$ViolationInfo;)V
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onUnbufferedIO()V
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onWriteToDisk()V
@@ -12756,7 +12808,7 @@ HSPLandroid/os/StrictMode$ThreadSpanState;-><init>(Landroid/os/StrictMode$Thread
HSPLandroid/os/StrictMode$UnsafeIntentStrictModeCallback;-><init>()V
HSPLandroid/os/StrictMode$UnsafeIntentStrictModeCallback;-><init>(Landroid/os/StrictMode$UnsafeIntentStrictModeCallback-IA;)V
HSPLandroid/os/StrictMode$ViolationInfo;->-$$Nest$fgetmViolation(Landroid/os/StrictMode$ViolationInfo;)Landroid/os/strictmode/Violation;
-HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/Parcel;Z)V
+HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/Parcel;Z)V+]Ljava/util/Deque;Ljava/util/ArrayDeque;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/strictmode/Violation;I)V
HSPLandroid/os/StrictMode$ViolationInfo;->getStackTrace()Ljava/lang/String;
HSPLandroid/os/StrictMode$ViolationInfo;->hashCode()I
@@ -13084,7 +13136,7 @@ HSPLandroid/os/storage/StorageManager;-><init>(Landroid/content/Context;Landroid
HSPLandroid/os/storage/StorageManager;->allocateBytes(Ljava/io/FileDescriptor;JI)V
HSPLandroid/os/storage/StorageManager;->allocateBytes(Ljava/util/UUID;JI)V
HSPLandroid/os/storage/StorageManager;->convert(Ljava/lang/String;)Ljava/util/UUID;
-HSPLandroid/os/storage/StorageManager;->convert(Ljava/util/UUID;)Ljava/lang/String;
+HSPLandroid/os/storage/StorageManager;->convert(Ljava/util/UUID;)Ljava/lang/String;+]Ljava/lang/Object;Ljava/util/UUID;
HSPLandroid/os/storage/StorageManager;->getAllocatableBytes(Ljava/util/UUID;I)J
HSPLandroid/os/storage/StorageManager;->getStorageVolume(Ljava/io/File;I)Landroid/os/storage/StorageVolume;
HSPLandroid/os/storage/StorageManager;->getStorageVolume([Landroid/os/storage/StorageVolume;Ljava/io/File;)Landroid/os/storage/StorageVolume;
@@ -13173,9 +13225,10 @@ HSPLandroid/permission/PermissionManager$SplitPermissionInfo;->getTargetSdk()I
HSPLandroid/permission/PermissionManager;-><clinit>()V
HSPLandroid/permission/PermissionManager;-><init>(Landroid/content/Context;)V
HSPLandroid/permission/PermissionManager;->addOnPermissionsChangeListener(Landroid/content/pm/PackageManager$OnPermissionsChangedListener;)V
-HSPLandroid/permission/PermissionManager;->checkPermissionUncached(Ljava/lang/String;III)I+]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;
+HSPLandroid/permission/PermissionManager;->checkPermissionUncached(Ljava/lang/String;III)I+]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/permission/PermissionManager;->getPermissionFlags(Ljava/lang/String;Ljava/lang/String;Landroid/os/UserHandle;)I
HSPLandroid/permission/PermissionManager;->getPermissionInfo(Ljava/lang/String;I)Landroid/content/pm/PermissionInfo;
+HSPLandroid/permission/PermissionManager;->getPersistentDeviceId(I)Ljava/lang/String;
HSPLandroid/permission/PermissionManager;->getSplitPermissions()Ljava/util/List;
HSPLandroid/permission/PermissionManager;->removeOnPermissionsChangeListener(Landroid/content/pm/PackageManager$OnPermissionsChangedListener;)V
HSPLandroid/permission/PermissionManager;->splitPermissionInfoListToNonParcelableList(Ljava/util/List;)Ljava/util/List;
@@ -13235,15 +13288,15 @@ HSPLandroid/provider/Settings$Global;->getInt(Landroid/content/ContentResolver;L
HSPLandroid/provider/Settings$Global;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
HSPLandroid/provider/Settings$Global;->getLong(Landroid/content/ContentResolver;Ljava/lang/String;J)J
HSPLandroid/provider/Settings$Global;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/provider/Settings$Global;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/provider/Settings$Global;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/provider/Settings$NameValueCache;Landroid/provider/Settings$NameValueCache;]Ljava/util/HashSet;Ljava/util/HashSet;
HSPLandroid/provider/Settings$Global;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/provider/Settings$Global;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
HSPLandroid/provider/Settings$Global;->putLong(Landroid/content/ContentResolver;Ljava/lang/String;J)Z
HSPLandroid/provider/Settings$Global;->putString(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;)Z
HSPLandroid/provider/Settings$Global;->putStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZIZ)Z
HSPLandroid/provider/Settings$NameValueCache$$ExternalSyntheticLambda0;-><init>(Landroid/provider/Settings$NameValueCache;)V
-HSPLandroid/provider/Settings$NameValueCache;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
-HSPLandroid/provider/Settings$NameValueCache;->getStringsForPrefixStripPrefix(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/util/List;)Ljava/util/Map;+]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Landroid/content/IContentProvider;Landroid/content/ContentProvider$Transport;,Landroid/content/ContentProviderProxy;]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/Iterator;Ljava/util/Arrays$ArrayItr;,Ljava/util/HashMap$EntryIterator;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
+HSPLandroid/provider/Settings$NameValueCache;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/content/IContentProvider;Landroid/content/ContentProviderProxy;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
+HSPLandroid/provider/Settings$NameValueCache;->getStringsForPrefixStripPrefix(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/util/List;)Ljava/util/Map;+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;]Ljava/lang/String;Ljava/lang/String;]Landroid/content/IContentProvider;Landroid/content/ContentProviderProxy;,Landroid/content/ContentProvider$Transport;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;,Ljava/util/Arrays$ArrayItr;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
HSPLandroid/provider/Settings$NameValueCache;->isCallerExemptFromReadableRestriction()Z
HSPLandroid/provider/Settings$NameValueCache;->putStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZIZ)Z
HSPLandroid/provider/Settings$NameValueTable;->getUriFor(Landroid/net/Uri;Ljava/lang/String;)Landroid/net/Uri;
@@ -13254,7 +13307,7 @@ HSPLandroid/provider/Settings$Secure;->getIntForUser(Landroid/content/ContentRes
HSPLandroid/provider/Settings$Secure;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)I
HSPLandroid/provider/Settings$Secure;->getLong(Landroid/content/ContentResolver;Ljava/lang/String;J)J
HSPLandroid/provider/Settings$Secure;->getLongForUser(Landroid/content/ContentResolver;Ljava/lang/String;JI)J
-HSPLandroid/provider/Settings$Secure;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/provider/Settings$Secure;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;+]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;
HSPLandroid/provider/Settings$Secure;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
HSPLandroid/provider/Settings$Secure;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/provider/Settings$Secure;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
@@ -13269,7 +13322,7 @@ HSPLandroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;L
HSPLandroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
HSPLandroid/provider/Settings$System;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)I
HSPLandroid/provider/Settings$System;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)I
-HSPLandroid/provider/Settings$System;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/provider/Settings$System;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/provider/Settings$NameValueCache;Landroid/provider/Settings$NameValueCache;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/HashSet;Ljava/util/HashSet;
HSPLandroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/provider/Settings$System;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
HSPLandroid/provider/Settings$System;->putIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)Z
@@ -13288,6 +13341,8 @@ HSPLandroid/provider/Settings;->parseLongSettingWithDefault(Ljava/lang/String;J)
HSPLandroid/provider/Telephony$Sms;->getDefaultSmsPackage(Landroid/content/Context;)Ljava/lang/String;
HSPLandroid/renderscript/RenderScriptCacheDir;->setupDiskCache(Ljava/io/File;)V
HSPLandroid/se/omapi/SeServiceManager;-><init>()V
+HSPLandroid/security/FeatureFlagsImpl;-><init>()V
+HSPLandroid/security/Flags;-><clinit>()V
HSPLandroid/security/KeyChain$1;-><init>(Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/CountDownLatch;)V
HSPLandroid/security/KeyChain$1;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
HSPLandroid/security/KeyChain$KeyChainConnection;-><init>(Landroid/content/Context;Landroid/content/ServiceConnection;Landroid/security/IKeyChainService;)V
@@ -13304,6 +13359,7 @@ HSPLandroid/security/KeyStore2;->getKeyEntry(Landroid/system/keystore2/KeyDescri
HSPLandroid/security/KeyStore2;->getKeyStoreException(ILjava/lang/String;)Landroid/security/KeyStoreException;
HSPLandroid/security/KeyStore2;->getService(Z)Landroid/system/keystore2/IKeystoreService;
HSPLandroid/security/KeyStore2;->handleRemoteExceptionWithRetry(Landroid/security/KeyStore2$CheckedRemoteRequest;)Ljava/lang/Object;
+HSPLandroid/security/KeyStore;->getInstance()Landroid/security/KeyStore;
HSPLandroid/security/KeyStoreException;-><init>(ILjava/lang/String;)V
HSPLandroid/security/KeyStoreException;-><init>(ILjava/lang/String;Ljava/lang/String;)V
HSPLandroid/security/KeyStoreException;->getErrorCode()I
@@ -13633,18 +13689,18 @@ HSPLandroid/service/notification/NotificationListenerService$NotificationListene
HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onListenerConnected(Landroid/service/notification/NotificationRankingUpdate;)V
HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationChannelGroupModification(Ljava/lang/String;Landroid/os/UserHandle;Landroid/app/NotificationChannelGroup;I)V
HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationChannelModification(Ljava/lang/String;Landroid/os/UserHandle;Landroid/app/NotificationChannel;I)V
-HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationPosted(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;)V
+HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationPosted(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;)V+]Landroid/os/Handler;Landroid/service/notification/NotificationListenerService$MyHandler;]Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/IStatusBarNotificationHolder$Stub$Proxy;]Landroid/service/notification/StatusBarNotification;Landroid/service/notification/StatusBarNotification;]Landroid/os/Message;Landroid/os/Message;
HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationRankingUpdate(Landroid/service/notification/NotificationRankingUpdate;)V
HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationRemoved(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;Landroid/service/notification/NotificationStats;I)V
HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>()V
-HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Object;Landroid/service/notification/NotificationListenerService$Ranking;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/service/notification/NotificationListenerService$Ranking;->getChannel()Landroid/app/NotificationChannel;
HSPLandroid/service/notification/NotificationListenerService$Ranking;->getKey()Ljava/lang/String;
-HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Landroid/service/notification/NotificationListenerService$Ranking;)V
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Landroid/service/notification/NotificationListenerService$Ranking;)V+]Landroid/service/notification/NotificationListenerService$Ranking;Landroid/service/notification/NotificationListenerService$Ranking;
HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Ljava/lang/String;IZIIILjava/lang/CharSequence;Ljava/lang/String;Landroid/app/NotificationChannel;Ljava/util/ArrayList;Ljava/util/ArrayList;ZIZJZLjava/util/ArrayList;Ljava/util/ArrayList;ZZZLandroid/content/pm/ShortcutInfo;IZIZ)V
HSPLandroid/service/notification/NotificationListenerService$RankingMap$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/NotificationListenerService$RankingMap;
HSPLandroid/service/notification/NotificationListenerService$RankingMap$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/service/notification/NotificationListenerService$RankingMap;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/NotificationListenerService$RankingMap;-><init>(Landroid/os/Parcel;)V+]Landroid/service/notification/NotificationListenerService$Ranking;Landroid/service/notification/NotificationListenerService$Ranking;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;Landroid/service/notification/NotificationListenerService$RankingMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/service/notification/NotificationListenerService$RankingMap;->getOrderedKeys()[Ljava/lang/String;
HSPLandroid/service/notification/NotificationListenerService$RankingMap;->getRanking(Ljava/lang/String;Landroid/service/notification/NotificationListenerService$Ranking;)Z
HSPLandroid/service/notification/NotificationListenerService;-><init>()V
@@ -13673,7 +13729,7 @@ HSPLandroid/service/notification/NotificationRankingUpdate;-><init>(Landroid/os/
HSPLandroid/service/notification/NotificationRankingUpdate;->getRankingMap()Landroid/service/notification/NotificationListenerService$RankingMap;
HSPLandroid/service/notification/StatusBarNotification$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/StatusBarNotification;
HSPLandroid/service/notification/StatusBarNotification$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/service/notification/StatusBarNotification;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/StatusBarNotification;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Lcom/android/internal/logging/InstanceId$1;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/service/notification/StatusBarNotification;->getGroupKey()Ljava/lang/String;
HSPLandroid/service/notification/StatusBarNotification;->getId()I
HSPLandroid/service/notification/StatusBarNotification;->getInstanceId()Lcom/android/internal/logging/InstanceId;
@@ -13692,7 +13748,7 @@ HSPLandroid/service/notification/StatusBarNotification;->groupKey()Ljava/lang/St
HSPLandroid/service/notification/StatusBarNotification;->isAppGroup()Z
HSPLandroid/service/notification/StatusBarNotification;->isGroup()Z
HSPLandroid/service/notification/StatusBarNotification;->isOngoing()Z
-HSPLandroid/service/notification/StatusBarNotification;->key()Ljava/lang/String;
+HSPLandroid/service/notification/StatusBarNotification;->key()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/UserHandle;Landroid/os/UserHandle;
HSPLandroid/service/notification/ZenModeConfig$ZenRule$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/ZenModeConfig$ZenRule;
HSPLandroid/service/notification/ZenModeConfig$ZenRule$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/service/notification/ZenModeConfig$ZenRule;-><init>(Landroid/os/Parcel;)V
@@ -13940,7 +13996,7 @@ HSPLandroid/telecom/PhoneAccountHandle;->getComponentName()Landroid/content/Comp
HSPLandroid/telecom/PhoneAccountHandle;->getId()Ljava/lang/String;
HSPLandroid/telecom/PhoneAccountHandle;->getUserHandle()Landroid/os/UserHandle;
HSPLandroid/telecom/PhoneAccountHandle;->hashCode()I
-HSPLandroid/telecom/PhoneAccountHandle;->toString()Ljava/lang/String;
+HSPLandroid/telecom/PhoneAccountHandle;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ComponentName;Landroid/content/ComponentName;
HSPLandroid/telecom/PhoneAccountHandle;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/telecom/TelecomManager;-><init>(Landroid/content/Context;)V
HSPLandroid/telecom/TelecomManager;-><init>(Landroid/content/Context;Lcom/android/internal/telecom/ITelecomService;)V
@@ -14079,7 +14135,7 @@ HSPLandroid/telephony/ModemActivityInfo;->toString()Ljava/lang/String;
HSPLandroid/telephony/NetworkRegistrationInfo$$ExternalSyntheticLambda0;->apply(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/telephony/NetworkRegistrationInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/NetworkRegistrationInfo;
HSPLandroid/telephony/NetworkRegistrationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/telephony/NetworkRegistrationInfo;)V
HSPLandroid/telephony/NetworkRegistrationInfo;->domainToString(I)Ljava/lang/String;
HSPLandroid/telephony/NetworkRegistrationInfo;->getAccessNetworkTechnology()I
@@ -14103,7 +14159,7 @@ HSPLandroid/telephony/PhoneNumberUtils;->formatNumberToE164(Ljava/lang/String;Lj
HSPLandroid/telephony/PhoneNumberUtils;->getMinMatch()I
HSPLandroid/telephony/PhoneNumberUtils;->isDialable(C)Z
HSPLandroid/telephony/PhoneNumberUtils;->isNonSeparator(C)Z
-HSPLandroid/telephony/PhoneNumberUtils;->normalizeNumber(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/telephony/PhoneNumberUtils;->normalizeNumber(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/telephony/PhoneNumberUtils;->stripSeparators(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub$$ExternalSyntheticLambda10;->runOrThrow()V
HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub$$ExternalSyntheticLambda19;->runOrThrow()V
@@ -14135,7 +14191,7 @@ HSPLandroid/telephony/Rlog;->d(Ljava/lang/String;Ljava/lang/String;)I
HSPLandroid/telephony/ServiceState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/ServiceState;
HSPLandroid/telephony/ServiceState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/telephony/ServiceState;-><init>()V
-HSPLandroid/telephony/ServiceState;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/telephony/ServiceState;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/telephony/ServiceState;-><init>(Landroid/telephony/ServiceState;)V
HSPLandroid/telephony/ServiceState;->copyFrom(Landroid/telephony/ServiceState;)V
HSPLandroid/telephony/ServiceState;->createLocationInfoSanitizedCopy(Z)Landroid/telephony/ServiceState;
@@ -14175,7 +14231,7 @@ HSPLandroid/telephony/SignalStrength;->getCellSignalStrengths(Ljava/lang/Class;)
HSPLandroid/telephony/SignalStrength;->getLevel()I
HSPLandroid/telephony/SignalStrength;->getPrimary()Landroid/telephony/CellSignalStrength;
HSPLandroid/telephony/SignalStrength;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/SubscriptionInfo;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/telephony/SubscriptionInfo$Builder;Landroid/telephony/SubscriptionInfo$Builder;
+HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/SubscriptionInfo;+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/telephony/SubscriptionInfo$Builder;Landroid/telephony/SubscriptionInfo$Builder;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/telephony/SubscriptionInfo$Builder;->-$$Nest$fgetmAreUiccApplicationsEnabled(Landroid/telephony/SubscriptionInfo$Builder;)Z
HSPLandroid/telephony/SubscriptionInfo$Builder;->-$$Nest$fgetmCardId(Landroid/telephony/SubscriptionInfo$Builder;)I
@@ -14258,6 +14314,8 @@ HSPLandroid/telephony/SubscriptionInfo;->getSubscriptionId()I
HSPLandroid/telephony/SubscriptionInfo;->isEmbedded()Z
HSPLandroid/telephony/SubscriptionInfo;->isOpportunistic()Z
HSPLandroid/telephony/SubscriptionInfo;->toString()Ljava/lang/String;
+HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda10;->applyOrThrow(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda15;->applyOrThrow(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda9;->applyOrThrow(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/telephony/SubscriptionManager$IntegerPropertyInvalidatedCache;->query(Ljava/lang/Integer;)Ljava/lang/Object;
HSPLandroid/telephony/SubscriptionManager$IntegerPropertyInvalidatedCache;->recompute(Ljava/lang/Integer;)Ljava/lang/Object;
@@ -14368,6 +14426,7 @@ HSPLandroid/telephony/TelephonyManager;->getRenouncedPermissions()Ljava/util/Set
HSPLandroid/telephony/TelephonyManager;->getServiceState()Landroid/telephony/ServiceState;
HSPLandroid/telephony/TelephonyManager;->getServiceState(I)Landroid/telephony/ServiceState;
HSPLandroid/telephony/TelephonyManager;->getServiceStateForSubscriber(I)Landroid/telephony/ServiceState;
+HSPLandroid/telephony/TelephonyManager;->getServiceStateForSubscriber(IZZ)Landroid/telephony/ServiceState;
HSPLandroid/telephony/TelephonyManager;->getSignalStrength()Landroid/telephony/SignalStrength;
HSPLandroid/telephony/TelephonyManager;->getSimCarrierId()I
HSPLandroid/telephony/TelephonyManager;->getSimCountryIso()Ljava/lang/String;
@@ -14480,7 +14539,7 @@ HSPLandroid/telephony/data/ApnSetting;->getApnName()Ljava/lang/String;
HSPLandroid/telephony/data/ApnSetting;->getApnTypeBitmask()I
HSPLandroid/telephony/data/ApnSetting;->getApnTypesStringFromBitmask(I)Ljava/lang/String;
HSPLandroid/telephony/data/ApnSetting;->portToString(I)Ljava/lang/String;
-HSPLandroid/telephony/data/ApnSetting;->toString()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Map;Landroid/util/ArrayMap;
+HSPLandroid/telephony/data/ApnSetting;->toString()Ljava/lang/String;
HSPLandroid/telephony/euicc/EuiccManager;->getIEuiccController()Lcom/android/internal/telephony/euicc/IEuiccController;
HSPLandroid/telephony/euicc/EuiccManager;->isEnabled()Z
HSPLandroid/telephony/ims/ImsMmTelManager;->createForSubscriptionId(I)Landroid/telephony/ims/ImsMmTelManager;
@@ -14529,7 +14588,7 @@ HSPLandroid/text/BidiFormatter;->markBefore(Ljava/lang/CharSequence;Landroid/tex
HSPLandroid/text/BidiFormatter;->unicodeWrap(Ljava/lang/CharSequence;Landroid/text/TextDirectionHeuristic;Z)Ljava/lang/CharSequence;
HSPLandroid/text/BoringLayout$Metrics;->-$$Nest$mreset(Landroid/text/BoringLayout$Metrics;)V
HSPLandroid/text/BoringLayout$Metrics;-><init>()V
-HSPLandroid/text/BoringLayout$Metrics;->reset()V+]Landroid/graphics/RectF;Landroid/graphics/RectF;
+HSPLandroid/text/BoringLayout$Metrics;->reset()V
HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;Z)V
HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;ZLandroid/text/TextUtils$TruncateAt;I)V
HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;ZLandroid/text/TextUtils$TruncateAt;IZ)V
@@ -14544,13 +14603,14 @@ HSPLandroid/text/BoringLayout;->getLineCount()I
HSPLandroid/text/BoringLayout;->getLineDescent(I)I
HSPLandroid/text/BoringLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
HSPLandroid/text/BoringLayout;->getLineMax(I)F
-HSPLandroid/text/BoringLayout;->getLineStart(I)I+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/text/BoringLayout;->getLineStart(I)I
HSPLandroid/text/BoringLayout;->getLineTop(I)I
HSPLandroid/text/BoringLayout;->getLineWidth(I)F
HSPLandroid/text/BoringLayout;->getParagraphDirection(I)I
HSPLandroid/text/BoringLayout;->hasAnyInterestingChars(Ljava/lang/CharSequence;I)Z
HSPLandroid/text/BoringLayout;->init(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/Layout$Alignment;Landroid/text/BoringLayout$Metrics;ZZZ)V+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;Landroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;
+HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;ZLandroid/graphics/Paint$FontMetrics;Landroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;+]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Spanned;megamorphic_types]Ljava/lang/CharSequence;megamorphic_types]Landroid/text/TextDirectionHeuristic;Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicLocale;,Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;
HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;ZLandroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;
HSPLandroid/text/BoringLayout;->isFallbackLineSpacingEnabled()Z
HSPLandroid/text/BoringLayout;->make(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;Z)Landroid/text/BoringLayout;
@@ -14565,7 +14625,8 @@ HSPLandroid/text/CharSequenceCharacterIterator;->getEndIndex()I
HSPLandroid/text/CharSequenceCharacterIterator;->getIndex()I
HSPLandroid/text/CharSequenceCharacterIterator;->next()C
HSPLandroid/text/CharSequenceCharacterIterator;->setIndex(I)C
-HSPLandroid/text/DynamicLayout$Builder;->obtain(Ljava/lang/CharSequence;Landroid/text/TextPaint;I)Landroid/text/DynamicLayout$Builder;
+HSPLandroid/text/ClientFlags;->icuBidiMigration()Z
+HSPLandroid/text/DynamicLayout$Builder;->obtain(Ljava/lang/CharSequence;Landroid/text/TextPaint;I)Landroid/text/DynamicLayout$Builder;+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
HSPLandroid/text/DynamicLayout$ChangeWatcher;->afterTextChanged(Landroid/text/Editable;)V
HSPLandroid/text/DynamicLayout$ChangeWatcher;->beforeTextChanged(Ljava/lang/CharSequence;III)V
HSPLandroid/text/DynamicLayout$ChangeWatcher;->onSpanAdded(Landroid/text/Spannable;Ljava/lang/Object;II)V
@@ -14573,29 +14634,29 @@ HSPLandroid/text/DynamicLayout$ChangeWatcher;->onSpanChanged(Landroid/text/Spann
HSPLandroid/text/DynamicLayout$ChangeWatcher;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
HSPLandroid/text/DynamicLayout$ChangeWatcher;->onTextChanged(Ljava/lang/CharSequence;III)V
HSPLandroid/text/DynamicLayout;-><init>(Landroid/text/DynamicLayout$Builder;)V
-HSPLandroid/text/DynamicLayout;->addBlockAtOffset(I)V
-HSPLandroid/text/DynamicLayout;->contentMayProtrudeFromLineTopOrBottom(Ljava/lang/CharSequence;II)Z
+HSPLandroid/text/DynamicLayout;->addBlockAtOffset(I)V+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;
+HSPLandroid/text/DynamicLayout;->contentMayProtrudeFromLineTopOrBottom(Ljava/lang/CharSequence;II)Z+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/graphics/Paint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;
HSPLandroid/text/DynamicLayout;->createBlocks()V
-HSPLandroid/text/DynamicLayout;->generate(Landroid/text/DynamicLayout$Builder;)V
+HSPLandroid/text/DynamicLayout;->generate(Landroid/text/DynamicLayout$Builder;)V+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/method/ReplacementTransformationMethod$SpannedReplacementCharSequence;,Landroid/text/SpannableStringBuilder;]Landroid/text/Spannable;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/DynamicLayout;->getBlockEndLines()[I
HSPLandroid/text/DynamicLayout;->getBlockIndices()[I
HSPLandroid/text/DynamicLayout;->getBlocksAlwaysNeedToBeRedrawn()Landroid/util/ArraySet;
HSPLandroid/text/DynamicLayout;->getEllipsisCount(I)I
HSPLandroid/text/DynamicLayout;->getEllipsisStart(I)I
HSPLandroid/text/DynamicLayout;->getEllipsizedWidth()I
-HSPLandroid/text/DynamicLayout;->getEndHyphenEdit(I)I
+HSPLandroid/text/DynamicLayout;->getEndHyphenEdit(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
HSPLandroid/text/DynamicLayout;->getIndexFirstChangedBlock()I
-HSPLandroid/text/DynamicLayout;->getLineContainsTab(I)Z
-HSPLandroid/text/DynamicLayout;->getLineCount()I
-HSPLandroid/text/DynamicLayout;->getLineDescent(I)I
-HSPLandroid/text/DynamicLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
+HSPLandroid/text/DynamicLayout;->getLineContainsTab(I)Z+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineCount()I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineDescent(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineDirections(I)Landroid/text/Layout$Directions;+]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;
HSPLandroid/text/DynamicLayout;->getLineExtra(I)I
-HSPLandroid/text/DynamicLayout;->getLineStart(I)I
-HSPLandroid/text/DynamicLayout;->getLineTop(I)I
+HSPLandroid/text/DynamicLayout;->getLineStart(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineTop(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
HSPLandroid/text/DynamicLayout;->getNumberOfBlocks()I
-HSPLandroid/text/DynamicLayout;->getParagraphDirection(I)I
-HSPLandroid/text/DynamicLayout;->getStartHyphenEdit(I)I
-HSPLandroid/text/DynamicLayout;->reflow(Ljava/lang/CharSequence;III)V
+HSPLandroid/text/DynamicLayout;->getParagraphDirection(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getStartHyphenEdit(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->reflow(Ljava/lang/CharSequence;III)V+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;]Landroid/text/StaticLayout;Landroid/text/StaticLayout;]Landroid/text/Spanned;Landroid/text/SpannableString;]Ljava/lang/CharSequence;Landroid/text/SpannableString;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;
HSPLandroid/text/DynamicLayout;->setIndexFirstChangedBlock(I)V
HSPLandroid/text/DynamicLayout;->updateAlwaysNeedsToBeRedrawn(I)V
HSPLandroid/text/DynamicLayout;->updateBlocks(III)V
@@ -14610,7 +14671,7 @@ HSPLandroid/text/Html;->fromHtml(Ljava/lang/String;)Landroid/text/Spanned;
HSPLandroid/text/Html;->fromHtml(Ljava/lang/String;I)Landroid/text/Spanned;
HSPLandroid/text/Html;->fromHtml(Ljava/lang/String;ILandroid/text/Html$ImageGetter;Landroid/text/Html$TagHandler;)Landroid/text/Spanned;
HSPLandroid/text/HtmlToSpannedConverter;-><init>(Ljava/lang/String;Landroid/text/Html$ImageGetter;Landroid/text/Html$TagHandler;Lorg/ccil/cowan/tagsoup/Parser;I)V
-HSPLandroid/text/HtmlToSpannedConverter;->characters([CII)V+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/HtmlToSpannedConverter;->characters([CII)V
HSPLandroid/text/HtmlToSpannedConverter;->convert()Landroid/text/Spanned;
HSPLandroid/text/HtmlToSpannedConverter;->end(Landroid/text/Editable;Ljava/lang/Class;Ljava/lang/Object;)V
HSPLandroid/text/HtmlToSpannedConverter;->endA(Landroid/text/Editable;)V
@@ -14619,8 +14680,8 @@ HSPLandroid/text/HtmlToSpannedConverter;->endElement(Ljava/lang/String;Ljava/lan
HSPLandroid/text/HtmlToSpannedConverter;->endPrefixMapping(Ljava/lang/String;)V
HSPLandroid/text/HtmlToSpannedConverter;->getLast(Landroid/text/Spanned;Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/text/HtmlToSpannedConverter;->handleBr(Landroid/text/Editable;)V
-HSPLandroid/text/HtmlToSpannedConverter;->handleEndTag(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/text/HtmlToSpannedConverter;->handleStartTag(Ljava/lang/String;Lorg/xml/sax/Attributes;)V+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/text/HtmlToSpannedConverter;->handleEndTag(Ljava/lang/String;)V
+HSPLandroid/text/HtmlToSpannedConverter;->handleStartTag(Ljava/lang/String;Lorg/xml/sax/Attributes;)V
HSPLandroid/text/HtmlToSpannedConverter;->setDocumentLocator(Lorg/xml/sax/Locator;)V
HSPLandroid/text/HtmlToSpannedConverter;->setSpanFromMark(Landroid/text/Spannable;Ljava/lang/Object;[Ljava/lang/Object;)V
HSPLandroid/text/HtmlToSpannedConverter;->start(Landroid/text/Editable;Ljava/lang/Object;)V
@@ -14638,7 +14699,7 @@ HSPLandroid/text/Layout$Directions;->getRunStart(I)I
HSPLandroid/text/Layout$Directions;->isRunRtl(I)Z
HSPLandroid/text/Layout$Ellipsizer;-><init>(Ljava/lang/CharSequence;)V
HSPLandroid/text/Layout$Ellipsizer;->charAt(I)C
-HSPLandroid/text/Layout$Ellipsizer;->getChars(II[CI)V+]Landroid/text/Layout;Landroid/text/StaticLayout;
+HSPLandroid/text/Layout$Ellipsizer;->getChars(II[CI)V
HSPLandroid/text/Layout$Ellipsizer;->length()I
HSPLandroid/text/Layout$HorizontalMeasurementProvider;->init()V
HSPLandroid/text/Layout$SpannedEllipsizer;->getSpanEnd(Ljava/lang/Object;)I
@@ -14647,12 +14708,13 @@ HSPLandroid/text/Layout$SpannedEllipsizer;->getSpanStart(Ljava/lang/Object;)I
HSPLandroid/text/Layout$SpannedEllipsizer;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
HSPLandroid/text/Layout$SpannedEllipsizer;->nextSpanTransition(IILjava/lang/Class;)I
HSPLandroid/text/Layout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FF)V
+HSPLandroid/text/Layout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;Landroid/text/TextDirectionHeuristic;FFZZILandroid/text/TextUtils$TruncateAt;III[I[IILandroid/graphics/text/LineBreakConfig;ZZLandroid/graphics/Paint$FontMetrics;)V
HSPLandroid/text/Layout;->addSelection(IIIIILandroid/text/Layout$SelectionRectangleConsumer;)V
HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;)V
HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Landroid/graphics/Path;Landroid/graphics/Paint;I)V
-HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;I)V
+HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;I)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
HSPLandroid/text/Layout;->drawBackground(Landroid/graphics/Canvas;II)V
-HSPLandroid/text/Layout;->drawText(Landroid/graphics/Canvas;II)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/Spanned;Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;
+HSPLandroid/text/Layout;->drawText(Landroid/graphics/Canvas;II)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Spanned;Landroid/text/SpannableString;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
HSPLandroid/text/Layout;->drawWithoutText(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;III)V
HSPLandroid/text/Layout;->ellipsize(III[CILandroid/text/TextUtils$TruncateAt;)V
HSPLandroid/text/Layout;->getCursorPath(ILandroid/graphics/Path;Ljava/lang/CharSequence;)V
@@ -14664,30 +14726,30 @@ HSPLandroid/text/Layout;->getHeight(Z)I
HSPLandroid/text/Layout;->getHorizontal(IZ)F
HSPLandroid/text/Layout;->getHorizontal(IZIZ)F
HSPLandroid/text/Layout;->getIndentAdjust(ILandroid/text/Layout$Alignment;)I
-HSPLandroid/text/Layout;->getLineBaseline(I)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineBaseline(I)I
HSPLandroid/text/Layout;->getLineBottom(I)I
HSPLandroid/text/Layout;->getLineBottom(IZ)I
-HSPLandroid/text/Layout;->getLineEnd(I)I
-HSPLandroid/text/Layout;->getLineExtent(ILandroid/text/Layout$TabStops;Z)F+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/text/Layout;->getLineEnd(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineExtent(ILandroid/text/Layout$TabStops;Z)F
HSPLandroid/text/Layout;->getLineExtent(IZ)F
-HSPLandroid/text/Layout;->getLineForOffset(I)I+]Landroid/text/Layout;Landroid/text/StaticLayout;
-HSPLandroid/text/Layout;->getLineForVertical(I)I+]Landroid/text/Layout;Landroid/text/BoringLayout;
+HSPLandroid/text/Layout;->getLineForOffset(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;
+HSPLandroid/text/Layout;->getLineForVertical(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;
HSPLandroid/text/Layout;->getLineLeft(I)F
HSPLandroid/text/Layout;->getLineMax(I)F
-HSPLandroid/text/Layout;->getLineRangeForDraw(Landroid/graphics/Canvas;)J+]Landroid/graphics/Canvas;missing_types]Landroid/text/Layout;Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineRangeForDraw(Landroid/graphics/Canvas;)J+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/text/Layout;->getLineRight(I)F
HSPLandroid/text/Layout;->getLineStartPos(III)I
HSPLandroid/text/Layout;->getLineVisibleEnd(I)I
HSPLandroid/text/Layout;->getLineWidth(I)F
HSPLandroid/text/Layout;->getOffsetAtStartOf(I)I
HSPLandroid/text/Layout;->getOffsetForHorizontal(IF)I
-HSPLandroid/text/Layout;->getOffsetForHorizontal(IFZ)I
+HSPLandroid/text/Layout;->getOffsetForHorizontal(IFZ)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Layout$HorizontalMeasurementProvider;Landroid/text/Layout$HorizontalMeasurementProvider;
HSPLandroid/text/Layout;->getPaint()Landroid/text/TextPaint;
-HSPLandroid/text/Layout;->getParagraphAlignment(I)Landroid/text/Layout$Alignment;
-HSPLandroid/text/Layout;->getParagraphLeadingMargin(I)I
+HSPLandroid/text/Layout;->getParagraphAlignment(I)Landroid/text/Layout$Alignment;+]Landroid/text/Layout;Landroid/text/DynamicLayout;
+HSPLandroid/text/Layout;->getParagraphLeadingMargin(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/text/Spanned;missing_types
HSPLandroid/text/Layout;->getParagraphLeft(I)I
HSPLandroid/text/Layout;->getParagraphRight(I)I
-HSPLandroid/text/Layout;->getParagraphSpans(Landroid/text/Spanned;IILjava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/text/Layout;->getParagraphSpans(Landroid/text/Spanned;IILjava/lang/Class;)[Ljava/lang/Object;+]Landroid/text/Spanned;Landroid/text/SpannableString;
HSPLandroid/text/Layout;->getPrimaryHorizontal(I)F
HSPLandroid/text/Layout;->getPrimaryHorizontal(IZ)F
HSPLandroid/text/Layout;->getSelection(IILandroid/text/Layout$SelectionRectangleConsumer;)V
@@ -14706,7 +14768,8 @@ HSPLandroid/text/Layout;->primaryIsTrailingPrevious(I)Z
HSPLandroid/text/Layout;->replaceWith(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FF)V
HSPLandroid/text/Layout;->shouldClampCursor(I)Z
HSPLandroid/text/MeasuredParagraph;-><init>()V
-HSPLandroid/text/MeasuredParagraph;->applyMetricsAffectingSpan(Landroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;[Landroid/text/style/MetricAffectingSpan;[Landroid/text/style/LineBreakConfigSpan;IILandroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/graphics/text/LineBreakConfig$Builder;Landroid/graphics/text/LineBreakConfig$Builder;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/style/MetricAffectingSpan;missing_types
+HSPLandroid/text/MeasuredParagraph;->applyMetricsAffectingSpan(Landroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;[Landroid/text/style/MetricAffectingSpan;[Landroid/text/style/LineBreakConfigSpan;IILandroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/text/LineBreakConfig$Builder;Landroid/graphics/text/LineBreakConfig$Builder;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/style/MetricAffectingSpan;missing_types
+HSPLandroid/text/MeasuredParagraph;->applyStyleRun(IILandroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;Landroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/text/AutoGrowArray$FloatArray;Landroid/text/AutoGrowArray$FloatArray;]Landroid/graphics/text/MeasuredText$Builder;Landroid/graphics/text/MeasuredText$Builder;]Landroid/text/AutoGrowArray$ByteArray;Landroid/text/AutoGrowArray$ByteArray;]Landroid/text/TextPaint;Landroid/text/TextPaint;
HSPLandroid/text/MeasuredParagraph;->breakText(IZF)I
HSPLandroid/text/MeasuredParagraph;->buildForBidi(Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;Landroid/text/MeasuredParagraph;)Landroid/text/MeasuredParagraph;
HSPLandroid/text/MeasuredParagraph;->buildForMeasurement(Landroid/text/TextPaint;Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;Landroid/text/MeasuredParagraph;)Landroid/text/MeasuredParagraph;
@@ -14725,9 +14788,9 @@ HSPLandroid/text/MeasuredParagraph;->reset()V
HSPLandroid/text/MeasuredParagraph;->resetAndAnalyzeBidi(Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;)V
HSPLandroid/text/PackedIntVector;->adjustValuesBelow(III)V
HSPLandroid/text/PackedIntVector;->deleteAt(II)V
-HSPLandroid/text/PackedIntVector;->getValue(II)I
+HSPLandroid/text/PackedIntVector;->getValue(II)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
HSPLandroid/text/PackedIntVector;->growBuffer()V
-HSPLandroid/text/PackedIntVector;->insertAt(I[I)V
+HSPLandroid/text/PackedIntVector;->insertAt(I[I)V+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
HSPLandroid/text/PackedIntVector;->moveRowGapTo(I)V
HSPLandroid/text/PackedIntVector;->moveValueGapTo(II)V
HSPLandroid/text/PackedIntVector;->size()I
@@ -14735,7 +14798,7 @@ HSPLandroid/text/PackedIntVector;->width()I
HSPLandroid/text/PackedObjectVector;->deleteAt(II)V
HSPLandroid/text/PackedObjectVector;->getValue(II)Ljava/lang/Object;
HSPLandroid/text/PackedObjectVector;->growBuffer()V
-HSPLandroid/text/PackedObjectVector;->insertAt(I[Ljava/lang/Object;)V
+HSPLandroid/text/PackedObjectVector;->insertAt(I[Ljava/lang/Object;)V+]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;
HSPLandroid/text/PackedObjectVector;->moveRowGapTo(I)V
HSPLandroid/text/PackedObjectVector;->setValue(IILjava/lang/Object;)V
HSPLandroid/text/PackedObjectVector;->size()I
@@ -14746,7 +14809,7 @@ HSPLandroid/text/PrecomputedText$Params;->getHyphenationFrequency()I
HSPLandroid/text/PrecomputedText$Params;->getTextDirection()Landroid/text/TextDirectionHeuristic;
HSPLandroid/text/PrecomputedText$Params;->getTextPaint()Landroid/text/TextPaint;
HSPLandroid/text/Selection;->getSelectionEnd(Ljava/lang/CharSequence;)I
-HSPLandroid/text/Selection;->getSelectionStart(Ljava/lang/CharSequence;)I
+HSPLandroid/text/Selection;->getSelectionStart(Ljava/lang/CharSequence;)I+]Landroid/text/Spanned;missing_types
HSPLandroid/text/Selection;->removeMemory(Landroid/text/Spannable;)V
HSPLandroid/text/Selection;->removeSelection(Landroid/text/Spannable;)V
HSPLandroid/text/Selection;->setSelection(Landroid/text/Spannable;I)V
@@ -14756,7 +14819,7 @@ HSPLandroid/text/Selection;->updateMemory(Landroid/text/Spannable;I)V
HSPLandroid/text/SpanSet;-><init>(Ljava/lang/Class;)V
HSPLandroid/text/SpanSet;->getNextTransition(II)I
HSPLandroid/text/SpanSet;->hasSpansIntersecting(II)Z
-HSPLandroid/text/SpanSet;->init(Landroid/text/Spanned;II)V
+HSPLandroid/text/SpanSet;->init(Landroid/text/Spanned;II)V+]Landroid/text/Spanned;Landroid/text/SpannableString;
HSPLandroid/text/SpanSet;->recycle()V
HSPLandroid/text/Spannable$Factory;->getInstance()Landroid/text/Spannable$Factory;
HSPLandroid/text/Spannable$Factory;->newSpannable(Ljava/lang/CharSequence;)Landroid/text/Spannable;
@@ -14774,32 +14837,32 @@ HSPLandroid/text/SpannableString;->setSpan(Ljava/lang/Object;III)V
HSPLandroid/text/SpannableString;->subSequence(II)Ljava/lang/CharSequence;
HSPLandroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;
HSPLandroid/text/SpannableStringBuilder;-><init>()V
-HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;)V
+HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;)V+]Ljava/lang/CharSequence;missing_types
HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;II)V
HSPLandroid/text/SpannableStringBuilder;->append(C)Landroid/text/Editable;
HSPLandroid/text/SpannableStringBuilder;->append(C)Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/Editable;
-HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
+HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->calcMax(I)I
-HSPLandroid/text/SpannableStringBuilder;->change(IILjava/lang/CharSequence;II)V
+HSPLandroid/text/SpannableStringBuilder;->change(IILjava/lang/CharSequence;II)V+]Landroid/text/Spanned;Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->charAt(I)C
-HSPLandroid/text/SpannableStringBuilder;->checkRange(Ljava/lang/String;II)V
+HSPLandroid/text/SpannableStringBuilder;->checkRange(Ljava/lang/String;II)V+]Landroid/text/SpannableStringBuilder;missing_types
HSPLandroid/text/SpannableStringBuilder;->checkSortBuffer([II)[I
HSPLandroid/text/SpannableStringBuilder;->clear()V
HSPLandroid/text/SpannableStringBuilder;->compareSpans(II[I[I)I
-HSPLandroid/text/SpannableStringBuilder;->countSpans(IILjava/lang/Class;I)I
+HSPLandroid/text/SpannableStringBuilder;->countSpans(IILjava/lang/Class;I)I+]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/text/SpannableStringBuilder;->delete(II)Landroid/text/Editable;
HSPLandroid/text/SpannableStringBuilder;->delete(II)Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->drawTextRun(Landroid/graphics/BaseCanvas;IIIIFFZLandroid/graphics/Paint;)V
HSPLandroid/text/SpannableStringBuilder;->equals(Ljava/lang/Object;)Z
HSPLandroid/text/SpannableStringBuilder;->getChars(II[CI)V
-HSPLandroid/text/SpannableStringBuilder;->getSpanEnd(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpanFlags(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpanStart(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/text/SpannableStringBuilder;->getSpanEnd(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpanFlags(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpanStart(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;+]Landroid/text/SpannableStringBuilder;missing_types
HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;Z)[Ljava/lang/Object;
-HSPLandroid/text/SpannableStringBuilder;->getSpansRec(IILjava/lang/Class;I[Ljava/lang/Object;[I[IIZ)I
+HSPLandroid/text/SpannableStringBuilder;->getSpansRec(IILjava/lang/Class;I[Ljava/lang/Object;[I[IIZ)I+]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/text/SpannableStringBuilder;->getTextWatcherDepth()I
HSPLandroid/text/SpannableStringBuilder;->hasNonExclusiveExclusiveSpanAt(Ljava/lang/CharSequence;I)Z
HSPLandroid/text/SpannableStringBuilder;->insert(ILjava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
@@ -14818,48 +14881,48 @@ HSPLandroid/text/SpannableStringBuilder;->removeSpan(Ljava/lang/Object;I)V
HSPLandroid/text/SpannableStringBuilder;->removeSpansForChange(IIZI)Z
HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;)Landroid/text/Editable;
HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
-HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;
+HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->resizeFor(I)V
HSPLandroid/text/SpannableStringBuilder;->resolveGap(I)I
-HSPLandroid/text/SpannableStringBuilder;->restoreInvariants()V
+HSPLandroid/text/SpannableStringBuilder;->restoreInvariants()V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
HSPLandroid/text/SpannableStringBuilder;->rightChild(I)I
HSPLandroid/text/SpannableStringBuilder;->sendAfterTextChanged([Landroid/text/TextWatcher;)V
HSPLandroid/text/SpannableStringBuilder;->sendBeforeTextChanged([Landroid/text/TextWatcher;III)V
-HSPLandroid/text/SpannableStringBuilder;->sendSpanAdded(Ljava/lang/Object;II)V
+HSPLandroid/text/SpannableStringBuilder;->sendSpanAdded(Ljava/lang/Object;II)V+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->sendSpanChanged(Ljava/lang/Object;IIII)V
HSPLandroid/text/SpannableStringBuilder;->sendSpanRemoved(Ljava/lang/Object;II)V
HSPLandroid/text/SpannableStringBuilder;->sendTextChanged([Landroid/text/TextWatcher;III)V
HSPLandroid/text/SpannableStringBuilder;->sendToSpanWatchers(III)V
HSPLandroid/text/SpannableStringBuilder;->setFilters([Landroid/text/InputFilter;)V
HSPLandroid/text/SpannableStringBuilder;->setSpan(Ljava/lang/Object;III)V
-HSPLandroid/text/SpannableStringBuilder;->setSpan(ZLjava/lang/Object;IIIZ)V
+HSPLandroid/text/SpannableStringBuilder;->setSpan(ZLjava/lang/Object;IIIZ)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
HSPLandroid/text/SpannableStringBuilder;->siftDown(I[Ljava/lang/Object;I[I[I)V
HSPLandroid/text/SpannableStringBuilder;->sort([Ljava/lang/Object;[I[I)V
HSPLandroid/text/SpannableStringBuilder;->subSequence(II)Ljava/lang/CharSequence;
-HSPLandroid/text/SpannableStringBuilder;->toString()Ljava/lang/String;
+HSPLandroid/text/SpannableStringBuilder;->toString()Ljava/lang/String;+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->treeRoot()I
HSPLandroid/text/SpannableStringBuilder;->updatedIntervalBound(IIIIZZ)I
-HSPLandroid/text/SpannableStringInternal;-><init>(Ljava/lang/CharSequence;IIZ)V
-HSPLandroid/text/SpannableStringInternal;->charAt(I)C
-HSPLandroid/text/SpannableStringInternal;->checkRange(Ljava/lang/String;II)V
-HSPLandroid/text/SpannableStringInternal;->copySpansFromInternal(Landroid/text/SpannableStringInternal;IIZ)V
-HSPLandroid/text/SpannableStringInternal;->copySpansFromSpanned(Landroid/text/Spanned;IIZ)V
+HSPLandroid/text/SpannableStringInternal;-><init>(Ljava/lang/CharSequence;IIZ)V+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->charAt(I)C+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/text/SpannableStringInternal;->checkRange(Ljava/lang/String;II)V+]Landroid/text/SpannableStringInternal;Landroid/text/SpannedString;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->copySpansFromInternal(Landroid/text/SpannableStringInternal;IIZ)V+]Landroid/text/SpannableStringInternal;Landroid/text/SpannedString;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->copySpansFromSpanned(Landroid/text/Spanned;IIZ)V+]Landroid/text/Spanned;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringInternal;->equals(Ljava/lang/Object;)Z
-HSPLandroid/text/SpannableStringInternal;->getChars(II[CI)V
+HSPLandroid/text/SpannableStringInternal;->getChars(II[CI)V+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/text/SpannableStringInternal;->getSpanEnd(Ljava/lang/Object;)I
HSPLandroid/text/SpannableStringInternal;->getSpanFlags(Ljava/lang/Object;)I
HSPLandroid/text/SpannableStringInternal;->getSpanStart(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringInternal;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
-HSPLandroid/text/SpannableStringInternal;->length()I
+HSPLandroid/text/SpannableStringInternal;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/text/SpannableStringInternal;Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->length()I+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/text/SpannableStringInternal;->nextSpanTransition(IILjava/lang/Class;)I
HSPLandroid/text/SpannableStringInternal;->removeSpan(Ljava/lang/Object;I)V
-HSPLandroid/text/SpannableStringInternal;->sendSpanAdded(Ljava/lang/Object;II)V
+HSPLandroid/text/SpannableStringInternal;->sendSpanAdded(Ljava/lang/Object;II)V+]Landroid/text/SpanWatcher;Landroid/text/DynamicLayout$ChangeWatcher;,Landroid/widget/Editor$SpanController;,Landroid/widget/TextView$ChangeWatcher;]Landroid/text/SpannableStringInternal;Landroid/text/SpannableString;
HSPLandroid/text/SpannableStringInternal;->sendSpanChanged(Ljava/lang/Object;IIII)V
HSPLandroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;III)V
HSPLandroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;IIIZ)V
HSPLandroid/text/SpannableStringInternal;->toString()Ljava/lang/String;
HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;)V
-HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;Z)V
+HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;Z)V+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannedString;->equals(Ljava/lang/Object;)Z
HSPLandroid/text/SpannedString;->getSpanEnd(Ljava/lang/Object;)I
HSPLandroid/text/SpannedString;->getSpanFlags(Ljava/lang/Object;)I
@@ -14902,8 +14965,9 @@ HSPLandroid/text/StaticLayout$Builder;->setLineSpacing(FF)Landroid/text/StaticLa
HSPLandroid/text/StaticLayout$Builder;->setMaxLines(I)Landroid/text/StaticLayout$Builder;
HSPLandroid/text/StaticLayout$Builder;->setTextDirection(Landroid/text/TextDirectionHeuristic;)Landroid/text/StaticLayout$Builder;
HSPLandroid/text/StaticLayout$Builder;->setUseLineSpacingFromFallbacks(Z)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout;-><init>(Landroid/text/StaticLayout$Builder;ZI)V+]Landroid/text/StaticLayout;Landroid/text/StaticLayout;
HSPLandroid/text/StaticLayout;->calculateEllipsis(IILandroid/text/MeasuredParagraph;IFLandroid/text/TextUtils$TruncateAt;IFLandroid/text/TextPaint;Z)V
-HSPLandroid/text/StaticLayout;->generate(Landroid/text/StaticLayout$Builder;ZZ)V+]Landroid/graphics/text/LineBreaker$Builder;Landroid/graphics/text/LineBreaker$Builder;]Landroid/graphics/text/LineBreaker$ParagraphConstraints;Landroid/graphics/text/LineBreaker$ParagraphConstraints;]Landroid/graphics/text/LineBreaker$Result;Landroid/graphics/text/LineBreaker$Result;]Landroid/graphics/text/LineBreaker;Landroid/graphics/text/LineBreaker;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/text/StaticLayout;->generate(Landroid/text/StaticLayout$Builder;ZZ)V+]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Landroid/graphics/text/LineBreaker$Builder;Landroid/graphics/text/LineBreaker$Builder;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/text/LineBreaker;Landroid/graphics/text/LineBreaker;]Ljava/lang/CharSequence;Landroid/text/SpannableString;]Landroid/graphics/text/LineBreaker$ParagraphConstraints;Landroid/graphics/text/LineBreaker$ParagraphConstraints;]Landroid/graphics/text/LineBreaker$Result;Landroid/graphics/text/LineBreaker$Result;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;
HSPLandroid/text/StaticLayout;->getBottomPadding()I
HSPLandroid/text/StaticLayout;->getEllipsisCount(I)I
HSPLandroid/text/StaticLayout;->getEllipsisStart(I)I
@@ -14913,7 +14977,7 @@ HSPLandroid/text/StaticLayout;->getIndentAdjust(ILandroid/text/Layout$Alignment;
HSPLandroid/text/StaticLayout;->getLineContainsTab(I)Z
HSPLandroid/text/StaticLayout;->getLineCount()I
HSPLandroid/text/StaticLayout;->getLineDescent(I)I
-HSPLandroid/text/StaticLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
+HSPLandroid/text/StaticLayout;->getLineDirections(I)Landroid/text/Layout$Directions;+]Landroid/text/StaticLayout;Landroid/text/StaticLayout;
HSPLandroid/text/StaticLayout;->getLineExtra(I)I
HSPLandroid/text/StaticLayout;->getLineForVertical(I)I
HSPLandroid/text/StaticLayout;->getLineStart(I)I
@@ -14922,38 +14986,43 @@ HSPLandroid/text/StaticLayout;->getParagraphDirection(I)I
HSPLandroid/text/StaticLayout;->getStartHyphenEdit(I)I
HSPLandroid/text/StaticLayout;->getTopPadding()I
HSPLandroid/text/StaticLayout;->getTotalInsets(I)F
-HSPLandroid/text/StaticLayout;->out(Ljava/lang/CharSequence;IIIIIIIFF[Landroid/text/style/LineHeightSpan;[ILandroid/graphics/Paint$FontMetricsInt;ZIZLandroid/text/MeasuredParagraph;IZZZ[CILandroid/text/TextUtils$TruncateAt;FFLandroid/text/TextPaint;Z)I
+HSPLandroid/text/StaticLayout;->out(Ljava/lang/CharSequence;IIIIIIIFF[Landroid/text/style/LineHeightSpan;[ILandroid/graphics/Paint$FontMetricsInt;ZIZLandroid/text/MeasuredParagraph;IZZZ[CILandroid/text/TextUtils$TruncateAt;FFLandroid/text/TextPaint;Z)I+]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
HSPLandroid/text/StaticLayout;->packHyphenEdit(II)I
HSPLandroid/text/StaticLayout;->unpackEndHyphenEdit(I)I
HSPLandroid/text/StaticLayout;->unpackStartHyphenEdit(I)I
HSPLandroid/text/TextDirectionHeuristics$FirstStrong;->checkRtl(Ljava/lang/CharSequence;II)I
-HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->doCheck(Ljava/lang/CharSequence;II)Z+]Landroid/text/TextDirectionHeuristics$TextDirectionAlgorithm;Landroid/text/TextDirectionHeuristics$FirstStrong;]Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;
+HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->doCheck(Ljava/lang/CharSequence;II)Z
HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->isRtl(Ljava/lang/CharSequence;II)Z
HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->isRtl([CII)Z
HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;->defaultIsRtl()Z
HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicLocale;->defaultIsRtl()Z
HSPLandroid/text/TextDirectionHeuristics;->isRtlCodePoint(I)I
HSPLandroid/text/TextFlags;->getKeyForFlag(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextFlags;->isFeatureEnabled(Ljava/lang/String;)Z
HSPLandroid/text/TextLine$DecorationInfo;-><init>()V
HSPLandroid/text/TextLine$DecorationInfo;->copyInfo()Landroid/text/TextLine$DecorationInfo;
HSPLandroid/text/TextLine$DecorationInfo;->hasDecoration()Z
HSPLandroid/text/TextLine;-><init>()V
HSPLandroid/text/TextLine;->adjustEndHyphenEdit(II)I
HSPLandroid/text/TextLine;->adjustStartHyphenEdit(II)I
-HSPLandroid/text/TextLine;->draw(Landroid/graphics/Canvas;FIII)V
+HSPLandroid/text/TextLine;->draw(Landroid/graphics/Canvas;FIII)V+]Landroid/text/Layout$Directions;Landroid/text/Layout$Directions;
HSPLandroid/text/TextLine;->drawStroke(Landroid/text/TextPaint;Landroid/graphics/Canvas;IFFFFF)V
-HSPLandroid/text/TextLine;->drawTextRun(Landroid/graphics/Canvas;Landroid/text/TextPaint;IIIIZFI)V
+HSPLandroid/text/TextLine;->drawTextRun(Landroid/graphics/Canvas;Landroid/text/TextPaint;IIIIZFI)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/text/TextLine;->equalAttributes(Landroid/text/TextPaint;Landroid/text/TextPaint;)Z
-HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/graphics/Paint$FontMetricsInt;Landroid/text/TextPaint;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/graphics/Paint$FontMetricsInt;Landroid/text/TextPaint;)V
HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/text/TextPaint;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
HSPLandroid/text/TextLine;->extractDecorationInfo(Landroid/text/TextPaint;Landroid/text/TextLine$DecorationInfo;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
-HSPLandroid/text/TextLine;->getOffsetBeforeAfter(IIIZIZ)I
+HSPLandroid/text/TextLine;->getOffsetBeforeAfter(IIIZIZ)I+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;
HSPLandroid/text/TextLine;->getOffsetToLeftRightOf(IZ)I
+HSPLandroid/text/TextLine;->getRunAdvance(Landroid/text/TextPaint;IIIIZI[FILandroid/graphics/RectF;Landroid/text/TextLine$LineInfo;)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/PrecomputedText;Landroid/text/PrecomputedText;]Landroid/text/TextPaint;Landroid/text/TextPaint;
HSPLandroid/text/TextLine;->handleReplacement(Landroid/text/style/ReplacementSpan;Landroid/text/TextPaint;IIZLandroid/graphics/Canvas;FIIILandroid/graphics/Paint$FontMetricsInt;Z)F
+HSPLandroid/text/TextLine;->handleRun(IIIZLandroid/graphics/Canvas;Landroid/text/TextShaper$GlyphsConsumer;FIIILandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;Z[FILandroid/text/TextLine$LineInfo;I)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/style/MetricAffectingSpan;megamorphic_types]Landroid/text/style/CharacterStyle;megamorphic_types]Landroid/text/TextPaint;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/text/TextLine$DecorationInfo;Landroid/text/TextLine$DecorationInfo;]Landroid/text/SpanSet;Landroid/text/SpanSet;
+HSPLandroid/text/TextLine;->handleText(Landroid/text/TextPaint;IIIIZLandroid/graphics/Canvas;Landroid/text/TextShaper$GlyphsConsumer;FIIILandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;ZILjava/util/ArrayList;[FILandroid/text/TextLine$LineInfo;I)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;,Landroid/graphics/Canvas;,Landroid/view/Surface$CompatibleCanvas;
HSPLandroid/text/TextLine;->isLineEndSpace(C)Z
+HSPLandroid/text/TextLine;->measure(IZLandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;Landroid/text/TextLine$LineInfo;)F+]Landroid/text/Layout$Directions;Landroid/text/Layout$Directions;]Landroid/text/TextLine;Landroid/text/TextLine;
HSPLandroid/text/TextLine;->obtain()Landroid/text/TextLine;
HSPLandroid/text/TextLine;->recycle(Landroid/text/TextLine;)Landroid/text/TextLine;+]Landroid/text/SpanSet;Landroid/text/SpanSet;
-HSPLandroid/text/TextLine;->set(Landroid/text/TextPaint;Ljava/lang/CharSequence;IIILandroid/text/Layout$Directions;ZLandroid/text/Layout$TabStops;IIZ)V
+HSPLandroid/text/TextLine;->set(Landroid/text/TextPaint;Ljava/lang/CharSequence;IIILandroid/text/Layout$Directions;ZLandroid/text/Layout$TabStops;IIZ)V+]Landroid/text/SpanSet;Landroid/text/SpanSet;
HSPLandroid/text/TextLine;->updateMetrics(Landroid/graphics/Paint$FontMetricsInt;IIIII)V
HSPLandroid/text/TextPaint;-><init>()V
HSPLandroid/text/TextPaint;-><init>(I)V
@@ -14961,8 +15030,8 @@ HSPLandroid/text/TextPaint;-><init>(Landroid/graphics/Paint;)V
HSPLandroid/text/TextPaint;->getUnderlineThickness()F
HSPLandroid/text/TextPaint;->set(Landroid/text/TextPaint;)V
HSPLandroid/text/TextPaint;->setUnderlineText(IF)V
-HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/CharSequence;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/text/TextUtils$1;Landroid/text/TextUtils$1;
HSPLandroid/text/TextUtils$SimpleStringSplitter;-><init>(C)V
HSPLandroid/text/TextUtils$SimpleStringSplitter;->hasNext()Z
HSPLandroid/text/TextUtils$SimpleStringSplitter;->iterator()Ljava/util/Iterator;
@@ -14970,7 +15039,7 @@ HSPLandroid/text/TextUtils$SimpleStringSplitter;->next()Ljava/lang/Object;
HSPLandroid/text/TextUtils$SimpleStringSplitter;->next()Ljava/lang/String;
HSPLandroid/text/TextUtils$SimpleStringSplitter;->setString(Ljava/lang/String;)V
HSPLandroid/text/TextUtils$StringWithRemovedChars;->toString()Ljava/lang/String;
-HSPLandroid/text/TextUtils;->concat([Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
+HSPLandroid/text/TextUtils;->concat([Ljava/lang/CharSequence;)Ljava/lang/CharSequence;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/TextUtils;->copySpansFrom(Landroid/text/Spanned;IILjava/lang/Class;Landroid/text/Spannable;I)V
HSPLandroid/text/TextUtils;->couldAffectRtl(C)Z
HSPLandroid/text/TextUtils;->doesNotNeedBidi([CII)Z
@@ -14978,23 +15047,23 @@ HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/Tex
HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/TextPaint;FLandroid/text/TextUtils$TruncateAt;ZLandroid/text/TextUtils$EllipsizeCallback;)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/TextPaint;FLandroid/text/TextUtils$TruncateAt;ZLandroid/text/TextUtils$EllipsizeCallback;Landroid/text/TextDirectionHeuristic;Ljava/lang/String;)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->emptyIfNull(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/text/TextUtils;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z
+HSPLandroid/text/TextUtils;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/text/TextUtils;->expandTemplate(Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils;->formatSimple(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;+]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextUtils;->formatSimple(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Boolean;Ljava/lang/Boolean;
HSPLandroid/text/TextUtils;->getCapsMode(Ljava/lang/CharSequence;II)I
-HSPLandroid/text/TextUtils;->getChars(Ljava/lang/CharSequence;II[CI)V+]Landroid/text/GetChars;Landroid/text/Layout$Ellipsizer;,Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;]Ljava/lang/Object;megamorphic_types]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextUtils;->getChars(Ljava/lang/CharSequence;II[CI)V+]Ljava/lang/Object;Landroid/text/SpannableString;]Landroid/text/GetChars;Landroid/text/SpannableString;
HSPLandroid/text/TextUtils;->getEllipsisString(Landroid/text/TextUtils$TruncateAt;)Ljava/lang/String;
HSPLandroid/text/TextUtils;->getLayoutDirectionFromLocale(Ljava/util/Locale;)I
HSPLandroid/text/TextUtils;->getTrimmedLength(Ljava/lang/CharSequence;)I
HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;C)I
HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CI)I
-HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CII)I
+HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CII)I+]Ljava/lang/Object;Landroid/text/SpannableString;
HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;Ljava/lang/CharSequence;II)I
HSPLandroid/text/TextUtils;->isDigitsOnly(Ljava/lang/CharSequence;)Z
-HSPLandroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z+]Ljava/lang/CharSequence;Landroid/text/SpannableStringBuilder;,Ljava/lang/String;
+HSPLandroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z+]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/text/TextUtils;->isGraphic(Ljava/lang/CharSequence;)Z
-HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;
+HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Iterable;missing_types]Ljava/util/Iterator;missing_types
HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;[Ljava/lang/Object;)Ljava/lang/String;
HSPLandroid/text/TextUtils;->lastIndexOf(Ljava/lang/CharSequence;CI)I
HSPLandroid/text/TextUtils;->lastIndexOf(Ljava/lang/CharSequence;CII)I
@@ -15007,14 +15076,14 @@ HSPLandroid/text/TextUtils;->removeEmptySpans([Ljava/lang/Object;Landroid/text/S
HSPLandroid/text/TextUtils;->safeIntern(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/text/TextUtils;->split(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
HSPLandroid/text/TextUtils;->stringOrSpannedString(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils;->substring(Ljava/lang/CharSequence;II)Ljava/lang/String;
+HSPLandroid/text/TextUtils;->substring(Ljava/lang/CharSequence;II)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/text/TextUtils;->toUpperCase(Ljava/util/Locale;Ljava/lang/CharSequence;Z)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->trimNoCopySpans(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->trimToParcelableSize(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->trimToSize(Ljava/lang/CharSequence;I)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->unpackRangeEndFromLong(J)I
HSPLandroid/text/TextUtils;->unpackRangeStartFromLong(J)I
-HSPLandroid/text/TextUtils;->writeToParcel(Ljava/lang/CharSequence;Landroid/os/Parcel;I)V
+HSPLandroid/text/TextUtils;->writeToParcel(Ljava/lang/CharSequence;Landroid/os/Parcel;I)V+]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;J)Ljava/lang/CharSequence;
HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;Ljava/util/Calendar;)Ljava/lang/CharSequence;
HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;Ljava/util/Date;)Ljava/lang/CharSequence;
@@ -15121,7 +15190,7 @@ HSPLandroid/text/method/TextKeyListener;->onSpanAdded(Landroid/text/Spannable;Lj
HSPLandroid/text/method/TextKeyListener;->onSpanChanged(Landroid/text/Spannable;Ljava/lang/Object;IIII)V
HSPLandroid/text/method/TextKeyListener;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
HSPLandroid/text/method/TextKeyListener;->updatePrefs(Landroid/content/ContentResolver;)V
-HSPLandroid/text/method/Touch;->onTouchEvent(Landroid/widget/TextView;Landroid/text/Spannable;Landroid/view/MotionEvent;)Z
+HSPLandroid/text/method/Touch;->onTouchEvent(Landroid/widget/TextView;Landroid/text/Spannable;Landroid/view/MotionEvent;)Z+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/text/Spannable;Landroid/text/SpannableString;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/text/method/WordIterator;-><init>(Ljava/util/Locale;)V
HSPLandroid/text/method/WordIterator;->checkOffsetIsValid(I)V
HSPLandroid/text/method/WordIterator;->following(I)I
@@ -15140,7 +15209,7 @@ HSPLandroid/text/style/ClickableSpan;->updateDrawState(Landroid/text/TextPaint;)
HSPLandroid/text/style/DynamicDrawableSpan;-><init>(I)V
HSPLandroid/text/style/ForegroundColorSpan;-><init>(I)V
HSPLandroid/text/style/ForegroundColorSpan;->getSpanTypeIdInternal()I
-HSPLandroid/text/style/ForegroundColorSpan;->updateDrawState(Landroid/text/TextPaint;)V
+HSPLandroid/text/style/ForegroundColorSpan;->updateDrawState(Landroid/text/TextPaint;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
HSPLandroid/text/style/ForegroundColorSpan;->writeToParcelInternal(Landroid/os/Parcel;I)V
HSPLandroid/text/style/ImageSpan;-><init>(Landroid/graphics/drawable/Drawable;I)V
HSPLandroid/text/style/ImageSpan;->getDrawable()Landroid/graphics/drawable/Drawable;
@@ -15206,7 +15275,7 @@ HSPLandroid/transition/Transition$2;->onAnimationEnd(Landroid/animation/Animator
HSPLandroid/transition/Transition$2;->onAnimationStart(Landroid/animation/Animator;)V
HSPLandroid/transition/Transition$3;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/transition/Transition;-><init>()V
-HSPLandroid/transition/Transition;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;megamorphic_types
+HSPLandroid/transition/Transition;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Ljava/lang/Object;megamorphic_types]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/transition/Transition;->addListener(Landroid/transition/Transition$TransitionListener;)Landroid/transition/Transition;
HSPLandroid/transition/Transition;->addTarget(Landroid/view/View;)Landroid/transition/Transition;
HSPLandroid/transition/Transition;->addUnmatched(Landroid/util/ArrayMap;Landroid/util/ArrayMap;)V
@@ -15237,7 +15306,7 @@ HSPLandroid/transition/Transition;->setEpicenterCallback(Landroid/transition/Tra
HSPLandroid/transition/Transition;->start()V
HSPLandroid/transition/TransitionInflater;-><init>(Landroid/content/Context;)V
HSPLandroid/transition/TransitionInflater;->createCustom(Landroid/util/AttributeSet;Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/transition/TransitionInflater;->createTransitionFromXml(Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/transition/Transition;)Landroid/transition/Transition;+]Landroid/transition/TransitionSet;Landroid/transition/TransitionSet;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/transition/TransitionInflater;->createTransitionFromXml(Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/transition/Transition;)Landroid/transition/Transition;
HSPLandroid/transition/TransitionInflater;->from(Landroid/content/Context;)Landroid/transition/TransitionInflater;
HSPLandroid/transition/TransitionInflater;->inflateTransition(I)Landroid/transition/Transition;
HSPLandroid/transition/TransitionListenerAdapter;-><init>()V
@@ -15318,7 +15387,7 @@ HSPLandroid/util/ArrayMap;->indexOfNull()I
HSPLandroid/util/ArrayMap;->indexOfValue(Ljava/lang/Object;)I
HSPLandroid/util/ArrayMap;->isEmpty()Z
HSPLandroid/util/ArrayMap;->keyAt(I)Ljava/lang/Object;
-HSPLandroid/util/ArrayMap;->keySet()Ljava/util/Set;
+HSPLandroid/util/ArrayMap;->keySet()Ljava/util/Set;+]Landroid/util/MapCollections;Landroid/util/ArrayMap$1;
HSPLandroid/util/ArrayMap;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;megamorphic_types
HSPLandroid/util/ArrayMap;->putAll(Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
HSPLandroid/util/ArrayMap;->putAll(Ljava/util/Map;)V
@@ -15341,11 +15410,11 @@ HSPLandroid/util/ArraySet;-><init>(IZ)V
HSPLandroid/util/ArraySet;-><init>(Landroid/util/ArraySet;)V
HSPLandroid/util/ArraySet;-><init>(Ljava/util/Collection;)V
HSPLandroid/util/ArraySet;-><init>([Ljava/lang/Object;)V
-HSPLandroid/util/ArraySet;->add(Ljava/lang/Object;)Z
+HSPLandroid/util/ArraySet;->add(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/lang/String;,Landroid/accounts/Account;,Landroid/window/SurfaceSyncGroup$2;,Landroid/net/UidRange;
HSPLandroid/util/ArraySet;->addAll(Landroid/util/ArraySet;)V
HSPLandroid/util/ArraySet;->addAll(Ljava/util/Collection;)Z
HSPLandroid/util/ArraySet;->allocArrays(I)V
-HSPLandroid/util/ArraySet;->append(Ljava/lang/Object;)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/Object;Landroid/app/PendingIntent;,Lcom/android/org/conscrypt/OpenSSLRSAPublicKey;
+HSPLandroid/util/ArraySet;->append(Ljava/lang/Object;)V+]Ljava/lang/Object;Lcom/android/org/conscrypt/OpenSSLRSAPublicKey;,Lcom/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey;
HSPLandroid/util/ArraySet;->binarySearch([II)I
HSPLandroid/util/ArraySet;->clear()V
HSPLandroid/util/ArraySet;->contains(Ljava/lang/Object;)Z
@@ -15383,11 +15452,11 @@ HSPLandroid/util/Base64$Decoder;-><init>(I[B)V
HSPLandroid/util/Base64$Decoder;->process([BIIZ)Z
HSPLandroid/util/Base64$Encoder;-><init>(I[B)V
HSPLandroid/util/Base64$Encoder;->process([BIIZ)Z
-HSPLandroid/util/Base64;->decode(Ljava/lang/String;I)[B+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/util/Base64;->decode(Ljava/lang/String;I)[B
HSPLandroid/util/Base64;->decode([BI)[B
HSPLandroid/util/Base64;->decode([BIII)[B+]Landroid/util/Base64$Decoder;Landroid/util/Base64$Decoder;
HSPLandroid/util/Base64;->encode([BI)[B
-HSPLandroid/util/Base64;->encode([BIII)[B+]Landroid/util/Base64$Encoder;Landroid/util/Base64$Encoder;
+HSPLandroid/util/Base64;->encode([BIII)[B
HSPLandroid/util/Base64;->encodeToString([BI)Ljava/lang/String;
HSPLandroid/util/Base64;->encodeToString([BIII)Ljava/lang/String;
HSPLandroid/util/CloseGuard;-><init>()V
@@ -15403,7 +15472,7 @@ HSPLandroid/util/DisplayMetrics;->setTo(Landroid/util/DisplayMetrics;)V
HSPLandroid/util/DisplayMetrics;->setToDefaults()V
HSPLandroid/util/DisplayUtils;->getDisplayUniqueIdConfigIndex(Landroid/content/res/Resources;Ljava/lang/String;)I
HSPLandroid/util/EventLog$Event;-><init>([B)V
-HSPLandroid/util/EventLog$Event;->decodeObject()Ljava/lang/Object;
+HSPLandroid/util/EventLog$Event;->decodeObject()Ljava/lang/Object;+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
HSPLandroid/util/EventLog$Event;->getData()Ljava/lang/Object;
HSPLandroid/util/EventLog$Event;->getHeaderSize()I
HSPLandroid/util/EventLog$Event;->getUid()I
@@ -15431,7 +15500,7 @@ HSPLandroid/util/IndentingPrintWriter;->write(Ljava/lang/String;II)V
HSPLandroid/util/IndentingPrintWriter;->write([CII)V
HSPLandroid/util/IntArray;-><init>()V
HSPLandroid/util/IntArray;-><init>(I)V
-HSPLandroid/util/IntArray;->add(I)V+]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/util/IntArray;->add(I)V
HSPLandroid/util/IntArray;->add(II)V
HSPLandroid/util/IntArray;->addAll(Landroid/util/IntArray;)V
HSPLandroid/util/IntArray;->binarySearch(I)I
@@ -15488,9 +15557,9 @@ HSPLandroid/util/JsonWriter;->flush()V
HSPLandroid/util/JsonWriter;->name(Ljava/lang/String;)Landroid/util/JsonWriter;
HSPLandroid/util/JsonWriter;->newline()V
HSPLandroid/util/JsonWriter;->open(Landroid/util/JsonScope;Ljava/lang/String;)Landroid/util/JsonWriter;
-HSPLandroid/util/JsonWriter;->peek()Landroid/util/JsonScope;
-HSPLandroid/util/JsonWriter;->replaceTop(Landroid/util/JsonScope;)V
-HSPLandroid/util/JsonWriter;->string(Ljava/lang/String;)V
+HSPLandroid/util/JsonWriter;->peek()Landroid/util/JsonScope;+]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/util/JsonWriter;->replaceTop(Landroid/util/JsonScope;)V+]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/util/JsonWriter;->string(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/io/Writer;Ljava/io/BufferedWriter;
HSPLandroid/util/JsonWriter;->value(J)Landroid/util/JsonWriter;
HSPLandroid/util/JsonWriter;->value(Ljava/lang/String;)Landroid/util/JsonWriter;
HSPLandroid/util/JsonWriter;->value(Z)Landroid/util/JsonWriter;
@@ -15563,21 +15632,21 @@ HSPLandroid/util/LruCache;-><init>(I)V
HSPLandroid/util/LruCache;->create(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/util/LruCache;->entryRemoved(ZLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
HSPLandroid/util/LruCache;->evictAll()V
-HSPLandroid/util/LruCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/util/LruCache;->get(Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;missing_types
HSPLandroid/util/LruCache;->hitCount()I
HSPLandroid/util/LruCache;->maxSize()I
HSPLandroid/util/LruCache;->missCount()I
-HSPLandroid/util/LruCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/util/LruCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;,Landroid/util/LruCache;
HSPLandroid/util/LruCache;->remove(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/util/LruCache;->resize(I)V
HSPLandroid/util/LruCache;->safeSizeOf(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/util/LruCache;->size()I
HSPLandroid/util/LruCache;->sizeOf(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/util/LruCache;->snapshot()Ljava/util/Map;
-HSPLandroid/util/LruCache;->trimToSize(I)V
-HSPLandroid/util/MapCollections$ArrayIterator;-><init>(Landroid/util/MapCollections;I)V
+HSPLandroid/util/LruCache;->trimToSize(I)V+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
+HSPLandroid/util/MapCollections$ArrayIterator;-><init>(Landroid/util/MapCollections;I)V+]Landroid/util/MapCollections;Landroid/util/ArraySet$1;,Landroid/util/ArrayMap$1;
HSPLandroid/util/MapCollections$ArrayIterator;->hasNext()Z
-HSPLandroid/util/MapCollections$ArrayIterator;->next()Ljava/lang/Object;
+HSPLandroid/util/MapCollections$ArrayIterator;->next()Ljava/lang/Object;+]Landroid/util/MapCollections$ArrayIterator;Landroid/util/MapCollections$ArrayIterator;]Landroid/util/MapCollections;Landroid/util/ArraySet$1;,Landroid/util/ArrayMap$1;
HSPLandroid/util/MapCollections$ArrayIterator;->remove()V
HSPLandroid/util/MapCollections$EntrySet;-><init>(Landroid/util/MapCollections;)V
HSPLandroid/util/MapCollections$EntrySet;->iterator()Ljava/util/Iterator;
@@ -15699,16 +15768,16 @@ HSPLandroid/util/SparseArray;->append(ILjava/lang/Object;)V+]Landroid/util/Spars
HSPLandroid/util/SparseArray;->clear()V
HSPLandroid/util/SparseArray;->clone()Landroid/util/SparseArray;
HSPLandroid/util/SparseArray;->contains(I)Z
-HSPLandroid/util/SparseArray;->contentEquals(Landroid/util/SparseArray;)Z+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->contentEquals(Landroid/util/SparseArray;)Z
HSPLandroid/util/SparseArray;->delete(I)V
HSPLandroid/util/SparseArray;->gc()V
-HSPLandroid/util/SparseArray;->get(I)Ljava/lang/Object;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->get(I)Ljava/lang/Object;+]Landroid/util/SparseArray;missing_types
HSPLandroid/util/SparseArray;->get(ILjava/lang/Object;)Ljava/lang/Object;
HSPLandroid/util/SparseArray;->indexOfKey(I)I
HSPLandroid/util/SparseArray;->indexOfValue(Ljava/lang/Object;)I
HSPLandroid/util/SparseArray;->keyAt(I)I
HSPLandroid/util/SparseArray;->put(ILjava/lang/Object;)V
-HSPLandroid/util/SparseArray;->remove(I)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->remove(I)V
HSPLandroid/util/SparseArray;->removeAt(I)V
HSPLandroid/util/SparseArray;->removeReturnOld(I)Ljava/lang/Object;
HSPLandroid/util/SparseArray;->setValueAt(ILjava/lang/Object;)V
@@ -15874,7 +15943,7 @@ HSPLandroid/view/AbsSavedState$2;->createFromParcel(Landroid/os/Parcel;Ljava/lan
HSPLandroid/view/AbsSavedState$2;->createFromParcel(Landroid/os/Parcel;Ljava/lang/ClassLoader;)Ljava/lang/Object;
HSPLandroid/view/AbsSavedState;-><init>(Landroid/os/Parcelable;)V
HSPLandroid/view/AbsSavedState;->getSuperState()Landroid/os/Parcelable;
-HSPLandroid/view/AbsSavedState;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/view/AbsSavedState;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/view/Choreographer$1;->initialValue()Landroid/view/Choreographer;
HSPLandroid/view/Choreographer$1;->initialValue()Ljava/lang/Object;
HSPLandroid/view/Choreographer$2;->initialValue()Landroid/view/Choreographer;
@@ -15886,8 +15955,8 @@ HSPLandroid/view/Choreographer$CallbackQueue;->extractDueCallbacksLocked(J)Landr
HSPLandroid/view/Choreographer$CallbackQueue;->removeCallbacksLocked(Ljava/lang/Object;Ljava/lang/Object;)V
HSPLandroid/view/Choreographer$CallbackRecord;-><init>()V
HSPLandroid/view/Choreographer$CallbackRecord;-><init>(Landroid/view/Choreographer$CallbackRecord-IA;)V
-HSPLandroid/view/Choreographer$CallbackRecord;->run(J)V+]Landroid/view/Choreographer$FrameCallback;missing_types]Ljava/lang/Runnable;Landroid/view/ViewPropertyAnimator$1;,Landroid/view/ViewRootImpl$ConsumeBatchedInputRunnable;,Landroid/view/ViewRootImpl$TraversalRunnable;,Lcom/android/internal/util/function/pooled/PooledLambdaImpl;
-HSPLandroid/view/Choreographer$CallbackRecord;->run(Landroid/view/Choreographer$FrameData;)V+]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;
+HSPLandroid/view/Choreographer$CallbackRecord;->run(J)V+]Landroid/view/Choreographer$FrameCallback;missing_types]Ljava/lang/Runnable;missing_types
+HSPLandroid/view/Choreographer$CallbackRecord;->run(Landroid/view/Choreographer$FrameData;)V+]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;
HSPLandroid/view/Choreographer$FrameData;->-$$Nest$fgetmFrameTimeNanos(Landroid/view/Choreographer$FrameData;)J
HSPLandroid/view/Choreographer$FrameData;-><init>()V
HSPLandroid/view/Choreographer$FrameData;->allocateFrameTimelines(I)V
@@ -15900,7 +15969,7 @@ HSPLandroid/view/Choreographer$FrameData;->update(JI)V
HSPLandroid/view/Choreographer$FrameData;->update(JLandroid/view/DisplayEventReceiver$VsyncEventData;)Landroid/view/Choreographer$FrameTimeline;+]Landroid/view/Choreographer$FrameTimeline;Landroid/view/Choreographer$FrameTimeline;
HSPLandroid/view/Choreographer$FrameData;->update(JLandroid/view/DisplayEventReceiver;J)Landroid/view/Choreographer$FrameTimeline;
HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;-><init>(Landroid/view/Choreographer;Landroid/os/Looper;IJ)V
-HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->onVsync(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->onVsync(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;
HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->run()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/view/Choreographer$FrameHandler;-><init>(Landroid/view/Choreographer;Landroid/os/Looper;)V
HSPLandroid/view/Choreographer$FrameHandler;->handleMessage(Landroid/os/Message;)V
@@ -15919,13 +15988,13 @@ HSPLandroid/view/Choreographer;-><init>(Landroid/os/Looper;I)V
HSPLandroid/view/Choreographer;-><init>(Landroid/os/Looper;IJ)V
HSPLandroid/view/Choreographer;-><init>(Landroid/os/Looper;ILandroid/view/Choreographer-IA;)V
HSPLandroid/view/Choreographer;->doCallbacks(IJ)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;
-HSPLandroid/view/Choreographer;->doFrame(JILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Landroid/graphics/FrameInfo;Landroid/graphics/FrameInfo;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/Choreographer;->doFrame(JILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/graphics/FrameInfo;Landroid/graphics/FrameInfo;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;
HSPLandroid/view/Choreographer;->doScheduleCallback(I)V
HSPLandroid/view/Choreographer;->doScheduleVsync()V
HSPLandroid/view/Choreographer;->getFrameIntervalNanos()J
-HSPLandroid/view/Choreographer;->getFrameTime()J
+HSPLandroid/view/Choreographer;->getFrameTime()J+]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/view/Choreographer;->getFrameTimeNanos()J
-HSPLandroid/view/Choreographer;->getInstance()Landroid/view/Choreographer;+]Ljava/lang/ThreadLocal;Landroid/view/Choreographer$1;
+HSPLandroid/view/Choreographer;->getInstance()Landroid/view/Choreographer;
HSPLandroid/view/Choreographer;->getMainThreadInstance()Landroid/view/Choreographer;
HSPLandroid/view/Choreographer;->getRefreshRate()F
HSPLandroid/view/Choreographer;->getSfInstance()Landroid/view/Choreographer;
@@ -15934,14 +16003,14 @@ HSPLandroid/view/Choreographer;->isRunningOnLooperThreadLocked()Z
HSPLandroid/view/Choreographer;->obtainCallbackLocked(JLjava/lang/Object;Ljava/lang/Object;)Landroid/view/Choreographer$CallbackRecord;
HSPLandroid/view/Choreographer;->postCallback(ILjava/lang/Runnable;Ljava/lang/Object;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/view/Choreographer;->postCallbackDelayed(ILjava/lang/Runnable;Ljava/lang/Object;J)V
-HSPLandroid/view/Choreographer;->postCallbackDelayedInternal(ILjava/lang/Object;Ljava/lang/Object;J)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->postCallbackDelayedInternal(ILjava/lang/Object;Ljava/lang/Object;J)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
HSPLandroid/view/Choreographer;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/view/Choreographer;->postFrameCallbackDelayed(Landroid/view/Choreographer$FrameCallback;J)V
HSPLandroid/view/Choreographer;->recycleCallbackLocked(Landroid/view/Choreographer$CallbackRecord;)V
HSPLandroid/view/Choreographer;->removeCallbacks(ILjava/lang/Runnable;Ljava/lang/Object;)V
-HSPLandroid/view/Choreographer;->removeCallbacksInternal(ILjava/lang/Object;Ljava/lang/Object;)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->removeCallbacksInternal(ILjava/lang/Object;Ljava/lang/Object;)V
HSPLandroid/view/Choreographer;->removeFrameCallback(Landroid/view/Choreographer$FrameCallback;)V
-HSPLandroid/view/Choreographer;->scheduleFrameLocked(J)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->scheduleFrameLocked(J)V
HSPLandroid/view/Choreographer;->scheduleVsyncLocked()V+]Landroid/view/Choreographer$FrameDisplayEventReceiver;Landroid/view/Choreographer$FrameDisplayEventReceiver;
HSPLandroid/view/Choreographer;->setFPSDivisor(I)V
HSPLandroid/view/ContextThemeWrapper;-><init>()V
@@ -15954,7 +16023,7 @@ HSPLandroid/view/ContextThemeWrapper;->getResources()Landroid/content/res/Resour
HSPLandroid/view/ContextThemeWrapper;->getResourcesInternal()Landroid/content/res/Resources;
HSPLandroid/view/ContextThemeWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
HSPLandroid/view/ContextThemeWrapper;->getTheme()Landroid/content/res/Resources$Theme;+]Landroid/view/ContextThemeWrapper;Landroid/view/ContextThemeWrapper;
-HSPLandroid/view/ContextThemeWrapper;->initializeTheme()V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ContextThemeWrapper;Landroid/view/ContextThemeWrapper;
+HSPLandroid/view/ContextThemeWrapper;->initializeTheme()V
HSPLandroid/view/ContextThemeWrapper;->onApplyThemeResource(Landroid/content/res/Resources$Theme;IZ)V
HSPLandroid/view/ContextThemeWrapper;->setTheme(I)V
HSPLandroid/view/CrossWindowBlurListeners;-><clinit>()V
@@ -15982,7 +16051,7 @@ HSPLandroid/view/Display$Mode;->matches(IIF)Z
HSPLandroid/view/Display$Mode;->toString()Ljava/lang/String;
HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/content/res/Resources;)V
HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;)V
-HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;Landroid/content/res/Resources;)V+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;Landroid/content/res/Resources;)V
HSPLandroid/view/Display;->getAppVsyncOffsetNanos()J
HSPLandroid/view/Display;->getCutout()Landroid/view/DisplayCutout;
HSPLandroid/view/Display;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -15992,7 +16061,7 @@ HSPLandroid/view/Display;->getFlags()I
HSPLandroid/view/Display;->getHdrSdrRatio()F
HSPLandroid/view/Display;->getHeight()I
HSPLandroid/view/Display;->getInstallOrientation()I
-HSPLandroid/view/Display;->getLocalRotation()I
+HSPLandroid/view/Display;->getLocalRotation()I+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/view/Display;->getMetrics(Landroid/util/DisplayMetrics;)V
HSPLandroid/view/Display;->getMode()Landroid/view/Display$Mode;
HSPLandroid/view/Display;->getName()Ljava/lang/String;
@@ -16038,7 +16107,7 @@ HSPLandroid/view/DisplayCutout$Bounds;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/DisplayCutout$Bounds;->getRects()[Landroid/graphics/Rect;
HSPLandroid/view/DisplayCutout$Bounds;->isEmpty()Z
HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;-><init>(IIIIFLjava/lang/String;IFF)V
-HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/DisplayCutout$ParcelableWrapper$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/DisplayCutout$ParcelableWrapper;
HSPLandroid/view/DisplayCutout$ParcelableWrapper$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/view/DisplayCutout$ParcelableWrapper;-><init>()V
@@ -16066,7 +16135,7 @@ HSPLandroid/view/DisplayCutout;->getSafeInsetTop()I
HSPLandroid/view/DisplayCutout;->inset(IIII)Landroid/view/DisplayCutout;
HSPLandroid/view/DisplayCutout;->insetInsets(IIIILandroid/graphics/Rect;)Landroid/graphics/Rect;
HSPLandroid/view/DisplayCutout;->isBoundsEmpty()Z
-HSPLandroid/view/DisplayCutout;->isEmpty()Z
+HSPLandroid/view/DisplayCutout;->isEmpty()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;-><init>()V
HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;-><init>(JJJ)V
HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;->copyFrom(Landroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;)V
@@ -16085,19 +16154,19 @@ HSPLandroid/view/DisplayInfo;-><init>()V
HSPLandroid/view/DisplayInfo;-><init>(Landroid/os/Parcel;)V
HSPLandroid/view/DisplayInfo;-><init>(Landroid/os/Parcel;Landroid/view/DisplayInfo-IA;)V
HSPLandroid/view/DisplayInfo;->copyFrom(Landroid/view/DisplayInfo;)V
-HSPLandroid/view/DisplayInfo;->equals(Landroid/view/DisplayInfo;)Z
+HSPLandroid/view/DisplayInfo;->equals(Landroid/view/DisplayInfo;)Z+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayInfo;Landroid/view/DisplayInfo;
HSPLandroid/view/DisplayInfo;->findMode(I)Landroid/view/Display$Mode;
HSPLandroid/view/DisplayInfo;->flagsToString(I)Ljava/lang/String;
HSPLandroid/view/DisplayInfo;->getAppMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
HSPLandroid/view/DisplayInfo;->getAppMetrics(Landroid/util/DisplayMetrics;Landroid/view/DisplayAdjustments;)V
HSPLandroid/view/DisplayInfo;->getLogicalMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
HSPLandroid/view/DisplayInfo;->getMaxBoundsMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
-HSPLandroid/view/DisplayInfo;->getMetricsWithSize(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;II)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/DisplayInfo;->getMetricsWithSize(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;II)V+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/view/DisplayInfo;->getMode()Landroid/view/Display$Mode;
HSPLandroid/view/DisplayInfo;->getRefreshRate()F
HSPLandroid/view/DisplayInfo;->hasAccess(I)Z
HSPLandroid/view/DisplayInfo;->isWideColorGamut()Z
-HSPLandroid/view/DisplayInfo;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/view/Display$Mode$1;
+HSPLandroid/view/DisplayInfo;->readFromParcel(Landroid/os/Parcel;)V
HSPLandroid/view/DisplayInfo;->toString()Ljava/lang/String;
HSPLandroid/view/DisplayInfo;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/view/DisplayShape$1;-><init>()V
@@ -16181,6 +16250,7 @@ HSPLandroid/view/HandwritingInitiator;->onInputConnectionClosed(Landroid/view/Vi
HSPLandroid/view/HandwritingInitiator;->onInputConnectionCreated(Landroid/view/View;)V
HSPLandroid/view/HandwritingInitiator;->onTouchEvent(Landroid/view/MotionEvent;)Z
HSPLandroid/view/HandwritingInitiator;->updateHandwritingAreasForView(Landroid/view/View;)V
+HSPLandroid/view/HdrRenderState;->updateForFrame(J)Z
HSPLandroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
HSPLandroid/view/IGraphicsStats$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/view/IGraphicsStats$Stub$Proxy;->requestBufferForProcess(Ljava/lang/String;Landroid/view/IGraphicsStatsCallback;)Landroid/os/ParcelFileDescriptor;
@@ -16213,7 +16283,8 @@ HSPLandroid/view/IWindowSession$Stub$Proxy;->finishDrawing(Landroid/view/IWindow
HSPLandroid/view/IWindowSession$Stub$Proxy;->getWindowId(Landroid/os/IBinder;)Landroid/view/IWindowId;
HSPLandroid/view/IWindowSession$Stub$Proxy;->onRectangleOnScreenRequested(Landroid/os/IBinder;Landroid/graphics/Rect;)V
HSPLandroid/view/IWindowSession$Stub$Proxy;->pokeDrawLock(Landroid/os/IBinder;)V
-HSPLandroid/view/IWindowSession$Stub$Proxy;->relayoutAsync(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIII)V
+HSPLandroid/view/IWindowSession$Stub$Proxy;->relayout(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIIILandroid/window/ClientWindowFrames;Landroid/util/MergedConfiguration;Landroid/view/SurfaceControl;Landroid/view/InsetsState;Landroid/view/InsetsSourceControl$Array;Landroid/os/Bundle;)I
+HSPLandroid/view/IWindowSession$Stub$Proxy;->relayoutAsync(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIII)V+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/view/IWindowSession$Stub$Proxy;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/view/IWindowSession$Stub$Proxy;->reportSystemGestureExclusionChanged(Landroid/view/IWindow;Ljava/util/List;)V
HSPLandroid/view/IWindowSession$Stub$Proxy;->setInsets(Landroid/view/IWindow;ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Region;)V
HSPLandroid/view/IWindowSession$Stub$Proxy;->setOnBackInvokedCallbackInfo(Landroid/view/IWindow;Landroid/window/OnBackInvokedCallbackInfo;)V
@@ -16229,7 +16300,7 @@ HSPLandroid/view/ImeFocusController;->onPostWindowFocus(Landroid/view/View;ZLand
HSPLandroid/view/ImeFocusController;->onPreWindowFocus(ZLandroid/view/WindowManager$LayoutParams;)V
HSPLandroid/view/ImeFocusController;->onProcessImeInputStage(Ljava/lang/Object;Landroid/view/InputEvent;Landroid/view/WindowManager$LayoutParams;Landroid/view/inputmethod/InputMethodManager$FinishedInputEventCallback;)I
HSPLandroid/view/ImeFocusController;->onTraversal(ZLandroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ImeFocusController;->onViewDetachedFromWindow(Landroid/view/View;)V+]Landroid/view/ImeFocusController$InputMethodManagerDelegate;Landroid/view/inputmethod/InputMethodManager$DelegateImpl;
+HSPLandroid/view/ImeFocusController;->onViewDetachedFromWindow(Landroid/view/View;)V
HSPLandroid/view/ImeFocusController;->onViewFocusChanged(Landroid/view/View;Z)V
HSPLandroid/view/ImeFocusController;->onWindowDismissed()V
HSPLandroid/view/ImeInsetsSourceConsumer;-><init>(ILandroid/view/InsetsState;Ljava/util/function/Supplier;Landroid/view/InsetsController;)V
@@ -16261,7 +16332,7 @@ HSPLandroid/view/InputDevice;->getSources()I
HSPLandroid/view/InputDevice;->isVirtual()Z
HSPLandroid/view/InputEvent;-><init>()V
HSPLandroid/view/InputEvent;->getSequenceNumber()I
-HSPLandroid/view/InputEvent;->isFromSource(I)Z
+HSPLandroid/view/InputEvent;->isFromSource(I)Z+]Landroid/view/InputEvent;Landroid/view/MotionEvent;
HSPLandroid/view/InputEvent;->prepareForReuse()V
HSPLandroid/view/InputEvent;->recycle()V
HSPLandroid/view/InputEvent;->recycleIfNeededAfterDispatch()V
@@ -16273,7 +16344,7 @@ HSPLandroid/view/InputEventCompatProcessor;->processInputEventForCompatibility(L
HSPLandroid/view/InputEventConsistencyVerifier;->isInstrumentationEnabled()Z
HSPLandroid/view/InputEventReceiver;-><init>(Landroid/view/InputChannel;Landroid/os/Looper;)V
HSPLandroid/view/InputEventReceiver;->consumeBatchedInputEvents(J)Z
-HSPLandroid/view/InputEventReceiver;->dispatchInputEvent(ILandroid/view/InputEvent;)V+]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Landroid/view/InputEventReceiver;Landroid/view/ViewRootImpl$WindowInputEventReceiver;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/InputEventReceiver;->dispatchInputEvent(ILandroid/view/InputEvent;)V
HSPLandroid/view/InputEventReceiver;->dispose()V
HSPLandroid/view/InputEventReceiver;->dispose(Z)V
HSPLandroid/view/InputEventReceiver;->finalize()V
@@ -16349,6 +16420,9 @@ HSPLandroid/view/InsetsController$3;->onStart(Landroid/view/InsetsState;Landroid
HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda0;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V
HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda3;->getInterpolation(F)F
HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda4;->getInterpolation(F)F
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$1;->initialValue()Landroid/animation/AnimationHandler;
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$1;->initialValue()Ljava/lang/Object;
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$2;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/view/InsetsController$InternalAnimationControlListener;-><init>(ZZIIZILandroid/view/WindowInsetsAnimationControlListener;Landroid/view/inputmethod/ImeTracker$InputMethodJankContext;)V
HSPLandroid/view/InsetsController$InternalAnimationControlListener;->calculateDurationMs()J
HSPLandroid/view/InsetsController$InternalAnimationControlListener;->getAlphaInterpolator()Landroid/view/animation/Interpolator;
@@ -16375,6 +16449,7 @@ HSPLandroid/view/InsetsController;->calculateVisibleInsets(IIII)Landroid/graphic
HSPLandroid/view/InsetsController;->cancelAnimation(Landroid/view/InsetsAnimationControlRunner;Z)V
HSPLandroid/view/InsetsController;->cancelExistingAnimations()V
HSPLandroid/view/InsetsController;->cancelExistingControllers(I)V
+HSPLandroid/view/InsetsController;->captionInsetsUnchanged()Z
HSPLandroid/view/InsetsController;->collectSourceControls(ZILandroid/util/SparseArray;ILandroid/view/inputmethod/ImeTracker$Token;)Landroid/util/Pair;
HSPLandroid/view/InsetsController;->controlAnimationUncheckedInner(ILandroid/os/CancellationSignal;Landroid/view/WindowInsetsAnimationControlListener;Landroid/graphics/Rect;ZJLandroid/view/animation/Interpolator;IIZLandroid/view/inputmethod/ImeTracker$Token;)V
HSPLandroid/view/InsetsController;->dispatchAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
@@ -16392,8 +16467,8 @@ HSPLandroid/view/InsetsController;->lambda$static$1(FLandroid/graphics/Insets;La
HSPLandroid/view/InsetsController;->notifyControlRevoked(Landroid/view/InsetsSourceConsumer;)V
HSPLandroid/view/InsetsController;->notifyFinished(Landroid/view/InsetsAnimationControlRunner;Z)V
HSPLandroid/view/InsetsController;->notifyVisibilityChanged()V
-HSPLandroid/view/InsetsController;->onControlsChanged([Landroid/view/InsetsSourceControl;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceConsumer;Landroid/view/ImeInsetsSourceConsumer;,Landroid/view/InsetsSourceConsumer;]Landroid/view/InsetsSourceControl;Landroid/view/InsetsSourceControl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/InsetsController;->onFrameChanged(Landroid/graphics/Rect;)V
+HSPLandroid/view/InsetsController;->onControlsChanged([Landroid/view/InsetsSourceControl;)V
+HSPLandroid/view/InsetsController;->onFrameChanged(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/view/InsetsController;->onStateChanged(Landroid/view/InsetsState;)Z
HSPLandroid/view/InsetsController;->onWindowFocusGained(Z)V
HSPLandroid/view/InsetsController;->onWindowFocusLost()V
@@ -16406,15 +16481,15 @@ HSPLandroid/view/InsetsController;->updateCompatSysUiVisibility()V
HSPLandroid/view/InsetsController;->updateState(Landroid/view/InsetsState;)V
HSPLandroid/view/InsetsFlags;-><init>()V
HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/view/InsetsSource$1;Landroid/view/InsetsSource$1;
+HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/view/InsetsSource;-><init>(II)V
-HSPLandroid/view/InsetsSource;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/graphics/Rect$1;
+HSPLandroid/view/InsetsSource;-><init>(Landroid/os/Parcel;)V
HSPLandroid/view/InsetsSource;-><init>(Landroid/view/InsetsSource;)V
-HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Landroid/graphics/Rect;Z)Landroid/graphics/Insets;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Landroid/graphics/Rect;Z)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Z)Landroid/graphics/Insets;
HSPLandroid/view/InsetsSource;->calculateVisibleInsets(Landroid/graphics/Rect;)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;)Z+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Ljava/lang/Object;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;)Z
+HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;Z)Z
HSPLandroid/view/InsetsSource;->getFlags()I
HSPLandroid/view/InsetsSource;->getFrame()Landroid/graphics/Rect;
HSPLandroid/view/InsetsSource;->getId()I
@@ -16468,30 +16543,30 @@ HSPLandroid/view/InsetsState;-><init>()V
HSPLandroid/view/InsetsState;-><init>(Landroid/os/Parcel;)V
HSPLandroid/view/InsetsState;-><init>(Landroid/view/InsetsState;Z)V
HSPLandroid/view/InsetsState;->addSource(Landroid/view/InsetsSource;)V
-HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;II)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;IZ)Landroid/graphics/Insets;
+HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;II)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;IZ)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/util/SparseArray;Landroid/util/SparseArray;
HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;Landroid/view/InsetsState;ZIIIIILandroid/util/SparseIntArray;)Landroid/view/WindowInsets;
HSPLandroid/view/InsetsState;->calculateRelativeCutout(Landroid/graphics/Rect;)Landroid/view/DisplayCutout;
HSPLandroid/view/InsetsState;->calculateRelativeDisplayShape(Landroid/graphics/Rect;)Landroid/view/DisplayShape;
HSPLandroid/view/InsetsState;->calculateRelativePrivacyIndicatorBounds(Landroid/graphics/Rect;)Landroid/view/PrivacyIndicatorBounds;
HSPLandroid/view/InsetsState;->calculateRelativeRoundedCorners(Landroid/graphics/Rect;)Landroid/view/RoundedCorners;
-HSPLandroid/view/InsetsState;->calculateUncontrollableInsetsFromFrame(Landroid/graphics/Rect;)I+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->calculateUncontrollableInsetsFromFrame(Landroid/graphics/Rect;)I
HSPLandroid/view/InsetsState;->calculateVisibleInsets(Landroid/graphics/Rect;IIII)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsState;->canControlSource(Landroid/graphics/Rect;Landroid/view/InsetsSource;)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->canControlSource(Landroid/graphics/Rect;Landroid/view/InsetsSource;)Z
HSPLandroid/view/InsetsState;->clearsCompatInsets(IIII)Z
HSPLandroid/view/InsetsState;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/InsetsState;->equals(Ljava/lang/Object;ZZ)Z
-HSPLandroid/view/InsetsState;->getDisplayCutout()Landroid/view/DisplayCutout;
-HSPLandroid/view/InsetsState;->getDisplayCutoutSafe(Landroid/graphics/Rect;)V
+HSPLandroid/view/InsetsState;->getDisplayCutout()Landroid/view/DisplayCutout;+]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;
+HSPLandroid/view/InsetsState;->getDisplayCutoutSafe(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;
HSPLandroid/view/InsetsState;->getDisplayFrame()Landroid/graphics/Rect;
HSPLandroid/view/InsetsState;->getDisplayShape()Landroid/view/DisplayShape;
HSPLandroid/view/InsetsState;->getPrivacyIndicatorBounds()Landroid/view/PrivacyIndicatorBounds;
HSPLandroid/view/InsetsState;->getRoundedCorners()Landroid/view/RoundedCorners;
HSPLandroid/view/InsetsState;->isSourceOrDefaultVisible(II)Z
HSPLandroid/view/InsetsState;->peekSource(I)Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsState;->readFromParcel(Landroid/os/Parcel;)Landroid/util/SparseArray;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->readFromParcel(Landroid/os/Parcel;)Landroid/util/SparseArray;
HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;I)V
-HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/view/InsetsState;Landroid/view/InsetsState;
+HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;Z)V
HSPLandroid/view/InsetsState;->setDisplayCutout(Landroid/view/DisplayCutout;)V
HSPLandroid/view/InsetsState;->setDisplayFrame(Landroid/graphics/Rect;)V
HSPLandroid/view/InsetsState;->setPrivacyIndicatorBounds(Landroid/view/PrivacyIndicatorBounds;)V
@@ -16550,28 +16625,28 @@ HSPLandroid/view/LayoutInflater;-><init>(Landroid/content/Context;)V
HSPLandroid/view/LayoutInflater;-><init>(Landroid/view/LayoutInflater;Landroid/content/Context;)V
HSPLandroid/view/LayoutInflater;->advanceToRootNode(Lorg/xmlpull/v1/XmlPullParser;)V
HSPLandroid/view/LayoutInflater;->consumeChildElements(Lorg/xmlpull/v1/XmlPullParser;)V
-HSPLandroid/view/LayoutInflater;->createView(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;+]Landroid/content/Context;missing_types]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/ViewStub;Landroid/view/ViewStub;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/reflect/Constructor;Ljava/lang/reflect/Constructor;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/view/LayoutInflater;->createView(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->createView(Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;Z)Landroid/view/View;+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;Z)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->from(Landroid/content/Context;)Landroid/view/LayoutInflater;
HSPLandroid/view/LayoutInflater;->getContext()Landroid/content/Context;
HSPLandroid/view/LayoutInflater;->getFactory()Landroid/view/LayoutInflater$Factory;
HSPLandroid/view/LayoutInflater;->getFactory2()Landroid/view/LayoutInflater$Factory2;
HSPLandroid/view/LayoutInflater;->inflate(ILandroid/view/ViewGroup;)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->inflate(ILandroid/view/ViewGroup;Z)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->inflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/ViewGroup;Z)Landroid/view/View;+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/LayoutInflater;->inflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/ViewGroup;Z)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->onCreateView(Landroid/content/Context;Landroid/view/View;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->onCreateView(Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->parseInclude(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/Context;Landroid/view/View;Landroid/util/AttributeSet;)V
-HSPLandroid/view/LayoutInflater;->rInflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/content/Context;Landroid/util/AttributeSet;Z)V+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
-HSPLandroid/view/LayoutInflater;->rInflateChildren(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/util/AttributeSet;Z)V+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types
+HSPLandroid/view/LayoutInflater;->parseInclude(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/Context;Landroid/view/View;Landroid/util/AttributeSet;)V+]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/widget/FrameLayout;,Landroid/widget/LinearLayout;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Ljava/lang/Object;Ljava/lang/String;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/res/XmlResourceParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/LayoutInflater;->rInflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/content/Context;Landroid/util/AttributeSet;Z)V+]Landroid/view/View;missing_types]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;]Landroid/view/ViewGroup;Landroid/widget/RelativeLayout;,Landroid/widget/FrameLayout;,Landroid/widget/LinearLayout;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/view/LayoutInflater;->rInflateChildren(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/util/AttributeSet;Z)V
HSPLandroid/view/LayoutInflater;->setFactory2(Landroid/view/LayoutInflater$Factory2;)V
HSPLandroid/view/LayoutInflater;->setFilter(Landroid/view/LayoutInflater$Filter;)V
HSPLandroid/view/LayoutInflater;->setPrivateFactory(Landroid/view/LayoutInflater$Factory2;)V
-HSPLandroid/view/LayoutInflater;->tryCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;+]Landroid/view/LayoutInflater$Factory2;missing_types]Ljava/lang/Object;Ljava/lang/String;
-HSPLandroid/view/LayoutInflater;->verifyClassLoader(Ljava/lang/reflect/Constructor;)Z+]Landroid/content/Context;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/reflect/Constructor;Ljava/lang/reflect/Constructor;
+HSPLandroid/view/LayoutInflater;->tryCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
+HSPLandroid/view/LayoutInflater;->verifyClassLoader(Ljava/lang/reflect/Constructor;)Z
HSPLandroid/view/MenuInflater;-><init>(Landroid/content/Context;)V
HSPLandroid/view/MotionEvent$PointerCoords;-><init>()V
HSPLandroid/view/MotionEvent$PointerProperties;-><init>()V
@@ -16612,7 +16687,7 @@ HSPLandroid/view/MotionEvent;->getX(I)F
HSPLandroid/view/MotionEvent;->getY()F
HSPLandroid/view/MotionEvent;->getY(I)F
HSPLandroid/view/MotionEvent;->initialize(IIIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;[Landroid/view/MotionEvent$PointerCoords;)Z
-HSPLandroid/view/MotionEvent;->isTargetAccessibilityFocus()Z
+HSPLandroid/view/MotionEvent;->isTargetAccessibilityFocus()Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/view/MotionEvent;->isTouchEvent()Z
HSPLandroid/view/MotionEvent;->obtain()Landroid/view/MotionEvent;
HSPLandroid/view/MotionEvent;->obtain(JJIFFFFIFFII)Landroid/view/MotionEvent;
@@ -16623,7 +16698,7 @@ HSPLandroid/view/MotionEvent;->offsetLocation(FF)V
HSPLandroid/view/MotionEvent;->recycle()V
HSPLandroid/view/MotionEvent;->setAction(I)V
HSPLandroid/view/MotionEvent;->setLocation(FF)V
-HSPLandroid/view/MotionEvent;->setTargetAccessibilityFocus(Z)V
+HSPLandroid/view/MotionEvent;->setTargetAccessibilityFocus(Z)V+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/view/MotionEvent;->split(I)Landroid/view/MotionEvent;
HSPLandroid/view/MotionEvent;->transform(Landroid/graphics/Matrix;)V
HSPLandroid/view/MotionEvent;->updateCursorPosition()V
@@ -16659,12 +16734,12 @@ HSPLandroid/view/RemoteAccessibilityController;->setRemoteAccessibilityEmbeddedC
HSPLandroid/view/RemoteAnimationAdapter;-><init>(Landroid/view/IRemoteAnimationRunner;JJ)V
HSPLandroid/view/RemoteAnimationAdapter;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/view/RoundedCorner$1;-><init>()V
-HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/RoundedCorner;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/view/RoundedCorner$1;Landroid/view/RoundedCorner$1;
+HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/RoundedCorner;
+HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/view/RoundedCorner;-><clinit>()V
HSPLandroid/view/RoundedCorner;-><init>(I)V
HSPLandroid/view/RoundedCorner;-><init>(IIII)V
-HSPLandroid/view/RoundedCorner;->equals(Ljava/lang/Object;)Z+]Landroid/graphics/Point;Landroid/graphics/Point;
+HSPLandroid/view/RoundedCorner;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/RoundedCorner;->getCenter()Landroid/graphics/Point;
HSPLandroid/view/RoundedCorner;->getRadius()I
HSPLandroid/view/RoundedCorner;->isEmpty()Z
@@ -16727,7 +16802,7 @@ HSPLandroid/view/SurfaceControl$Builder;->setOpaque(Z)Landroid/view/SurfaceContr
HSPLandroid/view/SurfaceControl$Builder;->setParent(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Builder;
HSPLandroid/view/SurfaceControl$Builder;->unsetBufferSize()V
HSPLandroid/view/SurfaceControl$Transaction;-><init>()V
-HSPLandroid/view/SurfaceControl$Transaction;-><init>(J)V
+HSPLandroid/view/SurfaceControl$Transaction;-><init>(J)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
HSPLandroid/view/SurfaceControl$Transaction;->apply()V
HSPLandroid/view/SurfaceControl$Transaction;->apply(Z)V
HSPLandroid/view/SurfaceControl$Transaction;->applyResizedSurfaces()V
@@ -16735,7 +16810,7 @@ HSPLandroid/view/SurfaceControl$Transaction;->checkPreconditions(Landroid/view/S
HSPLandroid/view/SurfaceControl$Transaction;->clear()V
HSPLandroid/view/SurfaceControl$Transaction;->close()V
HSPLandroid/view/SurfaceControl$Transaction;->hide(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/view/SurfaceControl$Transaction;->merge(Landroid/view/SurfaceControl$Transaction;)Landroid/view/SurfaceControl$Transaction;
+HSPLandroid/view/SurfaceControl$Transaction;->merge(Landroid/view/SurfaceControl$Transaction;)Landroid/view/SurfaceControl$Transaction;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
HSPLandroid/view/SurfaceControl$Transaction;->notifyReparentedSurfaces()V
HSPLandroid/view/SurfaceControl$Transaction;->remove(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->reparent(Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
@@ -16745,7 +16820,7 @@ HSPLandroid/view/SurfaceControl$Transaction;->setBufferSize(Landroid/view/Surfac
HSPLandroid/view/SurfaceControl$Transaction;->setColor(Landroid/view/SurfaceControl;[F)Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->setCornerRadius(Landroid/view/SurfaceControl;F)Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->setDesintationFrame(Landroid/view/SurfaceControl;II)Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/view/SurfaceControl$Transaction;->setExtendedRangeBrightness(Landroid/view/SurfaceControl;FF)Landroid/view/SurfaceControl$Transaction;
+HSPLandroid/view/SurfaceControl$Transaction;->setExtendedRangeBrightness(Landroid/view/SurfaceControl;FF)Landroid/view/SurfaceControl$Transaction;+]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->setFrameTimelineVsync(J)Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->setLayer(Landroid/view/SurfaceControl;I)Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->setMatrix(Landroid/view/SurfaceControl;FFFF)Landroid/view/SurfaceControl$Transaction;
@@ -16813,6 +16888,7 @@ HSPLandroid/view/SurfaceView;->onMeasure(II)V
HSPLandroid/view/SurfaceView;->onSetSurfacePositionAndScale(Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl;IIFF)V
HSPLandroid/view/SurfaceView;->onWindowVisibilityChanged(I)V
HSPLandroid/view/SurfaceView;->performDrawFinished()V
+HSPLandroid/view/SurfaceView;->performSurfaceTransaction(Landroid/view/ViewRootImpl;Landroid/content/res/CompatibilityInfo$Translator;ZZZZLandroid/view/SurfaceControl$Transaction;)Z
HSPLandroid/view/SurfaceView;->releaseSurfaces(Z)V
HSPLandroid/view/SurfaceView;->replacePositionUpdateListener(II)V
HSPLandroid/view/SurfaceView;->requiresSurfaceControlCreation(ZZ)Z
@@ -16853,8 +16929,8 @@ HSPLandroid/view/TextureView;->updateLayer()V
HSPLandroid/view/ThreadedRenderer$1$$ExternalSyntheticLambda0;-><init>(Ljava/util/ArrayList;)V
HSPLandroid/view/ThreadedRenderer$1$$ExternalSyntheticLambda0;->onFrameCommit(Z)V
HSPLandroid/view/ThreadedRenderer$1;-><init>(Landroid/view/ThreadedRenderer;Ljava/util/ArrayList;)V
-HSPLandroid/view/ThreadedRenderer$1;->lambda$onFrameDraw$0(Ljava/util/ArrayList;Z)V
-HSPLandroid/view/ThreadedRenderer$1;->onFrameDraw(IJ)Landroid/graphics/HardwareRenderer$FrameCommitCallback;
+HSPLandroid/view/ThreadedRenderer$1;->lambda$onFrameDraw$0(Ljava/util/ArrayList;Z)V+]Landroid/graphics/HardwareRenderer$FrameCommitCallback;Landroid/view/ViewRootImpl$7$$ExternalSyntheticLambda0;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ThreadedRenderer$1;->onFrameDraw(IJ)Landroid/graphics/HardwareRenderer$FrameCommitCallback;+]Landroid/graphics/HardwareRenderer$FrameDrawingCallback;Landroid/view/ViewRootImpl$3;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;->-$$Nest$fgetmSurfaceControl(Landroid/view/ThreadedRenderer$WebViewOverlayProvider;)Landroid/view/SurfaceControl;
HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;-><clinit>()V
HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;-><init>()V
@@ -16869,7 +16945,7 @@ HSPLandroid/view/ThreadedRenderer;->create(Landroid/content/Context;ZLjava/lang/
HSPLandroid/view/ThreadedRenderer;->destroy()V
HSPLandroid/view/ThreadedRenderer;->destroyHardwareResources(Landroid/view/View;)V
HSPLandroid/view/ThreadedRenderer;->destroyResources(Landroid/view/View;)V
-HSPLandroid/view/ThreadedRenderer;->draw(Landroid/view/View;Landroid/view/View$AttachInfo;Landroid/view/ThreadedRenderer$DrawCallbacks;)V
+HSPLandroid/view/ThreadedRenderer;->draw(Landroid/view/View;Landroid/view/View$AttachInfo;Landroid/view/ThreadedRenderer$DrawCallbacks;)V+]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ThreadedRenderer;->dumpArgsToFlags([Ljava/lang/String;)I
HSPLandroid/view/ThreadedRenderer;->getHeight()I
HSPLandroid/view/ThreadedRenderer;->getWidth()I
@@ -16880,20 +16956,20 @@ HSPLandroid/view/ThreadedRenderer;->invalidateRoot()V
HSPLandroid/view/ThreadedRenderer;->isEnabled()Z
HSPLandroid/view/ThreadedRenderer;->isRequested()Z
HSPLandroid/view/ThreadedRenderer;->loadSystemProperties()Z
-HSPLandroid/view/ThreadedRenderer;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V
+HSPLandroid/view/ThreadedRenderer;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ThreadedRenderer;->rendererOwnsSurfaceControlOpacity()Z
HSPLandroid/view/ThreadedRenderer;->setEnabled(Z)V
HSPLandroid/view/ThreadedRenderer;->setLightCenter(Landroid/view/View$AttachInfo;)V
HSPLandroid/view/ThreadedRenderer;->setRequested(Z)V
HSPLandroid/view/ThreadedRenderer;->setSurface(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->setSurfaceControl(Landroid/view/SurfaceControl;Landroid/graphics/BLASTBufferQueue;)V
+HSPLandroid/view/ThreadedRenderer;->setSurfaceControl(Landroid/view/SurfaceControl;Landroid/graphics/BLASTBufferQueue;)V+]Landroid/view/ThreadedRenderer$WebViewOverlayProvider;Landroid/view/ThreadedRenderer$WebViewOverlayProvider;
HSPLandroid/view/ThreadedRenderer;->setSurfaceControlOpaque(Z)Z
HSPLandroid/view/ThreadedRenderer;->setup(IILandroid/view/View$AttachInfo;Landroid/graphics/Rect;)V
HSPLandroid/view/ThreadedRenderer;->updateEnabledState(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->updateRootDisplayList(Landroid/view/View;Landroid/view/ThreadedRenderer$DrawCallbacks;)V
+HSPLandroid/view/ThreadedRenderer;->updateRootDisplayList(Landroid/view/View;Landroid/view/ThreadedRenderer$DrawCallbacks;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ThreadedRenderer$DrawCallbacks;Landroid/view/ViewRootImpl;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/view/ThreadedRenderer;->updateSurface(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->updateViewTreeDisplayList(Landroid/view/View;)V
-HSPLandroid/view/ThreadedRenderer;->updateWebViewOverlayCallbacks()V
+HSPLandroid/view/ThreadedRenderer;->updateViewTreeDisplayList(Landroid/view/View;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ThreadedRenderer;->updateWebViewOverlayCallbacks()V+]Landroid/view/ThreadedRenderer$WebViewOverlayProvider;Landroid/view/ThreadedRenderer$WebViewOverlayProvider;
HSPLandroid/view/TouchDelegate;-><init>(Landroid/graphics/Rect;Landroid/view/View;)V
HSPLandroid/view/VelocityTracker;-><init>(I)V
HSPLandroid/view/VelocityTracker;->addMovement(Landroid/view/MotionEvent;)V
@@ -16915,7 +16991,7 @@ HSPLandroid/view/View$$ExternalSyntheticLambda7;->run()V
HSPLandroid/view/View$12;->get(Landroid/view/View;)Ljava/lang/Float;
HSPLandroid/view/View$12;->get(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/view/View$12;->setValue(Landroid/view/View;F)V
-HSPLandroid/view/View$12;->setValue(Ljava/lang/Object;F)V
+HSPLandroid/view/View$12;->setValue(Ljava/lang/Object;F)V+]Landroid/view/View$12;Landroid/view/View$12;
HSPLandroid/view/View$13;->get(Landroid/view/View;)Ljava/lang/Float;
HSPLandroid/view/View$13;->get(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/view/View$13;->setValue(Landroid/view/View;F)V
@@ -16969,31 +17045,31 @@ HSPLandroid/view/View$MeasureSpec;->makeMeasureSpec(II)I
HSPLandroid/view/View$MeasureSpec;->makeSafeMeasureSpec(II)I
HSPLandroid/view/View$PerformClick;->run()V
HSPLandroid/view/View$ScrollabilityCache;-><init>(Landroid/view/ViewConfiguration;Landroid/view/View;)V
-HSPLandroid/view/View$ScrollabilityCache;->run()V
+HSPLandroid/view/View$ScrollabilityCache;->run()V+]Landroid/graphics/Interpolator;Landroid/graphics/Interpolator;]Landroid/view/View;missing_types
HSPLandroid/view/View$TintInfo;-><init>()V
HSPLandroid/view/View$TransformationInfo;-><init>()V
HSPLandroid/view/View$UnsetPressedState;->run()V
HSPLandroid/view/View$VisibilityChangeForAutofillHandler;->handleMessage(Landroid/os/Message;)V
-HSPLandroid/view/View;-><init>(Landroid/content/Context;)V+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/view/View;-><init>(Landroid/content/Context;)V+]Landroid/view/View;missing_types]Ljava/lang/Object;missing_types]Landroid/content/Context;missing_types]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/view/View;missing_types]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/view/View;->addFocusables(Ljava/util/ArrayList;I)V
HSPLandroid/view/View;->addFocusables(Ljava/util/ArrayList;II)V
HSPLandroid/view/View;->addFrameMetricsListener(Landroid/view/Window;Landroid/view/Window$OnFrameMetricsAvailableListener;Landroid/os/Handler;)V
HSPLandroid/view/View;->addOnAttachStateChangeListener(Landroid/view/View$OnAttachStateChangeListener;)V
-HSPLandroid/view/View;->addOnLayoutChangeListener(Landroid/view/View$OnLayoutChangeListener;)V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/View;->addOnLayoutChangeListener(Landroid/view/View$OnLayoutChangeListener;)V
HSPLandroid/view/View;->animate()Landroid/view/ViewPropertyAnimator;
HSPLandroid/view/View;->announceForAccessibility(Ljava/lang/CharSequence;)V
HSPLandroid/view/View;->appendId(Ljava/lang/StringBuilder;)V
HSPLandroid/view/View;->applyBackgroundTint()V
HSPLandroid/view/View;->applyForegroundTint()V
HSPLandroid/view/View;->applyInsets(Landroid/graphics/Rect;)V
-HSPLandroid/view/View;->applyLegacyAnimation(Landroid/view/ViewGroup;JLandroid/view/animation/Animation;Z)Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
+HSPLandroid/view/View;->applyLegacyAnimation(Landroid/view/ViewGroup;JLandroid/view/animation/Animation;Z)Z
HSPLandroid/view/View;->areDrawablesResolved()Z
HSPLandroid/view/View;->assignParent(Landroid/view/ViewParent;)V
HSPLandroid/view/View;->awakenScrollBars()Z
-HSPLandroid/view/View;->awakenScrollBars(IZ)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->awakenScrollBars(IZ)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/View;Landroid/widget/ImageView;,Landroid/widget/TextView;,Landroid/widget/LinearLayout;
HSPLandroid/view/View;->bringToFront()V
HSPLandroid/view/View;->buildDrawingCache(Z)V
HSPLandroid/view/View;->buildDrawingCacheImpl(Z)V
@@ -17001,7 +17077,7 @@ HSPLandroid/view/View;->buildLayer()V
HSPLandroid/view/View;->calculateAccessibilityDataSensitive()V
HSPLandroid/view/View;->calculateIsImportantForContentCapture()Z
HSPLandroid/view/View;->canHaveDisplayList()Z
-HSPLandroid/view/View;->canNotifyAutofillEnterExitEvent()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->canNotifyAutofillEnterExitEvent()Z
HSPLandroid/view/View;->canReceivePointerEvents()Z
HSPLandroid/view/View;->canResolveLayoutDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
HSPLandroid/view/View;->canResolveTextDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
@@ -17013,8 +17089,8 @@ HSPLandroid/view/View;->cancelLongPress()V
HSPLandroid/view/View;->cancelPendingInputEvents()V
HSPLandroid/view/View;->checkForLongClick(JFFI)V
HSPLandroid/view/View;->checkInputConnectionProxy(Landroid/view/View;)Z
-HSPLandroid/view/View;->cleanupDraw()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
-HSPLandroid/view/View;->clearAccessibilityFocus()V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->cleanupDraw()V
+HSPLandroid/view/View;->clearAccessibilityFocus()V
HSPLandroid/view/View;->clearAccessibilityFocusNoCallbacks(I)V
HSPLandroid/view/View;->clearAccessibilityThrottles()V
HSPLandroid/view/View;->clearAnimation()V
@@ -17023,7 +17099,7 @@ HSPLandroid/view/View;->clearFocusInternal(Landroid/view/View;ZZ)V
HSPLandroid/view/View;->clearParentsWantFocus()V
HSPLandroid/view/View;->clearTranslationState()V
HSPLandroid/view/View;->clearViewTranslationResponse()V
-HSPLandroid/view/View;->collectPreferKeepClearRects()Ljava/util/List;+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->collectPreferKeepClearRects()Ljava/util/List;
HSPLandroid/view/View;->collectUnrestrictedPreferKeepClearRects()Ljava/util/List;
HSPLandroid/view/View;->combineMeasuredStates(II)I
HSPLandroid/view/View;->combineVisibility(II)I
@@ -17031,21 +17107,21 @@ HSPLandroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/
HSPLandroid/view/View;->computeHorizontalScrollExtent()I
HSPLandroid/view/View;->computeHorizontalScrollOffset()I
HSPLandroid/view/View;->computeHorizontalScrollRange()I
-HSPLandroid/view/View;->computeOpaqueFlags()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->computeOpaqueFlags()V
HSPLandroid/view/View;->computeScroll()V
HSPLandroid/view/View;->computeSystemWindowInsets(Landroid/view/WindowInsets;Landroid/graphics/Rect;)Landroid/view/WindowInsets;
-HSPLandroid/view/View;->computeVerticalScrollExtent()I
+HSPLandroid/view/View;->computeVerticalScrollExtent()I+]Landroid/view/View;missing_types
HSPLandroid/view/View;->computeVerticalScrollOffset()I
-HSPLandroid/view/View;->computeVerticalScrollRange()I
-HSPLandroid/view/View;->damageInParent()V+]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->computeVerticalScrollRange()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->damageInParent()V
HSPLandroid/view/View;->destroyDrawingCache()V
HSPLandroid/view/View;->destroyHardwareResources()V
-HSPLandroid/view/View;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/View;missing_types]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
-HSPLandroid/view/View;->dispatchCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
+HSPLandroid/view/View;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/View;missing_types]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;
+HSPLandroid/view/View;->dispatchCancelPendingInputEvents()V
HSPLandroid/view/View;->dispatchCollectViewAttributes(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->dispatchConfigurationChanged(Landroid/content/res/Configuration;)V
-HSPLandroid/view/View;->dispatchDetachedFromWindow()V+]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/view/ViewOverlay$OverlayViewGroup;]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;]Ljava/util/List;Ljava/util/Collections$EmptyList;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
+HSPLandroid/view/View;->dispatchDetachedFromWindow()V+]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/View;->dispatchDraw(Landroid/graphics/Canvas;)V
HSPLandroid/view/View;->dispatchDrawableHotspotChanged(FF)V
HSPLandroid/view/View;->dispatchFinishTemporaryDetach()V
@@ -17061,7 +17137,7 @@ HSPLandroid/view/View;->dispatchProvideAutofillStructure(Landroid/view/ViewStruc
HSPLandroid/view/View;->dispatchProvideContentCaptureStructure()V
HSPLandroid/view/View;->dispatchProvideStructure(Landroid/view/ViewStructure;II)V
HSPLandroid/view/View;->dispatchRestoreInstanceState(Landroid/util/SparseArray;)V
-HSPLandroid/view/View;->dispatchSaveInstanceState(Landroid/util/SparseArray;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/View;->dispatchSaveInstanceState(Landroid/util/SparseArray;)V
HSPLandroid/view/View;->dispatchScreenStateChanged(I)V
HSPLandroid/view/View;->dispatchSetActivated(Z)V
HSPLandroid/view/View;->dispatchSetPressed(Z)V
@@ -17070,18 +17146,18 @@ HSPLandroid/view/View;->dispatchStartTemporaryDetach()V
HSPLandroid/view/View;->dispatchSystemUiVisibilityChanged(I)V
HSPLandroid/view/View;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
HSPLandroid/view/View;->dispatchVisibilityAggregated(Z)Z+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->dispatchVisibilityChanged(Landroid/view/View;I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchVisibilityChanged(Landroid/view/View;I)V
HSPLandroid/view/View;->dispatchWindowFocusChanged(Z)V
HSPLandroid/view/View;->dispatchWindowInsetsAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
HSPLandroid/view/View;->dispatchWindowSystemUiVisiblityChanged(I)V
-HSPLandroid/view/View;->dispatchWindowVisibilityChanged(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchWindowVisibilityChanged(I)V
HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;Landroid/view/ViewGroup;J)Z+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/AnimationSet;,Landroid/view/animation/RotateAnimation;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
-HSPLandroid/view/View;->drawAutofilledHighlight(Landroid/graphics/Canvas;)V
-HSPLandroid/view/View;->drawBackground(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;Landroid/view/ViewGroup;J)Z+]Landroid/view/View;missing_types]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/view/ViewGroup;Landroid/widget/FrameLayout;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;]Landroid/view/animation/Animation;Landroid/view/animation/TranslateAnimation;,Landroid/view/animation/AlphaAnimation;
+HSPLandroid/view/View;->drawAutofilledHighlight(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->drawBackground(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/view/View;->drawDefaultFocusHighlight(Landroid/graphics/Canvas;)V
HSPLandroid/view/View;->drawableHotspotChanged(FF)V
-HSPLandroid/view/View;->drawableStateChanged()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->drawableStateChanged()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/view/View;missing_types]Landroid/graphics/drawable/Drawable;Landroid/widget/ScrollBarDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/StateListDrawable;,Landroid/graphics/drawable/ColorDrawable;
HSPLandroid/view/View;->drawsWithRenderNode(Landroid/graphics/Canvas;)Z+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/view/View;->ensureTransformationInfo()V
HSPLandroid/view/View;->findAccessibilityFocusHost(Z)Landroid/view/View;
@@ -17091,7 +17167,7 @@ HSPLandroid/view/View;->findKeyboardNavigationCluster()Landroid/view/View;
HSPLandroid/view/View;->findOnBackInvokedDispatcher()Landroid/window/OnBackInvokedDispatcher;
HSPLandroid/view/View;->findUserSetNextFocus(Landroid/view/View;I)Landroid/view/View;
HSPLandroid/view/View;->findViewByAutofillIdTraversal(I)Landroid/view/View;
-HSPLandroid/view/View;->findViewById(I)Landroid/view/View;+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->findViewById(I)Landroid/view/View;
HSPLandroid/view/View;->findViewTraversal(I)Landroid/view/View;
HSPLandroid/view/View;->findViewWithTag(Ljava/lang/Object;)Landroid/view/View;
HSPLandroid/view/View;->findViewWithTagTraversal(Ljava/lang/Object;)Landroid/view/View;
@@ -17126,7 +17202,7 @@ HSPLandroid/view/View;->getContentDescription()Ljava/lang/CharSequence;
HSPLandroid/view/View;->getContext()Landroid/content/Context;
HSPLandroid/view/View;->getDefaultSize(II)I
HSPLandroid/view/View;->getDisplay()Landroid/view/Display;
-HSPLandroid/view/View;->getDrawableRenderNode(Landroid/graphics/drawable/Drawable;Landroid/graphics/RenderNode;)Landroid/graphics/RenderNode;+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/drawable/Drawable;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/view/View;->getDrawableRenderNode(Landroid/graphics/drawable/Drawable;Landroid/graphics/RenderNode;)Landroid/graphics/RenderNode;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/view/View;->getDrawableState()[I+]Landroid/view/View;missing_types
HSPLandroid/view/View;->getDrawingCache(Z)Landroid/graphics/Bitmap;
HSPLandroid/view/View;->getDrawingRect(Landroid/graphics/Rect;)V
@@ -17156,16 +17232,16 @@ HSPLandroid/view/View;->getImportantForContentCapture()I
HSPLandroid/view/View;->getInverseMatrix()Landroid/graphics/Matrix;
HSPLandroid/view/View;->getKeyDispatcherState()Landroid/view/KeyEvent$DispatcherState;
HSPLandroid/view/View;->getLayerType()I
-HSPLandroid/view/View;->getLayoutDirection()I+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getLayoutDirection()I+]Landroid/view/View;missing_types]Landroid/content/Context;missing_types
HSPLandroid/view/View;->getLayoutParams()Landroid/view/ViewGroup$LayoutParams;
HSPLandroid/view/View;->getLeft()I
HSPLandroid/view/View;->getListenerInfo()Landroid/view/View$ListenerInfo;
HSPLandroid/view/View;->getLocalVisibleRect(Landroid/graphics/Rect;)Z
HSPLandroid/view/View;->getLocationInSurface([I)V
-HSPLandroid/view/View;->getLocationInWindow([I)V
+HSPLandroid/view/View;->getLocationInWindow([I)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->getLocationOnScreen()[I
-HSPLandroid/view/View;->getLocationOnScreen([I)V
-HSPLandroid/view/View;->getMatrix()Landroid/graphics/Matrix;
+HSPLandroid/view/View;->getLocationOnScreen([I)V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->getMatrix()Landroid/graphics/Matrix;+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->getMeasuredHeight()I
HSPLandroid/view/View;->getMeasuredState()I
HSPLandroid/view/View;->getMeasuredWidth()I
@@ -17177,9 +17253,9 @@ HSPLandroid/view/View;->getOutlineProvider()Landroid/view/ViewOutlineProvider;
HSPLandroid/view/View;->getOverScrollMode()I
HSPLandroid/view/View;->getPaddingBottom()I
HSPLandroid/view/View;->getPaddingEnd()I
-HSPLandroid/view/View;->getPaddingLeft()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getPaddingLeft()I
HSPLandroid/view/View;->getPaddingRight()I
-HSPLandroid/view/View;->getPaddingStart()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getPaddingStart()I
HSPLandroid/view/View;->getPaddingTop()I
HSPLandroid/view/View;->getParent()Landroid/view/ViewParent;
HSPLandroid/view/View;->getPivotX()F
@@ -17197,8 +17273,8 @@ HSPLandroid/view/View;->getRotation()F
HSPLandroid/view/View;->getRotationX()F
HSPLandroid/view/View;->getRotationY()F
HSPLandroid/view/View;->getRunQueue()Landroid/view/HandlerActionQueue;
-HSPLandroid/view/View;->getScaleX()F
-HSPLandroid/view/View;->getScaleY()F
+HSPLandroid/view/View;->getScaleX()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->getScaleY()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->getScrollX()I
HSPLandroid/view/View;->getScrollY()I
HSPLandroid/view/View;->getSolidColor()I
@@ -17217,7 +17293,7 @@ HSPLandroid/view/View;->getTop()I
HSPLandroid/view/View;->getTransitionAlpha()F
HSPLandroid/view/View;->getTransitionName()Ljava/lang/String;
HSPLandroid/view/View;->getTranslationX()F
-HSPLandroid/view/View;->getTranslationY()F
+HSPLandroid/view/View;->getTranslationY()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->getTranslationZ()F
HSPLandroid/view/View;->getVerticalFadingEdgeLength()I
HSPLandroid/view/View;->getVerticalScrollbarWidth()I+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
@@ -17228,11 +17304,11 @@ HSPLandroid/view/View;->getVisibility()I
HSPLandroid/view/View;->getWidth()I
HSPLandroid/view/View;->getWindowAttachCount()I
HSPLandroid/view/View;->getWindowId()Landroid/view/WindowId;
-HSPLandroid/view/View;->getWindowInsetsController()Landroid/view/WindowInsetsController;
+HSPLandroid/view/View;->getWindowInsetsController()Landroid/view/WindowInsetsController;+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/View;->getWindowSystemUiVisibility()I
HSPLandroid/view/View;->getWindowToken()Landroid/os/IBinder;
HSPLandroid/view/View;->getWindowVisibility()I
-HSPLandroid/view/View;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V
HSPLandroid/view/View;->getX()F
HSPLandroid/view/View;->getY()F
HSPLandroid/view/View;->getZ()F
@@ -17250,7 +17326,7 @@ HSPLandroid/view/View;->hasListenersForAccessibility()Z
HSPLandroid/view/View;->hasNestedScrollingParent()Z
HSPLandroid/view/View;->hasOnClickListeners()Z
HSPLandroid/view/View;->hasOverlappingRendering()Z
-HSPLandroid/view/View;->hasRtlSupport()Z+]Landroid/content/Context;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;
+HSPLandroid/view/View;->hasRtlSupport()Z
HSPLandroid/view/View;->hasSize()Z
HSPLandroid/view/View;->hasTransientState()Z
HSPLandroid/view/View;->hasTranslationTransientState()Z
@@ -17263,22 +17339,22 @@ HSPLandroid/view/View;->includeForAccessibility()Z
HSPLandroid/view/View;->includeForAccessibility(Z)Z
HSPLandroid/view/View;->inflate(Landroid/content/Context;ILandroid/view/ViewGroup;)Landroid/view/View;
HSPLandroid/view/View;->initScrollCache()V
-HSPLandroid/view/View;->initialAwakenScrollBars()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->initialAwakenScrollBars()Z+]Landroid/view/View;Landroid/widget/ScrollView;
HSPLandroid/view/View;->initializeFadingEdgeInternal(Landroid/content/res/TypedArray;)V
HSPLandroid/view/View;->initializeScrollIndicatorsInternal()V
HSPLandroid/view/View;->initializeScrollbarsInternal(Landroid/content/res/TypedArray;)V
-HSPLandroid/view/View;->internalSetPadding(IIII)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidate()V
+HSPLandroid/view/View;->internalSetPadding(IIII)V
+HSPLandroid/view/View;->invalidate()V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->invalidate(IIII)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidate(Landroid/graphics/Rect;)V
+HSPLandroid/view/View;->invalidate(Landroid/graphics/Rect;)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->invalidate(Z)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidateInternal(IIIIZZ)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
-HSPLandroid/view/View;->invalidateOutline()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/View;missing_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->invalidateInternal(IIIIZZ)V+]Landroid/view/View;megamorphic_types]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewParent;missing_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->invalidateOutline()V
HSPLandroid/view/View;->invalidateParentCaches()V
HSPLandroid/view/View;->invalidateParentIfNeeded()V
HSPLandroid/view/View;->invalidateParentIfNeededAndWasQuickRejected()V
-HSPLandroid/view/View;->invalidateViewProperty(ZZ)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->invalidateViewProperty(ZZ)V
HSPLandroid/view/View;->isAccessibilityFocused()Z
HSPLandroid/view/View;->isAccessibilityFocusedViewOrHost()Z
HSPLandroid/view/View;->isAccessibilityPane()Z
@@ -17313,7 +17389,7 @@ HSPLandroid/view/View;->isInScrollingContainer()Z
HSPLandroid/view/View;->isInTouchMode()Z
HSPLandroid/view/View;->isKeyboardNavigationCluster()Z
HSPLandroid/view/View;->isLaidOut()Z
-HSPLandroid/view/View;->isLayoutDirectionInherited()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->isLayoutDirectionInherited()Z
HSPLandroid/view/View;->isLayoutDirectionResolved()Z
HSPLandroid/view/View;->isLayoutModeOptical(Ljava/lang/Object;)Z+]Landroid/view/ViewGroup;missing_types
HSPLandroid/view/View;->isLayoutRequested()Z
@@ -17326,7 +17402,7 @@ HSPLandroid/view/View;->isPaddingResolved()Z
HSPLandroid/view/View;->isPressed()Z
HSPLandroid/view/View;->isProjectionReceiver()Z
HSPLandroid/view/View;->isRootNamespace()Z
-HSPLandroid/view/View;->isRtlCompatibilityMode()Z+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->isRtlCompatibilityMode()Z
HSPLandroid/view/View;->isSelected()Z
HSPLandroid/view/View;->isShowingLayoutBounds()Z
HSPLandroid/view/View;->isShown()Z
@@ -17342,44 +17418,44 @@ HSPLandroid/view/View;->isVerticalScrollBarHidden()Z
HSPLandroid/view/View;->isViewIdGenerated(I)Z
HSPLandroid/view/View;->isVisibleToUser()Z
HSPLandroid/view/View;->isVisibleToUser(Landroid/graphics/Rect;)Z
-HSPLandroid/view/View;->jumpDrawablesToCurrentState()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/view/View;->layout(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->jumpDrawablesToCurrentState()V
+HSPLandroid/view/View;->layout(IIII)V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/View;->makeFrameworkOptionalFitsSystemWindows()V
HSPLandroid/view/View;->makeOptionalFitsSystemWindows()V
HSPLandroid/view/View;->mapRectFromViewToScreenCoords(Landroid/graphics/RectF;Z)V
HSPLandroid/view/View;->mapRectFromViewToWindowCoords(Landroid/graphics/RectF;Z)V
-HSPLandroid/view/View;->measure(II)V+]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->measure(II)V+]Landroid/view/View;megamorphic_types]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;
HSPLandroid/view/View;->mergeDrawableStates([I[I)[I
HSPLandroid/view/View;->needGlobalAttributesUpdate(Z)V
HSPLandroid/view/View;->needRtlPropertiesResolution()Z
HSPLandroid/view/View;->notifyAppearedOrDisappearedForContentCaptureIfNeeded(Z)V
HSPLandroid/view/View;->notifyAutofillManagerOnClick()V
-HSPLandroid/view/View;->notifyEnterOrExitForAutoFillIfNeeded(Z)V+]Landroid/view/View;missing_types]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/View;->notifyEnterOrExitForAutoFillIfNeeded(Z)V
HSPLandroid/view/View;->notifyGlobalFocusCleared(Landroid/view/View;)V
HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedByParentIfNeeded()V
-HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedIfNeeded()V+]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
-HSPLandroid/view/View;->notifyViewAccessibilityStateChangedIfNeeded(I)V+]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
+HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedIfNeeded()V
+HSPLandroid/view/View;->notifyViewAccessibilityStateChangedIfNeeded(I)V
HSPLandroid/view/View;->offsetLeftAndRight(I)V
HSPLandroid/view/View;->offsetTopAndBottom(I)V
HSPLandroid/view/View;->onAnimationEnd()V
HSPLandroid/view/View;->onAnimationStart()V
HSPLandroid/view/View;->onApplyFrameworkOptionalFitSystemWindows(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
HSPLandroid/view/View;->onApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
-HSPLandroid/view/View;->onAttachedToWindow()V+]Landroid/view/View;missing_types]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;
-HSPLandroid/view/View;->onCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onAttachedToWindow()V+]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onCancelPendingInputEvents()V
HSPLandroid/view/View;->onCheckIsTextEditor()Z
HSPLandroid/view/View;->onCloseSystemDialogs(Ljava/lang/String;)V
HSPLandroid/view/View;->onConfigurationChanged(Landroid/content/res/Configuration;)V
HSPLandroid/view/View;->onCreateDrawableState(I)[I+]Landroid/view/View;missing_types
HSPLandroid/view/View;->onCreateInputConnection(Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection;
HSPLandroid/view/View;->onDetachedFromWindow()V
-HSPLandroid/view/View;->onDetachedFromWindowInternal()V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;
+HSPLandroid/view/View;->onDetachedFromWindowInternal()V+]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->onDraw(Landroid/graphics/Canvas;)V
HSPLandroid/view/View;->onDrawForeground(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->onDrawHorizontalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
-HSPLandroid/view/View;->onDrawScrollBars(Landroid/graphics/Canvas;)V
+HSPLandroid/view/View;->onDrawScrollBars(Landroid/graphics/Canvas;)V+]Landroid/graphics/Interpolator;Landroid/graphics/Interpolator;]Landroid/view/View;missing_types]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
HSPLandroid/view/View;->onDrawScrollIndicators(Landroid/graphics/Canvas;)V
-HSPLandroid/view/View;->onDrawVerticalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
+HSPLandroid/view/View;->onDrawVerticalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V+]Landroid/graphics/drawable/Drawable;Landroid/widget/ScrollBarDrawable;
HSPLandroid/view/View;->onFilterTouchEventForSecurity(Landroid/view/MotionEvent;)Z
HSPLandroid/view/View;->onFinishInflate()V
HSPLandroid/view/View;->onFinishTemporaryDetach()V
@@ -17389,7 +17465,7 @@ HSPLandroid/view/View;->onKeyDown(ILandroid/view/KeyEvent;)Z
HSPLandroid/view/View;->onKeyPreIme(ILandroid/view/KeyEvent;)Z
HSPLandroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z
HSPLandroid/view/View;->onLayout(ZIIII)V
-HSPLandroid/view/View;->onMeasure(II)V+]Landroid/view/View;Landroid/view/View;
+HSPLandroid/view/View;->onMeasure(II)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->onProvideAutofillStructure(Landroid/view/ViewStructure;I)V
HSPLandroid/view/View;->onProvideAutofillVirtualStructure(Landroid/view/ViewStructure;I)V
HSPLandroid/view/View;->onProvideContentCaptureStructure(Landroid/view/ViewStructure;I)V
@@ -17399,14 +17475,14 @@ HSPLandroid/view/View;->onRestoreInstanceState(Landroid/os/Parcelable;)V
HSPLandroid/view/View;->onRtlPropertiesChanged(I)V
HSPLandroid/view/View;->onSaveInstanceState()Landroid/os/Parcelable;
HSPLandroid/view/View;->onScreenStateChanged(I)V
-HSPLandroid/view/View;->onScrollChanged(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onScrollChanged(IIII)V
HSPLandroid/view/View;->onSetAlpha(I)Z
HSPLandroid/view/View;->onSizeChanged(IIII)V
HSPLandroid/view/View;->onStartTemporaryDetach()V
HSPLandroid/view/View;->onTouchEvent(Landroid/view/MotionEvent;)Z
-HSPLandroid/view/View;->onVisibilityAggregated(Z)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/view/View;->onVisibilityAggregated(Z)V+]Landroid/view/View;megamorphic_types]Ljava/util/List;Ljava/util/Collections$EmptyList;,Ljava/util/ArrayList;]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/view/View;->onVisibilityChanged(Landroid/view/View;I)V
-HSPLandroid/view/View;->onWindowFocusChanged(Z)V+]Landroid/view/View;megamorphic_types
+HSPLandroid/view/View;->onWindowFocusChanged(Z)V
HSPLandroid/view/View;->onWindowSystemUiVisibilityChanged(I)V
HSPLandroid/view/View;->onWindowVisibilityChanged(I)V
HSPLandroid/view/View;->overScrollBy(IIIIIIIIZ)Z
@@ -17430,9 +17506,9 @@ HSPLandroid/view/View;->postOnAnimation(Ljava/lang/Runnable;)V
HSPLandroid/view/View;->postOnAnimationDelayed(Ljava/lang/Runnable;J)V
HSPLandroid/view/View;->postSendViewScrolledAccessibilityEventCallback(II)V
HSPLandroid/view/View;->postUpdate(Ljava/lang/Runnable;)V
-HSPLandroid/view/View;->rebuildOutline()V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/ViewOutlineProvider;missing_types
+HSPLandroid/view/View;->rebuildOutline()V+]Landroid/view/ViewOutlineProvider;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/Outline;Landroid/graphics/Outline;
HSPLandroid/view/View;->recomputePadding()V
-HSPLandroid/view/View;->refreshDrawableState()V+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->refreshDrawableState()V
HSPLandroid/view/View;->registerPendingFrameMetricsObservers()V
HSPLandroid/view/View;->removeCallbacks(Ljava/lang/Runnable;)Z
HSPLandroid/view/View;->removeFrameMetricsListener(Landroid/view/Window$OnFrameMetricsAvailableListener;)V
@@ -17448,30 +17524,30 @@ HSPLandroid/view/View;->requestFocus()Z
HSPLandroid/view/View;->requestFocus(I)Z
HSPLandroid/view/View;->requestFocus(ILandroid/graphics/Rect;)Z
HSPLandroid/view/View;->requestFocusNoSearch(ILandroid/graphics/Rect;)Z
-HSPLandroid/view/View;->requestLayout()V+]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->requestLayout()V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/ViewParent;missing_types
HSPLandroid/view/View;->requestRectangleOnScreen(Landroid/graphics/Rect;)Z
HSPLandroid/view/View;->requestRectangleOnScreen(Landroid/graphics/Rect;Z)Z
HSPLandroid/view/View;->requireViewById(I)Landroid/view/View;
-HSPLandroid/view/View;->resetDisplayList()V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->resetDisplayList()V
HSPLandroid/view/View;->resetPressedState()V
-HSPLandroid/view/View;->resetResolvedDrawables()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetResolvedDrawables()V
HSPLandroid/view/View;->resetResolvedDrawablesInternal()V
HSPLandroid/view/View;->resetResolvedLayoutDirection()V
-HSPLandroid/view/View;->resetResolvedPadding()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetResolvedPadding()V
HSPLandroid/view/View;->resetResolvedPaddingInternal()V
HSPLandroid/view/View;->resetResolvedTextAlignment()V
HSPLandroid/view/View;->resetResolvedTextDirection()V
-HSPLandroid/view/View;->resetRtlProperties()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetRtlProperties()V
HSPLandroid/view/View;->resetSubtreeAccessibilityStateChanged()V
-HSPLandroid/view/View;->resolveDrawables()V+]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/view/View;missing_types
-HSPLandroid/view/View;->resolveLayoutDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->resolveDrawables()V
+HSPLandroid/view/View;->resolveLayoutDirection()Z
HSPLandroid/view/View;->resolveLayoutParams()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup$LayoutParams;missing_types
-HSPLandroid/view/View;->resolvePadding()V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
+HSPLandroid/view/View;->resolvePadding()V+]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/ColorDrawable;
HSPLandroid/view/View;->resolveRtlPropertiesIfNeeded()Z+]Landroid/view/View;missing_types
HSPLandroid/view/View;->resolveSize(II)I
HSPLandroid/view/View;->resolveSizeAndState(III)I
-HSPLandroid/view/View;->resolveTextAlignment()Z+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->resolveTextDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->resolveTextAlignment()Z
+HSPLandroid/view/View;->resolveTextDirection()Z
HSPLandroid/view/View;->restoreHierarchyState(Landroid/util/SparseArray;)V
HSPLandroid/view/View;->retrieveExplicitStyle(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;)V
HSPLandroid/view/View;->rootViewRequestFocus()Z
@@ -17493,53 +17569,53 @@ HSPLandroid/view/View;->setAccessibilityTraversalBefore(I)V
HSPLandroid/view/View;->setActivated(Z)V
HSPLandroid/view/View;->setAlpha(F)V
HSPLandroid/view/View;->setAlphaInternal(F)V
-HSPLandroid/view/View;->setAlphaNoInvalidation(F)Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setAlphaNoInvalidation(F)Z
HSPLandroid/view/View;->setAnimation(Landroid/view/animation/Animation;)V
HSPLandroid/view/View;->setAutoHandwritingEnabled(Z)V
HSPLandroid/view/View;->setAutofilled(ZZ)V
HSPLandroid/view/View;->setBackground(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/view/View;->setBackgroundBounds()V+]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/view/View;->setBackgroundColor(I)V
-HSPLandroid/view/View;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
+HSPLandroid/view/View;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/ColorDrawable;
HSPLandroid/view/View;->setBackgroundRenderNodeProperties(Landroid/graphics/RenderNode;)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->setBackgroundResource(I)V
HSPLandroid/view/View;->setBackgroundTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/view/View;->setBottom(I)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setBottom(I)V
HSPLandroid/view/View;->setClickable(Z)V
HSPLandroid/view/View;->setClipBounds(Landroid/graphics/Rect;)V
HSPLandroid/view/View;->setClipToOutline(Z)V
HSPLandroid/view/View;->setContentDescription(Ljava/lang/CharSequence;)V
HSPLandroid/view/View;->setDefaultFocusHighlightEnabled(Z)V
HSPLandroid/view/View;->setDetached(Z)V
-HSPLandroid/view/View;->setDisplayListProperties(Landroid/graphics/RenderNode;)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setDisplayListProperties(Landroid/graphics/RenderNode;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->setDrawingCacheEnabled(Z)V
HSPLandroid/view/View;->setElevation(F)V
HSPLandroid/view/View;->setEnabled(Z)V
HSPLandroid/view/View;->setFitsSystemWindows(Z)V
-HSPLandroid/view/View;->setFlags(II)V+]Landroid/view/View;megamorphic_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewParent;missing_types]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
+HSPLandroid/view/View;->setFlags(II)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/view/ViewParent;missing_types
HSPLandroid/view/View;->setFocusable(I)V
HSPLandroid/view/View;->setFocusable(Z)V
HSPLandroid/view/View;->setFocusableInTouchMode(Z)V
HSPLandroid/view/View;->setForeground(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/view/View;->setForegroundGravity(I)V
-HSPLandroid/view/View;->setFrame(IIII)Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setFrame(IIII)Z+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->setHandwritingArea(Landroid/graphics/Rect;)V
HSPLandroid/view/View;->setHapticFeedbackEnabled(Z)V
HSPLandroid/view/View;->setHasTransientState(Z)V
HSPLandroid/view/View;->setHorizontalFadingEdgeEnabled(Z)V
HSPLandroid/view/View;->setHorizontalScrollBarEnabled(Z)V
HSPLandroid/view/View;->setId(I)V
-HSPLandroid/view/View;->setImportantForAccessibility(I)V+]Landroid/view/View;megamorphic_types
+HSPLandroid/view/View;->setImportantForAccessibility(I)V
HSPLandroid/view/View;->setImportantForAutofill(I)V
HSPLandroid/view/View;->setImportantForContentCapture(I)V
HSPLandroid/view/View;->setIsRootNamespace(Z)V
HSPLandroid/view/View;->setKeepScreenOn(Z)V
HSPLandroid/view/View;->setKeyboardNavigationCluster(Z)V
-HSPLandroid/view/View;->setKeyedTag(ILjava/lang/Object;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/View;->setKeyedTag(ILjava/lang/Object;)V
HSPLandroid/view/View;->setLayerPaint(Landroid/graphics/Paint;)V
HSPLandroid/view/View;->setLayerType(ILandroid/graphics/Paint;)V
HSPLandroid/view/View;->setLayoutDirection(I)V
-HSPLandroid/view/View;->setLayoutParams(Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/View;->setLayoutParams(Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Lcom/android/internal/policy/DecorView;
HSPLandroid/view/View;->setLeft(I)V
HSPLandroid/view/View;->setLeftTopRightBottom(IIII)V
HSPLandroid/view/View;->setLongClickable(Z)V
@@ -17564,21 +17640,21 @@ HSPLandroid/view/View;->setOutlineProvider(Landroid/view/ViewOutlineProvider;)V
HSPLandroid/view/View;->setOutlineProviderFromAttribute(I)V
HSPLandroid/view/View;->setOutlineSpotShadowColor(I)V
HSPLandroid/view/View;->setOverScrollMode(I)V
-HSPLandroid/view/View;->setPadding(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setPadding(IIII)V
HSPLandroid/view/View;->setPaddingRelative(IIII)V
HSPLandroid/view/View;->setPivotX(F)V
HSPLandroid/view/View;->setPivotY(F)V
HSPLandroid/view/View;->setPointerIcon(Landroid/view/PointerIcon;)V
HSPLandroid/view/View;->setPressed(Z)V
HSPLandroid/view/View;->setRenderEffect(Landroid/graphics/RenderEffect;)V
-HSPLandroid/view/View;->setRight(I)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setRight(I)V
HSPLandroid/view/View;->setRotation(F)V
HSPLandroid/view/View;->setRotationX(F)V
HSPLandroid/view/View;->setRotationY(F)V
HSPLandroid/view/View;->setSaveEnabled(Z)V
HSPLandroid/view/View;->setSaveFromParentEnabled(Z)V
-HSPLandroid/view/View;->setScaleX(F)V
-HSPLandroid/view/View;->setScaleY(F)V
+HSPLandroid/view/View;->setScaleX(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setScaleY(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->setScrollContainer(Z)V
HSPLandroid/view/View;->setScrollIndicators(II)V
HSPLandroid/view/View;->setScrollX(I)V
@@ -17601,40 +17677,41 @@ HSPLandroid/view/View;->setTransitionName(Ljava/lang/String;)V
HSPLandroid/view/View;->setTransitionVisibility(I)V
HSPLandroid/view/View;->setTranslationX(F)V
HSPLandroid/view/View;->setTranslationY(F)V
-HSPLandroid/view/View;->setTranslationZ(F)V
+HSPLandroid/view/View;->setTranslationZ(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->setVerticalScrollBarEnabled(Z)V
-HSPLandroid/view/View;->setVisibility(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setVisibility(I)V
HSPLandroid/view/View;->setWillNotDraw(Z)V
HSPLandroid/view/View;->setX(F)V
HSPLandroid/view/View;->setY(F)V
-HSPLandroid/view/View;->shouldDrawRoundScrollbar()Z+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/Resources;Landroid/content/res/Resources;
-HSPLandroid/view/View;->sizeChange(IIII)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/View;->shouldDrawRoundScrollbar()Z+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;
+HSPLandroid/view/View;->sizeChange(IIII)V
HSPLandroid/view/View;->skipInvalidate()Z+]Landroid/view/ViewGroup;missing_types
HSPLandroid/view/View;->startAnimation(Landroid/view/animation/Animation;)V
HSPLandroid/view/View;->startNestedScroll(I)Z
HSPLandroid/view/View;->stopNestedScroll()V
HSPLandroid/view/View;->switchDefaultFocusHighlight()V
HSPLandroid/view/View;->toString()Ljava/lang/String;
-HSPLandroid/view/View;->transformFromViewToWindowSpace([I)V
+HSPLandroid/view/View;->transformFromViewToWindowSpace([I)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->unFocus(Landroid/view/View;)V
-HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
+HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;Ljava/lang/Runnable;)V
-HSPLandroid/view/View;->updateDisplayListIfDirty()Landroid/graphics/RenderNode;+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/view/ViewOverlay$OverlayViewGroup;]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/View;->updateDisplayListIfDirty()Landroid/graphics/RenderNode;+]Landroid/view/View;megamorphic_types]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->updateFocusedInCluster(Landroid/view/View;I)V
HSPLandroid/view/View;->updateHandwritingArea()V
HSPLandroid/view/View;->updateKeepClearRects()V
HSPLandroid/view/View;->updateLocalSystemUiVisibility(II)Z
HSPLandroid/view/View;->updatePflags3AndNotifyA11yIfChanged(IZ)V
-HSPLandroid/view/View;->updatePositionUpdateListener()V+]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/view/View;->updatePositionUpdateListener()V
HSPLandroid/view/View;->updatePreferKeepClearForFocus()V
HSPLandroid/view/View;->updateSystemGestureExclusionRects()V
HSPLandroid/view/View;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
HSPLandroid/view/View;->willNotDraw()Z
HSPLandroid/view/ViewAnimationHostBridge;-><init>(Landroid/view/View;)V
HSPLandroid/view/ViewAnimationHostBridge;->isAttached()Z
+HSPLandroid/view/ViewAnimationHostBridge;->registerAnimatingRenderNode(Landroid/graphics/RenderNode;)V
HSPLandroid/view/ViewAnimationHostBridge;->registerVectorDrawableAnimator(Landroid/view/NativeVectorDrawableAnimator;)V
HSPLandroid/view/ViewConfiguration;-><init>(Landroid/content/Context;)V
-HSPLandroid/view/ViewConfiguration;->get(Landroid/content/Context;)Landroid/view/ViewConfiguration;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/ViewConfiguration;->get(Landroid/content/Context;)Landroid/view/ViewConfiguration;
HSPLandroid/view/ViewConfiguration;->getDoubleTapTimeout()I
HSPLandroid/view/ViewConfiguration;->getLongPressTimeout()I
HSPLandroid/view/ViewConfiguration;->getPressedStateDuration()I
@@ -17681,9 +17758,9 @@ HSPLandroid/view/ViewGroup$LayoutParams;-><init>(II)V
HSPLandroid/view/ViewGroup$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/view/ViewGroup$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup$LayoutParams;->resolveLayoutDirection(I)V
-HSPLandroid/view/ViewGroup$LayoutParams;->setBaseAttributes(Landroid/content/res/TypedArray;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/view/ViewGroup$LayoutParams;->setBaseAttributes(Landroid/content/res/TypedArray;II)V
HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(II)V
-HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/ViewGroup$MarginLayoutParams;missing_types
+HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/view/ViewGroup$MarginLayoutParams;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/view/ViewGroup$MarginLayoutParams;)V
HSPLandroid/view/ViewGroup$MarginLayoutParams;->doResolveMargins()V
@@ -17709,12 +17786,12 @@ HSPLandroid/view/ViewGroup;->addTouchTarget(Landroid/view/View;I)Landroid/view/V
HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;I)V
HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;II)V
-HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup;->addViewInLayout(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)Z
HSPLandroid/view/ViewGroup;->addViewInLayout(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)Z
-HSPLandroid/view/ViewGroup;->addViewInner(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)V+]Landroid/animation/LayoutTransition;Landroid/animation/LayoutTransition;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->attachViewToParent(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->addViewInner(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->attachViewToParent(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup;->bringChildToFront(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->buildOrderedChildList()Ljava/util/ArrayList;
HSPLandroid/view/ViewGroup;->buildTouchDispatchChildList()Ljava/util/ArrayList;
@@ -17731,20 +17808,20 @@ HSPLandroid/view/ViewGroup;->clearDisappearingChildren()V
HSPLandroid/view/ViewGroup;->clearFocus()V
HSPLandroid/view/ViewGroup;->clearFocusedInCluster()V
HSPLandroid/view/ViewGroup;->clearTouchTargets()V
-HSPLandroid/view/ViewGroup;->destroyHardwareResources()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->destroyHardwareResources()V
HSPLandroid/view/ViewGroup;->detachAllViewsFromParent()V
HSPLandroid/view/ViewGroup;->detachViewFromParent(I)V
HSPLandroid/view/ViewGroup;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
-HSPLandroid/view/ViewGroup;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->dispatchCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V
+HSPLandroid/view/ViewGroup;->dispatchCancelPendingInputEvents()V
HSPLandroid/view/ViewGroup;->dispatchCollectViewAttributes(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types
HSPLandroid/view/ViewGroup;->dispatchConfigurationChanged(Landroid/content/res/Configuration;)V
HSPLandroid/view/ViewGroup;->dispatchDetachedFromWindow()V
-HSPLandroid/view/ViewGroup;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/animation/LayoutAnimationController;Landroid/view/animation/LayoutAnimationController;
+HSPLandroid/view/ViewGroup;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/view/ViewGroup;->dispatchDrawableHotspotChanged(FF)V
HSPLandroid/view/ViewGroup;->dispatchFinishTemporaryDetach()V
HSPLandroid/view/ViewGroup;->dispatchFreezeSelfOnly(Landroid/util/SparseArray;)V
-HSPLandroid/view/ViewGroup;->dispatchGetDisplayList()V+]Landroid/view/View;missing_types]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/ViewGroup;->dispatchGetDisplayList()V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewGroup;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
HSPLandroid/view/ViewGroup;->dispatchKeyEventPreIme(Landroid/view/KeyEvent;)Z
HSPLandroid/view/ViewGroup;->dispatchProvideAutofillStructure(Landroid/view/ViewStructure;I)V
@@ -17758,17 +17835,17 @@ HSPLandroid/view/ViewGroup;->dispatchSetSelected(Z)V
HSPLandroid/view/ViewGroup;->dispatchStartTemporaryDetach()V
HSPLandroid/view/ViewGroup;->dispatchSystemUiVisibilityChanged(I)V
HSPLandroid/view/ViewGroup;->dispatchThawSelfOnly(Landroid/util/SparseArray;)V
-HSPLandroid/view/ViewGroup;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/ViewGroup;->dispatchTransformedTouchEvent(Landroid/view/MotionEvent;ZLandroid/view/View;I)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/ViewGroup$TouchTarget;Landroid/view/ViewGroup$TouchTarget;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
+HSPLandroid/view/ViewGroup;->dispatchTransformedTouchEvent(Landroid/view/MotionEvent;ZLandroid/view/View;I)Z+]Landroid/view/View;missing_types]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/view/ViewGroup;->dispatchUnhandledKeyEvent(Landroid/view/KeyEvent;)Landroid/view/View;
-HSPLandroid/view/ViewGroup;->dispatchViewAdded(Landroid/view/View;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->dispatchViewAdded(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->dispatchViewRemoved(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->dispatchVisibilityAggregated(Z)Z+]Landroid/view/View;missing_types
-HSPLandroid/view/ViewGroup;->dispatchVisibilityChanged(Landroid/view/View;I)V+]Landroid/view/View;missing_types
-HSPLandroid/view/ViewGroup;->dispatchWindowFocusChanged(Z)V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchVisibilityChanged(Landroid/view/View;I)V
+HSPLandroid/view/ViewGroup;->dispatchWindowFocusChanged(Z)V
HSPLandroid/view/ViewGroup;->dispatchWindowInsetsAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
HSPLandroid/view/ViewGroup;->dispatchWindowSystemUiVisiblityChanged(I)V
-HSPLandroid/view/ViewGroup;->dispatchWindowVisibilityChanged(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchWindowVisibilityChanged(I)V
HSPLandroid/view/ViewGroup;->drawChild(Landroid/graphics/Canvas;Landroid/view/View;J)Z+]Landroid/view/View;missing_types
HSPLandroid/view/ViewGroup;->drawableStateChanged()V
HSPLandroid/view/ViewGroup;->endViewTransition(Landroid/view/View;)V
@@ -17778,7 +17855,7 @@ HSPLandroid/view/ViewGroup;->findFocus()Landroid/view/View;
HSPLandroid/view/ViewGroup;->findOnBackInvokedDispatcherForChild(Landroid/view/View;Landroid/view/View;)Landroid/window/OnBackInvokedDispatcher;
HSPLandroid/view/ViewGroup;->findViewByAutofillIdTraversal(I)Landroid/view/View;
HSPLandroid/view/ViewGroup;->findViewByPredicateTraversal(Ljava/util/function/Predicate;Landroid/view/View;)Landroid/view/View;
-HSPLandroid/view/ViewGroup;->findViewTraversal(I)Landroid/view/View;+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->findViewTraversal(I)Landroid/view/View;
HSPLandroid/view/ViewGroup;->findViewWithTagTraversal(Ljava/lang/Object;)Landroid/view/View;
HSPLandroid/view/ViewGroup;->finishAnimatingView(Landroid/view/View;Landroid/view/animation/Animation;)V
HSPLandroid/view/ViewGroup;->focusSearch(Landroid/view/View;I)Landroid/view/View;
@@ -17794,7 +17871,7 @@ HSPLandroid/view/ViewGroup;->getChildCount()I
HSPLandroid/view/ViewGroup;->getChildMeasureSpec(III)I
HSPLandroid/view/ViewGroup;->getChildTransformation()Landroid/view/animation/Transformation;
HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
-HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewParent;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;Z)Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewParent;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewGroup;->getChildrenForAutofill(I)Landroid/view/ViewGroup$ChildListForAutoFillOrContentCapture;
HSPLandroid/view/ViewGroup;->getChildrenForContentCapture()Landroid/view/ViewGroup$ChildListForAutoFillOrContentCapture;
HSPLandroid/view/ViewGroup;->getClipChildren()Z
@@ -17820,8 +17897,8 @@ HSPLandroid/view/ViewGroup;->hasTransientState()Z
HSPLandroid/view/ViewGroup;->hasUnhandledKeyListener()Z
HSPLandroid/view/ViewGroup;->hasWindowInsetsAnimationCallback()Z
HSPLandroid/view/ViewGroup;->indexOfChild(Landroid/view/View;)I
-HSPLandroid/view/ViewGroup;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->initViewGroup()V+]Landroid/content/Context;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V
+HSPLandroid/view/ViewGroup;->initViewGroup()V
HSPLandroid/view/ViewGroup;->internalSetPadding(IIII)V
HSPLandroid/view/ViewGroup;->invalidateChild(Landroid/view/View;Landroid/graphics/Rect;)V+]Landroid/view/ViewGroup;missing_types
HSPLandroid/view/ViewGroup;->invalidateChildInParent([ILandroid/graphics/Rect;)Landroid/view/ViewParent;
@@ -17830,7 +17907,7 @@ HSPLandroid/view/ViewGroup;->isLayoutModeOptical()Z
HSPLandroid/view/ViewGroup;->isLayoutSuppressed()Z
HSPLandroid/view/ViewGroup;->isTransformedTouchPointInView(FFLandroid/view/View;Landroid/graphics/PointF;)Z
HSPLandroid/view/ViewGroup;->isViewTransitioning(Landroid/view/View;)Z
-HSPLandroid/view/ViewGroup;->jumpDrawablesToCurrentState()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->jumpDrawablesToCurrentState()V
HSPLandroid/view/ViewGroup;->layout(IIII)V
HSPLandroid/view/ViewGroup;->makeFrameworkOptionalFitsSystemWindows()V
HSPLandroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V
@@ -17847,9 +17924,9 @@ HSPLandroid/view/ViewGroup;->onCreateDrawableState(I)[I
HSPLandroid/view/ViewGroup;->onDescendantInvalidated(Landroid/view/View;Landroid/view/View;)V+]Landroid/view/ViewParent;missing_types
HSPLandroid/view/ViewGroup;->onDescendantUnbufferedRequested()V
HSPLandroid/view/ViewGroup;->onDetachedFromWindow()V
-HSPLandroid/view/ViewGroup;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z
+HSPLandroid/view/ViewGroup;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/view/ViewGroup;->onRequestFocusInDescendants(ILandroid/graphics/Rect;)Z
-HSPLandroid/view/ViewGroup;->onSetLayoutParams(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->onSetLayoutParams(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup;->onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z
HSPLandroid/view/ViewGroup;->onViewAdded(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->onViewRemoved(Landroid/view/View;)V
@@ -17870,22 +17947,22 @@ HSPLandroid/view/ViewGroup;->removeViewInternal(ILandroid/view/View;)V
HSPLandroid/view/ViewGroup;->removeViewInternal(Landroid/view/View;)Z
HSPLandroid/view/ViewGroup;->requestChildFocus(Landroid/view/View;Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->requestChildRectangleOnScreen(Landroid/view/View;Landroid/graphics/Rect;Z)Z
-HSPLandroid/view/ViewGroup;->requestDisallowInterceptTouchEvent(Z)V
+HSPLandroid/view/ViewGroup;->requestDisallowInterceptTouchEvent(Z)V+]Landroid/view/ViewParent;missing_types
HSPLandroid/view/ViewGroup;->requestFocus(ILandroid/graphics/Rect;)Z
HSPLandroid/view/ViewGroup;->requestTransitionStart(Landroid/animation/LayoutTransition;)V
HSPLandroid/view/ViewGroup;->requestTransparentRegion(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->resetCancelNextUpFlag(Landroid/view/View;)Z
-HSPLandroid/view/ViewGroup;->resetResolvedDrawables()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedLayoutDirection()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedPadding()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedTextAlignment()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedTextDirection()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetSubtreeAccessibilityStateChanged()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->resetResolvedDrawables()V
+HSPLandroid/view/ViewGroup;->resetResolvedLayoutDirection()V
+HSPLandroid/view/ViewGroup;->resetResolvedPadding()V
+HSPLandroid/view/ViewGroup;->resetResolvedTextAlignment()V
+HSPLandroid/view/ViewGroup;->resetResolvedTextDirection()V
+HSPLandroid/view/ViewGroup;->resetSubtreeAccessibilityStateChanged()V
HSPLandroid/view/ViewGroup;->resetTouchState()V
HSPLandroid/view/ViewGroup;->resolveDrawables()V
HSPLandroid/view/ViewGroup;->resolveLayoutDirection()Z
HSPLandroid/view/ViewGroup;->resolveLayoutParams()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resolvePadding()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->resolvePadding()V
HSPLandroid/view/ViewGroup;->resolveRtlPropertiesIfNeeded()Z+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
HSPLandroid/view/ViewGroup;->resolveTextAlignment()Z
HSPLandroid/view/ViewGroup;->resolveTextDirection()Z
@@ -17906,7 +17983,7 @@ HSPLandroid/view/ViewGroup;->shouldBlockFocusForTouchscreen()Z
HSPLandroid/view/ViewGroup;->shouldDelayChildPressedState()Z
HSPLandroid/view/ViewGroup;->startViewTransition(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->suppressLayout(Z)V
-HSPLandroid/view/ViewGroup;->touchAccessibilityNodeProviderIfNeeded(Landroid/view/View;)V+]Landroid/content/Context;missing_types
+HSPLandroid/view/ViewGroup;->touchAccessibilityNodeProviderIfNeeded(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->transformPointToViewLocal([FLandroid/view/View;)V
HSPLandroid/view/ViewGroup;->unFocus(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->updateLocalSystemUiVisibility(II)Z
@@ -17938,7 +18015,7 @@ HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;-><init>(Landroid/vi
HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationCancel(Landroid/animation/Animator;)V
HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationStart(Landroid/animation/Animator;)V
-HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/view/View;Landroid/widget/LinearLayout;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
HSPLandroid/view/ViewPropertyAnimator$NameValuesHolder;-><init>(IFF)V
HSPLandroid/view/ViewPropertyAnimator$PropertyBundle;-><init>(ILjava/util/ArrayList;)V
HSPLandroid/view/ViewPropertyAnimator$PropertyBundle;->cancel(I)Z
@@ -17962,6 +18039,7 @@ HSPLandroid/view/ViewPropertyAnimator;->translationY(F)Landroid/view/ViewPropert
HSPLandroid/view/ViewPropertyAnimator;->withEndAction(Ljava/lang/Runnable;)Landroid/view/ViewPropertyAnimator;
HSPLandroid/view/ViewPropertyAnimator;->withLayer()Landroid/view/ViewPropertyAnimator;
HSPLandroid/view/ViewPropertyAnimator;->withStartAction(Ljava/lang/Runnable;)Landroid/view/ViewPropertyAnimator;
+HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda0;->run()V
HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda17;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda3;->run()V
HSPLandroid/view/ViewRootImpl$AccessibilityInteractionConnectionManager;-><init>(Landroid/view/ViewRootImpl;)V
@@ -17978,13 +18056,13 @@ HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;-><init>(Landroid/view/View
HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processKeyEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processMotionEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
-HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$HighContrastTextManager;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$ImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;Ljava/lang/String;)V
HSPLandroid/view/ViewRootImpl$ImeInputStage;->onFinishedInputEvent(Ljava/lang/Object;Z)V
HSPLandroid/view/ViewRootImpl$ImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$InputMetricsListener;-><init>(Landroid/view/ViewRootImpl;)V
-HSPLandroid/view/ViewRootImpl$InputMetricsListener;->onFrameMetricsAvailable(I)V
+HSPLandroid/view/ViewRootImpl$InputMetricsListener;->onFrameMetricsAvailable(I)V+]Landroid/view/ViewRootImpl$WindowInputEventReceiver;Landroid/view/ViewRootImpl$WindowInputEventReceiver;
HSPLandroid/view/ViewRootImpl$InputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;)V
HSPLandroid/view/ViewRootImpl$InputStage;->apply(Landroid/view/ViewRootImpl$QueuedInputEvent;I)V
HSPLandroid/view/ViewRootImpl$InputStage;->deliver(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
@@ -17993,12 +18071,12 @@ HSPLandroid/view/ViewRootImpl$InputStage;->forward(Landroid/view/ViewRootImpl$Qu
HSPLandroid/view/ViewRootImpl$InputStage;->onDeliverToNext(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
HSPLandroid/view/ViewRootImpl$InputStage;->onDetachedFromWindow()V
HSPLandroid/view/ViewRootImpl$InputStage;->onWindowFocusChanged(Z)V
-HSPLandroid/view/ViewRootImpl$InputStage;->shouldDropInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)Z+]Landroid/view/InputEvent;Landroid/view/MotionEvent;
-HSPLandroid/view/ViewRootImpl$InputStage;->traceEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;J)V+]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/view/ViewRootImpl$EarlyPostImeInputStage;,Landroid/view/ViewRootImpl$NativePostImeInputStage;,Landroid/view/ViewRootImpl$SyntheticInputStage;,Landroid/view/ViewRootImpl$ViewPostImeInputStage;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl$InputStage;->shouldDropInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)Z
+HSPLandroid/view/ViewRootImpl$InputStage;->traceEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;J)V
HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->addView(Landroid/view/View;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->postIfNeededLocked()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
-HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->removeView(Landroid/view/View;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->removeView(Landroid/view/View;)V
HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->run()V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewRootImpl$NativePostImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;Ljava/lang/String;)V
HSPLandroid/view/ViewRootImpl$NativePostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
@@ -18017,6 +18095,7 @@ HSPLandroid/view/ViewRootImpl$SyntheticJoystickHandler$JoystickAxesState;->reset
HSPLandroid/view/ViewRootImpl$SyntheticJoystickHandler;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$SyntheticJoystickHandler;->cancel()V
HSPLandroid/view/ViewRootImpl$SyntheticKeyboardHandler;-><init>(Landroid/view/ViewRootImpl;)V
+HSPLandroid/view/ViewRootImpl$SyntheticTouchNavigationHandler$1;-><init>(Landroid/view/ViewRootImpl$SyntheticTouchNavigationHandler;)V
HSPLandroid/view/ViewRootImpl$SyntheticTouchNavigationHandler;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$SyntheticTrackballHandler;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$SystemUiVisibilityInfo;-><init>()V
@@ -18033,7 +18112,7 @@ HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->maybeUpdatePointerIcon(Lan
HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->onDeliverToNext(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processKeyEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
-HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I+]Landroid/view/HandwritingInitiator;Landroid/view/HandwritingInitiator;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$ViewPreImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;)V
HSPLandroid/view/ViewRootImpl$ViewPreImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$ViewRootHandler;-><init>(Landroid/view/ViewRootImpl;)V
@@ -18045,6 +18124,7 @@ HSPLandroid/view/ViewRootImpl$W;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$W;->closeSystemDialogs(Ljava/lang/String;)V
HSPLandroid/view/ViewRootImpl$W;->dispatchAppVisibility(Z)V
HSPLandroid/view/ViewRootImpl$W;->dispatchWindowShown()V
+HSPLandroid/view/ViewRootImpl$W;->insetsControlChanged(Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
HSPLandroid/view/ViewRootImpl$W;->moved(II)V
HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;-><init>(Landroid/view/ViewRootImpl;Landroid/view/InputChannel;Landroid/os/Looper;)V
HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;->dispose()V
@@ -18053,27 +18133,29 @@ HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;->onFocusEvent(Z)V
HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;->onInputEvent(Landroid/view/InputEvent;)V
HSPLandroid/view/ViewRootImpl;->-$$Nest$fgetmBlastBufferQueue(Landroid/view/ViewRootImpl;)Landroid/graphics/BLASTBufferQueue;
HSPLandroid/view/ViewRootImpl;->-$$Nest$fputmProfileRendering(Landroid/view/ViewRootImpl;Z)V
+HSPLandroid/view/ViewRootImpl;->-$$Nest$mdispatchInsetsControlChanged(Landroid/view/ViewRootImpl;Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
HSPLandroid/view/ViewRootImpl;->-$$Nest$mprofileRendering(Landroid/view/ViewRootImpl;Z)V
HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;)V
-HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;Landroid/view/IWindowSession;Landroid/view/WindowLayout;)V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowLeaked;Landroid/view/WindowLeaked;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Optional;Ljava/util/Optional;
+HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;Landroid/view/IWindowSession;Landroid/view/WindowLayout;)V
HSPLandroid/view/ViewRootImpl;->addConfigCallback(Landroid/view/ViewRootImpl$ConfigChangedCallback;)V
-HSPLandroid/view/ViewRootImpl;->addFrameCommitCallbackIfNeeded()V
+HSPLandroid/view/ViewRootImpl;->addFrameCommitCallbackIfNeeded()V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->addSurfaceChangedCallback(Landroid/view/ViewRootImpl$SurfaceChangedCallback;)V
HSPLandroid/view/ViewRootImpl;->addWindowCallbacks(Landroid/view/WindowCallbacks;)V
+HSPLandroid/view/ViewRootImpl;->adjustLayoutParamsForCompatibility(Landroid/view/WindowManager$LayoutParams;)V
HSPLandroid/view/ViewRootImpl;->applyKeepScreenOnFlag(Landroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ViewRootImpl;->applyTransactionOnDraw(Landroid/view/SurfaceControl$Transaction;)Z
+HSPLandroid/view/ViewRootImpl;->applyTransactionOnDraw(Landroid/view/SurfaceControl$Transaction;)Z+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->canResolveTextDirection()Z
-HSPLandroid/view/ViewRootImpl;->cancelInvalidate(Landroid/view/View;)V+]Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;
+HSPLandroid/view/ViewRootImpl;->cancelInvalidate(Landroid/view/View;)V
HSPLandroid/view/ViewRootImpl;->checkForLeavingTouchModeAndConsume(Landroid/view/KeyEvent;)Z
HSPLandroid/view/ViewRootImpl;->checkThread()V
HSPLandroid/view/ViewRootImpl;->childDrawableStateChanged(Landroid/view/View;)V
HSPLandroid/view/ViewRootImpl;->childHasTransientStateChanged(Landroid/view/View;Z)V
HSPLandroid/view/ViewRootImpl;->clearChildFocus(Landroid/view/View;)V
HSPLandroid/view/ViewRootImpl;->clearLowProfileModeIfNeeded(IZ)V
-HSPLandroid/view/ViewRootImpl;->collectViewAttributes()Z+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->collectViewAttributes()Z+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
HSPLandroid/view/ViewRootImpl;->controlInsetsForCompatibility(Landroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ViewRootImpl;->createSyncIfNeeded()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/view/ViewRootImpl;->deliverInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V+]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Landroid/view/ViewRootImpl$InputStage;Landroid/view/ViewRootImpl$EarlyPostImeInputStage;]Landroid/view/ViewRootImpl$QueuedInputEvent;Landroid/view/ViewRootImpl$QueuedInputEvent;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl;->createSyncIfNeeded()V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;
+HSPLandroid/view/ViewRootImpl;->deliverInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
HSPLandroid/view/ViewRootImpl;->destroyHardwareRenderer()V
HSPLandroid/view/ViewRootImpl;->destroyHardwareResources()V
HSPLandroid/view/ViewRootImpl;->destroySurface()V
@@ -18085,14 +18167,15 @@ HSPLandroid/view/ViewRootImpl;->dispatchCheckFocus()V
HSPLandroid/view/ViewRootImpl;->dispatchDetachedFromWindow()V
HSPLandroid/view/ViewRootImpl;->dispatchDispatchSystemUiVisibilityChanged()V
HSPLandroid/view/ViewRootImpl;->dispatchFocusEvent(ZZ)V
+HSPLandroid/view/ViewRootImpl;->dispatchInsetsControlChanged(Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
HSPLandroid/view/ViewRootImpl;->dispatchInvalidateDelayed(Landroid/view/View;J)V
-HSPLandroid/view/ViewRootImpl;->dispatchInvalidateOnAnimation(Landroid/view/View;)V
+HSPLandroid/view/ViewRootImpl;->dispatchInvalidateOnAnimation(Landroid/view/View;)V+]Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;
HSPLandroid/view/ViewRootImpl;->dispatchMoved(II)V
HSPLandroid/view/ViewRootImpl;->doConsumeBatchedInput(J)Z
HSPLandroid/view/ViewRootImpl;->doDie()V
-HSPLandroid/view/ViewRootImpl;->doProcessInputEvents()V+]Landroid/view/InputEventAssigner;Landroid/view/InputEventAssigner;]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;
-HSPLandroid/view/ViewRootImpl;->doTraversal()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;
-HSPLandroid/view/ViewRootImpl;->draw(ZLandroid/window/SurfaceSyncGroup;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;
+HSPLandroid/view/ViewRootImpl;->doProcessInputEvents()V
+HSPLandroid/view/ViewRootImpl;->doTraversal()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
+HSPLandroid/view/ViewRootImpl;->draw(ZLandroid/window/SurfaceSyncGroup;Z)Z+]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/ViewRootImpl;->drawAccessibilityFocusedDrawableIfNeeded(Landroid/graphics/Canvas;)V
HSPLandroid/view/ViewRootImpl;->drawSoftware(Landroid/view/Surface;Landroid/view/View$AttachInfo;IIZLandroid/graphics/Rect;Landroid/graphics/Rect;)Z
HSPLandroid/view/ViewRootImpl;->enableHardwareAcceleration(Landroid/view/WindowManager$LayoutParams;)V
@@ -18114,10 +18197,10 @@ HSPLandroid/view/ViewRootImpl;->getAutofillManager()Landroid/view/autofill/Autof
HSPLandroid/view/ViewRootImpl;->getBufferTransformHint()I
HSPLandroid/view/ViewRootImpl;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
HSPLandroid/view/ViewRootImpl;->getCompatWindowConfiguration()Landroid/app/WindowConfiguration;
-HSPLandroid/view/ViewRootImpl;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/view/ViewRootImpl;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;
HSPLandroid/view/ViewRootImpl;->getDisplayId()I
HSPLandroid/view/ViewRootImpl;->getHandwritingInitiator()Landroid/view/HandwritingInitiator;
-HSPLandroid/view/ViewRootImpl;->getHostVisibility()I+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->getHostVisibility()I+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
HSPLandroid/view/ViewRootImpl;->getImeFocusController()Landroid/view/ImeFocusController;
HSPLandroid/view/ViewRootImpl;->getImpliedSystemUiVisibility(Landroid/view/WindowManager$LayoutParams;)I
HSPLandroid/view/ViewRootImpl;->getInsetsController()Landroid/view/InsetsController;
@@ -18131,14 +18214,14 @@ HSPLandroid/view/ViewRootImpl;->getSurfaceControl()Landroid/view/SurfaceControl;
HSPLandroid/view/ViewRootImpl;->getSurfaceSequenceId()I
HSPLandroid/view/ViewRootImpl;->getTextDirection()I
HSPLandroid/view/ViewRootImpl;->getTitle()Ljava/lang/CharSequence;
-HSPLandroid/view/ViewRootImpl;->getUpdatedFrameInfo()Landroid/graphics/FrameInfo;
+HSPLandroid/view/ViewRootImpl;->getUpdatedFrameInfo()Landroid/graphics/FrameInfo;+]Landroid/view/InputEventAssigner;Landroid/view/InputEventAssigner;]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;
HSPLandroid/view/ViewRootImpl;->getValidLayoutRequesters(Ljava/util/ArrayList;Z)Ljava/util/ArrayList;
HSPLandroid/view/ViewRootImpl;->getView()Landroid/view/View;
HSPLandroid/view/ViewRootImpl;->getViewBoundsSandboxingEnabled()Z
HSPLandroid/view/ViewRootImpl;->getWindowBoundsInsetSystemBars()Landroid/graphics/Rect;
HSPLandroid/view/ViewRootImpl;->getWindowFlags()I
-HSPLandroid/view/ViewRootImpl;->getWindowInsets(Z)Landroid/view/WindowInsets;+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/Insets;Landroid/graphics/Insets;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;
-HSPLandroid/view/ViewRootImpl;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->getWindowInsets(Z)Landroid/view/WindowInsets;
+HSPLandroid/view/ViewRootImpl;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V
HSPLandroid/view/ViewRootImpl;->handleAppVisibility(Z)V
HSPLandroid/view/ViewRootImpl;->handleContentCaptureFlush()V
HSPLandroid/view/ViewRootImpl;->handleDispatchSystemUiVisibilityChanged()V
@@ -18147,6 +18230,7 @@ HSPLandroid/view/ViewRootImpl;->invalidate()V+]Landroid/graphics/Rect;Landroid/g
HSPLandroid/view/ViewRootImpl;->invalidateChild(Landroid/view/View;Landroid/graphics/Rect;)V
HSPLandroid/view/ViewRootImpl;->invalidateChildInParent([ILandroid/graphics/Rect;)Landroid/view/ViewParent;
HSPLandroid/view/ViewRootImpl;->invalidateRectOnScreen(Landroid/graphics/Rect;)V
+HSPLandroid/view/ViewRootImpl;->isAccessibilityFocusDirty()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
HSPLandroid/view/ViewRootImpl;->isContentCaptureEnabled()Z
HSPLandroid/view/ViewRootImpl;->isContentCaptureReallyEnabled()Z
HSPLandroid/view/ViewRootImpl;->isHardwareEnabled()Z+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
@@ -18164,10 +18248,10 @@ HSPLandroid/view/ViewRootImpl;->lambda$new$1(Landroid/view/View;)Ljava/util/List
HSPLandroid/view/ViewRootImpl;->lambda$new$2(Landroid/view/View;)Ljava/util/List;
HSPLandroid/view/ViewRootImpl;->loadSystemProperties()V
HSPLandroid/view/ViewRootImpl;->maybeFireAccessibilityWindowStateChangedEvent()V
-HSPLandroid/view/ViewRootImpl;->maybeHandleWindowMove(Landroid/graphics/Rect;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->maybeHandleWindowMove(Landroid/graphics/Rect;)V
HSPLandroid/view/ViewRootImpl;->maybeUpdateTooltip(Landroid/view/MotionEvent;)V
-HSPLandroid/view/ViewRootImpl;->measureHierarchy(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/content/res/Resources;IIZ)Z+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
-HSPLandroid/view/ViewRootImpl;->mergeWithNextTransaction(Landroid/view/SurfaceControl$Transaction;J)V
+HSPLandroid/view/ViewRootImpl;->measureHierarchy(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/content/res/Resources;IIZ)Z+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->mergeWithNextTransaction(Landroid/view/SurfaceControl$Transaction;J)V+]Landroid/graphics/BLASTBufferQueue;Landroid/graphics/BLASTBufferQueue;
HSPLandroid/view/ViewRootImpl;->notifyContentCaptureEvents()V
HSPLandroid/view/ViewRootImpl;->notifyDrawStarted(Z)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewRootImpl;->notifyInsetsChanged()V
@@ -18182,24 +18266,24 @@ HSPLandroid/view/ViewRootImpl;->onPostDraw(Landroid/graphics/RecordingCanvas;)V
HSPLandroid/view/ViewRootImpl;->onPreDraw(Landroid/graphics/RecordingCanvas;)V
HSPLandroid/view/ViewRootImpl;->onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z
HSPLandroid/view/ViewRootImpl;->performContentCaptureInitialReport()V
-HSPLandroid/view/ViewRootImpl;->performDraw(Landroid/window/SurfaceSyncGroup;)Z+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/view/ViewRootImpl;->performLayout(Landroid/view/WindowManager$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/ViewRootImpl;->performMeasure(II)V+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
-HSPLandroid/view/ViewRootImpl;->performTraversals()V+]Landroid/content/Context;missing_types]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/Region;Landroid/graphics/Region;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Landroid/window/WindowOnBackInvokedDispatcher;Landroid/window/WindowOnBackInvokedDispatcher;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl;->performDraw(Landroid/window/SurfaceSyncGroup;)Z+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->performLayout(Landroid/view/WindowManager$LayoutParams;II)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl;->performMeasure(II)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->performTraversals()V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/View;missing_types]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Landroid/graphics/Region;Landroid/graphics/Region;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Landroid/window/WindowOnBackInvokedDispatcher;Landroid/window/WindowOnBackInvokedDispatcher;
HSPLandroid/view/ViewRootImpl;->playSoundEffect(I)V
HSPLandroid/view/ViewRootImpl;->pokeDrawLockIfNeeded()V
-HSPLandroid/view/ViewRootImpl;->prepareSurfaces()V
+HSPLandroid/view/ViewRootImpl;->prepareSurfaces()V+]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->profileRendering(Z)V
HSPLandroid/view/ViewRootImpl;->recomputeViewAttributes(Landroid/view/View;)V
HSPLandroid/view/ViewRootImpl;->recycleQueuedInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
HSPLandroid/view/ViewRootImpl;->registerAnimatingRenderNode(Landroid/graphics/RenderNode;)V
HSPLandroid/view/ViewRootImpl;->registerBackCallbackOnWindow()V
-HSPLandroid/view/ViewRootImpl;->registerCallbackForPendingTransactions()V
+HSPLandroid/view/ViewRootImpl;->registerCallbackForPendingTransactions()V+]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->registerCallbacksForSync(ZLandroid/window/SurfaceSyncGroup;)V
HSPLandroid/view/ViewRootImpl;->registerCompatOnBackInvokedCallback()V
HSPLandroid/view/ViewRootImpl;->registerListeners()V
-HSPLandroid/view/ViewRootImpl;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V
-HSPLandroid/view/ViewRootImpl;->relayoutWindow(Landroid/view/WindowManager$LayoutParams;IZ)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/view/Display;Landroid/view/Display;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->relayoutWindow(Landroid/view/WindowManager$LayoutParams;IZ)I+]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/view/Display;Landroid/view/Display;
HSPLandroid/view/ViewRootImpl;->removeSendWindowContentChangedCallback()V
HSPLandroid/view/ViewRootImpl;->removeSurfaceChangedCallback(Landroid/view/ViewRootImpl$SurfaceChangedCallback;)V
HSPLandroid/view/ViewRootImpl;->removeWindowCallbacks(Landroid/view/WindowCallbacks;)V
@@ -18212,28 +18296,31 @@ HSPLandroid/view/ViewRootImpl;->requestFitSystemWindows()V
HSPLandroid/view/ViewRootImpl;->requestLayout()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->requestLayoutDuringLayout(Landroid/view/View;)Z
HSPLandroid/view/ViewRootImpl;->requestTransparentRegion(Landroid/view/View;)V
-HSPLandroid/view/ViewRootImpl;->scheduleConsumeBatchedInput()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
-HSPLandroid/view/ViewRootImpl;->scheduleTraversals()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->scheduleConsumeBatchedInput()V
+HSPLandroid/view/ViewRootImpl;->scheduleTraversals()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/view/ViewRootImpl;->scrollToRectOrFocus(Landroid/graphics/Rect;Z)Z
HSPLandroid/view/ViewRootImpl;->sendBackKeyEvent(I)V
HSPLandroid/view/ViewRootImpl;->setAccessibilityFocus(Landroid/view/View;Landroid/view/accessibility/AccessibilityNodeInfo;)V
HSPLandroid/view/ViewRootImpl;->setAccessibilityWindowAttributesIfNeeded()V
HSPLandroid/view/ViewRootImpl;->setActivityConfigCallback(Landroid/view/ViewRootImpl$ActivityConfigCallback;)V
HSPLandroid/view/ViewRootImpl;->setBoundsLayerCrop(Landroid/view/SurfaceControl$Transaction;)V
-HSPLandroid/view/ViewRootImpl;->setFrame(Landroid/graphics/Rect;Z)V
-HSPLandroid/view/ViewRootImpl;->setLayoutParams(Landroid/view/WindowManager$LayoutParams;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;
+HSPLandroid/view/ViewRootImpl;->setFrame(Landroid/graphics/Rect;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsController;Landroid/view/InsetsController;
+HSPLandroid/view/ViewRootImpl;->setLayoutParams(Landroid/view/WindowManager$LayoutParams;Z)V+]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->setOnContentApplyWindowInsetsListener(Landroid/view/Window$OnContentApplyWindowInsetsListener;)V
HSPLandroid/view/ViewRootImpl;->setTag()V
-HSPLandroid/view/ViewRootImpl;->setView(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/view/View;I)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/Display;Landroid/view/Display;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/view/FallbackEventHandler;Lcom/android/internal/policy/PhoneFallbackEventHandler;]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/PendingInsetsController;Landroid/view/PendingInsetsController;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl;->setView(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/view/View;I)V+]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/PendingInsetsController;Landroid/view/PendingInsetsController;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Landroid/view/FallbackEventHandler;Lcom/android/internal/policy/PhoneFallbackEventHandler;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/view/Display;Landroid/view/Display;
HSPLandroid/view/ViewRootImpl;->setWindowStopped(Z)V
HSPLandroid/view/ViewRootImpl;->shouldDispatchCutout()Z
HSPLandroid/view/ViewRootImpl;->shouldOptimizeMeasure(Landroid/view/WindowManager$LayoutParams;)Z
+HSPLandroid/view/ViewRootImpl;->shouldSetFrameRate()Z+]Landroid/view/Surface;Landroid/view/Surface;
+HSPLandroid/view/ViewRootImpl;->shouldSetFrameRateCategory()Z+]Landroid/view/Surface;Landroid/view/Surface;
HSPLandroid/view/ViewRootImpl;->shouldUseDisplaySize(Landroid/view/WindowManager$LayoutParams;)Z
HSPLandroid/view/ViewRootImpl;->systemGestureExclusionChanged()V
HSPLandroid/view/ViewRootImpl;->unscheduleConsumeBatchedInput()V
HSPLandroid/view/ViewRootImpl;->unscheduleTraversals()V
-HSPLandroid/view/ViewRootImpl;->updateBlastSurfaceIfNeeded()V
+HSPLandroid/view/ViewRootImpl;->updateBlastSurfaceIfNeeded()V+]Landroid/graphics/BLASTBufferQueue;Landroid/graphics/BLASTBufferQueue;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;
HSPLandroid/view/ViewRootImpl;->updateBoundsLayer(Landroid/view/SurfaceControl$Transaction;)Z
+HSPLandroid/view/ViewRootImpl;->updateCaptionInsets()Z
HSPLandroid/view/ViewRootImpl;->updateCompatSysUiVisibility(III)V
HSPLandroid/view/ViewRootImpl;->updateCompatSystemUiVisibilityInfo(IIII)V
HSPLandroid/view/ViewRootImpl;->updateConfiguration(I)V
@@ -18256,6 +18343,7 @@ HSPLandroid/view/ViewRootInsetsControllerHost;->getSystemBarsBehavior()I
HSPLandroid/view/ViewRootInsetsControllerHost;->getTranslator()Landroid/content/res/CompatibilityInfo$Translator;
HSPLandroid/view/ViewRootInsetsControllerHost;->getWindowToken()Landroid/os/IBinder;
HSPLandroid/view/ViewRootInsetsControllerHost;->hasAnimationCallbacks()Z
+HSPLandroid/view/ViewRootInsetsControllerHost;->isSystemBarsAppearanceControlled()Z
HSPLandroid/view/ViewRootInsetsControllerHost;->notifyInsetsChanged()V
HSPLandroid/view/ViewRootInsetsControllerHost;->updateCompatSysUiVisibility(III)V
HSPLandroid/view/ViewRootRectTracker$ViewInfo;-><init>(Landroid/view/ViewRootRectTracker;Landroid/view/View;)V
@@ -18278,16 +18366,16 @@ HSPLandroid/view/ViewStub;->setLayoutResource(I)V
HSPLandroid/view/ViewStub;->setOnInflateListener(Landroid/view/ViewStub$OnInflateListener;)V
HSPLandroid/view/ViewStub;->setVisibility(I)V
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;-><init>()V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->get(I)Ljava/lang/Object;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->get(I)Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->size()I
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;-><init>()V
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->add(Ljava/lang/Object;)V
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->addAll(Landroid/view/ViewTreeObserver$CopyOnWriteArray;)V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->end()V
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->end()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->getArray()Ljava/util/ArrayList;
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->remove(Ljava/lang/Object;)V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->size()I
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->start()Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->size()I+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->start()Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;-><init>()V
HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;->isEmpty()Z
@@ -18303,10 +18391,10 @@ HSPLandroid/view/ViewTreeObserver;->addOnScrollChangedListener(Landroid/view/Vie
HSPLandroid/view/ViewTreeObserver;->captureFrameCommitCallbacks()Ljava/util/ArrayList;
HSPLandroid/view/ViewTreeObserver;->checkIsAlive()V
HSPLandroid/view/ViewTreeObserver;->dispatchOnComputeInternalInsets(Landroid/view/ViewTreeObserver$InternalInsetsInfo;)V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnDraw()V
+HSPLandroid/view/ViewTreeObserver;->dispatchOnDraw()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/view/ViewTreeObserver$OnDrawListener;Landroid/widget/Editor$2;
HSPLandroid/view/ViewTreeObserver;->dispatchOnEnterAnimationComplete()V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnGlobalLayout()V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnPreDraw()Z
+HSPLandroid/view/ViewTreeObserver;->dispatchOnGlobalLayout()V+]Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;]Landroid/view/ViewTreeObserver$CopyOnWriteArray;Landroid/view/ViewTreeObserver$CopyOnWriteArray;
+HSPLandroid/view/ViewTreeObserver;->dispatchOnPreDraw()Z+]Landroid/view/ViewTreeObserver$OnPreDrawListener;missing_types]Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;]Landroid/view/ViewTreeObserver$CopyOnWriteArray;Landroid/view/ViewTreeObserver$CopyOnWriteArray;
HSPLandroid/view/ViewTreeObserver;->dispatchOnScrollChanged()V
HSPLandroid/view/ViewTreeObserver;->dispatchOnSystemGestureExclusionRectsChanged(Ljava/util/List;)V
HSPLandroid/view/ViewTreeObserver;->dispatchOnTouchModeChanged(Z)V
@@ -18354,7 +18442,7 @@ HSPLandroid/view/Window;->makeActive()V
HSPLandroid/view/Window;->onDrawLegacyNavigationBarBackgroundChanged(Z)Z
HSPLandroid/view/Window;->removeOnFrameMetricsAvailableListener(Landroid/view/Window$OnFrameMetricsAvailableListener;)V
HSPLandroid/view/Window;->requestFeature(I)Z
-HSPLandroid/view/Window;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V
+HSPLandroid/view/Window;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V+]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/Window;Lcom/android/internal/policy/PhoneWindow;
HSPLandroid/view/Window;->setBackgroundBlurRadius(I)V
HSPLandroid/view/Window;->setCallback(Landroid/view/Window$Callback;)V
HSPLandroid/view/Window;->setCloseOnTouchOutside(Z)V
@@ -18389,6 +18477,7 @@ HSPLandroid/view/WindowInsets$Type;->statusBars()I
HSPLandroid/view/WindowInsets$Type;->systemBars()I
HSPLandroid/view/WindowInsets$Type;->systemGestures()I
HSPLandroid/view/WindowInsets$Type;->toString(I)Ljava/lang/String;
+HSPLandroid/view/WindowInsets;-><init>([Landroid/graphics/Insets;[Landroid/graphics/Insets;[ZZIILandroid/view/DisplayCutout;Landroid/view/RoundedCorners;Landroid/view/PrivacyIndicatorBounds;Landroid/view/DisplayShape;IZ[[Landroid/graphics/Rect;[[Landroid/graphics/Rect;II)V+]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;][Landroid/graphics/Insets;[Landroid/graphics/Insets;][[Landroid/graphics/Rect;[[Landroid/graphics/Rect;
HSPLandroid/view/WindowInsets;->assignCompatInsets([Landroid/graphics/Insets;Landroid/graphics/Rect;)V
HSPLandroid/view/WindowInsets;->consumeDisplayCutout()Landroid/view/WindowInsets;
HSPLandroid/view/WindowInsets;->consumeStableInsets()Landroid/view/WindowInsets;
@@ -18410,13 +18499,13 @@ HSPLandroid/view/WindowInsets;->getSystemWindowInsetBottom()I
HSPLandroid/view/WindowInsets;->getSystemWindowInsetLeft()I
HSPLandroid/view/WindowInsets;->getSystemWindowInsetRight()I
HSPLandroid/view/WindowInsets;->getSystemWindowInsetTop()I
-HSPLandroid/view/WindowInsets;->getSystemWindowInsets()Landroid/graphics/Insets;+]Landroid/view/WindowInsets;Landroid/view/WindowInsets;
+HSPLandroid/view/WindowInsets;->getSystemWindowInsets()Landroid/graphics/Insets;
HSPLandroid/view/WindowInsets;->getSystemWindowInsetsAsRect()Landroid/graphics/Rect;
HSPLandroid/view/WindowInsets;->inset(IIII)Landroid/view/WindowInsets;
HSPLandroid/view/WindowInsets;->inset(Landroid/graphics/Insets;)Landroid/view/WindowInsets;
HSPLandroid/view/WindowInsets;->insetInsets(Landroid/graphics/Insets;IIII)Landroid/graphics/Insets;
HSPLandroid/view/WindowInsets;->insetInsets([Landroid/graphics/Insets;IIII)[Landroid/graphics/Insets;
-HSPLandroid/view/WindowInsets;->insetUnchecked(IIII)Landroid/view/WindowInsets;+]Landroid/view/PrivacyIndicatorBounds;Landroid/view/PrivacyIndicatorBounds;]Landroid/view/RoundedCorners;Landroid/view/RoundedCorners;
+HSPLandroid/view/WindowInsets;->insetUnchecked(IIII)Landroid/view/WindowInsets;
HSPLandroid/view/WindowInsets;->isConsumed()Z
HSPLandroid/view/WindowInsets;->isRound()Z
HSPLandroid/view/WindowInsets;->replaceSystemWindowInsets(IIII)Landroid/view/WindowInsets;
@@ -18427,8 +18516,8 @@ HSPLandroid/view/WindowInsetsAnimation;->getTypeMask()I
HSPLandroid/view/WindowInsetsAnimation;->setAlpha(F)V
HSPLandroid/view/WindowLayout;-><clinit>()V
HSPLandroid/view/WindowLayout;-><init>()V
-HSPLandroid/view/WindowLayout;->computeFrames(Landroid/view/WindowManager$LayoutParams;Landroid/view/InsetsState;Landroid/graphics/Rect;Landroid/graphics/Rect;IIIIFLandroid/window/ClientWindowFrames;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;
-HSPLandroid/view/WindowLayout;->computeSurfaceSize(Landroid/view/WindowManager$LayoutParams;Landroid/graphics/Rect;IILandroid/graphics/Rect;ZLandroid/graphics/Point;)V
+HSPLandroid/view/WindowLayout;->computeFrames(Landroid/view/WindowManager$LayoutParams;Landroid/view/InsetsState;Landroid/graphics/Rect;Landroid/graphics/Rect;IIIIFLandroid/window/ClientWindowFrames;)V+]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/WindowLayout;->computeSurfaceSize(Landroid/view/WindowManager$LayoutParams;Landroid/graphics/Rect;IILandroid/graphics/Rect;ZLandroid/graphics/Point;)V+]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/view/WindowLeaked;-><init>(Ljava/lang/String;)V
HSPLandroid/view/WindowManager$LayoutParams$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/WindowManager$LayoutParams;
HSPLandroid/view/WindowManager$LayoutParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -18463,7 +18552,7 @@ HSPLandroid/view/WindowManagerGlobal;->closeAll(Landroid/os/IBinder;Ljava/lang/S
HSPLandroid/view/WindowManagerGlobal;->closeAllExceptView(Landroid/os/IBinder;Landroid/view/View;Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/view/WindowManagerGlobal;->doRemoveView(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/WindowManagerGlobal;->dumpGfxInfo(Ljava/io/FileDescriptor;[Ljava/lang/String;)V
-HSPLandroid/view/WindowManagerGlobal;->findViewLocked(Landroid/view/View;Z)I
+HSPLandroid/view/WindowManagerGlobal;->findViewLocked(Landroid/view/View;Z)I+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/WindowManagerGlobal;->getInstance()Landroid/view/WindowManagerGlobal;
HSPLandroid/view/WindowManagerGlobal;->getRootViews(Landroid/os/IBinder;)Ljava/util/ArrayList;
HSPLandroid/view/WindowManagerGlobal;->getWindowManagerService()Landroid/view/IWindowManager;
@@ -18473,9 +18562,9 @@ HSPLandroid/view/WindowManagerGlobal;->initialize()V
HSPLandroid/view/WindowManagerGlobal;->peekWindowSession()Landroid/view/IWindowSession;
HSPLandroid/view/WindowManagerGlobal;->removeView(Landroid/view/View;Z)V
HSPLandroid/view/WindowManagerGlobal;->removeViewLocked(IZ)V
-HSPLandroid/view/WindowManagerGlobal;->setStoppedState(Landroid/os/IBinder;Z)V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowManagerGlobal;Landroid/view/WindowManagerGlobal;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/WindowManagerGlobal;->setStoppedState(Landroid/os/IBinder;Z)V
HSPLandroid/view/WindowManagerGlobal;->trimMemory(I)V
-HSPLandroid/view/WindowManagerGlobal;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
+HSPLandroid/view/WindowManagerGlobal;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/WindowManagerImpl;-><init>(Landroid/content/Context;)V
HSPLandroid/view/WindowManagerImpl;-><init>(Landroid/content/Context;Landroid/view/Window;Landroid/os/IBinder;)V
HSPLandroid/view/WindowManagerImpl;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
@@ -18488,7 +18577,7 @@ HSPLandroid/view/WindowManagerImpl;->getDefaultDisplay()Landroid/view/Display;
HSPLandroid/view/WindowManagerImpl;->getMaximumWindowMetrics()Landroid/view/WindowMetrics;
HSPLandroid/view/WindowManagerImpl;->removeView(Landroid/view/View;)V
HSPLandroid/view/WindowManagerImpl;->removeViewImmediate(Landroid/view/View;)V
-HSPLandroid/view/WindowManagerImpl;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
+HSPLandroid/view/WindowManagerImpl;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/WindowManagerGlobal;Landroid/view/WindowManagerGlobal;
HSPLandroid/view/WindowMetrics;-><init>(Landroid/graphics/Rect;Landroid/view/WindowInsets;)V
HSPLandroid/view/WindowMetrics;-><init>(Landroid/graphics/Rect;Ljava/util/function/Supplier;F)V
HSPLandroid/view/WindowMetrics;->getBounds()Landroid/graphics/Rect;
@@ -18530,8 +18619,8 @@ HSPLandroid/view/accessibility/AccessibilityManager;->updateFocusAppearanceLocke
HSPLandroid/view/accessibility/AccessibilityManager;->updateUiTimeout(J)V
HSPLandroid/view/accessibility/AccessibilityNodeIdManager;-><init>()V
HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->getInstance()Landroid/view/accessibility/AccessibilityNodeIdManager;
-HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->registerViewWithId(Landroid/view/View;I)V+]Landroid/view/accessibility/WeakSparseArray;Landroid/view/accessibility/WeakSparseArray;
-HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->unregisterViewWithId(I)V+]Landroid/view/accessibility/WeakSparseArray;Landroid/view/accessibility/WeakSparseArray;
+HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->registerViewWithId(Landroid/view/View;I)V
+HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->unregisterViewWithId(I)V
HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;-><init>(ILjava/lang/CharSequence;)V
HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;->getId()I
@@ -18571,9 +18660,9 @@ HSPLandroid/view/accessibility/IAccessibilityManagerClient$Stub;->getTransaction
HSPLandroid/view/accessibility/IAccessibilityManagerClient$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
HSPLandroid/view/accessibility/WeakSparseArray$WeakReferenceWithId;-><init>(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;I)V
HSPLandroid/view/accessibility/WeakSparseArray;-><init>()V
-HSPLandroid/view/accessibility/WeakSparseArray;->append(ILjava/lang/Object;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
-HSPLandroid/view/accessibility/WeakSparseArray;->remove(I)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
-HSPLandroid/view/accessibility/WeakSparseArray;->removeUnreachableValues()V+]Ljava/lang/ref/ReferenceQueue;Ljava/lang/ref/ReferenceQueue;
+HSPLandroid/view/accessibility/WeakSparseArray;->append(ILjava/lang/Object;)V
+HSPLandroid/view/accessibility/WeakSparseArray;->remove(I)V
+HSPLandroid/view/accessibility/WeakSparseArray;->removeUnreachableValues()V
HSPLandroid/view/animation/AccelerateDecelerateInterpolator;-><init>()V
HSPLandroid/view/animation/AccelerateDecelerateInterpolator;->createNativeInterpolator()J
HSPLandroid/view/animation/AccelerateDecelerateInterpolator;->getInterpolation(F)F
@@ -18583,7 +18672,7 @@ HSPLandroid/view/animation/AccelerateInterpolator;-><init>(Landroid/content/res/
HSPLandroid/view/animation/AccelerateInterpolator;->getInterpolation(F)F
HSPLandroid/view/animation/AlphaAnimation;-><init>(FF)V
HSPLandroid/view/animation/AlphaAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-HSPLandroid/view/animation/AlphaAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V+]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/AlphaAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V
HSPLandroid/view/animation/AlphaAnimation;->hasAlpha()Z
HSPLandroid/view/animation/AlphaAnimation;->willChangeBounds()Z
HSPLandroid/view/animation/AlphaAnimation;->willChangeTransformationMatrix()Z
@@ -18592,7 +18681,7 @@ HSPLandroid/view/animation/Animation$3;->run()V
HSPLandroid/view/animation/Animation$Description;-><init>()V
HSPLandroid/view/animation/Animation$Description;->parseValue(Landroid/util/TypedValue;Landroid/content/Context;)Landroid/view/animation/Animation$Description;
HSPLandroid/view/animation/Animation;-><init>()V
-HSPLandroid/view/animation/Animation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
+HSPLandroid/view/animation/Animation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/view/animation/Animation;->cancel()V
HSPLandroid/view/animation/Animation;->detach()V
HSPLandroid/view/animation/Animation;->dispatchAnimationEnd()V
@@ -18601,12 +18690,12 @@ HSPLandroid/view/animation/Animation;->ensureInterpolator()V
HSPLandroid/view/animation/Animation;->finalize()V
HSPLandroid/view/animation/Animation;->getDuration()J
HSPLandroid/view/animation/Animation;->getFillAfter()Z
-HSPLandroid/view/animation/Animation;->getInvalidateRegion(IIIILandroid/graphics/RectF;Landroid/view/animation/Transformation;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/Animation;->getInvalidateRegion(IIIILandroid/graphics/RectF;Landroid/view/animation/Transformation;)V
HSPLandroid/view/animation/Animation;->getScaleFactor()F
HSPLandroid/view/animation/Animation;->getStartOffset()J
-HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;)Z+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
-HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;F)Z+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
-HSPLandroid/view/animation/Animation;->getTransformationAt(FLandroid/view/animation/Transformation;)V+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;]Landroid/view/animation/Interpolator;Landroid/view/animation/AccelerateDecelerateInterpolator;,Landroid/view/animation/LinearInterpolator;
+HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;)Z
+HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;F)Z
+HSPLandroid/view/animation/Animation;->getTransformationAt(FLandroid/view/animation/Transformation;)V
HSPLandroid/view/animation/Animation;->hasAlpha()Z
HSPLandroid/view/animation/Animation;->hasEnded()Z
HSPLandroid/view/animation/Animation;->hasStarted()Z
@@ -18663,7 +18752,7 @@ HSPLandroid/view/animation/AnimationUtils$AnimationState;-><init>()V
HSPLandroid/view/animation/AnimationUtils$AnimationState;-><init>(Landroid/view/animation/AnimationUtils$AnimationState-IA;)V
HSPLandroid/view/animation/AnimationUtils;->createAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Animation;
HSPLandroid/view/animation/AnimationUtils;->createAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;Landroid/view/animation/AnimationSet;Landroid/util/AttributeSet;)Landroid/view/animation/Animation;
-HSPLandroid/view/animation/AnimationUtils;->createInterpolatorFromXml(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Interpolator;+]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/animation/AnimationUtils;->createInterpolatorFromXml(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Interpolator;
HSPLandroid/view/animation/AnimationUtils;->currentAnimationTimeMillis()J
HSPLandroid/view/animation/AnimationUtils;->loadAnimation(Landroid/content/Context;I)Landroid/view/animation/Animation;
HSPLandroid/view/animation/AnimationUtils;->loadInterpolator(Landroid/content/Context;I)Landroid/view/animation/Interpolator;
@@ -18689,7 +18778,7 @@ HSPLandroid/view/animation/PathInterpolator;-><init>(Landroid/content/res/Resour
HSPLandroid/view/animation/PathInterpolator;->createNativeInterpolator()J
HSPLandroid/view/animation/PathInterpolator;->getInterpolation(F)F
HSPLandroid/view/animation/PathInterpolator;->initCubic(FFFF)V
-HSPLandroid/view/animation/PathInterpolator;->initPath(Landroid/graphics/Path;)V
+HSPLandroid/view/animation/PathInterpolator;->initPath(Landroid/graphics/Path;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
HSPLandroid/view/animation/PathInterpolator;->parseInterpolatorFromTypeArray(Landroid/content/res/TypedArray;)V
HSPLandroid/view/animation/ScaleAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/view/animation/ScaleAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V
@@ -18697,13 +18786,13 @@ HSPLandroid/view/animation/ScaleAnimation;->initialize(IIII)V
HSPLandroid/view/animation/ScaleAnimation;->initializePivotPoint()V
HSPLandroid/view/animation/ScaleAnimation;->resolveScale(FIIII)F
HSPLandroid/view/animation/Transformation;-><init>()V
-HSPLandroid/view/animation/Transformation;->clear()V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/animation/Transformation;->clear()V
HSPLandroid/view/animation/Transformation;->compose(Landroid/view/animation/Transformation;)V
HSPLandroid/view/animation/Transformation;->getAlpha()F
HSPLandroid/view/animation/Transformation;->getInsets()Landroid/graphics/Insets;
HSPLandroid/view/animation/Transformation;->getMatrix()Landroid/graphics/Matrix;
HSPLandroid/view/animation/Transformation;->getTransformationType()I
-HSPLandroid/view/animation/Transformation;->set(Landroid/view/animation/Transformation;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/Transformation;->set(Landroid/view/animation/Transformation;)V
HSPLandroid/view/animation/Transformation;->setAlpha(F)V
HSPLandroid/view/animation/Transformation;->setInsets(Landroid/graphics/Insets;)V
HSPLandroid/view/animation/TranslateAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
@@ -18776,7 +18865,7 @@ HSPLandroid/view/autofill/AutofillManager;->hasFillDialogUiFeature()Z
HSPLandroid/view/autofill/AutofillManager;->isActiveLocked()Z
HSPLandroid/view/autofill/AutofillManager;->isDisabledByServiceLocked()Z
HSPLandroid/view/autofill/AutofillManager;->isEnabled()Z
-HSPLandroid/view/autofill/AutofillManager;->notifyValueChanged(Landroid/view/View;)V+]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/autofill/AutofillManager;->notifyValueChanged(Landroid/view/View;)V
HSPLandroid/view/autofill/AutofillManager;->notifyViewEntered(Landroid/view/View;I)V
HSPLandroid/view/autofill/AutofillManager;->notifyViewEnteredForAugmentedAutofill(Landroid/view/View;)V
HSPLandroid/view/autofill/AutofillManager;->notifyViewEnteredForFillDialog(Landroid/view/View;)V
@@ -18808,6 +18897,7 @@ HSPLandroid/view/autofill/IAugmentedAutofillManagerClient$Stub;-><init>()V
HSPLandroid/view/autofill/IAugmentedAutofillManagerClient$Stub;->asBinder()Landroid/os/IBinder;
HSPLandroid/view/autofill/IAugmentedAutofillManagerClient$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->addClient(Landroid/view/autofill/IAutoFillManagerClient;Landroid/content/ComponentName;ILcom/android/internal/os/IResultReceiver;)V
HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->cancelSession(II)V
HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->getAutofillServiceComponentName(Lcom/android/internal/os/IResultReceiver;)V
@@ -19048,7 +19138,7 @@ HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;-><init>(Landroid/v
HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onPostWindowGainedFocus(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;)V
HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onPreWindowGainedFocus(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onScheduledCheckFocus(Landroid/view/ViewRootImpl;)V
-HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onViewDetachedFromWindow(Landroid/view/View;Landroid/view/ViewRootImpl;)V+]Landroid/view/View;missing_types
+HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onViewDetachedFromWindow(Landroid/view/View;Landroid/view/ViewRootImpl;)V
HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onWindowDismissed(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->setCurrentRootViewLocked(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/inputmethod/InputMethodManager$H$$ExternalSyntheticLambda0;->run()V
@@ -19375,17 +19465,17 @@ HSPLandroid/widget/AbsListView$AdapterDataSetObserver;->onChanged()V
HSPLandroid/widget/AbsListView$DeviceConfigChangeListener;-><init>()V
HSPLandroid/widget/AbsListView$DeviceConfigChangeListener;-><init>(Landroid/widget/AbsListView$DeviceConfigChangeListener-IA;)V
HSPLandroid/widget/AbsListView$PerformClick;->run()V
-HSPLandroid/widget/AbsListView$RecycleBin;->addScrapView(Landroid/view/View;I)V+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;]Landroid/widget/AbsListView;Landroid/widget/ListView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/AbsListView$RecycleBin;->addScrapView(Landroid/view/View;I)V
HSPLandroid/widget/AbsListView$RecycleBin;->clear()V
HSPLandroid/widget/AbsListView$RecycleBin;->clearTransientStateViews()V
HSPLandroid/widget/AbsListView$RecycleBin;->fillActiveViews(II)V
HSPLandroid/widget/AbsListView$RecycleBin;->getActiveView(I)Landroid/view/View;
-HSPLandroid/widget/AbsListView$RecycleBin;->getScrapView(I)Landroid/view/View;+]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView$RecycleBin;->getScrapView(I)Landroid/view/View;
HSPLandroid/widget/AbsListView$RecycleBin;->getTransientStateView(I)Landroid/view/View;
HSPLandroid/widget/AbsListView$RecycleBin;->markChildrenDirty()V
HSPLandroid/widget/AbsListView$RecycleBin;->pruneScrapViews()V
HSPLandroid/widget/AbsListView$RecycleBin;->removeSkippedScrap()V
-HSPLandroid/widget/AbsListView$RecycleBin;->retrieveFromScrap(Ljava/util/ArrayList;I)Landroid/view/View;+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/ListAdapter;Landroid/preference/PreferenceGroupAdapter;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/AbsListView$RecycleBin;->retrieveFromScrap(Ljava/util/ArrayList;I)Landroid/view/View;
HSPLandroid/widget/AbsListView$RecycleBin;->scrapActiveViews()V
HSPLandroid/widget/AbsListView$RecycleBin;->setViewTypeCount(I)V
HSPLandroid/widget/AbsListView$RecycleBin;->shouldRecycleViewType(I)Z
@@ -19395,12 +19485,12 @@ HSPLandroid/widget/AbsListView$WindowRunnnable;->sameWindow()Z
HSPLandroid/widget/AbsListView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
HSPLandroid/widget/AbsListView;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
HSPLandroid/widget/AbsListView;->clearChoices()V
-HSPLandroid/widget/AbsListView;->computeVerticalScrollExtent()I+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types
-HSPLandroid/widget/AbsListView;->computeVerticalScrollOffset()I+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types
+HSPLandroid/widget/AbsListView;->computeVerticalScrollExtent()I
+HSPLandroid/widget/AbsListView;->computeVerticalScrollOffset()I
HSPLandroid/widget/AbsListView;->computeVerticalScrollRange()I
HSPLandroid/widget/AbsListView;->dispatchDraw(Landroid/graphics/Canvas;)V
HSPLandroid/widget/AbsListView;->dispatchSetPressed(Z)V
-HSPLandroid/widget/AbsListView;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/widget/AbsListView;missing_types]Landroid/widget/EdgeEffect;Landroid/widget/EdgeEffect;
+HSPLandroid/widget/AbsListView;->draw(Landroid/graphics/Canvas;)V
HSPLandroid/widget/AbsListView;->drawableStateChanged()V
HSPLandroid/widget/AbsListView;->generateDefaultLayoutParams()Landroid/view/ViewGroup$LayoutParams;
HSPLandroid/widget/AbsListView;->generateLayoutParams(Landroid/util/AttributeSet;)Landroid/view/ViewGroup$LayoutParams;
@@ -19418,7 +19508,7 @@ HSPLandroid/widget/AbsListView;->isFastScrollEnabled()Z
HSPLandroid/widget/AbsListView;->isInFilterMode()Z
HSPLandroid/widget/AbsListView;->isVerticalScrollBarHidden()Z
HSPLandroid/widget/AbsListView;->jumpDrawablesToCurrentState()V
-HSPLandroid/widget/AbsListView;->obtainView(I[Z)Landroid/view/View;+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView;->obtainView(I[Z)Landroid/view/View;
HSPLandroid/widget/AbsListView;->onAttachedToWindow()V
HSPLandroid/widget/AbsListView;->onCancelPendingInputEvents()V
HSPLandroid/widget/AbsListView;->onDetachedFromWindow()V
@@ -19428,9 +19518,9 @@ HSPLandroid/widget/AbsListView;->onMeasure(II)V
HSPLandroid/widget/AbsListView;->onRtlPropertiesChanged(I)V
HSPLandroid/widget/AbsListView;->onSaveInstanceState()Landroid/os/Parcelable;
HSPLandroid/widget/AbsListView;->onTouchDown(Landroid/view/MotionEvent;)V
-HSPLandroid/widget/AbsListView;->onTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/VelocityTracker;Landroid/view/VelocityTracker;]Landroid/widget/AbsListView;Landroid/widget/ListView;
+HSPLandroid/widget/AbsListView;->onTouchEvent(Landroid/view/MotionEvent;)Z
HSPLandroid/widget/AbsListView;->onTouchModeChanged(Z)V
-HSPLandroid/widget/AbsListView;->onTouchMove(Landroid/view/MotionEvent;Landroid/view/MotionEvent;)V+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;Landroid/widget/ListView;
+HSPLandroid/widget/AbsListView;->onTouchMove(Landroid/view/MotionEvent;Landroid/view/MotionEvent;)V
HSPLandroid/widget/AbsListView;->onTouchUp(Landroid/view/MotionEvent;)V
HSPLandroid/widget/AbsListView;->onWindowFocusChanged(Z)V
HSPLandroid/widget/AbsListView;->performItemClick(Landroid/view/View;IJ)Z
@@ -19445,7 +19535,7 @@ HSPLandroid/widget/AbsListView;->setFastScrollAlwaysVisible(Z)V
HSPLandroid/widget/AbsListView;->setFastScrollEnabled(Z)V
HSPLandroid/widget/AbsListView;->setFastScrollStyle(I)V
HSPLandroid/widget/AbsListView;->setFrame(IIII)Z
-HSPLandroid/widget/AbsListView;->setItemViewLayoutParams(Landroid/view/View;I)V+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView;->setItemViewLayoutParams(Landroid/view/View;I)V
HSPLandroid/widget/AbsListView;->setOnScrollListener(Landroid/widget/AbsListView$OnScrollListener;)V
HSPLandroid/widget/AbsListView;->setScrollingCacheEnabled(Z)V
HSPLandroid/widget/AbsListView;->setSelectionFromTop(II)V
@@ -19585,7 +19675,7 @@ HSPLandroid/widget/EdgeEffect;->isAtEquilibrium()Z
HSPLandroid/widget/EdgeEffect;->isFinished()Z
HSPLandroid/widget/EdgeEffect;->onAbsorb(I)V
HSPLandroid/widget/EdgeEffect;->onPull(FF)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/widget/EdgeEffect;->onPullDistance(FF)F+]Landroid/widget/EdgeEffect;Landroid/widget/EdgeEffect;
+HSPLandroid/widget/EdgeEffect;->onPullDistance(FF)F
HSPLandroid/widget/EdgeEffect;->onRelease()V
HSPLandroid/widget/EdgeEffect;->setSize(II)V
HSPLandroid/widget/EdgeEffect;->update()V
@@ -19610,7 +19700,7 @@ HSPLandroid/widget/Editor$AccessibilitySmartActions;-><init>(Landroid/widget/Tex
HSPLandroid/widget/Editor$Blink;->cancel()V
HSPLandroid/widget/Editor$Blink;->run()V
HSPLandroid/widget/Editor$Blink;->uncancel()V
-HSPLandroid/widget/Editor$CursorAnchorInfoNotifier;->updatePosition(IIZZ)V
+HSPLandroid/widget/Editor$CursorAnchorInfoNotifier;->updatePosition(IIZZ)V+]Landroid/view/inputmethod/InputMethodManager;Landroid/view/inputmethod/InputMethodManager;
HSPLandroid/widget/Editor$EditOperation;-><init>(Landroid/widget/Editor;Ljava/lang/String;ILjava/lang/String;Z)V
HSPLandroid/widget/Editor$EditOperation;->commit()V
HSPLandroid/widget/Editor$EditOperation;->forceMergeWith(Landroid/widget/Editor$EditOperation;)V
@@ -19654,10 +19744,10 @@ HSPLandroid/widget/Editor$InsertionPointCursorController;->onDetached()V
HSPLandroid/widget/Editor$InsertionPointCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V
HSPLandroid/widget/Editor$InsertionPointCursorController;->show()V
HSPLandroid/widget/Editor$PositionListener;->addSubscriber(Landroid/widget/Editor$TextViewPositionListener;Z)V
-HSPLandroid/widget/Editor$PositionListener;->onPreDraw()Z
+HSPLandroid/widget/Editor$PositionListener;->onPreDraw()Z+]Landroid/widget/Editor$TextViewPositionListener;Landroid/widget/Editor$CursorAnchorInfoNotifier;,Landroid/widget/Editor$InsertionHandleView;
HSPLandroid/widget/Editor$PositionListener;->onScrollChanged()V
HSPLandroid/widget/Editor$PositionListener;->removeSubscriber(Landroid/widget/Editor$TextViewPositionListener;)V
-HSPLandroid/widget/Editor$PositionListener;->updatePosition()V
+HSPLandroid/widget/Editor$PositionListener;->updatePosition()V+]Landroid/widget/TextView;Landroid/widget/EditText;
HSPLandroid/widget/Editor$ProcessTextIntentActionsHandler;-><init>(Landroid/widget/Editor;)V
HSPLandroid/widget/Editor$SelectionModifierCursorController;->getMinTouchOffset()I
HSPLandroid/widget/Editor$SelectionModifierCursorController;->hide()V
@@ -19666,7 +19756,7 @@ HSPLandroid/widget/Editor$SelectionModifierCursorController;->isCursorBeingModif
HSPLandroid/widget/Editor$SelectionModifierCursorController;->isDragAcceleratorActive()Z
HSPLandroid/widget/Editor$SelectionModifierCursorController;->isSelectionStartDragged()Z
HSPLandroid/widget/Editor$SelectionModifierCursorController;->onDetached()V
-HSPLandroid/widget/Editor$SelectionModifierCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V
+HSPLandroid/widget/Editor$SelectionModifierCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V+]Landroid/widget/EditorTouchState;Landroid/widget/EditorTouchState;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/widget/Editor$SelectionModifierCursorController;Landroid/widget/Editor$SelectionModifierCursorController;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/widget/Editor$SelectionModifierCursorController;->resetDragAcceleratorState()V
HSPLandroid/widget/Editor$SelectionModifierCursorController;->resetTouchOffsets()V
HSPLandroid/widget/Editor$SelectionModifierCursorController;->updateSelection(Landroid/view/MotionEvent;)V
@@ -19674,7 +19764,7 @@ HSPLandroid/widget/Editor$SpanController;->hide()V
HSPLandroid/widget/Editor$SpanController;->onSpanAdded(Landroid/text/Spannable;Ljava/lang/Object;II)V
HSPLandroid/widget/Editor$SpanController;->onSpanChanged(Landroid/text/Spannable;Ljava/lang/Object;IIII)V
HSPLandroid/widget/Editor$SpanController;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
-HSPLandroid/widget/Editor$TextRenderNode;->needsRecord()Z
+HSPLandroid/widget/Editor$TextRenderNode;->needsRecord()Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/widget/Editor$UndoInputFilter;->beginBatchEdit()V
HSPLandroid/widget/Editor$UndoInputFilter;->canUndoEdit(Ljava/lang/CharSequence;IILandroid/text/Spanned;II)Z
HSPLandroid/widget/Editor$UndoInputFilter;->endBatchEdit()V
@@ -19695,7 +19785,7 @@ HSPLandroid/widget/Editor;->createInputContentTypeIfNeeded()V
HSPLandroid/widget/Editor;->createInputMethodStateIfNeeded()V
HSPLandroid/widget/Editor;->discardTextDisplayLists()V
HSPLandroid/widget/Editor;->downgradeEasyCorrectionSpans()V
-HSPLandroid/widget/Editor;->drawHardwareAcceleratedInner(Landroid/graphics/Canvas;Landroid/text/Layout;Landroid/graphics/Path;Landroid/graphics/Paint;I[I[IIII)I
+HSPLandroid/widget/Editor;->drawHardwareAcceleratedInner(Landroid/graphics/Canvas;Landroid/text/Layout;Landroid/graphics/Path;Landroid/graphics/Paint;I[I[IIII)I+]Landroid/widget/Editor$TextRenderNode;Landroid/widget/Editor$TextRenderNode;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/widget/Editor;->endBatchEdit()V
HSPLandroid/widget/Editor;->ensureEndedBatchEdit()V
HSPLandroid/widget/Editor;->ensureNoSelectionIfNonSelectable()V
@@ -19731,10 +19821,10 @@ HSPLandroid/widget/Editor;->onFocusChanged(ZI)V
HSPLandroid/widget/Editor;->onLocaleChanged()V
HSPLandroid/widget/Editor;->onScreenStateChanged(I)V
HSPLandroid/widget/Editor;->onScrollChanged()V
-HSPLandroid/widget/Editor;->onTouchEvent(Landroid/view/MotionEvent;)V
+HSPLandroid/widget/Editor;->onTouchEvent(Landroid/view/MotionEvent;)V+]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/EditorTouchState;Landroid/widget/EditorTouchState;]Landroid/widget/Editor$SelectionModifierCursorController;Landroid/widget/Editor$SelectionModifierCursorController;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/widget/Editor;->onTouchUpEvent(Landroid/view/MotionEvent;)V
HSPLandroid/widget/Editor;->onWindowFocusChanged(Z)V
-HSPLandroid/widget/Editor;->prepareCursorControllers()V
+HSPLandroid/widget/Editor;->prepareCursorControllers()V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/widget/Editor;Landroid/widget/Editor;
HSPLandroid/widget/Editor;->refreshTextActionMode()V
HSPLandroid/widget/Editor;->reportExtractedText()Z
HSPLandroid/widget/Editor;->restoreInstanceState(Landroid/os/ParcelableParcel;)V
@@ -19759,19 +19849,19 @@ HSPLandroid/widget/EditorTouchState;->getLastDownY()F
HSPLandroid/widget/EditorTouchState;->isMovedEnoughForDrag()Z
HSPLandroid/widget/EditorTouchState;->isMultiTap()Z
HSPLandroid/widget/EditorTouchState;->isMultiTapInSameArea()Z
-HSPLandroid/widget/EditorTouchState;->update(Landroid/view/MotionEvent;Landroid/view/ViewConfiguration;)V
+HSPLandroid/widget/EditorTouchState;->update(Landroid/view/MotionEvent;Landroid/view/ViewConfiguration;)V+]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/widget/Filter;-><init>()V
HSPLandroid/widget/ForwardingListener;-><init>(Landroid/view/View;)V
HSPLandroid/widget/ForwardingListener;->onViewAttachedToWindow(Landroid/view/View;)V
HSPLandroid/widget/ForwardingListener;->onViewDetachedFromWindow(Landroid/view/View;)V
HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(II)V
HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(III)V
-HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;)V
HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/FrameLayout;missing_types
+HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
HSPLandroid/widget/FrameLayout;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
HSPLandroid/widget/FrameLayout;->generateDefaultLayoutParams()Landroid/view/ViewGroup$LayoutParams;
HSPLandroid/widget/FrameLayout;->generateDefaultLayoutParams()Landroid/widget/FrameLayout$LayoutParams;
@@ -19785,7 +19875,7 @@ HSPLandroid/widget/FrameLayout;->getPaddingRightWithForeground()I+]Landroid/widg
HSPLandroid/widget/FrameLayout;->getPaddingTopWithForeground()I+]Landroid/widget/FrameLayout;missing_types
HSPLandroid/widget/FrameLayout;->layoutChildren(IIIIZ)V+]Landroid/view/View;missing_types]Landroid/widget/FrameLayout;missing_types
HSPLandroid/widget/FrameLayout;->onLayout(ZIIII)V+]Landroid/widget/FrameLayout;missing_types
-HSPLandroid/widget/FrameLayout;->onMeasure(II)V+]Landroid/view/View;missing_types]Landroid/widget/FrameLayout;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/FrameLayout;->onMeasure(II)V+]Landroid/widget/FrameLayout;missing_types]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/widget/FrameLayout;->setForegroundGravity(I)V
HSPLandroid/widget/FrameLayout;->setMeasureAllChildren(Z)V
HSPLandroid/widget/FrameLayout;->shouldDelayChildPressedState()Z
@@ -19882,13 +19972,13 @@ HSPLandroid/widget/ImageView$ScaleType;->values()[Landroid/widget/ImageView$Scal
HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;)V
HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/widget/ImageView;->applyAlpha()V
HSPLandroid/widget/ImageView;->applyColorFilter()V
-HSPLandroid/widget/ImageView;->applyImageTint()V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/widget/ImageView;->applyImageTint()V
HSPLandroid/widget/ImageView;->applyXfermode()V
HSPLandroid/widget/ImageView;->clearColorFilter()V
-HSPLandroid/widget/ImageView;->configureBounds()V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->configureBounds()V
HSPLandroid/widget/ImageView;->drawableHotspotChanged(FF)V
HSPLandroid/widget/ImageView;->drawableStateChanged()V
HSPLandroid/widget/ImageView;->getAccessibilityClassName()Ljava/lang/CharSequence;
@@ -19897,21 +19987,21 @@ HSPLandroid/widget/ImageView;->getDrawable()Landroid/graphics/drawable/Drawable;
HSPLandroid/widget/ImageView;->getImageMatrix()Landroid/graphics/Matrix;
HSPLandroid/widget/ImageView;->getScaleType()Landroid/widget/ImageView$ScaleType;
HSPLandroid/widget/ImageView;->hasOverlappingRendering()Z
-HSPLandroid/widget/ImageView;->initImageView()V+]Landroid/widget/ImageView;missing_types
-HSPLandroid/widget/ImageView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->initImageView()V
+HSPLandroid/widget/ImageView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/ImageView;->isFilledByImage()Z
-HSPLandroid/widget/ImageView;->isOpaque()Z+]Landroid/graphics/drawable/Drawable;megamorphic_types
-HSPLandroid/widget/ImageView;->jumpDrawablesToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/ImageView;->isOpaque()Z
+HSPLandroid/widget/ImageView;->jumpDrawablesToCurrentState()V
HSPLandroid/widget/ImageView;->onAttachedToWindow()V
HSPLandroid/widget/ImageView;->onCreateDrawableState(I)[I
HSPLandroid/widget/ImageView;->onDetachedFromWindow()V
-HSPLandroid/widget/ImageView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/widget/ImageView;->onMeasure(II)V+]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->onDraw(Landroid/graphics/Canvas;)V
+HSPLandroid/widget/ImageView;->onMeasure(II)V
HSPLandroid/widget/ImageView;->onRtlPropertiesChanged(I)V
-HSPLandroid/widget/ImageView;->onVisibilityAggregated(Z)V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/ImageView;->onVisibilityAggregated(Z)V
HSPLandroid/widget/ImageView;->resizeFromDrawable()V
HSPLandroid/widget/ImageView;->resolveAdjustedSize(III)I
-HSPLandroid/widget/ImageView;->resolveUri()V+]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->resolveUri()V
HSPLandroid/widget/ImageView;->scaleTypeToScaleToFit(Landroid/widget/ImageView$ScaleType;)Landroid/graphics/Matrix$ScaleToFit;
HSPLandroid/widget/ImageView;->setAdjustViewBounds(Z)V
HSPLandroid/widget/ImageView;->setAlpha(I)V
@@ -19922,9 +20012,9 @@ HSPLandroid/widget/ImageView;->setCropToPadding(Z)V
HSPLandroid/widget/ImageView;->setFrame(IIII)Z
HSPLandroid/widget/ImageView;->setImageAlpha(I)V
HSPLandroid/widget/ImageView;->setImageBitmap(Landroid/graphics/Bitmap;)V
-HSPLandroid/widget/ImageView;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ImageView;missing_types
-HSPLandroid/widget/ImageView;->setImageMatrix(Landroid/graphics/Matrix;)V
-HSPLandroid/widget/ImageView;->setImageResource(I)V+]Landroid/widget/ImageView;Landroid/widget/ImageView;
+HSPLandroid/widget/ImageView;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ImageView;->setImageMatrix(Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/widget/ImageView;->setImageResource(I)V
HSPLandroid/widget/ImageView;->setImageTintBlendMode(Landroid/graphics/BlendMode;)V
HSPLandroid/widget/ImageView;->setImageTintList(Landroid/content/res/ColorStateList;)V
HSPLandroid/widget/ImageView;->setMaxHeight(I)V
@@ -19932,16 +20022,16 @@ HSPLandroid/widget/ImageView;->setMaxWidth(I)V
HSPLandroid/widget/ImageView;->setScaleType(Landroid/widget/ImageView$ScaleType;)V
HSPLandroid/widget/ImageView;->setSelected(Z)V
HSPLandroid/widget/ImageView;->setVisibility(I)V
-HSPLandroid/widget/ImageView;->updateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->updateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/ImageView;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(II)V
HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(IIF)V
-HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;)V
HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/LinearLayout;missing_types
+HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
HSPLandroid/widget/LinearLayout;->allViewsAreGoneBefore(I)Z
HSPLandroid/widget/LinearLayout;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
HSPLandroid/widget/LinearLayout;->forceUniformHeight(II)V
@@ -19963,8 +20053,8 @@ HSPLandroid/widget/LinearLayout;->getOrientation()I
HSPLandroid/widget/LinearLayout;->getVirtualChildAt(I)Landroid/view/View;+]Landroid/widget/LinearLayout;missing_types
HSPLandroid/widget/LinearLayout;->getVirtualChildCount()I+]Landroid/widget/LinearLayout;missing_types
HSPLandroid/widget/LinearLayout;->hasDividerBeforeChildAt(I)Z
-HSPLandroid/widget/LinearLayout;->layoutHorizontal(IIII)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
-HSPLandroid/widget/LinearLayout;->layoutVertical(IIII)V+]Landroid/view/View;megamorphic_types]Landroid/widget/LinearLayout;missing_types
+HSPLandroid/widget/LinearLayout;->layoutHorizontal(IIII)V
+HSPLandroid/widget/LinearLayout;->layoutVertical(IIII)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;missing_types
HSPLandroid/widget/LinearLayout;->measureChildBeforeLayout(Landroid/view/View;IIIII)V+]Landroid/widget/LinearLayout;missing_types
HSPLandroid/widget/LinearLayout;->measureHorizontal(II)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
HSPLandroid/widget/LinearLayout;->measureVertical(II)V+]Landroid/view/View;megamorphic_types]Landroid/widget/LinearLayout;missing_types
@@ -19997,7 +20087,7 @@ HSPLandroid/widget/ListView;-><init>(Landroid/content/Context;Landroid/util/Attr
HSPLandroid/widget/ListView;->adjustViewsUpOrDown()V
HSPLandroid/widget/ListView;->clearRecycledState(Ljava/util/ArrayList;)V
HSPLandroid/widget/ListView;->correctTooHigh(I)V
-HSPLandroid/widget/ListView;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/ListAdapter;Landroid/preference/PreferenceGroupAdapter;]Landroid/widget/ListView;Landroid/widget/ListView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/ListView;->dispatchDraw(Landroid/graphics/Canvas;)V
HSPLandroid/widget/ListView;->drawChild(Landroid/graphics/Canvas;Landroid/view/View;J)Z
HSPLandroid/widget/ListView;->fillDown(II)Landroid/view/View;
HSPLandroid/widget/ListView;->fillFromTop(I)Landroid/view/View;
@@ -20013,8 +20103,8 @@ HSPLandroid/widget/ListView;->isOpaque()Z
HSPLandroid/widget/ListView;->layoutChildren()V
HSPLandroid/widget/ListView;->lookForSelectablePosition(IZ)I
HSPLandroid/widget/ListView;->makeAndAddView(IIZIZ)Landroid/view/View;
-HSPLandroid/widget/ListView;->measureHeightOfChildren(IIIII)I+]Landroid/view/View;Landroid/widget/CheckedTextView;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;
-HSPLandroid/widget/ListView;->measureScrapChild(Landroid/view/View;III)V+]Landroid/view/View;Landroid/widget/CheckedTextView;
+HSPLandroid/widget/ListView;->measureHeightOfChildren(IIIII)I
+HSPLandroid/widget/ListView;->measureScrapChild(Landroid/view/View;III)V
HSPLandroid/widget/ListView;->onDetachedFromWindow()V
HSPLandroid/widget/ListView;->onFinishInflate()V
HSPLandroid/widget/ListView;->onMeasure(II)V
@@ -20026,8 +20116,8 @@ HSPLandroid/widget/ListView;->setAdapter(Landroid/widget/ListAdapter;)V
HSPLandroid/widget/ListView;->setCacheColorHint(I)V
HSPLandroid/widget/ListView;->setDivider(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/ListView;->setSelection(I)V
-HSPLandroid/widget/ListView;->setupChild(Landroid/view/View;IIZIZZ)V+]Landroid/util/SparseBooleanArray;Landroid/util/SparseBooleanArray;]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/Checkable;Landroid/widget/CheckedTextView;]Landroid/widget/ListAdapter;missing_types]Landroid/widget/ListView;missing_types
-HSPLandroid/widget/OverScroller$SplineOverScroller;-><init>(Landroid/content/Context;)V
+HSPLandroid/widget/ListView;->setupChild(Landroid/view/View;IIZIZZ)V
+HSPLandroid/widget/OverScroller$SplineOverScroller;-><init>(Landroid/content/Context;)V+]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLandroid/widget/OverScroller$SplineOverScroller;->adjustDuration(III)V
HSPLandroid/widget/OverScroller$SplineOverScroller;->continueWhenFinished()Z
HSPLandroid/widget/OverScroller$SplineOverScroller;->finish()V
@@ -20039,13 +20129,14 @@ HSPLandroid/widget/OverScroller$SplineOverScroller;->springback(III)Z
HSPLandroid/widget/OverScroller$SplineOverScroller;->startScroll(III)V
HSPLandroid/widget/OverScroller$SplineOverScroller;->startSpringback(III)V
HSPLandroid/widget/OverScroller$SplineOverScroller;->update()Z
+HSPLandroid/widget/OverScroller$SplineOverScroller;->updateScroll(F)V
HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;)V
HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;Landroid/view/animation/Interpolator;)V
HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;Landroid/view/animation/Interpolator;Z)V
HSPLandroid/widget/OverScroller;->abortAnimation()V
HSPLandroid/widget/OverScroller;->computeScrollOffset()Z
HSPLandroid/widget/OverScroller;->fling(IIIIIIII)V
-HSPLandroid/widget/OverScroller;->fling(IIIIIIIIII)V
+HSPLandroid/widget/OverScroller;->fling(IIIIIIIIII)V+]Landroid/widget/OverScroller;Landroid/widget/OverScroller;]Landroid/widget/OverScroller$SplineOverScroller;Landroid/widget/OverScroller$SplineOverScroller;
HSPLandroid/widget/OverScroller;->forceFinished(Z)V
HSPLandroid/widget/OverScroller;->getCurrVelocity()F
HSPLandroid/widget/OverScroller;->getCurrX()I
@@ -20133,7 +20224,7 @@ HSPLandroid/widget/ProgressBar;->getMin()I
HSPLandroid/widget/ProgressBar;->getProgress()I
HSPLandroid/widget/ProgressBar;->getProgressDrawable()Landroid/graphics/drawable/Drawable;
HSPLandroid/widget/ProgressBar;->initProgressBar()V
-HSPLandroid/widget/ProgressBar;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ProgressBar;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
HSPLandroid/widget/ProgressBar;->isIndeterminate()Z
HSPLandroid/widget/ProgressBar;->jumpDrawablesToCurrentState()V
HSPLandroid/widget/ProgressBar;->needsTileify(Landroid/graphics/drawable/Drawable;)Z
@@ -20173,8 +20264,8 @@ HSPLandroid/widget/RelativeLayout$DependencyGraph$Node;->release()V
HSPLandroid/widget/RelativeLayout$DependencyGraph;-><init>()V
HSPLandroid/widget/RelativeLayout$DependencyGraph;->add(Landroid/view/View;)V
HSPLandroid/widget/RelativeLayout$DependencyGraph;->clear()V
-HSPLandroid/widget/RelativeLayout$DependencyGraph;->findRoots([I)Ljava/util/ArrayDeque;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/widget/RelativeLayout$DependencyGraph;->getSortedViews([Landroid/view/View;[I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;
+HSPLandroid/widget/RelativeLayout$DependencyGraph;->findRoots([I)Ljava/util/ArrayDeque;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/RelativeLayout$DependencyGraph;->getSortedViews([Landroid/view/View;[I)V
HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmBottom(Landroid/widget/RelativeLayout$LayoutParams;)I
HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmLeft(Landroid/widget/RelativeLayout$LayoutParams;)I
HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmRight(Landroid/widget/RelativeLayout$LayoutParams;)I
@@ -20182,7 +20273,7 @@ HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmTop(Landroid/widge
HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fputmBottom(Landroid/widget/RelativeLayout$LayoutParams;I)V
HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fputmTop(Landroid/widget/RelativeLayout$LayoutParams;I)V
HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(II)V
-HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/widget/RelativeLayout$LayoutParams;->addRule(I)V
HSPLandroid/widget/RelativeLayout$LayoutParams;->addRule(II)V
HSPLandroid/widget/RelativeLayout$LayoutParams;->getRules()[I
@@ -20209,21 +20300,21 @@ HSPLandroid/widget/RelativeLayout;->generateLayoutParams(Landroid/view/ViewGroup
HSPLandroid/widget/RelativeLayout;->getAccessibilityClassName()Ljava/lang/CharSequence;
HSPLandroid/widget/RelativeLayout;->getBaseline()I
HSPLandroid/widget/RelativeLayout;->getChildMeasureSpec(IIIIIIII)I
-HSPLandroid/widget/RelativeLayout;->getRelatedView([II)Landroid/view/View;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;
+HSPLandroid/widget/RelativeLayout;->getRelatedView([II)Landroid/view/View;
HSPLandroid/widget/RelativeLayout;->getRelatedViewBaselineOffset([I)I
HSPLandroid/widget/RelativeLayout;->getRelatedViewParams([II)Landroid/widget/RelativeLayout$LayoutParams;
HSPLandroid/widget/RelativeLayout;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V
-HSPLandroid/widget/RelativeLayout;->measureChild(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/TextView;
-HSPLandroid/widget/RelativeLayout;->measureChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/TextView;
+HSPLandroid/widget/RelativeLayout;->measureChild(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V
+HSPLandroid/widget/RelativeLayout;->measureChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V
HSPLandroid/widget/RelativeLayout;->onLayout(ZIIII)V
-HSPLandroid/widget/RelativeLayout;->onMeasure(II)V+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
+HSPLandroid/widget/RelativeLayout;->onMeasure(II)V+]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;
HSPLandroid/widget/RelativeLayout;->positionAtEdge(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;I)V
-HSPLandroid/widget/RelativeLayout;->positionChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
-HSPLandroid/widget/RelativeLayout;->positionChildVertical(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;
+HSPLandroid/widget/RelativeLayout;->positionChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z
+HSPLandroid/widget/RelativeLayout;->positionChildVertical(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z
HSPLandroid/widget/RelativeLayout;->queryCompatibilityModes(Landroid/content/Context;)V
HSPLandroid/widget/RelativeLayout;->requestLayout()V
HSPLandroid/widget/RelativeLayout;->shouldDelayChildPressedState()Z
-HSPLandroid/widget/RelativeLayout;->sortChildren()V+]Landroid/widget/RelativeLayout$DependencyGraph;Landroid/widget/RelativeLayout$DependencyGraph;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
+HSPLandroid/widget/RelativeLayout;->sortChildren()V+]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;]Landroid/widget/RelativeLayout$DependencyGraph;Landroid/widget/RelativeLayout$DependencyGraph;
HSPLandroid/widget/RemoteViews$2;->createFromParcel(Landroid/os/Parcel;)Landroid/widget/RemoteViews;
HSPLandroid/widget/RemoteViews$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/widget/RemoteViews$Action;-><init>()V
@@ -20299,15 +20390,15 @@ HSPLandroid/widget/RtlSpacingHelper;->setAbsolute(II)V
HSPLandroid/widget/RtlSpacingHelper;->setDirection(Z)V
HSPLandroid/widget/RtlSpacingHelper;->setRelative(II)V
HSPLandroid/widget/ScrollBarDrawable;-><init>()V
-HSPLandroid/widget/ScrollBarDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
-HSPLandroid/widget/ScrollBarDrawable;->drawThumb(Landroid/graphics/Canvas;Landroid/graphics/Rect;IIZ)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
-HSPLandroid/widget/ScrollBarDrawable;->getSize(Z)I
-HSPLandroid/widget/ScrollBarDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
-HSPLandroid/widget/ScrollBarDrawable;->isStateful()Z
-HSPLandroid/widget/ScrollBarDrawable;->mutate()Landroid/widget/ScrollBarDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/widget/ScrollBarDrawable;->drawThumb(Landroid/graphics/Canvas;Landroid/graphics/Rect;IIZ)V
+HSPLandroid/widget/ScrollBarDrawable;->getSize(Z)I+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->isStateful()Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->mutate()Landroid/widget/ScrollBarDrawable;+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
HSPLandroid/widget/ScrollBarDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/widget/ScrollBarDrawable;->onStateChange([I)Z
-HSPLandroid/widget/ScrollBarDrawable;->propagateCurrentState(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ScrollBarDrawable;->propagateCurrentState(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
HSPLandroid/widget/ScrollBarDrawable;->setAlpha(I)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
HSPLandroid/widget/ScrollBarDrawable;->setAlwaysDrawVerticalTrack(Z)V
HSPLandroid/widget/ScrollBarDrawable;->setHorizontalThumbDrawable(Landroid/graphics/drawable/Drawable;)V
@@ -20422,34 +20513,34 @@ HSPLandroid/widget/TextView$TextAppearanceAttributes;-><init>(Landroid/widget/Te
HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;)V
HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/Context;missing_types]Landroid/widget/TextView;missing_types
HSPLandroid/widget/TextView;->addSearchHighlightPaths()V
HSPLandroid/widget/TextView;->addTextChangedListener(Landroid/text/TextWatcher;)V
HSPLandroid/widget/TextView;->applyCompoundDrawableTint()V
HSPLandroid/widget/TextView;->applySingleLine(ZZZZ)V
-HSPLandroid/widget/TextView;->applyTextAppearance(Landroid/widget/TextView$TextAppearanceAttributes;)V+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->applyTextAppearance(Landroid/widget/TextView$TextAppearanceAttributes;)V
HSPLandroid/widget/TextView;->assumeLayout()V
HSPLandroid/widget/TextView;->autoSizeText()V
HSPLandroid/widget/TextView;->beginBatchEdit()V
HSPLandroid/widget/TextView;->bringPointIntoView(I)Z
HSPLandroid/widget/TextView;->bringPointIntoView(IZ)Z
-HSPLandroid/widget/TextView;->bringTextIntoView()Z+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->bringTextIntoView()Z
HSPLandroid/widget/TextView;->canMarquee()Z
HSPLandroid/widget/TextView;->cancelLongPress()V
-HSPLandroid/widget/TextView;->checkForRelayout()V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->checkForRelayout()V
HSPLandroid/widget/TextView;->checkForResize()V
HSPLandroid/widget/TextView;->cleanupAutoSizePresetSizes([I)[I
-HSPLandroid/widget/TextView;->compressText(F)Z+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;Landroid/widget/CheckedTextView;,Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->compressText(F)Z
HSPLandroid/widget/TextView;->computeHorizontalScrollRange()I
HSPLandroid/widget/TextView;->computeScroll()V
-HSPLandroid/widget/TextView;->computeVerticalScrollExtent()I
-HSPLandroid/widget/TextView;->computeVerticalScrollRange()I
+HSPLandroid/widget/TextView;->computeVerticalScrollExtent()I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->computeVerticalScrollRange()I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;
HSPLandroid/widget/TextView;->convertToLocalHorizontalCoordinate(F)F
HSPLandroid/widget/TextView;->createEditorIfNeeded()V
HSPLandroid/widget/TextView;->didTouchFocusSelect()Z
HSPLandroid/widget/TextView;->doKeyDown(ILandroid/view/KeyEvent;Landroid/view/KeyEvent;)I
HSPLandroid/widget/TextView;->drawableHotspotChanged(FF)V
-HSPLandroid/widget/TextView;->drawableStateChanged()V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->drawableStateChanged()V
HSPLandroid/widget/TextView;->endBatchEdit()V
HSPLandroid/widget/TextView;->findLargestTextSizeWhichFits(Landroid/graphics/RectF;)I
HSPLandroid/widget/TextView;->fixFocusableAndClickableSettings()V
@@ -20458,10 +20549,10 @@ HSPLandroid/widget/TextView;->getAutoSizeStepGranularity()I
HSPLandroid/widget/TextView;->getAutofillHints()[Ljava/lang/String;
HSPLandroid/widget/TextView;->getAutofillType()I
HSPLandroid/widget/TextView;->getAutofillValue()Landroid/view/autofill/AutofillValue;
-HSPLandroid/widget/TextView;->getBaseline()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getBaselineOffset()I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getBaseline()I
+HSPLandroid/widget/TextView;->getBaselineOffset()I
HSPLandroid/widget/TextView;->getBottomVerticalOffset(Z)I
-HSPLandroid/widget/TextView;->getBoxHeight(Landroid/text/Layout;)I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getBoxHeight(Landroid/text/Layout;)I+]Landroid/widget/TextView;Landroid/widget/EditText;,Landroid/widget/Button;
HSPLandroid/widget/TextView;->getBreakStrategy()I
HSPLandroid/widget/TextView;->getCompoundDrawablePadding()I
HSPLandroid/widget/TextView;->getCompoundDrawables()[Landroid/graphics/drawable/Drawable;
@@ -20474,12 +20565,12 @@ HSPLandroid/widget/TextView;->getCurrentTextColor()I
HSPLandroid/widget/TextView;->getDefaultEditable()Z
HSPLandroid/widget/TextView;->getDefaultMovementMethod()Landroid/text/method/MovementMethod;
HSPLandroid/widget/TextView;->getDesiredHeight()I
-HSPLandroid/widget/TextView;->getDesiredHeight(Landroid/text/Layout;Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getDesiredHeight(Landroid/text/Layout;Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;Landroid/widget/TextView;
HSPLandroid/widget/TextView;->getEditableText()Landroid/text/Editable;
HSPLandroid/widget/TextView;->getEllipsize()Landroid/text/TextUtils$TruncateAt;
HSPLandroid/widget/TextView;->getError()Ljava/lang/CharSequence;
-HSPLandroid/widget/TextView;->getExtendedPaddingBottom()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getExtendedPaddingTop()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getExtendedPaddingBottom()I+]Landroid/text/Layout;Landroid/text/StaticLayout;]Landroid/widget/TextView;Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->getExtendedPaddingTop()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/widget/TextView;Landroid/widget/TextView;,Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/Button;
HSPLandroid/widget/TextView;->getFilters()[Landroid/text/InputFilter;
HSPLandroid/widget/TextView;->getFocusedRect(Landroid/graphics/Rect;)V
HSPLandroid/widget/TextView;->getFreezesText()Z
@@ -20495,7 +20586,7 @@ HSPLandroid/widget/TextView;->getInterestingRect(Landroid/graphics/Rect;I)V
HSPLandroid/widget/TextView;->getJustificationMode()I
HSPLandroid/widget/TextView;->getKeyListener()Landroid/text/method/KeyListener;
HSPLandroid/widget/TextView;->getLayout()Landroid/text/Layout;
-HSPLandroid/widget/TextView;->getLayoutAlignment()Landroid/text/Layout$Alignment;+]Landroid/widget/TextView;Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->getLayoutAlignment()Landroid/text/Layout$Alignment;
HSPLandroid/widget/TextView;->getLineAtCoordinate(F)I
HSPLandroid/widget/TextView;->getLineAtCoordinateUnclamped(F)I
HSPLandroid/widget/TextView;->getLineCount()I
@@ -20511,14 +20602,14 @@ HSPLandroid/widget/TextView;->getOffsetForPosition(FF)I
HSPLandroid/widget/TextView;->getPaint()Landroid/text/TextPaint;
HSPLandroid/widget/TextView;->getSelectionEnd()I
HSPLandroid/widget/TextView;->getSelectionEndTransformed()I
-HSPLandroid/widget/TextView;->getSelectionStart()I
+HSPLandroid/widget/TextView;->getSelectionStart()I+]Landroid/widget/TextView;missing_types
HSPLandroid/widget/TextView;->getSelectionStartTransformed()I
HSPLandroid/widget/TextView;->getServiceManagerForUser(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/widget/TextView;->getSpellCheckerLocale()Ljava/util/Locale;
HSPLandroid/widget/TextView;->getText()Ljava/lang/CharSequence;
HSPLandroid/widget/TextView;->getTextColors()Landroid/content/res/ColorStateList;
HSPLandroid/widget/TextView;->getTextCursorDrawable()Landroid/graphics/drawable/Drawable;
-HSPLandroid/widget/TextView;->getTextDirectionHeuristic()Landroid/text/TextDirectionHeuristic;+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getTextDirectionHeuristic()Landroid/text/TextDirectionHeuristic;
HSPLandroid/widget/TextView;->getTextLocale()Ljava/util/Locale;
HSPLandroid/widget/TextView;->getTextLocales()Landroid/os/LocaleList;
HSPLandroid/widget/TextView;->getTextSelectHandle()Landroid/graphics/drawable/Drawable;
@@ -20532,53 +20623,53 @@ HSPLandroid/widget/TextView;->getTotalPaddingTop()I
HSPLandroid/widget/TextView;->getTransformationMethod()Landroid/text/method/TransformationMethod;
HSPLandroid/widget/TextView;->getTypeface()Landroid/graphics/Typeface;
HSPLandroid/widget/TextView;->getTypefaceStyle()I
-HSPLandroid/widget/TextView;->getUpdatedHighlightPath()Landroid/graphics/Path;+]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getVerticalOffset(Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/widget/TextView;->getUpdatedHighlightPath()Landroid/graphics/Path;
+HSPLandroid/widget/TextView;->getVerticalOffset(Z)I
HSPLandroid/widget/TextView;->handleBackInTextActionModeIfNeeded(Landroid/view/KeyEvent;)Z
HSPLandroid/widget/TextView;->handleTextChanged(Ljava/lang/CharSequence;III)V
HSPLandroid/widget/TextView;->hasGesturePreviewHighlight()Z
-HSPLandroid/widget/TextView;->hasOverlappingRendering()Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/widget/TextView;->hasOverlappingRendering()Z
HSPLandroid/widget/TextView;->hasPasswordTransformationMethod()Z
HSPLandroid/widget/TextView;->hasSelection()Z
HSPLandroid/widget/TextView;->hideErrorIfUnchanged()V
HSPLandroid/widget/TextView;->invalidateCursor()V
HSPLandroid/widget/TextView;->invalidateCursorPath()V
-HSPLandroid/widget/TextView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/RippleDrawable;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/Button;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/VectorDrawable;
HSPLandroid/widget/TextView;->invalidateRegion(IIZ)V
HSPLandroid/widget/TextView;->isAnyPasswordInputType()Z
HSPLandroid/widget/TextView;->isAutoSizeEnabled()Z
HSPLandroid/widget/TextView;->isAutofillable()Z
HSPLandroid/widget/TextView;->isFallbackLineSpacingForStaticLayout()Z
-HSPLandroid/widget/TextView;->isFromPrimePointer(Landroid/view/MotionEvent;Z)Z
+HSPLandroid/widget/TextView;->isFromPrimePointer(Landroid/view/MotionEvent;Z)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/widget/TextView;->isInBatchEditMode()Z
HSPLandroid/widget/TextView;->isInExtractedMode()Z
HSPLandroid/widget/TextView;->isInputMethodTarget()Z
HSPLandroid/widget/TextView;->isMarqueeFadeEnabled()Z
HSPLandroid/widget/TextView;->isMultilineInputType(I)Z
HSPLandroid/widget/TextView;->isPasswordInputType(I)Z
-HSPLandroid/widget/TextView;->isPositionVisible(FF)Z
+HSPLandroid/widget/TextView;->isPositionVisible(FF)Z+]Landroid/view/View;missing_types]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
HSPLandroid/widget/TextView;->isShowingHint()Z
HSPLandroid/widget/TextView;->isSuggestionsEnabled()Z
HSPLandroid/widget/TextView;->isTextAutofillable()Z
HSPLandroid/widget/TextView;->isTextEditable()Z
HSPLandroid/widget/TextView;->isTextSelectable()Z
HSPLandroid/widget/TextView;->isVisibleToAccessibility()Z
-HSPLandroid/widget/TextView;->jumpDrawablesToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/TextView;->jumpDrawablesToCurrentState()V
HSPLandroid/widget/TextView;->length()I
-HSPLandroid/widget/TextView;->makeNewLayout(IILandroid/text/BoringLayout$Metrics;Landroid/text/BoringLayout$Metrics;IZ)V+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->makeSingleLayout(ILandroid/text/BoringLayout$Metrics;ILandroid/text/Layout$Alignment;ZLandroid/text/TextUtils$TruncateAt;Z)Landroid/text/Layout;+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/widget/TextView;->maybeUpdateHighlightPaths()V+]Landroid/widget/TextView;missing_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/widget/TextView;->makeNewLayout(IILandroid/text/BoringLayout$Metrics;Landroid/text/BoringLayout$Metrics;IZ)V+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;,Landroid/widget/Button;
+HSPLandroid/widget/TextView;->makeSingleLayout(ILandroid/text/BoringLayout$Metrics;ILandroid/text/Layout$Alignment;ZLandroid/text/TextUtils$TruncateAt;Z)Landroid/text/Layout;+]Landroid/text/DynamicLayout$Builder;Landroid/text/DynamicLayout$Builder;]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;
+HSPLandroid/widget/TextView;->maybeUpdateHighlightPaths()V
HSPLandroid/widget/TextView;->notifyContentCaptureTextChanged()V
-HSPLandroid/widget/TextView;->notifyListeningManagersAfterTextChanged()V+]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->notifyListeningManagersAfterTextChanged()V
HSPLandroid/widget/TextView;->nullLayouts()V
HSPLandroid/widget/TextView;->onAttachedToWindow()V
HSPLandroid/widget/TextView;->onBeginBatchEdit()V
HSPLandroid/widget/TextView;->onCheckIsTextEditor()Z
HSPLandroid/widget/TextView;->onConfigurationChanged(Landroid/content/res/Configuration;)V
-HSPLandroid/widget/TextView;->onCreateDrawableState(I)[I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onCreateDrawableState(I)[I
HSPLandroid/widget/TextView;->onCreateInputConnection(Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection;
HSPLandroid/widget/TextView;->onDetachedFromWindowInternal()V
-HSPLandroid/widget/TextView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/widget/TextView;missing_types]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/widget/Editor;Landroid/widget/Editor;]Ljava/lang/CharSequence;Landroid/text/SpannableStringBuilder;
HSPLandroid/widget/TextView;->onEditorAction(I)V
HSPLandroid/widget/TextView;->onEndBatchEdit()V
HSPLandroid/widget/TextView;->onFocusChanged(ZILandroid/graphics/Rect;)V
@@ -20589,7 +20680,7 @@ HSPLandroid/widget/TextView;->onKeyPreIme(ILandroid/view/KeyEvent;)Z
HSPLandroid/widget/TextView;->onKeyUp(ILandroid/view/KeyEvent;)Z
HSPLandroid/widget/TextView;->onLayout(ZIIII)V
HSPLandroid/widget/TextView;->onLocaleChanged()V
-HSPLandroid/widget/TextView;->onMeasure(II)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/DynamicLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onMeasure(II)V+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;,Landroid/widget/Button;
HSPLandroid/widget/TextView;->onPreDraw()Z
HSPLandroid/widget/TextView;->onProvideStructure(Landroid/view/ViewStructure;II)V
HSPLandroid/widget/TextView;->onResolveDrawables(I)V
@@ -20606,7 +20697,7 @@ HSPLandroid/widget/TextView;->onVisibilityChanged(Landroid/view/View;I)V
HSPLandroid/widget/TextView;->onWindowFocusChanged(Z)V
HSPLandroid/widget/TextView;->originalToTransformed(II)I
HSPLandroid/widget/TextView;->preloadFontCache()V
-HSPLandroid/widget/TextView;->readTextAppearance(Landroid/content/Context;Landroid/content/res/TypedArray;Landroid/widget/TextView$TextAppearanceAttributes;Z)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/util/TypedValue;Landroid/util/TypedValue;
+HSPLandroid/widget/TextView;->readTextAppearance(Landroid/content/Context;Landroid/content/res/TypedArray;Landroid/widget/TextView$TextAppearanceAttributes;Z)V+]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/Context;missing_types
HSPLandroid/widget/TextView;->registerForPreDraw()V
HSPLandroid/widget/TextView;->removeAdjacentSuggestionSpans(I)V
HSPLandroid/widget/TextView;->removeIntersectingNonAdjacentSpans(IILjava/lang/Class;)V
@@ -20626,7 +20717,7 @@ HSPLandroid/widget/TextView;->setAutoSizeTextTypeUniformWithPresetSizes([II)V
HSPLandroid/widget/TextView;->setBreakStrategy(I)V
HSPLandroid/widget/TextView;->setCompoundDrawablePadding(I)V
HSPLandroid/widget/TextView;->setCompoundDrawableTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/widget/TextView;->setCompoundDrawables(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->setCompoundDrawables(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/TextView;->setCompoundDrawablesRelative(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/TextView;->setCompoundDrawablesRelativeWithIntrinsicBounds(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/TextView;->setCompoundDrawablesWithIntrinsicBounds(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
@@ -20656,7 +20747,7 @@ HSPLandroid/widget/TextView;->setInputTypeFromEditor()V
HSPLandroid/widget/TextView;->setInputTypeSingleLine(Z)V
HSPLandroid/widget/TextView;->setKeyListener(Landroid/text/method/KeyListener;)V
HSPLandroid/widget/TextView;->setKeyListenerOnly(Landroid/text/method/KeyListener;)V
-HSPLandroid/widget/TextView;->setLetterSpacing(F)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/widget/TextView;->setLetterSpacing(F)V
HSPLandroid/widget/TextView;->setLineHeight(I)V
HSPLandroid/widget/TextView;->setLineSpacing(FF)V
HSPLandroid/widget/TextView;->setLines(I)V
@@ -20673,7 +20764,7 @@ HSPLandroid/widget/TextView;->setPadding(IIII)V
HSPLandroid/widget/TextView;->setPaddingRelative(IIII)V
HSPLandroid/widget/TextView;->setPrivateImeOptions(Ljava/lang/String;)V
HSPLandroid/widget/TextView;->setRawInputType(I)V
-HSPLandroid/widget/TextView;->setRawTextSize(FZ)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/widget/TextView;->setRawTextSize(FZ)V
HSPLandroid/widget/TextView;->setRelativeDrawablesIfNeeded(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/TextView;->setSelected(Z)V
HSPLandroid/widget/TextView;->setShadowLayer(FFFI)V
@@ -20682,7 +20773,7 @@ HSPLandroid/widget/TextView;->setSingleLine(Z)V
HSPLandroid/widget/TextView;->setText(I)V
HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;)V
-HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V+]Landroid/text/Editable$Factory;Landroid/text/Editable$Factory;]Landroid/text/InputFilter;Landroid/text/InputFilter$LengthFilter;]Landroid/text/Spannable$Factory;Landroid/text/Spannable$Factory;]Landroid/text/Spannable;Landroid/text/SpannableString;,Landroid/text/SpannableStringBuilder;]Landroid/text/Spanned;Landroid/text/SpannableStringBuilder;,Landroid/text/SpannedString;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/method/MovementMethod;Landroid/text/method/ArrowKeyMovementMethod;,Landroid/text/method/LinkMovementMethod;]Landroid/text/method/TransformationMethod;Landroid/text/method/AllCapsTransformationMethod;,Landroid/text/method/SingleLineTransformationMethod;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Landroid/text/SpannableString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannedString;,Ljava/lang/String;
+HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V+]Landroid/text/Editable$Factory;Landroid/text/Editable$Factory;]Landroid/text/method/MovementMethod;Landroid/text/method/ArrowKeyMovementMethod;,Landroid/text/method/ScrollingMovementMethod;]Landroid/text/method/TransformationMethod;Landroid/text/method/SingleLineTransformationMethod;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/text/InputFilter;Landroid/text/InputFilter$LengthFilter;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;]Landroid/text/Spannable$Factory;Landroid/text/Spannable$Factory;]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/text/Spannable;Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;
HSPLandroid/widget/TextView;->setTextAppearance(I)V
HSPLandroid/widget/TextView;->setTextAppearance(Landroid/content/Context;I)V
HSPLandroid/widget/TextView;->setTextColor(I)V
@@ -20694,14 +20785,14 @@ HSPLandroid/widget/TextView;->setTextSize(IF)V
HSPLandroid/widget/TextView;->setTextSizeInternal(IFZ)V
HSPLandroid/widget/TextView;->setTransformationMethod(Landroid/text/method/TransformationMethod;)V
HSPLandroid/widget/TextView;->setTransformationMethodInternal(Landroid/text/method/TransformationMethod;Z)V
-HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
-HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;I)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;)V
+HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;I)V
HSPLandroid/widget/TextView;->setTypefaceFromAttrs(Landroid/graphics/Typeface;Ljava/lang/String;III)V
HSPLandroid/widget/TextView;->setupAutoSizeText()Z
HSPLandroid/widget/TextView;->setupAutoSizeUniformPresetSizesConfiguration()Z
HSPLandroid/widget/TextView;->shouldAdvanceFocusOnEnter()Z
HSPLandroid/widget/TextView;->spanChange(Landroid/text/Spanned;Ljava/lang/Object;IIII)V
-HSPLandroid/widget/TextView;->startMarquee()V+]Landroid/widget/TextView;Landroid/widget/CheckedTextView;,Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->startMarquee()V
HSPLandroid/widget/TextView;->startStopMarquee(Z)V
HSPLandroid/widget/TextView;->stopMarquee()V
HSPLandroid/widget/TextView;->stopTextActionMode()V
@@ -20711,8 +20802,8 @@ HSPLandroid/widget/TextView;->textCanBeSelected()Z
HSPLandroid/widget/TextView;->unregisterForPreDraw()V
HSPLandroid/widget/TextView;->updateAfterEdit()V
HSPLandroid/widget/TextView;->updateCursorVisibleInternal()V
-HSPLandroid/widget/TextView;->updateTextColors()V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/widget/TextView;->useDynamicLayout()Z+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->updateTextColors()V
+HSPLandroid/widget/TextView;->useDynamicLayout()Z
HSPLandroid/widget/TextView;->validateAndSetAutoSizeTextTypeUniformConfiguration(FFF)V
HSPLandroid/widget/TextView;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
HSPLandroid/widget/TextView;->viewClicked(Landroid/view/inputmethod/InputMethodManager;)V
@@ -20773,6 +20864,7 @@ HSPLandroid/widget/inline/InlinePresentationSpec$1;->createFromParcel(Landroid/o
HSPLandroid/widget/inline/InlinePresentationSpec;-><clinit>()V
HSPLandroid/widget/inline/InlinePresentationSpec;-><init>(Landroid/os/Parcel;)V
HSPLandroid/widget/inline/InlinePresentationSpec;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/window/BackProgressAnimator;-><init>()V+]Lcom/android/internal/dynamicanimation/animation/SpringAnimation;Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Lcom/android/internal/dynamicanimation/animation/SpringForce;Lcom/android/internal/dynamicanimation/animation/SpringForce;
HSPLandroid/window/ClientWindowFrames$1;-><init>()V
HSPLandroid/window/ClientWindowFrames$1;->createFromParcel(Landroid/os/Parcel;)Landroid/window/ClientWindowFrames;
HSPLandroid/window/ClientWindowFrames$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -20890,6 +20982,8 @@ HSPLandroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;->
HSPLandroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;->onBackCancelled()V
HSPLandroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;->onBackInvoked()V
HSPLandroid/window/WindowOnBackInvokedDispatcher;-><clinit>()V
+HSPLandroid/window/WindowOnBackInvokedDispatcher;-><init>(Landroid/content/Context;)V
+HSPLandroid/window/WindowOnBackInvokedDispatcher;->attachToWindow(Landroid/view/IWindowSession;Landroid/view/IWindow;)V
HSPLandroid/window/WindowOnBackInvokedDispatcher;->clear()V
HSPLandroid/window/WindowOnBackInvokedDispatcher;->detachFromWindow()V
HSPLandroid/window/WindowOnBackInvokedDispatcher;->getTopCallback()Landroid/window/OnBackInvokedCallback;
@@ -20925,12 +21019,12 @@ HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getMetadataForRegion(Ljava/l
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getMetadataForRegionOrCallingCode(ILjava/lang/String;)Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNationalSignificantNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberDescByType(Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;)Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberTypeHelper(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberTypeHelper(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;+]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;]Lcom/android/i18n/phonenumbers/PhoneNumberUtil;Lcom/android/i18n/phonenumbers/PhoneNumberUtil;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForCountryCode(I)Ljava/lang/String;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumberFromRegionList(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/util/List;)Ljava/lang/String;
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumberFromRegionList(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/util/List;)Ljava/lang/String;+]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;]Ljava/util/List;Ljava/util/ArrayList;]Lcom/android/i18n/phonenumbers/PhoneNumberUtil;Lcom/android/i18n/phonenumbers/PhoneNumberUtil;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->hasFormattingPatternForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isNumberMatchingDesc(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;)Z
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isNumberMatchingDesc(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;)Z+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/i18n/phonenumbers/internal/MatcherApi;Lcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;]Ljava/util/List;Ljava/util/ArrayList;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidNumberForRegion(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/lang/String;)Z
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidRegionCode(Ljava/lang/String;)Z
@@ -21035,8 +21129,8 @@ HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setCountryCode(I)Lco
HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setCountryCodeSource(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setNationalNumber(J)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setRawInput(Ljava/lang/String;)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
-HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->match(Ljava/lang/CharSequence;Ljava/util/regex/Pattern;Z)Z
-HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->matchNationalNumber(Ljava/lang/CharSequence;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Z)Z
+HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->match(Ljava/lang/CharSequence;Ljava/util/regex/Pattern;Z)Z+]Ljava/util/regex/Matcher;Ljava/util/regex/Matcher;]Ljava/util/regex/Pattern;Ljava/util/regex/Pattern;
+HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->matchNationalNumber(Ljava/lang/CharSequence;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Z)Z+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;]Lcom/android/i18n/phonenumbers/internal/RegexCache;Lcom/android/i18n/phonenumbers/internal/RegexCache;
HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z
HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache;->put(Ljava/lang/Object;Ljava/lang/Object;)V
@@ -21114,10 +21208,10 @@ HSPLcom/android/i18n/timezone/internal/NioBufferIterator;->readInt()I
HSPLcom/android/i18n/timezone/internal/NioBufferIterator;->readLongArray([JII)V
HSPLcom/android/i18n/timezone/internal/NioBufferIterator;->skip(I)V
HSPLcom/android/icu/charset/CharsetDecoderICU;-><init>(Ljava/nio/charset/Charset;FJ)V
-HSPLcom/android/icu/charset/CharsetDecoderICU;->decodeLoop(Ljava/nio/ByteBuffer;Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;
-HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/ByteBuffer;)I
-HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/CharBuffer;)I
-HSPLcom/android/icu/charset/CharsetDecoderICU;->implFlush(Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->decodeLoop(Ljava/nio/ByteBuffer;Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/ByteBuffer;)I+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/CharBuffer;)I+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->implFlush(Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;+]Lcom/android/icu/charset/CharsetDecoderICU;Lcom/android/icu/charset/CharsetDecoderICU;
HSPLcom/android/icu/charset/CharsetDecoderICU;->implOnMalformedInput(Ljava/nio/charset/CodingErrorAction;)V
HSPLcom/android/icu/charset/CharsetDecoderICU;->implOnUnmappableCharacter(Ljava/nio/charset/CodingErrorAction;)V
HSPLcom/android/icu/charset/CharsetDecoderICU;->implReplaceWith(Ljava/lang/String;)V
@@ -21127,16 +21221,16 @@ HSPLcom/android/icu/charset/CharsetDecoderICU;->setPosition(Ljava/nio/ByteBuffer
HSPLcom/android/icu/charset/CharsetDecoderICU;->setPosition(Ljava/nio/CharBuffer;)V
HSPLcom/android/icu/charset/CharsetDecoderICU;->updateCallback()V
HSPLcom/android/icu/charset/CharsetEncoderICU;-><init>(Ljava/nio/charset/Charset;FF[BJ)V
-HSPLcom/android/icu/charset/CharsetEncoderICU;->encodeLoop(Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;
-HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/ByteBuffer;)I
-HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/CharBuffer;)I
+HSPLcom/android/icu/charset/CharsetEncoderICU;->encodeLoop(Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
+HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/ByteBuffer;)I+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/CharBuffer;)I+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
HSPLcom/android/icu/charset/CharsetEncoderICU;->implFlush(Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;
HSPLcom/android/icu/charset/CharsetEncoderICU;->implOnMalformedInput(Ljava/nio/charset/CodingErrorAction;)V
HSPLcom/android/icu/charset/CharsetEncoderICU;->implOnUnmappableCharacter(Ljava/nio/charset/CodingErrorAction;)V
HSPLcom/android/icu/charset/CharsetEncoderICU;->implReset()V
HSPLcom/android/icu/charset/CharsetEncoderICU;->makeReplacement(Ljava/lang/String;J)[B
HSPLcom/android/icu/charset/CharsetEncoderICU;->newInstance(Ljava/nio/charset/Charset;Ljava/lang/String;)Lcom/android/icu/charset/CharsetEncoderICU;
-HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/ByteBuffer;)V
+HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/ByteBuffer;)V+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/CharBuffer;)V
HSPLcom/android/icu/charset/CharsetEncoderICU;->updateCallback()V
HSPLcom/android/icu/charset/CharsetFactory;->create(Ljava/lang/String;)Ljava/nio/charset/Charset;
@@ -21176,7 +21270,7 @@ HSPLcom/android/icu/util/ExtendedTimeZone;->utcStartTime(JLandroid/icu/util/Time
HSPLcom/android/icu/util/LocaleNative;->getDisplayCountry(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String;
HSPLcom/android/icu/util/LocaleNative;->getDisplayLanguage(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String;
HSPLcom/android/icu/util/LocaleNative;->setDefault(Ljava/lang/String;)V
-HSPLcom/android/icu/util/regex/MatcherNative;-><init>(Lcom/android/icu/util/regex/PatternNative;)V
+HSPLcom/android/icu/util/regex/MatcherNative;-><init>(Lcom/android/icu/util/regex/PatternNative;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;]Lcom/android/icu/util/regex/PatternNative;Lcom/android/icu/util/regex/PatternNative;
HSPLcom/android/icu/util/regex/MatcherNative;->create(Lcom/android/icu/util/regex/PatternNative;)Lcom/android/icu/util/regex/MatcherNative;
HSPLcom/android/icu/util/regex/MatcherNative;->find(I[I)Z
HSPLcom/android/icu/util/regex/MatcherNative;->findNext([I)Z
@@ -21188,7 +21282,7 @@ HSPLcom/android/icu/util/regex/MatcherNative;->requireEnd()Z
HSPLcom/android/icu/util/regex/MatcherNative;->setInput(Ljava/lang/String;II)V
HSPLcom/android/icu/util/regex/MatcherNative;->useAnchoringBounds(Z)V
HSPLcom/android/icu/util/regex/MatcherNative;->useTransparentBounds(Z)V
-HSPLcom/android/icu/util/regex/PatternNative;-><init>(Ljava/lang/String;I)V
+HSPLcom/android/icu/util/regex/PatternNative;-><init>(Ljava/lang/String;I)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
HSPLcom/android/icu/util/regex/PatternNative;->create(Ljava/lang/String;I)Lcom/android/icu/util/regex/PatternNative;
HSPLcom/android/icu/util/regex/PatternNative;->openMatcher()J
HSPLcom/android/internal/app/AlertController;-><init>(Landroid/content/Context;Landroid/content/DialogInterface;Landroid/view/Window;)V
@@ -21272,6 +21366,8 @@ HSPLcom/android/internal/content/ReferrerIntent$1;->createFromParcel(Landroid/os
HSPLcom/android/internal/content/ReferrerIntent$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLcom/android/internal/display/BrightnessSynchronizer;-><clinit>()V
HSPLcom/android/internal/display/BrightnessSynchronizer;->floatEquals(FF)Z
+HSPLcom/android/internal/dynamicanimation/animation/DynamicAnimation;-><init>(Ljava/lang/Object;Landroid/util/FloatProperty;)V
+HSPLcom/android/internal/dynamicanimation/animation/SpringForce;-><init>()V
HSPLcom/android/internal/graphics/ColorUtils;->HSLToColor([F)I
HSPLcom/android/internal/graphics/ColorUtils;->RGBToHSL(III[F)V
HSPLcom/android/internal/graphics/ColorUtils;->colorToHSL(I[F)V
@@ -21400,7 +21496,7 @@ HSPLcom/android/internal/listeners/ListenerExecutor$ListenerOperation;->onComple
HSPLcom/android/internal/listeners/ListenerExecutor$ListenerOperation;->onPostExecute(Z)V
HSPLcom/android/internal/listeners/ListenerExecutor$ListenerOperation;->onPreExecute()V
HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;)V
-HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V+]Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda2;,Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda3;]Ljava/util/concurrent/Executor;Landroid/net/connectivity/com/android/modules/utils/HandlerExecutor;,Landroid/os/HandlerExecutor;,Lcom/android/wifi/x/com/android/modules/utils/HandlerExecutor;]Ljava/util/function/Supplier;Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda1;
+HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V
HSPLcom/android/internal/listeners/ListenerExecutor;->lambda$executeSafely$0(Ljava/lang/Object;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V
HSPLcom/android/internal/logging/AndroidConfig;-><init>()V
HSPLcom/android/internal/logging/AndroidHandler$1;->format(Ljava/util/logging/LogRecord;)Ljava/lang/String;
@@ -21641,33 +21737,42 @@ HSPLcom/android/internal/policy/DecorView$ColorViewAttributes;->isPresent(ZIZ)Z
HSPLcom/android/internal/policy/DecorView$ColorViewAttributes;->isVisible(ZIIZ)Z
HSPLcom/android/internal/policy/DecorView$ColorViewState;-><init>(Lcom/android/internal/policy/DecorView$ColorViewAttributes;)V
HSPLcom/android/internal/policy/DecorView;-><init>(Landroid/content/Context;ILcom/android/internal/policy/PhoneWindow;Landroid/view/WindowManager$LayoutParams;)V
-HSPLcom/android/internal/policy/DecorView;->calculateNavigationBarColor(I)I
-HSPLcom/android/internal/policy/DecorView;->calculateStatusBarColor(I)I
+HSPLcom/android/internal/policy/DecorView;->calculateNavigationBarColor(I)I+]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->calculateStatusBarColor(I)I+]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->createDecorCaptionView(Landroid/view/LayoutInflater;)Lcom/android/internal/widget/DecorCaptionView;
HSPLcom/android/internal/policy/DecorView;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
HSPLcom/android/internal/policy/DecorView;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
HSPLcom/android/internal/policy/DecorView;->draw(Landroid/graphics/Canvas;)V
HSPLcom/android/internal/policy/DecorView;->drawLegacyNavigationBarBackground(Landroid/graphics/RecordingCanvas;)V
HSPLcom/android/internal/policy/DecorView;->drawableChanged()V
+HSPLcom/android/internal/policy/DecorView;->enableCaption(Z)V
+HSPLcom/android/internal/policy/DecorView;->enforceNonTranslucentBackground(Landroid/graphics/drawable/Drawable;Z)Landroid/graphics/drawable/Drawable;
HSPLcom/android/internal/policy/DecorView;->finishChanging()V
+HSPLcom/android/internal/policy/DecorView;->gatherTransparentRegion(Landroid/graphics/Region;)Z
+HSPLcom/android/internal/policy/DecorView;->gatherTransparentRegion(Lcom/android/internal/policy/DecorView$ColorViewState;Landroid/graphics/Region;)Z
HSPLcom/android/internal/policy/DecorView;->getAccessibilityViewId()I
HSPLcom/android/internal/policy/DecorView;->getBackground()Landroid/graphics/drawable/Drawable;
+HSPLcom/android/internal/policy/DecorView;->getCaptionHeight()I
+HSPLcom/android/internal/policy/DecorView;->getCaptionInsetsHeight()I
HSPLcom/android/internal/policy/DecorView;->getNavBarSize(III)I
-HSPLcom/android/internal/policy/DecorView;->getResources()Landroid/content/res/Resources;+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->getTitleSuffix(Landroid/view/WindowManager$LayoutParams;)Ljava/lang/String;
-HSPLcom/android/internal/policy/DecorView;->getWindowInsetsController()Landroid/view/WindowInsetsController;
+HSPLcom/android/internal/policy/DecorView;->getResources()Landroid/content/res/Resources;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;
+HSPLcom/android/internal/policy/DecorView;->getTitleSuffix(Landroid/view/WindowManager$LayoutParams;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLcom/android/internal/policy/DecorView;->getWindowInsetsController()Landroid/view/WindowInsetsController;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
HSPLcom/android/internal/policy/DecorView;->initializeElevation()V
HSPLcom/android/internal/policy/DecorView;->isNavBarToLeftEdge(II)Z
HSPLcom/android/internal/policy/DecorView;->isNavBarToRightEdge(II)Z
+HSPLcom/android/internal/policy/DecorView;->isResizing()Z
+HSPLcom/android/internal/policy/DecorView;->isShowingCaption()Z
HSPLcom/android/internal/policy/DecorView;->onApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
HSPLcom/android/internal/policy/DecorView;->onAttachedToWindow()V
HSPLcom/android/internal/policy/DecorView;->onCloseSystemDialogs(Ljava/lang/String;)V
HSPLcom/android/internal/policy/DecorView;->onConfigurationChanged(Landroid/content/res/Configuration;)V
HSPLcom/android/internal/policy/DecorView;->onContentDrawn(IIII)Z
HSPLcom/android/internal/policy/DecorView;->onDetachedFromWindow()V
-HSPLcom/android/internal/policy/DecorView;->onDraw(Landroid/graphics/Canvas;)V
+HSPLcom/android/internal/policy/DecorView;->onDraw(Landroid/graphics/Canvas;)V+]Lcom/android/internal/widget/BackgroundFallback;Lcom/android/internal/widget/BackgroundFallback;
HSPLcom/android/internal/policy/DecorView;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z
-HSPLcom/android/internal/policy/DecorView;->onLayout(ZIIII)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->onMeasure(II)V+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->onLayout(ZIIII)V
+HSPLcom/android/internal/policy/DecorView;->onMeasure(II)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLcom/android/internal/policy/DecorView;->onPostDraw(Landroid/graphics/RecordingCanvas;)V
HSPLcom/android/internal/policy/DecorView;->onResourcesLoaded(Landroid/view/LayoutInflater;I)V
HSPLcom/android/internal/policy/DecorView;->onRootViewScrollYChanged(I)V
@@ -21676,12 +21781,13 @@ HSPLcom/android/internal/policy/DecorView;->onTouchEvent(Landroid/view/MotionEve
HSPLcom/android/internal/policy/DecorView;->onWindowFocusChanged(Z)V
HSPLcom/android/internal/policy/DecorView;->onWindowSystemUiVisibilityChanged(I)V
HSPLcom/android/internal/policy/DecorView;->providePendingInsetsController()Landroid/view/PendingInsetsController;
+HSPLcom/android/internal/policy/DecorView;->releaseThreadedRenderer()V
HSPLcom/android/internal/policy/DecorView;->removeBackgroundBlurDrawable()V
HSPLcom/android/internal/policy/DecorView;->sendAccessibilityEvent(I)V
HSPLcom/android/internal/policy/DecorView;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLcom/android/internal/policy/DecorView;->setBackgroundFallback(Landroid/graphics/drawable/Drawable;)V
HSPLcom/android/internal/policy/DecorView;->setColor(Landroid/view/View;IIZZ)V
-HSPLcom/android/internal/policy/DecorView;->setFrame(IIII)Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
+HSPLcom/android/internal/policy/DecorView;->setFrame(IIII)Z+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;
HSPLcom/android/internal/policy/DecorView;->setWindow(Lcom/android/internal/policy/PhoneWindow;)V
HSPLcom/android/internal/policy/DecorView;->setWindowBackground(Landroid/graphics/drawable/Drawable;)V
HSPLcom/android/internal/policy/DecorView;->setWindowFrame(Landroid/graphics/drawable/Drawable;)V
@@ -21689,12 +21795,13 @@ HSPLcom/android/internal/policy/DecorView;->startChanging()V
HSPLcom/android/internal/policy/DecorView;->superDispatchKeyEvent(Landroid/view/KeyEvent;)Z
HSPLcom/android/internal/policy/DecorView;->superDispatchTouchEvent(Landroid/view/MotionEvent;)Z
HSPLcom/android/internal/policy/DecorView;->updateBackgroundBlurRadius()V
-HSPLcom/android/internal/policy/DecorView;->updateBackgroundDrawable()V
-HSPLcom/android/internal/policy/DecorView;->updateColorViewInt(Lcom/android/internal/policy/DecorView$ColorViewState;IIIZZIZZI)V+]Landroid/view/View;Landroid/view/View;]Landroid/view/ViewPropertyAnimator;Landroid/view/ViewPropertyAnimator;]Lcom/android/internal/policy/DecorView$ColorViewAttributes;Lcom/android/internal/policy/DecorView$ColorViewAttributes;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->updateBackgroundDrawable()V+]Landroid/graphics/Insets;Landroid/graphics/Insets;
+HSPLcom/android/internal/policy/DecorView;->updateColorViewInt(Lcom/android/internal/policy/DecorView$ColorViewState;IIIZZIZZI)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Landroid/view/View;Landroid/view/View;]Landroid/view/ViewPropertyAnimator;Landroid/view/ViewPropertyAnimator;]Lcom/android/internal/policy/DecorView$ColorViewAttributes;Lcom/android/internal/policy/DecorView$ColorViewAttributes;
HSPLcom/android/internal/policy/DecorView;->updateColorViewTranslations()V
-HSPLcom/android/internal/policy/DecorView;->updateColorViews(Landroid/view/WindowInsets;Z)Landroid/view/WindowInsets;+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ViewGroup;Landroid/widget/LinearLayout;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;]Landroid/view/WindowInsetsController;Landroid/view/InsetsController;,Landroid/view/PendingInsetsController;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
-HSPLcom/android/internal/policy/DecorView;->updateElevation()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->updateLogTag(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/DecorView;->updateColorViews(Landroid/view/WindowInsets;Z)Landroid/view/WindowInsets;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Landroid/view/ViewGroup;Landroid/widget/LinearLayout;]Landroid/view/WindowInsetsController;Landroid/view/InsetsController;,Landroid/view/PendingInsetsController;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLcom/android/internal/policy/DecorView;->updateDecorCaptionStatus(Landroid/content/res/Configuration;)V
+HSPLcom/android/internal/policy/DecorView;->updateElevation()V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLcom/android/internal/policy/DecorView;->updateLogTag(Landroid/view/WindowManager$LayoutParams;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLcom/android/internal/policy/DecorView;->updateStatusGuard(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
HSPLcom/android/internal/policy/DecorView;->willYouTakeTheInputQueue()Landroid/view/InputQueue$Callback;
HSPLcom/android/internal/policy/DecorView;->willYouTakeTheSurface()Landroid/view/SurfaceHolder$Callback2;
@@ -21728,10 +21835,10 @@ HSPLcom/android/internal/policy/PhoneWindow;->applyDecorFitsSystemWindows()V
HSPLcom/android/internal/policy/PhoneWindow;->closeAllPanels()V
HSPLcom/android/internal/policy/PhoneWindow;->closeContextMenu()V
HSPLcom/android/internal/policy/PhoneWindow;->closePanel(Lcom/android/internal/policy/PhoneWindow$PanelFeatureState;Z)V
-HSPLcom/android/internal/policy/PhoneWindow;->dispatchWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/PhoneWindow;->dispatchWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
HSPLcom/android/internal/policy/PhoneWindow;->doInvalidatePanelMenu(I)V
HSPLcom/android/internal/policy/PhoneWindow;->generateDecor(I)Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/PhoneWindow;->generateLayout(Lcom/android/internal/policy/DecorView;)Landroid/view/ViewGroup;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Ljava/lang/Boolean;Ljava/lang/Boolean;
+HSPLcom/android/internal/policy/PhoneWindow;->generateLayout(Lcom/android/internal/policy/DecorView;)Landroid/view/ViewGroup;
HSPLcom/android/internal/policy/PhoneWindow;->getCurrentFocus()Landroid/view/View;
HSPLcom/android/internal/policy/PhoneWindow;->getDecorView()Landroid/view/View;
HSPLcom/android/internal/policy/PhoneWindow;->getLayoutInflater()Landroid/view/LayoutInflater;
@@ -21759,7 +21866,7 @@ HSPLcom/android/internal/policy/PhoneWindow;->peekDecorView()Landroid/view/View;
HSPLcom/android/internal/policy/PhoneWindow;->requestFeature(I)Z
HSPLcom/android/internal/policy/PhoneWindow;->restoreHierarchyState(Landroid/os/Bundle;)V
HSPLcom/android/internal/policy/PhoneWindow;->saveHierarchyState()Landroid/os/Bundle;
-HSPLcom/android/internal/policy/PhoneWindow;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/PhoneWindow;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
HSPLcom/android/internal/policy/PhoneWindow;->setBackgroundBlurRadius(I)V
HSPLcom/android/internal/policy/PhoneWindow;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLcom/android/internal/policy/PhoneWindow;->setContentView(I)V
@@ -21832,6 +21939,7 @@ HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getAvailableSubscriptionInf
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultDataSubId()I
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSmsSubId()I
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSubId()I
+HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSubIdAsUser(I)I
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultVoiceSubId()I
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getPhoneId(I)I
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getSlotIndex(I)I
@@ -21917,7 +22025,7 @@ HSPLcom/android/internal/util/ArrayUtils;->convertToIntArray(Ljava/util/List;)[I
HSPLcom/android/internal/util/ArrayUtils;->deepToString(Ljava/lang/Object;)Ljava/lang/String;
HSPLcom/android/internal/util/ArrayUtils;->defeatNullable([Ljava/io/File;)[Ljava/io/File;
HSPLcom/android/internal/util/ArrayUtils;->defeatNullable([Ljava/lang/String;)[Ljava/lang/String;
-HSPLcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/Class;]Ljava/lang/Class;Ljava/lang/Class;
HSPLcom/android/internal/util/ArrayUtils;->emptyIfNull([Ljava/lang/Object;Ljava/lang/Class;)[Ljava/lang/Object;
HSPLcom/android/internal/util/ArrayUtils;->filter([Ljava/lang/Object;Ljava/util/function/IntFunction;Ljava/util/function/Predicate;)[Ljava/lang/Object;
HSPLcom/android/internal/util/ArrayUtils;->getOrNull([Ljava/lang/Object;I)Ljava/lang/Object;
@@ -21925,14 +22033,14 @@ HSPLcom/android/internal/util/ArrayUtils;->indexOf([Ljava/lang/Object;Ljava/lang
HSPLcom/android/internal/util/ArrayUtils;->isEmpty(Ljava/util/Collection;)Z
HSPLcom/android/internal/util/ArrayUtils;->isEmpty([I)Z
HSPLcom/android/internal/util/ArrayUtils;->isEmpty([Ljava/lang/Object;)Z
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object;+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedBooleanArray(I)[Z
HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedByteArray(I)[B
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedCharArray(I)[C
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedCharArray(I)[C+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedFloatArray(I)[F
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedLongArray(I)[J
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedObjectArray(I)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedObjectArray(I)[Ljava/lang/Object;+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
HSPLcom/android/internal/util/ArrayUtils;->remove(Ljava/util/ArrayList;Ljava/lang/Object;)Ljava/util/ArrayList;
HSPLcom/android/internal/util/ArrayUtils;->removeElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
HSPLcom/android/internal/util/ArrayUtils;->size([Ljava/lang/Object;)I
@@ -21973,13 +22081,13 @@ HSPLcom/android/internal/util/FastPrintWriter;->print(J)V
HSPLcom/android/internal/util/FastPrintWriter;->print(Ljava/lang/String;)V
HSPLcom/android/internal/util/FastPrintWriter;->println()V
HSPLcom/android/internal/util/FastPrintWriter;->write(I)V
-HSPLcom/android/internal/util/FastPrintWriter;->write(Ljava/lang/String;)V
+HSPLcom/android/internal/util/FastPrintWriter;->write(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
HSPLcom/android/internal/util/FastPrintWriter;->write([CII)V
HSPLcom/android/internal/util/FastXmlSerializer;-><init>()V
HSPLcom/android/internal/util/FastXmlSerializer;-><init>(I)V
HSPLcom/android/internal/util/FastXmlSerializer;->append(C)V
HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
-HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;II)V+]Ljava/lang/String;Ljava/lang/String;
+HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;II)V+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/internal/util/FastXmlSerializer;Lcom/android/internal/util/FastXmlSerializer;
HSPLcom/android/internal/util/FastXmlSerializer;->appendIndent(I)V+]Ljava/lang/String;Ljava/lang/String;
HSPLcom/android/internal/util/FastXmlSerializer;->attribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
HSPLcom/android/internal/util/FastXmlSerializer;->endDocument()V
@@ -22001,12 +22109,12 @@ HSPLcom/android/internal/util/FrameworkStatsLog;->write(ILjava/lang/String;I)V
HSPLcom/android/internal/util/FrameworkStatsLog;->write(ILjava/lang/String;IIF)V
HSPLcom/android/internal/util/GrowingArrayUtils;->append([III)[I
HSPLcom/android/internal/util/GrowingArrayUtils;->append([JIJ)[J
-HSPLcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;
+HSPLcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;
HSPLcom/android/internal/util/GrowingArrayUtils;->append([ZIZ)[Z
HSPLcom/android/internal/util/GrowingArrayUtils;->growSize(I)I
HSPLcom/android/internal/util/GrowingArrayUtils;->insert([IIII)[I
HSPLcom/android/internal/util/GrowingArrayUtils;->insert([JIIJ)[J
-HSPLcom/android/internal/util/GrowingArrayUtils;->insert([Ljava/lang/Object;IILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;[Ljava/lang/Object;
+HSPLcom/android/internal/util/GrowingArrayUtils;->insert([Ljava/lang/Object;IILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Object;[Ljava/lang/Object;]Ljava/lang/Class;Ljava/lang/Class;
HSPLcom/android/internal/util/GrowingArrayUtils;->insert([ZIIZ)[Z
HSPLcom/android/internal/util/IndentingPrintWriter;->decreaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
HSPLcom/android/internal/util/IndentingPrintWriter;->increaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
@@ -22076,7 +22184,7 @@ HSPLcom/android/internal/util/Preconditions;->checkStringNotEmpty(Ljava/lang/Cha
HSPLcom/android/internal/util/ProcFileReader;->finishLine()V
HSPLcom/android/internal/util/ScreenshotHelper;-><init>(Landroid/content/Context;)V
HSPLcom/android/internal/util/StatLogger;->getTime()J
-HSPLcom/android/internal/util/StatLogger;->logDurationStat(IJ)J+]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;
+HSPLcom/android/internal/util/StatLogger;->logDurationStat(IJ)J
HSPLcom/android/internal/util/State;-><init>()V
HSPLcom/android/internal/util/State;->enter()V
HSPLcom/android/internal/util/StateMachine$LogRecords;->add(Lcom/android/internal/util/StateMachine;Landroid/os/Message;Ljava/lang/String;Lcom/android/internal/util/IState;Lcom/android/internal/util/IState;Lcom/android/internal/util/IState;)V
@@ -22128,7 +22236,7 @@ HSPLcom/android/internal/util/XmlSerializerWrapper;->endTag(Ljava/lang/String;Lj
HSPLcom/android/internal/util/XmlSerializerWrapper;->setFeature(Ljava/lang/String;Z)V
HSPLcom/android/internal/util/XmlSerializerWrapper;->setOutput(Ljava/io/OutputStream;Ljava/lang/String;)V
HSPLcom/android/internal/util/XmlSerializerWrapper;->startDocument(Ljava/lang/String;Ljava/lang/Boolean;)V
-HSPLcom/android/internal/util/XmlSerializerWrapper;->startTag(Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;+]Lorg/xmlpull/v1/XmlSerializer;Lcom/android/internal/util/FastXmlSerializer;
+HSPLcom/android/internal/util/XmlSerializerWrapper;->startTag(Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
HSPLcom/android/internal/util/XmlSerializerWrapper;->text(Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
HSPLcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;-><init>(Lorg/xmlpull/v1/XmlPullParser;)V
HSPLcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;->getAttributeBoolean(I)Z
@@ -22151,19 +22259,19 @@ HSPLcom/android/internal/util/XmlUtils;->readLongAttribute(Lorg/xmlpull/v1/XmlPu
HSPLcom/android/internal/util/XmlUtils;->readLongAttribute(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;J)J
HSPLcom/android/internal/util/XmlUtils;->readMapXml(Ljava/io/InputStream;)Ljava/util/HashMap;
HSPLcom/android/internal/util/XmlUtils;->readStringAttribute(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;)Ljava/lang/String;
-HSPLcom/android/internal/util/XmlUtils;->readThisMapXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;)Ljava/util/HashMap;
-HSPLcom/android/internal/util/XmlUtils;->readThisPrimitiveValueXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;)Ljava/lang/Object;
+HSPLcom/android/internal/util/XmlUtils;->readThisMapXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;)Ljava/util/HashMap;+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
+HSPLcom/android/internal/util/XmlUtils;->readThisPrimitiveValueXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
HSPLcom/android/internal/util/XmlUtils;->readThisSetXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/util/HashSet;
-HSPLcom/android/internal/util/XmlUtils;->readThisValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/lang/Object;
+HSPLcom/android/internal/util/XmlUtils;->readThisValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Lcom/android/internal/util/XmlUtils$ReadMapCallback;Landroid/os/PersistableBundle$MyReadMapCallback;
HSPLcom/android/internal/util/XmlUtils;->readValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;)Ljava/lang/Object;
HSPLcom/android/internal/util/XmlUtils;->skipCurrentTag(Lorg/xmlpull/v1/XmlPullParser;)V
-HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/util/Map;Ljava/util/HashMap;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
+HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V
HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/io/OutputStream;)V
HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V
HSPLcom/android/internal/util/XmlUtils;->writeSetXml(Ljava/util/Set;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
-HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlSerializer;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/Object;Ljava/lang/String;
+HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlSerializer;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/Float;Ljava/lang/Float;
HSPLcom/android/internal/util/function/pooled/OmniFunction;->run()V
HSPLcom/android/internal/util/function/pooled/PooledLambda;->obtainMessage(Lcom/android/internal/util/function/HexConsumer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
HSPLcom/android/internal/util/function/pooled/PooledLambda;->obtainMessage(Lcom/android/internal/util/function/QuadConsumer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
@@ -22199,6 +22307,7 @@ HSPLcom/android/internal/view/AppearanceRegion;->equals(Ljava/lang/Object;)Z
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->addClient(Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/inputmethod/IRemoteInputConnection;I)V
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getEnabledInputMethodList(I)Ljava/util/List;
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getImeTrackerService()Lcom/android/internal/inputmethod/IImeTracker;
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->isImeTraceEnabled()Z
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->removeImeSurfaceFromWindowAsync(Landroid/os/IBinder;)V
@@ -22243,7 +22352,7 @@ HSPLcom/android/internal/widget/AlertDialogLayout;->onMeasure(II)V
HSPLcom/android/internal/widget/AlertDialogLayout;->setChildFrame(Landroid/view/View;IIII)V
HSPLcom/android/internal/widget/AlertDialogLayout;->tryOnMeasure(II)Z
HSPLcom/android/internal/widget/BackgroundFallback;-><init>()V
-HSPLcom/android/internal/widget/BackgroundFallback;->draw(Landroid/view/ViewGroup;Landroid/view/ViewGroup;Landroid/graphics/Canvas;Landroid/view/View;Landroid/view/View;Landroid/view/View;)V
+HSPLcom/android/internal/widget/BackgroundFallback;->draw(Landroid/view/ViewGroup;Landroid/view/ViewGroup;Landroid/graphics/Canvas;Landroid/view/View;Landroid/view/View;Landroid/view/View;)V+]Lcom/android/internal/widget/BackgroundFallback;Lcom/android/internal/widget/BackgroundFallback;
HSPLcom/android/internal/widget/BackgroundFallback;->hasFallback()Z
HSPLcom/android/internal/widget/BackgroundFallback;->setDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLcom/android/internal/widget/ButtonBarLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
@@ -22262,6 +22371,7 @@ HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker;->handleStron
HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker;->isNonStrongBiometricAllowedAfterIdleTimeout(I)Z
HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker;->onIsNonStrongBiometricAllowedChanged(I)V
HSPLcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;)V
+HSPLcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;Lcom/android/internal/widget/ILockSettings;)V+]Landroid/content/Context;Landroid/app/ContextImpl;,Landroid/app/ReceiverRestrictedContext;
HSPLcom/android/internal/widget/LockPatternUtils;->credentialTypeToPasswordQuality(I)I
HSPLcom/android/internal/widget/LockPatternUtils;->getBoolean(Ljava/lang/String;ZI)Z
HSPLcom/android/internal/widget/LockPatternUtils;->getCredentialTypeForUser(I)I
@@ -22277,8 +22387,8 @@ HSPLcom/android/internal/widget/LockPatternUtils;->isOwnerInfoEnabled(I)Z
HSPLcom/android/internal/widget/LockPatternUtils;->isSecure(I)Z
HSPLcom/android/internal/widget/LockPatternUtils;->isSeparateProfileChallengeEnabled(I)Z
HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeBoolean(Ljava/lang/String;Ljava/lang/String;)Z+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
-HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeFloat(Ljava/lang/String;Ljava/lang/String;)F+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
-HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndex(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;]Ljava/lang/Object;Ljava/lang/String;
+HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeFloat(Ljava/lang/String;Ljava/lang/String;)F
+HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndex(Ljava/lang/String;Ljava/lang/String;)I+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndexOrThrow(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeInt(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeLong(Ljava/lang/String;Ljava/lang/String;)J+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
@@ -22297,6 +22407,12 @@ HSPLcom/android/telephony/Rlog;->e(Ljava/lang/String;Ljava/lang/String;)I
HSPLcom/android/telephony/Rlog;->log(ILjava/lang/String;Ljava/lang/String;)I
HSPLcom/android/telephony/Rlog;->pii(ZLjava/lang/Object;)Ljava/lang/String;
HSPLcom/android/telephony/Rlog;->w(Ljava/lang/String;Ljava/lang/String;)I
+HSPLcom/android/text/flags/FeatureFlagsImpl;-><init>()V
+HSPLcom/android/text/flags/Flags;-><clinit>()V
+HSPLcom/android/window/flags/FeatureFlagsImpl;-><init>()V
+HSPLcom/android/window/flags/FeatureFlagsImpl;->bundleClientTransactionFlag()Z
+HSPLcom/android/window/flags/Flags;-><clinit>()V
+HSPLcom/android/window/flags/Flags;->bundleClientTransactionFlag()Z+]Lcom/android/window/flags/FeatureFlags;Lcom/android/window/flags/FeatureFlagsImpl;
HSPLcom/google/android/collect/Lists;->newArrayList()Ljava/util/ArrayList;
HSPLcom/google/android/collect/Lists;->newArrayList([Ljava/lang/Object;)Ljava/util/ArrayList;
HSPLcom/google/android/collect/Maps;->newHashMap()Ljava/util/HashMap;
@@ -22330,8 +22446,8 @@ HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->getURI(I)Ljava/lang/String;
HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->getValue(I)Ljava/lang/String;
HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->getValue(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->removeAttribute(I)V
-HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->setAttributes(Lorg/xml/sax/Attributes;)V+]Lorg/ccil/cowan/tagsoup/AttributesImpl;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;
-HSPLorg/ccil/cowan/tagsoup/Element;-><init>(Lorg/ccil/cowan/tagsoup/ElementType;Z)V+]Lorg/ccil/cowan/tagsoup/ElementType;Lorg/ccil/cowan/tagsoup/ElementType;
+HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->setAttributes(Lorg/xml/sax/Attributes;)V
+HSPLorg/ccil/cowan/tagsoup/Element;-><init>(Lorg/ccil/cowan/tagsoup/ElementType;Z)V
HSPLorg/ccil/cowan/tagsoup/Element;->atts()Lorg/ccil/cowan/tagsoup/AttributesImpl;
HSPLorg/ccil/cowan/tagsoup/Element;->canContain(Lorg/ccil/cowan/tagsoup/Element;)Z
HSPLorg/ccil/cowan/tagsoup/Element;->clean()V
@@ -22360,10 +22476,10 @@ HSPLorg/ccil/cowan/tagsoup/HTMLScanner;-><init>()V
HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->mark()V
HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->resetDocumentLocator(Ljava/lang/String;Ljava/lang/String;)V
HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->save(ILorg/ccil/cowan/tagsoup/ScanHandler;)V
-HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->scan(Ljava/io/Reader;Lorg/ccil/cowan/tagsoup/ScanHandler;)V+]Ljava/io/PushbackReader;Ljava/io/PushbackReader;]Lorg/ccil/cowan/tagsoup/ScanHandler;Lorg/ccil/cowan/tagsoup/Parser;
+HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->scan(Ljava/io/Reader;Lorg/ccil/cowan/tagsoup/ScanHandler;)V
HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->unread(Ljava/io/PushbackReader;I)V
HSPLorg/ccil/cowan/tagsoup/Parser$1;-><init>(Lorg/ccil/cowan/tagsoup/Parser;)V
-HSPLorg/ccil/cowan/tagsoup/Parser;-><init>()V+]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLorg/ccil/cowan/tagsoup/Parser;-><init>()V
HSPLorg/ccil/cowan/tagsoup/Parser;->aname([CII)V
HSPLorg/ccil/cowan/tagsoup/Parser;->aval([CII)V
HSPLorg/ccil/cowan/tagsoup/Parser;->entity([CII)V
@@ -22378,16 +22494,16 @@ HSPLorg/ccil/cowan/tagsoup/Parser;->getReader(Lorg/xml/sax/InputSource;)Ljava/io
HSPLorg/ccil/cowan/tagsoup/Parser;->gi([CII)V
HSPLorg/ccil/cowan/tagsoup/Parser;->lookupEntity([CII)I
HSPLorg/ccil/cowan/tagsoup/Parser;->makeName([CII)Ljava/lang/String;
-HSPLorg/ccil/cowan/tagsoup/Parser;->parse(Lorg/xml/sax/InputSource;)V+]Ljava/lang/Object;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Scanner;Lorg/ccil/cowan/tagsoup/HTMLScanner;]Lorg/ccil/cowan/tagsoup/Schema;Lorg/ccil/cowan/tagsoup/HTMLSchema;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;]Lorg/xml/sax/InputSource;Lorg/xml/sax/InputSource;
+HSPLorg/ccil/cowan/tagsoup/Parser;->parse(Lorg/xml/sax/InputSource;)V
HSPLorg/ccil/cowan/tagsoup/Parser;->pcdata([CII)V
-HSPLorg/ccil/cowan/tagsoup/Parser;->pop()V+]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;
+HSPLorg/ccil/cowan/tagsoup/Parser;->pop()V
HSPLorg/ccil/cowan/tagsoup/Parser;->prefixOf(Ljava/lang/String;)Ljava/lang/String;
-HSPLorg/ccil/cowan/tagsoup/Parser;->push(Lorg/ccil/cowan/tagsoup/Element;)V+]Ljava/lang/String;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;
-HSPLorg/ccil/cowan/tagsoup/Parser;->rectify(Lorg/ccil/cowan/tagsoup/Element;)V+]Ljava/lang/Object;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;
+HSPLorg/ccil/cowan/tagsoup/Parser;->push(Lorg/ccil/cowan/tagsoup/Element;)V
+HSPLorg/ccil/cowan/tagsoup/Parser;->rectify(Lorg/ccil/cowan/tagsoup/Element;)V
HSPLorg/ccil/cowan/tagsoup/Parser;->restart(Lorg/ccil/cowan/tagsoup/Element;)V
HSPLorg/ccil/cowan/tagsoup/Parser;->setContentHandler(Lorg/xml/sax/ContentHandler;)V
HSPLorg/ccil/cowan/tagsoup/Parser;->setProperty(Ljava/lang/String;Ljava/lang/Object;)V
-HSPLorg/ccil/cowan/tagsoup/Parser;->setup()V+]Lorg/ccil/cowan/tagsoup/Schema;Lorg/ccil/cowan/tagsoup/HTMLSchema;
+HSPLorg/ccil/cowan/tagsoup/Parser;->setup()V
HSPLorg/ccil/cowan/tagsoup/Parser;->stagc([CII)V
HSPLorg/ccil/cowan/tagsoup/Parser;->truthValue(Z)Ljava/lang/Boolean;
HSPLorg/ccil/cowan/tagsoup/Schema;->getElementType(Ljava/lang/String;)Lorg/ccil/cowan/tagsoup/ElementType;
@@ -22447,6 +22563,7 @@ Landroid/accounts/AuthenticatorDescription$1;
Landroid/accounts/AuthenticatorDescription-IA;
Landroid/accounts/AuthenticatorDescription;
Landroid/accounts/AuthenticatorException;
+Landroid/accounts/IAccountAuthenticator$Stub$Proxy;
Landroid/accounts/IAccountAuthenticator$Stub;
Landroid/accounts/IAccountAuthenticator;
Landroid/accounts/IAccountAuthenticatorResponse$Stub$Proxy;
@@ -22455,6 +22572,7 @@ Landroid/accounts/IAccountAuthenticatorResponse;
Landroid/accounts/IAccountManager$Stub$Proxy;
Landroid/accounts/IAccountManager$Stub;
Landroid/accounts/IAccountManager;
+Landroid/accounts/IAccountManagerResponse$Stub$Proxy;
Landroid/accounts/IAccountManagerResponse$Stub;
Landroid/accounts/IAccountManagerResponse;
Landroid/accounts/NetworkErrorException;
@@ -22583,6 +22701,7 @@ Landroid/app/ActivityClient$ActivityClientControllerSingleton-IA;
Landroid/app/ActivityClient$ActivityClientControllerSingleton;
Landroid/app/ActivityClient-IA;
Landroid/app/ActivityClient;
+Landroid/app/ActivityManager$1;
Landroid/app/ActivityManager$2;
Landroid/app/ActivityManager$3;
Landroid/app/ActivityManager$AppTask;
@@ -22615,7 +22734,6 @@ Landroid/app/ActivityManagerInternal;
Landroid/app/ActivityOptions$1;
Landroid/app/ActivityOptions$2;
Landroid/app/ActivityOptions$OnAnimationStartedListener;
-Landroid/app/ActivityOptions$SceneTransitionInfo$1;
Landroid/app/ActivityOptions$SceneTransitionInfo;
Landroid/app/ActivityOptions$SourceInfo$1;
Landroid/app/ActivityOptions$SourceInfo;
@@ -22677,7 +22795,6 @@ Landroid/app/AlarmManager;
Landroid/app/AlertDialog$Builder;
Landroid/app/AlertDialog;
Landroid/app/AppCompatCallbacks;
-Landroid/app/AppCompatTaskInfo$1;
Landroid/app/AppCompatTaskInfo;
Landroid/app/AppComponentFactory;
Landroid/app/AppDetailsActivity;
@@ -22690,6 +22807,7 @@ Landroid/app/AppOpsManager$$ExternalSyntheticLambda4;
Landroid/app/AppOpsManager$$ExternalSyntheticLambda5;
Landroid/app/AppOpsManager$$ExternalSyntheticLambda6;
Landroid/app/AppOpsManager$1;
+Landroid/app/AppOpsManager$2;
Landroid/app/AppOpsManager$3;
Landroid/app/AppOpsManager$4;
Landroid/app/AppOpsManager$AppOpsCollector;
@@ -22766,11 +22884,9 @@ Landroid/app/BackStackRecord$Op;
Landroid/app/BackStackRecord;
Landroid/app/BackStackState$1;
Landroid/app/BackStackState;
-Landroid/app/BackgroundInstallControlManager;
Landroid/app/BackgroundServiceStartNotAllowedException$1;
Landroid/app/BackgroundServiceStartNotAllowedException;
Landroid/app/BroadcastOptions;
-Landroid/app/CameraCompatTaskInfo;
Landroid/app/ClientTransactionHandler;
Landroid/app/ComponentCaller;
Landroid/app/ComponentOptions;
@@ -22915,6 +23031,7 @@ Landroid/app/IServiceConnection;
Landroid/app/IStopUserCallback$Stub$Proxy;
Landroid/app/IStopUserCallback$Stub;
Landroid/app/IStopUserCallback;
+Landroid/app/ITaskStackListener$Stub$Proxy;
Landroid/app/ITaskStackListener$Stub;
Landroid/app/ITaskStackListener;
Landroid/app/ITransientNotification$Stub$Proxy;
@@ -23037,6 +23154,7 @@ Landroid/app/PendingIntent$$ExternalSyntheticLambda3;
Landroid/app/PendingIntent$1;
Landroid/app/PendingIntent$CancelListener;
Landroid/app/PendingIntent$CanceledException;
+Landroid/app/PendingIntent$FinishedDispatcher;
Landroid/app/PendingIntent$OnFinished;
Landroid/app/PendingIntent$OnMarshaledListener;
Landroid/app/PendingIntent;
@@ -23086,7 +23204,6 @@ Landroid/app/ResourcesManager$ActivityResources-IA;
Landroid/app/ResourcesManager$ActivityResources;
Landroid/app/ResourcesManager$ApkAssetsSupplier;
Landroid/app/ResourcesManager$ApkKey;
-Landroid/app/ResourcesManager$SharedLibraryAssets;
Landroid/app/ResourcesManager$UpdateHandler-IA;
Landroid/app/ResourcesManager$UpdateHandler;
Landroid/app/ResourcesManager;
@@ -23118,6 +23235,7 @@ Landroid/app/SharedPreferencesImpl$EditorImpl;
Landroid/app/SharedPreferencesImpl$MemoryCommitResult-IA;
Landroid/app/SharedPreferencesImpl$MemoryCommitResult;
Landroid/app/SharedPreferencesImpl$SharedPreferencesThreadFactory;
+Landroid/app/SharedPreferencesImpl;
Landroid/app/StackTrace;
Landroid/app/StatusBarManager;
Landroid/app/SyncNotedAppOp$1;
@@ -23168,12 +23286,8 @@ Landroid/app/SystemServiceRegistry$138;
Landroid/app/SystemServiceRegistry$139;
Landroid/app/SystemServiceRegistry$13;
Landroid/app/SystemServiceRegistry$140;
-Landroid/app/SystemServiceRegistry$141;
-Landroid/app/SystemServiceRegistry$142;
Landroid/app/SystemServiceRegistry$143;
Landroid/app/SystemServiceRegistry$144;
-Landroid/app/SystemServiceRegistry$145;
-Landroid/app/SystemServiceRegistry$146;
Landroid/app/SystemServiceRegistry$14;
Landroid/app/SystemServiceRegistry$15;
Landroid/app/SystemServiceRegistry$16;
@@ -23481,13 +23595,13 @@ Landroid/app/contentsuggestions/SelectionsRequest$1;
Landroid/app/contentsuggestions/SelectionsRequest$Builder;
Landroid/app/contentsuggestions/SelectionsRequest-IA;
Landroid/app/contentsuggestions/SelectionsRequest;
-Landroid/app/contextualsearch/ContextualSearchManager;
Landroid/app/job/IJobCallback$Stub$Proxy;
Landroid/app/job/IJobCallback$Stub;
Landroid/app/job/IJobCallback;
Landroid/app/job/IJobScheduler$Stub$Proxy;
Landroid/app/job/IJobScheduler$Stub;
Landroid/app/job/IJobScheduler;
+Landroid/app/job/IJobService$Stub$Proxy;
Landroid/app/job/IJobService$Stub;
Landroid/app/job/IJobService;
Landroid/app/job/IUserVisibleJobObserver;
@@ -23506,14 +23620,15 @@ Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda0;
Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda1;
Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda2;
Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda3;
+Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda4;
Landroid/app/job/JobSchedulerFrameworkInitializer;
Landroid/app/job/JobService$1;
Landroid/app/job/JobService;
Landroid/app/job/JobServiceEngine$JobHandler;
+Landroid/app/job/JobServiceEngine$JobInterface;
Landroid/app/job/JobServiceEngine;
Landroid/app/job/JobWorkItem$1;
Landroid/app/job/JobWorkItem;
-Landroid/app/ondeviceintelligence/OnDeviceIntelligenceManager;
Landroid/app/people/IPeopleManager$Stub$Proxy;
Landroid/app/people/IPeopleManager$Stub;
Landroid/app/people/IPeopleManager;
@@ -23593,6 +23708,7 @@ Landroid/app/servertransaction/TopResumedActivityChangeItem-IA;
Landroid/app/servertransaction/TopResumedActivityChangeItem;
Landroid/app/servertransaction/TransactionExecutor;
Landroid/app/servertransaction/TransactionExecutorHelper;
+Landroid/app/servertransaction/WindowStateResizeItem$ResizeListener;
Landroid/app/slice/ISliceManager$Stub$Proxy;
Landroid/app/slice/ISliceManager$Stub;
Landroid/app/slice/ISliceManager;
@@ -23644,6 +23760,7 @@ Landroid/app/smartspace/uitemplatedata/TapAction$1;
Landroid/app/smartspace/uitemplatedata/TapAction;
Landroid/app/smartspace/uitemplatedata/Text$1;
Landroid/app/smartspace/uitemplatedata/Text;
+Landroid/app/tare/EconomyManager;
Landroid/app/time/ITimeZoneDetectorListener$Stub$Proxy;
Landroid/app/time/ITimeZoneDetectorListener$Stub;
Landroid/app/time/ITimeZoneDetectorListener;
@@ -23705,8 +23822,6 @@ Landroid/app/usage/ConfigurationStats;
Landroid/app/usage/EventList;
Landroid/app/usage/ExternalStorageStats$1;
Landroid/app/usage/ExternalStorageStats;
-Landroid/app/usage/FeatureFlags;
-Landroid/app/usage/FeatureFlagsImpl;
Landroid/app/usage/Flags;
Landroid/app/usage/ICacheQuotaService$Stub$Proxy;
Landroid/app/usage/ICacheQuotaService$Stub;
@@ -23746,8 +23861,6 @@ Landroid/appwidget/AppWidgetProviderInfo$1;
Landroid/appwidget/AppWidgetProviderInfo;
Landroid/appwidget/PendingHostUpdate$1;
Landroid/appwidget/PendingHostUpdate;
-Landroid/appwidget/flags/FeatureFlags;
-Landroid/appwidget/flags/FeatureFlagsImpl;
Landroid/appwidget/flags/Flags;
Landroid/attention/AttentionManagerInternal$AttentionCallbackInternal;
Landroid/attention/AttentionManagerInternal;
@@ -23766,7 +23879,6 @@ Landroid/companion/virtual/IVirtualDevice;
Landroid/companion/virtual/IVirtualDeviceManager$Stub$Proxy;
Landroid/companion/virtual/IVirtualDeviceManager$Stub;
Landroid/companion/virtual/IVirtualDeviceManager;
-Landroid/companion/virtual/VirtualDevice;
Landroid/companion/virtual/VirtualDeviceManager;
Landroid/companion/virtual/flags/FeatureFlags;
Landroid/companion/virtual/flags/FeatureFlagsImpl;
@@ -23814,8 +23926,8 @@ Landroid/content/ComponentName$1;
Landroid/content/ComponentName$WithComponentName;
Landroid/content/ComponentName;
Landroid/content/ContentCaptureOptions$1;
+Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda0;
Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;
-Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;
Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
Landroid/content/ContentCaptureOptions;
Landroid/content/ContentInterface;
@@ -23836,10 +23948,12 @@ Landroid/content/ContentProviderOperation$Builder-IA;
Landroid/content/ContentProviderOperation$Builder;
Landroid/content/ContentProviderOperation-IA;
Landroid/content/ContentProviderOperation;
+Landroid/content/ContentProviderProxy;
Landroid/content/ContentProviderResult$1;
Landroid/content/ContentProviderResult;
Landroid/content/ContentResolver$1;
Landroid/content/ContentResolver$2;
+Landroid/content/ContentResolver$CursorWrapperInner;
Landroid/content/ContentResolver$OpenResourceIdResult;
Landroid/content/ContentResolver$ParcelFileDescriptorInner;
Landroid/content/ContentResolver$ResultListener-IA;
@@ -23891,6 +24005,7 @@ Landroid/content/ISyncAdapterUnsyncableAccountCallback;
Landroid/content/ISyncContext$Stub$Proxy;
Landroid/content/ISyncContext$Stub;
Landroid/content/ISyncContext;
+Landroid/content/ISyncStatusObserver$Stub$Proxy;
Landroid/content/ISyncStatusObserver$Stub;
Landroid/content/ISyncStatusObserver;
Landroid/content/Intent$1;
@@ -23993,7 +24108,6 @@ Landroid/content/pm/ApplicationInfo$1$$ExternalSyntheticLambda0;
Landroid/content/pm/ApplicationInfo$1;
Landroid/content/pm/ApplicationInfo-IA;
Landroid/content/pm/ApplicationInfo;
-Landroid/content/pm/ArchivedPackageParcel$1;
Landroid/content/pm/ArchivedPackageParcel;
Landroid/content/pm/Attribution$1;
Landroid/content/pm/Attribution;
@@ -24017,6 +24131,8 @@ Landroid/content/pm/DataLoaderParams;
Landroid/content/pm/DataLoaderParamsParcel$1;
Landroid/content/pm/DataLoaderParamsParcel;
Landroid/content/pm/FallbackCategoryProvider;
+Landroid/content/pm/FeatureFlags;
+Landroid/content/pm/FeatureFlagsImpl;
Landroid/content/pm/FeatureGroupInfo$1;
Landroid/content/pm/FeatureGroupInfo;
Landroid/content/pm/FeatureInfo$1;
@@ -24024,6 +24140,7 @@ Landroid/content/pm/FeatureInfo-IA;
Landroid/content/pm/FeatureInfo;
Landroid/content/pm/FileSystemControlParcel$1;
Landroid/content/pm/FileSystemControlParcel;
+Landroid/content/pm/Flags;
Landroid/content/pm/ICrossProfileApps$Stub$Proxy;
Landroid/content/pm/ICrossProfileApps$Stub;
Landroid/content/pm/ICrossProfileApps;
@@ -24040,6 +24157,7 @@ Landroid/content/pm/IDexModuleRegisterCallback;
Landroid/content/pm/ILauncherApps$Stub$Proxy;
Landroid/content/pm/ILauncherApps$Stub;
Landroid/content/pm/ILauncherApps;
+Landroid/content/pm/IOnAppsChangedListener$Stub$Proxy;
Landroid/content/pm/IOnAppsChangedListener$Stub;
Landroid/content/pm/IOnAppsChangedListener;
Landroid/content/pm/IOnChecksumsReadyListener$Stub$Proxy;
@@ -24407,7 +24525,6 @@ Landroid/content/rollback/RollbackManagerFrameworkInitializer;
Landroid/content/type/DefaultMimeMapFactory$$ExternalSyntheticLambda0;
Landroid/content/type/DefaultMimeMapFactory;
Landroid/credentials/CredentialManager;
-Landroid/credentials/GetCredentialResponse$1;
Landroid/credentials/GetCredentialResponse;
Landroid/database/AbstractCursor$SelfContentObserver;
Landroid/database/AbstractCursor;
@@ -24472,6 +24589,7 @@ Landroid/database/sqlite/SQLiteConnectionPool$ConnectionWaiter;
Landroid/database/sqlite/SQLiteConnectionPool$IdleConnectionHandler;
Landroid/database/sqlite/SQLiteConnectionPool;
Landroid/database/sqlite/SQLiteConstraintException;
+Landroid/database/sqlite/SQLiteCursor;
Landroid/database/sqlite/SQLiteCursorDriver;
Landroid/database/sqlite/SQLiteCustomFunction;
Landroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;
@@ -24644,7 +24762,6 @@ Landroid/graphics/LightingColorFilter;
Landroid/graphics/LinearGradient;
Landroid/graphics/MaskFilter;
Landroid/graphics/Matrix$1;
-Landroid/graphics/Matrix$ExtraNatives;
Landroid/graphics/Matrix$NoImagePreloadHolder;
Landroid/graphics/Matrix$ScaleToFit;
Landroid/graphics/Matrix;
@@ -24668,7 +24785,6 @@ Landroid/graphics/Paint;
Landroid/graphics/PaintFlagsDrawFilter;
Landroid/graphics/Path$Direction;
Landroid/graphics/Path$FillType;
-Landroid/graphics/Path$NoImagePreloadHolder;
Landroid/graphics/Path$Op;
Landroid/graphics/Path;
Landroid/graphics/PathDashPathEffect;
@@ -24879,7 +24995,6 @@ Landroid/graphics/drawable/shapes/RectShape;
Landroid/graphics/drawable/shapes/RoundRectShape;
Landroid/graphics/drawable/shapes/Shape;
Landroid/graphics/fonts/Font$Builder;
-Landroid/graphics/fonts/Font$NoImagePreloadHolder;
Landroid/graphics/fonts/Font;
Landroid/graphics/fonts/FontCustomizationParser$Result;
Landroid/graphics/fonts/FontCustomizationParser;
@@ -24924,7 +25039,6 @@ Landroid/hardware/CameraSessionStats;
Landroid/hardware/CameraStatus$1;
Landroid/hardware/CameraStatus;
Landroid/hardware/ConsumerIrManager;
-Landroid/hardware/DataSpace;
Landroid/hardware/GeomagneticField$LegendreTable;
Landroid/hardware/GeomagneticField;
Landroid/hardware/HardwareBuffer$1;
@@ -24972,6 +25086,7 @@ Landroid/hardware/SyncFence;
Landroid/hardware/SystemSensorManager$BaseEventQueue;
Landroid/hardware/SystemSensorManager$SensorEventQueue;
Landroid/hardware/SystemSensorManager$TriggerEventQueue;
+Landroid/hardware/SystemSensorManager;
Landroid/hardware/TriggerEvent;
Landroid/hardware/TriggerEventListener;
Landroid/hardware/biometrics/BiometricAuthenticator$AuthenticationCallback;
@@ -25038,10 +25153,13 @@ Landroid/hardware/camera2/CameraCharacteristics;
Landroid/hardware/camera2/CameraDevice$StateCallback;
Landroid/hardware/camera2/CameraDevice;
Landroid/hardware/camera2/CameraManager$AvailabilityCallback;
-Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$$ExternalSyntheticLambda0;
Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$$ExternalSyntheticLambda2;
Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;
-Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$DeviceCameraInfo;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$3;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$4;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$5;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$6;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$7;
Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;
Landroid/hardware/camera2/CameraManager$DeviceStateListener;
Landroid/hardware/camera2/CameraManager$FoldStateListener$$ExternalSyntheticLambda0;
@@ -25198,7 +25316,6 @@ Landroid/hardware/contexthub/V1_0/MemRange;
Landroid/hardware/contexthub/V1_0/NanoAppBinary;
Landroid/hardware/contexthub/V1_0/PhysicalSensor;
Landroid/hardware/contexthub/V1_1/Setting;
-Landroid/hardware/devicestate/DeviceState$Configuration;
Landroid/hardware/devicestate/DeviceState;
Landroid/hardware/devicestate/DeviceStateInfo$1;
Landroid/hardware/devicestate/DeviceStateInfo;
@@ -25313,9 +25430,12 @@ Landroid/hardware/fingerprint/Fingerprint$1;
Landroid/hardware/fingerprint/Fingerprint;
Landroid/hardware/fingerprint/FingerprintManager$1;
Landroid/hardware/fingerprint/FingerprintManager$2;
+Landroid/hardware/fingerprint/FingerprintManager$3;
Landroid/hardware/fingerprint/FingerprintManager$AuthenticationCallback;
Landroid/hardware/fingerprint/FingerprintManager$AuthenticationResult;
Landroid/hardware/fingerprint/FingerprintManager$LockoutResetCallback;
+Landroid/hardware/fingerprint/FingerprintManager$MyHandler-IA;
+Landroid/hardware/fingerprint/FingerprintManager$MyHandler;
Landroid/hardware/fingerprint/FingerprintManager;
Landroid/hardware/fingerprint/FingerprintSensorPropertiesInternal$1;
Landroid/hardware/fingerprint/FingerprintSensorPropertiesInternal;
@@ -25801,9 +25921,13 @@ Landroid/icu/impl/CacheValue;
Landroid/icu/impl/CalType;
Landroid/icu/impl/CalendarAstronomer$1;
Landroid/icu/impl/CalendarAstronomer$2;
+Landroid/icu/impl/CalendarAstronomer$3;
+Landroid/icu/impl/CalendarAstronomer$4;
Landroid/icu/impl/CalendarAstronomer$AngleFunc;
+Landroid/icu/impl/CalendarAstronomer$CoordFunc;
Landroid/icu/impl/CalendarAstronomer$Ecliptic;
Landroid/icu/impl/CalendarAstronomer$Equatorial;
+Landroid/icu/impl/CalendarAstronomer$Horizon;
Landroid/icu/impl/CalendarAstronomer$MoonAge;
Landroid/icu/impl/CalendarAstronomer$SolarLongitude;
Landroid/icu/impl/CalendarAstronomer;
@@ -25840,7 +25964,6 @@ Landroid/icu/impl/DayPeriodRules$DayPeriodRulesDataSink;
Landroid/icu/impl/DayPeriodRules-IA;
Landroid/icu/impl/DayPeriodRules;
Landroid/icu/impl/DontCareFieldPosition;
-Landroid/icu/impl/EmojiProps$IsAcceptable;
Landroid/icu/impl/EmojiProps;
Landroid/icu/impl/EraRules;
Landroid/icu/impl/FormattedStringBuilder$FieldWrapper;
@@ -26116,8 +26239,6 @@ Landroid/icu/impl/UCharacterProperty$24;
Landroid/icu/impl/UCharacterProperty$25;
Landroid/icu/impl/UCharacterProperty$26;
Landroid/icu/impl/UCharacterProperty$27;
-Landroid/icu/impl/UCharacterProperty$28;
-Landroid/icu/impl/UCharacterProperty$29;
Landroid/icu/impl/UCharacterProperty$2;
Landroid/icu/impl/UCharacterProperty$3;
Landroid/icu/impl/UCharacterProperty$4;
@@ -26135,7 +26256,6 @@ Landroid/icu/impl/UCharacterProperty$IntProperty;
Landroid/icu/impl/UCharacterProperty$IsAcceptable;
Landroid/icu/impl/UCharacterProperty$LayoutProps$IsAcceptable;
Landroid/icu/impl/UCharacterProperty$LayoutProps;
-Landroid/icu/impl/UCharacterProperty$MathCompatBinaryProperty;
Landroid/icu/impl/UCharacterProperty$NormInertBinaryProperty;
Landroid/icu/impl/UCharacterProperty$NormQuickCheckIntProperty;
Landroid/icu/impl/UCharacterProperty;
@@ -26320,15 +26440,8 @@ Landroid/icu/impl/locale/KeyTypeData$Type;
Landroid/icu/impl/locale/KeyTypeData$TypeInfoType;
Landroid/icu/impl/locale/KeyTypeData$ValueType;
Landroid/icu/impl/locale/KeyTypeData;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda0;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda1;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda2;
-Landroid/icu/impl/locale/LSR$CachedDecoder;
Landroid/icu/impl/locale/LSR;
Landroid/icu/impl/locale/LanguageTag;
-Landroid/icu/impl/locale/LikelySubtags$1;
-Landroid/icu/impl/locale/LikelySubtags$Data;
-Landroid/icu/impl/locale/LikelySubtags;
Landroid/icu/impl/locale/LocaleDistance$Data;
Landroid/icu/impl/locale/LocaleDistance;
Landroid/icu/impl/locale/LocaleExtensions;
@@ -26359,6 +26472,9 @@ Landroid/icu/impl/locale/XCldrStub$ReusableEntry;
Landroid/icu/impl/locale/XCldrStub$Splitter;
Landroid/icu/impl/locale/XCldrStub$TreeMultimap;
Landroid/icu/impl/locale/XCldrStub;
+Landroid/icu/impl/locale/XLikelySubtags$1;
+Landroid/icu/impl/locale/XLikelySubtags$Data;
+Landroid/icu/impl/locale/XLikelySubtags;
Landroid/icu/impl/number/AdoptingModifierStore$1;
Landroid/icu/impl/number/AdoptingModifierStore;
Landroid/icu/impl/number/AffixPatternProvider$Flags;
@@ -26489,7 +26605,6 @@ Landroid/icu/lang/UCharacter$DummyValueIterator;
Landroid/icu/lang/UCharacter$EastAsianWidth;
Landroid/icu/lang/UCharacter$GraphemeClusterBreak;
Landroid/icu/lang/UCharacter$HangulSyllableType;
-Landroid/icu/lang/UCharacter$IdentifierType;
Landroid/icu/lang/UCharacter$IndicPositionalCategory;
Landroid/icu/lang/UCharacter$IndicSyllabicCategory;
Landroid/icu/lang/UCharacter$JoiningGroup;
@@ -27035,7 +27150,6 @@ Landroid/icu/text/TitlecaseTransliterator;
Landroid/icu/text/Transform;
Landroid/icu/text/TransliterationRule;
Landroid/icu/text/TransliterationRuleSet;
-Landroid/icu/text/Transliterator$$ExternalSyntheticLambda0;
Landroid/icu/text/Transliterator$Factory;
Landroid/icu/text/Transliterator$Position;
Landroid/icu/text/Transliterator;
@@ -27082,7 +27196,6 @@ Landroid/icu/text/UnicodeSet$EntryRangeIterable;
Landroid/icu/text/UnicodeSet$EntryRangeIterator;
Landroid/icu/text/UnicodeSet$Filter;
Landroid/icu/text/UnicodeSet$GeneralCategoryMaskFilter;
-Landroid/icu/text/UnicodeSet$IdentifierTypeFilter;
Landroid/icu/text/UnicodeSet$IntPropertyFilter;
Landroid/icu/text/UnicodeSet$NumericValueFilter;
Landroid/icu/text/UnicodeSet$ScriptExtensionsFilter;
@@ -27189,12 +27302,7 @@ Landroid/icu/util/ICUUncheckedIOException;
Landroid/icu/util/IllformedLocaleException;
Landroid/icu/util/IndianCalendar;
Landroid/icu/util/InitialTimeZoneRule;
-Landroid/icu/util/IslamicCalendar$Algorithm;
Landroid/icu/util/IslamicCalendar$CalculationType;
-Landroid/icu/util/IslamicCalendar$CivilAlgorithm;
-Landroid/icu/util/IslamicCalendar$IslamicAlgorithm;
-Landroid/icu/util/IslamicCalendar$TBLAAlgorithm;
-Landroid/icu/util/IslamicCalendar$UmalquraAlgorithm;
Landroid/icu/util/IslamicCalendar;
Landroid/icu/util/JapaneseCalendar;
Landroid/icu/util/LocaleData$MeasurementSystem;
@@ -27544,8 +27652,6 @@ Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;
Landroid/media/ImageWriter$WriterSurfaceImage;
Landroid/media/ImageWriter;
Landroid/media/JetPlayer;
-Landroid/media/MediaCodec$$ExternalSyntheticLambda6;
-Landroid/media/MediaCodec$$ExternalSyntheticLambda7;
Landroid/media/MediaCodec$BufferInfo;
Landroid/media/MediaCodec$BufferMap$CodecBuffer-IA;
Landroid/media/MediaCodec$BufferMap$CodecBuffer;
@@ -27770,8 +27876,6 @@ Landroid/media/VolumeShaper$Operation;
Landroid/media/VolumeShaper$State$1;
Landroid/media/VolumeShaper$State;
Landroid/media/VolumeShaper;
-Landroid/media/audio/FeatureFlags;
-Landroid/media/audio/FeatureFlagsImpl;
Landroid/media/audio/Flags;
Landroid/media/audio/common/AidlConversion;
Landroid/media/audio/common/HeadTracking$SensorData$Tag;
@@ -28220,7 +28324,6 @@ Landroid/net/wifi/nl80211/WifiNl80211Manager$ScanEventHandler;
Landroid/net/wifi/nl80211/WifiNl80211Manager$SignalPollResult;
Landroid/net/wifi/nl80211/WifiNl80211Manager;
Landroid/net/wifi/sharedconnectivity/app/SharedConnectivityManager;
-Landroid/nfc/NfcAdapter;
Landroid/nfc/NfcFrameworkInitializer$$ExternalSyntheticLambda0;
Landroid/nfc/NfcFrameworkInitializer;
Landroid/nfc/NfcManager;
@@ -28471,6 +28574,7 @@ Landroid/os/IIncidentCompanion;
Landroid/os/IIncidentManager$Stub$Proxy;
Landroid/os/IIncidentManager$Stub;
Landroid/os/IIncidentManager;
+Landroid/os/IInstalld$Stub$Proxy;
Landroid/os/IInstalld$Stub;
Landroid/os/IInstalld;
Landroid/os/IInterface;
@@ -28693,6 +28797,7 @@ Landroid/os/StrictMode$1;
Landroid/os/StrictMode$2;
Landroid/os/StrictMode$3;
Landroid/os/StrictMode$4;
+Landroid/os/StrictMode$5;
Landroid/os/StrictMode$6;
Landroid/os/StrictMode$7;
Landroid/os/StrictMode$8;
@@ -28723,6 +28828,7 @@ Landroid/os/StrictMode;
Landroid/os/SynchronousResultReceiver$Result;
Landroid/os/SynchronousResultReceiver;
Landroid/os/SystemClock$2;
+Landroid/os/SystemClock$3;
Landroid/os/SystemClock;
Landroid/os/SystemConfigManager;
Landroid/os/SystemProperties$Handle-IA;
@@ -28881,8 +28987,6 @@ Landroid/os/strictmode/UnsafeIntentLaunchViolation;
Landroid/os/strictmode/UntaggedSocketViolation;
Landroid/os/strictmode/Violation;
Landroid/os/strictmode/WebViewMethodCalledOnWrongThreadViolation;
-Landroid/os/vibrator/FeatureFlags;
-Landroid/os/vibrator/FeatureFlagsImpl;
Landroid/os/vibrator/Flags;
Landroid/os/vibrator/PrebakedSegment$1;
Landroid/os/vibrator/PrebakedSegment;
@@ -28916,13 +29020,15 @@ Landroid/permission/PermissionControllerManager$1;
Landroid/permission/PermissionControllerManager;
Landroid/permission/PermissionManager$1;
Landroid/permission/PermissionManager$2;
-Landroid/permission/PermissionManager$OnPermissionsChangeListenerDelegate;
Landroid/permission/PermissionManager$PackageNamePermissionQuery;
Landroid/permission/PermissionManager$PermissionQuery;
Landroid/permission/PermissionManager$SplitPermissionInfo-IA;
Landroid/permission/PermissionManager$SplitPermissionInfo;
Landroid/permission/PermissionManager;
Landroid/permission/PermissionManagerInternal;
+Landroid/permission/flags/FeatureFlags;
+Landroid/permission/flags/FeatureFlagsImpl;
+Landroid/permission/flags/Flags;
Landroid/preference/DialogPreference;
Landroid/preference/GenericInflater$Parent;
Landroid/preference/GenericInflater;
@@ -29151,6 +29257,7 @@ Landroid/security/KeyStore2$$ExternalSyntheticLambda4;
Landroid/security/KeyStore2$$ExternalSyntheticLambda8;
Landroid/security/KeyStore2$CheckedRemoteRequest;
Landroid/security/KeyStore2;
+Landroid/security/KeyStore;
Landroid/security/KeyStoreException$PublicErrorInformation;
Landroid/security/KeyStoreException;
Landroid/security/KeyStoreOperation$$ExternalSyntheticLambda0;
@@ -29321,8 +29428,6 @@ Landroid/service/appprediction/IPredictionService;
Landroid/service/autofill/AutofillServiceInfo;
Landroid/service/autofill/Dataset$1;
Landroid/service/autofill/Dataset;
-Landroid/service/autofill/FeatureFlags;
-Landroid/service/autofill/FeatureFlagsImpl;
Landroid/service/autofill/FieldClassificationUserData;
Landroid/service/autofill/FillContext$1;
Landroid/service/autofill/FillContext;
@@ -29459,7 +29564,6 @@ Landroid/service/media/MediaBrowserService$Result;
Landroid/service/media/MediaBrowserService$ServiceBinder$$ExternalSyntheticLambda1;
Landroid/service/media/MediaBrowserService$ServiceBinder-IA;
Landroid/service/media/MediaBrowserService$ServiceBinder;
-Landroid/service/media/MediaBrowserService$ServiceState-IA;
Landroid/service/media/MediaBrowserService$ServiceState;
Landroid/service/media/MediaBrowserService;
Landroid/service/notification/Adjustment$1;
@@ -29498,7 +29602,6 @@ Landroid/service/notification/SnoozeCriterion$1;
Landroid/service/notification/SnoozeCriterion;
Landroid/service/notification/StatusBarNotification$1;
Landroid/service/notification/StatusBarNotification;
-Landroid/service/notification/ZenDeviceEffects$1;
Landroid/service/notification/ZenDeviceEffects;
Landroid/service/notification/ZenModeConfig$1;
Landroid/service/notification/ZenModeConfig$EventInfo;
@@ -29885,6 +29988,7 @@ Landroid/telephony/ICellBroadcastService;
Landroid/telephony/ICellInfoCallback$Stub$Proxy;
Landroid/telephony/ICellInfoCallback$Stub;
Landroid/telephony/ICellInfoCallback;
+Landroid/telephony/INetworkService$Stub$Proxy;
Landroid/telephony/INetworkService$Stub;
Landroid/telephony/INetworkService;
Landroid/telephony/INetworkServiceCallback$Stub$Proxy;
@@ -29920,6 +30024,7 @@ Landroid/telephony/NetworkRegistrationInfo;
Landroid/telephony/NetworkScan;
Landroid/telephony/NetworkScanRequest$1;
Landroid/telephony/NetworkScanRequest;
+Landroid/telephony/NetworkService$INetworkServiceWrapper;
Landroid/telephony/NetworkService$NetworkServiceHandler;
Landroid/telephony/NetworkService$NetworkServiceProvider;
Landroid/telephony/NetworkService;
@@ -30056,7 +30161,6 @@ Landroid/telephony/TelephonyCallback$CallDisconnectCauseListener;
Landroid/telephony/TelephonyCallback$CallForwardingIndicatorListener;
Landroid/telephony/TelephonyCallback$CallStateListener;
Landroid/telephony/TelephonyCallback$CarrierNetworkListener;
-Landroid/telephony/TelephonyCallback$CarrierRoamingNtnModeListener;
Landroid/telephony/TelephonyCallback$CellInfoListener;
Landroid/telephony/TelephonyCallback$CellLocationListener;
Landroid/telephony/TelephonyCallback$DataActivationStateListener;
@@ -30357,6 +30461,7 @@ Landroid/telephony/ims/aidl/IImsConfig;
Landroid/telephony/ims/aidl/IImsConfigCallback$Stub$Proxy;
Landroid/telephony/ims/aidl/IImsConfigCallback$Stub;
Landroid/telephony/ims/aidl/IImsConfigCallback;
+Landroid/telephony/ims/aidl/IImsMmTelFeature$Stub$Proxy;
Landroid/telephony/ims/aidl/IImsMmTelFeature$Stub;
Landroid/telephony/ims/aidl/IImsMmTelFeature;
Landroid/telephony/ims/aidl/IImsMmTelListener$Stub$Proxy;
@@ -30366,6 +30471,7 @@ Landroid/telephony/ims/aidl/IImsRcsController$Stub;
Landroid/telephony/ims/aidl/IImsRcsController;
Landroid/telephony/ims/aidl/IImsRcsFeature$Stub;
Landroid/telephony/ims/aidl/IImsRcsFeature;
+Landroid/telephony/ims/aidl/IImsRegistration$Stub$Proxy;
Landroid/telephony/ims/aidl/IImsRegistration$Stub;
Landroid/telephony/ims/aidl/IImsRegistration;
Landroid/telephony/ims/aidl/IImsRegistrationCallback$Stub$Proxy;
@@ -30504,7 +30610,6 @@ Landroid/text/Layout$SpannedEllipsizer;
Landroid/text/Layout$TabStops;
Landroid/text/Layout$TextInclusionStrategy;
Landroid/text/Layout;
-Landroid/text/MeasuredParagraph$StyleRunCallback;
Landroid/text/MeasuredParagraph;
Landroid/text/NoCopySpan$Concrete;
Landroid/text/NoCopySpan;
@@ -30545,7 +30650,6 @@ Landroid/text/TextDirectionHeuristics;
Landroid/text/TextFlags;
Landroid/text/TextLine$DecorationInfo-IA;
Landroid/text/TextLine$DecorationInfo;
-Landroid/text/TextLine$LineInfo;
Landroid/text/TextLine;
Landroid/text/TextPaint;
Landroid/text/TextShaper$GlyphsConsumer;
@@ -30630,7 +30734,6 @@ Landroid/text/style/LeadingMarginSpan$Standard;
Landroid/text/style/LeadingMarginSpan;
Landroid/text/style/LineBackgroundSpan$Standard;
Landroid/text/style/LineBackgroundSpan;
-Landroid/text/style/LineBreakConfigSpan$1;
Landroid/text/style/LineBreakConfigSpan;
Landroid/text/style/LineHeightSpan$Standard;
Landroid/text/style/LineHeightSpan$WithDensity;
@@ -30684,7 +30787,6 @@ Landroid/timezone/TelephonyLookup;
Landroid/timezone/TelephonyNetwork;
Landroid/timezone/TelephonyNetworkFinder;
Landroid/timezone/TimeZoneFinder;
-Landroid/tracing/Flags;
Landroid/tracing/perfetto/CreateIncrementalStateArgs;
Landroid/tracing/perfetto/CreateTlsStateArgs;
Landroid/tracing/perfetto/DataSource;
@@ -30884,6 +30986,7 @@ Landroid/util/SparseIntArray;
Landroid/util/SparseLongArray;
Landroid/util/SparseSetArray;
Landroid/util/Spline$LinearSpline;
+Landroid/util/Spline$MonotoneCubicSpline;
Landroid/util/Spline;
Landroid/util/StateSet;
Landroid/util/StringBuilderPrinter;
@@ -31110,7 +31213,6 @@ Landroid/view/IScrollCaptureCallbacks;
Landroid/view/IScrollCaptureResponseListener$Stub$Proxy;
Landroid/view/IScrollCaptureResponseListener$Stub;
Landroid/view/IScrollCaptureResponseListener;
-Landroid/view/ISensitiveContentProtectionManager$Stub$Proxy;
Landroid/view/ISensitiveContentProtectionManager$Stub;
Landroid/view/ISensitiveContentProtectionManager;
Landroid/view/ISurfaceControlViewHost;
@@ -31137,7 +31239,6 @@ Landroid/view/IWindowSession;
Landroid/view/IWindowSessionCallback$Stub$Proxy;
Landroid/view/IWindowSessionCallback$Stub;
Landroid/view/IWindowSessionCallback;
-Landroid/view/ImeBackAnimationController;
Landroid/view/ImeFocusController$InputMethodManagerDelegate;
Landroid/view/ImeFocusController;
Landroid/view/ImeInsetsSourceConsumer;
@@ -31199,6 +31300,7 @@ Landroid/view/InsetsController$InternalAnimationControlListener$$ExternalSynthet
Landroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda3;
Landroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda4;
Landroid/view/InsetsController$InternalAnimationControlListener$1;
+Landroid/view/InsetsController$InternalAnimationControlListener$2;
Landroid/view/InsetsController$InternalAnimationControlListener;
Landroid/view/InsetsController$PendingControlRequest;
Landroid/view/InsetsController$RunningAnimation;
@@ -31287,7 +31389,6 @@ Landroid/view/ScaleGestureDetector$1;
Landroid/view/ScaleGestureDetector$OnScaleGestureListener;
Landroid/view/ScaleGestureDetector$SimpleOnScaleGestureListener;
Landroid/view/ScaleGestureDetector;
-Landroid/view/ScrollCaptureSearchResults$$ExternalSyntheticLambda0;
Landroid/view/ScrollCaptureSearchResults;
Landroid/view/ScrollFeedbackProvider;
Landroid/view/SearchEvent;
@@ -31306,7 +31407,6 @@ Landroid/view/SurfaceControl$DesiredDisplayModeSpecs;
Landroid/view/SurfaceControl$DisplayMode;
Landroid/view/SurfaceControl$DisplayPrimaries;
Landroid/view/SurfaceControl$DynamicDisplayInfo;
-Landroid/view/SurfaceControl$IdleScreenRefreshRateConfig;
Landroid/view/SurfaceControl$JankData;
Landroid/view/SurfaceControl$OnJankDataListener;
Landroid/view/SurfaceControl$OnReparentListener;
@@ -31615,14 +31715,12 @@ Landroid/view/WindowManager;
Landroid/view/WindowManagerGlobal$$ExternalSyntheticLambda0;
Landroid/view/WindowManagerGlobal$1;
Landroid/view/WindowManagerGlobal$2;
-Landroid/view/WindowManagerGlobal$TrustedPresentationListener-IA;
Landroid/view/WindowManagerGlobal$TrustedPresentationListener;
Landroid/view/WindowManagerGlobal;
Landroid/view/WindowManagerImpl;
Landroid/view/WindowManagerPolicyConstants$PointerEventListener;
Landroid/view/WindowManagerPolicyConstants;
Landroid/view/WindowMetrics;
-Landroid/view/WindowRelayoutResult;
Landroid/view/WindowlessWindowLayout;
Landroid/view/WindowlessWindowManager;
Landroid/view/accessibility/AccessibilityCache$AccessibilityNodeRefresher;
@@ -31666,8 +31764,6 @@ Landroid/view/accessibility/CaptioningManager$CaptioningChangeListener;
Landroid/view/accessibility/CaptioningManager$MyContentObserver;
Landroid/view/accessibility/CaptioningManager;
Landroid/view/accessibility/DirectAccessibilityConnection;
-Landroid/view/accessibility/FeatureFlags;
-Landroid/view/accessibility/FeatureFlagsImpl;
Landroid/view/accessibility/Flags;
Landroid/view/accessibility/IAccessibilityEmbeddedConnection;
Landroid/view/accessibility/IAccessibilityInteractionConnection$Stub$Proxy;
@@ -31793,6 +31889,7 @@ Landroid/view/contentcapture/IContentCaptureManager$Stub;
Landroid/view/contentcapture/IContentCaptureManager;
Landroid/view/contentcapture/IContentCaptureOptionsCallback$Stub;
Landroid/view/contentcapture/IContentCaptureOptionsCallback;
+Landroid/view/contentcapture/IDataShareWriteAdapter$Stub$Proxy;
Landroid/view/contentcapture/IDataShareWriteAdapter$Stub;
Landroid/view/contentcapture/IDataShareWriteAdapter;
Landroid/view/contentcapture/MainContentCaptureSession$$ExternalSyntheticLambda0;
@@ -31847,8 +31944,6 @@ Landroid/view/inputmethod/ExtractedText$1;
Landroid/view/inputmethod/ExtractedText;
Landroid/view/inputmethod/ExtractedTextRequest$1;
Landroid/view/inputmethod/ExtractedTextRequest;
-Landroid/view/inputmethod/FeatureFlags;
-Landroid/view/inputmethod/FeatureFlagsImpl;
Landroid/view/inputmethod/Flags;
Landroid/view/inputmethod/HandwritingGesture;
Landroid/view/inputmethod/IAccessibilityInputMethodSessionInvoker$$ExternalSyntheticLambda0;
@@ -32449,7 +32544,6 @@ Landroid/widget/RemoteViews$BaseReflectionAction;
Landroid/widget/RemoteViews$BitmapCache;
Landroid/widget/RemoteViews$BitmapReflectionAction;
Landroid/widget/RemoteViews$ComplexUnitDimensionReflectionAction;
-Landroid/widget/RemoteViews$DrawInstructions;
Landroid/widget/RemoteViews$HierarchyRootData;
Landroid/widget/RemoteViews$InteractionHandler;
Landroid/widget/RemoteViews$LayoutParamAction;
@@ -32608,12 +32702,10 @@ Landroid/widget/ViewFlipper$1;
Landroid/widget/ViewFlipper;
Landroid/widget/ViewSwitcher;
Landroid/widget/WrapperListAdapter;
-Landroid/widget/flags/Flags;
Landroid/widget/inline/InlinePresentationSpec$1;
Landroid/widget/inline/InlinePresentationSpec$BaseBuilder;
Landroid/widget/inline/InlinePresentationSpec$Builder;
Landroid/widget/inline/InlinePresentationSpec;
-Landroid/window/ActivityWindowInfo$1;
Landroid/window/ActivityWindowInfo;
Landroid/window/BackAnimationAdapter$1;
Landroid/window/BackAnimationAdapter;
@@ -32622,12 +32714,9 @@ Landroid/window/BackMotionEvent$1;
Landroid/window/BackMotionEvent;
Landroid/window/BackNavigationInfo$1;
Landroid/window/BackNavigationInfo;
-Landroid/window/BackProgressAnimator$$ExternalSyntheticLambda0;
Landroid/window/BackProgressAnimator$1;
Landroid/window/BackProgressAnimator$ProgressCallback;
Landroid/window/BackProgressAnimator;
-Landroid/window/BackTouchTracker$TouchTrackerState;
-Landroid/window/BackTouchTracker;
Landroid/window/ClientWindowFrames$1;
Landroid/window/ClientWindowFrames-IA;
Landroid/window/ClientWindowFrames;
@@ -32661,6 +32750,7 @@ Landroid/window/ITaskFragmentOrganizer$Stub;
Landroid/window/ITaskFragmentOrganizer;
Landroid/window/ITaskFragmentOrganizerController$Stub;
Landroid/window/ITaskFragmentOrganizerController;
+Landroid/window/ITaskOrganizer$Stub$Proxy;
Landroid/window/ITaskOrganizer$Stub;
Landroid/window/ITaskOrganizer;
Landroid/window/ITaskOrganizerController$Stub$Proxy;
@@ -32684,11 +32774,8 @@ Landroid/window/IWindowOrganizerController;
Landroid/window/ImeOnBackInvokedDispatcher$$ExternalSyntheticLambda0;
Landroid/window/ImeOnBackInvokedDispatcher$1;
Landroid/window/ImeOnBackInvokedDispatcher$2;
-Landroid/window/ImeOnBackInvokedDispatcher$DefaultImeOnBackAnimationCallback;
Landroid/window/ImeOnBackInvokedDispatcher$ImeOnBackInvokedCallback;
Landroid/window/ImeOnBackInvokedDispatcher;
-Landroid/window/InputTransferToken$1;
-Landroid/window/InputTransferToken;
Landroid/window/OnBackAnimationCallback;
Landroid/window/OnBackInvokedCallback;
Landroid/window/OnBackInvokedCallbackInfo$1;
@@ -32712,7 +32799,6 @@ Landroid/window/SizeConfigurationBuckets$1;
Landroid/window/SizeConfigurationBuckets;
Landroid/window/SplashScreen$SplashScreenManagerGlobal$1;
Landroid/window/SplashScreen$SplashScreenManagerGlobal;
-Landroid/window/SplashScreen;
Landroid/window/SplashScreenView$SplashScreenViewParcelable$1;
Landroid/window/SplashScreenView$SplashScreenViewParcelable;
Landroid/window/SplashScreenView;
@@ -32740,7 +32826,6 @@ Landroid/window/TaskFragmentOrganizer$1;
Landroid/window/TaskFragmentOrganizer;
Landroid/window/TaskFragmentOrganizerToken$1;
Landroid/window/TaskFragmentOrganizerToken;
-Landroid/window/TaskFragmentTransaction$1;
Landroid/window/TaskFragmentTransaction;
Landroid/window/TaskOrganizer$1;
Landroid/window/TaskOrganizer;
@@ -32775,6 +32860,7 @@ Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$Exte
Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda2;
Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda3;
Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda4;
+Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda5;
Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$CallbackRef;
Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;
Landroid/window/WindowOnBackInvokedDispatcher;
@@ -32859,9 +32945,6 @@ Lcom/android/framework/protobuf/nano/InternalNano;
Lcom/android/framework/protobuf/nano/InvalidProtocolBufferNanoException;
Lcom/android/framework/protobuf/nano/MessageNano;
Lcom/android/framework/protobuf/nano/WireFormatNano;
-Lcom/android/graphics/flags/Flags;
-Lcom/android/graphics/hwui/flags/FeatureFlags;
-Lcom/android/graphics/hwui/flags/FeatureFlagsImpl;
Lcom/android/graphics/hwui/flags/Flags;
Lcom/android/i18n/phonenumbers/AlternateFormatsCountryCodeSet;
Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;
@@ -32981,7 +33064,6 @@ Lcom/android/i18n/timezone/internal/Memory;
Lcom/android/i18n/timezone/internal/MemoryMappedFile;
Lcom/android/i18n/timezone/internal/NioBufferIterator;
Lcom/android/i18n/util/Log;
-Lcom/android/icu/charset/CharsetDecoderICU;
Lcom/android/icu/charset/CharsetEncoderICU;
Lcom/android/icu/charset/CharsetFactory;
Lcom/android/icu/charset/NativeConverter;
@@ -33051,6 +33133,7 @@ Lcom/android/ims/ImsManager$$ExternalSyntheticLambda2;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda3;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda4;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda5;
+Lcom/android/ims/ImsManager$$ExternalSyntheticLambda6;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda7;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda8;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda9;
@@ -33129,6 +33212,7 @@ Lcom/android/ims/internal/IImsRegistrationListener$Stub;
Lcom/android/ims/internal/IImsRegistrationListener;
Lcom/android/ims/internal/IImsServiceController$Stub;
Lcom/android/ims/internal/IImsServiceController;
+Lcom/android/ims/internal/IImsServiceFeatureCallback$Stub$Proxy;
Lcom/android/ims/internal/IImsServiceFeatureCallback$Stub;
Lcom/android/ims/internal/IImsServiceFeatureCallback;
Lcom/android/ims/internal/IImsStreamMediaSession;
@@ -33383,8 +33467,6 @@ Lcom/android/ims/rcs/uce/util/FeatureTags$$ExternalSyntheticLambda0;
Lcom/android/ims/rcs/uce/util/FeatureTags;
Lcom/android/ims/rcs/uce/util/NetworkSipCode;
Lcom/android/ims/rcs/uce/util/UceUtils;
-Lcom/android/input/flags/FeatureFlags;
-Lcom/android/input/flags/FeatureFlagsImpl;
Lcom/android/input/flags/Flags;
Lcom/android/internal/R$attr;
Lcom/android/internal/R$dimen;
@@ -33412,6 +33494,7 @@ Lcom/android/internal/app/IAppOpsActiveCallback$Stub;
Lcom/android/internal/app/IAppOpsActiveCallback;
Lcom/android/internal/app/IAppOpsAsyncNotedCallback$Stub;
Lcom/android/internal/app/IAppOpsAsyncNotedCallback;
+Lcom/android/internal/app/IAppOpsCallback$Stub$Proxy;
Lcom/android/internal/app/IAppOpsCallback$Stub;
Lcom/android/internal/app/IAppOpsCallback;
Lcom/android/internal/app/IAppOpsNotedCallback$Stub;
@@ -33506,7 +33589,6 @@ Lcom/android/internal/colorextraction/types/Tonal$ConfigParser;
Lcom/android/internal/colorextraction/types/Tonal$TonalPalette;
Lcom/android/internal/colorextraction/types/Tonal;
Lcom/android/internal/compat/AndroidBuildClassifier;
-Lcom/android/internal/compat/ChangeReporter$$ExternalSyntheticLambda0;
Lcom/android/internal/compat/ChangeReporter$ChangeReport;
Lcom/android/internal/compat/ChangeReporter;
Lcom/android/internal/compat/CompatibilityChangeConfig$1;
@@ -33520,9 +33602,6 @@ Lcom/android/internal/compat/IPlatformCompat$Stub;
Lcom/android/internal/compat/IPlatformCompat;
Lcom/android/internal/compat/IPlatformCompatNative$Stub;
Lcom/android/internal/compat/IPlatformCompatNative;
-Lcom/android/internal/compat/flags/FeatureFlags;
-Lcom/android/internal/compat/flags/FeatureFlagsImpl;
-Lcom/android/internal/compat/flags/Flags;
Lcom/android/internal/config/appcloning/AppCloningDeviceConfigHelper$$ExternalSyntheticLambda0;
Lcom/android/internal/config/appcloning/AppCloningDeviceConfigHelper;
Lcom/android/internal/config/sysui/SystemUiSystemPropertiesFlags$DebugResolver;
@@ -33571,7 +33650,6 @@ Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$7;
Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$8;
Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$9;
Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$MassState;
-Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$OnAnimationEndListener;
Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$ViewProperty;
Lcom/android/internal/dynamicanimation/animation/DynamicAnimation;
Lcom/android/internal/dynamicanimation/animation/Force;
@@ -33591,15 +33669,6 @@ Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable$Aggregator;
Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable$BlurRegion;
Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable-IA;
Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable;
-Lcom/android/internal/hidden_from_bootclasspath/android/app/job/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/FeatureFlagsImpl;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/FeatureFlagsImpl;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/FeatureFlagsImpl;
Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/Flags;
Lcom/android/internal/infra/AbstractMultiplePendingRequestsRemoteService;
Lcom/android/internal/infra/AbstractRemoteService$AsyncRequest;
@@ -33763,7 +33832,8 @@ Lcom/android/internal/os/BinderCallsStats;
Lcom/android/internal/os/BinderDeathDispatcher$RecipientsInfo-IA;
Lcom/android/internal/os/BinderDeathDispatcher$RecipientsInfo;
Lcom/android/internal/os/BinderDeathDispatcher;
-Lcom/android/internal/os/BinderInternal$BinderProxyCountEventListenerDelegate;
+Lcom/android/internal/os/BinderInternal$BinderProxyLimitListener;
+Lcom/android/internal/os/BinderInternal$BinderProxyLimitListenerDelegate;
Lcom/android/internal/os/BinderInternal$CallSession;
Lcom/android/internal/os/BinderInternal$CallStatsObserver;
Lcom/android/internal/os/BinderInternal$GcWatcher;
@@ -33782,9 +33852,6 @@ Lcom/android/internal/os/CachedDeviceState$TimeInStateStopwatch;
Lcom/android/internal/os/CachedDeviceState;
Lcom/android/internal/os/ClassLoaderFactory;
Lcom/android/internal/os/Clock;
-Lcom/android/internal/os/FeatureFlags;
-Lcom/android/internal/os/FeatureFlagsImpl;
-Lcom/android/internal/os/Flags;
Lcom/android/internal/os/FuseAppLoop$1;
Lcom/android/internal/os/FuseAppLoop;
Lcom/android/internal/os/FuseUnavailableMountException;
@@ -33891,11 +33958,10 @@ Lcom/android/internal/os/ZygoteServer;
Lcom/android/internal/os/logging/MetricsLoggerWrapper;
Lcom/android/internal/pm/parsing/PackageParser2$Callback;
Lcom/android/internal/pm/parsing/PackageParserException;
-Lcom/android/internal/pm/pkg/component/flags/FeatureFlags;
-Lcom/android/internal/pm/pkg/component/flags/FeatureFlagsImpl;
Lcom/android/internal/pm/pkg/component/flags/Flags;
Lcom/android/internal/pm/pkg/parsing/ParsingPackageUtils$Callback;
Lcom/android/internal/policy/AttributeCache;
+Lcom/android/internal/policy/BackdropFrameRenderer;
Lcom/android/internal/policy/DecorContext;
Lcom/android/internal/policy/DecorView$$ExternalSyntheticLambda0;
Lcom/android/internal/policy/DecorView$$ExternalSyntheticLambda1;
@@ -33962,6 +34028,7 @@ Lcom/android/internal/protolog/common/IProtoLogGroup;
Lcom/android/internal/protolog/common/LogDataType;
Lcom/android/internal/security/VerityUtils;
Lcom/android/internal/statusbar/IAddTileResultCallback;
+Lcom/android/internal/statusbar/IStatusBar$Stub$Proxy;
Lcom/android/internal/statusbar/IStatusBar$Stub;
Lcom/android/internal/statusbar/IStatusBar;
Lcom/android/internal/statusbar/IStatusBarService$Stub$Proxy;
@@ -34044,8 +34111,6 @@ Lcom/android/internal/telephony/CarrierAppUtils;
Lcom/android/internal/telephony/CarrierInfoManager;
Lcom/android/internal/telephony/CarrierKeyDownloadManager$1;
Lcom/android/internal/telephony/CarrierKeyDownloadManager$2;
-Lcom/android/internal/telephony/CarrierKeyDownloadManager$3;
-Lcom/android/internal/telephony/CarrierKeyDownloadManager$DefaultNetworkCallback;
Lcom/android/internal/telephony/CarrierKeyDownloadManager;
Lcom/android/internal/telephony/CarrierPrivilegesTracker$1;
Lcom/android/internal/telephony/CarrierPrivilegesTracker;
@@ -34200,6 +34265,7 @@ Lcom/android/internal/telephony/IState;
Lcom/android/internal/telephony/ISub$Stub$Proxy;
Lcom/android/internal/telephony/ISub$Stub;
Lcom/android/internal/telephony/ISub;
+Lcom/android/internal/telephony/ITelephony$Stub$Proxy;
Lcom/android/internal/telephony/ITelephony$Stub;
Lcom/android/internal/telephony/ITelephony;
Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;
@@ -34374,6 +34440,7 @@ Lcom/android/internal/telephony/RIL;
Lcom/android/internal/telephony/RILConstants$$ExternalSyntheticLambda0;
Lcom/android/internal/telephony/RILConstants$$ExternalSyntheticLambda1;
Lcom/android/internal/telephony/RILConstants;
+Lcom/android/internal/telephony/RILRequest$$ExternalSyntheticLambda0;
Lcom/android/internal/telephony/RILRequest;
Lcom/android/internal/telephony/RadioBugDetector;
Lcom/android/internal/telephony/RadioCapability;
@@ -35025,7 +35092,6 @@ Lcom/android/internal/telephony/nano/PersistAtomsProto$CarrierIdMismatch;
Lcom/android/internal/telephony/nano/PersistAtomsProto$CellularDataServiceSwitch;
Lcom/android/internal/telephony/nano/PersistAtomsProto$CellularServiceState;
Lcom/android/internal/telephony/nano/PersistAtomsProto$DataCallSession;
-Lcom/android/internal/telephony/nano/PersistAtomsProto$DataNetworkValidation;
Lcom/android/internal/telephony/nano/PersistAtomsProto$EmergencyNumbersInfo;
Lcom/android/internal/telephony/nano/PersistAtomsProto$GbaEvent;
Lcom/android/internal/telephony/nano/PersistAtomsProto$ImsDedicatedBearerEvent;
@@ -35681,6 +35747,7 @@ Lcom/android/internal/widget/CachingIconView;
Lcom/android/internal/widget/ConversationLayout$1;
Lcom/android/internal/widget/ConversationLayout$TouchDelegateComposite;
Lcom/android/internal/widget/ConversationLayout;
+Lcom/android/internal/widget/DecorCaptionView;
Lcom/android/internal/widget/DecorContentParent;
Lcom/android/internal/widget/DecorToolbar;
Lcom/android/internal/widget/DialogTitle;
@@ -35745,11 +35812,8 @@ Lcom/android/internal/widget/floatingtoolbar/FloatingToolbar$$ExternalSyntheticL
Lcom/android/internal/widget/floatingtoolbar/FloatingToolbar$$ExternalSyntheticLambda1;
Lcom/android/internal/widget/floatingtoolbar/FloatingToolbar;
Lcom/android/internal/widget/floatingtoolbar/FloatingToolbarPopup;
-Lcom/android/media/flags/FeatureFlags;
-Lcom/android/media/flags/FeatureFlagsImpl;
Lcom/android/media/flags/Flags;
Lcom/android/modules/expresslog/Counter;
-Lcom/android/modules/expresslog/MetricIds$MetricInfo;
Lcom/android/modules/expresslog/MetricIds;
Lcom/android/modules/expresslog/StatsExpressLog;
Lcom/android/modules/utils/BasicShellCommandHandler;
@@ -35783,16 +35847,12 @@ Lcom/android/phone/ecc/nano/ProtobufEccData$CountryInfo;
Lcom/android/phone/ecc/nano/ProtobufEccData$EccInfo;
Lcom/android/phone/ecc/nano/UnknownFieldData;
Lcom/android/phone/ecc/nano/WireFormatNano;
-Lcom/android/sdksandbox/flags/FeatureFlags;
-Lcom/android/sdksandbox/flags/FeatureFlagsImpl;
Lcom/android/sdksandbox/flags/Flags;
Lcom/android/server/AppWidgetBackupBridge;
Lcom/android/server/LocalServices;
Lcom/android/server/WidgetBackupProvider;
Lcom/android/server/am/nano/Capabilities;
Lcom/android/server/am/nano/Capability;
-Lcom/android/server/am/nano/FrameworkCapability;
-Lcom/android/server/am/nano/VMCapability;
Lcom/android/server/backup/AccountManagerBackupHelper;
Lcom/android/server/backup/AccountSyncSettingsBackupHelper;
Lcom/android/server/backup/NotificationBackupHelper;
@@ -35821,7 +35881,6 @@ Lcom/android/server/connectivity/metrics/nano/IpConnectivityLogClass$WakeupStats
Lcom/android/server/criticalevents/nano/CriticalEventLogProto;
Lcom/android/server/criticalevents/nano/CriticalEventLogStorageProto;
Lcom/android/server/criticalevents/nano/CriticalEventProto$AppNotResponding;
-Lcom/android/server/criticalevents/nano/CriticalEventProto$ExcessiveBinderCalls;
Lcom/android/server/criticalevents/nano/CriticalEventProto$HalfWatchdog;
Lcom/android/server/criticalevents/nano/CriticalEventProto$InstallPackages;
Lcom/android/server/criticalevents/nano/CriticalEventProto$JavaCrash;
@@ -35872,9 +35931,6 @@ Lcom/android/server/sip/SipWakeLock;
Lcom/android/server/sip/SipWakeupTimer$MyEvent;
Lcom/android/server/sip/SipWakeupTimer$MyEventComparator;
Lcom/android/server/sip/SipWakeupTimer;
-Lcom/android/server/telecom/flags/FeatureFlags;
-Lcom/android/server/telecom/flags/FeatureFlagsImpl;
-Lcom/android/server/telecom/flags/Flags;
Lcom/android/server/usage/AppStandbyInternal$AppIdleStateChangeListener;
Lcom/android/server/usage/AppStandbyInternal;
Lcom/android/server/wm/nano/WindowManagerProtos$TaskSnapshotProto;
@@ -36344,6 +36400,7 @@ Lgov/nist/javax/sip/stack/TLSMessageProcessor;
Lgov/nist/javax/sip/stack/UDPMessageChannel$PingBackTimerTask;
Lgov/nist/javax/sip/stack/UDPMessageChannel;
Lgov/nist/javax/sip/stack/UDPMessageProcessor;
+Ljava/io/InterruptedIOException;
Ljavax/microedition/khronos/egl/EGL10;
Ljavax/microedition/khronos/egl/EGL11;
Ljavax/microedition/khronos/egl/EGL;
@@ -36592,8 +36649,6 @@ Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;
[Landroid/graphics/fonts/FontVariationAxis;
[Landroid/hardware/CameraStatus;
[Landroid/hardware/biometrics/BiometricSourceType;
-[Landroid/hardware/camera2/CameraCharacteristics$Key;
-[Landroid/hardware/camera2/marshal/MarshalQueryable;
[Landroid/hardware/camera2/params/Capability;
[Landroid/hardware/camera2/params/Face;
[Landroid/hardware/camera2/params/HighSpeedVideoConfiguration;
@@ -36655,7 +36710,6 @@ Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;
[Landroid/icu/impl/units/MeasureUnitImpl$InitialCompoundPart;
[Landroid/icu/impl/units/MeasureUnitImpl$PowerPart;
[Landroid/icu/impl/units/MeasureUnitImpl$UnitsParser$Token$Type;
-[Landroid/icu/lang/UCharacter$IdentifierType;
[Landroid/icu/lang/UCharacter$UnicodeBlock;
[Landroid/icu/lang/UScript$ScriptUsage;
[Landroid/icu/lang/UScriptRun$ParenStackEntry;
@@ -36910,7 +36964,6 @@ Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;
[Landroid/widget/SpellChecker$SpellParser;
[Landroid/widget/TextView$BufferType;
[Landroid/widget/TextView$ChangeWatcher;
-[Landroid/window/BackTouchTracker$TouchTrackerState;
[Landroid/window/TransitionFilter$Requirement;
[Lcom/android/framework/protobuf/GeneratedMessageLite$MethodToInvoke;
[Lcom/android/framework/protobuf/MessageInfoFactory;
@@ -36998,4 +37051,4 @@ Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;
[[Landroid/graphics/Rect;
[[Landroid/media/ExifInterface$ExifTag;
[[Landroid/widget/GridLayout$Arc;
-[[Lcom/android/internal/widget/LockPatternView$Cell;
+[[Lcom/android/internal/widget/LockPatternView$Cell; \ No newline at end of file
diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt
index c830a7b4f3d3..ee417e8e8639 100644
--- a/config/boot-image-profile.txt
+++ b/config/boot-image-profile.txt
@@ -26,6 +26,7 @@ HSPLandroid/accounts/Account;-><init>(Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/accounts/Account;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/accounts/Account;->equals(Ljava/lang/Object;)Z
HSPLandroid/accounts/Account;->hashCode()I
+HSPLandroid/accounts/Account;->onAccountAccessed(Ljava/lang/String;)V
HSPLandroid/accounts/Account;->toString()Ljava/lang/String;
HSPLandroid/accounts/Account;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/accounts/AccountManager$10;-><init>(Landroid/accounts/AccountManager;Landroid/app/Activity;Landroid/os/Handler;Landroid/accounts/AccountManagerCallback;Landroid/accounts/Account;Ljava/lang/String;ZLandroid/os/Bundle;)V
@@ -125,13 +126,13 @@ HSPLandroid/animation/AnimationHandler$$ExternalSyntheticLambda0;->doFrame(J)V
HSPLandroid/animation/AnimationHandler$1;-><init>(Landroid/animation/AnimationHandler;)V
HSPLandroid/animation/AnimationHandler$1;->doFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;Landroid/animation/AnimationHandler$MyFrameCallbackProvider;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;-><init>(Landroid/animation/AnimationHandler;)V
-HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->getFrameTime()J
-HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V
+HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->getFrameTime()J+]Landroid/view/Choreographer;Landroid/view/Choreographer;
+HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/animation/AnimationHandler;-><init>()V
-HSPLandroid/animation/AnimationHandler;->addAnimationFrameCallback(Landroid/animation/AnimationHandler$AnimationFrameCallback;J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;Landroid/animation/AnimationHandler$MyFrameCallbackProvider;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/animation/AnimationHandler;->autoCancelBasedOn(Landroid/animation/ObjectAnimator;)V
-HSPLandroid/animation/AnimationHandler;->cleanUpList()V
-HSPLandroid/animation/AnimationHandler;->doAnimationFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallback;Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;,Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->addAnimationFrameCallback(Landroid/animation/AnimationHandler$AnimationFrameCallback;J)V
+HSPLandroid/animation/AnimationHandler;->autoCancelBasedOn(Landroid/animation/ObjectAnimator;)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->cleanUpList()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->doAnimationFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallback;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;,Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/AnimationHandler;->getAnimationCount()I
HSPLandroid/animation/AnimationHandler;->getInstance()Landroid/animation/AnimationHandler;
HSPLandroid/animation/AnimationHandler;->getProvider()Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;
@@ -156,18 +157,18 @@ HSPLandroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda6;-><init>
HSPLandroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda6;->call(Ljava/lang/Object;Ljava/lang/Object;Z)V
HSPLandroid/animation/Animator$AnimatorCaller;-><clinit>()V
HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$0(Landroid/animation/Animator$AnimatorListener;Landroid/animation/Animator;Z)V
-HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$4(Landroid/animation/ValueAnimator$AnimatorUpdateListener;Landroid/animation/ValueAnimator;Z)V
+HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$4(Landroid/animation/ValueAnimator$AnimatorUpdateListener;Landroid/animation/ValueAnimator;Z)V+]Landroid/animation/ValueAnimator$AnimatorUpdateListener;missing_types
HSPLandroid/animation/Animator$AnimatorConstantState;-><init>(Landroid/animation/Animator;)V
HSPLandroid/animation/Animator$AnimatorConstantState;->getChangingConfigurations()I
HSPLandroid/animation/Animator$AnimatorConstantState;->newInstance()Landroid/animation/Animator;
HSPLandroid/animation/Animator$AnimatorConstantState;->newInstance()Ljava/lang/Object;
-HSPLandroid/animation/Animator$AnimatorListener;->onAnimationEnd(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;megamorphic_types
-HSPLandroid/animation/Animator$AnimatorListener;->onAnimationStart(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;megamorphic_types
+HSPLandroid/animation/Animator$AnimatorListener;->onAnimationEnd(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;missing_types
+HSPLandroid/animation/Animator$AnimatorListener;->onAnimationStart(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;missing_types
HSPLandroid/animation/Animator;-><init>()V
-HSPLandroid/animation/Animator;->addListener(Landroid/animation/Animator$AnimatorListener;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/Animator;->addListener(Landroid/animation/Animator$AnimatorListener;)V
HSPLandroid/animation/Animator;->addPauseListener(Landroid/animation/Animator$AnimatorPauseListener;)V
HSPLandroid/animation/Animator;->appendChangingConfigurations(I)V
-HSPLandroid/animation/Animator;->callOnList(Ljava/util/ArrayList;Landroid/animation/Animator$AnimatorCaller;Ljava/lang/Object;Z)V+]Landroid/animation/Animator$AnimatorCaller;megamorphic_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/atomic/AtomicReference;
+HSPLandroid/animation/Animator;->callOnList(Ljava/util/ArrayList;Landroid/animation/Animator$AnimatorCaller;Ljava/lang/Object;Z)V+]Landroid/animation/Animator$AnimatorCaller;Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda1;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda0;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda6;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda2;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/atomic/AtomicReference;
HSPLandroid/animation/Animator;->clone()Landroid/animation/Animator;
HSPLandroid/animation/Animator;->createConstantState()Landroid/content/res/ConstantState;
HSPLandroid/animation/Animator;->getBackgroundPauseDelay()J
@@ -176,10 +177,10 @@ HSPLandroid/animation/Animator;->getListeners()Ljava/util/ArrayList;
HSPLandroid/animation/Animator;->getStartAndEndTimes(Landroid/util/LongArray;J)V
HSPLandroid/animation/Animator;->notifyEndListeners(Z)V
HSPLandroid/animation/Animator;->notifyListeners(Landroid/animation/Animator$AnimatorCaller;Z)V
-HSPLandroid/animation/Animator;->notifyStartListeners(Z)V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/Animator;->notifyStartListeners(Z)V
HSPLandroid/animation/Animator;->pause()V
HSPLandroid/animation/Animator;->removeAllListeners()V
-HSPLandroid/animation/Animator;->removeListener(Landroid/animation/Animator$AnimatorListener;)V
+HSPLandroid/animation/Animator;->removeListener(Landroid/animation/Animator$AnimatorListener;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/Animator;->setAllowRunningAsynchronously(Z)V
HSPLandroid/animation/AnimatorInflater$PathDataEvaluator;->evaluate(FLandroid/util/PathParser$PathData;Landroid/util/PathParser$PathData;)Landroid/util/PathParser$PathData;
HSPLandroid/animation/AnimatorInflater$PathDataEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
@@ -201,53 +202,53 @@ HSPLandroid/animation/AnimatorListenerAdapter;->onAnimationCancel(Landroid/anima
HSPLandroid/animation/AnimatorListenerAdapter;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorListenerAdapter;->onAnimationStart(Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorSet$1;-><init>(Landroid/animation/AnimatorSet;)V
-HSPLandroid/animation/AnimatorSet$1;->onAnimationEnd(Landroid/animation/Animator;)V
+HSPLandroid/animation/AnimatorSet$1;->onAnimationEnd(Landroid/animation/Animator;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
HSPLandroid/animation/AnimatorSet$2;-><init>(Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;)V
HSPLandroid/animation/AnimatorSet$2;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorSet$3;-><init>(Landroid/animation/AnimatorSet;)V
-HSPLandroid/animation/AnimatorSet$3;->compare(Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;)I
+HSPLandroid/animation/AnimatorSet$3;->compare(Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;)I+]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;
HSPLandroid/animation/AnimatorSet$3;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/animation/AnimatorSet$AnimationEvent;-><init>(Landroid/animation/AnimatorSet$Node;I)V
-HSPLandroid/animation/AnimatorSet$AnimationEvent;->getTime()J
+HSPLandroid/animation/AnimatorSet$AnimationEvent;->getTime()J+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
HSPLandroid/animation/AnimatorSet$Builder;-><init>(Landroid/animation/AnimatorSet;Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorSet$Builder;->after(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
HSPLandroid/animation/AnimatorSet$Builder;->before(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
HSPLandroid/animation/AnimatorSet$Builder;->with(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
HSPLandroid/animation/AnimatorSet$Node;-><init>(Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorSet$Node;->addChild(Landroid/animation/AnimatorSet$Node;)V
-HSPLandroid/animation/AnimatorSet$Node;->addParent(Landroid/animation/AnimatorSet$Node;)V
+HSPLandroid/animation/AnimatorSet$Node;->addParent(Landroid/animation/AnimatorSet$Node;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;
HSPLandroid/animation/AnimatorSet$Node;->addParents(Ljava/util/ArrayList;)V
-HSPLandroid/animation/AnimatorSet$Node;->addSibling(Landroid/animation/AnimatorSet$Node;)V
-HSPLandroid/animation/AnimatorSet$Node;->clone()Landroid/animation/AnimatorSet$Node;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet$Node;->addSibling(Landroid/animation/AnimatorSet$Node;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;
+HSPLandroid/animation/AnimatorSet$Node;->clone()Landroid/animation/AnimatorSet$Node;+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet$SeekState;-><init>(Landroid/animation/AnimatorSet;)V
HSPLandroid/animation/AnimatorSet$SeekState;->getPlayTimeNormalized()J
HSPLandroid/animation/AnimatorSet$SeekState;->isActive()Z
HSPLandroid/animation/AnimatorSet$SeekState;->reset()V
-HSPLandroid/animation/AnimatorSet;-><init>()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;-><init>()V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->addAnimationCallback(J)V
-HSPLandroid/animation/AnimatorSet;->addAnimationEndListener()V
+HSPLandroid/animation/AnimatorSet;->addAnimationEndListener()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->cancel()V
HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/Animator;
-HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/AnimatorSet;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/AnimatorSet;->createDependencyGraph()V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/AnimatorSet;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->createDependencyGraph()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->doAnimationFrame(J)Z+]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/animation/AnimatorSet;->end()V
-HSPLandroid/animation/AnimatorSet;->endAnimation()V
+HSPLandroid/animation/AnimatorSet;->end()V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
+HSPLandroid/animation/AnimatorSet;->endAnimation()V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/AnimatorSet;->ensureChildStartAndEndTimes()[J
HSPLandroid/animation/AnimatorSet;->findLatestEventIdForTime(J)I
HSPLandroid/animation/AnimatorSet;->findNextIndex(J[J)I
HSPLandroid/animation/AnimatorSet;->findSiblings(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V
HSPLandroid/animation/AnimatorSet;->getChangingConfigurations()I
-HSPLandroid/animation/AnimatorSet;->getChildAnimations()Ljava/util/ArrayList;
-HSPLandroid/animation/AnimatorSet;->getNodeForAnimation(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Node;
+HSPLandroid/animation/AnimatorSet;->getChildAnimations()Ljava/util/ArrayList;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->getNodeForAnimation(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Node;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/AnimatorSet;->getStartAndEndTimes(Landroid/util/LongArray;J)V
HSPLandroid/animation/AnimatorSet;->getStartDelay()J
HSPLandroid/animation/AnimatorSet;->getTotalDuration()J
-HSPLandroid/animation/AnimatorSet;->handleAnimationEvents(IIJ)V
-HSPLandroid/animation/AnimatorSet;->initAnimation()V
+HSPLandroid/animation/AnimatorSet;->handleAnimationEvents(IIJ)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->initAnimation()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->initChildren()V
-HSPLandroid/animation/AnimatorSet;->isEmptySet(Landroid/animation/AnimatorSet;)Z
-HSPLandroid/animation/AnimatorSet;->isInitialized()Z
+HSPLandroid/animation/AnimatorSet;->isEmptySet(Landroid/animation/AnimatorSet;)Z+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->isInitialized()Z+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->isRunning()Z
HSPLandroid/animation/AnimatorSet;->isStarted()Z
HSPLandroid/animation/AnimatorSet;->play(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
@@ -257,46 +258,46 @@ HSPLandroid/animation/AnimatorSet;->playTogether([Landroid/animation/Animator;)V
HSPLandroid/animation/AnimatorSet;->pulseAnimationFrame(J)Z
HSPLandroid/animation/AnimatorSet;->pulseFrame(Landroid/animation/AnimatorSet$Node;J)V
HSPLandroid/animation/AnimatorSet;->removeAnimationCallback()V
-HSPLandroid/animation/AnimatorSet;->removeAnimationEndListener()V
+HSPLandroid/animation/AnimatorSet;->removeAnimationEndListener()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->setDuration(J)Landroid/animation/Animator;
HSPLandroid/animation/AnimatorSet;->setDuration(J)Landroid/animation/AnimatorSet;
HSPLandroid/animation/AnimatorSet;->setInterpolator(Landroid/animation/TimeInterpolator;)V
HSPLandroid/animation/AnimatorSet;->setStartDelay(J)V
-HSPLandroid/animation/AnimatorSet;->setTarget(Ljava/lang/Object;)V
+HSPLandroid/animation/AnimatorSet;->setTarget(Ljava/lang/Object;)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/animation/AnimatorSet;->shouldPlayTogether()Z
HSPLandroid/animation/AnimatorSet;->skipToEndValue(Z)V
-HSPLandroid/animation/AnimatorSet;->sortAnimationEvents()V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->sortAnimationEvents()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->start()V
-HSPLandroid/animation/AnimatorSet;->start(ZZ)V
-HSPLandroid/animation/AnimatorSet;->startAnimation()V
+HSPLandroid/animation/AnimatorSet;->start(ZZ)V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->startAnimation()V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/AnimatorSet;->startWithoutPulsing(Z)V
-HSPLandroid/animation/AnimatorSet;->updateAnimatorsDuration()V
-HSPLandroid/animation/AnimatorSet;->updatePlayTime(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V
+HSPLandroid/animation/AnimatorSet;->updateAnimatorsDuration()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->updatePlayTime(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
HSPLandroid/animation/ArgbEvaluator;-><init>()V
-HSPLandroid/animation/ArgbEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/lang/Integer;Ljava/lang/Integer;
+HSPLandroid/animation/ArgbEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/animation/ArgbEvaluator;->getInstance()Landroid/animation/ArgbEvaluator;
HSPLandroid/animation/FloatKeyframeSet;-><init>([Landroid/animation/Keyframe$FloatKeyframe;)V
HSPLandroid/animation/FloatKeyframeSet;->clone()Landroid/animation/FloatKeyframeSet;
HSPLandroid/animation/FloatKeyframeSet;->clone()Landroid/animation/Keyframes;
-HSPLandroid/animation/FloatKeyframeSet;->getFloatValue(F)F+]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/FloatKeyframeSet;->getFloatValue(F)F+]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;
HSPLandroid/animation/FloatKeyframeSet;->getValue(F)Ljava/lang/Object;
HSPLandroid/animation/IntKeyframeSet;-><init>([Landroid/animation/Keyframe$IntKeyframe;)V
-HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/IntKeyframeSet;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/IntKeyframeSet;+]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;
HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/Keyframes;
-HSPLandroid/animation/IntKeyframeSet;->getIntValue(F)I+]Landroid/animation/Keyframe$IntKeyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/IntKeyframeSet;->getIntValue(F)I
HSPLandroid/animation/Keyframe$FloatKeyframe;-><init>(F)V
HSPLandroid/animation/Keyframe$FloatKeyframe;-><init>(FF)V
HSPLandroid/animation/Keyframe$FloatKeyframe;->clone()Landroid/animation/Keyframe$FloatKeyframe;+]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;
HSPLandroid/animation/Keyframe$FloatKeyframe;->clone()Landroid/animation/Keyframe;
HSPLandroid/animation/Keyframe$FloatKeyframe;->getFloatValue()F
HSPLandroid/animation/Keyframe$FloatKeyframe;->getValue()Ljava/lang/Object;
-HSPLandroid/animation/Keyframe$FloatKeyframe;->setValue(Ljava/lang/Object;)V
+HSPLandroid/animation/Keyframe$FloatKeyframe;->setValue(Ljava/lang/Object;)V+]Ljava/lang/Object;Ljava/lang/Float;]Ljava/lang/Float;Ljava/lang/Float;
HSPLandroid/animation/Keyframe$IntKeyframe;-><init>(FI)V
-HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe$IntKeyframe;+]Landroid/animation/Keyframe$IntKeyframe;Landroid/animation/Keyframe$IntKeyframe;
+HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe$IntKeyframe;
HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe;
HSPLandroid/animation/Keyframe$IntKeyframe;->getIntValue()I
HSPLandroid/animation/Keyframe$IntKeyframe;->getValue()Ljava/lang/Object;
-HSPLandroid/animation/Keyframe$IntKeyframe;->setValue(Ljava/lang/Object;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Object;Ljava/lang/Integer;
+HSPLandroid/animation/Keyframe$IntKeyframe;->setValue(Ljava/lang/Object;)V
HSPLandroid/animation/Keyframe$ObjectKeyframe;-><init>(FLjava/lang/Object;)V
HSPLandroid/animation/Keyframe$ObjectKeyframe;->clone()Landroid/animation/Keyframe$ObjectKeyframe;
HSPLandroid/animation/Keyframe$ObjectKeyframe;->clone()Landroid/animation/Keyframe;
@@ -312,17 +313,17 @@ HSPLandroid/animation/Keyframe;->ofObject(FLjava/lang/Object;)Landroid/animation
HSPLandroid/animation/Keyframe;->setInterpolator(Landroid/animation/TimeInterpolator;)V
HSPLandroid/animation/Keyframe;->setValueWasSetOnStart(Z)V
HSPLandroid/animation/Keyframe;->valueWasSetOnStart()Z
-HSPLandroid/animation/KeyframeSet;-><init>([Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;
+HSPLandroid/animation/KeyframeSet;-><init>([Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$FloatKeyframe;
HSPLandroid/animation/KeyframeSet;->clone()Landroid/animation/KeyframeSet;
HSPLandroid/animation/KeyframeSet;->clone()Landroid/animation/Keyframes;
HSPLandroid/animation/KeyframeSet;->getKeyframes()Ljava/util/List;
-HSPLandroid/animation/KeyframeSet;->getValue(F)Ljava/lang/Object;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/TypeEvaluator;Landroid/animation/ArgbEvaluator;
+HSPLandroid/animation/KeyframeSet;->getValue(F)Ljava/lang/Object;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;
HSPLandroid/animation/KeyframeSet;->ofFloat([F)Landroid/animation/KeyframeSet;
HSPLandroid/animation/KeyframeSet;->ofInt([I)Landroid/animation/KeyframeSet;
HSPLandroid/animation/KeyframeSet;->ofObject([Ljava/lang/Object;)Landroid/animation/KeyframeSet;
HSPLandroid/animation/KeyframeSet;->setEvaluator(Landroid/animation/TypeEvaluator;)V
HSPLandroid/animation/LayoutTransition$1;->onAnimationEnd(Landroid/animation/Animator;)V
-HSPLandroid/animation/LayoutTransition$2;->onLayoutChange(Landroid/view/View;IIIIIIII)V+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/lang/Object;Ljava/lang/Integer;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;
+HSPLandroid/animation/LayoutTransition$2;->onLayoutChange(Landroid/view/View;IIIIIIII)V
HSPLandroid/animation/LayoutTransition$3;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/animation/LayoutTransition$3;->onAnimationStart(Landroid/animation/Animator;)V
HSPLandroid/animation/LayoutTransition$4;->onAnimationEnd(Landroid/animation/Animator;)V
@@ -350,20 +351,20 @@ HSPLandroid/animation/LayoutTransition;->setAnimator(ILandroid/animation/Animato
HSPLandroid/animation/LayoutTransition;->setDuration(J)V
HSPLandroid/animation/LayoutTransition;->setInterpolator(ILandroid/animation/TimeInterpolator;)V
HSPLandroid/animation/LayoutTransition;->setStartDelay(IJ)V
-HSPLandroid/animation/LayoutTransition;->setupChangeAnimation(Landroid/view/ViewGroup;ILandroid/animation/Animator;JLandroid/view/View;)V+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/view/View;missing_types]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/LayoutTransition;->setupChangeAnimation(Landroid/view/ViewGroup;ILandroid/animation/Animator;JLandroid/view/View;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/view/View;missing_types]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
HSPLandroid/animation/LayoutTransition;->showChild(Landroid/view/ViewGroup;Landroid/view/View;I)V
HSPLandroid/animation/LayoutTransition;->startChangingAnimations()V
HSPLandroid/animation/ObjectAnimator;-><init>()V
HSPLandroid/animation/ObjectAnimator;-><init>(Ljava/lang/Object;Landroid/util/Property;)V
HSPLandroid/animation/ObjectAnimator;-><init>(Ljava/lang/Object;Ljava/lang/String;)V
-HSPLandroid/animation/ObjectAnimator;->animateValue(F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ObjectAnimator;->animateValue(F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/ObjectAnimator;->clone()Landroid/animation/Animator;
HSPLandroid/animation/ObjectAnimator;->clone()Landroid/animation/ObjectAnimator;
-HSPLandroid/animation/ObjectAnimator;->getNameForTrace()Ljava/lang/String;+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/animation/ObjectAnimator;->getPropertyName()Ljava/lang/String;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/animation/ObjectAnimator;->getTarget()Ljava/lang/Object;+]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/animation/ObjectAnimator;->getNameForTrace()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;
+HSPLandroid/animation/ObjectAnimator;->getPropertyName()Ljava/lang/String;+]Landroid/util/Property;missing_types
+HSPLandroid/animation/ObjectAnimator;->getTarget()Ljava/lang/Object;
HSPLandroid/animation/ObjectAnimator;->hasSameTargetAndProperties(Landroid/animation/Animator;)Z
-HSPLandroid/animation/ObjectAnimator;->initAnimation()V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ObjectAnimator;->initAnimation()V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/ObjectAnimator;->isInitialized()Z
HSPLandroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Landroid/util/Property;[F)Landroid/animation/ObjectAnimator;
HSPLandroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Ljava/lang/String;[F)Landroid/animation/ObjectAnimator;
@@ -376,7 +377,7 @@ HSPLandroid/animation/ObjectAnimator;->setAutoCancel(Z)V
HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/Animator;
HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/ObjectAnimator;
HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ObjectAnimator;->setFloatValues([F)V
+HSPLandroid/animation/ObjectAnimator;->setFloatValues([F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;
HSPLandroid/animation/ObjectAnimator;->setIntValues([I)V
HSPLandroid/animation/ObjectAnimator;->setObjectValues([Ljava/lang/Object;)V
HSPLandroid/animation/ObjectAnimator;->setProperty(Landroid/util/Property;)V
@@ -402,50 +403,50 @@ HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->calculate
HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
-HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/util/FloatProperty;Landroid/view/View$12;,Landroid/view/View$13;]Landroid/util/Property;missing_types
+HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/util/FloatProperty;Landroid/view/View$2;,Landroid/view/View$12;,Landroid/view/View$13;,Landroid/view/View$5;
HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setFloatValues([F)V
HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setProperty(Landroid/util/Property;)V
-HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V
+HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Long;Ljava/lang/Long;
HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;-><init>(Ljava/lang/String;[I)V
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->calculateValue(F)V
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->calculateValue(F)V+]Landroid/animation/Keyframes$IntKeyframes;Landroid/animation/IntKeyframeSet;
HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V
HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setIntValues([I)V
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/lang/Long;Ljava/lang/Long;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Long;Ljava/lang/Long;
HSPLandroid/animation/PropertyValuesHolder$PropertyValues;-><init>()V
-HSPLandroid/animation/PropertyValuesHolder;-><init>(Landroid/util/Property;)V
+HSPLandroid/animation/PropertyValuesHolder;-><init>(Landroid/util/Property;)V+]Landroid/util/Property;missing_types
HSPLandroid/animation/PropertyValuesHolder;-><init>(Ljava/lang/String;)V
HSPLandroid/animation/PropertyValuesHolder;-><init>(Ljava/lang/String;Landroid/animation/PropertyValuesHolder-IA;)V
-HSPLandroid/animation/PropertyValuesHolder;->calculateValue(F)V
-HSPLandroid/animation/PropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->calculateValue(F)V+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/FloatKeyframeSet;
HSPLandroid/animation/PropertyValuesHolder;->convertBack(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/animation/PropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
HSPLandroid/animation/PropertyValuesHolder;->getMethodName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/animation/PropertyValuesHolder;->getPropertyFunction(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;
HSPLandroid/animation/PropertyValuesHolder;->getPropertyName()Ljava/lang/String;
-HSPLandroid/animation/PropertyValuesHolder;->getPropertyValues(Landroid/animation/PropertyValuesHolder$PropertyValues;)V+]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/PropertyValuesHolder;->getPropertyValues(Landroid/animation/PropertyValuesHolder$PropertyValues;)V
HSPLandroid/animation/PropertyValuesHolder;->getValueType()Ljava/lang/Class;
-HSPLandroid/animation/PropertyValuesHolder;->init()V+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->init()V
HSPLandroid/animation/PropertyValuesHolder;->ofFloat(Landroid/util/Property;[F)Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder;->ofFloat(Ljava/lang/String;[F)Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder;->ofInt(Ljava/lang/String;[I)Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder;->ofKeyframes(Ljava/lang/String;Landroid/animation/Keyframes;)Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder;->ofObject(Ljava/lang/String;Landroid/animation/TypeEvaluator;[Ljava/lang/Object;)Landroid/animation/PropertyValuesHolder;
-HSPLandroid/animation/PropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V
+HSPLandroid/animation/PropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder;
HSPLandroid/animation/PropertyValuesHolder;->setEvaluator(Landroid/animation/TypeEvaluator;)V
HSPLandroid/animation/PropertyValuesHolder;->setFloatValues([F)V
HSPLandroid/animation/PropertyValuesHolder;->setIntValues([I)V
HSPLandroid/animation/PropertyValuesHolder;->setObjectValues([Ljava/lang/Object;)V
HSPLandroid/animation/PropertyValuesHolder;->setProperty(Landroid/util/Property;)V
HSPLandroid/animation/PropertyValuesHolder;->setPropertyName(Ljava/lang/String;)V
-HSPLandroid/animation/PropertyValuesHolder;->setupEndValue(Ljava/lang/Object;)V+]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/PropertyValuesHolder;->setupEndValue(Ljava/lang/Object;)V
HSPLandroid/animation/PropertyValuesHolder;->setupGetter(Ljava/lang/Class;)V
-HSPLandroid/animation/PropertyValuesHolder;->setupSetterAndGetter(Ljava/lang/Object;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/KeyframeSet;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
-HSPLandroid/animation/PropertyValuesHolder;->setupSetterOrGetter(Ljava/lang/Class;Ljava/util/HashMap;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;+]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/PropertyValuesHolder;->setupStartValue(Ljava/lang/Object;)V+]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
-HSPLandroid/animation/PropertyValuesHolder;->setupValue(Ljava/lang/Object;Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupSetterAndGetter(Ljava/lang/Object;)V+]Ljava/lang/Object;missing_types]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;,Landroid/animation/FloatKeyframeSet;,Landroid/animation/KeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;]Landroid/util/Property;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupSetterOrGetter(Ljava/lang/Class;Ljava/util/HashMap;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupStartValue(Ljava/lang/Object;)V
+HSPLandroid/animation/PropertyValuesHolder;->setupValue(Ljava/lang/Object;Landroid/animation/Keyframe;)V+]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;
HSPLandroid/animation/StateListAnimator$1;-><init>(Landroid/animation/StateListAnimator;)V
HSPLandroid/animation/StateListAnimator$1;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;-><init>(Landroid/animation/StateListAnimator;)V
@@ -453,10 +454,10 @@ HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;->newInst
HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;->newInstance()Ljava/lang/Object;
HSPLandroid/animation/StateListAnimator$Tuple;-><init>([ILandroid/animation/Animator;)V
HSPLandroid/animation/StateListAnimator;-><init>()V
-HSPLandroid/animation/StateListAnimator;->addState([ILandroid/animation/Animator;)V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/StateListAnimator;->addState([ILandroid/animation/Animator;)V
HSPLandroid/animation/StateListAnimator;->appendChangingConfigurations(I)V
HSPLandroid/animation/StateListAnimator;->clearTarget()V
-HSPLandroid/animation/StateListAnimator;->clone()Landroid/animation/StateListAnimator;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/StateListAnimator;->clone()Landroid/animation/StateListAnimator;
HSPLandroid/animation/StateListAnimator;->createConstantState()Landroid/content/res/ConstantState;
HSPLandroid/animation/StateListAnimator;->getChangingConfigurations()I
HSPLandroid/animation/StateListAnimator;->getTarget()Landroid/view/View;
@@ -472,17 +473,17 @@ HSPLandroid/animation/ValueAnimator;-><init>()V
HSPLandroid/animation/ValueAnimator;->addAnimationCallback(J)V
HSPLandroid/animation/ValueAnimator;->addUpdateListener(Landroid/animation/ValueAnimator$AnimatorUpdateListener;)V
HSPLandroid/animation/ValueAnimator;->animateBasedOnTime(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ValueAnimator;->animateValue(F)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Landroid/animation/TimeInterpolator;missing_types]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->animateValue(F)V+]Landroid/animation/TimeInterpolator;missing_types]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;,Landroid/animation/ObjectAnimator;
HSPLandroid/animation/ValueAnimator;->areAnimatorsEnabled()Z
HSPLandroid/animation/ValueAnimator;->cancel()V
HSPLandroid/animation/ValueAnimator;->clampFraction(F)F
HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/Animator;
-HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/ValueAnimator;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/ValueAnimator;->doAnimationFrame(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/ValueAnimator;+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ValueAnimator;->doAnimationFrame(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;,Landroid/animation/ObjectAnimator;
HSPLandroid/animation/ValueAnimator;->end()V
-HSPLandroid/animation/ValueAnimator;->endAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->endAnimation()V
HSPLandroid/animation/ValueAnimator;->getAnimatedFraction()F
-HSPLandroid/animation/ValueAnimator;->getAnimatedValue()Ljava/lang/Object;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ValueAnimator;->getAnimatedValue()Ljava/lang/Object;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;
HSPLandroid/animation/ValueAnimator;->getAnimationHandler()Landroid/animation/AnimationHandler;
HSPLandroid/animation/ValueAnimator;->getCurrentAnimationsCount()I
HSPLandroid/animation/ValueAnimator;->getCurrentIteration(F)I
@@ -513,25 +514,25 @@ HSPLandroid/animation/ValueAnimator;->removeAnimationCallback()V
HSPLandroid/animation/ValueAnimator;->resolveDurationScale()F
HSPLandroid/animation/ValueAnimator;->setAllowRunningAsynchronously(Z)V
HSPLandroid/animation/ValueAnimator;->setAnimationHandler(Landroid/animation/AnimationHandler;)V
-HSPLandroid/animation/ValueAnimator;->setCurrentFraction(F)V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->setCurrentFraction(F)V
HSPLandroid/animation/ValueAnimator;->setCurrentPlayTime(J)V
HSPLandroid/animation/ValueAnimator;->setDuration(J)Landroid/animation/Animator;
HSPLandroid/animation/ValueAnimator;->setDuration(J)Landroid/animation/ValueAnimator;
HSPLandroid/animation/ValueAnimator;->setDurationScale(F)V
HSPLandroid/animation/ValueAnimator;->setEvaluator(Landroid/animation/TypeEvaluator;)V
-HSPLandroid/animation/ValueAnimator;->setFloatValues([F)V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->setFloatValues([F)V
HSPLandroid/animation/ValueAnimator;->setIntValues([I)V
HSPLandroid/animation/ValueAnimator;->setInterpolator(Landroid/animation/TimeInterpolator;)V
HSPLandroid/animation/ValueAnimator;->setObjectValues([Ljava/lang/Object;)V
HSPLandroid/animation/ValueAnimator;->setRepeatCount(I)V
HSPLandroid/animation/ValueAnimator;->setRepeatMode(I)V
HSPLandroid/animation/ValueAnimator;->setStartDelay(J)V
-HSPLandroid/animation/ValueAnimator;->setValues([Landroid/animation/PropertyValuesHolder;)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/ValueAnimator;->setValues([Landroid/animation/PropertyValuesHolder;)V
HSPLandroid/animation/ValueAnimator;->shouldPlayBackward(IZ)Z
HSPLandroid/animation/ValueAnimator;->skipToEndValue(Z)V
HSPLandroid/animation/ValueAnimator;->start()V
-HSPLandroid/animation/ValueAnimator;->start(Z)V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ValueAnimator;->startAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->start(Z)V
+HSPLandroid/animation/ValueAnimator;->startAnimation()V
HSPLandroid/animation/ValueAnimator;->startWithoutPulsing(Z)V
HSPLandroid/app/Activity$1;-><init>(Landroid/app/Activity;)V
HSPLandroid/app/Activity$1;->isTaskRoot()Z
@@ -545,7 +546,7 @@ HSPLandroid/app/Activity;-><init>()V
HSPLandroid/app/Activity;->attach(Landroid/content/Context;Landroid/app/ActivityThread;Landroid/app/Instrumentation;Landroid/os/IBinder;ILandroid/app/Application;Landroid/content/Intent;Landroid/content/pm/ActivityInfo;Ljava/lang/CharSequence;Landroid/app/Activity;Ljava/lang/String;Landroid/app/Activity$NonConfigurationInstances;Landroid/content/res/Configuration;Ljava/lang/String;Lcom/android/internal/app/IVoiceInteractor;Landroid/view/Window;Landroid/view/ViewRootImpl$ActivityConfigCallback;Landroid/os/IBinder;Landroid/os/IBinder;)V
HSPLandroid/app/Activity;->attachBaseContext(Landroid/content/Context;)V
HSPLandroid/app/Activity;->cancelInputsAndStartExitTransition(Landroid/os/Bundle;)V
-HSPLandroid/app/Activity;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/Activity;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;
HSPLandroid/app/Activity;->dispatchActivityCreated(Landroid/os/Bundle;)V
HSPLandroid/app/Activity;->dispatchActivityPostCreated(Landroid/os/Bundle;)V
HSPLandroid/app/Activity;->dispatchActivityPostResumed()V
@@ -608,7 +609,7 @@ HSPLandroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
HSPLandroid/app/Activity;->onCreateDescription()Ljava/lang/CharSequence;
HSPLandroid/app/Activity;->onCreateOptionsMenu(Landroid/view/Menu;)Z
HSPLandroid/app/Activity;->onCreatePanelMenu(ILandroid/view/Menu;)Z
-HSPLandroid/app/Activity;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;+]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/app/Activity;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/app/Activity;->onCreateView(Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/app/Activity;->onDestroy()V
HSPLandroid/app/Activity;->onDetachedFromWindow()V
@@ -639,7 +640,7 @@ HSPLandroid/app/Activity;->onTouchEvent(Landroid/view/MotionEvent;)Z
HSPLandroid/app/Activity;->onTrimMemory(I)V
HSPLandroid/app/Activity;->onUserInteraction()V
HSPLandroid/app/Activity;->onUserLeaveHint()V
-HSPLandroid/app/Activity;->onWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V
+HSPLandroid/app/Activity;->onWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/WindowManager;Landroid/view/WindowManagerImpl;
HSPLandroid/app/Activity;->onWindowFocusChanged(Z)V
HSPLandroid/app/Activity;->overridePendingTransition(II)V
HSPLandroid/app/Activity;->overridePendingTransition(III)V
@@ -689,10 +690,10 @@ HSPLandroid/app/ActivityClient;->activityResumed(Landroid/os/IBinder;Z)V
HSPLandroid/app/ActivityClient;->activityStopped(Landroid/os/IBinder;Landroid/os/Bundle;Landroid/os/PersistableBundle;Ljava/lang/CharSequence;)V
HSPLandroid/app/ActivityClient;->activityTopResumedStateLost()V
HSPLandroid/app/ActivityClient;->finishActivity(Landroid/os/IBinder;ILandroid/content/Intent;I)Z
-HSPLandroid/app/ActivityClient;->getActivityClientController()Landroid/app/IActivityClientController;+]Landroid/app/ActivityClient$ActivityClientControllerSingleton;Landroid/app/ActivityClient$ActivityClientControllerSingleton;
+HSPLandroid/app/ActivityClient;->getActivityClientController()Landroid/app/IActivityClientController;
HSPLandroid/app/ActivityClient;->getCallingActivity(Landroid/os/IBinder;)Landroid/content/ComponentName;
HSPLandroid/app/ActivityClient;->getDisplayId(Landroid/os/IBinder;)I
-HSPLandroid/app/ActivityClient;->getInstance()Landroid/app/ActivityClient;+]Landroid/util/Singleton;Landroid/app/ActivityClient$1;
+HSPLandroid/app/ActivityClient;->getInstance()Landroid/app/ActivityClient;
HSPLandroid/app/ActivityClient;->getTaskForActivity(Landroid/os/IBinder;Z)I
HSPLandroid/app/ActivityClient;->overridePendingTransition(Landroid/os/IBinder;Ljava/lang/String;III)V
HSPLandroid/app/ActivityClient;->reportActivityFullyDrawn(Landroid/os/IBinder;Z)V
@@ -868,7 +869,7 @@ HSPLandroid/app/ActivityThread$DumpResourcesData;-><init>()V
HSPLandroid/app/ActivityThread$GcIdler;-><init>(Landroid/app/ActivityThread;)V
HSPLandroid/app/ActivityThread$GcIdler;->queueIdle()Z
HSPLandroid/app/ActivityThread$H;-><init>(Landroid/app/ActivityThread;)V
-HSPLandroid/app/ActivityThread$H;->handleMessage(Landroid/os/Message;)V
+HSPLandroid/app/ActivityThread$H;->handleMessage(Landroid/os/Message;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/servertransaction/TransactionExecutor;Landroid/app/servertransaction/TransactionExecutor;
HSPLandroid/app/ActivityThread$Idler;-><init>(Landroid/app/ActivityThread;)V
HSPLandroid/app/ActivityThread$Idler;-><init>(Landroid/app/ActivityThread;Landroid/app/ActivityThread$Idler-IA;)V
HSPLandroid/app/ActivityThread$Idler;->queueIdle()Z
@@ -924,8 +925,8 @@ HSPLandroid/app/ActivityThread;->deliverNewIntents(Landroid/app/ActivityThread$A
HSPLandroid/app/ActivityThread;->deliverResults(Landroid/app/ActivityThread$ActivityClientRecord;Ljava/util/List;Ljava/lang/String;)V
HSPLandroid/app/ActivityThread;->dumpMemoryInfo(Landroid/util/proto/ProtoOutputStream;JLjava/lang/String;IIIIIIZIII)V
HSPLandroid/app/ActivityThread;->getActivitiesToBeDestroyed()Ljava/util/Map;
-HSPLandroid/app/ActivityThread;->getActivity(Landroid/os/IBinder;)Landroid/app/Activity;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
-HSPLandroid/app/ActivityThread;->getActivityClient(Landroid/os/IBinder;)Landroid/app/ActivityThread$ActivityClientRecord;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/app/ActivityThread;->getActivity(Landroid/os/IBinder;)Landroid/app/Activity;
+HSPLandroid/app/ActivityThread;->getActivityClient(Landroid/os/IBinder;)Landroid/app/ActivityThread$ActivityClientRecord;
HSPLandroid/app/ActivityThread;->getApplication()Landroid/app/Application;
HSPLandroid/app/ActivityThread;->getApplicationThread()Landroid/app/ActivityThread$ApplicationThread;
HSPLandroid/app/ActivityThread;->getBackupAgentName(Landroid/app/ActivityThread$CreateBackupAgentData;)Ljava/lang/String;
@@ -935,7 +936,7 @@ HSPLandroid/app/ActivityThread;->getFloatCoreSetting(Ljava/lang/String;F)F
HSPLandroid/app/ActivityThread;->getGetProviderKey(Ljava/lang/String;I)Landroid/app/ActivityThread$ProviderKey;
HSPLandroid/app/ActivityThread;->getHandler()Landroid/os/Handler;
HSPLandroid/app/ActivityThread;->getInstrumentation()Landroid/app/Instrumentation;
-HSPLandroid/app/ActivityThread;->getIntCoreSetting(Ljava/lang/String;I)I
+HSPLandroid/app/ActivityThread;->getIntCoreSetting(Ljava/lang/String;I)I+]Landroid/os/Bundle;Landroid/os/Bundle;
HSPLandroid/app/ActivityThread;->getIntentBeingBroadcast()Landroid/content/Intent;
HSPLandroid/app/ActivityThread;->getLooper()Landroid/os/Looper;
HSPLandroid/app/ActivityThread;->getOperationTypeFromBackupMode(I)I
@@ -957,7 +958,7 @@ HSPLandroid/app/ActivityThread;->handleBindApplication(Landroid/app/ActivityThre
HSPLandroid/app/ActivityThread;->handleBindService(Landroid/app/ActivityThread$BindServiceData;)V
HSPLandroid/app/ActivityThread;->handleConfigurationChanged(Landroid/content/res/Configuration;I)V
HSPLandroid/app/ActivityThread;->handleCreateBackupAgent(Landroid/app/ActivityThread$CreateBackupAgentData;)V
-HSPLandroid/app/ActivityThread;->handleCreateService(Landroid/app/ActivityThread$CreateServiceData;)V
+HSPLandroid/app/ActivityThread;->handleCreateService(Landroid/app/ActivityThread$CreateServiceData;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Ljava/util/List;Ljava/util/Collections$EmptyList;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;
HSPLandroid/app/ActivityThread;->handleDestroyBackupAgent(Landroid/app/ActivityThread$CreateBackupAgentData;)V
HSPLandroid/app/ActivityThread;->handleDispatchPackageBroadcast(I[Ljava/lang/String;)V
HSPLandroid/app/ActivityThread;->handleDumpGfxInfo(Landroid/app/ActivityThread$DumpComponentInfo;)V
@@ -997,10 +998,11 @@ HSPLandroid/app/ActivityThread;->isProtectedComponent(Landroid/content/pm/Activi
HSPLandroid/app/ActivityThread;->isProtectedComponent(Landroid/content/pm/ComponentInfo;Ljava/lang/String;)Z
HSPLandroid/app/ActivityThread;->isProtectedComponent(Landroid/content/pm/ServiceInfo;)Z
HSPLandroid/app/ActivityThread;->isSystem()Z
+HSPLandroid/app/ActivityThread;->lambda$getGetProviderKey$3(Landroid/app/ActivityThread$ProviderKey;)Landroid/app/ActivityThread$ProviderKey;
HSPLandroid/app/ActivityThread;->main([Ljava/lang/String;)V
HSPLandroid/app/ActivityThread;->onCoreSettingsChange()V
HSPLandroid/app/ActivityThread;->peekPackageInfo(Ljava/lang/String;Z)Landroid/app/LoadedApk;
-HSPLandroid/app/ActivityThread;->performLaunchActivity(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/content/Intent;)Landroid/app/Activity;+]Landroid/app/ActivityThread$ActivityClientRecord;Landroid/app/ActivityThread$ActivityClientRecord;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ConfigurationController;Landroid/app/ConfigurationController;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/Instrumentation;Landroid/app/Instrumentation;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/ComponentName;Landroid/content/ComponentName;]Landroid/content/Intent;Landroid/content/Intent;]Landroid/content/pm/ActivityInfo;Landroid/content/pm/ActivityInfo;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/app/ActivityThread;->performLaunchActivity(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/content/Intent;)Landroid/app/Activity;
HSPLandroid/app/ActivityThread;->performPauseActivity(Landroid/app/ActivityThread$ActivityClientRecord;ZLjava/lang/String;Landroid/app/servertransaction/PendingTransactionActions;)Landroid/os/Bundle;
HSPLandroid/app/ActivityThread;->performPauseActivityIfNeeded(Landroid/app/ActivityThread$ActivityClientRecord;Ljava/lang/String;)V
HSPLandroid/app/ActivityThread;->performRestartActivity(Landroid/app/ActivityThread$ActivityClientRecord;Z)V
@@ -1071,7 +1073,7 @@ HSPLandroid/app/AppComponentFactory;->instantiateProvider(Ljava/lang/ClassLoader
HSPLandroid/app/AppComponentFactory;->instantiateReceiver(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Intent;)Landroid/content/BroadcastReceiver;
HSPLandroid/app/AppComponentFactory;->instantiateService(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Intent;)Landroid/app/Service;
HSPLandroid/app/AppGlobals;->getInitialApplication()Landroid/app/Application;
-HSPLandroid/app/AppGlobals;->getIntCoreSetting(Ljava/lang/String;I)I
+HSPLandroid/app/AppGlobals;->getIntCoreSetting(Ljava/lang/String;I)I+]Landroid/app/ActivityThread;Landroid/app/ActivityThread;
HSPLandroid/app/AppGlobals;->getPackageManager()Landroid/content/pm/IPackageManager;
HSPLandroid/app/AppOpsManager$1;->onNoted(Landroid/app/SyncNotedAppOp;)V
HSPLandroid/app/AppOpsManager$1;->onSelfNoted(Landroid/app/SyncNotedAppOp;)V
@@ -1164,7 +1166,7 @@ HSPLandroid/app/Application$ActivityLifecycleCallbacks;->onActivityPreStarted(La
HSPLandroid/app/Application$ActivityLifecycleCallbacks;->onActivityPreStopped(Landroid/app/Activity;)V
HSPLandroid/app/Application;-><init>()V
HSPLandroid/app/Application;->attach(Landroid/content/Context;)V
-HSPLandroid/app/Application;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/Application;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;
HSPLandroid/app/Application;->dispatchActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
HSPLandroid/app/Application;->dispatchActivityDestroyed(Landroid/app/Activity;)V
HSPLandroid/app/Application;->dispatchActivityPaused(Landroid/app/Activity;)V
@@ -1264,7 +1266,7 @@ HSPLandroid/app/ApplicationPackageManager;->getInstalledPackages(Landroid/conten
HSPLandroid/app/ApplicationPackageManager;->getInstalledPackagesAsUser(II)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->getInstalledPackagesAsUser(Landroid/content/pm/PackageManager$PackageInfoFlags;I)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/app/ApplicationPackageManager;->getLaunchIntentForPackage(Ljava/lang/String;)Landroid/content/Intent;+]Landroid/app/ApplicationPackageManager;Landroid/app/ApplicationPackageManager;]Landroid/content/Intent;Landroid/content/Intent;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/ApplicationPackageManager;->getLaunchIntentForPackage(Ljava/lang/String;)Landroid/content/Intent;+]Ljava/util/List;Ljava/util/ArrayList;]Landroid/app/ApplicationPackageManager;Landroid/app/ApplicationPackageManager;]Landroid/content/Intent;Landroid/content/Intent;
HSPLandroid/app/ApplicationPackageManager;->getModuleInfo(Ljava/lang/String;I)Landroid/content/pm/ModuleInfo;
HSPLandroid/app/ApplicationPackageManager;->getNameForUid(I)Ljava/lang/String;
HSPLandroid/app/ApplicationPackageManager;->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;
@@ -1288,7 +1290,7 @@ HSPLandroid/app/ApplicationPackageManager;->getProviderInfo(Landroid/content/Com
HSPLandroid/app/ApplicationPackageManager;->getReceiverInfo(Landroid/content/ComponentName;I)Landroid/content/pm/ActivityInfo;
HSPLandroid/app/ApplicationPackageManager;->getReceiverInfo(Landroid/content/ComponentName;Landroid/content/pm/PackageManager$ComponentInfoFlags;)Landroid/content/pm/ActivityInfo;
HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;)Landroid/content/res/Resources;
-HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;Landroid/content/res/Configuration;)Landroid/content/res/Resources;
+HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;Landroid/content/res/Configuration;)Landroid/content/res/Resources;+]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Ljava/lang/Object;Ljava/lang/String;
HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Ljava/lang/String;)Landroid/content/res/Resources;
HSPLandroid/app/ApplicationPackageManager;->getServiceInfo(Landroid/content/ComponentName;I)Landroid/content/pm/ServiceInfo;
HSPLandroid/app/ApplicationPackageManager;->getServiceInfo(Landroid/content/ComponentName;Landroid/content/pm/PackageManager$ComponentInfoFlags;)Landroid/content/pm/ServiceInfo;
@@ -1298,7 +1300,7 @@ HSPLandroid/app/ApplicationPackageManager;->getSystemSharedLibraryNames()[Ljava/
HSPLandroid/app/ApplicationPackageManager;->getText(Ljava/lang/String;ILandroid/content/pm/ApplicationInfo;)Ljava/lang/CharSequence;
HSPLandroid/app/ApplicationPackageManager;->getUserBadgeColor(Landroid/os/UserHandle;Z)I
HSPLandroid/app/ApplicationPackageManager;->getUserBadgedIcon(Landroid/graphics/drawable/Drawable;Landroid/os/UserHandle;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/app/ApplicationPackageManager;->getUserId()I
+HSPLandroid/app/ApplicationPackageManager;->getUserId()I+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
HSPLandroid/app/ApplicationPackageManager;->getUserManager()Landroid/os/UserManager;
HSPLandroid/app/ApplicationPackageManager;->getXml(Ljava/lang/String;ILandroid/content/pm/ApplicationInfo;)Landroid/content/res/XmlResourceParser;
HSPLandroid/app/ApplicationPackageManager;->handlePackageBroadcast(I[Ljava/lang/String;Z)V
@@ -1323,7 +1325,7 @@ HSPLandroid/app/ApplicationPackageManager;->queryBroadcastReceiversAsUser(Landro
HSPLandroid/app/ApplicationPackageManager;->queryIntentActivities(Landroid/content/Intent;I)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->queryIntentActivities(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;II)Ljava/util/List;
-HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;I)Ljava/util/List;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/Intent;Landroid/content/Intent;]Landroid/content/pm/IPackageManager;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/content/pm/PackageManager$ResolveInfoFlags;Landroid/content/pm/PackageManager$ResolveInfoFlags;]Landroid/content/pm/ParceledListSlice;Landroid/content/pm/ParceledListSlice;
+HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;I)Ljava/util/List;+]Landroid/content/pm/IPackageManager;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/pm/PackageManager$ResolveInfoFlags;Landroid/content/pm/PackageManager$ResolveInfoFlags;]Landroid/content/pm/ParceledListSlice;Landroid/content/pm/ParceledListSlice;]Landroid/content/Intent;Landroid/content/Intent;
HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProviders(Landroid/content/Intent;I)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProviders(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;)Ljava/util/List;
HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProvidersAsUser(Landroid/content/Intent;II)Ljava/util/List;
@@ -1411,7 +1413,7 @@ HSPLandroid/app/ContextImpl$ApplicationContentResolver;->releaseProvider(Landroi
HSPLandroid/app/ContextImpl$ApplicationContentResolver;->releaseUnstableProvider(Landroid/content/IContentProvider;)Z
HSPLandroid/app/ContextImpl$ApplicationContentResolver;->resolveUserIdFromAuthority(Ljava/lang/String;)I
HSPLandroid/app/ContextImpl$ApplicationContentResolver;->unstableProviderDied(Landroid/content/IContentProvider;)V
-HSPLandroid/app/ContextImpl;-><init>(Landroid/app/ContextImpl;Landroid/app/ActivityThread;Landroid/app/LoadedApk;Landroid/content/ContextParams;Ljava/lang/String;Landroid/content/AttributionSource;Ljava/lang/String;Landroid/os/IBinder;Landroid/os/UserHandle;ILjava/lang/ClassLoader;Ljava/lang/String;IZ)V+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/content/ContextParams;Landroid/content/ContextParams;
+HSPLandroid/app/ContextImpl;-><init>(Landroid/app/ContextImpl;Landroid/app/ActivityThread;Landroid/app/LoadedApk;Landroid/content/ContextParams;Ljava/lang/String;Landroid/content/AttributionSource;Ljava/lang/String;Landroid/os/IBinder;Landroid/os/UserHandle;ILjava/lang/ClassLoader;Ljava/lang/String;IZ)V+]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/ContextParams;Landroid/content/ContextParams;
HSPLandroid/app/ContextImpl;->bindIsolatedService(Landroid/content/Intent;ILjava/lang/String;Ljava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z
HSPLandroid/app/ContextImpl;->bindService(Landroid/content/Intent;Landroid/content/ServiceConnection;I)Z
HSPLandroid/app/ContextImpl;->bindServiceAsUser(Landroid/content/Intent;Landroid/content/ServiceConnection;ILandroid/os/Handler;Landroid/os/UserHandle;)Z
@@ -1431,7 +1433,7 @@ HSPLandroid/app/ContextImpl;->createAppContext(Landroid/app/ActivityThread;Landr
HSPLandroid/app/ContextImpl;->createAppContext(Landroid/app/ActivityThread;Landroid/app/LoadedApk;Ljava/lang/String;)Landroid/app/ContextImpl;
HSPLandroid/app/ContextImpl;->createApplicationContext(Landroid/content/pm/ApplicationInfo;I)Landroid/content/Context;
HSPLandroid/app/ContextImpl;->createAttributionContext(Ljava/lang/String;)Landroid/content/Context;
-HSPLandroid/app/ContextImpl;->createAttributionSource(Ljava/lang/String;Landroid/content/AttributionSource;Ljava/util/Set;ZI)Landroid/content/AttributionSource;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/permission/PermissionManager;Landroid/permission/PermissionManager;]Ljava/util/Set;missing_types
+HSPLandroid/app/ContextImpl;->createAttributionSource(Ljava/lang/String;Landroid/content/AttributionSource;Ljava/util/Set;ZI)Landroid/content/AttributionSource;+]Ljava/util/Set;missing_types]Landroid/permission/PermissionManager;Landroid/permission/PermissionManager;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
HSPLandroid/app/ContextImpl;->createConfigurationContext(Landroid/content/res/Configuration;)Landroid/content/Context;
HSPLandroid/app/ContextImpl;->createContext(Landroid/content/ContextParams;)Landroid/content/Context;
HSPLandroid/app/ContextImpl;->createContextAsUser(Landroid/os/UserHandle;I)Landroid/content/Context;
@@ -1510,11 +1512,11 @@ HSPLandroid/app/ContextImpl;->getPackageResourcePath()Ljava/lang/String;
HSPLandroid/app/ContextImpl;->getPreferencesDir()Ljava/io/File;
HSPLandroid/app/ContextImpl;->getReceiverRestrictedContext()Landroid/content/Context;
HSPLandroid/app/ContextImpl;->getResources()Landroid/content/res/Resources;
-HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/io/File;I)Landroid/content/SharedPreferences;
-HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
-HSPLandroid/app/ContextImpl;->getSharedPreferencesCacheLocked()Landroid/util/ArrayMap;
+HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/io/File;I)Landroid/content/SharedPreferences;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
+HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
+HSPLandroid/app/ContextImpl;->getSharedPreferencesCacheLocked()Landroid/util/ArrayMap;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
HSPLandroid/app/ContextImpl;->getSharedPreferencesPath(Ljava/lang/String;)Ljava/io/File;
-HSPLandroid/app/ContextImpl;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/app/ContextImpl;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
HSPLandroid/app/ContextImpl;->getSystemServiceName(Ljava/lang/Class;)Ljava/lang/String;
HSPLandroid/app/ContextImpl;->getTheme()Landroid/content/res/Resources$Theme;
HSPLandroid/app/ContextImpl;->getThemeResId()I
@@ -1733,13 +1735,13 @@ HSPLandroid/app/FragmentManagerImpl;->addAddedFragments(Landroid/util/ArraySet;)
HSPLandroid/app/FragmentManagerImpl;->addFragment(Landroid/app/Fragment;Z)V
HSPLandroid/app/FragmentManagerImpl;->attachController(Landroid/app/FragmentHostCallback;Landroid/app/FragmentContainer;Landroid/app/Fragment;)V
HSPLandroid/app/FragmentManagerImpl;->beginTransaction()Landroid/app/FragmentTransaction;
-HSPLandroid/app/FragmentManagerImpl;->burpActive()V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/app/FragmentManagerImpl;->burpActive()V
HSPLandroid/app/FragmentManagerImpl;->checkStateLoss()V
HSPLandroid/app/FragmentManagerImpl;->cleanupExec()V
HSPLandroid/app/FragmentManagerImpl;->dispatchActivityCreated()V
HSPLandroid/app/FragmentManagerImpl;->dispatchCreate()V
HSPLandroid/app/FragmentManagerImpl;->dispatchCreateOptionsMenu(Landroid/view/Menu;Landroid/view/MenuInflater;)Z
-HSPLandroid/app/FragmentManagerImpl;->dispatchMoveToState(I)V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;
+HSPLandroid/app/FragmentManagerImpl;->dispatchMoveToState(I)V
HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentActivityCreated(Landroid/app/Fragment;Landroid/os/Bundle;Z)V
HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentAttached(Landroid/app/Fragment;Landroid/content/Context;Z)V
HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentCreated(Landroid/app/Fragment;Landroid/os/Bundle;Z)V
@@ -1762,9 +1764,9 @@ HSPLandroid/app/FragmentManagerImpl;->dispatchStop()V
HSPLandroid/app/FragmentManagerImpl;->doPendingDeferredStart()V
HSPLandroid/app/FragmentManagerImpl;->endAnimatingAwayFragments()V
HSPLandroid/app/FragmentManagerImpl;->enqueueAction(Landroid/app/FragmentManagerImpl$OpGenerator;Z)V
-HSPLandroid/app/FragmentManagerImpl;->ensureExecReady(Z)V+]Landroid/app/FragmentHostCallback;Landroid/app/Activity$HostCallbacks;]Landroid/os/Handler;Landroid/os/Handler;
+HSPLandroid/app/FragmentManagerImpl;->ensureExecReady(Z)V
HSPLandroid/app/FragmentManagerImpl;->ensureInflatedFragmentView(Landroid/app/Fragment;)V
-HSPLandroid/app/FragmentManagerImpl;->execPendingActions()Z+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;
+HSPLandroid/app/FragmentManagerImpl;->execPendingActions()Z
HSPLandroid/app/FragmentManagerImpl;->executeOps(Ljava/util/ArrayList;Ljava/util/ArrayList;II)V
HSPLandroid/app/FragmentManagerImpl;->executeOpsTogether(Ljava/util/ArrayList;Ljava/util/ArrayList;II)V
HSPLandroid/app/FragmentManagerImpl;->executePendingTransactions()Z
@@ -1782,9 +1784,9 @@ HSPLandroid/app/FragmentManagerImpl;->makeActive(Landroid/app/Fragment;)V
HSPLandroid/app/FragmentManagerImpl;->makeInactive(Landroid/app/Fragment;)V
HSPLandroid/app/FragmentManagerImpl;->makeRemovedFragmentsInvisible(Landroid/util/ArraySet;)V
HSPLandroid/app/FragmentManagerImpl;->moveFragmentToExpectedState(Landroid/app/Fragment;)V
-HSPLandroid/app/FragmentManagerImpl;->moveToState(IZ)V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/FragmentManagerImpl;->moveToState(IZ)V
HSPLandroid/app/FragmentManagerImpl;->moveToState(Landroid/app/Fragment;IIIZ)V
-HSPLandroid/app/FragmentManagerImpl;->noteStateNotSaved()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/FragmentManagerImpl;->noteStateNotSaved()V
HSPLandroid/app/FragmentManagerImpl;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/app/FragmentManagerImpl;->performPendingDeferredStart(Landroid/app/Fragment;)V
HSPLandroid/app/FragmentManagerImpl;->popBackStackImmediate()Z
@@ -1798,7 +1800,7 @@ HSPLandroid/app/FragmentManagerImpl;->saveFragmentBasicState(Landroid/app/Fragme
HSPLandroid/app/FragmentManagerImpl;->saveNonConfig()V
HSPLandroid/app/FragmentManagerImpl;->scheduleCommit()V
HSPLandroid/app/FragmentManagerImpl;->setRetaining(Landroid/app/FragmentManagerNonConfig;)V
-HSPLandroid/app/FragmentManagerImpl;->startPendingDeferredFragments()V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/app/FragmentManagerImpl;->startPendingDeferredFragments()V
HSPLandroid/app/FragmentManagerState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/FragmentManagerState;
HSPLandroid/app/FragmentManagerState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/app/FragmentManagerState;-><init>(Landroid/os/Parcel;)V
@@ -1841,11 +1843,12 @@ HSPLandroid/app/IActivityManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/app/IActivityManager$Stub$Proxy;->attachApplication(Landroid/app/IApplicationThread;J)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->backupAgentCreated(Ljava/lang/String;Landroid/os/IBinder;I)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->bindServiceInstance(Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/content/Intent;Ljava/lang/String;Landroid/app/IServiceConnection;JLjava/lang/String;Ljava/lang/String;I)I
-HSPLandroid/app/IActivityManager$Stub$Proxy;->broadcastIntentWithFeature(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->broadcastIntentWithFeature(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I
HSPLandroid/app/IActivityManager$Stub$Proxy;->cancelIntentSender(Landroid/content/IIntentSender;)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermission(Ljava/lang/String;II)I
-HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermissionForDevice(Ljava/lang/String;III)I+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermissionForDevice(Ljava/lang/String;III)I+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/IActivityManager$Stub$Proxy;->checkUriPermission(Landroid/net/Uri;IIIILandroid/os/IBinder;)I
+HSPLandroid/app/IActivityManager$Stub$Proxy;->finishAttachApplication(J)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->finishReceiver(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/Bundle;ZI)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->getContentProvider(Landroid/app/IApplicationThread;Ljava/lang/String;Ljava/lang/String;IZ)Landroid/app/ContentProviderHolder;
HSPLandroid/app/IActivityManager$Stub$Proxy;->getCurrentUser()Landroid/content/pm/UserInfo;
@@ -1872,7 +1875,7 @@ HSPLandroid/app/IActivityManager$Stub$Proxy;->registerStrictModeCallback(Landroi
HSPLandroid/app/IActivityManager$Stub$Proxy;->registerUidObserver(Landroid/app/IUidObserver;IILjava/lang/String;)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->removeContentProvider(Landroid/os/IBinder;Z)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->revokeUriPermission(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/net/Uri;II)V
-HSPLandroid/app/IActivityManager$Stub$Proxy;->serviceDoneExecuting(Landroid/os/IBinder;IIILandroid/content/Intent;)V+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->serviceDoneExecuting(Landroid/os/IBinder;IIILandroid/content/Intent;)V+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/IActivityManager$Stub$Proxy;->setRenderThread(I)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->setServiceForeground(Landroid/content/ComponentName;Landroid/os/IBinder;ILandroid/app/Notification;II)V
HSPLandroid/app/IActivityManager$Stub$Proxy;->startService(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;I)Landroid/content/ComponentName;
@@ -1931,7 +1934,7 @@ HSPLandroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
HSPLandroid/app/INotificationManager$Stub$Proxy;->areNotificationsEnabled(Ljava/lang/String;)Z
HSPLandroid/app/INotificationManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelAllNotifications(Ljava/lang/String;I)V
-HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V+]Landroid/app/INotificationManager$Stub$Proxy;Landroid/app/INotificationManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V
HSPLandroid/app/INotificationManager$Stub$Proxy;->createNotificationChannelGroups(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
HSPLandroid/app/INotificationManager$Stub$Proxy;->createNotificationChannels(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
HSPLandroid/app/INotificationManager$Stub$Proxy;->deleteNotificationChannel(Ljava/lang/String;Ljava/lang/String;)V
@@ -2035,7 +2038,7 @@ HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0;-><i
HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0;->run()V
HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;-><init>(Landroid/app/LoadedApk$ReceiverDispatcher;Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZZIILjava/lang/String;)V
HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->getRunnable()Ljava/lang/Runnable;
-HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->lambda$getRunnable$0()V+]Landroid/app/LoadedApk$ReceiverDispatcher$Args;Landroid/app/LoadedApk$ReceiverDispatcher$Args;]Landroid/content/Intent;Landroid/content/Intent;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->lambda$getRunnable$0()V
HSPLandroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZI)V
HSPLandroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZZIILjava/lang/String;)V
HSPLandroid/app/LoadedApk$ReceiverDispatcher;-><init>(Landroid/app/IApplicationThread;Landroid/content/BroadcastReceiver;Landroid/content/Context;Landroid/os/Handler;Landroid/app/Instrumentation;Z)V
@@ -2263,7 +2266,7 @@ HSPLandroid/app/Notification$Style;->restoreFromExtras(Landroid/os/Bundle;)V
HSPLandroid/app/Notification$Style;->setBuilder(Landroid/app/Notification$Builder;)V
HSPLandroid/app/Notification$Style;->validate(Landroid/content/Context;)V
HSPLandroid/app/Notification;-><init>()V
-HSPLandroid/app/Notification;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/Notification;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/Notification;->addFieldsFromContext(Landroid/content/Context;Landroid/app/Notification;)V
HSPLandroid/app/Notification;->addFieldsFromContext(Landroid/content/pm/ApplicationInfo;Landroid/app/Notification;)V
HSPLandroid/app/Notification;->areStyledNotificationsVisiblyDifferent(Landroid/app/Notification$Builder;Landroid/app/Notification$Builder;)Z
@@ -2288,7 +2291,7 @@ HSPLandroid/app/Notification;->isForegroundService()Z
HSPLandroid/app/Notification;->isGroupChild()Z
HSPLandroid/app/Notification;->isGroupSummary()Z
HSPLandroid/app/Notification;->isMediaNotification()Z
-HSPLandroid/app/Notification;->readFromParcelImpl(Landroid/os/Parcel;)V
+HSPLandroid/app/Notification;->readFromParcelImpl(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/graphics/drawable/Icon$1;,Landroid/app/PendingIntent$1;,Landroid/media/AudioAttributes$1;]Landroid/graphics/drawable/Icon;Landroid/graphics/drawable/Icon;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/Notification;->reduceImageSizes(Landroid/content/Context;)V
HSPLandroid/app/Notification;->reduceImageSizesForRemoteView(Landroid/widget/RemoteViews;Landroid/content/Context;Z)V
HSPLandroid/app/Notification;->removeTextSizeSpans(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
@@ -2298,10 +2301,10 @@ HSPLandroid/app/Notification;->suppressAlertingDueToGrouping()Z
HSPLandroid/app/Notification;->toString()Ljava/lang/String;
HSPLandroid/app/Notification;->visibilityToString(I)Ljava/lang/String;
HSPLandroid/app/Notification;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/app/Notification;->writeToParcelImpl(Landroid/os/Parcel;I)V
+HSPLandroid/app/Notification;->writeToParcelImpl(Landroid/os/Parcel;I)V+]Landroid/app/PendingIntent;Landroid/app/PendingIntent;]Landroid/media/AudioAttributes;Landroid/media/AudioAttributes;]Landroid/graphics/drawable/Icon;Landroid/graphics/drawable/Icon;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/NotificationChannel;
-HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/app/NotificationChannel;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/app/NotificationChannel$1;Landroid/app/NotificationChannel$1;
+HSPLandroid/app/NotificationChannel;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/net/Uri$1;,Landroid/media/AudioAttributes$1;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
HSPLandroid/app/NotificationChannel;-><init>(Ljava/lang/String;Ljava/lang/CharSequence;I)V
HSPLandroid/app/NotificationChannel;->canBubble()Z
HSPLandroid/app/NotificationChannel;->canBypassDnd()Z
@@ -2320,7 +2323,7 @@ HSPLandroid/app/NotificationChannel;->getLockscreenVisibility()I
HSPLandroid/app/NotificationChannel;->getName()Ljava/lang/CharSequence;
HSPLandroid/app/NotificationChannel;->getOriginalImportance()I
HSPLandroid/app/NotificationChannel;->getSound()Landroid/net/Uri;
-HSPLandroid/app/NotificationChannel;->getTrimmedString(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/app/NotificationChannel;->getTrimmedString(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/app/NotificationChannel;->getUserLockedFields()I
HSPLandroid/app/NotificationChannel;->getVibrationPattern()[J
HSPLandroid/app/NotificationChannel;->hasUserSetImportance()Z
@@ -2363,7 +2366,7 @@ HSPLandroid/app/NotificationManager;->areNotificationsEnabled()Z
HSPLandroid/app/NotificationManager;->cancel(I)V
HSPLandroid/app/NotificationManager;->cancel(Ljava/lang/String;I)V
HSPLandroid/app/NotificationManager;->cancelAll()V
-HSPLandroid/app/NotificationManager;->cancelAsUser(Ljava/lang/String;ILandroid/os/UserHandle;)V+]Landroid/app/INotificationManager;Landroid/app/INotificationManager$Stub$Proxy;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;]Landroid/os/UserHandle;Landroid/os/UserHandle;
+HSPLandroid/app/NotificationManager;->cancelAsUser(Ljava/lang/String;ILandroid/os/UserHandle;)V
HSPLandroid/app/NotificationManager;->createNotificationChannel(Landroid/app/NotificationChannel;)V
HSPLandroid/app/NotificationManager;->createNotificationChannelGroup(Landroid/app/NotificationChannelGroup;)V
HSPLandroid/app/NotificationManager;->createNotificationChannelGroups(Ljava/util/List;)V
@@ -2386,6 +2389,7 @@ HSPLandroid/app/NotificationManager;->notify(ILandroid/app/Notification;)V
HSPLandroid/app/NotificationManager;->notify(Ljava/lang/String;ILandroid/app/Notification;)V
HSPLandroid/app/NotificationManager;->notifyAsUser(Ljava/lang/String;ILandroid/app/Notification;Landroid/os/UserHandle;)V
HSPLandroid/app/NotificationManager;->zenModeToInterruptionFilter(I)I
+HSPLandroid/app/PendingIntent$$ExternalSyntheticLambda3;->get()Ljava/lang/Object;
HSPLandroid/app/PendingIntent$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/PendingIntent;
HSPLandroid/app/PendingIntent$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/app/PendingIntent$FinishedDispatcher;-><init>(Landroid/app/PendingIntent;Landroid/app/PendingIntent$OnFinished;Landroid/os/Handler;)V
@@ -2443,7 +2447,7 @@ HSPLandroid/app/PictureInPictureParams$1;->createFromParcel(Landroid/os/Parcel;)
HSPLandroid/app/PictureInPictureParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/app/PictureInPictureParams;-><init>(Landroid/os/Parcel;)V
HSPLandroid/app/PropertyInvalidatedCache$1;-><init>(Landroid/app/PropertyInvalidatedCache;IFZ)V
-HSPLandroid/app/PropertyInvalidatedCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z+]Landroid/app/PropertyInvalidatedCache$1;Landroid/app/PropertyInvalidatedCache$1;
+HSPLandroid/app/PropertyInvalidatedCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z
HSPLandroid/app/PropertyInvalidatedCache$DefaultComputer;-><init>(Landroid/app/PropertyInvalidatedCache;)V
HSPLandroid/app/PropertyInvalidatedCache$NoPreloadHolder;-><clinit>()V
HSPLandroid/app/PropertyInvalidatedCache$NoPreloadHolder;->next()J
@@ -2470,7 +2474,7 @@ HSPLandroid/app/PropertyInvalidatedCache;->invalidateCacheLocked(Ljava/lang/Stri
HSPLandroid/app/PropertyInvalidatedCache;->isDisabled()Z
HSPLandroid/app/PropertyInvalidatedCache;->isReservedNonce(J)Z
HSPLandroid/app/PropertyInvalidatedCache;->maybeCheckConsistency(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/app/PropertyInvalidatedCache;->query(Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/app/PropertyInvalidatedCache;megamorphic_types]Ljava/util/LinkedHashMap;Landroid/app/PropertyInvalidatedCache$1;
+HSPLandroid/app/PropertyInvalidatedCache;->query(Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Landroid/app/PropertyInvalidatedCache$1;]Landroid/app/PropertyInvalidatedCache;megamorphic_types
HSPLandroid/app/PropertyInvalidatedCache;->recompute(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/app/PropertyInvalidatedCache;->refresh(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/app/PropertyInvalidatedCache;->registerCache()V
@@ -2539,7 +2543,7 @@ HSPLandroid/app/ResourcesManager;->createResources(Landroid/content/res/Resource
HSPLandroid/app/ResourcesManager;->createResourcesForActivity(Landroid/os/IBinder;Landroid/content/res/ResourcesKey;Landroid/content/res/Configuration;Ljava/lang/Integer;Ljava/lang/ClassLoader;Landroid/app/ResourcesManager$ApkAssetsSupplier;)Landroid/content/res/Resources;
HSPLandroid/app/ResourcesManager;->createResourcesForActivityLocked(Landroid/os/IBinder;Landroid/content/res/Configuration;Ljava/lang/Integer;Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;
HSPLandroid/app/ResourcesManager;->createResourcesImpl(Landroid/content/res/ResourcesKey;Landroid/app/ResourcesManager$ApkAssetsSupplier;)Landroid/content/res/ResourcesImpl;
-HSPLandroid/app/ResourcesManager;->createResourcesLocked(Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;
+HSPLandroid/app/ResourcesManager;->createResourcesLocked(Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/app/ResourcesManager;->extractApkKeys(Landroid/content/res/ResourcesKey;)Ljava/util/ArrayList;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/app/ResourcesManager;->findKeyForResourceImplLocked(Landroid/content/res/ResourcesImpl;)Landroid/content/res/ResourcesKey;
HSPLandroid/app/ResourcesManager;->findOrCreateResourcesImplForKeyLocked(Landroid/content/res/ResourcesKey;)Landroid/content/res/ResourcesImpl;
@@ -2561,7 +2565,7 @@ HSPLandroid/app/ResourcesManager;->initializeApplicationPaths(Ljava/lang/String;
HSPLandroid/app/ResourcesManager;->isSameResourcesOverrideConfig(Landroid/os/IBinder;Landroid/content/res/Configuration;)Z
HSPLandroid/app/ResourcesManager;->lambda$cleanupReferences$1(Ljava/util/function/Function;Ljava/util/HashSet;Ljava/lang/Object;)Z
HSPLandroid/app/ResourcesManager;->lambda$createResourcesForActivityLocked$0(Landroid/app/ResourcesManager$ActivityResource;)Ljava/lang/ref/WeakReference;
-HSPLandroid/app/ResourcesManager;->loadApkAssets(Landroid/app/ResourcesManager$ApkKey;)Landroid/content/res/ApkAssets;+]Landroid/content/res/ApkAssets;Landroid/content/res/ApkAssets;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/app/ResourcesManager;->loadApkAssets(Landroid/app/ResourcesManager$ApkKey;)Landroid/content/res/ApkAssets;
HSPLandroid/app/ResourcesManager;->overlayPathToIdmapPath(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/app/ResourcesManager;->rebaseActivityOverrideConfig(Landroid/app/ResourcesManager$ActivityResource;Landroid/content/res/Configuration;I)Landroid/content/res/ResourcesKey;
HSPLandroid/app/ResourcesManager;->rebaseKeyForActivity(Landroid/os/IBinder;Landroid/content/res/ResourcesKey;Z)V
@@ -2613,7 +2617,7 @@ HSPLandroid/app/SharedPreferencesImpl$EditorImpl;-><init>(Landroid/app/SharedPre
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->apply()V
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->clear()Landroid/content/SharedPreferences$Editor;
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commit()Z
-HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commitToMemory()Landroid/app/SharedPreferencesImpl$MemoryCommitResult;
+HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commitToMemory()Landroid/app/SharedPreferencesImpl$MemoryCommitResult;+]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/lang/Object;Ljava/lang/String;,Ljava/lang/Boolean;,Ljava/lang/Long;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/Map;Ljava/util/HashMap;]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->notifyListeners(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;)V
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->putBoolean(Ljava/lang/String;Z)Landroid/content/SharedPreferences$Editor;
HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->putFloat(Ljava/lang/String;F)Landroid/content/SharedPreferences$Editor;
@@ -2658,7 +2662,7 @@ HSPLandroid/app/SharedPreferencesImpl;->registerOnSharedPreferenceChangeListener
HSPLandroid/app/SharedPreferencesImpl;->startLoadFromDisk()V
HSPLandroid/app/SharedPreferencesImpl;->startReloadIfChangedUnexpectedly()V
HSPLandroid/app/SharedPreferencesImpl;->unregisterOnSharedPreferenceChangeListener(Landroid/content/SharedPreferences$OnSharedPreferenceChangeListener;)V
-HSPLandroid/app/SharedPreferencesImpl;->writeToFile(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Z)V
+HSPLandroid/app/SharedPreferencesImpl;->writeToFile(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Z)V+]Ljava/io/File;Ljava/io/File;]Lcom/android/internal/util/ExponentiallyBucketedHistogram;Lcom/android/internal/util/ExponentiallyBucketedHistogram;]Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Landroid/app/SharedPreferencesImpl$MemoryCommitResult;]Ljava/io/FileOutputStream;Ljava/io/FileOutputStream;
HSPLandroid/app/StackTrace;-><init>(Ljava/lang/String;)V
HSPLandroid/app/StatusBarManager;-><init>(Landroid/content/Context;)V
HSPLandroid/app/SyncNotedAppOp$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/SyncNotedAppOp;
@@ -2743,9 +2747,11 @@ HSPLandroid/app/SystemServiceRegistry$3;->createService(Landroid/app/ContextImpl
HSPLandroid/app/SystemServiceRegistry$3;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$40;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$41;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$42;->createService(Landroid/app/ContextImpl;)Landroid/hardware/SensorManager;
HSPLandroid/app/SystemServiceRegistry$42;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$43;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$44;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$45;->createService(Landroid/app/ContextImpl;)Landroid/os/storage/StorageManager;
HSPLandroid/app/SystemServiceRegistry$45;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$46;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$47;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2764,6 +2770,7 @@ HSPLandroid/app/SystemServiceRegistry$56;->createService(Landroid/app/ContextImp
HSPLandroid/app/SystemServiceRegistry$57;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$58;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$59;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$60;->createService(Landroid/app/ContextImpl;)Landroid/view/WindowManager;
HSPLandroid/app/SystemServiceRegistry$60;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$61;->createService(Landroid/app/ContextImpl;)Landroid/os/UserManager;
HSPLandroid/app/SystemServiceRegistry$61;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2774,6 +2781,7 @@ HSPLandroid/app/SystemServiceRegistry$64;->createService(Landroid/app/ContextImp
HSPLandroid/app/SystemServiceRegistry$65;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$66;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$67;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$68;->createService(Landroid/app/ContextImpl;)Landroid/companion/virtual/VirtualDeviceManager;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLandroid/app/SystemServiceRegistry$68;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$71;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$74;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2802,7 +2810,7 @@ HSPLandroid/app/SystemServiceRegistry$97;->createService(Landroid/app/ContextImp
HSPLandroid/app/SystemServiceRegistry$98;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$99;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$9;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
-HSPLandroid/app/SystemServiceRegistry$CachedServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$CachedServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;+]Landroid/app/SystemServiceRegistry$CachedServiceFetcher;megamorphic_types]Ljava/lang/Object;[Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry$StaticServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry;->createServiceCache()[Ljava/lang/Object;
HSPLandroid/app/SystemServiceRegistry;->getSystemService(Landroid/app/ContextImpl;Ljava/lang/String;)Ljava/lang/Object;+]Landroid/app/SystemServiceRegistry$ServiceFetcher;megamorphic_types
@@ -2857,6 +2865,7 @@ HSPLandroid/app/WindowConfiguration$1;->createFromParcel(Landroid/os/Parcel;)Lja
HSPLandroid/app/WindowConfiguration;-><init>()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/app/WindowConfiguration;-><init>(Landroid/os/Parcel;)V
HSPLandroid/app/WindowConfiguration;->activityTypeToString(I)Ljava/lang/String;
+HSPLandroid/app/WindowConfiguration;->areConfigurationsEqualForDisplay(Landroid/content/res/Configuration;Landroid/content/res/Configuration;)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/app/WindowConfiguration;->canReceiveKeys()Z
HSPLandroid/app/WindowConfiguration;->compareTo(Landroid/app/WindowConfiguration;)I
HSPLandroid/app/WindowConfiguration;->diff(Landroid/app/WindowConfiguration;Z)J+]Landroid/graphics/Rect;Landroid/graphics/Rect;
@@ -2868,17 +2877,19 @@ HSPLandroid/app/WindowConfiguration;->getDisplayRotation()I
HSPLandroid/app/WindowConfiguration;->getMaxBounds()Landroid/graphics/Rect;
HSPLandroid/app/WindowConfiguration;->getRotation()I
HSPLandroid/app/WindowConfiguration;->getWindowingMode()I
+HSPLandroid/app/WindowConfiguration;->hasWindowDecorCaption()Z
HSPLandroid/app/WindowConfiguration;->hasWindowShadow()Z
HSPLandroid/app/WindowConfiguration;->inMultiWindowMode(I)Z
HSPLandroid/app/WindowConfiguration;->isFloating(I)Z
-HSPLandroid/app/WindowConfiguration;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/WindowConfiguration;->readFromParcel(Landroid/os/Parcel;)V
HSPLandroid/app/WindowConfiguration;->setActivityType(I)V
HSPLandroid/app/WindowConfiguration;->setAlwaysOnTop(I)V
-HSPLandroid/app/WindowConfiguration;->setAppBounds(IIII)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/app/WindowConfiguration;->setAppBounds(Landroid/graphics/Rect;)V
-HSPLandroid/app/WindowConfiguration;->setBounds(Landroid/graphics/Rect;)V
+HSPLandroid/app/WindowConfiguration;->setAppBounds(IIII)V
+HSPLandroid/app/WindowConfiguration;->setAppBounds(Landroid/graphics/Rect;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLandroid/app/WindowConfiguration;->setBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/app/WindowConfiguration;->setDisplayRotation(I)V
-HSPLandroid/app/WindowConfiguration;->setMaxBounds(Landroid/graphics/Rect;)V
+HSPLandroid/app/WindowConfiguration;->setDisplayWindowingMode(I)V
+HSPLandroid/app/WindowConfiguration;->setMaxBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/app/WindowConfiguration;->setRotation(I)V
HSPLandroid/app/WindowConfiguration;->setTo(Landroid/app/WindowConfiguration;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/app/WindowConfiguration;->setTo(Landroid/app/WindowConfiguration;I)V
@@ -2887,7 +2898,7 @@ HSPLandroid/app/WindowConfiguration;->setWindowingMode(I)V
HSPLandroid/app/WindowConfiguration;->tasksAreFloating()Z
HSPLandroid/app/WindowConfiguration;->toString()Ljava/lang/String;
HSPLandroid/app/WindowConfiguration;->unset()V
-HSPLandroid/app/WindowConfiguration;->updateFrom(Landroid/app/WindowConfiguration;)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/app/WindowConfiguration;->updateFrom(Landroid/app/WindowConfiguration;)I+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/app/WindowConfiguration;->windowingModeToString(I)Ljava/lang/String;
HSPLandroid/app/WindowConfiguration;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/app/admin/DevicePolicyManager$$ExternalSyntheticLambda5;-><init>(Landroid/app/admin/DevicePolicyManager;)V
@@ -3153,10 +3164,10 @@ HSPLandroid/app/job/JobInfo$TriggerContentUri$1;->newArray(I)[Landroid/app/job/J
HSPLandroid/app/job/JobInfo$TriggerContentUri$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/app/job/JobInfo$TriggerContentUri;-><init>(Landroid/net/Uri;I)V
HSPLandroid/app/job/JobInfo$TriggerContentUri;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;)V
+HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;)V+]Landroid/os/PersistableBundle;Landroid/os/PersistableBundle;]Landroid/os/Bundle;Landroid/os/Bundle;
HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;Landroid/app/job/JobInfo-IA;)V
-HSPLandroid/app/job/JobInfo;-><init>(Landroid/os/Parcel;)V
-HSPLandroid/app/job/JobInfo;->enforceValidity(ZZZZ)V+]Landroid/content/ComponentName;Landroid/content/ComponentName;]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/app/job/JobInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/net/NetworkRequest$1;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/job/JobInfo;->enforceValidity(ZZZZ)V+]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/content/ComponentName;Landroid/content/ComponentName;
HSPLandroid/app/job/JobInfo;->getExtras()Landroid/os/PersistableBundle;
HSPLandroid/app/job/JobInfo;->getFlags()I
HSPLandroid/app/job/JobInfo;->getFlexMillis()J
@@ -3175,7 +3186,7 @@ HSPLandroid/app/job/JobInfo;->isPersisted()Z
HSPLandroid/app/job/JobInfo;->isRequireCharging()Z
HSPLandroid/app/job/JobInfo;->isRequireDeviceIdle()Z
HSPLandroid/app/job/JobInfo;->validateTraceTag(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/app/job/JobInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/app/job/JobInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/app/job/JobParameters$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/job/JobParameters;
HSPLandroid/app/job/JobParameters$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/app/job/JobParameters;-><init>(Landroid/os/Parcel;)V
@@ -3263,13 +3274,14 @@ HSPLandroid/app/servertransaction/ActivityResultItem;->getPostExecutionState()I
HSPLandroid/app/servertransaction/ActivityTransactionItem;-><init>()V
HSPLandroid/app/servertransaction/ClientTransaction$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/servertransaction/ClientTransaction;
HSPLandroid/app/servertransaction/ClientTransaction$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;)V+]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/app/servertransaction/ClientTransaction;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;)V
HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;Landroid/app/servertransaction/ClientTransaction-IA;)V
HSPLandroid/app/servertransaction/ClientTransaction;->getCallbacks()Ljava/util/List;
HSPLandroid/app/servertransaction/ClientTransaction;->getLifecycleStateRequest()Landroid/app/servertransaction/ActivityLifecycleItem;
-HSPLandroid/app/servertransaction/ClientTransaction;->preExecute(Landroid/app/ClientTransactionHandler;)V+]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/servertransaction/ClientTransaction;->preExecute(Landroid/app/ClientTransactionHandler;)V
HSPLandroid/app/servertransaction/ClientTransactionItem;-><init>()V
HSPLandroid/app/servertransaction/ClientTransactionItem;->getPostExecutionState()I
+HSPLandroid/app/servertransaction/ClientTransactionItem;->isActivityLifecycleItem()Z
HSPLandroid/app/servertransaction/ClientTransactionItem;->shouldHaveDefinedPreExecutionState()Z
HSPLandroid/app/servertransaction/ConfigurationChangeItem$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/servertransaction/ConfigurationChangeItem;
HSPLandroid/app/servertransaction/ConfigurationChangeItem$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -3330,11 +3342,13 @@ HSPLandroid/app/servertransaction/TransactionExecutor;->cycleToPath(Landroid/app
HSPLandroid/app/servertransaction/TransactionExecutor;->execute(Landroid/app/servertransaction/ClientTransaction;)V
HSPLandroid/app/servertransaction/TransactionExecutor;->executeCallbacks(Landroid/app/servertransaction/ClientTransaction;)V
HSPLandroid/app/servertransaction/TransactionExecutor;->executeLifecycleState(Landroid/app/servertransaction/ClientTransaction;)V
-HSPLandroid/app/servertransaction/TransactionExecutor;->performLifecycleSequence(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/util/IntArray;Landroid/app/servertransaction/ClientTransaction;)V+]Landroid/app/ClientTransactionHandler;Landroid/app/ActivityThread;]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/app/servertransaction/TransactionExecutor;->executeNonLifecycleItem(Landroid/app/servertransaction/ClientTransaction;Landroid/app/servertransaction/ClientTransactionItem;Z)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/servertransaction/TransactionExecutorHelper;Landroid/app/servertransaction/TransactionExecutorHelper;]Landroid/app/ClientTransactionHandler;Landroid/app/ActivityThread;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Landroid/content/Context;missing_types]Ljava/util/Map;Ljava/util/Collections$SynchronizedMap;]Landroid/app/servertransaction/TransactionExecutor;Landroid/app/servertransaction/TransactionExecutor;
+HSPLandroid/app/servertransaction/TransactionExecutor;->executeTransactionItems(Landroid/app/servertransaction/ClientTransaction;)V+]Landroid/app/servertransaction/ClientTransaction;Landroid/app/servertransaction/ClientTransaction;]Ljava/util/List;Ljava/util/ArrayList;]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types
+HSPLandroid/app/servertransaction/TransactionExecutor;->performLifecycleSequence(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/util/IntArray;Landroid/app/servertransaction/ClientTransaction;)V
HSPLandroid/app/servertransaction/TransactionExecutorHelper;-><init>()V
HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getClosestOfStates(Landroid/app/ActivityThread$ActivityClientRecord;[I)I
HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getClosestPreExecutionState(Landroid/app/ActivityThread$ActivityClientRecord;I)I
-HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getLifecyclePath(IIZ)Landroid/util/IntArray;+]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getLifecyclePath(IIZ)Landroid/util/IntArray;
HSPLandroid/app/servertransaction/TransactionExecutorHelper;->lastCallbackRequestingState(Landroid/app/servertransaction/ClientTransaction;)I
HSPLandroid/app/slice/ISliceManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
HSPLandroid/app/slice/ISliceManager$Stub$Proxy;->getPinnedSlices(Ljava/lang/String;)[Landroid/net/Uri;
@@ -3426,10 +3440,10 @@ HSPLandroid/app/usage/UsageEvents$Event;->getTimeStamp()J
HSPLandroid/app/usage/UsageEvents;-><init>(Landroid/os/Parcel;)V
HSPLandroid/app/usage/UsageEvents;->getNextEvent(Landroid/app/usage/UsageEvents$Event;)Z
HSPLandroid/app/usage/UsageEvents;->hasNextEvent()Z
-HSPLandroid/app/usage/UsageEvents;->readEventFromParcel(Landroid/os/Parcel;Landroid/app/usage/UsageEvents$Event;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/content/res/Configuration$1;
-HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/usage/UsageStats;+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
-HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/app/usage/UsageStats$1;Landroid/app/usage/UsageStats$1;
-HSPLandroid/app/usage/UsageStats$1;->readBundleToEventMap(Landroid/os/Bundle;Landroid/util/ArrayMap;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/app/usage/UsageEvents;->readEventFromParcel(Landroid/os/Parcel;Landroid/app/usage/UsageEvents$Event;)V
+HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/usage/UsageStats;+]Landroid/os/Bundle;Landroid/os/Bundle;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/usage/UsageStats$1;->readBundleToEventMap(Landroid/os/Bundle;Landroid/util/ArrayMap;)V
HSPLandroid/app/usage/UsageStats;-><init>()V
HSPLandroid/app/usage/UsageStats;->getPackageName()Ljava/lang/String;
HSPLandroid/app/usage/UsageStats;->update(Ljava/lang/String;JII)V
@@ -3452,7 +3466,7 @@ HSPLandroid/appwidget/AppWidgetProvider;-><init>()V
HSPLandroid/appwidget/AppWidgetProvider;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
HSPLandroid/appwidget/AppWidgetProviderInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/appwidget/AppWidgetProviderInfo;
HSPLandroid/appwidget/AppWidgetProviderInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/appwidget/AppWidgetProviderInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/appwidget/AppWidgetProviderInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/appwidget/AppWidgetProviderInfo;->getProfile()Landroid/os/UserHandle;
HSPLandroid/appwidget/AppWidgetProviderInfo;->updateDimensions(Landroid/util/DisplayMetrics;)V
HSPLandroid/appwidget/AppWidgetProviderInfo;->writeToParcel(Landroid/os/Parcel;I)V
@@ -3463,6 +3477,10 @@ HSPLandroid/companion/virtual/IVirtualDeviceManager$Stub$Proxy;->getDeviceIdForD
HSPLandroid/companion/virtual/IVirtualDeviceManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/companion/virtual/IVirtualDeviceManager;
HSPLandroid/companion/virtual/VirtualDeviceManager;-><init>(Landroid/companion/virtual/IVirtualDeviceManager;Landroid/content/Context;)V
HSPLandroid/companion/virtual/VirtualDeviceManager;->getDeviceIdForDisplayId(I)I
+HSPLandroid/companion/virtual/flags/FeatureFlagsImpl;-><init>()V
+HSPLandroid/companion/virtual/flags/FeatureFlagsImpl;->enableNativeVdm()Z
+HSPLandroid/companion/virtual/flags/Flags;-><clinit>()V
+HSPLandroid/companion/virtual/flags/Flags;->enableNativeVdm()Z+]Landroid/companion/virtual/flags/FeatureFlags;Landroid/companion/virtual/flags/FeatureFlagsImpl;
HSPLandroid/compat/Compatibility$BehaviorChangeDelegate;->isChangeEnabled(J)Z
HSPLandroid/compat/Compatibility;->isChangeEnabled(J)Z
HSPLandroid/compat/Compatibility;->setBehaviorChangeDelegate(Landroid/compat/Compatibility$BehaviorChangeDelegate;)V
@@ -3492,6 +3510,7 @@ HSPLandroid/content/AttributionSource$ScopedParcelState;->close()V
HSPLandroid/content/AttributionSource$ScopedParcelState;->getParcel()Landroid/os/Parcel;
HSPLandroid/content/AttributionSource;-><clinit>()V
HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;[Ljava/lang/String;ILandroid/content/AttributionSource;)V
+HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;[Ljava/lang/String;Landroid/content/AttributionSource;)V
HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;ILandroid/content/AttributionSource;)V
HSPLandroid/content/AttributionSource;-><init>(ILjava/lang/String;Ljava/lang/String;)V
HSPLandroid/content/AttributionSource;-><init>(ILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;)V
@@ -3603,20 +3622,22 @@ HSPLandroid/content/ComponentName;->getClassName()Ljava/lang/String;
HSPLandroid/content/ComponentName;->getPackageName()Ljava/lang/String;
HSPLandroid/content/ComponentName;->getShortClassName()Ljava/lang/String;
HSPLandroid/content/ComponentName;->hashCode()I
-HSPLandroid/content/ComponentName;->readFromParcel(Landroid/os/Parcel;)Landroid/content/ComponentName;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/ComponentName;->readFromParcel(Landroid/os/Parcel;)Landroid/content/ComponentName;
HSPLandroid/content/ComponentName;->toShortString()Ljava/lang/String;
HSPLandroid/content/ComponentName;->toString()Ljava/lang/String;
-HSPLandroid/content/ComponentName;->unflattenFromString(Ljava/lang/String;)Landroid/content/ComponentName;
+HSPLandroid/content/ComponentName;->unflattenFromString(Ljava/lang/String;)Landroid/content/ComponentName;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/content/ComponentName;->writeToParcel(Landroid/content/ComponentName;Landroid/os/Parcel;)V
HSPLandroid/content/ComponentName;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/ContentCaptureOptions$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions;
HSPLandroid/content/ContentCaptureOptions$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;-><init>()V
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;->apply(I)Ljava/lang/Object;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;->accept(Ljava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->-$$Nest$smcreateFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;-><init>(ZILjava/util/List;Ljava/util/List;I)V
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
-HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createGroupsFromParcel(Landroid/os/Parcel;)Ljava/util/List;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$11;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createGroupsFromParcel(Landroid/os/Parcel;)Ljava/util/List;+]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$11;,Ljava/util/stream/ReferencePipeline$15;,Ljava/util/stream/IntPipeline$1;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->lambda$createGroupsFromParcel$0(I)Ljava/util/ArrayList;
HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->writeToParcel(Landroid/os/Parcel;)V
HSPLandroid/content/ContentCaptureOptions;-><init>(IIIIILandroid/util/ArraySet;)V
@@ -3651,6 +3672,7 @@ HSPLandroid/content/ContentProvider;->checkUser(IILandroid/content/Context;)Z
HSPLandroid/content/ContentProvider;->clearCallingIdentity()Landroid/content/ContentProvider$CallingIdentity;
HSPLandroid/content/ContentProvider;->coerceToLocalContentProvider(Landroid/content/IContentProvider;)Landroid/content/ContentProvider;
HSPLandroid/content/ContentProvider;->delete(Landroid/net/Uri;Landroid/os/Bundle;)I
+HSPLandroid/content/ContentProvider;->deniedAccessSystemUserOnlyProvider(IZ)Z
HSPLandroid/content/ContentProvider;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
HSPLandroid/content/ContentProvider;->enforceReadPermissionInner(Landroid/net/Uri;Landroid/content/AttributionSource;)I
HSPLandroid/content/ContentProvider;->enforceWritePermissionInner(Landroid/net/Uri;Landroid/content/AttributionSource;)I
@@ -3727,7 +3749,7 @@ HSPLandroid/content/ContentProviderOperation$Builder;->withValue(Ljava/lang/Stri
HSPLandroid/content/ContentProviderOperation$Builder;->withValues(Landroid/content/ContentValues;)Landroid/content/ContentProviderOperation$Builder;
HSPLandroid/content/ContentProviderOperation;-><init>(Landroid/content/ContentProviderOperation$Builder;)V
HSPLandroid/content/ContentProviderOperation;->apply(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;
-HSPLandroid/content/ContentProviderOperation;->applyInternal(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;
+HSPLandroid/content/ContentProviderOperation;->applyInternal(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;+]Landroid/content/ContentProviderOperation;Landroid/content/ContentProviderOperation;
HSPLandroid/content/ContentProviderOperation;->getUri()Landroid/net/Uri;
HSPLandroid/content/ContentProviderOperation;->isInsert()Z
HSPLandroid/content/ContentProviderOperation;->isReadOperation()Z
@@ -3739,7 +3761,7 @@ HSPLandroid/content/ContentProviderOperation;->newInsert(Landroid/net/Uri;)Landr
HSPLandroid/content/ContentProviderOperation;->newUpdate(Landroid/net/Uri;)Landroid/content/ContentProviderOperation$Builder;
HSPLandroid/content/ContentProviderOperation;->resolveExtrasBackReferences([Landroid/content/ContentProviderResult;I)Landroid/os/Bundle;
HSPLandroid/content/ContentProviderOperation;->resolveSelectionArgsBackReferences([Landroid/content/ContentProviderResult;I)[Ljava/lang/String;
-HSPLandroid/content/ContentProviderOperation;->resolveValueBackReferences([Landroid/content/ContentProviderResult;I)Landroid/content/ContentValues;
+HSPLandroid/content/ContentProviderOperation;->resolveValueBackReferences([Landroid/content/ContentProviderResult;I)Landroid/content/ContentValues;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/content/ContentValues;Landroid/content/ContentValues;
HSPLandroid/content/ContentProviderOperation;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/ContentProviderProxy;-><init>(Landroid/os/IBinder;)V
HSPLandroid/content/ContentProviderProxy;->asBinder()Landroid/os/IBinder;
@@ -3748,7 +3770,7 @@ HSPLandroid/content/ContentProviderProxy;->createCancellationSignal()Landroid/os
HSPLandroid/content/ContentProviderProxy;->delete(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/os/Bundle;)I
HSPLandroid/content/ContentProviderProxy;->insert(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/content/ContentValues;Landroid/os/Bundle;)Landroid/net/Uri;
HSPLandroid/content/ContentProviderProxy;->openTypedAssetFile(Landroid/content/AttributionSource;Landroid/net/Uri;Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/content/res/AssetFileDescriptor;
-HSPLandroid/content/ContentProviderProxy;->query(Landroid/content/AttributionSource;Landroid/net/Uri;[Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/content/ContentProviderProxy;->query(Landroid/content/AttributionSource;Landroid/net/Uri;[Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/database/Cursor;+]Landroid/content/AttributionSource;Landroid/content/AttributionSource;]Landroid/os/Parcelable$Creator;Landroid/database/BulkCursorDescriptor$1;]Landroid/database/IBulkCursor;Landroid/database/BulkCursorProxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/ICancellationSignal;Landroid/os/ICancellationSignal$Stub$Proxy;]Landroid/database/BulkCursorToCursorAdaptor;Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/IContentObserver;Landroid/database/ContentObserver$Transport;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;,Landroid/net/Uri$StringUri;
HSPLandroid/content/ContentProviderProxy;->update(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/content/ContentValues;Landroid/os/Bundle;)I
HSPLandroid/content/ContentProviderResult$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentProviderResult;
HSPLandroid/content/ContentProviderResult$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -3865,7 +3887,7 @@ HSPLandroid/content/ContentValues;->putNull(Ljava/lang/String;)V
HSPLandroid/content/ContentValues;->putObject(Ljava/lang/String;Ljava/lang/Object;)V
HSPLandroid/content/ContentValues;->remove(Ljava/lang/String;)V
HSPLandroid/content/ContentValues;->size()I
-HSPLandroid/content/ContentValues;->toString()Ljava/lang/String;+]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/content/ContentValues;->toString()Ljava/lang/String;
HSPLandroid/content/ContentValues;->valueSet()Ljava/util/Set;
HSPLandroid/content/ContentValues;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/Context;-><init>()V
@@ -3879,11 +3901,11 @@ HSPLandroid/content/Context;->getString(I[Ljava/lang/Object;)Ljava/lang/String;
HSPLandroid/content/Context;->getSystemService(Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/content/Context;->getText(I)Ljava/lang/CharSequence;
HSPLandroid/content/Context;->getToken(Landroid/content/Context;)Landroid/os/IBinder;
-HSPLandroid/content/Context;->isAutofillCompatibilityEnabled()Z+]Landroid/content/Context;missing_types
-HSPLandroid/content/Context;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/Context;->isAutofillCompatibilityEnabled()Z
+HSPLandroid/content/Context;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;
+HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;
+HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/Context;missing_types
+HSPLandroid/content/Context;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;
HSPLandroid/content/Context;->registerComponentCallbacks(Landroid/content/ComponentCallbacks;)V
HSPLandroid/content/Context;->unregisterComponentCallbacks(Landroid/content/ComponentCallbacks;)V
HSPLandroid/content/ContextParams$Builder;-><init>()V
@@ -3930,25 +3952,25 @@ HSPLandroid/content/ContextWrapper;->enforceCallingPermission(Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->enforcePermission(Ljava/lang/String;IILjava/lang/String;)V
HSPLandroid/content/ContextWrapper;->fileList()[Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getActivityToken()Landroid/os/IBinder;
-HSPLandroid/content/ContextWrapper;->getApplicationContext()Landroid/content/Context;+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->getApplicationContext()Landroid/content/Context;
HSPLandroid/content/ContextWrapper;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getAssets()Landroid/content/res/AssetManager;
HSPLandroid/content/ContextWrapper;->getAttributionSource()Landroid/content/AttributionSource;
HSPLandroid/content/ContextWrapper;->getAttributionTag()Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getAutofillClient()Landroid/view/autofill/AutofillManager$AutofillClient;
-HSPLandroid/content/ContextWrapper;->getAutofillOptions()Landroid/content/AutofillOptions;+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->getAutofillOptions()Landroid/content/AutofillOptions;
HSPLandroid/content/ContextWrapper;->getBaseContext()Landroid/content/Context;
HSPLandroid/content/ContextWrapper;->getBasePackageName()Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getCacheDir()Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getClassLoader()Ljava/lang/ClassLoader;
HSPLandroid/content/ContextWrapper;->getContentCaptureOptions()Landroid/content/ContentCaptureOptions;
-HSPLandroid/content/ContextWrapper;->getContentResolver()Landroid/content/ContentResolver;
+HSPLandroid/content/ContextWrapper;->getContentResolver()Landroid/content/ContentResolver;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getDataDir()Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getDatabasePath(Ljava/lang/String;)Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getDeviceId()I
HSPLandroid/content/ContextWrapper;->getDir(Ljava/lang/String;I)Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getDisplay()Landroid/view/Display;
-HSPLandroid/content/ContextWrapper;->getDisplayId()I
+HSPLandroid/content/ContextWrapper;->getDisplayId()I+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getDisplayNoVerify()Landroid/view/Display;
HSPLandroid/content/ContextWrapper;->getExternalCacheDir()Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getExternalCacheDirs()[Ljava/io/File;
@@ -3964,21 +3986,21 @@ HSPLandroid/content/ContextWrapper;->getNextAutofillId()I
HSPLandroid/content/ContextWrapper;->getNoBackupFilesDir()Ljava/io/File;
HSPLandroid/content/ContextWrapper;->getOpPackageName()Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getPackageCodePath()Ljava/lang/String;
-HSPLandroid/content/ContextWrapper;->getPackageManager()Landroid/content/pm/PackageManager;
+HSPLandroid/content/ContextWrapper;->getPackageManager()Landroid/content/pm/PackageManager;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getPackageName()Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getPackageResourcePath()Ljava/lang/String;
HSPLandroid/content/ContextWrapper;->getResources()Landroid/content/res/Resources;
-HSPLandroid/content/ContextWrapper;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
+HSPLandroid/content/ContextWrapper;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getSharedPreferencesPath(Ljava/lang/String;)Ljava/io/File;
-HSPLandroid/content/ContextWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/content/ContextWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getSystemServiceName(Ljava/lang/Class;)Ljava/lang/String;+]Landroid/content/Context;missing_types
-HSPLandroid/content/ContextWrapper;->getTheme()Landroid/content/res/Resources$Theme;
+HSPLandroid/content/ContextWrapper;->getTheme()Landroid/content/res/Resources$Theme;+]Landroid/content/Context;missing_types
HSPLandroid/content/ContextWrapper;->getUser()Landroid/os/UserHandle;
HSPLandroid/content/ContextWrapper;->getUserId()I
HSPLandroid/content/ContextWrapper;->getWindowContextToken()Landroid/os/IBinder;
HSPLandroid/content/ContextWrapper;->grantUriPermission(Ljava/lang/String;Landroid/net/Uri;I)V
HSPLandroid/content/ContextWrapper;->isDeviceProtectedStorage()Z
-HSPLandroid/content/ContextWrapper;->isRestricted()Z+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->isRestricted()Z
HSPLandroid/content/ContextWrapper;->isUiContext()Z
HSPLandroid/content/ContextWrapper;->openFileInput(Ljava/lang/String;)Ljava/io/FileInputStream;
HSPLandroid/content/ContextWrapper;->openFileOutput(Ljava/lang/String;I)Ljava/io/FileOutputStream;
@@ -4064,7 +4086,7 @@ HSPLandroid/content/Intent;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/Intent;-><init>(Ljava/lang/String;)V
HSPLandroid/content/Intent;-><init>(Ljava/lang/String;Landroid/net/Uri;)V
HSPLandroid/content/Intent;-><init>(Ljava/lang/String;Landroid/net/Uri;Landroid/content/Context;Ljava/lang/Class;)V
-HSPLandroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;+]Ljava/lang/String;Ljava/lang/String;]Landroid/util/ArraySet;Landroid/util/ArraySet;
HSPLandroid/content/Intent;->addFlags(I)Landroid/content/Intent;
HSPLandroid/content/Intent;->cloneFilter()Landroid/content/Intent;
HSPLandroid/content/Intent;->filterEquals(Landroid/content/Intent;)Z
@@ -4129,8 +4151,8 @@ HSPLandroid/content/Intent;->putExtras(Landroid/content/Intent;)Landroid/content
HSPLandroid/content/Intent;->putExtras(Landroid/os/Bundle;)Landroid/content/Intent;
HSPLandroid/content/Intent;->putParcelableArrayListExtra(Ljava/lang/String;Ljava/util/ArrayList;)Landroid/content/Intent;
HSPLandroid/content/Intent;->putStringArrayListExtra(Ljava/lang/String;Ljava/util/ArrayList;)Landroid/content/Intent;
-HSPLandroid/content/Intent;->readFromParcel(Landroid/os/Parcel;)V
-HSPLandroid/content/Intent;->removeCategory(Ljava/lang/String;)V
+HSPLandroid/content/Intent;->readFromParcel(Landroid/os/Parcel;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/os/Parcelable$Creator;Landroid/net/Uri$1;,Landroid/graphics/Rect$1;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/content/Intent;Landroid/content/Intent;
+HSPLandroid/content/Intent;->removeCategory(Ljava/lang/String;)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;
HSPLandroid/content/Intent;->removeExtra(Ljava/lang/String;)V
HSPLandroid/content/Intent;->replaceExtras(Landroid/os/Bundle;)Landroid/content/Intent;
HSPLandroid/content/Intent;->resolveActivity(Landroid/content/pm/PackageManager;)Landroid/content/ComponentName;
@@ -4155,13 +4177,13 @@ HSPLandroid/content/Intent;->setPackage(Ljava/lang/String;)Landroid/content/Inte
HSPLandroid/content/Intent;->setSelector(Landroid/content/Intent;)V
HSPLandroid/content/Intent;->setSourceBounds(Landroid/graphics/Rect;)V
HSPLandroid/content/Intent;->setType(Ljava/lang/String;)Landroid/content/Intent;
-HSPLandroid/content/Intent;->toShortString(Ljava/lang/StringBuilder;ZZZZ)V
+HSPLandroid/content/Intent;->toShortString(Ljava/lang/StringBuilder;ZZZZ)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ComponentName;Landroid/content/ComponentName;
HSPLandroid/content/Intent;->toString()Ljava/lang/String;
HSPLandroid/content/Intent;->toString(Ljava/lang/StringBuilder;)V
HSPLandroid/content/Intent;->toUri(I)Ljava/lang/String;
HSPLandroid/content/Intent;->toUriFragment(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
HSPLandroid/content/Intent;->toUriInner(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
-HSPLandroid/content/Intent;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/Intent;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/IntentFilter$$ExternalSyntheticLambda0;->accept(Ljava/lang/Object;Ljava/lang/Object;)V
HSPLandroid/content/IntentFilter$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/IntentFilter;
HSPLandroid/content/IntentFilter$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4225,7 +4247,7 @@ HSPLandroid/content/IntentFilter;->setOrder(I)V
HSPLandroid/content/IntentFilter;->setPriority(I)V
HSPLandroid/content/IntentFilter;->setVisibilityToInstantApp(I)V
HSPLandroid/content/IntentFilter;->typesIterator()Ljava/util/Iterator;
-HSPLandroid/content/IntentFilter;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/IntentFilter;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/content/IntentFilter;Landroid/content/IntentFilter;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/IntentSender;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/LocusId$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/LocusId;
HSPLandroid/content/LocusId$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4301,7 +4323,7 @@ HSPLandroid/content/UriMatcher;-><init>(I)V
HSPLandroid/content/UriMatcher;-><init>(ILjava/lang/String;)V
HSPLandroid/content/UriMatcher;->addURI(Ljava/lang/String;Ljava/lang/String;I)V
HSPLandroid/content/UriMatcher;->createChild(Ljava/lang/String;)Landroid/content/UriMatcher;
-HSPLandroid/content/UriMatcher;->match(Landroid/net/Uri;)I
+HSPLandroid/content/UriMatcher;->match(Landroid/net/Uri;)I+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/List;Landroid/net/Uri$PathSegments;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;
HSPLandroid/content/om/OverlayInfo;->ensureValidState()V
HSPLandroid/content/om/OverlayInfo;->isEnabled()Z
HSPLandroid/content/pm/ActivityInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ActivityInfo;
@@ -4309,7 +4331,7 @@ HSPLandroid/content/pm/ActivityInfo$1;->createFromParcel(Landroid/os/Parcel;)Lja
HSPLandroid/content/pm/ActivityInfo$1;->newArray(I)[Landroid/content/pm/ActivityInfo;
HSPLandroid/content/pm/ActivityInfo$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/content/pm/ActivityInfo$WindowLayout;-><init>(Landroid/os/Parcel;)V
-HSPLandroid/content/pm/ActivityInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Ljava/util/Set;Landroid/util/ArraySet;
+HSPLandroid/content/pm/ActivityInfo;-><init>(Landroid/os/Parcel;)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Landroid/util/ArraySet;
HSPLandroid/content/pm/ActivityInfo;->activityInfoConfigNativeToJava(I)I
HSPLandroid/content/pm/ActivityInfo;->getRealConfigChanged()I
HSPLandroid/content/pm/ActivityInfo;->getThemeResource()I
@@ -4328,7 +4350,7 @@ HSPLandroid/content/pm/ApplicationInfo$1;->createFromParcel(Landroid/os/Parcel;)
HSPLandroid/content/pm/ApplicationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/ApplicationInfo;-><init>()V
HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/content/pm/ApplicationInfo;)V
-HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/os/Parcel;Landroid/os/Parcel;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
+HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/ApplicationInfo-IA;)V
HSPLandroid/content/pm/ApplicationInfo;->getAllApkPaths()[Ljava/lang/String;
HSPLandroid/content/pm/ApplicationInfo;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;
@@ -4365,16 +4387,16 @@ HSPLandroid/content/pm/ApplicationInfo;->setSplitCodePaths([Ljava/lang/String;)V
HSPLandroid/content/pm/ApplicationInfo;->setSplitResourcePaths([Ljava/lang/String;)V
HSPLandroid/content/pm/ApplicationInfo;->setVersionCode(J)V
HSPLandroid/content/pm/ApplicationInfo;->toString()Ljava/lang/String;
-HSPLandroid/content/pm/ApplicationInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/pm/ApplicationInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/UUID;Ljava/util/UUID;
HSPLandroid/content/pm/Attribution$1;-><init>()V
HSPLandroid/content/pm/Attribution;-><clinit>()V
HSPLandroid/content/pm/BaseParceledListSlice$1;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
-HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Landroid/os/Parcel;Ljava/lang/ClassLoader;)V
+HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Landroid/os/Parcel;Ljava/lang/ClassLoader;)V+]Landroid/content/pm/BaseParceledListSlice;Landroid/content/pm/ParceledListSlice;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Ljava/util/List;)V
HSPLandroid/content/pm/BaseParceledListSlice;->getList()Ljava/util/List;
HSPLandroid/content/pm/BaseParceledListSlice;->readCreator(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;)Ljava/lang/Object;
-HSPLandroid/content/pm/BaseParceledListSlice;->readVerifyAndAddElement(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;
-HSPLandroid/content/pm/BaseParceledListSlice;->verifySameType(Ljava/lang/Class;Ljava/lang/Class;)V+]Ljava/lang/Object;Ljava/lang/Class;
+HSPLandroid/content/pm/BaseParceledListSlice;->readVerifyAndAddElement(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;+]Ljava/lang/Object;megamorphic_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/content/pm/BaseParceledListSlice;->verifySameType(Ljava/lang/Class;Ljava/lang/Class;)V
HSPLandroid/content/pm/BaseParceledListSlice;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/pm/Checksum$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/Checksum;
HSPLandroid/content/pm/Checksum$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4383,12 +4405,12 @@ HSPLandroid/content/pm/Checksum;->getType()I
HSPLandroid/content/pm/Checksum;->getValue()[B
HSPLandroid/content/pm/ComponentInfo;-><init>()V
HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/content/pm/ComponentInfo;)V
-HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/ComponentInfo;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;
HSPLandroid/content/pm/ComponentInfo;->getComponentName()Landroid/content/ComponentName;
HSPLandroid/content/pm/ComponentInfo;->getIconResource()I
HSPLandroid/content/pm/ComponentInfo;->isEnabled()Z
-HSPLandroid/content/pm/ComponentInfo;->loadUnsafeLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;
+HSPLandroid/content/pm/ComponentInfo;->loadUnsafeLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;+]Landroid/content/pm/PackageManager;Landroid/app/ApplicationPackageManager;
HSPLandroid/content/pm/ComponentInfo;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/pm/ConfigurationInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ConfigurationInfo;
HSPLandroid/content/pm/ConfigurationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4397,9 +4419,13 @@ HSPLandroid/content/pm/CrossProfileApps;-><init>(Landroid/content/Context;Landro
HSPLandroid/content/pm/CrossProfileApps;->getTargetUserProfiles()Ljava/util/List;
HSPLandroid/content/pm/FallbackCategoryProvider;->getFallbackCategory(Ljava/lang/String;)I
HSPLandroid/content/pm/FallbackCategoryProvider;->loadFallbacks()V
+HSPLandroid/content/pm/FeatureFlagsImpl;-><init>()V
+HSPLandroid/content/pm/FeatureFlagsImpl;->relativeReferenceIntentFilters()Z
HSPLandroid/content/pm/FeatureInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/FeatureInfo;
HSPLandroid/content/pm/FeatureInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/FeatureInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/Flags;-><clinit>()V
+HSPLandroid/content/pm/Flags;->relativeReferenceIntentFilters()Z+]Landroid/content/pm/FeatureFlags;Landroid/content/pm/FeatureFlagsImpl;
HSPLandroid/content/pm/ICrossProfileApps$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/content/pm/ICrossProfileApps$Stub$Proxy;->getTargetUserProfiles(Ljava/lang/String;)Ljava/util/List;
HSPLandroid/content/pm/ICrossProfileApps$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/ICrossProfileApps;
@@ -4421,15 +4447,15 @@ HSPLandroid/content/pm/IPackageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->checkPermission(Ljava/lang/String;Ljava/lang/String;I)I
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getActivityInfo(Landroid/content/ComponentName;JI)Landroid/content/pm/ActivityInfo;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationEnabledSetting(Ljava/lang/String;I)I+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationInfo(Ljava/lang/String;JI)Landroid/content/pm/ApplicationInfo;+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationEnabledSetting(Ljava/lang/String;I)I+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationInfo(Ljava/lang/String;JI)Landroid/content/pm/ApplicationInfo;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getComponentEnabledSetting(Landroid/content/ComponentName;I)I
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledApplications(JI)Landroid/content/pm/ParceledListSlice;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledPackages(JI)Landroid/content/pm/ParceledListSlice;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getNameForUid(I)Ljava/lang/String;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;JI)Landroid/content/pm/PackageInfo;+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;JI)Landroid/content/pm/PackageInfo;+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInstaller()Landroid/content/pm/IPackageInstaller;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageUid(Ljava/lang/String;JI)I
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
@@ -4447,7 +4473,7 @@ HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->lambda$notifyDexLoad$1(Landr
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyDexLoad(Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)V
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyPackageUse(Ljava/lang/String;I)V
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyPackagesReplacedReceived([Ljava/lang/String;)V
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentActivities(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentActivities(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentContentProviders(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentReceivers(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentServices(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
@@ -4499,7 +4525,7 @@ HSPLandroid/content/pm/ModuleInfo;->getPackageName()Ljava/lang/String;
HSPLandroid/content/pm/PackageInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/PackageInfo;
HSPLandroid/content/pm/PackageInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/PackageInfo;-><init>()V
-HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;,Landroid/content/pm/SigningInfo$1;
+HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;,Landroid/content/pm/SigningInfo$1;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/PackageInfo-IA;)V
HSPLandroid/content/pm/PackageInfo;->composeLongVersionCode(II)J
HSPLandroid/content/pm/PackageInfo;->getLongVersionCode()J
@@ -4523,7 +4549,7 @@ HSPLandroid/content/pm/PackageInstaller;->getSessionInfo(I)Landroid/content/pm/P
HSPLandroid/content/pm/PackageInstaller;->registerSessionCallback(Landroid/content/pm/PackageInstaller$SessionCallback;Landroid/os/Handler;)V
HSPLandroid/content/pm/PackageItemInfo;-><init>()V
HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/content/pm/PackageItemInfo;)V
-HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/PackageItemInfo;->forceSafeLabels()V
HSPLandroid/content/pm/PackageItemInfo;->loadIcon(Landroid/content/pm/PackageManager;)Landroid/graphics/drawable/Drawable;
HSPLandroid/content/pm/PackageItemInfo;->loadLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;
@@ -4681,7 +4707,7 @@ HSPLandroid/content/pm/RegisteredServicesCache;->containsType(Ljava/util/ArrayLi
HSPLandroid/content/pm/ResolveInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ResolveInfo;
HSPLandroid/content/pm/ResolveInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/ResolveInfo;-><init>()V
-HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ServiceInfo$1;,Landroid/content/pm/ActivityInfo$1;,Landroid/text/TextUtils$1;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/ResolveInfo-IA;)V
HSPLandroid/content/pm/ResolveInfo;->getComponentInfo()Landroid/content/pm/ComponentInfo;
HSPLandroid/content/pm/ResolveInfo;->loadIcon(Landroid/content/pm/PackageManager;)Landroid/graphics/drawable/Drawable;
@@ -4694,8 +4720,8 @@ HSPLandroid/content/pm/ServiceInfo$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/content/pm/ServiceInfo;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/pm/ServiceInfo;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SharedLibraryInfo;
-HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/content/pm/SharedLibraryInfo$1;Landroid/content/pm/SharedLibraryInfo$1;
+HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/SharedLibraryInfo-IA;)V
HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;JILandroid/content/pm/VersionedPackage;Ljava/util/List;Ljava/util/List;Z)V
HSPLandroid/content/pm/SharedLibraryInfo;->addDependency(Landroid/content/pm/SharedLibraryInfo;)V
@@ -4705,7 +4731,7 @@ HSPLandroid/content/pm/SharedLibraryInfo;->getName()Ljava/lang/String;
HSPLandroid/content/pm/SharedLibraryInfo;->getPath()Ljava/lang/String;
HSPLandroid/content/pm/SharedLibraryInfo;->isNative()Z
HSPLandroid/content/pm/SharedLibraryInfo;->isSdk()Z
-HSPLandroid/content/pm/SharedLibraryInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/pm/SharedLibraryInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/ShortcutInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ShortcutInfo;
HSPLandroid/content/pm/ShortcutInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/ShortcutInfo$Builder;-><init>(Landroid/content/Context;Ljava/lang/String;)V
@@ -4718,7 +4744,7 @@ HSPLandroid/content/pm/ShortcutInfo$Builder;->setLongLabel(Ljava/lang/CharSequen
HSPLandroid/content/pm/ShortcutInfo$Builder;->setLongLived(Z)Landroid/content/pm/ShortcutInfo$Builder;
HSPLandroid/content/pm/ShortcutInfo$Builder;->setRank(I)Landroid/content/pm/ShortcutInfo$Builder;
HSPLandroid/content/pm/ShortcutInfo$Builder;->setShortLabel(Ljava/lang/CharSequence;)Landroid/content/pm/ShortcutInfo$Builder;
-HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/content/pm/ShortcutInfo$Builder;)V
+HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/content/pm/ShortcutInfo$Builder;)V+]Landroid/content/pm/ShortcutInfo;Landroid/content/pm/ShortcutInfo;
HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/pm/ShortcutInfo;->addFlags(I)V
HSPLandroid/content/pm/ShortcutInfo;->cloneCapabilityBindings(Ljava/util/Map;)Ljava/util/Map;
@@ -4769,7 +4795,7 @@ HSPLandroid/content/pm/Signature$1;->createFromParcel(Landroid/os/Parcel;)Landro
HSPLandroid/content/pm/Signature$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/content/pm/Signature$1;->newArray(I)[Landroid/content/pm/Signature;
HSPLandroid/content/pm/Signature$1;->newArray(I)[Ljava/lang/Object;
-HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;Landroid/content/pm/Signature-IA;)V
HSPLandroid/content/pm/Signature;-><init>(Ljava/lang/String;)V
HSPLandroid/content/pm/Signature;-><init>([B)V
@@ -4782,11 +4808,11 @@ HSPLandroid/content/pm/Signature;->toChars([C[I)[C
HSPLandroid/content/pm/Signature;->toCharsString()Ljava/lang/String;
HSPLandroid/content/pm/SigningDetails$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SigningDetails;
HSPLandroid/content/pm/SigningDetails$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SigningDetails;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/content/pm/SigningDetails;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/SigningDetails;->getSignatures()[Landroid/content/pm/Signature;
HSPLandroid/content/pm/SigningInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SigningInfo;
HSPLandroid/content/pm/SigningInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SigningInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/SigningDetails$1;
+HSPLandroid/content/pm/SigningInfo;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/pm/SigningInfo;->getApkContentsSigners()[Landroid/content/pm/Signature;
HSPLandroid/content/pm/SigningInfo;->getSigningCertificateHistory()[Landroid/content/pm/Signature;
HSPLandroid/content/pm/SigningInfo;->hasMultipleSigners()Z
@@ -4796,7 +4822,7 @@ HSPLandroid/content/pm/StringParceledListSlice$1;->createFromParcel(Landroid/os/
HSPLandroid/content/pm/StringParceledListSlice;->getList()Ljava/util/List;
HSPLandroid/content/pm/UserInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/UserInfo;
HSPLandroid/content/pm/UserInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/UserInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/UserInfo;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/pm/UserInfo;->getUserHandle()Landroid/os/UserHandle;
HSPLandroid/content/pm/UserInfo;->isAdmin()Z
HSPLandroid/content/pm/UserInfo;->isEnabled()Z
@@ -4815,8 +4841,8 @@ HSPLandroid/content/pm/UserPackage;->hashCode()I
HSPLandroid/content/pm/UserPackage;->of(ILjava/lang/String;)Landroid/content/pm/UserPackage;
HSPLandroid/content/pm/UserProperties;->isPresent(J)Z
HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/VersionedPackage;
-HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/content/pm/VersionedPackage$1;Landroid/content/pm/VersionedPackage$1;
+HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;Landroid/content/pm/VersionedPackage-IA;)V
HSPLandroid/content/pm/VersionedPackage;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/pm/dex/ArtManager;->getCurrentProfilePath(Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;
@@ -4933,7 +4959,7 @@ HSPLandroid/content/res/AssetManager;->getResourceTypeName(I)Ljava/lang/String;
HSPLandroid/content/res/AssetManager;->getResourceValue(IILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
HSPLandroid/content/res/AssetManager;->getSizeConfigurations()[Landroid/content/res/Configuration;
HSPLandroid/content/res/AssetManager;->getSystem()Landroid/content/res/AssetManager;
-HSPLandroid/content/res/AssetManager;->getThemeValue(JILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/AssetManager;->getThemeValue(JILandroid/util/TypedValue;Z)Z
HSPLandroid/content/res/AssetManager;->incRefsLocked(J)V
HSPLandroid/content/res/AssetManager;->isUpToDate()Z
HSPLandroid/content/res/AssetManager;->list(Ljava/lang/String;)[Ljava/lang/String;
@@ -4972,13 +4998,13 @@ HSPLandroid/content/res/ColorStateList;->getChangingConfigurations()I
HSPLandroid/content/res/ColorStateList;->getColorForState([II)I
HSPLandroid/content/res/ColorStateList;->getConstantState()Landroid/content/res/ConstantState;
HSPLandroid/content/res/ColorStateList;->getDefaultColor()I
-HSPLandroid/content/res/ColorStateList;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/ColorStateList;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/content/res/ColorStateList;->isStateful()Z
HSPLandroid/content/res/ColorStateList;->modulateColor(IFF)I
HSPLandroid/content/res/ColorStateList;->obtainForTheme(Landroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/ColorStateList;->obtainForTheme(Landroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
HSPLandroid/content/res/ColorStateList;->onColorsChanged()V
-HSPLandroid/content/res/ColorStateList;->valueOf(I)Landroid/content/res/ColorStateList;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/content/res/ColorStateList;->valueOf(I)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/ColorStateList;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/res/CompatibilityInfo$2;->createFromParcel(Landroid/os/Parcel;)Landroid/content/res/CompatibilityInfo;
HSPLandroid/content/res/CompatibilityInfo$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -5010,11 +5036,11 @@ HSPLandroid/content/res/Configuration;-><init>(Landroid/os/Parcel;)V
HSPLandroid/content/res/Configuration;-><init>(Landroid/os/Parcel;Landroid/content/res/Configuration-IA;)V
HSPLandroid/content/res/Configuration;->compareTo(Landroid/content/res/Configuration;)I
HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;)I
-HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;ZZ)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/os/LocaleList;Landroid/os/LocaleList;
+HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;ZZ)I
HSPLandroid/content/res/Configuration;->diffPublicOnly(Landroid/content/res/Configuration;)I
HSPLandroid/content/res/Configuration;->equals(Landroid/content/res/Configuration;)Z
HSPLandroid/content/res/Configuration;->equals(Ljava/lang/Object;)Z
-HSPLandroid/content/res/Configuration;->fixUpLocaleList()V+]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Object;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->fixUpLocaleList()V
HSPLandroid/content/res/Configuration;->generateDelta(Landroid/content/res/Configuration;Landroid/content/res/Configuration;)Landroid/content/res/Configuration;
HSPLandroid/content/res/Configuration;->getGrammaticalGender()I
HSPLandroid/content/res/Configuration;->getLayoutDirection()I
@@ -5026,19 +5052,19 @@ HSPLandroid/content/res/Configuration;->isOtherSeqNewer(Landroid/content/res/Con
HSPLandroid/content/res/Configuration;->isScreenRound()Z
HSPLandroid/content/res/Configuration;->isScreenWideColorGamut()Z
HSPLandroid/content/res/Configuration;->needNewResources(II)Z
-HSPLandroid/content/res/Configuration;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/res/Configuration;->readFromParcel(Landroid/os/Parcel;)V
HSPLandroid/content/res/Configuration;->readFromProto(Landroid/util/proto/ProtoInputStream;J)V
HSPLandroid/content/res/Configuration;->reduceScreenLayout(III)I
HSPLandroid/content/res/Configuration;->resetScreenLayout(I)I
HSPLandroid/content/res/Configuration;->setLayoutDirection(Ljava/util/Locale;)V
HSPLandroid/content/res/Configuration;->setLocale(Ljava/util/Locale;)V
HSPLandroid/content/res/Configuration;->setLocales(Landroid/os/LocaleList;)V
-HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;)V+]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;II)V
HSPLandroid/content/res/Configuration;->setToDefaults()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/content/res/Configuration;->toString()Ljava/lang/String;
HSPLandroid/content/res/Configuration;->unset()V
-HSPLandroid/content/res/Configuration;->updateFrom(Landroid/content/res/Configuration;)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->updateFrom(Landroid/content/res/Configuration;)I+]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/content/res/Configuration;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/content/res/ConfigurationBoundResourceCache;-><init>()V
HSPLandroid/content/res/ConfigurationBoundResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;
@@ -5057,10 +5083,10 @@ HSPLandroid/content/res/DrawableCache;->getInstance(JLandroid/content/res/Resour
HSPLandroid/content/res/DrawableCache;->shouldInvalidateEntry(Landroid/graphics/drawable/Drawable$ConstantState;I)Z
HSPLandroid/content/res/DrawableCache;->shouldInvalidateEntry(Ljava/lang/Object;I)Z
HSPLandroid/content/res/FeatureFlagsImpl;->defaultLocale()Z
-HSPLandroid/content/res/Flags;->defaultLocale()Z
+HSPLandroid/content/res/Flags;->defaultLocale()Z+]Landroid/content/res/FeatureFlags;Landroid/content/res/FeatureFlagsImpl;
HSPLandroid/content/res/FontResourcesParser;->parse(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
-HSPLandroid/content/res/FontResourcesParser;->readFamilies(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;+]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
-HSPLandroid/content/res/FontResourcesParser;->readFamily(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/util/List;Ljava/util/ArrayList;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/FontResourcesParser;->readFamilies(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
+HSPLandroid/content/res/FontResourcesParser;->readFamily(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
HSPLandroid/content/res/FontScaleConverterFactory;->forScale(F)Landroid/content/res/FontScaleConverter;
HSPLandroid/content/res/FontScaleConverterFactory;->isNonLinearFontScalingActive(F)Z
HSPLandroid/content/res/GradientColor;-><init>()V
@@ -5079,28 +5105,28 @@ HSPLandroid/content/res/Resources$NotFoundException;-><init>(Ljava/lang/String;)
HSPLandroid/content/res/Resources$Theme;-><init>(Landroid/content/res/Resources;)V
HSPLandroid/content/res/Resources$Theme;-><init>(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme-IA;)V
HSPLandroid/content/res/Resources$Theme;->applyStyle(IZ)V
-HSPLandroid/content/res/Resources$Theme;->equals(Ljava/lang/Object;)Z+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Ljava/lang/Object;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/res/Resources$Theme;->equals(Ljava/lang/Object;)Z
HSPLandroid/content/res/Resources$Theme;->getAppliedStyleResId()I
HSPLandroid/content/res/Resources$Theme;->getChangingConfigurations()I
-HSPLandroid/content/res/Resources$Theme;->getKey()Landroid/content/res/Resources$ThemeKey;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->getKey()Landroid/content/res/Resources$ThemeKey;
HSPLandroid/content/res/Resources$Theme;->getParentThemeIdentifier(I)I
HSPLandroid/content/res/Resources$Theme;->getResources()Landroid/content/res/Resources;
HSPLandroid/content/res/Resources$Theme;->getTheme()[Ljava/lang/String;
HSPLandroid/content/res/Resources$Theme;->hashCode()I
-HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;
HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;
HSPLandroid/content/res/Resources$Theme;->rebase()V
HSPLandroid/content/res/Resources$Theme;->rebase(Landroid/content/res/ResourcesImpl;)V
-HSPLandroid/content/res/Resources$Theme;->resolveAttribute(ILandroid/util/TypedValue;Z)Z+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->resolveAttribute(ILandroid/util/TypedValue;Z)Z
HSPLandroid/content/res/Resources$Theme;->resolveAttributes([I[I)Landroid/content/res/TypedArray;
HSPLandroid/content/res/Resources$Theme;->setImpl(Landroid/content/res/ResourcesImpl$ThemeImpl;)V
HSPLandroid/content/res/Resources$Theme;->setTo(Landroid/content/res/Resources$Theme;)V
-HSPLandroid/content/res/Resources$Theme;->toString()Ljava/lang/String;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/content/res/Resources$Theme;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLandroid/content/res/Resources$ThemeKey;-><init>()V
HSPLandroid/content/res/Resources$ThemeKey;->append(IZ)V
HSPLandroid/content/res/Resources$ThemeKey;->clone()Landroid/content/res/Resources$ThemeKey;
-HSPLandroid/content/res/Resources$ThemeKey;->equals(Ljava/lang/Object;)Z+]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Ljava/lang/Object;Landroid/content/res/Resources$ThemeKey;
+HSPLandroid/content/res/Resources$ThemeKey;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Landroid/content/res/Resources$ThemeKey;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;
HSPLandroid/content/res/Resources$ThemeKey;->hashCode()I
HSPLandroid/content/res/Resources$ThemeKey;->moveToLast(I)V
HSPLandroid/content/res/Resources$ThemeKey;->setTo(Landroid/content/res/Resources$ThemeKey;)V+][I[I][Z[Z
@@ -5119,12 +5145,12 @@ HSPLandroid/content/res/Resources;->getAttributeSetSourceResId(Landroid/util/Att
HSPLandroid/content/res/Resources;->getBoolean(I)Z
HSPLandroid/content/res/Resources;->getClassLoader()Ljava/lang/ClassLoader;
HSPLandroid/content/res/Resources;->getColor(I)I
-HSPLandroid/content/res/Resources;->getColor(ILandroid/content/res/Resources$Theme;)I+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getColor(ILandroid/content/res/Resources$Theme;)I
HSPLandroid/content/res/Resources;->getColorStateList(I)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/Resources;->getColorStateList(ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/Resources;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo;
HSPLandroid/content/res/Resources;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
-HSPLandroid/content/res/Resources;->getDimension(I)F+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getDimension(I)F
HSPLandroid/content/res/Resources;->getDimensionPixelOffset(I)I
HSPLandroid/content/res/Resources;->getDimensionPixelSize(I)I
HSPLandroid/content/res/Resources;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -5132,7 +5158,7 @@ HSPLandroid/content/res/Resources;->getDisplayMetrics()Landroid/util/DisplayMetr
HSPLandroid/content/res/Resources;->getDrawable(I)Landroid/graphics/drawable/Drawable;
HSPLandroid/content/res/Resources;->getDrawable(ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
HSPLandroid/content/res/Resources;->getDrawableForDensity(II)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/Resources;->getDrawableForDensity(IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getDrawableForDensity(IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
HSPLandroid/content/res/Resources;->getDrawableInflater()Landroid/graphics/drawable/DrawableInflater;
HSPLandroid/content/res/Resources;->getFloat(I)F
HSPLandroid/content/res/Resources;->getFont(Landroid/util/TypedValue;I)Landroid/graphics/Typeface;
@@ -5146,7 +5172,7 @@ HSPLandroid/content/res/Resources;->getLoaders()Ljava/util/List;
HSPLandroid/content/res/Resources;->getQuantityString(II)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getQuantityString(II[Ljava/lang/Object;)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getQuantityText(II)Ljava/lang/CharSequence;
-HSPLandroid/content/res/Resources;->getResourceEntryName(I)Ljava/lang/String;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getResourceEntryName(I)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getResourceName(I)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getResourcePackageName(I)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getResourceTypeName(I)Ljava/lang/String;
@@ -5154,24 +5180,24 @@ HSPLandroid/content/res/Resources;->getSizeConfigurations()[Landroid/content/res
HSPLandroid/content/res/Resources;->getStateListAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
HSPLandroid/content/res/Resources;->getString(I)Ljava/lang/String;
HSPLandroid/content/res/Resources;->getString(I[Ljava/lang/Object;)Ljava/lang/String;
-HSPLandroid/content/res/Resources;->getStringArray(I)[Ljava/lang/String;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getStringArray(I)[Ljava/lang/String;
HSPLandroid/content/res/Resources;->getSystem()Landroid/content/res/Resources;
HSPLandroid/content/res/Resources;->getText(I)Ljava/lang/CharSequence;
HSPLandroid/content/res/Resources;->getTextArray(I)[Ljava/lang/CharSequence;
-HSPLandroid/content/res/Resources;->getValue(ILandroid/util/TypedValue;Z)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getValue(ILandroid/util/TypedValue;Z)V
HSPLandroid/content/res/Resources;->getValueForDensity(IILandroid/util/TypedValue;Z)V
HSPLandroid/content/res/Resources;->getXml(I)Landroid/content/res/XmlResourceParser;
HSPLandroid/content/res/Resources;->hasOverrideDisplayAdjustments()Z
-HSPLandroid/content/res/Resources;->loadColorStateList(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->loadColorStateList(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/Resources;->loadComplexColor(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
HSPLandroid/content/res/Resources;->loadDrawable(Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/Resources;->loadXmlResourceParser(ILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/content/res/Resources;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
-HSPLandroid/content/res/Resources;->newTheme()Landroid/content/res/Resources$Theme;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/content/res/Resources;->loadXmlResourceParser(ILjava/lang/String;)Landroid/content/res/XmlResourceParser;
+HSPLandroid/content/res/Resources;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;
+HSPLandroid/content/res/Resources;->newTheme()Landroid/content/res/Resources$Theme;
HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;
-HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
HSPLandroid/content/res/Resources;->obtainTempTypedValue()Landroid/util/TypedValue;
-HSPLandroid/content/res/Resources;->obtainTypedArray(I)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->obtainTypedArray(I)Landroid/content/res/TypedArray;
HSPLandroid/content/res/Resources;->openRawResource(I)Ljava/io/InputStream;
HSPLandroid/content/res/Resources;->openRawResource(ILandroid/util/TypedValue;)Ljava/io/InputStream;
HSPLandroid/content/res/Resources;->openRawResourceFd(I)Landroid/content/res/AssetFileDescriptor;
@@ -5201,26 +5227,26 @@ HSPLandroid/content/res/ResourcesImpl$LookupStack;-><init>(Landroid/content/res/
HSPLandroid/content/res/ResourcesImpl$LookupStack;->contains(I)Z
HSPLandroid/content/res/ResourcesImpl$LookupStack;->pop()V
HSPLandroid/content/res/ResourcesImpl$LookupStack;->push(I)V
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;-><init>(Landroid/content/res/ResourcesImpl;)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->applyStyle(IZ)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;-><init>(Landroid/content/res/ResourcesImpl;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->applyStyle(IZ)V
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->finalize()V
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getAppliedStyleResId()I
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getChangingConfigurations()I
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getKey()Landroid/content/res/Resources$ThemeKey;
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getParentThemeIdentifier(I)I
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getTheme()[Ljava/lang/String;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->obtainStyledAttributes(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->obtainStyledAttributes(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->rebase()V
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->rebase(Landroid/content/res/AssetManager;)V
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttribute(ILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttribute(ILandroid/util/TypedValue;Z)Z
HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttributes(Landroid/content/res/Resources$Theme;[I[I)Landroid/content/res/TypedArray;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->setTo(Landroid/content/res/ResourcesImpl$ThemeImpl;)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->setTo(Landroid/content/res/ResourcesImpl$ThemeImpl;)V
HSPLandroid/content/res/ResourcesImpl;->-$$Nest$sfgetsThemeRegistry()Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/content/res/ResourcesImpl;-><init>(Landroid/content/res/AssetManager;Landroid/util/DisplayMetrics;Landroid/content/res/Configuration;Landroid/view/DisplayAdjustments;)V+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;
+HSPLandroid/content/res/ResourcesImpl;-><init>(Landroid/content/res/AssetManager;Landroid/util/DisplayMetrics;Landroid/content/res/Configuration;Landroid/view/DisplayAdjustments;)V+]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
HSPLandroid/content/res/ResourcesImpl;->adjustLanguageTag(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/content/res/ResourcesImpl;->attrForQuantityCode(Ljava/lang/String;)I
-HSPLandroid/content/res/ResourcesImpl;->cacheDrawable(Landroid/util/TypedValue;ZLandroid/content/res/DrawableCache;Landroid/content/res/Resources$Theme;ZJLandroid/graphics/drawable/Drawable;I)V
-HSPLandroid/content/res/ResourcesImpl;->calcConfigChanges(Landroid/content/res/Configuration;)I+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;
+HSPLandroid/content/res/ResourcesImpl;->cacheDrawable(Landroid/util/TypedValue;ZLandroid/content/res/DrawableCache;Landroid/content/res/Resources$Theme;ZJLandroid/graphics/drawable/Drawable;I)V+]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/content/res/ResourcesImpl;->calcConfigChanges(Landroid/content/res/Configuration;)I
HSPLandroid/content/res/ResourcesImpl;->decodeImageDrawable(Landroid/content/res/AssetManager$AssetInputStream;Landroid/content/res/Resources;Landroid/util/TypedValue;)Landroid/graphics/drawable/Drawable;
HSPLandroid/content/res/ResourcesImpl;->dump(Ljava/io/PrintWriter;Ljava/lang/String;)V
HSPLandroid/content/res/ResourcesImpl;->finishPreloading()V
@@ -5228,7 +5254,7 @@ HSPLandroid/content/res/ResourcesImpl;->flushLayoutCache()V
HSPLandroid/content/res/ResourcesImpl;->getAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
HSPLandroid/content/res/ResourcesImpl;->getAssets()Landroid/content/res/AssetManager;
HSPLandroid/content/res/ResourcesImpl;->getAttributeSetSourceResId(Landroid/util/AttributeSet;)I
-HSPLandroid/content/res/ResourcesImpl;->getColorStateListFromInt(Landroid/util/TypedValue;J)Landroid/content/res/ColorStateList;+]Landroid/content/res/ConstantState;Landroid/content/res/ColorStateList$ColorStateListFactory;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
+HSPLandroid/content/res/ResourcesImpl;->getColorStateListFromInt(Landroid/util/TypedValue;J)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/ResourcesImpl;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo;
HSPLandroid/content/res/ResourcesImpl;->getConfiguration()Landroid/content/res/Configuration;
HSPLandroid/content/res/ResourcesImpl;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -5242,7 +5268,7 @@ HSPLandroid/content/res/ResourcesImpl;->getResourcePackageName(I)Ljava/lang/Stri
HSPLandroid/content/res/ResourcesImpl;->getResourceTypeName(I)Ljava/lang/String;
HSPLandroid/content/res/ResourcesImpl;->getSizeConfigurations()[Landroid/content/res/Configuration;
HSPLandroid/content/res/ResourcesImpl;->getStateListAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
-HSPLandroid/content/res/ResourcesImpl;->getValue(ILandroid/util/TypedValue;Z)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl;->getValue(ILandroid/util/TypedValue;Z)V
HSPLandroid/content/res/ResourcesImpl;->getValueForDensity(IILandroid/util/TypedValue;Z)V
HSPLandroid/content/res/ResourcesImpl;->isIntLike(Ljava/lang/String;)Z
HSPLandroid/content/res/ResourcesImpl;->lambda$decodeImageDrawable$1(Landroid/graphics/ImageDecoder;Landroid/graphics/ImageDecoder$ImageInfo;Landroid/graphics/ImageDecoder$Source;)V
@@ -5250,18 +5276,18 @@ HSPLandroid/content/res/ResourcesImpl;->lambda$new$0()Landroid/content/res/Resou
HSPLandroid/content/res/ResourcesImpl;->loadColorStateList(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
HSPLandroid/content/res/ResourcesImpl;->loadComplexColor(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
HSPLandroid/content/res/ResourcesImpl;->loadComplexColorForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
-HSPLandroid/content/res/ResourcesImpl;->loadComplexColorFromName(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/TypedValue;I)Landroid/content/res/ComplexColor;+]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;,Landroid/content/res/GradientColor;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/ConstantState;Landroid/content/res/ColorStateList$ColorStateListFactory;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
-HSPLandroid/content/res/ResourcesImpl;->loadDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
-HSPLandroid/content/res/ResourcesImpl;->loadDrawableForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;II)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl$LookupStack;Landroid/content/res/ResourcesImpl$LookupStack;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
-HSPLandroid/content/res/ResourcesImpl;->loadFont(Landroid/content/res/Resources;Landroid/util/TypedValue;I)Landroid/graphics/Typeface;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/content/res/ResourcesImpl;->loadComplexColorFromName(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/TypedValue;I)Landroid/content/res/ComplexColor;+]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;
+HSPLandroid/content/res/ResourcesImpl;->loadDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/content/res/ResourcesImpl;->loadDrawableForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;II)Landroid/graphics/drawable/Drawable;
+HSPLandroid/content/res/ResourcesImpl;->loadFont(Landroid/content/res/Resources;Landroid/util/TypedValue;I)Landroid/graphics/Typeface;
HSPLandroid/content/res/ResourcesImpl;->loadXmlDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILjava/lang/String;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/ResourcesImpl;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock;Landroid/content/res/XmlBlock;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/content/res/ResourcesImpl;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Ljava/lang/Object;Ljava/lang/String;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock;Landroid/content/res/XmlBlock;
HSPLandroid/content/res/ResourcesImpl;->newThemeImpl()Landroid/content/res/ResourcesImpl$ThemeImpl;
HSPLandroid/content/res/ResourcesImpl;->openRawResource(ILandroid/util/TypedValue;)Ljava/io/InputStream;
HSPLandroid/content/res/ResourcesImpl;->openRawResourceFd(ILandroid/util/TypedValue;)Landroid/content/res/AssetFileDescriptor;
HSPLandroid/content/res/ResourcesImpl;->startPreloading()V
-HSPLandroid/content/res/ResourcesImpl;->updateConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V+]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Ljava/util/Locale;Ljava/util/Locale;
-HSPLandroid/content/res/ResourcesImpl;->updateConfigurationImpl(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Z)V+]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/ResourcesImpl;->updateConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;
+HSPLandroid/content/res/ResourcesImpl;->updateConfigurationImpl(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Z)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Ljava/lang/Object;Ljava/util/Locale;
HSPLandroid/content/res/ResourcesImpl;->verifyPreloadConfig(IIILjava/lang/String;)Z
HSPLandroid/content/res/ResourcesKey;-><init>(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/content/res/Configuration;Landroid/content/res/CompatibilityInfo;[Landroid/content/res/loader/ResourcesLoader;)V
HSPLandroid/content/res/ResourcesKey;->equals(Ljava/lang/Object;)Z
@@ -5274,9 +5300,9 @@ HSPLandroid/content/res/StringBlock;->finalize()V
HSPLandroid/content/res/StringBlock;->get(I)Ljava/lang/CharSequence;
HSPLandroid/content/res/StringBlock;->getSequence(I)Ljava/lang/CharSequence;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
HSPLandroid/content/res/ThemedResourceCache;-><init>()V
-HSPLandroid/content/res/ThemedResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;+]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/content/res/ThemedResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;
HSPLandroid/content/res/ThemedResourceCache;->getGeneration()I
-HSPLandroid/content/res/ThemedResourceCache;->getThemedLocked(Landroid/content/res/Resources$Theme;Z)Landroid/util/LongSparseArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/content/res/ThemedResourceCache;->getThemedLocked(Landroid/content/res/Resources$Theme;Z)Landroid/util/LongSparseArray;
HSPLandroid/content/res/ThemedResourceCache;->getUnthemedLocked(Z)Landroid/util/LongSparseArray;
HSPLandroid/content/res/ThemedResourceCache;->onConfigurationChange(I)V
HSPLandroid/content/res/ThemedResourceCache;->pruneEntriesLocked(Landroid/util/LongSparseArray;I)Z
@@ -5288,24 +5314,24 @@ HSPLandroid/content/res/TypedArray;->extractThemeAttrs()[I
HSPLandroid/content/res/TypedArray;->extractThemeAttrs([I)[I
HSPLandroid/content/res/TypedArray;->getBoolean(IZ)Z
HSPLandroid/content/res/TypedArray;->getChangingConfigurations()I+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
-HSPLandroid/content/res/TypedArray;->getColor(II)I+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/content/res/TypedArray;->getColor(II)I
HSPLandroid/content/res/TypedArray;->getColorStateList(I)Landroid/content/res/ColorStateList;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLandroid/content/res/TypedArray;->getComplexColor(I)Landroid/content/res/ComplexColor;
HSPLandroid/content/res/TypedArray;->getDimension(IF)F
HSPLandroid/content/res/TypedArray;->getDimensionPixelOffset(II)I
HSPLandroid/content/res/TypedArray;->getDimensionPixelSize(II)I
-HSPLandroid/content/res/TypedArray;->getDrawable(I)Landroid/graphics/drawable/Drawable;
+HSPLandroid/content/res/TypedArray;->getDrawable(I)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/content/res/TypedArray;->getDrawableForDensity(II)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLandroid/content/res/TypedArray;->getFloat(IF)F
-HSPLandroid/content/res/TypedArray;->getFont(I)Landroid/graphics/Typeface;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/content/res/TypedArray;->getFont(I)Landroid/graphics/Typeface;
HSPLandroid/content/res/TypedArray;->getFraction(IIIF)F
HSPLandroid/content/res/TypedArray;->getIndex(I)I
HSPLandroid/content/res/TypedArray;->getIndexCount()I
HSPLandroid/content/res/TypedArray;->getInt(II)I
HSPLandroid/content/res/TypedArray;->getInteger(II)I
HSPLandroid/content/res/TypedArray;->getLayoutDimension(II)I
-HSPLandroid/content/res/TypedArray;->getLayoutDimension(ILjava/lang/String;)I+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/content/res/TypedArray;->getNonConfigurationString(II)Ljava/lang/String;
+HSPLandroid/content/res/TypedArray;->getLayoutDimension(ILjava/lang/String;)I
+HSPLandroid/content/res/TypedArray;->getNonConfigurationString(II)Ljava/lang/String;+]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/content/res/TypedArray;->getNonResourceString(I)Ljava/lang/String;
HSPLandroid/content/res/TypedArray;->getPositionDescription()Ljava/lang/String;
HSPLandroid/content/res/TypedArray;->getResourceId(II)I
@@ -5319,7 +5345,7 @@ HSPLandroid/content/res/TypedArray;->getValueAt(ILandroid/util/TypedValue;)Z
HSPLandroid/content/res/TypedArray;->hasValue(I)Z
HSPLandroid/content/res/TypedArray;->hasValueOrEmpty(I)Z
HSPLandroid/content/res/TypedArray;->length()I
-HSPLandroid/content/res/TypedArray;->loadStringValueAt(I)Ljava/lang/CharSequence;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/TypedArray;->loadStringValueAt(I)Ljava/lang/CharSequence;+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Validator;Landroid/content/res/Validator;
HSPLandroid/content/res/TypedArray;->obtain(Landroid/content/res/Resources;I)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
HSPLandroid/content/res/TypedArray;->peekValue(I)Landroid/util/TypedValue;
HSPLandroid/content/res/TypedArray;->recycle()V+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
@@ -5336,7 +5362,7 @@ HSPLandroid/content/res/XmlBlock$Parser;->getAttributeName(I)Ljava/lang/String;
HSPLandroid/content/res/XmlBlock$Parser;->getAttributeNameResource(I)I
HSPLandroid/content/res/XmlBlock$Parser;->getAttributeResourceValue(II)I
HSPLandroid/content/res/XmlBlock$Parser;->getAttributeResourceValue(Ljava/lang/String;Ljava/lang/String;I)I
-HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(I)Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(I)Ljava/lang/String;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/content/res/XmlBlock$Parser;->getClassAttribute()Ljava/lang/String;
HSPLandroid/content/res/XmlBlock$Parser;->getDepth()I
@@ -5345,14 +5371,14 @@ HSPLandroid/content/res/XmlBlock$Parser;->getLineNumber()I
HSPLandroid/content/res/XmlBlock$Parser;->getName()Ljava/lang/String;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
HSPLandroid/content/res/XmlBlock$Parser;->getPooledString(I)Ljava/lang/CharSequence;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
HSPLandroid/content/res/XmlBlock$Parser;->getPositionDescription()Ljava/lang/String;
-HSPLandroid/content/res/XmlBlock$Parser;->getSequenceString(Ljava/lang/CharSequence;)Ljava/lang/String;+]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->getSequenceString(Ljava/lang/CharSequence;)Ljava/lang/String;
HSPLandroid/content/res/XmlBlock$Parser;->getSourceResId()I
HSPLandroid/content/res/XmlBlock$Parser;->getText()Ljava/lang/String;
HSPLandroid/content/res/XmlBlock$Parser;->isEmptyElementTag()Z
-HSPLandroid/content/res/XmlBlock$Parser;->next()I+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/XmlBlock$Parser;->next()I+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Landroid/content/res/Validator;Landroid/content/res/Validator;
HSPLandroid/content/res/XmlBlock$Parser;->nextTag()I
HSPLandroid/content/res/XmlBlock$Parser;->nextText()Ljava/lang/String;
-HSPLandroid/content/res/XmlBlock$Parser;->require(ILjava/lang/String;Ljava/lang/String;)V+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->require(ILjava/lang/String;Ljava/lang/String;)V
HSPLandroid/content/res/XmlBlock;->-$$Nest$fgetmOpenCount(Landroid/content/res/XmlBlock;)I
HSPLandroid/content/res/XmlBlock;->-$$Nest$fputmOpenCount(Landroid/content/res/XmlBlock;I)V
HSPLandroid/content/res/XmlBlock;->-$$Nest$smnativeGetAttributeCount(J)I
@@ -5366,7 +5392,7 @@ HSPLandroid/content/res/XmlBlock;->-$$Nest$smnativeGetLineNumber(J)I
HSPLandroid/content/res/XmlBlock;->-$$Nest$smnativeGetText(J)I
HSPLandroid/content/res/XmlBlock;-><init>(Landroid/content/res/AssetManager;J)V
HSPLandroid/content/res/XmlBlock;->close()V
-HSPLandroid/content/res/XmlBlock;->decOpenCountLocked()V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;]Ljava/lang/Object;Landroid/content/res/XmlBlock;
+HSPLandroid/content/res/XmlBlock;->decOpenCountLocked()V
HSPLandroid/content/res/XmlBlock;->finalize()V
HSPLandroid/content/res/XmlBlock;->newParser()Landroid/content/res/XmlResourceParser;
HSPLandroid/content/res/XmlBlock;->newParser(I)Landroid/content/res/XmlResourceParser;
@@ -5376,29 +5402,29 @@ HSPLandroid/content/type/DefaultMimeMapFactory;->lambda$create$0(Ljava/lang/Clas
HSPLandroid/content/type/DefaultMimeMapFactory;->parseTypes(Llibcore/content/type/MimeMap$Builder;Ljava/util/function/Function;Ljava/lang/String;)V
HSPLandroid/database/AbstractCursor$SelfContentObserver;-><init>(Landroid/database/AbstractCursor;)V
HSPLandroid/database/AbstractCursor$SelfContentObserver;->onChange(Z)V
-HSPLandroid/database/AbstractCursor;-><init>()V
-HSPLandroid/database/AbstractCursor;->checkPosition()V+]Landroid/database/AbstractCursor;Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/sqlite/SQLiteCursor;
-HSPLandroid/database/AbstractCursor;->close()V
+HSPLandroid/database/AbstractCursor;-><init>()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/AbstractCursor;->checkPosition()V+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
+HSPLandroid/database/AbstractCursor;->close()V+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/MatrixCursor;]Landroid/database/ContentObservable;Landroid/database/ContentObservable;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
HSPLandroid/database/AbstractCursor;->fillWindow(ILandroid/database/CursorWindow;)V
HSPLandroid/database/AbstractCursor;->finalize()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
-HSPLandroid/database/AbstractCursor;->getColumnCount()I
+HSPLandroid/database/AbstractCursor;->getColumnCount()I+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;
HSPLandroid/database/AbstractCursor;->getColumnIndex(Ljava/lang/String;)I
HSPLandroid/database/AbstractCursor;->getColumnIndexOrThrow(Ljava/lang/String;)I
-HSPLandroid/database/AbstractCursor;->getColumnName(I)Ljava/lang/String;
+HSPLandroid/database/AbstractCursor;->getColumnName(I)Ljava/lang/String;+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;
HSPLandroid/database/AbstractCursor;->getExtras()Landroid/os/Bundle;
HSPLandroid/database/AbstractCursor;->getPosition()I
HSPLandroid/database/AbstractCursor;->getWantsAllOnMoveCalls()Z
HSPLandroid/database/AbstractCursor;->getWindow()Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractCursor;->isAfterLast()Z
+HSPLandroid/database/AbstractCursor;->isAfterLast()Z+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/AbstractCursor;->isClosed()Z
HSPLandroid/database/AbstractCursor;->isLast()Z
HSPLandroid/database/AbstractCursor;->move(I)Z
HSPLandroid/database/AbstractCursor;->moveToFirst()Z
HSPLandroid/database/AbstractCursor;->moveToLast()Z
-HSPLandroid/database/AbstractCursor;->moveToNext()Z
-HSPLandroid/database/AbstractCursor;->moveToPosition(I)Z
+HSPLandroid/database/AbstractCursor;->moveToNext()Z+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/MatrixCursor;,Landroid/database/BulkCursorToCursorAdaptor;
+HSPLandroid/database/AbstractCursor;->moveToPosition(I)Z+]Landroid/database/AbstractCursor;missing_types
HSPLandroid/database/AbstractCursor;->onChange(Z)V
-HSPLandroid/database/AbstractCursor;->onDeactivateOrClose()V
+HSPLandroid/database/AbstractCursor;->onDeactivateOrClose()V+]Landroid/database/DataSetObservable;Landroid/database/DataSetObservable;
HSPLandroid/database/AbstractCursor;->onMove(II)Z
HSPLandroid/database/AbstractCursor;->registerContentObserver(Landroid/database/ContentObserver;)V
HSPLandroid/database/AbstractCursor;->registerDataSetObserver(Landroid/database/DataSetObserver;)V
@@ -5409,18 +5435,18 @@ HSPLandroid/database/AbstractCursor;->unregisterContentObserver(Landroid/databas
HSPLandroid/database/AbstractWindowedCursor;-><init>()V
HSPLandroid/database/AbstractWindowedCursor;->checkPosition()V
HSPLandroid/database/AbstractWindowedCursor;->clearOrCreateWindow(Ljava/lang/String;)V
-HSPLandroid/database/AbstractWindowedCursor;->closeWindow()V
+HSPLandroid/database/AbstractWindowedCursor;->closeWindow()V+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/AbstractWindowedCursor;->getBlob(I)[B
-HSPLandroid/database/AbstractWindowedCursor;->getDouble(I)D
+HSPLandroid/database/AbstractWindowedCursor;->getDouble(I)D+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/AbstractWindowedCursor;->getFloat(I)F
-HSPLandroid/database/AbstractWindowedCursor;->getInt(I)I+]Landroid/database/AbstractWindowedCursor;Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->getLong(I)J+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->getString(I)Ljava/lang/String;+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getInt(I)I+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getLong(I)J+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getString(I)Ljava/lang/String;+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/AbstractWindowedCursor;->getType(I)I
HSPLandroid/database/AbstractWindowedCursor;->getWindow()Landroid/database/CursorWindow;
HSPLandroid/database/AbstractWindowedCursor;->hasWindow()Z
HSPLandroid/database/AbstractWindowedCursor;->isNull(I)Z+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->onDeactivateOrClose()V
+HSPLandroid/database/AbstractWindowedCursor;->onDeactivateOrClose()V+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/AbstractWindowedCursor;->setWindow(Landroid/database/CursorWindow;)V
HSPLandroid/database/BulkCursorDescriptor$1;->createFromParcel(Landroid/os/Parcel;)Landroid/database/BulkCursorDescriptor;
HSPLandroid/database/BulkCursorDescriptor$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -5441,7 +5467,7 @@ HSPLandroid/database/BulkCursorToCursorAdaptor;->getColumnNames()[Ljava/lang/Str
HSPLandroid/database/BulkCursorToCursorAdaptor;->getCount()I
HSPLandroid/database/BulkCursorToCursorAdaptor;->getObserver()Landroid/database/IContentObserver;
HSPLandroid/database/BulkCursorToCursorAdaptor;->initialize(Landroid/database/BulkCursorDescriptor;)V
-HSPLandroid/database/BulkCursorToCursorAdaptor;->onMove(II)Z
+HSPLandroid/database/BulkCursorToCursorAdaptor;->onMove(II)Z+]Landroid/database/IBulkCursor;Landroid/database/BulkCursorProxy;]Landroid/database/BulkCursorToCursorAdaptor;Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/BulkCursorToCursorAdaptor;->throwIfCursorIsClosed()V
HSPLandroid/database/ContentObservable;-><init>()V
HSPLandroid/database/ContentObservable;->dispatchChange(ZLandroid/net/Uri;)V
@@ -5480,18 +5506,18 @@ HSPLandroid/database/CursorWindow$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/database/CursorWindow;-><init>(Landroid/os/Parcel;)V
HSPLandroid/database/CursorWindow;-><init>(Landroid/os/Parcel;Landroid/database/CursorWindow-IA;)V
HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;)V
-HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;J)V
+HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;J)V+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/database/CursorWindow;->allocRow()Z
HSPLandroid/database/CursorWindow;->clear()V
-HSPLandroid/database/CursorWindow;->dispose()V
-HSPLandroid/database/CursorWindow;->finalize()V
-HSPLandroid/database/CursorWindow;->getBlob(II)[B+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/CursorWindow;->dispose()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/CursorWindow;->finalize()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/CursorWindow;->getBlob(II)[B
HSPLandroid/database/CursorWindow;->getCursorWindowSize()I
-HSPLandroid/database/CursorWindow;->getDouble(II)D
+HSPLandroid/database/CursorWindow;->getDouble(II)D+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/CursorWindow;->getFloat(II)F
-HSPLandroid/database/CursorWindow;->getInt(II)I
+HSPLandroid/database/CursorWindow;->getInt(II)I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/CursorWindow;->getLong(II)J+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/CursorWindow;->getNumRows()I
+HSPLandroid/database/CursorWindow;->getNumRows()I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/CursorWindow;->getStartPosition()I
HSPLandroid/database/CursorWindow;->getString(II)Ljava/lang/String;+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/CursorWindow;->getType(II)I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
@@ -5513,16 +5539,16 @@ HSPLandroid/database/CursorWrapper;->getColumnName(I)Ljava/lang/String;
HSPLandroid/database/CursorWrapper;->getColumnNames()[Ljava/lang/String;
HSPLandroid/database/CursorWrapper;->getCount()I
HSPLandroid/database/CursorWrapper;->getExtras()Landroid/os/Bundle;
-HSPLandroid/database/CursorWrapper;->getInt(I)I
+HSPLandroid/database/CursorWrapper;->getInt(I)I+]Landroid/database/Cursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/content/ContentProviderClient$CursorWrapperInner;,Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/CursorWrapper;->getLong(I)J
HSPLandroid/database/CursorWrapper;->getPosition()I
HSPLandroid/database/CursorWrapper;->getString(I)Ljava/lang/String;
HSPLandroid/database/CursorWrapper;->getType(I)I
HSPLandroid/database/CursorWrapper;->getWrappedCursor()Landroid/database/Cursor;
-HSPLandroid/database/CursorWrapper;->isAfterLast()Z
+HSPLandroid/database/CursorWrapper;->isAfterLast()Z+]Landroid/database/Cursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/content/ContentProviderClient$CursorWrapperInner;,Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/CursorWrapper;->isClosed()Z
HSPLandroid/database/CursorWrapper;->isLast()Z
-HSPLandroid/database/CursorWrapper;->isNull(I)Z
+HSPLandroid/database/CursorWrapper;->isNull(I)Z+]Landroid/database/Cursor;Landroid/database/BulkCursorToCursorAdaptor;
HSPLandroid/database/CursorWrapper;->moveToFirst()Z
HSPLandroid/database/CursorWrapper;->moveToLast()Z
HSPLandroid/database/CursorWrapper;->moveToNext()Z
@@ -5530,9 +5556,9 @@ HSPLandroid/database/CursorWrapper;->moveToPosition(I)Z
HSPLandroid/database/CursorWrapper;->registerContentObserver(Landroid/database/ContentObserver;)V
HSPLandroid/database/DataSetObservable;-><init>()V
HSPLandroid/database/DataSetObservable;->notifyChanged()V
-HSPLandroid/database/DataSetObservable;->notifyInvalidated()V
+HSPLandroid/database/DataSetObservable;->notifyInvalidated()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/database/DataSetObserver;-><init>()V
-HSPLandroid/database/DatabaseUtils;->appendEscapedSQLString(Ljava/lang/StringBuilder;Ljava/lang/String;)V
+HSPLandroid/database/DatabaseUtils;->appendEscapedSQLString(Ljava/lang/StringBuilder;Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/database/DatabaseUtils;->categorizeStatement(Ljava/lang/String;Ljava/lang/String;)I+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/database/DatabaseUtils;->cursorFillWindow(Landroid/database/Cursor;ILandroid/database/CursorWindow;)V
HSPLandroid/database/DatabaseUtils;->getSqlStatementPrefixSimple(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
@@ -5587,16 +5613,16 @@ HSPLandroid/database/MergeCursor;->getString(I)Ljava/lang/String;
HSPLandroid/database/MergeCursor;->onMove(II)Z
HSPLandroid/database/Observable;-><init>()V
HSPLandroid/database/Observable;->registerObserver(Ljava/lang/Object;)V
-HSPLandroid/database/Observable;->unregisterAll()V
+HSPLandroid/database/Observable;->unregisterAll()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/database/Observable;->unregisterObserver(Ljava/lang/Object;)V
HSPLandroid/database/sqlite/FeatureFlagsImpl;-><init>()V
HSPLandroid/database/sqlite/FeatureFlagsImpl;->sqliteAllowTempTables()Z
HSPLandroid/database/sqlite/Flags;-><clinit>()V
-HSPLandroid/database/sqlite/Flags;->sqliteAllowTempTables()Z
+HSPLandroid/database/sqlite/Flags;->sqliteAllowTempTables()Z+]Landroid/database/sqlite/FeatureFlags;Landroid/database/sqlite/FeatureFlagsImpl;
HSPLandroid/database/sqlite/SQLiteClosable;-><init>()V
HSPLandroid/database/sqlite/SQLiteClosable;->acquireReference()V
-HSPLandroid/database/sqlite/SQLiteClosable;->close()V
-HSPLandroid/database/sqlite/SQLiteClosable;->releaseReference()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;,Landroid/database/sqlite/SQLiteStatement;
+HSPLandroid/database/sqlite/SQLiteClosable;->close()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteClosable;->releaseReference()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;
HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->getTruncateSize()J
HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->init(Ljava/lang/String;)V
HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->initIfNeeded()V
@@ -5610,7 +5636,7 @@ HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->beginOperation(Ljava
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->dump(Landroid/util/Printer;)V
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperation(I)V
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLog(I)Z
-HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLogLocked(I)Z
+HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLogLocked(I)Z+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->failOperation(ILjava/lang/Exception;)V
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->getOperationLocked(I)Landroid/database/sqlite/SQLiteConnection$Operation;
HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->newOperationCookieLocked(I)I
@@ -5626,38 +5652,38 @@ HSPLandroid/database/sqlite/SQLiteConnection$PreparedStatementCache;->getStateme
HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$fgetmConnectionPtr(Landroid/database/sqlite/SQLiteConnection;)J
HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$mfinalizePreparedStatement(Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$smnativePrepareStatement(JLjava/lang/String;)J
-HSPLandroid/database/sqlite/SQLiteConnection;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)V
+HSPLandroid/database/sqlite/SQLiteConnection;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
HSPLandroid/database/sqlite/SQLiteConnection;->acquirePreparedStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;
HSPLandroid/database/sqlite/SQLiteConnection;->acquirePreparedStatementLI(Ljava/lang/String;)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;+]Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
-HSPLandroid/database/sqlite/SQLiteConnection;->applyBlockGuardPolicy(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->attachCancellationSignal(Landroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->bindArguments(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;[Ljava/lang/Object;)V+]Ljava/lang/Number;Ljava/lang/Double;,Ljava/lang/Integer;,Ljava/lang/Long;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteConnection;->applyBlockGuardPolicy(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;]Ldalvik/system/BlockGuard$Policy;Ldalvik/system/BlockGuard$1;,Landroid/os/StrictMode$AndroidBlockGuardPolicy;
+HSPLandroid/database/sqlite/SQLiteConnection;->attachCancellationSignal(Landroid/os/CancellationSignal;)V+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
+HSPLandroid/database/sqlite/SQLiteConnection;->bindArguments(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;[Ljava/lang/Object;)V+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/Number;Ljava/lang/Integer;,Ljava/lang/Double;,Ljava/lang/Long;
HSPLandroid/database/sqlite/SQLiteConnection;->canonicalizeSyncMode(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteConnection;->checkDatabaseWiped()V
HSPLandroid/database/sqlite/SQLiteConnection;->close()V
HSPLandroid/database/sqlite/SQLiteConnection;->collectDbStats(Ljava/util/ArrayList;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->detachCancellationSignal(Landroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteConnection;->detachCancellationSignal(Landroid/os/CancellationSignal;)V+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
HSPLandroid/database/sqlite/SQLiteConnection;->dispose(Z)V
HSPLandroid/database/sqlite/SQLiteConnection;->dumpUnsafe(Landroid/util/Printer;Z)V
-HSPLandroid/database/sqlite/SQLiteConnection;->execute(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)I
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZLandroid/os/CancellationSignal;)I
+HSPLandroid/database/sqlite/SQLiteConnection;->execute(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZLandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
HSPLandroid/database/sqlite/SQLiteConnection;->executeForLastInsertedRowId(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForString(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForString(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)Ljava/lang/String;+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
HSPLandroid/database/sqlite/SQLiteConnection;->executePerConnectionSqlFromConfiguration(I)V
HSPLandroid/database/sqlite/SQLiteConnection;->finalize()V
HSPLandroid/database/sqlite/SQLiteConnection;->finalizePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
HSPLandroid/database/sqlite/SQLiteConnection;->getConnectionId()I
HSPLandroid/database/sqlite/SQLiteConnection;->getMainDbStatsUnsafe(IJJ)Landroid/database/sqlite/SQLiteDebug$DbStats;
HSPLandroid/database/sqlite/SQLiteConnection;->isCacheable(I)Z
-HSPLandroid/database/sqlite/SQLiteConnection;->isPreparedStatementInCache(Ljava/lang/String;)Z
+HSPLandroid/database/sqlite/SQLiteConnection;->isPreparedStatementInCache(Ljava/lang/String;)Z+]Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
HSPLandroid/database/sqlite/SQLiteConnection;->isPrimaryConnection()Z
HSPLandroid/database/sqlite/SQLiteConnection;->maybeTruncateWalFile()V
HSPLandroid/database/sqlite/SQLiteConnection;->obtainPreparedStatement(Ljava/lang/String;JIIZJ)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;
-HSPLandroid/database/sqlite/SQLiteConnection;->open()V
+HSPLandroid/database/sqlite/SQLiteConnection;->open()V+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
HSPLandroid/database/sqlite/SQLiteConnection;->open(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->prepare(Ljava/lang/String;Landroid/database/sqlite/SQLiteStatementInfo;)V
+HSPLandroid/database/sqlite/SQLiteConnection;->prepare(Ljava/lang/String;Landroid/database/sqlite/SQLiteStatementInfo;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
HSPLandroid/database/sqlite/SQLiteConnection;->reconfigure(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
HSPLandroid/database/sqlite/SQLiteConnection;->recyclePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
HSPLandroid/database/sqlite/SQLiteConnection;->releasePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
@@ -5682,6 +5708,7 @@ HSPLandroid/database/sqlite/SQLiteConnectionPool$IdleConnectionHandler;->connect
HSPLandroid/database/sqlite/SQLiteConnectionPool$IdleConnectionHandler;->handleMessage(Landroid/os/Message;)V
HSPLandroid/database/sqlite/SQLiteConnectionPool;-><init>(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->clearAcquiredConnectionsPreparedStatementCache()V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/Iterator;Ljava/util/WeakHashMap$KeyIterator;]Ljava/util/Set;Ljava/util/WeakHashMap$KeySet;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->close()V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->closeAvailableConnectionLocked(I)Z
HSPLandroid/database/sqlite/SQLiteConnectionPool;->closeAvailableConnectionsAndLogExceptionsLocked()V
@@ -5695,13 +5722,13 @@ HSPLandroid/database/sqlite/SQLiteConnectionPool;->discardAcquiredConnectionsLoc
HSPLandroid/database/sqlite/SQLiteConnectionPool;->dispose(Z)V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->dump(Landroid/util/Printer;ZLandroid/util/ArraySet;)V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->finalize()V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->finishAcquireConnectionLocked(Landroid/database/sqlite/SQLiteConnection;I)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->finishAcquireConnectionLocked(Landroid/database/sqlite/SQLiteConnection;I)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->getPath()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->getPriority(I)I
HSPLandroid/database/sqlite/SQLiteConnectionPool;->isSessionBlockingImportantConnectionWaitersLocked(ZI)Z
HSPLandroid/database/sqlite/SQLiteConnectionPool;->markAcquiredConnectionsLocked(Landroid/database/sqlite/SQLiteConnectionPool$AcquiredConnectionStatus;)V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->obtainConnectionWaiterLocked(Ljava/lang/Thread;JIZLjava/lang/String;I)Landroid/database/sqlite/SQLiteConnectionPool$ConnectionWaiter;
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->onStatementExecuted(J)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->onStatementExecuted(J)V+]Ljava/util/concurrent/atomic/AtomicLong;Ljava/util/concurrent/atomic/AtomicLong;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->open()V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->open(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)Landroid/database/sqlite/SQLiteConnectionPool;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->openConnectionLocked(Landroid/database/sqlite/SQLiteDatabaseConfiguration;Z)Landroid/database/sqlite/SQLiteConnection;
@@ -5709,23 +5736,23 @@ HSPLandroid/database/sqlite/SQLiteConnectionPool;->reconfigure(Landroid/database
HSPLandroid/database/sqlite/SQLiteConnectionPool;->reconfigureAllConnectionsLocked()V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->recycleConnectionLocked(Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnectionPool$AcquiredConnectionStatus;)Z
HSPLandroid/database/sqlite/SQLiteConnectionPool;->recycleConnectionWaiterLocked(Landroid/database/sqlite/SQLiteConnectionPool$ConnectionWaiter;)V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->releaseConnection(Landroid/database/sqlite/SQLiteConnection;)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->releaseConnection(Landroid/database/sqlite/SQLiteConnection;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->setMaxConnectionPoolSizeLocked()V
HSPLandroid/database/sqlite/SQLiteConnectionPool;->shouldYieldConnection(Landroid/database/sqlite/SQLiteConnection;I)Z
HSPLandroid/database/sqlite/SQLiteConnectionPool;->throwIfClosedLocked()V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquireNonPrimaryConnectionLocked(Ljava/lang/String;I)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquireNonPrimaryConnectionLocked(Ljava/lang/String;I)Landroid/database/sqlite/SQLiteConnection;+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquirePrimaryConnectionLocked(I)Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->waitForConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->waitForConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;+]Ljava/util/concurrent/atomic/AtomicBoolean;Ljava/util/concurrent/atomic/AtomicBoolean;
HSPLandroid/database/sqlite/SQLiteConnectionPool;->wakeConnectionWaitersLocked()V
HSPLandroid/database/sqlite/SQLiteConstraintException;-><init>(Ljava/lang/String;)V
-HSPLandroid/database/sqlite/SQLiteCursor;-><init>(Landroid/database/sqlite/SQLiteCursorDriver;Ljava/lang/String;Landroid/database/sqlite/SQLiteQuery;)V
-HSPLandroid/database/sqlite/SQLiteCursor;->close()V
-HSPLandroid/database/sqlite/SQLiteCursor;->fillWindow(I)V
+HSPLandroid/database/sqlite/SQLiteCursor;-><init>(Landroid/database/sqlite/SQLiteCursorDriver;Ljava/lang/String;Landroid/database/sqlite/SQLiteQuery;)V+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteCursor;->close()V+]Landroid/database/sqlite/SQLiteCursorDriver;Landroid/database/sqlite/SQLiteDirectCursorDriver;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteCursor;->fillWindow(I)V+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteCursor;->finalize()V
-HSPLandroid/database/sqlite/SQLiteCursor;->getColumnIndex(Ljava/lang/String;)I
+HSPLandroid/database/sqlite/SQLiteCursor;->getColumnIndex(Ljava/lang/String;)I+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/Map;Ljava/util/HashMap;
HSPLandroid/database/sqlite/SQLiteCursor;->getColumnNames()[Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteCursor;->getCount()I
-HSPLandroid/database/sqlite/SQLiteCursor;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteCursor;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
HSPLandroid/database/sqlite/SQLiteCursor;->onMove(II)Z+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
HSPLandroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;-><init>(Landroid/database/sqlite/SQLiteDatabase;)V
HSPLandroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;->get()Ljava/lang/Object;
@@ -5752,13 +5779,13 @@ HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->-$$Nest$fgetmOpenFlags(L
HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->-$$Nest$fgetmSyncMode(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;-><init>(ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V
HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;-><init>(ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$OpenParams-IA;)V
-HSPLandroid/database/sqlite/SQLiteDatabase;-><init>(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteDatabase;-><init>(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;
HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransaction()V
HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransaction(Landroid/database/sqlite/SQLiteTransactionListener;Z)V
HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransactionNonExclusive()V
HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransactionWithListener(Landroid/database/sqlite/SQLiteTransactionListener;)V
HSPLandroid/database/sqlite/SQLiteDatabase;->collectDbStats(Ljava/util/ArrayList;)V
-HSPLandroid/database/sqlite/SQLiteDatabase;->compileStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteStatement;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteDatabase;->compileStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteStatement;
HSPLandroid/database/sqlite/SQLiteDatabase;->createSession()Landroid/database/sqlite/SQLiteSession;
HSPLandroid/database/sqlite/SQLiteDatabase;->delete(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)I
HSPLandroid/database/sqlite/SQLiteDatabase;->deleteDatabase(Ljava/io/File;)Z
@@ -5773,7 +5800,7 @@ HSPLandroid/database/sqlite/SQLiteDatabase;->execSQL(Ljava/lang/String;)V
HSPLandroid/database/sqlite/SQLiteDatabase;->execSQL(Ljava/lang/String;[Ljava/lang/Object;)V
HSPLandroid/database/sqlite/SQLiteDatabase;->executeSql(Ljava/lang/String;[Ljava/lang/Object;)I
HSPLandroid/database/sqlite/SQLiteDatabase;->finalize()V
-HSPLandroid/database/sqlite/SQLiteDatabase;->findEditTable(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteDatabase;->findEditTable(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabase;->getActiveDatabasePools()Ljava/util/ArrayList;
HSPLandroid/database/sqlite/SQLiteDatabase;->getActiveDatabases()Ljava/util/ArrayList;
HSPLandroid/database/sqlite/SQLiteDatabase;->getFileTimestamps(Ljava/lang/String;)Ljava/lang/String;
@@ -5781,12 +5808,12 @@ HSPLandroid/database/sqlite/SQLiteDatabase;->getMaximumSize()J
HSPLandroid/database/sqlite/SQLiteDatabase;->getPageSize()J
HSPLandroid/database/sqlite/SQLiteDatabase;->getPath()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadDefaultConnectionFlags(Z)I
-HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadSession()Landroid/database/sqlite/SQLiteSession;
+HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadSession()Landroid/database/sqlite/SQLiteSession;+]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
HSPLandroid/database/sqlite/SQLiteDatabase;->getVersion()I
-HSPLandroid/database/sqlite/SQLiteDatabase;->inTransaction()Z
+HSPLandroid/database/sqlite/SQLiteDatabase;->inTransaction()Z+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteDatabase;->insert(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
HSPLandroid/database/sqlite/SQLiteDatabase;->insertOrThrow(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
-HSPLandroid/database/sqlite/SQLiteDatabase;->insertWithOnConflict(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;I)J+]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/database/sqlite/SQLiteDatabase;->insertWithOnConflict(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;I)J
HSPLandroid/database/sqlite/SQLiteDatabase;->isMainThread()Z
HSPLandroid/database/sqlite/SQLiteDatabase;->isOpen()Z
HSPLandroid/database/sqlite/SQLiteDatabase;->isReadOnly()Z
@@ -5804,11 +5831,11 @@ HSPLandroid/database/sqlite/SQLiteDatabase;->query(Ljava/lang/String;[Ljava/lang
HSPLandroid/database/sqlite/SQLiteDatabase;->query(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
HSPLandroid/database/sqlite/SQLiteDatabase;->query(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
HSPLandroid/database/sqlite/SQLiteDatabase;->query(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->queryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDatabase;->queryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteDatabase;->rawQuery(Ljava/lang/String;[Ljava/lang/String;)Landroid/database/Cursor;
HSPLandroid/database/sqlite/SQLiteDatabase;->rawQuery(Ljava/lang/String;[Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteCursorDriver;Landroid/database/sqlite/SQLiteDirectCursorDriver;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteDatabase;->releaseMemory()I
HSPLandroid/database/sqlite/SQLiteDatabase;->replace(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
HSPLandroid/database/sqlite/SQLiteDatabase;->replaceOrThrow(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
@@ -5816,26 +5843,26 @@ HSPLandroid/database/sqlite/SQLiteDatabase;->setForeignKeyConstraintsEnabled(Z)V
HSPLandroid/database/sqlite/SQLiteDatabase;->setTransactionSuccessful()V
HSPLandroid/database/sqlite/SQLiteDatabase;->throwIfNotOpenLocked()V
HSPLandroid/database/sqlite/SQLiteDatabase;->update(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
-HSPLandroid/database/sqlite/SQLiteDatabase;->updateWithOnConflict(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;I)I
+HSPLandroid/database/sqlite/SQLiteDatabase;->updateWithOnConflict(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;I)I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
HSPLandroid/database/sqlite/SQLiteDatabase;->validateSql(Ljava/lang/String;Landroid/os/CancellationSignal;)V
HSPLandroid/database/sqlite/SQLiteDatabase;->yieldIfContendedHelper(ZJ)Z
HSPLandroid/database/sqlite/SQLiteDatabase;->yieldIfContendedSafely(J)Z
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;-><init>(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;-><init>(Ljava/lang/String;I)V
-HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isInMemoryDb()Z
+HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isInMemoryDb()Z+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isLegacyCompatibilityWalEnabled()Z
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isReadOnlyDatabase()Z
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isWalEnabledInternal()Z
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->resolveJournalMode()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->resolveSyncMode()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->stripPathForLogs(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->updateParametersFrom(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
+HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->updateParametersFrom(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/database/sqlite/SQLiteDebug$NoPreloadHolder;-><clinit>()V
HSPLandroid/database/sqlite/SQLiteDebug;->getDatabaseInfo()Landroid/database/sqlite/SQLiteDebug$PagerStats;
HSPLandroid/database/sqlite/SQLiteDebug;->shouldLogSlowQuery(J)Z
HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)V
HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->cursorClosed()V
-HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->query(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;[Ljava/lang/String;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->query(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;[Ljava/lang/String;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
HSPLandroid/database/sqlite/SQLiteException;-><init>(Ljava/lang/String;)V
HSPLandroid/database/sqlite/SQLiteGlobal;->checkDbWipe()Z
HSPLandroid/database/sqlite/SQLiteGlobal;->getDefaultJournalMode()Ljava/lang/String;
@@ -5852,7 +5879,7 @@ HSPLandroid/database/sqlite/SQLiteOpenHelper;-><init>(Landroid/content/Context;L
HSPLandroid/database/sqlite/SQLiteOpenHelper;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$CursorFactory;IILandroid/database/DatabaseErrorHandler;)V
HSPLandroid/database/sqlite/SQLiteOpenHelper;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ILandroid/database/DatabaseErrorHandler;)V
HSPLandroid/database/sqlite/SQLiteOpenHelper;->close()V
-HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseLocked(Z)Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseLocked(Z)Landroid/database/sqlite/SQLiteDatabase;+]Ljava/io/File;Ljava/io/File;]Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseName()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteOpenHelper;->getReadableDatabase()Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteOpenHelper;->getWritableDatabase()Landroid/database/sqlite/SQLiteDatabase;
@@ -5862,9 +5889,9 @@ HSPLandroid/database/sqlite/SQLiteOpenHelper;->setFilePermissionsForDb(Ljava/lan
HSPLandroid/database/sqlite/SQLiteOpenHelper;->setIdleConnectionTimeout(J)V
HSPLandroid/database/sqlite/SQLiteOpenHelper;->setOpenParamsBuilder(Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;)V
HSPLandroid/database/sqlite/SQLiteOpenHelper;->setWriteAheadLoggingEnabled(Z)V
-HSPLandroid/database/sqlite/SQLiteProgram;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteProgram;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteProgram;->bind(ILjava/lang/Object;)V
-HSPLandroid/database/sqlite/SQLiteProgram;->bindAllArgsAsStrings([Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteProgram;->bindAllArgsAsStrings([Ljava/lang/String;)V+]Landroid/database/sqlite/SQLiteProgram;Landroid/database/sqlite/SQLiteQuery;,Landroid/database/sqlite/SQLiteStatement;
HSPLandroid/database/sqlite/SQLiteProgram;->bindBlob(I[B)V
HSPLandroid/database/sqlite/SQLiteProgram;->bindDouble(ID)V
HSPLandroid/database/sqlite/SQLiteProgram;->bindLong(IJ)V
@@ -5873,19 +5900,19 @@ HSPLandroid/database/sqlite/SQLiteProgram;->bindString(ILjava/lang/String;)V
HSPLandroid/database/sqlite/SQLiteProgram;->clearBindings()V
HSPLandroid/database/sqlite/SQLiteProgram;->getBindArgs()[Ljava/lang/Object;
HSPLandroid/database/sqlite/SQLiteProgram;->getColumnNames()[Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteProgram;->getConnectionFlags()I
+HSPLandroid/database/sqlite/SQLiteProgram;->getConnectionFlags()I+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteProgram;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;
-HSPLandroid/database/sqlite/SQLiteProgram;->getSession()Landroid/database/sqlite/SQLiteSession;
+HSPLandroid/database/sqlite/SQLiteProgram;->getSession()Landroid/database/sqlite/SQLiteSession;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
HSPLandroid/database/sqlite/SQLiteProgram;->getSql()Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteProgram;->onAllReferencesReleased()V
+HSPLandroid/database/sqlite/SQLiteProgram;->onAllReferencesReleased()V+]Landroid/database/sqlite/SQLiteProgram;Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteQuery;
HSPLandroid/database/sqlite/SQLiteQuery;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;Landroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteQuery;->fillWindow(Landroid/database/CursorWindow;IIZ)I
+HSPLandroid/database/sqlite/SQLiteQuery;->fillWindow(Landroid/database/CursorWindow;IIZ)I+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
HSPLandroid/database/sqlite/SQLiteQueryBuilder;-><init>()V
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendClause(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;)V
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendColumns(Ljava/lang/StringBuilder;[Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendClause(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendColumns(Ljava/lang/StringBuilder;[Ljava/lang/String;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendWhere(Ljava/lang/CharSequence;)V
HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQuery([Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQueryString(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQueryString(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeProjection([Ljava/lang/String;)[Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeSingleProjection(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeSingleProjectionOrThrow(Ljava/lang/String;)Ljava/lang/String;
@@ -5905,25 +5932,25 @@ HSPLandroid/database/sqlite/SQLiteQueryBuilder;->wrap(Ljava/lang/String;)Ljava/l
HSPLandroid/database/sqlite/SQLiteSession$Transaction;-><init>()V
HSPLandroid/database/sqlite/SQLiteSession$Transaction;-><init>(Landroid/database/sqlite/SQLiteSession$Transaction-IA;)V
HSPLandroid/database/sqlite/SQLiteSession;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;)V
-HSPLandroid/database/sqlite/SQLiteSession;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteSession;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
HSPLandroid/database/sqlite/SQLiteSession;->beginTransaction(ILandroid/database/sqlite/SQLiteTransactionListener;ILandroid/os/CancellationSignal;)V
HSPLandroid/database/sqlite/SQLiteSession;->beginTransactionUnchecked(ILandroid/database/sqlite/SQLiteTransactionListener;ILandroid/os/CancellationSignal;)V
HSPLandroid/database/sqlite/SQLiteSession;->closeOpenDependents()V+]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;
HSPLandroid/database/sqlite/SQLiteSession;->endTransaction(Landroid/os/CancellationSignal;)V
HSPLandroid/database/sqlite/SQLiteSession;->endTransactionUnchecked(Landroid/os/CancellationSignal;Z)V
-HSPLandroid/database/sqlite/SQLiteSession;->execute(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteSession;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)I
-HSPLandroid/database/sqlite/SQLiteSession;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZILandroid/os/CancellationSignal;)I
+HSPLandroid/database/sqlite/SQLiteSession;->execute(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteSession;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteSession;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZILandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
HSPLandroid/database/sqlite/SQLiteSession;->executeForLastInsertedRowId(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)J
HSPLandroid/database/sqlite/SQLiteSession;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)J
HSPLandroid/database/sqlite/SQLiteSession;->executeForString(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteSession;->executeSpecial(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Z
+HSPLandroid/database/sqlite/SQLiteSession;->executeSpecial(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Z+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
HSPLandroid/database/sqlite/SQLiteSession;->hasNestedTransaction()Z
HSPLandroid/database/sqlite/SQLiteSession;->hasTransaction()Z
HSPLandroid/database/sqlite/SQLiteSession;->obtainTransaction(ILandroid/database/sqlite/SQLiteTransactionListener;)Landroid/database/sqlite/SQLiteSession$Transaction;
-HSPLandroid/database/sqlite/SQLiteSession;->prepare(Ljava/lang/String;ILandroid/os/CancellationSignal;Landroid/database/sqlite/SQLiteStatementInfo;)V
+HSPLandroid/database/sqlite/SQLiteSession;->prepare(Ljava/lang/String;ILandroid/os/CancellationSignal;Landroid/database/sqlite/SQLiteStatementInfo;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
HSPLandroid/database/sqlite/SQLiteSession;->recycleTransaction(Landroid/database/sqlite/SQLiteSession$Transaction;)V
-HSPLandroid/database/sqlite/SQLiteSession;->releaseConnection()V
+HSPLandroid/database/sqlite/SQLiteSession;->releaseConnection()V+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
HSPLandroid/database/sqlite/SQLiteSession;->setTransactionSuccessful()V
HSPLandroid/database/sqlite/SQLiteSession;->throwIfNestedTransaction()V
HSPLandroid/database/sqlite/SQLiteSession;->throwIfNoTransaction()V
@@ -5933,7 +5960,7 @@ HSPLandroid/database/sqlite/SQLiteSession;->yieldTransactionUnchecked(JLandroid/
HSPLandroid/database/sqlite/SQLiteStatement;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;)V
HSPLandroid/database/sqlite/SQLiteStatement;->execute()V+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;
HSPLandroid/database/sqlite/SQLiteStatement;->executeInsert()J
-HSPLandroid/database/sqlite/SQLiteStatement;->executeUpdateDelete()I
+HSPLandroid/database/sqlite/SQLiteStatement;->executeUpdateDelete()I+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;
HSPLandroid/database/sqlite/SQLiteStatement;->simpleQueryForLong()J
HSPLandroid/database/sqlite/SQLiteStatement;->simpleQueryForString()Ljava/lang/String;
HSPLandroid/database/sqlite/SQLiteStatementInfo;-><init>()V
@@ -5968,33 +5995,33 @@ HSPLandroid/graphics/BaseCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/g
HSPLandroid/graphics/BaseCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Rect;Landroid/graphics/RectF;Landroid/graphics/Paint;)V
HSPLandroid/graphics/BaseCanvas;->drawColor(I)V
HSPLandroid/graphics/BaseCanvas;->drawLine(FFFFLandroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/BaseCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V
HSPLandroid/graphics/BaseCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V
HSPLandroid/graphics/BaseCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V
HSPLandroid/graphics/BaseCanvas;->throwIfCannotDraw(Landroid/graphics/Bitmap;)V
-HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Paint;)V+]Landroid/graphics/BaseCanvas;Landroid/graphics/Canvas;
+HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Paint;)V
HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Shader;)V
HSPLandroid/graphics/BaseCanvas;->throwIfHwBitmapInSwMode(Landroid/graphics/Bitmap;)V
HSPLandroid/graphics/BaseRecordingCanvas;-><init>(J)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawArc(Landroid/graphics/RectF;FFZLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawArc(Landroid/graphics/RectF;FFZLandroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/graphics/BaseRecordingCanvas;->drawBitmap(Landroid/graphics/Bitmap;FFLandroid/graphics/Paint;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawCircle(FFFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawCircle(FFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
HSPLandroid/graphics/BaseRecordingCanvas;->drawColor(I)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawColor(ILandroid/graphics/PorterDuff$Mode;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawLine(FFFFLandroid/graphics/Paint;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawOval(FFFFLandroid/graphics/Paint;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawOval(Landroid/graphics/RectF;Landroid/graphics/Paint;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawPatch(Landroid/graphics/NinePatch;Landroid/graphics/Rect;Landroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;missing_types]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/BaseRecordingCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/Path;Landroid/graphics/Path;
HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(FFFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/Rect;Landroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/RectF;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
+HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/RectF;Landroid/graphics/Paint;)V
HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(FFFFFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/Layout$Ellipsizer;
HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/String;FFLandroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun([CIIIIFFZLandroid/graphics/Paint;)V
HSPLandroid/graphics/Bitmap$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Bitmap;
HSPLandroid/graphics/Bitmap$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -6075,7 +6102,7 @@ HSPLandroid/graphics/BitmapShader;-><init>(Landroid/graphics/Bitmap;II)V
HSPLandroid/graphics/BitmapShader;-><init>(Landroid/graphics/Bitmap;Landroid/graphics/Shader$TileMode;Landroid/graphics/Shader$TileMode;)V
HSPLandroid/graphics/BitmapShader;->createNativeInstance(JZ)J
HSPLandroid/graphics/BitmapShader;->shouldDiscardNativeInstance(Z)Z
-HSPLandroid/graphics/BlendMode;->blendModeToPorterDuffMode(Landroid/graphics/BlendMode;)Landroid/graphics/PorterDuff$Mode;+]Landroid/graphics/BlendMode;Landroid/graphics/BlendMode;
+HSPLandroid/graphics/BlendMode;->blendModeToPorterDuffMode(Landroid/graphics/BlendMode;)Landroid/graphics/PorterDuff$Mode;
HSPLandroid/graphics/BlendMode;->fromValue(I)Landroid/graphics/BlendMode;
HSPLandroid/graphics/BlendMode;->getXfermode()Landroid/graphics/Xfermode;
HSPLandroid/graphics/BlendMode;->toValue(Landroid/graphics/BlendMode;)I
@@ -6139,8 +6166,8 @@ HSPLandroid/graphics/Canvas;->rotate(FFF)V
HSPLandroid/graphics/Canvas;->save()I
HSPLandroid/graphics/Canvas;->save(I)I
HSPLandroid/graphics/Canvas;->saveLayer(FFFFLandroid/graphics/Paint;I)I
-HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;)I+]Landroid/graphics/Canvas;Landroid/graphics/Canvas;,Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;I)I+]Landroid/graphics/Canvas;Landroid/graphics/Canvas;,Landroid/graphics/RecordingCanvas;
+HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;)I
+HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;I)I
HSPLandroid/graphics/Canvas;->saveLayerAlpha(FFFFI)I
HSPLandroid/graphics/Canvas;->saveLayerAlpha(FFFFII)I
HSPLandroid/graphics/Canvas;->saveUnclippedLayer(IIII)I
@@ -6173,7 +6200,7 @@ HSPLandroid/graphics/Color;->green()F
HSPLandroid/graphics/Color;->green(I)I
HSPLandroid/graphics/Color;->green(J)F
HSPLandroid/graphics/Color;->luminance()F
-HSPLandroid/graphics/Color;->pack(FFFFLandroid/graphics/ColorSpace;)J+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;
+HSPLandroid/graphics/Color;->pack(FFFFLandroid/graphics/ColorSpace;)J
HSPLandroid/graphics/Color;->pack(I)J
HSPLandroid/graphics/Color;->parseColor(Ljava/lang/String;)I
HSPLandroid/graphics/Color;->red()F
@@ -6299,8 +6326,8 @@ HSPLandroid/graphics/HardwareRendererObserver$$ExternalSyntheticLambda0;-><init>
HSPLandroid/graphics/HardwareRendererObserver$$ExternalSyntheticLambda0;->run()V
HSPLandroid/graphics/HardwareRendererObserver;-><init>(Landroid/graphics/HardwareRendererObserver$OnFrameMetricsAvailableListener;[JLandroid/os/Handler;Z)V
HSPLandroid/graphics/HardwareRendererObserver;->getNativeInstance()J
-HSPLandroid/graphics/HardwareRendererObserver;->invokeDataAvailable(Ljava/lang/ref/WeakReference;)Z
-HSPLandroid/graphics/HardwareRendererObserver;->notifyDataAvailable()V
+HSPLandroid/graphics/HardwareRendererObserver;->invokeDataAvailable(Ljava/lang/ref/WeakReference;)Z+]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/graphics/HardwareRendererObserver;->notifyDataAvailable()V+]Landroid/os/Handler;Landroid/os/Handler;,Landroid/view/ViewRootImpl$ViewRootHandler;
HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;-><init>(Landroid/content/res/AssetManager$AssetInputStream;Landroid/content/res/Resources;Landroid/util/TypedValue;)V
HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;->createImageDecoder(Z)Landroid/graphics/ImageDecoder;
HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;->getDensity()I
@@ -6365,18 +6392,18 @@ HSPLandroid/graphics/LeakyTypefaceStorage;->writeTypefaceToParcel(Landroid/graph
HSPLandroid/graphics/LinearGradient;-><init>(FFFFIILandroid/graphics/Shader$TileMode;)V
HSPLandroid/graphics/LinearGradient;-><init>(FFFFJJLandroid/graphics/Shader$TileMode;)V
HSPLandroid/graphics/LinearGradient;-><init>(FFFF[I[FLandroid/graphics/Shader$TileMode;)V
-HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;)V
+HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;)V+][J[J
HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;Landroid/graphics/ColorSpace;)V
-HSPLandroid/graphics/LinearGradient;->createNativeInstance(JZ)J+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;]Landroid/graphics/LinearGradient;Landroid/graphics/LinearGradient;
+HSPLandroid/graphics/LinearGradient;->createNativeInstance(JZ)J
HSPLandroid/graphics/MaskFilter;->finalize()V
HSPLandroid/graphics/Matrix;-><init>()V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/graphics/Matrix;-><init>(Landroid/graphics/Matrix;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Matrix;-><init>(Landroid/graphics/Matrix;)V
HSPLandroid/graphics/Matrix;->checkPointArrays([FI[FII)V
HSPLandroid/graphics/Matrix;->equals(Ljava/lang/Object;)Z
HSPLandroid/graphics/Matrix;->getValues([F)V
HSPLandroid/graphics/Matrix;->invert(Landroid/graphics/Matrix;)Z
HSPLandroid/graphics/Matrix;->isIdentity()Z
-HSPLandroid/graphics/Matrix;->mapPoints([F)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/graphics/Matrix;->mapPoints([F)V
HSPLandroid/graphics/Matrix;->mapPoints([FI[FII)V
HSPLandroid/graphics/Matrix;->mapRect(Landroid/graphics/RectF;)Z+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
HSPLandroid/graphics/Matrix;->mapRect(Landroid/graphics/RectF;Landroid/graphics/RectF;)Z
@@ -6414,18 +6441,18 @@ HSPLandroid/graphics/Outline;-><init>()V
HSPLandroid/graphics/Outline;->isEmpty()Z
HSPLandroid/graphics/Outline;->setAlpha(F)V
HSPLandroid/graphics/Outline;->setConvexPath(Landroid/graphics/Path;)V
-HSPLandroid/graphics/Outline;->setEmpty()V+]Landroid/graphics/Path;Landroid/graphics/Path;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/Outline;->setEmpty()V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/graphics/Outline;->setOval(IIII)V
HSPLandroid/graphics/Outline;->setOval(Landroid/graphics/Rect;)V
HSPLandroid/graphics/Outline;->setPath(Landroid/graphics/Path;)V
-HSPLandroid/graphics/Outline;->setRect(IIII)V
+HSPLandroid/graphics/Outline;->setRect(IIII)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
HSPLandroid/graphics/Outline;->setRect(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/Outline;->setRoundRect(IIIIF)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/graphics/Outline;->setRoundRect(Landroid/graphics/Rect;F)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
+HSPLandroid/graphics/Outline;->setRoundRect(IIIIF)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/Outline;Landroid/graphics/Outline;
+HSPLandroid/graphics/Outline;->setRoundRect(Landroid/graphics/Rect;F)V
HSPLandroid/graphics/Paint$FontMetrics;-><init>()V
HSPLandroid/graphics/Paint$FontMetricsInt;-><init>()V
HSPLandroid/graphics/Paint;-><init>()V
-HSPLandroid/graphics/Paint;-><init>(I)V+]Landroid/graphics/Paint;missing_types]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Paint;-><init>(I)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;,Landroid/text/TextPaint;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
HSPLandroid/graphics/Paint;-><init>(Landroid/graphics/Paint;)V
HSPLandroid/graphics/Paint;->ascent()F
HSPLandroid/graphics/Paint;->descent()F
@@ -6437,17 +6464,18 @@ HSPLandroid/graphics/Paint;->getFlags()I
HSPLandroid/graphics/Paint;->getFontFeatureSettings()Ljava/lang/String;
HSPLandroid/graphics/Paint;->getFontMetrics()Landroid/graphics/Paint$FontMetrics;
HSPLandroid/graphics/Paint;->getFontMetrics(Landroid/graphics/Paint$FontMetrics;)F
-HSPLandroid/graphics/Paint;->getFontMetricsInt()Landroid/graphics/Paint$FontMetricsInt;
+HSPLandroid/graphics/Paint;->getFontMetricsInt()Landroid/graphics/Paint$FontMetricsInt;+]Landroid/graphics/Paint;Landroid/text/TextPaint;
HSPLandroid/graphics/Paint;->getFontMetricsInt(Landroid/graphics/Paint$FontMetricsInt;)I
-HSPLandroid/graphics/Paint;->getFontMetricsInt(Ljava/lang/CharSequence;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V+]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/graphics/Paint;->getFontMetricsInt(Ljava/lang/CharSequence;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V
HSPLandroid/graphics/Paint;->getFontVariationSettings()Ljava/lang/String;
HSPLandroid/graphics/Paint;->getHinting()I
HSPLandroid/graphics/Paint;->getLetterSpacing()F
HSPLandroid/graphics/Paint;->getMaskFilter()Landroid/graphics/MaskFilter;
-HSPLandroid/graphics/Paint;->getNativeInstance()J+]Landroid/graphics/ColorFilter;Landroid/graphics/BlendModeColorFilter;,Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Paint;missing_types]Landroid/graphics/Shader;Landroid/graphics/BitmapShader;,Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;
+HSPLandroid/graphics/Paint;->getNativeInstance()J+]Landroid/graphics/ColorFilter;Landroid/graphics/PorterDuffColorFilter;,Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/Paint;missing_types]Landroid/graphics/Shader;Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;,Landroid/graphics/BitmapShader;,Landroid/graphics/RadialGradient;
HSPLandroid/graphics/Paint;->getRunAdvance(Ljava/lang/CharSequence;IIIIZI)F
HSPLandroid/graphics/Paint;->getRunAdvance([CIIIIZI)F
HSPLandroid/graphics/Paint;->getRunCharacterAdvance(Ljava/lang/CharSequence;IIIIZI[FI)F
+HSPLandroid/graphics/Paint;->getRunCharacterAdvance(Ljava/lang/CharSequence;IIIIZI[FILandroid/graphics/RectF;Landroid/graphics/Paint$RunInfo;)F+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;megamorphic_types
HSPLandroid/graphics/Paint;->getRunCharacterAdvance([CIIIIZI[FI)F
HSPLandroid/graphics/Paint;->getShader()Landroid/graphics/Shader;
HSPLandroid/graphics/Paint;->getShadowLayerColor()I
@@ -6461,7 +6489,7 @@ HSPLandroid/graphics/Paint;->getStrokeMiter()F
HSPLandroid/graphics/Paint;->getStrokeWidth()F
HSPLandroid/graphics/Paint;->getStyle()Landroid/graphics/Paint$Style;
HSPLandroid/graphics/Paint;->getTextAlign()Landroid/graphics/Paint$Align;
-HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/CharSequence;IILandroid/graphics/Rect;)V
+HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/CharSequence;IILandroid/graphics/Rect;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/String;IILandroid/graphics/Rect;)V
HSPLandroid/graphics/Paint;->getTextBounds([CIILandroid/graphics/Rect;)V
HSPLandroid/graphics/Paint;->getTextLocale()Ljava/util/Locale;
@@ -6507,7 +6535,7 @@ HSPLandroid/graphics/Paint;->setMaskFilter(Landroid/graphics/MaskFilter;)Landroi
HSPLandroid/graphics/Paint;->setPathEffect(Landroid/graphics/PathEffect;)Landroid/graphics/PathEffect;
HSPLandroid/graphics/Paint;->setShader(Landroid/graphics/Shader;)Landroid/graphics/Shader;
HSPLandroid/graphics/Paint;->setShadowLayer(FFFI)V
-HSPLandroid/graphics/Paint;->setShadowLayer(FFFJ)V+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;
+HSPLandroid/graphics/Paint;->setShadowLayer(FFFJ)V
HSPLandroid/graphics/Paint;->setStartHyphenEdit(I)V
HSPLandroid/graphics/Paint;->setStrokeCap(Landroid/graphics/Paint$Cap;)V
HSPLandroid/graphics/Paint;->setStrokeJoin(Landroid/graphics/Paint$Join;)V
@@ -6522,9 +6550,9 @@ HSPLandroid/graphics/Paint;->setTextSkewX(F)V
HSPLandroid/graphics/Paint;->setTypeface(Landroid/graphics/Typeface;)Landroid/graphics/Typeface;
HSPLandroid/graphics/Paint;->setUnderlineText(Z)V
HSPLandroid/graphics/Paint;->setXfermode(Landroid/graphics/Xfermode;)Landroid/graphics/Xfermode;
-HSPLandroid/graphics/Paint;->syncTextLocalesWithMinikin()V+]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/graphics/Paint;->syncTextLocalesWithMinikin()V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/os/LocaleList;Landroid/os/LocaleList;
HSPLandroid/graphics/PaintFlagsDrawFilter;-><init>(II)V
-HSPLandroid/graphics/Path;-><init>()V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Path;-><init>()V
HSPLandroid/graphics/Path;-><init>(Landroid/graphics/Path;)V
HSPLandroid/graphics/Path;->addArc(FFFFFF)V
HSPLandroid/graphics/Path;->addArc(Landroid/graphics/RectF;FF)V
@@ -6533,7 +6561,7 @@ HSPLandroid/graphics/Path;->addOval(FFFFLandroid/graphics/Path$Direction;)V
HSPLandroid/graphics/Path;->addOval(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V
HSPLandroid/graphics/Path;->addPath(Landroid/graphics/Path;Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
HSPLandroid/graphics/Path;->addRect(FFFFLandroid/graphics/Path$Direction;)V
-HSPLandroid/graphics/Path;->addRect(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/Path;->addRect(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V
HSPLandroid/graphics/Path;->addRoundRect(FFFFFFLandroid/graphics/Path$Direction;)V
HSPLandroid/graphics/Path;->addRoundRect(FFFF[FLandroid/graphics/Path$Direction;)V
HSPLandroid/graphics/Path;->addRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Path$Direction;)V
@@ -6551,8 +6579,8 @@ HSPLandroid/graphics/Path;->isEmpty()Z
HSPLandroid/graphics/Path;->lineTo(FF)V
HSPLandroid/graphics/Path;->moveTo(FF)V
HSPLandroid/graphics/Path;->offset(FF)V
-HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z+]Landroid/graphics/Path;Landroid/graphics/Path;
-HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z+]Landroid/graphics/Path$Op;Landroid/graphics/Path$Op;
+HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z
+HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z
HSPLandroid/graphics/Path;->rLineTo(FF)V
HSPLandroid/graphics/Path;->readOnlyNI()J
HSPLandroid/graphics/Path;->reset()V+]Landroid/graphics/Path;Landroid/graphics/Path;
@@ -6592,7 +6620,7 @@ HSPLandroid/graphics/Point;->toString()Ljava/lang/String;
HSPLandroid/graphics/PointF;-><init>()V
HSPLandroid/graphics/PointF;-><init>(FF)V
HSPLandroid/graphics/PointF;->equals(FF)Z
-HSPLandroid/graphics/PointF;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Landroid/graphics/PointF;
+HSPLandroid/graphics/PointF;->equals(Ljava/lang/Object;)Z
HSPLandroid/graphics/PointF;->length()F
HSPLandroid/graphics/PointF;->length(FF)F
HSPLandroid/graphics/PointF;->set(FF)V
@@ -6619,8 +6647,8 @@ HSPLandroid/graphics/RecordingCanvas;->isHardwareAccelerated()Z
HSPLandroid/graphics/RecordingCanvas;->obtain(Landroid/graphics/RenderNode;II)Landroid/graphics/RecordingCanvas;+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
HSPLandroid/graphics/RecordingCanvas;->recycle()V+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
HSPLandroid/graphics/RecordingCanvas;->throwIfCannotDraw(Landroid/graphics/Bitmap;)V
-HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/graphics/Rect$1;Landroid/graphics/Rect$1;
+HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Rect;
+HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/graphics/Rect$1;->newArray(I)[Landroid/graphics/Rect;
HSPLandroid/graphics/Rect$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/graphics/Rect;-><init>()V
@@ -6647,7 +6675,7 @@ HSPLandroid/graphics/Rect;->isEmpty()Z
HSPLandroid/graphics/Rect;->isValid()Z
HSPLandroid/graphics/Rect;->offset(II)V
HSPLandroid/graphics/Rect;->offsetTo(II)V
-HSPLandroid/graphics/Rect;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/graphics/Rect;->readFromParcel(Landroid/os/Parcel;)V
HSPLandroid/graphics/Rect;->scale(F)V
HSPLandroid/graphics/Rect;->set(IIII)V
HSPLandroid/graphics/Rect;->set(Landroid/graphics/Rect;)V
@@ -6656,7 +6684,7 @@ HSPLandroid/graphics/Rect;->setIntersect(Landroid/graphics/Rect;Landroid/graphic
HSPLandroid/graphics/Rect;->toShortString(Ljava/lang/StringBuilder;)Ljava/lang/String;
HSPLandroid/graphics/Rect;->toString()Ljava/lang/String;
HSPLandroid/graphics/Rect;->union(IIII)V
-HSPLandroid/graphics/Rect;->union(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/Rect;->union(Landroid/graphics/Rect;)V
HSPLandroid/graphics/Rect;->width()I
HSPLandroid/graphics/Rect;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/graphics/RectF;-><init>()V
@@ -6710,7 +6738,7 @@ HSPLandroid/graphics/RenderNode$CompositePositionUpdateListener;->without(Landro
HSPLandroid/graphics/RenderNode$PositionUpdateListener;->callPositionChanged(Ljava/lang/ref/WeakReference;JIIII)Z
HSPLandroid/graphics/RenderNode$PositionUpdateListener;->callPositionLost(Ljava/lang/ref/WeakReference;J)Z
HSPLandroid/graphics/RenderNode;-><init>(J)V
-HSPLandroid/graphics/RenderNode;-><init>(Ljava/lang/String;Landroid/graphics/RenderNode$AnimationHost;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/RenderNode;-><init>(Ljava/lang/String;Landroid/graphics/RenderNode$AnimationHost;)V
HSPLandroid/graphics/RenderNode;->addPositionUpdateListener(Landroid/graphics/RenderNode$PositionUpdateListener;)V
HSPLandroid/graphics/RenderNode;->adopt(J)Landroid/graphics/RenderNode;
HSPLandroid/graphics/RenderNode;->beginRecording(II)Landroid/graphics/RecordingCanvas;
@@ -6720,7 +6748,7 @@ HSPLandroid/graphics/RenderNode;->discardDisplayList()V
HSPLandroid/graphics/RenderNode;->endRecording()V+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/graphics/RenderNode;->getClipToOutline()Z
HSPLandroid/graphics/RenderNode;->getElevation()F
-HSPLandroid/graphics/RenderNode;->getMatrix(Landroid/graphics/Matrix;)V
+HSPLandroid/graphics/RenderNode;->getMatrix(Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
HSPLandroid/graphics/RenderNode;->getPivotY()F
HSPLandroid/graphics/RenderNode;->getRotationX()F
HSPLandroid/graphics/RenderNode;->getRotationY()F
@@ -6737,7 +6765,7 @@ HSPLandroid/graphics/RenderNode;->offsetTopAndBottom(I)Z
HSPLandroid/graphics/RenderNode;->removePositionUpdateListener(Landroid/graphics/RenderNode$PositionUpdateListener;)V
HSPLandroid/graphics/RenderNode;->setAlpha(F)Z
HSPLandroid/graphics/RenderNode;->setAmbientShadowColor(I)Z
-HSPLandroid/graphics/RenderNode;->setAnimationMatrix(Landroid/graphics/Matrix;)Z+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/graphics/RenderNode;->setAnimationMatrix(Landroid/graphics/Matrix;)Z
HSPLandroid/graphics/RenderNode;->setClipToBounds(Z)Z
HSPLandroid/graphics/RenderNode;->setClipToOutline(Z)Z
HSPLandroid/graphics/RenderNode;->setElevation(F)Z
@@ -6774,7 +6802,7 @@ HSPLandroid/graphics/Shader;->detectColorSpace([J)Landroid/graphics/ColorSpace;
HSPLandroid/graphics/Shader;->discardNativeInstance()V
HSPLandroid/graphics/Shader;->discardNativeInstanceLocked()V
HSPLandroid/graphics/Shader;->getNativeInstance()J
-HSPLandroid/graphics/Shader;->getNativeInstance(Z)J+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Shader;Landroid/graphics/BitmapShader;,Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Shader;->getNativeInstance(Z)J
HSPLandroid/graphics/Shader;->setLocalMatrix(Landroid/graphics/Matrix;)V
HSPLandroid/graphics/Shader;->shouldDiscardNativeInstance(Z)Z
HSPLandroid/graphics/SurfaceTexture$1;->handleMessage(Landroid/os/Message;)V
@@ -6792,7 +6820,7 @@ HSPLandroid/graphics/TextureLayer;-><init>(Landroid/graphics/HardwareRenderer;J)
HSPLandroid/graphics/TextureLayer;->close()V
HSPLandroid/graphics/TextureLayer;->detachSurfaceTexture()V
HSPLandroid/graphics/Typeface$Builder;->build()Landroid/graphics/Typeface;
-HSPLandroid/graphics/Typeface$Builder;->createAssetUid(Landroid/content/res/AssetManager;Ljava/lang/String;I[Landroid/graphics/fonts/FontVariationAxis;IILjava/lang/String;)Ljava/lang/String;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/graphics/Typeface$Builder;->createAssetUid(Landroid/content/res/AssetManager;Ljava/lang/String;I[Landroid/graphics/fonts/FontVariationAxis;IILjava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
HSPLandroid/graphics/Typeface$CustomFallbackBuilder;-><init>(Landroid/graphics/fonts/FontFamily;)V
HSPLandroid/graphics/Typeface$CustomFallbackBuilder;->build()Landroid/graphics/Typeface;
HSPLandroid/graphics/Typeface$CustomFallbackBuilder;->setStyle(Landroid/graphics/fonts/FontStyle;)Landroid/graphics/Typeface$CustomFallbackBuilder;
@@ -6806,9 +6834,9 @@ HSPLandroid/graphics/Typeface;->createWeightStyle(Landroid/graphics/Typeface;IZ)
HSPLandroid/graphics/Typeface;->defaultFromStyle(I)Landroid/graphics/Typeface;
HSPLandroid/graphics/Typeface;->deserializeFontMap(Ljava/nio/ByteBuffer;Ljava/util/Map;)[J
HSPLandroid/graphics/Typeface;->equals(Ljava/lang/Object;)Z
-HSPLandroid/graphics/Typeface;->findFromCache(Landroid/content/res/AssetManager;Ljava/lang/String;)Landroid/graphics/Typeface;+]Landroid/util/LruCache;Landroid/util/LruCache;
+HSPLandroid/graphics/Typeface;->findFromCache(Landroid/content/res/AssetManager;Ljava/lang/String;)Landroid/graphics/Typeface;
HSPLandroid/graphics/Typeface;->getStyle()I
-HSPLandroid/graphics/Typeface;->getSystemDefaultTypeface(Ljava/lang/String;)Landroid/graphics/Typeface;+]Ljava/util/Map;Landroid/util/ArrayMap;
+HSPLandroid/graphics/Typeface;->getSystemDefaultTypeface(Ljava/lang/String;)Landroid/graphics/Typeface;
HSPLandroid/graphics/Typeface;->getSystemFontFamilyName()Ljava/lang/String;
HSPLandroid/graphics/Typeface;->hasFontFamily(Ljava/lang/String;)Z
HSPLandroid/graphics/Typeface;->readString(Ljava/nio/ByteBuffer;)Ljava/lang/String;
@@ -6917,7 +6945,7 @@ HSPLandroid/graphics/drawable/AnimatedVectorDrawable$2;->onAnimationEnd(Landroid
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$2;->onAnimationStart(Landroid/animation/Animator;)V
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator;-><init>(IFLjava/lang/String;)V
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator;->newInstance(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;)Landroid/animation/Animator;
-HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;-><init>(Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;Landroid/graphics/drawable/Drawable$Callback;Landroid/content/res/Resources;)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;-><init>(Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;Landroid/graphics/drawable/Drawable$Callback;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->addPendingAnimator(IFLjava/lang/String;)V
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->addTargetAnimator(Ljava/lang/String;Landroid/animation/Animator;)V
HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->canApplyTheme()Z
@@ -7071,7 +7099,7 @@ HSPLandroid/graphics/drawable/ColorDrawable;-><init>(Landroid/graphics/drawable/
HSPLandroid/graphics/drawable/ColorDrawable;-><init>(Landroid/graphics/drawable/ColorDrawable$ColorState;Landroid/content/res/Resources;Landroid/graphics/drawable/ColorDrawable-IA;)V
HSPLandroid/graphics/drawable/ColorDrawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/ColorDrawable;->clearMutated()V
-HSPLandroid/graphics/drawable/ColorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;
+HSPLandroid/graphics/drawable/ColorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/graphics/drawable/ColorDrawable;->getAlpha()I
HSPLandroid/graphics/drawable/ColorDrawable;->getChangingConfigurations()I
HSPLandroid/graphics/drawable/ColorDrawable;->getColor()I
@@ -7086,7 +7114,7 @@ HSPLandroid/graphics/drawable/ColorDrawable;->setAlpha(I)V
HSPLandroid/graphics/drawable/ColorDrawable;->setColor(I)V
HSPLandroid/graphics/drawable/ColorDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
HSPLandroid/graphics/drawable/ColorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/graphics/drawable/ColorDrawable;->updateLocalState(Landroid/content/res/Resources;)V
+HSPLandroid/graphics/drawable/ColorDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;
HSPLandroid/graphics/drawable/ColorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/Drawable$ConstantState;-><init>()V
HSPLandroid/graphics/drawable/Drawable$ConstantState;->canApplyTheme()Z
@@ -7097,7 +7125,7 @@ HSPLandroid/graphics/drawable/Drawable;->applyTheme(Landroid/content/res/Resourc
HSPLandroid/graphics/drawable/Drawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/Drawable;->clearColorFilter()V
HSPLandroid/graphics/drawable/Drawable;->clearMutated()V
-HSPLandroid/graphics/drawable/Drawable;->copyBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/drawable/Drawable;->copyBounds(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/Drawable;->createFromXmlForDensity(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/Drawable;->createFromXmlInner(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/Drawable;->createFromXmlInnerForDensity(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
@@ -7113,7 +7141,7 @@ HSPLandroid/graphics/drawable/Drawable;->getIntrinsicWidth()I
HSPLandroid/graphics/drawable/Drawable;->getLayoutDirection()I
HSPLandroid/graphics/drawable/Drawable;->getLevel()I
HSPLandroid/graphics/drawable/Drawable;->getMinimumHeight()I+]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/graphics/drawable/Drawable;->getMinimumWidth()I+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/Drawable;->getMinimumWidth()I+]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/graphics/drawable/Drawable;->getOutline(Landroid/graphics/Outline;)V
HSPLandroid/graphics/drawable/Drawable;->getPadding(Landroid/graphics/Rect;)Z
HSPLandroid/graphics/drawable/Drawable;->getState()[I
@@ -7130,13 +7158,13 @@ HSPLandroid/graphics/drawable/Drawable;->onBoundsChange(Landroid/graphics/Rect;)
HSPLandroid/graphics/drawable/Drawable;->onLevelChange(I)Z
HSPLandroid/graphics/drawable/Drawable;->onStateChange([I)Z
HSPLandroid/graphics/drawable/Drawable;->parseBlendMode(ILandroid/graphics/BlendMode;)Landroid/graphics/BlendMode;
-HSPLandroid/graphics/drawable/Drawable;->resolveDensity(Landroid/content/res/Resources;I)I+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/graphics/drawable/Drawable;->resolveDensity(Landroid/content/res/Resources;I)I
HSPLandroid/graphics/drawable/Drawable;->resolveOpacity(II)I
HSPLandroid/graphics/drawable/Drawable;->scaleFromDensity(FII)F
HSPLandroid/graphics/drawable/Drawable;->scaleFromDensity(IIIZ)I
HSPLandroid/graphics/drawable/Drawable;->scheduleSelf(Ljava/lang/Runnable;J)V
HSPLandroid/graphics/drawable/Drawable;->setAutoMirrored(Z)V
-HSPLandroid/graphics/drawable/Drawable;->setBounds(IIII)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/Drawable;->setBounds(IIII)V
HSPLandroid/graphics/drawable/Drawable;->setBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/Drawable;megamorphic_types
HSPLandroid/graphics/drawable/Drawable;->setCallback(Landroid/graphics/drawable/Drawable$Callback;)V
HSPLandroid/graphics/drawable/Drawable;->setChangingConfigurations(I)V
@@ -7146,20 +7174,20 @@ HSPLandroid/graphics/drawable/Drawable;->setHotspot(FF)V
HSPLandroid/graphics/drawable/Drawable;->setLayoutDirection(I)Z
HSPLandroid/graphics/drawable/Drawable;->setLevel(I)Z
HSPLandroid/graphics/drawable/Drawable;->setSrcDensityOverride(I)V
-HSPLandroid/graphics/drawable/Drawable;->setState([I)Z+]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/graphics/drawable/Drawable;->setState([I)Z+]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/graphics/drawable/Drawable;->setTint(I)V
HSPLandroid/graphics/drawable/Drawable;->setTintList(Landroid/content/res/ColorStateList;)V
HSPLandroid/graphics/drawable/Drawable;->setTintMode(Landroid/graphics/PorterDuff$Mode;)V
-HSPLandroid/graphics/drawable/Drawable;->setVisible(ZZ)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/Drawable;->setVisible(ZZ)Z
HSPLandroid/graphics/drawable/Drawable;->unscheduleSelf(Ljava/lang/Runnable;)V
-HSPLandroid/graphics/drawable/Drawable;->updateBlendModeFilter(Landroid/graphics/BlendModeColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/BlendMode;)Landroid/graphics/BlendModeColorFilter;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BlendModeColorFilter;Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/ShapeDrawable;,Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/Drawable;->updateBlendModeFilter(Landroid/graphics/BlendModeColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/BlendMode;)Landroid/graphics/BlendModeColorFilter;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BlendModeColorFilter;Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/drawable/Drawable;megamorphic_types
HSPLandroid/graphics/drawable/Drawable;->updateTintFilter(Landroid/graphics/PorterDuffColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuffColorFilter;
HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;-><init>()V
HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;-><init>(Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback-IA;)V
HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->unwrap()Landroid/graphics/drawable/Drawable$Callback;
HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->wrap(Landroid/graphics/drawable/Drawable$Callback;)Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;
-HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;-><init>(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;Landroid/graphics/drawable/DrawableContainer;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;-><init>(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;Landroid/graphics/drawable/DrawableContainer;Landroid/content/res/Resources;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/graphics/drawable/Drawable;megamorphic_types
HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->addChild(Landroid/graphics/drawable/Drawable;)I
HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->canApplyTheme()Z
@@ -7202,11 +7230,11 @@ HSPLandroid/graphics/drawable/DrawableContainer;->getOpacity()I
HSPLandroid/graphics/drawable/DrawableContainer;->getOpticalInsets()Landroid/graphics/Insets;
HSPLandroid/graphics/drawable/DrawableContainer;->getOutline(Landroid/graphics/Outline;)V
HSPLandroid/graphics/drawable/DrawableContainer;->getPadding(Landroid/graphics/Rect;)Z
-HSPLandroid/graphics/drawable/DrawableContainer;->initializeDrawableForDisplay(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;]Landroid/graphics/drawable/DrawableContainer;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/StateListDrawable;,Lcom/android/internal/graphics/drawable/AnimationScaleListDrawable;
+HSPLandroid/graphics/drawable/DrawableContainer;->initializeDrawableForDisplay(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;]Landroid/graphics/drawable/DrawableContainer;Landroid/graphics/drawable/AnimatedStateListDrawable;,Lcom/android/internal/graphics/drawable/AnimationScaleListDrawable;,Landroid/graphics/drawable/StateListDrawable;]Landroid/graphics/drawable/Drawable;megamorphic_types
HSPLandroid/graphics/drawable/DrawableContainer;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/DrawableContainer;->isAutoMirrored()Z
HSPLandroid/graphics/drawable/DrawableContainer;->isStateful()Z
-HSPLandroid/graphics/drawable/DrawableContainer;->jumpToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/DrawableContainer;->jumpToCurrentState()V
HSPLandroid/graphics/drawable/DrawableContainer;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/DrawableContainer;->needsMirroring()Z
HSPLandroid/graphics/drawable/DrawableContainer;->onBoundsChange(Landroid/graphics/Rect;)V
@@ -7240,27 +7268,27 @@ HSPLandroid/graphics/drawable/DrawableWrapper;->applyTheme(Landroid/content/res/
HSPLandroid/graphics/drawable/DrawableWrapper;->canApplyTheme()Z
HSPLandroid/graphics/drawable/DrawableWrapper;->clearMutated()V
HSPLandroid/graphics/drawable/DrawableWrapper;->draw(Landroid/graphics/Canvas;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->getChangingConfigurations()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;Landroid/graphics/drawable/InsetDrawable$InsetState;
+HSPLandroid/graphics/drawable/DrawableWrapper;->getChangingConfigurations()I
HSPLandroid/graphics/drawable/DrawableWrapper;->getColorFilter()Landroid/graphics/ColorFilter;
HSPLandroid/graphics/drawable/DrawableWrapper;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
HSPLandroid/graphics/drawable/DrawableWrapper;->getDrawable()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/DrawableWrapper;->getIntrinsicHeight()I
HSPLandroid/graphics/drawable/DrawableWrapper;->getIntrinsicWidth()I
HSPLandroid/graphics/drawable/DrawableWrapper;->getOpacity()I
-HSPLandroid/graphics/drawable/DrawableWrapper;->getPadding(Landroid/graphics/Rect;)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->getPadding(Landroid/graphics/Rect;)Z
HSPLandroid/graphics/drawable/DrawableWrapper;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/DrawableWrapper;->inflateChildDrawable(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable$Callback;Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/drawable/DrawableWrapper;Landroid/graphics/drawable/InsetDrawable;
+HSPLandroid/graphics/drawable/DrawableWrapper;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/DrawableWrapper;->isStateful()Z
HSPLandroid/graphics/drawable/DrawableWrapper;->jumpToCurrentState()V
HSPLandroid/graphics/drawable/DrawableWrapper;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/DrawableWrapper;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
HSPLandroid/graphics/drawable/DrawableWrapper;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/DrawableWrapper;->onLevelChange(I)Z
-HSPLandroid/graphics/drawable/DrawableWrapper;->onStateChange([I)Z+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->onStateChange([I)Z
HSPLandroid/graphics/drawable/DrawableWrapper;->setAlpha(I)V
HSPLandroid/graphics/drawable/DrawableWrapper;->setColorFilter(Landroid/graphics/ColorFilter;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->setDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->setDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/DrawableWrapper;->setHotspot(FF)V
HSPLandroid/graphics/drawable/DrawableWrapper;->setTintBlendMode(Landroid/graphics/BlendMode;)V
HSPLandroid/graphics/drawable/DrawableWrapper;->setTintList(Landroid/content/res/ColorStateList;)V
@@ -7269,7 +7297,7 @@ HSPLandroid/graphics/drawable/DrawableWrapper;->updateLocalState(Landroid/conten
HSPLandroid/graphics/drawable/DrawableWrapper;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->-$$Nest$mcomputeOpacity(Landroid/graphics/drawable/GradientDrawable$GradientState;)V
HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$GradientState;Landroid/content/res/Resources;)V
-HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$Orientation;[I)V
+HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$Orientation;[I)V+]Landroid/graphics/drawable/GradientDrawable$GradientState;Landroid/graphics/drawable/GradientDrawable$GradientState;
HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->applyDensityScaling(II)V
HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->canApplyTheme()Z
HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->computeOpacity()V
@@ -7290,8 +7318,8 @@ HSPLandroid/graphics/drawable/GradientDrawable;->applyTheme(Landroid/content/res
HSPLandroid/graphics/drawable/GradientDrawable;->applyThemeChildElements(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/GradientDrawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/GradientDrawable;->clearMutated()V
-HSPLandroid/graphics/drawable/GradientDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Paint;Landroid/graphics/Paint;
-HSPLandroid/graphics/drawable/GradientDrawable;->ensureValidRect()Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/GradientDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;,Landroid/graphics/Canvas;
+HSPLandroid/graphics/drawable/GradientDrawable;->ensureValidRect()Z
HSPLandroid/graphics/drawable/GradientDrawable;->getChangingConfigurations()I
HSPLandroid/graphics/drawable/GradientDrawable;->getColorFilter()Landroid/graphics/ColorFilter;
HSPLandroid/graphics/drawable/GradientDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
@@ -7311,7 +7339,7 @@ HSPLandroid/graphics/drawable/GradientDrawable;->mutate()Landroid/graphics/drawa
HSPLandroid/graphics/drawable/GradientDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/GradientDrawable;->onLevelChange(I)Z
HSPLandroid/graphics/drawable/GradientDrawable;->onStateChange([I)Z
-HSPLandroid/graphics/drawable/GradientDrawable;->setAlpha(I)V
+HSPLandroid/graphics/drawable/GradientDrawable;->setAlpha(I)V+]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
HSPLandroid/graphics/drawable/GradientDrawable;->setColor(I)V
HSPLandroid/graphics/drawable/GradientDrawable;->setColor(Landroid/content/res/ColorStateList;)V
HSPLandroid/graphics/drawable/GradientDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
@@ -7332,7 +7360,7 @@ HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawablePadding(L
HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableSize(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableSolid(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableStroke(Landroid/content/res/TypedArray;)V
-HSPLandroid/graphics/drawable/GradientDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/GradientDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/Paint;Landroid/graphics/Paint;
HSPLandroid/graphics/drawable/GradientDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/Icon$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/drawable/Icon;
HSPLandroid/graphics/drawable/Icon$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -7357,7 +7385,7 @@ HSPLandroid/graphics/drawable/Icon;->setBitmap(Landroid/graphics/Bitmap;)V
HSPLandroid/graphics/drawable/Icon;->setTint(I)Landroid/graphics/drawable/Icon;
HSPLandroid/graphics/drawable/Icon;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->-$$Nest$fputmThemeAttrs(Landroid/graphics/drawable/InsetDrawable$InsetState;[I)V
-HSPLandroid/graphics/drawable/InsetDrawable$InsetState;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable$InsetState;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;)V
HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->applyDensityScaling(II)V
HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->onDensityChanged(II)V
@@ -7373,19 +7401,19 @@ HSPLandroid/graphics/drawable/InsetDrawable;-><init>(Landroid/graphics/drawable/
HSPLandroid/graphics/drawable/InsetDrawable;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;Landroid/graphics/drawable/InsetDrawable-IA;)V
HSPLandroid/graphics/drawable/InsetDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/InsetDrawable;->getInset(Landroid/content/res/TypedArray;ILandroid/graphics/drawable/InsetDrawable$InsetValue;)Landroid/graphics/drawable/InsetDrawable$InsetValue;
-HSPLandroid/graphics/drawable/InsetDrawable;->getInsets(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;]Landroid/graphics/drawable/InsetDrawable;missing_types
-HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicHeight()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
-HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
+HSPLandroid/graphics/drawable/InsetDrawable;->getInsets(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/InsetDrawable;Landroid/graphics/drawable/InsetDrawable;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicHeight()I
+HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicWidth()I
HSPLandroid/graphics/drawable/InsetDrawable;->getOpacity()I
-HSPLandroid/graphics/drawable/InsetDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
+HSPLandroid/graphics/drawable/InsetDrawable;->getOutline(Landroid/graphics/Outline;)V
HSPLandroid/graphics/drawable/InsetDrawable;->getPadding(Landroid/graphics/Rect;)Z
HSPLandroid/graphics/drawable/InsetDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/InsetDrawable;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
-HSPLandroid/graphics/drawable/InsetDrawable;->onBoundsChange(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/InsetDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/InsetDrawable;->verifyRequiredAttributes(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(I)V
-HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/graphics/drawable/LayerDrawable;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/graphics/drawable/LayerDrawable;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;missing_types]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->applyDensityScaling(II)V
HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->setDensity(I)V
@@ -7405,11 +7433,11 @@ HSPLandroid/graphics/drawable/LayerDrawable$LayerState;->newDrawable(Landroid/co
HSPLandroid/graphics/drawable/LayerDrawable$LayerState;->onDensityChanged(II)V
HSPLandroid/graphics/drawable/LayerDrawable$LayerState;->setDensity(I)V
HSPLandroid/graphics/drawable/LayerDrawable;-><init>()V
-HSPLandroid/graphics/drawable/LayerDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/content/res/Resources;)V
HSPLandroid/graphics/drawable/LayerDrawable;-><init>([Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/LayerDrawable;-><init>([Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/LayerDrawable$LayerState;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/Drawable;[IIIIII)Landroid/graphics/drawable/LayerDrawable$ChildDrawable;+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;missing_types
-HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;)I+]Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/graphics/drawable/RippleDrawable$RippleState;
+HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/Drawable;[IIIIII)Landroid/graphics/drawable/LayerDrawable$ChildDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;)I
HSPLandroid/graphics/drawable/LayerDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/LayerDrawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/LayerDrawable;->clearMutated()V
@@ -7423,23 +7451,23 @@ HSPLandroid/graphics/drawable/LayerDrawable;->findIndexByLayerId(I)I
HSPLandroid/graphics/drawable/LayerDrawable;->getChangingConfigurations()I
HSPLandroid/graphics/drawable/LayerDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
HSPLandroid/graphics/drawable/LayerDrawable;->getDrawable(I)Landroid/graphics/drawable/Drawable;
-HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicHeight()I+]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicHeight()I
+HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicWidth()I
HSPLandroid/graphics/drawable/LayerDrawable;->getNumberOfLayers()I
HSPLandroid/graphics/drawable/LayerDrawable;->getOpacity()I
-HSPLandroid/graphics/drawable/LayerDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
-HSPLandroid/graphics/drawable/LayerDrawable;->getPadding(Landroid/graphics/Rect;)Z+]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->getOutline(Landroid/graphics/Outline;)V
+HSPLandroid/graphics/drawable/LayerDrawable;->getPadding(Landroid/graphics/Rect;)Z
HSPLandroid/graphics/drawable/LayerDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/LayerDrawable;->inflateLayers(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/graphics/drawable/LayerDrawable$LayerState;,Landroid/graphics/drawable/RippleDrawable$RippleState;]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/graphics/drawable/LayerDrawable;->isAutoMirrored()Z
HSPLandroid/graphics/drawable/LayerDrawable;->isProjected()Z
HSPLandroid/graphics/drawable/LayerDrawable;->isStateful()Z
-HSPLandroid/graphics/drawable/LayerDrawable;->jumpToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->jumpToCurrentState()V
HSPLandroid/graphics/drawable/LayerDrawable;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/LayerDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
-HSPLandroid/graphics/drawable/LayerDrawable;->refreshChildPadding(ILandroid/graphics/drawable/LayerDrawable$ChildDrawable;)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/LayerDrawable;->refreshChildPadding(ILandroid/graphics/drawable/LayerDrawable$ChildDrawable;)Z
HSPLandroid/graphics/drawable/LayerDrawable;->refreshPadding()V
HSPLandroid/graphics/drawable/LayerDrawable;->resolveGravity(IIIII)I
HSPLandroid/graphics/drawable/LayerDrawable;->resumeChildInvalidation()V
@@ -7455,10 +7483,10 @@ HSPLandroid/graphics/drawable/LayerDrawable;->setLayerInset(IIIII)V
HSPLandroid/graphics/drawable/LayerDrawable;->setPaddingMode(I)V
HSPLandroid/graphics/drawable/LayerDrawable;->setTintBlendMode(Landroid/graphics/BlendMode;)V
HSPLandroid/graphics/drawable/LayerDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->setVisible(ZZ)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->setVisible(ZZ)Z
HSPLandroid/graphics/drawable/LayerDrawable;->suspendChildInvalidation()V
HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBounds(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBoundsInternal(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBoundsInternal(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerFromTypedArray(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/LayerDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/NinePatchDrawable$$ExternalSyntheticLambda0;->onHeaderDecoded(Landroid/graphics/ImageDecoder;Landroid/graphics/ImageDecoder$ImageInfo;Landroid/graphics/ImageDecoder$Source;)V
@@ -7555,12 +7583,12 @@ HSPLandroid/graphics/drawable/RippleDrawable$RippleState;->newDrawable()Landroid
HSPLandroid/graphics/drawable/RippleDrawable$RippleState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/RippleDrawable$RippleState;->onDensityChanged(II)V
HSPLandroid/graphics/drawable/RippleDrawable;-><init>()V
-HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/content/res/ColorStateList;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/RippleDrawable;missing_types
-HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/content/res/ColorStateList;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;)V
HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;Landroid/graphics/drawable/RippleDrawable-IA;)V
HSPLandroid/graphics/drawable/RippleDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/RippleDrawable;->canApplyTheme()Z
-HSPLandroid/graphics/drawable/RippleDrawable;->cancelExitingRipples()V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->cancelExitingRipples()V
HSPLandroid/graphics/drawable/RippleDrawable;->clearHotspots()V
HSPLandroid/graphics/drawable/RippleDrawable;->computeRadius()F
HSPLandroid/graphics/drawable/RippleDrawable;->createAnimationProperties(FFFFFF)Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;
@@ -7569,27 +7597,27 @@ HSPLandroid/graphics/drawable/RippleDrawable;->createConstantState(Landroid/grap
HSPLandroid/graphics/drawable/RippleDrawable;->draw(Landroid/graphics/Canvas;)V
HSPLandroid/graphics/drawable/RippleDrawable;->drawBackgroundAndRipples(Landroid/graphics/Canvas;)V
HSPLandroid/graphics/drawable/RippleDrawable;->drawContent(Landroid/graphics/Canvas;)V
-HSPLandroid/graphics/drawable/RippleDrawable;->drawPatterned(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;]Landroid/graphics/drawable/RippleDrawable;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/RippleDrawable;->drawPatterned(Landroid/graphics/Canvas;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;
HSPLandroid/graphics/drawable/RippleDrawable;->drawPatternedBackground(Landroid/graphics/Canvas;FF)V
HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedAnimation()V
-HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedBackgroundAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedBackgroundAnimation()V
HSPLandroid/graphics/drawable/RippleDrawable;->getComputedRadius()I
HSPLandroid/graphics/drawable/RippleDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
-HSPLandroid/graphics/drawable/RippleDrawable;->getDirtyBounds()Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->getDirtyBounds()Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
HSPLandroid/graphics/drawable/RippleDrawable;->getMaskType()I
HSPLandroid/graphics/drawable/RippleDrawable;->getOpacity()I
HSPLandroid/graphics/drawable/RippleDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/StateListDrawable;
HSPLandroid/graphics/drawable/RippleDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf()V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf()V
HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf(Z)V
-HSPLandroid/graphics/drawable/RippleDrawable;->isBounded()Z+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->isBounded()Z
HSPLandroid/graphics/drawable/RippleDrawable;->isProjected()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
HSPLandroid/graphics/drawable/RippleDrawable;->isStateful()Z
HSPLandroid/graphics/drawable/RippleDrawable;->jumpToCurrentState()V
HSPLandroid/graphics/drawable/RippleDrawable;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/RippleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/RippleDrawable;->onHotspotBoundsChanged()V
-HSPLandroid/graphics/drawable/RippleDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->onStateChange([I)Z
HSPLandroid/graphics/drawable/RippleDrawable;->pruneRipples()V
HSPLandroid/graphics/drawable/RippleDrawable;->setBackgroundActive(ZZZZ)V
HSPLandroid/graphics/drawable/RippleDrawable;->setColor(Landroid/content/res/ColorStateList;)V
@@ -7598,11 +7626,11 @@ HSPLandroid/graphics/drawable/RippleDrawable;->setHotspotBounds(IIII)V
HSPLandroid/graphics/drawable/RippleDrawable;->setPaddingMode(I)V
HSPLandroid/graphics/drawable/RippleDrawable;->setRippleActive(Z)V
HSPLandroid/graphics/drawable/RippleDrawable;->setVisible(ZZ)Z
-HSPLandroid/graphics/drawable/RippleDrawable;->startBackgroundAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/graphics/drawable/RippleDrawable;->startBackgroundAnimation()V
HSPLandroid/graphics/drawable/RippleDrawable;->tryRippleEnter()V
HSPLandroid/graphics/drawable/RippleDrawable;->updateLocalState()V
HSPLandroid/graphics/drawable/RippleDrawable;->updateMaskShaderIfNeeded()V
-HSPLandroid/graphics/drawable/RippleDrawable;->updateRipplePaint()Landroid/graphics/Paint;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BitmapShader;Landroid/graphics/BitmapShader;]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/PorterDuffColorFilter;Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/drawable/RippleShader;Landroid/graphics/drawable/RippleShader;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/RippleDrawable;->updateRipplePaint()Landroid/graphics/Paint;
HSPLandroid/graphics/drawable/RippleDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/RippleDrawable;->verifyRequiredAttributes(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/RippleForeground$1;->onAnimationEnd(Landroid/animation/Animator;)V
@@ -7662,7 +7690,7 @@ HSPLandroid/graphics/drawable/ScaleDrawable;->draw(Landroid/graphics/Canvas;)V
HSPLandroid/graphics/drawable/ScaleDrawable;->getPercent(Landroid/content/res/TypedArray;IF)F
HSPLandroid/graphics/drawable/ScaleDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/ScaleDrawable;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
-HSPLandroid/graphics/drawable/ScaleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
+HSPLandroid/graphics/drawable/ScaleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/ScaleDrawable;Landroid/graphics/drawable/ScaleDrawable;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/StateListDrawable;
HSPLandroid/graphics/drawable/ScaleDrawable;->onLevelChange(I)Z
HSPLandroid/graphics/drawable/ScaleDrawable;->updateLocalState()V
HSPLandroid/graphics/drawable/ScaleDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
@@ -7680,7 +7708,7 @@ HSPLandroid/graphics/drawable/ShapeDrawable;->getOpacity()I
HSPLandroid/graphics/drawable/ShapeDrawable;->getOutline(Landroid/graphics/Outline;)V
HSPLandroid/graphics/drawable/ShapeDrawable;->getPadding(Landroid/graphics/Rect;)Z
HSPLandroid/graphics/drawable/ShapeDrawable;->getPaint()Landroid/graphics/Paint;
-HSPLandroid/graphics/drawable/ShapeDrawable;->isStateful()Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;
+HSPLandroid/graphics/drawable/ShapeDrawable;->isStateful()Z
HSPLandroid/graphics/drawable/ShapeDrawable;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/ShapeDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/graphics/drawable/ShapeDrawable;->onDraw(Landroid/graphics/drawable/shapes/Shape;Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
@@ -7690,7 +7718,7 @@ HSPLandroid/graphics/drawable/ShapeDrawable;->setIntrinsicWidth(I)V
HSPLandroid/graphics/drawable/ShapeDrawable;->setShape(Landroid/graphics/drawable/shapes/Shape;)V
HSPLandroid/graphics/drawable/ShapeDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
HSPLandroid/graphics/drawable/ShapeDrawable;->updateLocalState()V
-HSPLandroid/graphics/drawable/ShapeDrawable;->updateShape()V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/ShapeDrawable;Landroid/graphics/drawable/PaintDrawable;]Landroid/graphics/drawable/shapes/Shape;Landroid/graphics/drawable/shapes/OvalShape;,Landroid/graphics/drawable/shapes/RoundRectShape;
+HSPLandroid/graphics/drawable/ShapeDrawable;->updateShape()V
HSPLandroid/graphics/drawable/StateListDrawable$StateListState;-><init>(Landroid/graphics/drawable/StateListDrawable$StateListState;Landroid/graphics/drawable/StateListDrawable;Landroid/content/res/Resources;)V
HSPLandroid/graphics/drawable/StateListDrawable$StateListState;->addStateSet([ILandroid/graphics/drawable/Drawable;)I
HSPLandroid/graphics/drawable/StateListDrawable$StateListState;->canApplyTheme()Z
@@ -7739,23 +7767,23 @@ HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->getProperty(Ljava/lang/
HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->getPropertyIndex(Ljava/lang/String;)I
HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->inflate(Landroid/content/res/Resources;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->isStateful()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->onStateChange([I)Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;
-HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;,Landroid/content/res/GradientColor;]Landroid/content/res/GradientColor;Landroid/content/res/GradientColor;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/Shader;Landroid/graphics/LinearGradient;]Ljava/lang/String;Ljava/lang/String;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->-$$Nest$fgetmChangingConfigurations(Landroid/graphics/drawable/VectorDrawable$VGroup;)I
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->-$$Nest$fgetmNativePtr(Landroid/graphics/drawable/VectorDrawable$VGroup;)J
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>()V
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>(Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/util/ArrayMap;)V+]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->addChild(Landroid/graphics/drawable/VectorDrawable$VObject;)V+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>(Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->addChild(Landroid/graphics/drawable/VectorDrawable$VObject;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VGroup;,Landroid/graphics/drawable/VectorDrawable$VFullPath;
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->canApplyTheme()Z
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getGroupName()Ljava/lang/String;
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativePtr()J
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativeSize()I+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativeSize()I
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getProperty(Ljava/lang/String;)Landroid/util/Property;
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->inflate(Landroid/content/res/Resources;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->isStateful()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->onStateChange([I)Z+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setTree(Lcom/android/internal/util/VirtualRefBasePtr;)V+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setTree(Lcom/android/internal/util/VirtualRefBasePtr;)V
HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
HSPLandroid/graphics/drawable/VectorDrawable$VObject;-><init>()V
HSPLandroid/graphics/drawable/VectorDrawable$VObject;->isTreeValid()Z
@@ -7769,21 +7797,21 @@ HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;-><init>(Landro
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->applyDensityScaling(II)V
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->applyTheme(Landroid/content/res/Resources$Theme;)V
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canApplyTheme()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canReuseCache()Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canReuseCache()Z
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTree(Landroid/graphics/drawable/VectorDrawable$VGroup;)V
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTreeFromCopy(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VGroup;)V+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTreeFromCopy(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VGroup;)V
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->finalize()V
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getAlpha()F+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getAlpha()F
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getChangingConfigurations()I
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getNativeRenderer()J+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->isStateful()Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getNativeRenderer()J
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->isStateful()Z
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->newDrawable()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onStateChange([I)Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onTreeConstructionFinished()V+]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onTreeConstructionFinished()V+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setAlpha(F)Z
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setDensity(I)Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setViewportSize(FF)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setViewportSize(FF)V
HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->updateCacheStates()V
HSPLandroid/graphics/drawable/VectorDrawable;->-$$Nest$smnAddChild(JJ)V
HSPLandroid/graphics/drawable/VectorDrawable;->-$$Nest$smnCreateFullPath()J
@@ -7806,37 +7834,37 @@ HSPLandroid/graphics/drawable/VectorDrawable;->-$$Nest$smnUpdateGroupProperties(
HSPLandroid/graphics/drawable/VectorDrawable;-><init>()V
HSPLandroid/graphics/drawable/VectorDrawable;-><init>(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/content/res/Resources;)V
HSPLandroid/graphics/drawable/VectorDrawable;-><init>(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/content/res/Resources;Landroid/graphics/drawable/VectorDrawable-IA;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/graphics/drawable/VectorDrawable;->canApplyTheme()Z
HSPLandroid/graphics/drawable/VectorDrawable;->clearMutated()V
HSPLandroid/graphics/drawable/VectorDrawable;->computeVectorSize()V
-HSPLandroid/graphics/drawable/VectorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/ColorFilter;Landroid/graphics/BlendModeColorFilter;,Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
-HSPLandroid/graphics/drawable/VectorDrawable;->getAlpha()I+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->draw(Landroid/graphics/Canvas;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->getAlpha()I
HSPLandroid/graphics/drawable/VectorDrawable;->getChangingConfigurations()I
HSPLandroid/graphics/drawable/VectorDrawable;->getColorFilter()Landroid/graphics/ColorFilter;
HSPLandroid/graphics/drawable/VectorDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicHeight()I
-HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicWidth()I
HSPLandroid/graphics/drawable/VectorDrawable;->getNativeTree()J
HSPLandroid/graphics/drawable/VectorDrawable;->getOpacity()I
HSPLandroid/graphics/drawable/VectorDrawable;->getPixelSize()F
HSPLandroid/graphics/drawable/VectorDrawable;->getTargetByName(Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/graphics/drawable/VectorDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
-HSPLandroid/graphics/drawable/VectorDrawable;->inflateChildElements(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VClipPath;Landroid/graphics/drawable/VectorDrawable$VClipPath;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/Stack;Ljava/util/Stack;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/graphics/drawable/VectorDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
+HSPLandroid/graphics/drawable/VectorDrawable;->inflateChildElements(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/Stack;Ljava/util/Stack;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;
HSPLandroid/graphics/drawable/VectorDrawable;->isAutoMirrored()Z
-HSPLandroid/graphics/drawable/VectorDrawable;->isStateful()Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->isStateful()Z
HSPLandroid/graphics/drawable/VectorDrawable;->mutate()Landroid/graphics/drawable/Drawable;
HSPLandroid/graphics/drawable/VectorDrawable;->needMirroring()Z
-HSPLandroid/graphics/drawable/VectorDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->onStateChange([I)Z
HSPLandroid/graphics/drawable/VectorDrawable;->setAllowCaching(Z)V
HSPLandroid/graphics/drawable/VectorDrawable;->setAlpha(I)V
HSPLandroid/graphics/drawable/VectorDrawable;->setAutoMirrored(Z)V
HSPLandroid/graphics/drawable/VectorDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
HSPLandroid/graphics/drawable/VectorDrawable;->setTintBlendMode(Landroid/graphics/BlendMode;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
-HSPLandroid/graphics/drawable/VectorDrawable;->updateColorFilters(Landroid/graphics/BlendMode;Landroid/content/res/ColorStateList;)V+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->updateColorFilters(Landroid/graphics/BlendMode;Landroid/content/res/ColorStateList;)V
HSPLandroid/graphics/drawable/VectorDrawable;->updateLocalState(Landroid/content/res/Resources;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/graphics/drawable/shapes/OvalShape;-><init>()V
HSPLandroid/graphics/drawable/shapes/OvalShape;->draw(Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
HSPLandroid/graphics/drawable/shapes/OvalShape;->getOutline(Landroid/graphics/Outline;)V
@@ -7913,13 +7941,13 @@ HSPLandroid/graphics/text/LineBreaker;->computeLineBreaks(Landroid/graphics/text
HSPLandroid/graphics/text/MeasuredText$Builder;-><init>([C)V
HSPLandroid/graphics/text/MeasuredText$Builder;->appendReplacementRun(Landroid/graphics/Paint;IF)Landroid/graphics/text/MeasuredText$Builder;
HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;IZ)Landroid/graphics/text/MeasuredText$Builder;
-HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;Landroid/graphics/text/LineBreakConfig;IZ)Landroid/graphics/text/MeasuredText$Builder;+]Landroid/graphics/Paint;Landroid/text/TextPaint;
+HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;Landroid/graphics/text/LineBreakConfig;IZ)Landroid/graphics/text/MeasuredText$Builder;
HSPLandroid/graphics/text/MeasuredText$Builder;->build()Landroid/graphics/text/MeasuredText;
HSPLandroid/graphics/text/MeasuredText$Builder;->ensureNativePtrNoReuse()V
HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeHyphenation(I)Landroid/graphics/text/MeasuredText$Builder;
HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeHyphenation(Z)Landroid/graphics/text/MeasuredText$Builder;
HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeLayout(Z)Landroid/graphics/text/MeasuredText$Builder;
-HSPLandroid/graphics/text/MeasuredText;->getCharWidthAt(I)F+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/graphics/text/MeasuredText;->getCharWidthAt(I)F
HSPLandroid/graphics/text/MeasuredText;->getChars()[C
HSPLandroid/graphics/text/MeasuredText;->getNativePtr()J
HSPLandroid/hardware/Camera$CameraInfo;-><init>()V
@@ -7942,6 +7970,7 @@ HSPLandroid/hardware/HardwareBuffer;->isClosed()Z
HSPLandroid/hardware/ICameraService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
HSPLandroid/hardware/ICameraService$Stub$Proxy;->addListener(Landroid/hardware/ICameraServiceListener;)[Landroid/hardware/CameraStatus;
HSPLandroid/hardware/ICameraService$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/ICameraService$Stub$Proxy;->getCameraCharacteristics(Ljava/lang/String;IZ)Landroid/hardware/camera2/impl/CameraMetadataNative;
HSPLandroid/hardware/ICameraService$Stub$Proxy;->getConcurrentCameraIds()[Landroid/hardware/camera2/utils/ConcurrentCameraIdCombination;
HSPLandroid/hardware/ICameraService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/ICameraService;
HSPLandroid/hardware/ICameraServiceListener$Stub;->getMaxTransactionId()I
@@ -7989,7 +8018,7 @@ HSPLandroid/hardware/SystemSensorManager$BaseEventQueue;->removeSensor(Landroid/
HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;-><init>(Landroid/hardware/SensorEventListener;Landroid/os/Looper;Landroid/hardware/SystemSensorManager;Ljava/lang/String;)V
HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->addSensorEvent(Landroid/hardware/Sensor;)V
HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchAdditionalInfoEvent(III[F[I)V
-HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchSensorEvent(I[FIJ)V+]Landroid/hardware/Sensor;Landroid/hardware/Sensor;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchSensorEvent(I[FIJ)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/hardware/Sensor;Landroid/hardware/Sensor;]Landroid/util/SparseArray;Landroid/util/SparseArray;
HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->removeSensorEvent(Landroid/hardware/Sensor;)V
HSPLandroid/hardware/SystemSensorManager$TriggerEventQueue;->addSensorEvent(Landroid/hardware/Sensor;)V
HSPLandroid/hardware/SystemSensorManager$TriggerEventQueue;->dispatchSensorEvent(I[FIJ)V
@@ -8024,11 +8053,19 @@ HSPLandroid/hardware/camera2/CameraCharacteristics;->overrideProperty(Landroid/h
HSPLandroid/hardware/camera2/CameraManager$AvailabilityCallback;-><init>()V
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;->compare(Ljava/lang/String;Ljava/lang/String;)I
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$3;-><init>(Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;Landroid/hardware/camera2/CameraManager$AvailabilityCallback;)V
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->cameraIdHasConcurrentStreamsLocked(Ljava/lang/String;)Z
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->connectCameraServiceLocked()V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->extractCameraIdListLocked()[Ljava/lang/String;
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->get()Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->getCameraIdList()[Ljava/lang/String;
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->getCameraService()Landroid/hardware/ICameraService;
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onCameraAccessPrioritiesChanged()V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onStatusChanged(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onStatusChangedLocked(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onTorchStatusChanged(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onTorchStatusChangedLocked(ILjava/lang/String;)V
HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->postSingleAccessPriorityChangeUpdate(Landroid/hardware/camera2/CameraManager$AvailabilityCallback;Ljava/util/concurrent/Executor;)V
HSPLandroid/hardware/camera2/CameraManager$FoldStateListener;->addDeviceStateListener(Landroid/hardware/camera2/CameraManager$DeviceStateListener;)V
HSPLandroid/hardware/camera2/CameraManager$FoldStateListener;->handleStateChange(I)V
@@ -8038,6 +8075,7 @@ HSPLandroid/hardware/camera2/CameraManager;->getCameraIdList()[Ljava/lang/String
HSPLandroid/hardware/camera2/CameraManager;->getDisplaySize()Landroid/util/Size;
HSPLandroid/hardware/camera2/CameraManager;->getPhysicalCameraMultiResolutionConfigs(Ljava/lang/String;Landroid/hardware/camera2/impl/CameraMetadataNative;Landroid/hardware/ICameraService;)Ljava/util/Map;
HSPLandroid/hardware/camera2/CameraManager;->registerDeviceStateListener(Landroid/hardware/camera2/CameraCharacteristics;)V
+HSPLandroid/hardware/camera2/CameraManager;->shouldOverrideToPortrait(Landroid/content/Context;)Z
HSPLandroid/hardware/camera2/CameraMetadata;-><init>()V
HSPLandroid/hardware/camera2/CameraMetadata;->setNativeInstance(Landroid/hardware/camera2/impl/CameraMetadataNative;)V
HSPLandroid/hardware/camera2/impl/CameraDeviceImpl$CameraHandlerExecutor;->execute(Ljava/lang/Runnable;)V
@@ -8184,7 +8222,9 @@ HSPLandroid/hardware/display/DisplayManagerGlobal$1;-><init>(Landroid/hardware/d
HSPLandroid/hardware/display/DisplayManagerGlobal$1;->recompute(Ljava/lang/Integer;)Landroid/view/DisplayInfo;
HSPLandroid/hardware/display/DisplayManagerGlobal$1;->recompute(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate$$ExternalSyntheticLambda0;->run()V
+HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;-><init>(Landroid/hardware/display/DisplayManager$DisplayListener;Ljava/util/concurrent/Executor;JLjava/lang/String;)V
HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;->clearEvents()V
+HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;->handleDisplayEventInner(IILandroid/view/DisplayInfo;Z)V+]Landroid/view/DisplayInfo;Landroid/view/DisplayInfo;]Landroid/hardware/display/DisplayManager$DisplayListener;missing_types
HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;-><init>(Landroid/hardware/display/DisplayManagerGlobal;)V
HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;-><init>(Landroid/hardware/display/DisplayManagerGlobal;Landroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback-IA;)V
HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;->onDisplayEvent(II)V
@@ -8205,6 +8245,7 @@ HSPLandroid/hardware/display/DisplayManagerGlobal;->getPreferredWideGamutColorSp
HSPLandroid/hardware/display/DisplayManagerGlobal;->getStableDisplaySize()Landroid/graphics/Point;
HSPLandroid/hardware/display/DisplayManagerGlobal;->getWifiDisplayStatus()Landroid/hardware/display/WifiDisplayStatus;
HSPLandroid/hardware/display/DisplayManagerGlobal;->initExtraLogging()Z
+HSPLandroid/hardware/display/DisplayManagerGlobal;->maybeLogAllDisplayListeners()V
HSPLandroid/hardware/display/DisplayManagerGlobal;->registerCallbackIfNeededLocked()V
HSPLandroid/hardware/display/DisplayManagerGlobal;->registerDisplayListener(Landroid/hardware/display/DisplayManager$DisplayListener;Ljava/util/concurrent/Executor;JLjava/lang/String;)V+]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
HSPLandroid/hardware/display/DisplayManagerGlobal;->registerNativeChoreographerForRefreshRateCallbacks()V
@@ -8324,7 +8365,7 @@ HSPLandroid/hardware/location/NanoAppMessage;->getNanoAppId()J
HSPLandroid/hardware/location/NanoAppMessage;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/hardware/location/NanoAppState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/location/NanoAppState;
HSPLandroid/hardware/location/NanoAppState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/hardware/location/NanoAppState;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/hardware/location/NanoAppState;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/hardware/location/NanoAppState;->getNanoAppId()J
HSPLandroid/hardware/security/keymint/KeyParameter$1;-><init>()V
HSPLandroid/hardware/security/keymint/KeyParameter$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/security/keymint/KeyParameter;
@@ -8437,7 +8478,7 @@ HSPLandroid/icu/impl/FormattedStringBuilder;->copyFrom(Landroid/icu/impl/Formatt
HSPLandroid/icu/impl/FormattedStringBuilder;->fieldAt(I)Ljava/lang/Object;
HSPLandroid/icu/impl/FormattedStringBuilder;->getCapacity()I
HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;IILjava/lang/Object;)I
-HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;Ljava/lang/Object;)I
+HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;Ljava/lang/Object;)I+]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/icu/impl/FormattedStringBuilder;->insert(I[C[Ljava/lang/Object;)I
HSPLandroid/icu/impl/FormattedStringBuilder;->insertCodePoint(IILjava/lang/Object;)I
HSPLandroid/icu/impl/FormattedStringBuilder;->length()I
@@ -8448,7 +8489,7 @@ HSPLandroid/icu/impl/FormattedStringBuilder;->toFieldArray()[Ljava/lang/Object;
HSPLandroid/icu/impl/FormattedStringBuilder;->toString()Ljava/lang/String;
HSPLandroid/icu/impl/FormattedStringBuilder;->unwrapField(Ljava/lang/Object;)Ljava/text/Format$Field;
HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->isIntOrGroup(Ljava/lang/Object;)Z
-HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextFieldPosition(Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;)Z
+HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextFieldPosition(Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;)Z+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;]Ljava/text/FieldPosition;Ljava/text/DontCareFieldPosition;
HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextPosition(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/text/ConstrainedFieldPosition;Ljava/text/Format$Field;)Z+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;
HSPLandroid/icu/impl/Grego;->dayOfWeek(J)I
HSPLandroid/icu/impl/Grego;->dayToFields(J[I)[I
@@ -8469,7 +8510,7 @@ HSPLandroid/icu/impl/ICUBinary$PackageDataFile;->addBaseNamesInFolder(Ljava/lang
HSPLandroid/icu/impl/ICUBinary$PackageDataFile;->getData(Ljava/lang/String;)Ljava/nio/ByteBuffer;
HSPLandroid/icu/impl/ICUBinary;->addBaseNamesInFileFolder(Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;Ljava/nio/ByteBuffer;I)I
-HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;[BI)I
+HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;[BI)I+]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/icu/impl/ICUBinary;->getBytes(Ljava/nio/ByteBuffer;II)[B
HSPLandroid/icu/impl/ICUBinary;->getChars(Ljava/nio/ByteBuffer;II)[C
HSPLandroid/icu/impl/ICUBinary;->getData(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)Ljava/nio/ByteBuffer;
@@ -8505,7 +8546,7 @@ HSPLandroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;->add(Ljava/lang/Object;)V
HSPLandroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;->create()Landroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;
HSPLandroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;->list()Ljava/util/List;
HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collect(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;)Ljava/util/List;
-HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collectRegion(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;ILandroid/icu/impl/ICUResourceBundle;)V
+HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collectRegion(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;ILandroid/icu/impl/ICUResourceBundle;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundle;Landroid/icu/impl/ICUResourceBundleImpl$ResourceString;,Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;,Landroid/icu/impl/ICUResourceBundleImpl$ResourceArray;]Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/impl/ICUCurrencyMetaInfo$CurrencyCollector;
HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->currencies(Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;)Ljava/util/List;
HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->currencyDigits(Ljava/lang/String;Landroid/icu/util/Currency$CurrencyUsage;)Landroid/icu/text/CurrencyMetaInfo$CurrencyDigits;
HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->getDate(Landroid/icu/impl/ICUResourceBundle;JZ)J
@@ -8513,9 +8554,9 @@ HSPLandroid/icu/impl/ICUData;->checkStreamForBinaryData(Ljava/io/InputStream;Lja
HSPLandroid/icu/impl/ICUData;->getStream(Ljava/lang/ClassLoader;Ljava/lang/String;Z)Ljava/io/InputStream;
HSPLandroid/icu/impl/ICULocaleService$ICUResourceBundleFactory;->getSupportedIDs()Ljava/util/Set;
HSPLandroid/icu/impl/ICULocaleService$ICUResourceBundleFactory;->loader()Ljava/lang/ClassLoader;
-HSPLandroid/icu/impl/ICULocaleService$LocaleKey;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICULocaleService$LocaleKey;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->createWithCanonical(Landroid/icu/util/ULocale;Ljava/lang/String;I)Landroid/icu/impl/ICULocaleService$LocaleKey;
-HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentDescriptor()Ljava/lang/String;
+HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentDescriptor()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/ICULocaleService$LocaleKey;Landroid/icu/impl/ICULocaleService$LocaleKey;
HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentID()Ljava/lang/String;
HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentLocale()Landroid/icu/util/ULocale;
HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->fallback()Z
@@ -8547,20 +8588,21 @@ HSPLandroid/icu/impl/ICUResourceBundle$Loader;-><init>(Landroid/icu/impl/ICUReso
HSPLandroid/icu/impl/ICUResourceBundle$WholeBundle;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundleReader;)V
HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$mgetNoFallback(Landroid/icu/impl/ICUResourceBundle;)Z
HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$sfgetDEBUG()Z
+HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$smgetParentLocaleID(Ljava/lang/String;Ljava/lang/String;Landroid/icu/impl/ICUResourceBundle$OpenType;)Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$sminstantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
HSPLandroid/icu/impl/ICUResourceBundle;-><init>(Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;)V
HSPLandroid/icu/impl/ICUResourceBundle;->addBundleBaseNamesFromClassLoader(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/util/Set;)V
HSPLandroid/icu/impl/ICUResourceBundle;->at(I)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->at(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundle;->countPathKeys(Ljava/lang/String;)I
+HSPLandroid/icu/impl/ICUResourceBundle;->countPathKeys(Ljava/lang/String;)I+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundle;->createBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->createFullLocaleNameSet(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/util/Set;
HSPLandroid/icu/impl/ICUResourceBundle;->equals(Ljava/lang/Object;)Z
HSPLandroid/icu/impl/ICUResourceBundle;->findResourceWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->findResourceWithFallback([Ljava/lang/String;ILandroid/icu/impl/ICUResourceBundle;Landroid/icu/util/UResourceBundle;)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Ljava/lang/String;
+HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Ljava/lang/String;+]Landroid/icu/impl/ICUResourceBundleReader$Container;Landroid/icu/impl/ICUResourceBundleReader$Table;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundle;Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
HSPLandroid/icu/impl/ICUResourceBundle;->findTopLevel(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->findTopLevel(Ljava/lang/String;)Landroid/icu/util/UResourceBundle;
HSPLandroid/icu/impl/ICUResourceBundle;->findWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
@@ -8593,7 +8635,7 @@ HSPLandroid/icu/impl/ICUResourceBundle;->getResPathKeys([Ljava/lang/String;I)V
HSPLandroid/icu/impl/ICUResourceBundle;->getStringWithFallback(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundle;->getULocale()Landroid/icu/util/ULocale;
HSPLandroid/icu/impl/ICUResourceBundle;->getWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundle;->instantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;
+HSPLandroid/icu/impl/ICUResourceBundle;->instantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/ICUResourceBundle$OpenType;Landroid/icu/impl/ICUResourceBundle$OpenType;]Landroid/icu/impl/CacheBase;Landroid/icu/impl/ICUResourceBundle$1;
HSPLandroid/icu/impl/ICUResourceBundle;->setParent(Ljava/util/ResourceBundle;)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceArray;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceArray;->getStringArray()[Ljava/lang/String;
@@ -8605,22 +8647,22 @@ HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceBinary;->getBinary([B)[B
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->createBundleObject(ILjava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getContainerResource(I)I
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getContainerResource(I)I+]Landroid/icu/impl/ICUResourceBundleReader$Container;Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getSize()I
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getString(I)Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceInt;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceInt;->getInt()I
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceIntVector;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceIntVector;->getIntVector()[I
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;->getString()Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;->getType()I
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;I)V
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V+]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->findString(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->getType()I
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(ILjava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(Ljava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(Ljava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;+]Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGetObject(Ljava/lang/String;)Ljava/lang/Object;
HSPLandroid/icu/impl/ICUResourceBundleImpl;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
HSPLandroid/icu/impl/ICUResourceBundleImpl;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
@@ -8651,13 +8693,13 @@ HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getStringArray()[Ljav
HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getStringArray(Landroid/icu/impl/ICUResourceBundleReader$Array;)[Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getTable()Landroid/icu/impl/UResource$Table;
HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getType()I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->get(I)Ljava/lang/Object;
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->get(I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;-><init>(I)V
HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->findSimple(I)I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->get(I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->get(I)Ljava/lang/Object;+]Ljava/lang/ref/SoftReference;Ljava/lang/ref/SoftReference;]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->makeKey(I)I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfCleared([Ljava/lang/Object;ILjava/lang/Object;I)Ljava/lang/Object;
HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->storeDirectly(I)Z
HSPLandroid/icu/impl/ICUResourceBundleReader$Table1632;-><init>(Landroid/icu/impl/ICUResourceBundleReader;I)V
@@ -8667,7 +8709,7 @@ HSPLandroid/icu/impl/ICUResourceBundleReader$Table;-><init>()V
HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->findTableItem(Landroid/icu/impl/ICUResourceBundleReader;Ljava/lang/CharSequence;)I
HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->findValue(Ljava/lang/CharSequence;Landroid/icu/impl/UResource$Value;)Z
HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKey(Landroid/icu/impl/ICUResourceBundleReader;I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKeyAndValue(ILandroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)Z
+HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKeyAndValue(ILandroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)Z+]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getResource(Landroid/icu/impl/ICUResourceBundleReader;Ljava/lang/String;)I
HSPLandroid/icu/impl/ICUResourceBundleReader;->-$$Nest$fgetb16BitUnits(Landroid/icu/impl/ICUResourceBundleReader;)Ljava/nio/CharBuffer;
HSPLandroid/icu/impl/ICUResourceBundleReader;->-$$Nest$fgetpoolStringIndex16Limit(Landroid/icu/impl/ICUResourceBundleReader;)I
@@ -8691,7 +8733,7 @@ HSPLandroid/icu/impl/ICUResourceBundleReader;->getAlias(I)Ljava/lang/String;
HSPLandroid/icu/impl/ICUResourceBundleReader;->getArray(I)Landroid/icu/impl/ICUResourceBundleReader$Array;
HSPLandroid/icu/impl/ICUResourceBundleReader;->getBinary(I[B)[B
HSPLandroid/icu/impl/ICUResourceBundleReader;->getChars(II)[C
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getFullName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getFullName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/icu/impl/ICUResourceBundleReader;->getIndexesInt(I)I
HSPLandroid/icu/impl/ICUResourceBundleReader;->getInt(I)I
HSPLandroid/icu/impl/ICUResourceBundleReader;->getIntVector(I)[I
@@ -8701,10 +8743,10 @@ HSPLandroid/icu/impl/ICUResourceBundleReader;->getNoFallback()Z
HSPLandroid/icu/impl/ICUResourceBundleReader;->getReader(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)Landroid/icu/impl/ICUResourceBundleReader;
HSPLandroid/icu/impl/ICUResourceBundleReader;->getResourceByteOffset(I)I
HSPLandroid/icu/impl/ICUResourceBundleReader;->getRootResource()I
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getString(I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getStringV2(I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable(I)Landroid/icu/impl/ICUResourceBundleReader$Table;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable16KeyOffsets(I)[C
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getString(I)Ljava/lang/String;+]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getStringV2(I)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;]Ljava/nio/CharBuffer;Ljava/nio/ByteBufferAsCharBuffer;]Ljava/lang/CharSequence;Ljava/nio/ByteBufferAsCharBuffer;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable(I)Landroid/icu/impl/ICUResourceBundleReader$Table;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table16;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable16KeyOffsets(I)[C+]Ljava/nio/CharBuffer;Ljava/nio/ByteBufferAsCharBuffer;
HSPLandroid/icu/impl/ICUResourceBundleReader;->getTableKeyOffsets(I)[C
HSPLandroid/icu/impl/ICUResourceBundleReader;->init(Ljava/nio/ByteBuffer;)V
HSPLandroid/icu/impl/ICUResourceBundleReader;->makeKeyStringFromBytes([BI)Ljava/lang/String;
@@ -8714,10 +8756,10 @@ HSPLandroid/icu/impl/ICUService$CacheEntry;-><init>(Ljava/lang/String;Ljava/lang
HSPLandroid/icu/impl/ICUService$Key;-><init>(Ljava/lang/String;)V
HSPLandroid/icu/impl/ICUService;->clearServiceCache()V
HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;Landroid/icu/impl/ICUService$Factory;)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;Landroid/icu/impl/ICUService$Factory;)Ljava/lang/Object;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/Map;Ljava/util/concurrent/ConcurrentHashMap;]Landroid/icu/impl/ICURWLock;Landroid/icu/impl/ICURWLock;]Landroid/icu/impl/ICUService$Key;Landroid/icu/impl/ICULocaleService$LocaleKey;
HSPLandroid/icu/impl/ICUService;->isDefault()Z
-HSPLandroid/icu/impl/IDNA2003;->convertIDNToASCII(Ljava/lang/String;I)Ljava/lang/StringBuffer;
-HSPLandroid/icu/impl/IDNA2003;->convertToASCII(Landroid/icu/text/UCharacterIterator;I)Ljava/lang/StringBuffer;
+HSPLandroid/icu/impl/IDNA2003;->convertIDNToASCII(Ljava/lang/String;I)Ljava/lang/StringBuffer;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
+HSPLandroid/icu/impl/IDNA2003;->convertToASCII(Landroid/icu/text/UCharacterIterator;I)Ljava/lang/StringBuffer;+]Landroid/icu/text/UCharacterIterator;Landroid/icu/impl/ReplaceableUCharacterIterator;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
HSPLandroid/icu/impl/IDNA2003;->getSeparatorIndex([CII)I
HSPLandroid/icu/impl/IDNA2003;->isLDHChar(I)Z
HSPLandroid/icu/impl/IDNA2003;->isLabelSeparator(I)Z
@@ -8725,9 +8767,9 @@ HSPLandroid/icu/impl/LocaleIDParser$1;-><init>(Landroid/icu/impl/LocaleIDParser;
HSPLandroid/icu/impl/LocaleIDParser$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/icu/impl/LocaleIDParser$1;->compare(Ljava/lang/String;Ljava/lang/String;)I
HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;)V
-HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;Z)V
+HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;Z)V+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/LocaleIDParser;->addSeparator()V
-HSPLandroid/icu/impl/LocaleIDParser;->append(C)V
+HSPLandroid/icu/impl/LocaleIDParser;->append(C)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/icu/impl/LocaleIDParser;->append(Ljava/lang/String;)V
HSPLandroid/icu/impl/LocaleIDParser;->atTerminator()Z
HSPLandroid/icu/impl/LocaleIDParser;->getBaseName()Ljava/lang/String;
@@ -8751,10 +8793,10 @@ HSPLandroid/icu/impl/LocaleIDParser;->isTerminator(C)Z
HSPLandroid/icu/impl/LocaleIDParser;->isTerminatorOrIDSeparator(C)Z
HSPLandroid/icu/impl/LocaleIDParser;->next()C
HSPLandroid/icu/impl/LocaleIDParser;->parseBaseName()V
-HSPLandroid/icu/impl/LocaleIDParser;->parseCountry()I
+HSPLandroid/icu/impl/LocaleIDParser;->parseCountry()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/icu/impl/LocaleIDParser;->parseKeywords()I
-HSPLandroid/icu/impl/LocaleIDParser;->parseLanguage()I
-HSPLandroid/icu/impl/LocaleIDParser;->parseScript()I
+HSPLandroid/icu/impl/LocaleIDParser;->parseLanguage()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/icu/impl/LocaleIDParser;->parseScript()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/icu/impl/LocaleIDParser;->parseVariant()I
HSPLandroid/icu/impl/LocaleIDParser;->reset()V
HSPLandroid/icu/impl/LocaleIDParser;->setKeywordValue(Ljava/lang/String;Ljava/lang/String;)V
@@ -8783,7 +8825,7 @@ HSPLandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;->flushAndAppendZeroCC(Lja
HSPLandroid/icu/impl/Normalizer2Impl;->addToStartSet(Landroid/icu/util/MutableCodePointTrie;II)V
HSPLandroid/icu/impl/Normalizer2Impl;->composeQuickCheck(Ljava/lang/CharSequence;IIZZ)I
HSPLandroid/icu/impl/Normalizer2Impl;->decompose(IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)V
-HSPLandroid/icu/impl/Normalizer2Impl;->decompose(Ljava/lang/CharSequence;IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)I
+HSPLandroid/icu/impl/Normalizer2Impl;->decompose(Ljava/lang/CharSequence;IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)I+]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/icu/impl/Normalizer2Impl;->decomposeAndAppend(Ljava/lang/CharSequence;ZLandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)V
HSPLandroid/icu/impl/Normalizer2Impl;->ensureCanonIterData()Landroid/icu/impl/Normalizer2Impl;
HSPLandroid/icu/impl/Normalizer2Impl;->getRawNorm16(I)I
@@ -8813,11 +8855,11 @@ HSPLandroid/icu/impl/OlsonTimeZone;->initialDstOffset()I
HSPLandroid/icu/impl/OlsonTimeZone;->initialRawOffset()I
HSPLandroid/icu/impl/OlsonTimeZone;->isFrozen()Z
HSPLandroid/icu/impl/OlsonTimeZone;->loadRule(Landroid/icu/util/UResourceBundle;Ljava/lang/String;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/OlsonTimeZone;->toString()Ljava/lang/String;
+HSPLandroid/icu/impl/OlsonTimeZone;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/icu/impl/PatternProps;->isWhiteSpace(I)Z
HSPLandroid/icu/impl/PatternProps;->skipWhiteSpace(Ljava/lang/CharSequence;I)I
HSPLandroid/icu/impl/PatternTokenizer;-><init>()V
-HSPLandroid/icu/impl/PatternTokenizer;->next(Ljava/lang/StringBuffer;)I
+HSPLandroid/icu/impl/PatternTokenizer;->next(Ljava/lang/StringBuffer;)I+]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
HSPLandroid/icu/impl/PatternTokenizer;->quoteLiteral(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/impl/PatternTokenizer;->setExtraQuotingCharacters(Landroid/icu/text/UnicodeSet;)Landroid/icu/impl/PatternTokenizer;
HSPLandroid/icu/impl/PatternTokenizer;->setPattern(Ljava/lang/String;)Landroid/icu/impl/PatternTokenizer;
@@ -8838,7 +8880,7 @@ HSPLandroid/icu/impl/RBBIDataWrapper;->get(Ljava/nio/ByteBuffer;)Landroid/icu/im
HSPLandroid/icu/impl/ReplaceableUCharacterIterator;-><init>(Ljava/lang/String;)V
HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->getLength()I
HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->getText([CI)I
-HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->next()I
+HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->next()I+]Landroid/icu/text/Replaceable;Landroid/icu/text/ReplaceableString;
HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->setIndex(I)V
HSPLandroid/icu/impl/RuleCharacterIterator;->_advance(I)V
HSPLandroid/icu/impl/RuleCharacterIterator;->_current()I
@@ -8865,14 +8907,14 @@ HSPLandroid/icu/impl/StaticUnicodeSets;->chooseFrom(Ljava/lang/String;Landroid/i
HSPLandroid/icu/impl/StaticUnicodeSets;->get(Landroid/icu/impl/StaticUnicodeSets$Key;)Landroid/icu/text/UnicodeSet;
HSPLandroid/icu/impl/StringSegment;-><init>(Ljava/lang/String;Z)V
HSPLandroid/icu/impl/StringSegment;->adjustOffset(I)V
-HSPLandroid/icu/impl/StringSegment;->charAt(I)C+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->charAt(I)C
HSPLandroid/icu/impl/StringSegment;->codePointsEqual(IIZ)Z
-HSPLandroid/icu/impl/StringSegment;->getCodePoint()I+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->getCodePoint()I
HSPLandroid/icu/impl/StringSegment;->getCommonPrefixLength(Ljava/lang/CharSequence;)I
HSPLandroid/icu/impl/StringSegment;->getOffset()I
-HSPLandroid/icu/impl/StringSegment;->getPrefixLengthInternal(Ljava/lang/CharSequence;Z)I+]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->getPrefixLengthInternal(Ljava/lang/CharSequence;Z)I
HSPLandroid/icu/impl/StringSegment;->length()I
-HSPLandroid/icu/impl/StringSegment;->startsWith(Landroid/icu/text/UnicodeSet;)Z+]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
+HSPLandroid/icu/impl/StringSegment;->startsWith(Landroid/icu/text/UnicodeSet;)Z
HSPLandroid/icu/impl/StringSegment;->startsWith(Ljava/lang/CharSequence;)Z
HSPLandroid/icu/impl/TextTrieMap$Node;-><init>(Landroid/icu/impl/TextTrieMap;)V
HSPLandroid/icu/impl/TextTrieMap;-><init>(Z)V
@@ -8930,7 +8972,7 @@ HSPLandroid/icu/impl/Trie2_32;->get(I)I
HSPLandroid/icu/impl/Trie2_32;->getFromU16SingleLead(C)I
HSPLandroid/icu/impl/UBiDiProps;->getClass(I)I
HSPLandroid/icu/impl/UBiDiProps;->getClassFromProps(I)I
-HSPLandroid/icu/impl/UCaseProps;->fold(II)I+]Landroid/icu/impl/Trie2_16;Landroid/icu/impl/Trie2_16;
+HSPLandroid/icu/impl/UCaseProps;->fold(II)I
HSPLandroid/icu/impl/UCaseProps;->getCaseLocale(Ljava/lang/String;)I
HSPLandroid/icu/impl/UCaseProps;->getCaseLocale(Ljava/util/Locale;)I
HSPLandroid/icu/impl/UCaseProps;->getDelta(I)I
@@ -8962,7 +9004,7 @@ HSPLandroid/icu/impl/UResource$Sink;-><init>()V
HSPLandroid/icu/impl/UResource$Value;-><init>()V
HSPLandroid/icu/impl/UResource$Value;->toString()Ljava/lang/String;
HSPLandroid/icu/impl/Utility;->addExact(II)I
-HSPLandroid/icu/impl/Utility;->appendTo(Ljava/lang/CharSequence;Ljava/lang/Appendable;)Ljava/lang/Appendable;
+HSPLandroid/icu/impl/Utility;->appendTo(Ljava/lang/CharSequence;Ljava/lang/Appendable;)Ljava/lang/Appendable;+]Ljava/lang/Appendable;Ljava/lang/StringBuffer;
HSPLandroid/icu/impl/Utility;->arrayEquals([BLjava/lang/Object;)Z
HSPLandroid/icu/impl/Utility;->arrayRegionMatches([BI[BII)Z
HSPLandroid/icu/impl/Utility;->sameObjects(Ljava/lang/Object;Ljava/lang/Object;)Z
@@ -9093,9 +9135,9 @@ HSPLandroid/icu/impl/locale/BaseLocale$Key;->-$$Nest$fget_scrt(Landroid/icu/impl
HSPLandroid/icu/impl/locale/BaseLocale$Key;->-$$Nest$fget_vart(Landroid/icu/impl/locale/BaseLocale$Key;)Ljava/lang/String;
HSPLandroid/icu/impl/locale/BaseLocale$Key;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/icu/impl/locale/BaseLocale$Key;->equals(Ljava/lang/Object;)Z
-HSPLandroid/icu/impl/locale/BaseLocale$Key;->hashCode()I
+HSPLandroid/icu/impl/locale/BaseLocale$Key;->hashCode()I+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/locale/BaseLocale$Key;->normalize(Landroid/icu/impl/locale/BaseLocale$Key;)Landroid/icu/impl/locale/BaseLocale$Key;
-HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/icu/impl/locale/BaseLocale-IA;)V
HSPLandroid/icu/impl/locale/BaseLocale;->getInstance(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/icu/impl/locale/BaseLocale;
HSPLandroid/icu/impl/locale/BaseLocale;->getLanguage()Ljava/lang/String;
@@ -9116,7 +9158,7 @@ HSPLandroid/icu/impl/locale/LocaleObjectCache;->cleanStaleEntries()V
HSPLandroid/icu/impl/locale/LocaleObjectCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/icu/impl/number/AdoptingModifierStore$1;-><clinit>()V
HSPLandroid/icu/impl/number/AdoptingModifierStore;-><init>(Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;)V
-HSPLandroid/icu/impl/number/AdoptingModifierStore;->getModifierWithoutPlural(Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/Modifier;
+HSPLandroid/icu/impl/number/AdoptingModifierStore;->getModifierWithoutPlural(Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/Modifier;+]Landroid/icu/impl/number/Modifier$Signum;Landroid/icu/impl/number/Modifier$Signum;
HSPLandroid/icu/impl/number/AffixUtils;->containsType(Ljava/lang/CharSequence;I)Z
HSPLandroid/icu/impl/number/AffixUtils;->escape(Ljava/lang/CharSequence;)Ljava/lang/String;
HSPLandroid/icu/impl/number/AffixUtils;->getFieldForType(I)Landroid/icu/text/NumberFormat$Field;
@@ -9131,14 +9173,14 @@ HSPLandroid/icu/impl/number/AffixUtils;->makeTag(IIII)J
HSPLandroid/icu/impl/number/AffixUtils;->nextToken(JLjava/lang/CharSequence;)J
HSPLandroid/icu/impl/number/AffixUtils;->unescape(Ljava/lang/CharSequence;Landroid/icu/impl/FormattedStringBuilder;ILandroid/icu/impl/number/AffixUtils$SymbolProvider;Landroid/icu/text/NumberFormat$Field;)I
HSPLandroid/icu/impl/number/AffixUtils;->unescapedCount(Ljava/lang/CharSequence;ZLandroid/icu/impl/number/AffixUtils$SymbolProvider;)I
-HSPLandroid/icu/impl/number/ConstantAffixModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
+HSPLandroid/icu/impl/number/ConstantAffixModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;
HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;-><init>(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;ZZ)V
HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;-><init>(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;ZZLandroid/icu/impl/number/Modifier$Parameters;)V
-HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
+HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;
HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->getPrefixLength()I
HSPLandroid/icu/impl/number/CurrencySpacingEnabledModifier;->applyCurrencySpacing(Landroid/icu/impl/FormattedStringBuilder;IIIILandroid/icu/text/DecimalFormatSymbols;)I
HSPLandroid/icu/impl/number/CurrencySpacingEnabledModifier;->applyCurrencySpacingAffix(Landroid/icu/impl/FormattedStringBuilder;IBLandroid/icu/text/DecimalFormatSymbols;)I
-HSPLandroid/icu/impl/number/CustomSymbolCurrency;->resolve(Landroid/icu/util/Currency;Landroid/icu/util/ULocale;Landroid/icu/text/DecimalFormatSymbols;)Landroid/icu/util/Currency;
+HSPLandroid/icu/impl/number/CustomSymbolCurrency;->resolve(Landroid/icu/util/Currency;Landroid/icu/util/ULocale;Landroid/icu/text/DecimalFormatSymbols;)Landroid/icu/util/Currency;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/util/Currency;Landroid/icu/util/Currency;
HSPLandroid/icu/impl/number/DecimalFormatProperties;-><init>()V
HSPLandroid/icu/impl/number/DecimalFormatProperties;->_clear()Landroid/icu/impl/number/DecimalFormatProperties;
HSPLandroid/icu/impl/number/DecimalFormatProperties;->_copyFrom(Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/DecimalFormatProperties;
@@ -9218,14 +9260,14 @@ HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;-><init>()V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToBigDecimal(Ljava/math/BigDecimal;)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToBigInteger(Ljava/math/BigInteger;)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToDoubleFast(D)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToLong(J)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToLong(J)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->adjustMagnitude(I)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->appendDigit(BIZ)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->appendDigit(BIZ)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->applyMaxInteger(I)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->convertToAccurateDouble()V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->copyFrom(Landroid/icu/impl/number/DecimalQuantity;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->fitsInLong()Z+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getDigit(I)B
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->fitsInLong()Z
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getDigit(I)B+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getLowerDisplayMagnitude()I
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getMagnitude()I
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getPluralOperand(Landroid/icu/text/PluralRules$Operand;)D
@@ -9238,18 +9280,18 @@ HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->isZeroish()Z
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->negate()V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->populateUFieldPosition(Ljava/text/FieldPosition;)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;Z)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;Z)V+]Ljava/math/MathContext;Ljava/math/MathContext;]Ljava/math/RoundingMode;Ljava/math/RoundingMode;]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->safeSubtract(II)I
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setMinFraction(I)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setMinInteger(I)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToBigDecimal(Ljava/math/BigDecimal;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToDouble(D)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToDouble(D)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToInt(I)V
HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToLong(J)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->signum()Landroid/icu/impl/number/Modifier$Signum;
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->toLong(Z)J+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>()V+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(D)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->signum()Landroid/icu/impl/number/Modifier$Signum;+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->toLong(Z)J
+HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>()V
+HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(D)V+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(I)V
HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(J)V
HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(Ljava/lang/Number;)V
@@ -9281,14 +9323,14 @@ HSPLandroid/icu/impl/number/MacroProps;-><init>()V
HSPLandroid/icu/impl/number/MacroProps;->fallback(Landroid/icu/impl/number/MacroProps;)V
HSPLandroid/icu/impl/number/MicroProps;-><init>(Z)V
HSPLandroid/icu/impl/number/MicroProps;->clone()Ljava/lang/Object;
-HSPLandroid/icu/impl/number/MicroProps;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/impl/number/MicroProps;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/MicroProps;
HSPLandroid/icu/impl/number/Modifier$Signum;->values()[Landroid/icu/impl/number/Modifier$Signum;
HSPLandroid/icu/impl/number/MultiplierFormatHandler;-><init>(Landroid/icu/number/Scale;Landroid/icu/impl/number/MicroPropsGenerator;)V
HSPLandroid/icu/impl/number/MultiplierFormatHandler;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;-><init>(Landroid/icu/impl/number/AdoptingModifierStore;Landroid/icu/text/PluralRules;)V
HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->addToChain(Landroid/icu/impl/number/MicroPropsGenerator;)Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;
-HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->applyToMicros(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;)V
-HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->applyToMicros(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;)V+]Landroid/icu/impl/number/AdoptingModifierStore;Landroid/icu/impl/number/AdoptingModifierStore;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroPropsGenerator;Landroid/icu/impl/number/MicroProps;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;
HSPLandroid/icu/impl/number/MutablePatternModifier;-><init>(Z)V
HSPLandroid/icu/impl/number/MutablePatternModifier;->addToChain(Landroid/icu/impl/number/MicroPropsGenerator;)Landroid/icu/impl/number/MicroPropsGenerator;
HSPLandroid/icu/impl/number/MutablePatternModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
@@ -9318,7 +9360,7 @@ HSPLandroid/icu/impl/number/PatternStringParser;->consumeAffix(Landroid/icu/impl
HSPLandroid/icu/impl/number/PatternStringParser;->consumeExponent(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
HSPLandroid/icu/impl/number/PatternStringParser;->consumeFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
HSPLandroid/icu/impl/number/PatternStringParser;->consumeFractionFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
-HSPLandroid/icu/impl/number/PatternStringParser;->consumeIntegerFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
+HSPLandroid/icu/impl/number/PatternStringParser;->consumeIntegerFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V+]Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParserState;
HSPLandroid/icu/impl/number/PatternStringParser;->consumeLiteral(Landroid/icu/impl/number/PatternStringParser$ParserState;)V
HSPLandroid/icu/impl/number/PatternStringParser;->consumePadding(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;Landroid/icu/impl/number/Padder$PadPosition;)V
HSPLandroid/icu/impl/number/PatternStringParser;->consumePattern(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedPatternInfo;)V
@@ -9331,9 +9373,9 @@ HSPLandroid/icu/impl/number/PatternStringUtils$PatternSignType;-><clinit>()V
HSPLandroid/icu/impl/number/PatternStringUtils$PatternSignType;-><init>(Ljava/lang/String;I)V
HSPLandroid/icu/impl/number/PatternStringUtils$PatternSignType;->values()[Landroid/icu/impl/number/PatternStringUtils$PatternSignType;
HSPLandroid/icu/impl/number/PatternStringUtils;->patternInfoToStringBuilder(Landroid/icu/impl/number/AffixPatternProvider;ZLandroid/icu/impl/number/PatternStringUtils$PatternSignType;ZLandroid/icu/impl/StandardPlural;ZLjava/lang/StringBuilder;)V
-HSPLandroid/icu/impl/number/PatternStringUtils;->propertiesToPatternString(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/lang/String;
+HSPLandroid/icu/impl/number/PatternStringUtils;->propertiesToPatternString(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
HSPLandroid/icu/impl/number/PatternStringUtils;->resolveSignDisplay(Landroid/icu/number/NumberFormatter$SignDisplay;Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/PatternStringUtils$PatternSignType;
-HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;-><init>(Landroid/icu/impl/number/DecimalFormatProperties;)V
+HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;-><init>(Landroid/icu/impl/number/DecimalFormatProperties;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->charAt(II)C
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->containsSymbolType(I)Z
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->currencyAsDecimal()Z
@@ -9341,7 +9383,7 @@ HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->forProperties(Landr
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->getString(I)Ljava/lang/String;
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasBody()Z
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasCurrencySign()Z
-HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasNegativeSubpattern()Z
+HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasNegativeSubpattern()Z+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->length(I)I
HSPLandroid/icu/impl/number/RoundingUtils;->getMathContextOr34Digits(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/math/MathContext;
HSPLandroid/icu/impl/number/RoundingUtils;->getMathContextOrUnlimited(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/math/MathContext;
@@ -9353,14 +9395,14 @@ HSPLandroid/icu/impl/number/SimpleModifier;->apply(Landroid/icu/impl/FormattedSt
HSPLandroid/icu/impl/number/parse/AffixMatcher$1;->compare(Landroid/icu/impl/number/parse/AffixMatcher;Landroid/icu/impl/number/parse/AffixMatcher;)I
HSPLandroid/icu/impl/number/parse/AffixMatcher$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/icu/impl/number/parse/AffixMatcher;-><init>(Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;I)V
-HSPLandroid/icu/impl/number/parse/AffixMatcher;->createMatchers(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/AffixTokenMatcherFactory;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)V+]Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/NumberParserImpl;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/icu/impl/number/parse/AffixMatcher;->createMatchers(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/AffixTokenMatcherFactory;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)V
HSPLandroid/icu/impl/number/parse/AffixMatcher;->getInstance(Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;I)Landroid/icu/impl/number/parse/AffixMatcher;
HSPLandroid/icu/impl/number/parse/AffixMatcher;->isInteresting(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)Z
HSPLandroid/icu/impl/number/parse/AffixMatcher;->length(Landroid/icu/impl/number/parse/AffixPatternMatcher;)I
HSPLandroid/icu/impl/number/parse/AffixMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)Z
HSPLandroid/icu/impl/number/parse/AffixMatcher;->matched(Landroid/icu/impl/number/parse/AffixPatternMatcher;Ljava/lang/String;)Z
HSPLandroid/icu/impl/number/parse/AffixMatcher;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
-HSPLandroid/icu/impl/number/parse/AffixMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z+]Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;
+HSPLandroid/icu/impl/number/parse/AffixMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z
HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;-><init>(Ljava/lang/String;)V
HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->consumeToken(I)V
HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->equals(Ljava/lang/Object;)Z
@@ -9368,10 +9410,10 @@ HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->fromAffixPattern(Ljava/l
HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->getPattern()Ljava/lang/String;
HSPLandroid/icu/impl/number/parse/AffixTokenMatcherFactory;-><init>()V
HSPLandroid/icu/impl/number/parse/AffixTokenMatcherFactory;->minusSign()Landroid/icu/impl/number/parse/MinusSignMatcher;
-HSPLandroid/icu/impl/number/parse/DecimalMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)V+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;
+HSPLandroid/icu/impl/number/parse/DecimalMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)V
HSPLandroid/icu/impl/number/parse/DecimalMatcher;->getInstance(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)Landroid/icu/impl/number/parse/DecimalMatcher;
HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)Z
-HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;I)Z
+HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;I)Z+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/number/parse/ParsedNumber;Landroid/icu/impl/number/parse/ParsedNumber;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;
HSPLandroid/icu/impl/number/parse/DecimalMatcher;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
HSPLandroid/icu/impl/number/parse/DecimalMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z
HSPLandroid/icu/impl/number/parse/DecimalMatcher;->validateGroup(IIZ)Z
@@ -9382,14 +9424,14 @@ HSPLandroid/icu/impl/number/parse/NanMatcher;->getInstance(Landroid/icu/text/Dec
HSPLandroid/icu/impl/number/parse/NumberParserImpl;-><init>(I)V
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->addMatcher(Landroid/icu/impl/number/parse/NumberParseMatcher;)V
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->addMatchers(Ljava/util/Collection;)V
-HSPLandroid/icu/impl/number/parse/NumberParserImpl;->createParserFromProperties(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Z)Landroid/icu/impl/number/parse/NumberParserImpl;
+HSPLandroid/icu/impl/number/parse/NumberParserImpl;->createParserFromProperties(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Z)Landroid/icu/impl/number/parse/NumberParserImpl;+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/NumberParserImpl;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->freeze()V
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->getParseFlags()I
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->parse(Ljava/lang/String;IZLandroid/icu/impl/number/parse/ParsedNumber;)V
HSPLandroid/icu/impl/number/parse/NumberParserImpl;->parseGreedy(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)V
HSPLandroid/icu/impl/number/parse/ParsedNumber;-><init>()V
HSPLandroid/icu/impl/number/parse/ParsedNumber;->clear()V
-HSPLandroid/icu/impl/number/parse/ParsedNumber;->getNumber(I)Ljava/lang/Number;+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/parse/ParsedNumber;->getNumber(I)Ljava/lang/Number;
HSPLandroid/icu/impl/number/parse/ParsedNumber;->postProcess()V
HSPLandroid/icu/impl/number/parse/ParsedNumber;->seenNumber()Z
HSPLandroid/icu/impl/number/parse/ParsedNumber;->setCharsConsumed(Landroid/icu/impl/StringSegment;)V
@@ -9398,7 +9440,7 @@ HSPLandroid/icu/impl/number/parse/RequireAffixValidator;-><init>()V
HSPLandroid/icu/impl/number/parse/RequireAffixValidator;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
HSPLandroid/icu/impl/number/parse/RequireNumberValidator;-><init>()V
HSPLandroid/icu/impl/number/parse/RequireNumberValidator;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
-HSPLandroid/icu/impl/number/parse/ScientificMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)V+]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
+HSPLandroid/icu/impl/number/parse/ScientificMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)V
HSPLandroid/icu/impl/number/parse/ScientificMatcher;->getInstance(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)Landroid/icu/impl/number/parse/ScientificMatcher;
HSPLandroid/icu/impl/number/parse/ScientificMatcher;->minusSignSet()Landroid/icu/text/UnicodeSet;
HSPLandroid/icu/impl/number/parse/ScientificMatcher;->plusSignSet()Landroid/icu/text/UnicodeSet;
@@ -9426,7 +9468,7 @@ HSPLandroid/icu/impl/number/range/StandardPluralRanges;->getSetForLocale(Landroi
HSPLandroid/icu/impl/number/range/StandardPluralRanges;->setCapacity(I)V
HSPLandroid/icu/lang/UCharacter;->codePointAt(Ljava/lang/CharSequence;I)I
HSPLandroid/icu/lang/UCharacter;->digit(I)I
-HSPLandroid/icu/lang/UCharacter;->foldCase(II)I+]Landroid/icu/impl/UCaseProps;Landroid/icu/impl/UCaseProps;
+HSPLandroid/icu/lang/UCharacter;->foldCase(II)I
HSPLandroid/icu/lang/UCharacter;->foldCase(IZ)I
HSPLandroid/icu/lang/UCharacter;->getPropertyValueEnumNoThrow(ILjava/lang/CharSequence;)I
HSPLandroid/icu/lang/UCharacter;->getType(I)I
@@ -9442,33 +9484,33 @@ HSPLandroid/icu/number/IntegerWidth;-><init>(II)V
HSPLandroid/icu/number/IntegerWidth;->truncateAt(I)Landroid/icu/number/IntegerWidth;
HSPLandroid/icu/number/IntegerWidth;->zeroFillTo(I)Landroid/icu/number/IntegerWidth;
HSPLandroid/icu/number/LocalizedNumberFormatter;-><init>(Landroid/icu/number/NumberFormatterSettings;ILjava/lang/Object;)V
-HSPLandroid/icu/number/LocalizedNumberFormatter;->computeCompiled()Z
+HSPLandroid/icu/number/LocalizedNumberFormatter;->computeCompiled()Z+]Ljava/util/concurrent/atomic/AtomicLongFieldUpdater;Ljava/util/concurrent/atomic/AtomicLongFieldUpdater$CASUpdater;]Landroid/icu/number/LocalizedNumberFormatter;Landroid/icu/number/LocalizedNumberFormatter;]Ljava/lang/Long;Ljava/lang/Long;
HSPLandroid/icu/number/LocalizedNumberFormatter;->create(ILjava/lang/Object;)Landroid/icu/number/LocalizedNumberFormatter;
HSPLandroid/icu/number/LocalizedNumberFormatter;->create(ILjava/lang/Object;)Landroid/icu/number/NumberFormatterSettings;
HSPLandroid/icu/number/LocalizedNumberFormatter;->format(D)Landroid/icu/number/FormattedNumber;
HSPLandroid/icu/number/LocalizedNumberFormatter;->format(J)Landroid/icu/number/FormattedNumber;
HSPLandroid/icu/number/LocalizedNumberFormatter;->format(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/number/FormattedNumber;
-HSPLandroid/icu/number/LocalizedNumberFormatter;->formatImpl(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/LocalizedNumberFormatter;->formatImpl(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/number/NumberFormatterImpl;Landroid/icu/number/NumberFormatterImpl;
HSPLandroid/icu/number/LocalizedNumberFormatter;->getAffixImpl(ZZ)Ljava/lang/String;
HSPLandroid/icu/number/NumberFormatter;->fromDecimalFormat(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/number/UnlocalizedNumberFormatter;
HSPLandroid/icu/number/NumberFormatter;->with()Landroid/icu/number/UnlocalizedNumberFormatter;
HSPLandroid/icu/number/NumberFormatterImpl;-><init>(Landroid/icu/impl/number/MacroProps;)V
-HSPLandroid/icu/number/NumberFormatterImpl;->format(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/NumberFormatterImpl;->format(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/number/NumberFormatterImpl;Landroid/icu/number/NumberFormatterImpl;
HSPLandroid/icu/number/NumberFormatterImpl;->formatStatic(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffix(BLandroid/icu/impl/StandardPlural;Landroid/icu/impl/FormattedStringBuilder;)I
HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffixImpl(Landroid/icu/impl/number/MicroPropsGenerator;BLandroid/icu/impl/FormattedStringBuilder;)I
HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffixStatic(Landroid/icu/impl/number/MacroProps;BLandroid/icu/impl/StandardPlural;Landroid/icu/impl/FormattedStringBuilder;)I
-HSPLandroid/icu/number/NumberFormatterImpl;->macrosToMicroGenerator(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/MicroProps;Z)Landroid/icu/impl/number/MicroPropsGenerator;+]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/impl/number/MutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/text/NumberingSystem;Landroid/icu/text/NumberingSystem;
-HSPLandroid/icu/number/NumberFormatterImpl;->preProcess(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/NumberFormatterImpl;->macrosToMicroGenerator(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/MicroProps;Z)Landroid/icu/impl/number/MicroPropsGenerator;+]Landroid/icu/impl/number/MutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier;]Landroid/icu/text/NumberingSystem;Landroid/icu/text/NumberingSystem;]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;
+HSPLandroid/icu/number/NumberFormatterImpl;->preProcess(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroPropsGenerator;Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/number/NumberFormatterImpl;->preProcessUnsafe(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
HSPLandroid/icu/number/NumberFormatterImpl;->unitIsBaseUnit(Landroid/icu/util/MeasureUnit;)Z
HSPLandroid/icu/number/NumberFormatterImpl;->unitIsCurrency(Landroid/icu/util/MeasureUnit;)Z
HSPLandroid/icu/number/NumberFormatterImpl;->unitIsPercent(Landroid/icu/util/MeasureUnit;)Z
HSPLandroid/icu/number/NumberFormatterImpl;->unitIsPermille(Landroid/icu/util/MeasureUnit;)Z
-HSPLandroid/icu/number/NumberFormatterImpl;->writeAffixes(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/FormattedStringBuilder;II)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeFractionDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeIntegerDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeNumber(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
+HSPLandroid/icu/number/NumberFormatterImpl;->writeAffixes(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/number/Padder;Landroid/icu/impl/number/Padder;]Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/ConstantMultiFieldModifier;,Landroid/icu/impl/number/ConstantAffixModifier;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeFractionDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeIntegerDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeNumber(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/number/NumberFormatterSettings;-><init>(Landroid/icu/number/NumberFormatterSettings;ILjava/lang/Object;)V
HSPLandroid/icu/number/NumberFormatterSettings;->macros(Landroid/icu/impl/number/MacroProps;)Landroid/icu/number/NumberFormatterSettings;
HSPLandroid/icu/number/NumberFormatterSettings;->perUnit(Landroid/icu/util/MeasureUnit;)Landroid/icu/number/NumberFormatterSettings;
@@ -9476,9 +9518,9 @@ HSPLandroid/icu/number/NumberFormatterSettings;->resolve()Landroid/icu/impl/numb
HSPLandroid/icu/number/NumberFormatterSettings;->unit(Landroid/icu/util/MeasureUnit;)Landroid/icu/number/NumberFormatterSettings;
HSPLandroid/icu/number/NumberFormatterSettings;->unitWidth(Landroid/icu/number/NumberFormatter$UnitWidth;)Landroid/icu/number/NumberFormatterSettings;
HSPLandroid/icu/number/NumberPropertyMapper;->create(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/number/UnlocalizedNumberFormatter;
-HSPLandroid/icu/number/NumberPropertyMapper;->oldToNew(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/MacroProps;
+HSPLandroid/icu/number/NumberPropertyMapper;->oldToNew(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/MacroProps;+]Ljava/math/MathContext;Ljava/math/MathContext;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;,Landroid/icu/number/Precision$CurrencyRounderImpl;]Landroid/icu/number/IntegerWidth;Landroid/icu/number/IntegerWidth;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;]Landroid/icu/number/CurrencyPrecision;Landroid/icu/number/Precision$CurrencyRounderImpl;]Landroid/icu/util/Currency;Landroid/icu/util/Currency;
HSPLandroid/icu/number/Precision$FractionRounderImpl;-><init>(II)V
-HSPLandroid/icu/number/Precision$FractionRounderImpl;->apply(Landroid/icu/impl/number/DecimalQuantity;)V
+HSPLandroid/icu/number/Precision$FractionRounderImpl;->apply(Landroid/icu/impl/number/DecimalQuantity;)V+]Landroid/icu/number/Precision$FractionRounderImpl;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/number/Precision$FractionRounderImpl;->createCopy()Landroid/icu/number/Precision$FractionRounderImpl;
HSPLandroid/icu/number/Precision$FractionRounderImpl;->createCopy()Landroid/icu/number/Precision;
HSPLandroid/icu/number/Precision;->-$$Nest$smgetDisplayMagnitudeFraction(I)I
@@ -9489,7 +9531,7 @@ HSPLandroid/icu/number/Precision;->constructFraction(II)Landroid/icu/number/Frac
HSPLandroid/icu/number/Precision;->constructFromCurrency(Landroid/icu/number/CurrencyPrecision;Landroid/icu/util/Currency;)Landroid/icu/number/Precision;
HSPLandroid/icu/number/Precision;->getDisplayMagnitudeFraction(I)I
HSPLandroid/icu/number/Precision;->getRoundingMagnitudeFraction(I)I
-HSPLandroid/icu/number/Precision;->setResolvedMinFraction(Landroid/icu/impl/number/DecimalQuantity;I)V
+HSPLandroid/icu/number/Precision;->setResolvedMinFraction(Landroid/icu/impl/number/DecimalQuantity;I)V+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
HSPLandroid/icu/number/Precision;->withLocaleData(Landroid/icu/util/Currency;)Landroid/icu/number/Precision;
HSPLandroid/icu/number/Precision;->withMode(Ljava/math/MathContext;)Landroid/icu/number/Precision;
HSPLandroid/icu/number/Scale;->applyTo(Landroid/icu/impl/number/DecimalQuantity;)V
@@ -9538,7 +9580,7 @@ HSPLandroid/icu/text/CollationKey;->toByteArray()[B
HSPLandroid/icu/text/Collator$ServiceShim;-><init>()V
HSPLandroid/icu/text/Collator;-><init>()V
HSPLandroid/icu/text/Collator;->clone()Ljava/lang/Object;
-HSPLandroid/icu/text/Collator;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
+HSPLandroid/icu/text/Collator;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;+]Landroid/icu/text/Collator$ServiceShim;Landroid/icu/text/CollatorServiceShim;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;
HSPLandroid/icu/text/Collator;->getInstance(Ljava/util/Locale;)Landroid/icu/text/Collator;
HSPLandroid/icu/text/Collator;->getShim()Landroid/icu/text/Collator$ServiceShim;
HSPLandroid/icu/text/CollatorServiceShim$CService$1CollatorFactory;->handleCreate(Landroid/icu/util/ULocale;ILandroid/icu/impl/ICUService;)Ljava/lang/Object;
@@ -9546,13 +9588,13 @@ HSPLandroid/icu/text/CollatorServiceShim$CService;->validateFallbackLocale()Ljav
HSPLandroid/icu/text/CollatorServiceShim;-><init>()V
HSPLandroid/icu/text/CollatorServiceShim;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
HSPLandroid/icu/text/CollatorServiceShim;->makeInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
-HSPLandroid/icu/text/ConstrainedFieldPosition;-><init>()V
+HSPLandroid/icu/text/ConstrainedFieldPosition;-><init>()V+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;
HSPLandroid/icu/text/ConstrainedFieldPosition;->constrainField(Ljava/text/Format$Field;)V
HSPLandroid/icu/text/ConstrainedFieldPosition;->getField()Ljava/text/Format$Field;
HSPLandroid/icu/text/ConstrainedFieldPosition;->getFieldValue()Ljava/lang/Object;
HSPLandroid/icu/text/ConstrainedFieldPosition;->getLimit()I
HSPLandroid/icu/text/ConstrainedFieldPosition;->getStart()I
-HSPLandroid/icu/text/ConstrainedFieldPosition;->matchesField(Ljava/text/Format$Field;Ljava/lang/Object;)Z
+HSPLandroid/icu/text/ConstrainedFieldPosition;->matchesField(Ljava/text/Format$Field;Ljava/lang/Object;)Z+]Landroid/icu/text/ConstrainedFieldPosition$ConstraintType;Landroid/icu/text/ConstrainedFieldPosition$ConstraintType;
HSPLandroid/icu/text/ConstrainedFieldPosition;->reset()V
HSPLandroid/icu/text/ConstrainedFieldPosition;->setState(Ljava/text/Format$Field;Ljava/lang/Object;II)V
HSPLandroid/icu/text/CurrencyDisplayNames;-><init>()V
@@ -9605,6 +9647,7 @@ HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/text/DateFo
HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;)V
HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;Landroid/icu/text/DateFormatSymbols$AospExtendedDateFormatSymbols;)V
HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Ljava/lang/String;)V
+HSPLandroid/icu/text/DateFormatSymbols;->loadDayPeriodStrings(Ljava/util/Map;)[Ljava/lang/String;
HSPLandroid/icu/text/DateFormatSymbols;->setLocale(Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;)V
HSPLandroid/icu/text/DateFormatSymbols;->setTimeSeparatorString(Ljava/lang/String;)V
HSPLandroid/icu/text/DateIntervalFormat;-><init>(Ljava/lang/String;Landroid/icu/util/ULocale;Landroid/icu/text/SimpleDateFormat;)V
@@ -9650,7 +9693,7 @@ HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->fieldIsNumeric(I
HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getBasePattern()Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getDistance(Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;ILandroid/icu/text/DateTimePatternGenerator$DistanceInfo;)I
HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getFieldMask()I
-HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->set(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$FormatParser;Z)Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;
+HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->set(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$FormatParser;Z)Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/text/DateTimePatternGenerator$VariableField;Landroid/icu/text/DateTimePatternGenerator$VariableField;]Landroid/icu/text/DateTimePatternGenerator$FormatParser;Landroid/icu/text/DateTimePatternGenerator$FormatParser;]Landroid/icu/text/DateTimePatternGenerator$SkeletonFields;Landroid/icu/text/DateTimePatternGenerator$SkeletonFields;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;
HSPLandroid/icu/text/DateTimePatternGenerator$DisplayWidth;->cldrKey()Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator$DistanceInfo;-><init>()V
HSPLandroid/icu/text/DateTimePatternGenerator$DistanceInfo;->addExtra(I)V
@@ -9662,7 +9705,7 @@ HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->addVariable(Ljava/l
HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->getItems()Ljava/util/List;
HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->quoteLiteral(Ljava/lang/String;)Ljava/lang/Object;
HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;)Landroid/icu/text/DateTimePatternGenerator$FormatParser;
-HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;Z)Landroid/icu/text/DateTimePatternGenerator$FormatParser;
+HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;Z)Landroid/icu/text/DateTimePatternGenerator$FormatParser;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;]Landroid/icu/impl/PatternTokenizer;Landroid/icu/impl/PatternTokenizer;
HSPLandroid/icu/text/DateTimePatternGenerator$PatternInfo;-><init>()V
HSPLandroid/icu/text/DateTimePatternGenerator$PatternWithMatcher;-><init>(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;)V
HSPLandroid/icu/text/DateTimePatternGenerator$PatternWithSkeletonFlag;-><init>(Ljava/lang/String;Z)V
@@ -9705,9 +9748,9 @@ HSPLandroid/icu/text/DateTimePatternGenerator;->getBestPattern(Ljava/lang/String
HSPLandroid/icu/text/DateTimePatternGenerator;->getBestPattern(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;I)Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator;->getBestPattern(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;IZ)Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator;->getBestRaw(Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;ILandroid/icu/text/DateTimePatternGenerator$DistanceInfo;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;)Landroid/icu/text/DateTimePatternGenerator$PatternWithMatcher;
-HSPLandroid/icu/text/DateTimePatternGenerator;->getCLDRFieldAndWidthNumber(Landroid/icu/impl/UResource$Key;)I
+HSPLandroid/icu/text/DateTimePatternGenerator;->getCLDRFieldAndWidthNumber(Landroid/icu/impl/UResource$Key;)I+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Key;
HSPLandroid/icu/text/DateTimePatternGenerator;->getCalendarTypeToUse(Landroid/icu/util/ULocale;)Ljava/lang/String;
-HSPLandroid/icu/text/DateTimePatternGenerator;->getCanonicalIndex(Ljava/lang/String;Z)I
+HSPLandroid/icu/text/DateTimePatternGenerator;->getCanonicalIndex(Ljava/lang/String;Z)I+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator;->getDateTimeFormat()Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator;->getFieldDisplayName(ILandroid/icu/text/DateTimePatternGenerator$DisplayWidth;)Ljava/lang/String;
HSPLandroid/icu/text/DateTimePatternGenerator;->getFilteredPattern(Landroid/icu/text/DateTimePatternGenerator$FormatParser;Ljava/util/BitSet;)Ljava/lang/String;
@@ -9730,8 +9773,8 @@ HSPLandroid/icu/text/DateTimePatternGenerator;->setFieldDisplayName(ILandroid/ic
HSPLandroid/icu/text/DecimalFormat;-><init>(Ljava/lang/String;Landroid/icu/text/DecimalFormatSymbols;)V
HSPLandroid/icu/text/DecimalFormat;-><init>(Ljava/lang/String;Landroid/icu/text/DecimalFormatSymbols;I)V
HSPLandroid/icu/text/DecimalFormat;->clone()Ljava/lang/Object;
-HSPLandroid/icu/text/DecimalFormat;->fieldPositionHelper(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;I)V
-HSPLandroid/icu/text/DecimalFormat;->format(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
+HSPLandroid/icu/text/DecimalFormat;->fieldPositionHelper(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;I)V+]Ljava/text/FieldPosition;Ljava/text/DontCareFieldPosition;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/text/DecimalFormat;->format(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;+]Landroid/icu/number/LocalizedNumberFormatter;Landroid/icu/number/LocalizedNumberFormatter;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
HSPLandroid/icu/text/DecimalFormat;->format(JLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
HSPLandroid/icu/text/DecimalFormat;->getDecimalFormatSymbols()Landroid/icu/text/DecimalFormatSymbols;
HSPLandroid/icu/text/DecimalFormat;->getMaximumFractionDigits()I
@@ -9746,7 +9789,7 @@ HSPLandroid/icu/text/DecimalFormat;->getPositiveSuffix()Ljava/lang/String;
HSPLandroid/icu/text/DecimalFormat;->isParseBigDecimal()Z
HSPLandroid/icu/text/DecimalFormat;->isParseIntegerOnly()Z
HSPLandroid/icu/text/DecimalFormat;->parse(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;
-HSPLandroid/icu/text/DecimalFormat;->refreshFormatter()V
+HSPLandroid/icu/text/DecimalFormat;->refreshFormatter()V+]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/number/UnlocalizedNumberFormatter;Landroid/icu/number/UnlocalizedNumberFormatter;]Landroid/icu/text/DecimalFormat;Landroid/icu/text/DecimalFormat;
HSPLandroid/icu/text/DecimalFormat;->setCurrency(Landroid/icu/util/Currency;)V
HSPLandroid/icu/text/DecimalFormat;->setDecimalSeparatorAlwaysShown(Z)V
HSPLandroid/icu/text/DecimalFormat;->setGroupingUsed(Z)V
@@ -9758,7 +9801,7 @@ HSPLandroid/icu/text/DecimalFormat;->setParseIntegerOnly(Z)V
HSPLandroid/icu/text/DecimalFormat;->setParseStrictMode(Landroid/icu/impl/number/DecimalFormatProperties$ParseMode;)V
HSPLandroid/icu/text/DecimalFormat;->setPropertiesFromPattern(Ljava/lang/String;I)V
HSPLandroid/icu/text/DecimalFormat;->toNumberFormatter()Landroid/icu/number/LocalizedNumberFormatter;
-HSPLandroid/icu/text/DecimalFormat;->toPattern()Ljava/lang/String;+]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
+HSPLandroid/icu/text/DecimalFormat;->toPattern()Ljava/lang/String;
HSPLandroid/icu/text/DecimalFormatSymbols$1;->createInstance(Landroid/icu/util/ULocale;Ljava/lang/Void;)Landroid/icu/text/DecimalFormatSymbols$CacheData;
HSPLandroid/icu/text/DecimalFormatSymbols$1;->createInstance(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/icu/text/DecimalFormatSymbols$CacheData;-><init>(Landroid/icu/util/ULocale;[Ljava/lang/String;[Ljava/lang/String;)V
@@ -9800,7 +9843,7 @@ HSPLandroid/icu/text/DecimalFormatSymbols;->getPlusSignString()Ljava/lang/String
HSPLandroid/icu/text/DecimalFormatSymbols;->getULocale()Landroid/icu/util/ULocale;
HSPLandroid/icu/text/DecimalFormatSymbols;->getZeroDigit()C
HSPLandroid/icu/text/DecimalFormatSymbols;->initSpacingInfo(Landroid/icu/impl/CurrencyData$CurrencySpacingInfo;)V
-HSPLandroid/icu/text/DecimalFormatSymbols;->initialize(Landroid/icu/util/ULocale;Landroid/icu/text/NumberingSystem;)V
+HSPLandroid/icu/text/DecimalFormatSymbols;->initialize(Landroid/icu/util/ULocale;Landroid/icu/text/NumberingSystem;)V+]Landroid/icu/impl/CurrencyData$CurrencyDisplayInfoProvider;Landroid/icu/impl/ICUCurrencyDisplayInfoProvider;]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/CurrencyData$CurrencyDisplayInfo;Landroid/icu/impl/ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo;
HSPLandroid/icu/text/DecimalFormatSymbols;->loadData(Landroid/icu/util/ULocale;)Landroid/icu/text/DecimalFormatSymbols$CacheData;
HSPLandroid/icu/text/DecimalFormatSymbols;->setApproximatelySignString(Ljava/lang/String;)V
HSPLandroid/icu/text/DecimalFormatSymbols;->setCurrency(Landroid/icu/util/Currency;)V
@@ -9996,7 +10039,7 @@ HSPLandroid/icu/text/RuleBasedCollator;->checkNotFrozen()V
HSPLandroid/icu/text/RuleBasedCollator;->clone()Ljava/lang/Object;
HSPLandroid/icu/text/RuleBasedCollator;->cloneAsThawed()Landroid/icu/text/RuleBasedCollator;
HSPLandroid/icu/text/RuleBasedCollator;->compare(Ljava/lang/String;Ljava/lang/String;)I
-HSPLandroid/icu/text/RuleBasedCollator;->doCompare(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
+HSPLandroid/icu/text/RuleBasedCollator;->doCompare(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I+]Landroid/icu/impl/coll/CollationData;Landroid/icu/impl/coll/CollationData;]Landroid/icu/impl/coll/SharedObject$Reference;Landroid/icu/impl/coll/SharedObject$Reference;]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/icu/impl/coll/CollationSettings;Landroid/icu/impl/coll/CollationSettings;
HSPLandroid/icu/text/RuleBasedCollator;->freeze()Landroid/icu/text/Collator;
HSPLandroid/icu/text/RuleBasedCollator;->getCollationBuffer()Landroid/icu/text/RuleBasedCollator$CollationBuffer;
HSPLandroid/icu/text/RuleBasedCollator;->getCollationKey(Ljava/lang/String;)Landroid/icu/text/CollationKey;
@@ -10074,7 +10117,7 @@ HSPLandroid/icu/text/UnicodeSet;->checkFrozen()V
HSPLandroid/icu/text/UnicodeSet;->clear()Landroid/icu/text/UnicodeSet;
HSPLandroid/icu/text/UnicodeSet;->clone()Ljava/lang/Object;
HSPLandroid/icu/text/UnicodeSet;->compact()Landroid/icu/text/UnicodeSet;
-HSPLandroid/icu/text/UnicodeSet;->contains(I)Z
+HSPLandroid/icu/text/UnicodeSet;->contains(I)Z+]Landroid/icu/impl/BMPSet;Landroid/icu/impl/BMPSet;
HSPLandroid/icu/text/UnicodeSet;->contains(Ljava/lang/CharSequence;)Z
HSPLandroid/icu/text/UnicodeSet;->containsAll(Ljava/lang/String;)Z
HSPLandroid/icu/text/UnicodeSet;->findCodePoint(I)I
@@ -10375,17 +10418,19 @@ HSPLandroid/icu/util/ULocale$Builder;->setLanguage(Ljava/lang/String;)Landroid/i
HSPLandroid/icu/util/ULocale$Builder;->setRegion(Ljava/lang/String;)Landroid/icu/util/ULocale$Builder;
HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->getDefault(Landroid/icu/util/ULocale$Category;)Ljava/util/Locale;
HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toLocale(Landroid/icu/util/ULocale;)Ljava/util/Locale;
-HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toULocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;
+HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toULocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Locale;Ljava/util/Locale;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
HSPLandroid/icu/util/ULocale;->-$$Nest$smgetInstance(Landroid/icu/impl/locale/BaseLocale;Landroid/icu/impl/locale/LocaleExtensions;)Landroid/icu/util/ULocale;
HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;)V
HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;Ljava/util/Locale;)V
HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;Ljava/util/Locale;Landroid/icu/util/ULocale-IA;)V
HSPLandroid/icu/util/ULocale;->addLikelySubtags(Landroid/icu/util/ULocale;)Landroid/icu/util/ULocale;
HSPLandroid/icu/util/ULocale;->appendTag(Ljava/lang/String;Ljava/lang/StringBuilder;)V
-HSPLandroid/icu/util/ULocale;->base()Landroid/icu/impl/locale/BaseLocale;
+HSPLandroid/icu/util/ULocale;->base()Landroid/icu/impl/locale/BaseLocale;+]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;]Landroid/icu/impl/LocaleIDParser;Landroid/icu/impl/LocaleIDParser;
HSPLandroid/icu/util/ULocale;->canonicalize(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->createCanonical(Ljava/lang/String;)Landroid/icu/util/ULocale;
+HSPLandroid/icu/util/ULocale;->createLikelySubtagsString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->createTagString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/util/ULocale;->createTagString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->equals(Ljava/lang/Object;)Z
HSPLandroid/icu/util/ULocale;->forLocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;
HSPLandroid/icu/util/ULocale;->getBaseName()Ljava/lang/String;
@@ -10400,7 +10445,7 @@ HSPLandroid/icu/util/ULocale;->getKeywords()Ljava/util/Iterator;
HSPLandroid/icu/util/ULocale;->getKeywords(Ljava/lang/String;)Ljava/util/Iterator;
HSPLandroid/icu/util/ULocale;->getLanguage()Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->getName()Ljava/lang/String;
-HSPLandroid/icu/util/ULocale;->getName(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/util/ULocale;->getName(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/CacheBase;Landroid/icu/util/ULocale$1;
HSPLandroid/icu/util/ULocale;->getRegionForSupplementalData(Landroid/icu/util/ULocale;Z)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->getScript()Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->getScript(Ljava/lang/String;)Ljava/lang/String;
@@ -10411,6 +10456,7 @@ HSPLandroid/icu/util/ULocale;->hashCode()I
HSPLandroid/icu/util/ULocale;->isEmptyString(Ljava/lang/String;)Z
HSPLandroid/icu/util/ULocale;->isKnownCanonicalizedLocale(Ljava/lang/String;)Z
HSPLandroid/icu/util/ULocale;->isRightToLeft()Z
+HSPLandroid/icu/util/ULocale;->lookupLikelySubtags(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->lscvToID(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/icu/util/ULocale;->parseTagString(Ljava/lang/String;[Ljava/lang/String;)I
HSPLandroid/icu/util/ULocale;->setKeywordValue(Ljava/lang/String;Ljava/lang/String;)Landroid/icu/util/ULocale;
@@ -10483,7 +10529,7 @@ HSPLandroid/location/Location;->setVerticalAccuracyMeters(F)V
HSPLandroid/location/Location;->toString()Ljava/lang/String;
HSPLandroid/location/Location;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Landroid/media/AudioAttributes;
-HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/media/AudioAttributes$1;Landroid/media/AudioAttributes$1;
HSPLandroid/media/AudioAttributes$Builder;-><init>()V
HSPLandroid/media/AudioAttributes$Builder;-><init>(Landroid/media/AudioAttributes;)V
HSPLandroid/media/AudioAttributes$Builder;->addTag(Ljava/lang/String;)Landroid/media/AudioAttributes$Builder;
@@ -10509,7 +10555,7 @@ HSPLandroid/media/AudioAttributes;->-$$Nest$fputmTags(Landroid/media/AudioAttrib
HSPLandroid/media/AudioAttributes;->-$$Nest$fputmUsage(Landroid/media/AudioAttributes;I)V
HSPLandroid/media/AudioAttributes;-><init>()V
HSPLandroid/media/AudioAttributes;-><init>(Landroid/media/AudioAttributes-IA;)V
-HSPLandroid/media/AudioAttributes;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/media/AudioAttributes;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/media/AudioAttributes;->areHapticChannelsMuted()Z
HSPLandroid/media/AudioAttributes;->equals(Ljava/lang/Object;)Z
HSPLandroid/media/AudioAttributes;->getAllFlags()I
@@ -10645,7 +10691,7 @@ HSPLandroid/media/AudioPlaybackConfiguration$IPlayerShell;-><init>(Landroid/medi
HSPLandroid/media/AudioPlaybackConfiguration;->getAudioAttributes()Landroid/media/AudioAttributes;
HSPLandroid/media/AudioPlaybackConfiguration;->isActive()Z
HSPLandroid/media/AudioPort$$ExternalSyntheticLambda0;->applyAsInt(Ljava/lang/Object;)I
-HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;Ljava/util/List;[Landroid/media/AudioGain;Ljava/util/List;)V
+HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;Ljava/util/List;[Landroid/media/AudioGain;Ljava/util/List;)V+]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$Head;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;,Ljava/util/stream/ReferencePipeline$4;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;]Landroid/media/AudioProfile;Landroid/media/AudioProfile;]Ljava/util/Set;Ljava/util/HashSet;
HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V
HSPLandroid/media/AudioPort;->handle()Landroid/media/AudioHandle;
HSPLandroid/media/AudioPort;->id()I
@@ -10765,8 +10811,8 @@ HSPLandroid/media/MediaCodec$BufferMap$CodecBuffer;->setByteBuffer(Ljava/nio/Byt
HSPLandroid/media/MediaCodec$BufferMap;-><init>()V
HSPLandroid/media/MediaCodec$BufferMap;-><init>(Landroid/media/MediaCodec$BufferMap-IA;)V
HSPLandroid/media/MediaCodec$BufferMap;->clear()V
-HSPLandroid/media/MediaCodec$BufferMap;->put(ILjava/nio/ByteBuffer;)V
-HSPLandroid/media/MediaCodec$BufferMap;->remove(I)V
+HSPLandroid/media/MediaCodec$BufferMap;->put(ILjava/nio/ByteBuffer;)V+]Landroid/media/MediaCodec$BufferMap$CodecBuffer;Landroid/media/MediaCodec$BufferMap$CodecBuffer;]Ljava/util/Map;Ljava/util/HashMap;
+HSPLandroid/media/MediaCodec$BufferMap;->remove(I)V+]Landroid/media/MediaCodec$BufferMap$CodecBuffer;Landroid/media/MediaCodec$BufferMap$CodecBuffer;]Ljava/util/Map;Ljava/util/HashMap;
HSPLandroid/media/MediaCodec$CryptoInfo$Pattern;-><init>(II)V
HSPLandroid/media/MediaCodec$CryptoInfo$Pattern;->set(II)V
HSPLandroid/media/MediaCodec$CryptoInfo;-><init>()V
@@ -10778,18 +10824,18 @@ HSPLandroid/media/MediaCodec;->configure(Landroid/media/MediaFormat;Landroid/vie
HSPLandroid/media/MediaCodec;->configure(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;Landroid/os/IHwBinder;I)V
HSPLandroid/media/MediaCodec;->createByCodecName(Ljava/lang/String;)Landroid/media/MediaCodec;
HSPLandroid/media/MediaCodec;->dequeueInputBuffer(J)I
-HSPLandroid/media/MediaCodec;->dequeueOutputBuffer(Landroid/media/MediaCodec$BufferInfo;J)I
+HSPLandroid/media/MediaCodec;->dequeueOutputBuffer(Landroid/media/MediaCodec$BufferInfo;J)I+]Landroid/media/MediaCodec$BufferInfo;Landroid/media/MediaCodec$BufferInfo;]Ljava/util/Map;Ljava/util/HashMap;
HSPLandroid/media/MediaCodec;->finalize()V
HSPLandroid/media/MediaCodec;->freeAllTrackedBuffers()V
-HSPLandroid/media/MediaCodec;->getInputBuffer(I)Ljava/nio/ByteBuffer;
-HSPLandroid/media/MediaCodec;->getOutputBuffer(I)Ljava/nio/ByteBuffer;
+HSPLandroid/media/MediaCodec;->getInputBuffer(I)Ljava/nio/ByteBuffer;+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
+HSPLandroid/media/MediaCodec;->getOutputBuffer(I)Ljava/nio/ByteBuffer;+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
HSPLandroid/media/MediaCodec;->getOutputFormat()Landroid/media/MediaFormat;
-HSPLandroid/media/MediaCodec;->lockAndGetContext()J
-HSPLandroid/media/MediaCodec;->queueInputBuffer(IIIJI)V
+HSPLandroid/media/MediaCodec;->lockAndGetContext()J+]Ljava/util/concurrent/locks/Lock;Ljava/util/concurrent/locks/ReentrantLock;
+HSPLandroid/media/MediaCodec;->queueInputBuffer(IIIJI)V+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
HSPLandroid/media/MediaCodec;->release()V
HSPLandroid/media/MediaCodec;->releaseOutputBuffer(IZ)V
-HSPLandroid/media/MediaCodec;->releaseOutputBufferInternal(IZZJ)V
-HSPLandroid/media/MediaCodec;->setAndUnlockContext(J)V
+HSPLandroid/media/MediaCodec;->releaseOutputBufferInternal(IZZJ)V+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;]Ljava/util/Map;Ljava/util/HashMap;
+HSPLandroid/media/MediaCodec;->setAndUnlockContext(J)V+]Ljava/util/concurrent/locks/Lock;Ljava/util/concurrent/locks/ReentrantLock;
HSPLandroid/media/MediaCodec;->start()V
HSPLandroid/media/MediaCodec;->stop()V
HSPLandroid/media/MediaCodecInfo$AudioCapabilities;->applyLevelLimits()V
@@ -11284,6 +11330,10 @@ HSPLandroid/metrics/LogMaker;->setCategory(I)Landroid/metrics/LogMaker;
HSPLandroid/metrics/LogMaker;->setComponentName(Landroid/content/ComponentName;)Landroid/metrics/LogMaker;
HSPLandroid/metrics/LogMaker;->setSubtype(I)Landroid/metrics/LogMaker;
HSPLandroid/metrics/LogMaker;->setType(I)Landroid/metrics/LogMaker;
+HSPLandroid/multiuser/FeatureFlagsImpl;-><init>()V
+HSPLandroid/multiuser/FeatureFlagsImpl;->enableSystemUserOnlyForServicesAndProviders()Z
+HSPLandroid/multiuser/Flags;-><clinit>()V
+HSPLandroid/multiuser/Flags;->enableSystemUserOnlyForServicesAndProviders()Z+]Landroid/multiuser/FeatureFlags;Landroid/multiuser/FeatureFlagsImpl;
HSPLandroid/net/Credentials;-><init>(III)V
HSPLandroid/net/Credentials;->getPid()I
HSPLandroid/net/Credentials;->getUid()I
@@ -11376,8 +11426,8 @@ HSPLandroid/net/TelephonyNetworkSpecifier;->equals(Ljava/lang/Object;)Z
HSPLandroid/net/TelephonyNetworkSpecifier;->hashCode()I
HSPLandroid/net/TelephonyNetworkSpecifier;->toString()Ljava/lang/String;
HSPLandroid/net/TelephonyNetworkSpecifier;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/Uri;
-HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/Uri;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/net/Uri$1;Landroid/net/Uri$1;
HSPLandroid/net/Uri$1;->newArray(I)[Landroid/net/Uri;
HSPLandroid/net/Uri$1;->newArray(I)[Ljava/lang/Object;
HSPLandroid/net/Uri$AbstractHierarchicalUri;-><init>()V
@@ -11412,11 +11462,11 @@ HSPLandroid/net/Uri$Builder;->path(Landroid/net/Uri$PathPart;)Landroid/net/Uri$B
HSPLandroid/net/Uri$Builder;->path(Ljava/lang/String;)Landroid/net/Uri$Builder;
HSPLandroid/net/Uri$Builder;->query(Landroid/net/Uri$Part;)Landroid/net/Uri$Builder;
HSPLandroid/net/Uri$Builder;->scheme(Ljava/lang/String;)Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$Builder;->toString()Ljava/lang/String;
+HSPLandroid/net/Uri$Builder;->toString()Ljava/lang/String;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;
HSPLandroid/net/Uri$HierarchicalUri;-><init>(Ljava/lang/String;Landroid/net/Uri$Part;Landroid/net/Uri$PathPart;Landroid/net/Uri$Part;Landroid/net/Uri$Part;)V
-HSPLandroid/net/Uri$HierarchicalUri;->appendSspTo(Ljava/lang/StringBuilder;)V
-HSPLandroid/net/Uri$HierarchicalUri;->buildUpon()Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$HierarchicalUri;->generatePath(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;,Landroid/net/Uri$Part;
+HSPLandroid/net/Uri$HierarchicalUri;->appendSspTo(Ljava/lang/StringBuilder;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$Part;Landroid/net/Uri$Part;,Landroid/net/Uri$Part$EmptyPart;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$HierarchicalUri;->buildUpon()Landroid/net/Uri$Builder;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;
+HSPLandroid/net/Uri$HierarchicalUri;->generatePath(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;,Landroid/net/Uri$Part;]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->getAuthority()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->getEncodedAuthority()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->getEncodedFragment()Ljava/lang/String;
@@ -11429,7 +11479,7 @@ HSPLandroid/net/Uri$HierarchicalUri;->getQuery()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->getScheme()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->getSchemeSpecificPart()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->isHierarchical()Z
-HSPLandroid/net/Uri$HierarchicalUri;->makeUriString()Ljava/lang/String;
+HSPLandroid/net/Uri$HierarchicalUri;->makeUriString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;
HSPLandroid/net/Uri$HierarchicalUri;->readFrom(Landroid/os/Parcel;)Landroid/net/Uri;
HSPLandroid/net/Uri$HierarchicalUri;->toString()Ljava/lang/String;
HSPLandroid/net/Uri$HierarchicalUri;->writeToParcel(Landroid/os/Parcel;I)V
@@ -11450,13 +11500,13 @@ HSPLandroid/net/Uri$Part;->isEmpty()Z
HSPLandroid/net/Uri$Part;->nonNull(Landroid/net/Uri$Part;)Landroid/net/Uri$Part;
HSPLandroid/net/Uri$PathPart;-><init>(Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/net/Uri$PathPart;->appendDecodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;
-HSPLandroid/net/Uri$PathPart;->appendEncodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->appendEncodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
HSPLandroid/net/Uri$PathPart;->from(Ljava/lang/String;Ljava/lang/String;)Landroid/net/Uri$PathPart;
HSPLandroid/net/Uri$PathPart;->fromDecoded(Ljava/lang/String;)Landroid/net/Uri$PathPart;
HSPLandroid/net/Uri$PathPart;->fromEncoded(Ljava/lang/String;)Landroid/net/Uri$PathPart;
HSPLandroid/net/Uri$PathPart;->getEncoded()Ljava/lang/String;
-HSPLandroid/net/Uri$PathPart;->getPathSegments()Landroid/net/Uri$PathSegments;
-HSPLandroid/net/Uri$PathPart;->makeAbsolute(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->getPathSegments()Landroid/net/Uri$PathSegments;+]Ljava/lang/String;Ljava/lang/String;]Landroid/net/Uri$PathSegmentsBuilder;Landroid/net/Uri$PathSegmentsBuilder;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->makeAbsolute(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$PathSegments;-><init>([Ljava/lang/String;I)V
HSPLandroid/net/Uri$PathSegments;->get(I)Ljava/lang/Object;
HSPLandroid/net/Uri$PathSegments;->get(I)Ljava/lang/String;
@@ -11465,9 +11515,9 @@ HSPLandroid/net/Uri$PathSegmentsBuilder;->add(Ljava/lang/String;)V
HSPLandroid/net/Uri$PathSegmentsBuilder;->build()Landroid/net/Uri$PathSegments;
HSPLandroid/net/Uri$StringUri;-><init>(Ljava/lang/String;)V
HSPLandroid/net/Uri$StringUri;-><init>(Ljava/lang/String;Landroid/net/Uri$StringUri-IA;)V
-HSPLandroid/net/Uri$StringUri;->buildUpon()Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$StringUri;->findFragmentSeparator()I
-HSPLandroid/net/Uri$StringUri;->findSchemeSeparator()I
+HSPLandroid/net/Uri$StringUri;->buildUpon()Landroid/net/Uri$Builder;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;]Landroid/net/Uri$StringUri;Landroid/net/Uri$StringUri;
+HSPLandroid/net/Uri$StringUri;->findFragmentSeparator()I+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->findSchemeSeparator()I+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->getAuthority()Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->getAuthorityPart()Landroid/net/Uri$Part;
HSPLandroid/net/Uri$StringUri;->getEncodedAuthority()Ljava/lang/String;
@@ -11485,11 +11535,11 @@ HSPLandroid/net/Uri$StringUri;->getScheme()Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->getSchemeSpecificPart()Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->isHierarchical()Z
HSPLandroid/net/Uri$StringUri;->isRelative()Z
-HSPLandroid/net/Uri$StringUri;->parseAuthority(Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parseAuthority(Ljava/lang/String;I)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->parseFragment()Ljava/lang/String;
-HSPLandroid/net/Uri$StringUri;->parsePath()Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parsePath()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->parsePath(Ljava/lang/String;I)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/net/Uri$StringUri;->parseQuery()Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parseQuery()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->parseScheme()Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->toString()Ljava/lang/String;
HSPLandroid/net/Uri$StringUri;->writeToParcel(Landroid/os/Parcel;I)V
@@ -11506,8 +11556,8 @@ HSPLandroid/net/Uri;->equals(Ljava/lang/Object;)Z
HSPLandroid/net/Uri;->fromFile(Ljava/io/File;)Landroid/net/Uri;
HSPLandroid/net/Uri;->fromParts(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/net/Uri;->getBooleanQueryParameter(Ljava/lang/String;Z)Z
-HSPLandroid/net/Uri;->getQueryParameter(Ljava/lang/String;)Ljava/lang/String;+]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/net/Uri;->getQueryParameterNames()Ljava/util/Set;+]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Set;Ljava/util/LinkedHashSet;
+HSPLandroid/net/Uri;->getQueryParameter(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
+HSPLandroid/net/Uri;->getQueryParameterNames()Ljava/util/Set;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Set;Ljava/util/LinkedHashSet;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
HSPLandroid/net/Uri;->hashCode()I
HSPLandroid/net/Uri;->isAbsolute()Z
HSPLandroid/net/Uri;->isAllowed(CLjava/lang/String;)Z+]Ljava/lang/String;Ljava/lang/String;
@@ -11517,9 +11567,9 @@ HSPLandroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/net/Uri;->toSafeString()Ljava/lang/String;
HSPLandroid/net/Uri;->withAppendedPath(Landroid/net/Uri;Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/net/Uri;->writeToParcel(Landroid/os/Parcel;Landroid/net/Uri;)V
-HSPLandroid/net/UriCodec;->appendDecoded(Ljava/lang/StringBuilder;Ljava/lang/String;ZLjava/nio/charset/Charset;Z)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/nio/charset/Charset;Lcom/android/icu/charset/CharsetICU;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
+HSPLandroid/net/UriCodec;->appendDecoded(Ljava/lang/StringBuilder;Ljava/lang/String;ZLjava/nio/charset/Charset;Z)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Ljava/nio/charset/Charset;Lcom/android/icu/charset/CharsetICU;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
HSPLandroid/net/UriCodec;->decode(Ljava/lang/String;ZLjava/nio/charset/Charset;Z)Ljava/lang/String;
-HSPLandroid/net/UriCodec;->flushDecodingByteAccumulator(Ljava/lang/StringBuilder;Ljava/nio/charset/CharsetDecoder;Ljava/nio/ByteBuffer;Z)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
+HSPLandroid/net/UriCodec;->flushDecodingByteAccumulator(Ljava/lang/StringBuilder;Ljava/nio/charset/CharsetDecoder;Ljava/nio/ByteBuffer;Z)V+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
HSPLandroid/net/UriCodec;->getNextCharacter(Ljava/lang/String;IILjava/lang/String;)C
HSPLandroid/net/UriCodec;->hexCharToValue(C)I
HSPLandroid/net/WebAddress;-><init>(Ljava/lang/String;)V
@@ -11536,6 +11586,7 @@ HSPLandroid/net/vcn/VcnTransportInfo$1;-><init>()V
HSPLandroid/net/vcn/VcnTransportInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/vcn/VcnTransportInfo;
HSPLandroid/net/vcn/VcnTransportInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/net/vcn/VcnTransportInfo;-><clinit>()V
+HSPLandroid/nfc/NfcFrameworkInitializer;->setNfcServiceManager(Landroid/nfc/NfcServiceManager;)V
HSPLandroid/nfc/NfcServiceManager;-><init>()V
HSPLandroid/nfc/cardemulation/AidGroup$1;->createFromParcel(Landroid/os/Parcel;)Landroid/nfc/cardemulation/AidGroup;
HSPLandroid/nfc/cardemulation/AidGroup$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -11587,13 +11638,13 @@ HSPLandroid/os/AsyncTask;->postResultIfNotInvoked(Ljava/lang/Object;)V
HSPLandroid/os/BaseBundle;-><init>()V
HSPLandroid/os/BaseBundle;-><init>(I)V
HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;)V
-HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;Z)V
+HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;Z)V+]Landroid/os/BaseBundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/BaseBundle;-><init>(Landroid/os/Parcel;I)V
-HSPLandroid/os/BaseBundle;-><init>(Ljava/lang/ClassLoader;I)V+]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;-><init>(Ljava/lang/ClassLoader;I)V+]Ljava/lang/Object;Landroid/os/Bundle;,Landroid/os/PersistableBundle;]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/os/BaseBundle;->clear()V
HSPLandroid/os/BaseBundle;->containsKey(Ljava/lang/String;)Z
HSPLandroid/os/BaseBundle;->deepCopyValue(Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/os/BaseBundle;->getArrayList(Ljava/lang/String;Ljava/lang/Class;)Ljava/util/ArrayList;
HSPLandroid/os/BaseBundle;->getBoolean(Ljava/lang/String;)Z
@@ -11602,9 +11653,9 @@ HSPLandroid/os/BaseBundle;->getBooleanArray(Ljava/lang/String;)[Z
HSPLandroid/os/BaseBundle;->getByteArray(Ljava/lang/String;)[B
HSPLandroid/os/BaseBundle;->getCharSequence(Ljava/lang/String;)Ljava/lang/CharSequence;
HSPLandroid/os/BaseBundle;->getCharSequenceArray(Ljava/lang/String;)[Ljava/lang/CharSequence;
-HSPLandroid/os/BaseBundle;->getFloat(Ljava/lang/String;F)F
+HSPLandroid/os/BaseBundle;->getFloat(Ljava/lang/String;F)F+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Float;Ljava/lang/Float;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;)I
-HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;I)I
+HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;I)I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->getIntArray(Ljava/lang/String;)[I
HSPLandroid/os/BaseBundle;->getIntegerArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
HSPLandroid/os/BaseBundle;->getLong(Ljava/lang/String;)J
@@ -11614,18 +11665,18 @@ HSPLandroid/os/BaseBundle;->getSerializable(Ljava/lang/String;)Ljava/io/Serializ
HSPLandroid/os/BaseBundle;->getSerializable(Ljava/lang/String;Ljava/lang/Class;)Ljava/io/Serializable;
HSPLandroid/os/BaseBundle;->getString(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/os/BaseBundle;->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/os/BaseBundle;->getStringArray(Ljava/lang/String;)[Ljava/lang/String;
+HSPLandroid/os/BaseBundle;->getStringArray(Ljava/lang/String;)[Ljava/lang/String;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->getStringArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValueAt(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->initializeFromParcelLocked(Landroid/os/Parcel;ZZ)V
-HSPLandroid/os/BaseBundle;->isEmpty()Z
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValueAt(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/os/BaseBundle;->initializeFromParcelLocked(Landroid/os/Parcel;ZZ)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/BaseBundle;->isEmpty()Z+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->isEmptyParcel()Z
HSPLandroid/os/BaseBundle;->isEmptyParcel(Landroid/os/Parcel;)Z
HSPLandroid/os/BaseBundle;->isParcelled()Z
-HSPLandroid/os/BaseBundle;->keySet()Ljava/util/Set;+]Landroid/os/BaseBundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/BaseBundle;->keySet()Ljava/util/Set;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->putAll(Landroid/os/PersistableBundle;)V
HSPLandroid/os/BaseBundle;->putAll(Landroid/util/ArrayMap;)V
HSPLandroid/os/BaseBundle;->putBoolean(Ljava/lang/String;Z)V
@@ -11634,7 +11685,7 @@ HSPLandroid/os/BaseBundle;->putByteArray(Ljava/lang/String;[B)V
HSPLandroid/os/BaseBundle;->putCharSequence(Ljava/lang/String;Ljava/lang/CharSequence;)V
HSPLandroid/os/BaseBundle;->putCharSequenceArray(Ljava/lang/String;[Ljava/lang/CharSequence;)V
HSPLandroid/os/BaseBundle;->putDouble(Ljava/lang/String;D)V
-HSPLandroid/os/BaseBundle;->putFloat(Ljava/lang/String;F)V
+HSPLandroid/os/BaseBundle;->putFloat(Ljava/lang/String;F)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
HSPLandroid/os/BaseBundle;->putInt(Ljava/lang/String;I)V
HSPLandroid/os/BaseBundle;->putIntArray(Ljava/lang/String;[I)V
HSPLandroid/os/BaseBundle;->putLong(Ljava/lang/String;J)V
@@ -11644,16 +11695,16 @@ HSPLandroid/os/BaseBundle;->putString(Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/os/BaseBundle;->putStringArray(Ljava/lang/String;[Ljava/lang/String;)V
HSPLandroid/os/BaseBundle;->putStringArrayList(Ljava/lang/String;Ljava/util/ArrayList;)V
HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;)V
-HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;I)V
-HSPLandroid/os/BaseBundle;->recycleParcel(Landroid/os/Parcel;)V
+HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/BaseBundle;->recycleParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/BaseBundle;->remove(Ljava/lang/String;)V
HSPLandroid/os/BaseBundle;->setClassLoader(Ljava/lang/ClassLoader;)V
HSPLandroid/os/BaseBundle;->setShouldDefuse(Z)V
-HSPLandroid/os/BaseBundle;->size()I
-HSPLandroid/os/BaseBundle;->unparcel()V+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->size()I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->unparcel()V+]Landroid/os/BaseBundle;Landroid/os/Bundle;,Landroid/os/PersistableBundle;
HSPLandroid/os/BaseBundle;->unparcel(Z)V
-HSPLandroid/os/BaseBundle;->unwrapLazyValueFromMapLocked(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;]Ljava/util/function/BiFunction;Landroid/os/Parcel$LazyValue;
-HSPLandroid/os/BaseBundle;->writeToParcelInner(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/BaseBundle;->unwrapLazyValueFromMapLocked(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/function/BiFunction;Landroid/os/Parcel$LazyValue;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/os/BaseBundle;->writeToParcelInner(Landroid/os/Parcel;I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/BatteryManager;-><init>(Landroid/content/Context;Lcom/android/internal/app/IBatteryStats;Landroid/os/IBatteryPropertiesRegistrar;)V
HSPLandroid/os/BatteryManager;->getIntProperty(I)I
HSPLandroid/os/BatteryManager;->getLongProperty(I)J
@@ -11720,12 +11771,12 @@ HSPLandroid/os/Binder;->setTransactionCallback(Landroid/os/IBinderCallback;)V
HSPLandroid/os/Binder;->transact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
HSPLandroid/os/Binder;->unlinkToDeath(Landroid/os/IBinder$DeathRecipient;I)Z
HSPLandroid/os/Binder;->withCleanCallingIdentity(Lcom/android/internal/util/FunctionalUtils$ThrowingRunnable;)V
-HSPLandroid/os/BinderProxy$ProxyMap;->get(J)Landroid/os/BinderProxy;+]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/BinderProxy$ProxyMap;->get(J)Landroid/os/BinderProxy;
HSPLandroid/os/BinderProxy$ProxyMap;->hash(J)I
HSPLandroid/os/BinderProxy$ProxyMap;->remove(II)V
HSPLandroid/os/BinderProxy$ProxyMap;->set(JLandroid/os/BinderProxy;)V
HSPLandroid/os/BinderProxy;-><init>(J)V
-HSPLandroid/os/BinderProxy;->getInstance(JJ)Landroid/os/BinderProxy;+]Landroid/os/BinderProxy$ProxyMap;Landroid/os/BinderProxy$ProxyMap;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/os/BinderProxy;->getInstance(JJ)Landroid/os/BinderProxy;
HSPLandroid/os/BinderProxy;->linkToDeath(Landroid/os/IBinder$DeathRecipient;I)V+]Ljava/util/List;Ljava/util/Collections$SynchronizedRandomAccessList;
HSPLandroid/os/BinderProxy;->queryLocalInterface(Ljava/lang/String;)Landroid/os/IInterface;
HSPLandroid/os/BinderProxy;->sendDeathNotice(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V
@@ -11764,7 +11815,7 @@ HSPLandroid/os/Bundle;->getFloat(Ljava/lang/String;F)F
HSPLandroid/os/Bundle;->getIntegerArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
HSPLandroid/os/Bundle;->getParcelable(Ljava/lang/String;)Landroid/os/Parcelable;
HSPLandroid/os/Bundle;->getParcelable(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;)[Landroid/os/Parcelable;
+HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;)[Landroid/os/Parcelable;+]Landroid/os/Bundle;Landroid/os/Bundle;
HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;Ljava/lang/Class;)[Ljava/lang/Object;
HSPLandroid/os/Bundle;->getParcelableArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
HSPLandroid/os/Bundle;->getSerializable(Ljava/lang/String;)Ljava/io/Serializable;
@@ -11772,10 +11823,10 @@ HSPLandroid/os/Bundle;->getSerializable(Ljava/lang/String;Ljava/lang/Class;)Ljav
HSPLandroid/os/Bundle;->getSparseParcelableArray(Ljava/lang/String;)Landroid/util/SparseArray;
HSPLandroid/os/Bundle;->getStringArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
HSPLandroid/os/Bundle;->hasFileDescriptors()Z
-HSPLandroid/os/Bundle;->maybePrefillHasFds()V
+HSPLandroid/os/Bundle;->maybePrefillHasFds()V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Bundle;->putAll(Landroid/os/Bundle;)V
HSPLandroid/os/Bundle;->putBinder(Ljava/lang/String;Landroid/os/IBinder;)V
-HSPLandroid/os/Bundle;->putBundle(Ljava/lang/String;Landroid/os/Bundle;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/Bundle;->putBundle(Ljava/lang/String;Landroid/os/Bundle;)V
HSPLandroid/os/Bundle;->putByteArray(Ljava/lang/String;[B)V
HSPLandroid/os/Bundle;->putCharSequence(Ljava/lang/String;Ljava/lang/CharSequence;)V
HSPLandroid/os/Bundle;->putCharSequenceArray(Ljava/lang/String;[Ljava/lang/CharSequence;)V
@@ -11942,7 +11993,7 @@ HSPLandroid/os/FileObserver;-><init>(Ljava/io/File;I)V
HSPLandroid/os/FileObserver;-><init>(Ljava/lang/String;I)V
HSPLandroid/os/FileObserver;-><init>(Ljava/util/List;I)V
HSPLandroid/os/FileObserver;->startWatching()V
-HSPLandroid/os/FileUtils;->buildValidExtFilename(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/os/FileUtils;->buildValidExtFilename(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;
HSPLandroid/os/FileUtils;->bytesToFile(Ljava/lang/String;[B)V
HSPLandroid/os/FileUtils;->closeQuietly(Ljava/lang/AutoCloseable;)V
HSPLandroid/os/FileUtils;->contains(Ljava/io/File;Ljava/io/File;)Z
@@ -12014,7 +12065,7 @@ HSPLandroid/os/Handler;->obtainMessage(IIILjava/lang/Object;)Landroid/os/Message
HSPLandroid/os/Handler;->obtainMessage(ILjava/lang/Object;)Landroid/os/Message;
HSPLandroid/os/Handler;->post(Ljava/lang/Runnable;)Z+]Landroid/os/Handler;missing_types
HSPLandroid/os/Handler;->postAtFrontOfQueue(Ljava/lang/Runnable;)Z
-HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;J)Z
+HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;J)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;
HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;Ljava/lang/Object;J)Z
HSPLandroid/os/Handler;->postDelayed(Ljava/lang/Runnable;IJ)Z
HSPLandroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z
@@ -12027,7 +12078,7 @@ HSPLandroid/os/Handler;->runWithScissors(Ljava/lang/Runnable;J)Z
HSPLandroid/os/Handler;->sendEmptyMessage(I)Z
HSPLandroid/os/Handler;->sendEmptyMessageAtTime(IJ)Z
HSPLandroid/os/Handler;->sendEmptyMessageDelayed(IJ)Z
-HSPLandroid/os/Handler;->sendMessage(Landroid/os/Message;)Z
+HSPLandroid/os/Handler;->sendMessage(Landroid/os/Message;)Z+]Landroid/os/Handler;missing_types
HSPLandroid/os/Handler;->sendMessageAtFrontOfQueue(Landroid/os/Message;)Z
HSPLandroid/os/Handler;->sendMessageAtTime(Landroid/os/Message;J)Z
HSPLandroid/os/Handler;->sendMessageDelayed(Landroid/os/Message;J)Z+]Landroid/os/Handler;missing_types
@@ -12073,6 +12124,7 @@ HSPLandroid/os/IDeviceIdentifiersPolicyService$Stub;->asInterface(Landroid/os/IB
HSPLandroid/os/IDeviceIdleController$Stub$Proxy;->isPowerSaveWhitelistApp(Ljava/lang/String;)Z
HSPLandroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController;
HSPLandroid/os/IHintManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/os/IHintManager$Stub$Proxy;->createHintSession(Landroid/os/IBinder;[IJ)Landroid/os/IHintSession;
HSPLandroid/os/IHintManager$Stub$Proxy;->getHintSessionPreferredRate()J
HSPLandroid/os/IHintManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IHintManager;
HSPLandroid/os/IHintSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IHintSession;
@@ -12167,14 +12219,14 @@ HSPLandroid/os/IpcDataCache;-><init>(ILjava/lang/String;Ljava/lang/String;Ljava/
HSPLandroid/os/IpcDataCache;-><init>(Landroid/os/IpcDataCache$Config;Landroid/os/IpcDataCache$QueryHandler;)V
HSPLandroid/os/IpcDataCache;-><init>(Landroid/os/IpcDataCache$Config;Landroid/os/IpcDataCache$RemoteCall;)V
HSPLandroid/os/IpcDataCache;->query(Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/LocaleList;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/os/LocaleList$1;Landroid/os/LocaleList$1;
-HSPLandroid/os/LocaleList;-><init>([Ljava/util/Locale;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashSet;Ljava/util/HashSet;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/LocaleList;
+HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/os/LocaleList;-><init>([Ljava/util/Locale;)V
HSPLandroid/os/LocaleList;->computeFirstMatch(Ljava/util/Collection;Z)Ljava/util/Locale;
HSPLandroid/os/LocaleList;->computeFirstMatchIndex(Ljava/util/Collection;Z)I
-HSPLandroid/os/LocaleList;->equals(Ljava/lang/Object;)Z
+HSPLandroid/os/LocaleList;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/util/Locale;
HSPLandroid/os/LocaleList;->findFirstMatchIndex(Ljava/util/Locale;)I
-HSPLandroid/os/LocaleList;->forLanguageTags(Ljava/lang/String;)Landroid/os/LocaleList;+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/os/LocaleList;->forLanguageTags(Ljava/lang/String;)Landroid/os/LocaleList;
HSPLandroid/os/LocaleList;->get(I)Ljava/util/Locale;
HSPLandroid/os/LocaleList;->getAdjustedDefault()Landroid/os/LocaleList;
HSPLandroid/os/LocaleList;->getDefault()Landroid/os/LocaleList;+]Ljava/lang/Object;Ljava/util/Locale;
@@ -12196,10 +12248,10 @@ HSPLandroid/os/Looper;-><init>(Z)V
HSPLandroid/os/Looper;->getMainLooper()Landroid/os/Looper;
HSPLandroid/os/Looper;->getQueue()Landroid/os/MessageQueue;
HSPLandroid/os/Looper;->getThread()Ljava/lang/Thread;
-HSPLandroid/os/Looper;->getThresholdOverride()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Thread;Landroid/os/HandlerThread;
+HSPLandroid/os/Looper;->getThresholdOverride()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Thread;missing_types
HSPLandroid/os/Looper;->isCurrentThread()Z
HSPLandroid/os/Looper;->loop()V
-HSPLandroid/os/Looper;->loopOnce(Landroid/os/Looper;JI)Z+]Landroid/os/Handler;missing_types]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
+HSPLandroid/os/Looper;->loopOnce(Landroid/os/Looper;JI)Z+]Landroid/os/Handler;megamorphic_types]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
HSPLandroid/os/Looper;->myLooper()Landroid/os/Looper;+]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal;
HSPLandroid/os/Looper;->myQueue()Landroid/os/MessageQueue;
HSPLandroid/os/Looper;->prepare()V
@@ -12233,7 +12285,7 @@ HSPLandroid/os/Message;->peekData()Landroid/os/Bundle;
HSPLandroid/os/Message;->readFromParcel(Landroid/os/Parcel;)V
HSPLandroid/os/Message;->recycle()V
HSPLandroid/os/Message;->recycleUnchecked()V
-HSPLandroid/os/Message;->sendToTarget()V
+HSPLandroid/os/Message;->sendToTarget()V+]Landroid/os/Handler;megamorphic_types
HSPLandroid/os/Message;->setAsynchronous(Z)V
HSPLandroid/os/Message;->setCallback(Ljava/lang/Runnable;)Landroid/os/Message;
HSPLandroid/os/Message;->setData(Landroid/os/Bundle;)V
@@ -12252,13 +12304,13 @@ HSPLandroid/os/MessageQueue;->enqueueMessage(Landroid/os/Message;J)Z+]Landroid/o
HSPLandroid/os/MessageQueue;->finalize()V
HSPLandroid/os/MessageQueue;->hasMessages(Landroid/os/Handler;ILjava/lang/Object;)Z
HSPLandroid/os/MessageQueue;->hasMessages(Landroid/os/Handler;Ljava/lang/Runnable;Ljava/lang/Object;)Z
-HSPLandroid/os/MessageQueue;->next()Landroid/os/Message;+]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue$IdleHandler;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/MessageQueue;->next()Landroid/os/Message;+]Landroid/os/MessageQueue$IdleHandler;missing_types]Landroid/os/Message;Landroid/os/Message;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/os/MessageQueue;->postSyncBarrier()I
HSPLandroid/os/MessageQueue;->postSyncBarrier(J)I+]Landroid/os/Message;Landroid/os/Message;
HSPLandroid/os/MessageQueue;->quit(Z)V
HSPLandroid/os/MessageQueue;->removeAllFutureMessagesLocked()V
HSPLandroid/os/MessageQueue;->removeAllMessagesLocked()V
-HSPLandroid/os/MessageQueue;->removeCallbacksAndMessages(Landroid/os/Handler;Ljava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
+HSPLandroid/os/MessageQueue;->removeCallbacksAndMessages(Landroid/os/Handler;Ljava/lang/Object;)V
HSPLandroid/os/MessageQueue;->removeIdleHandler(Landroid/os/MessageQueue$IdleHandler;)V
HSPLandroid/os/MessageQueue;->removeMessages(Landroid/os/Handler;ILjava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
HSPLandroid/os/MessageQueue;->removeMessages(Landroid/os/Handler;Ljava/lang/Runnable;Ljava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
@@ -12279,12 +12331,12 @@ HSPLandroid/os/Parcel$2;-><init>(Landroid/os/Parcel;Ljava/io/InputStream;Ljava/l
HSPLandroid/os/Parcel$2;->resolveClass(Ljava/io/ObjectStreamClass;)Ljava/lang/Class;+]Ljava/io/ObjectStreamClass;Ljava/io/ObjectStreamClass;
HSPLandroid/os/Parcel$LazyValue;-><init>(Landroid/os/Parcel;IIILjava/lang/ClassLoader;)V
HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/os/Parcel$LazyValue;Landroid/os/Parcel$LazyValue;
HSPLandroid/os/Parcel$LazyValue;->writeToParcel(Landroid/os/Parcel;)V
HSPLandroid/os/Parcel$ReadWriteHelper;->readString16(Landroid/os/Parcel;)Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel$ReadWriteHelper;->readString8(Landroid/os/Parcel;)Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel$ReadWriteHelper;->writeString16(Landroid/os/Parcel;Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel$ReadWriteHelper;->writeString8(Landroid/os/Parcel;Ljava/lang/String;)V
+HSPLandroid/os/Parcel$ReadWriteHelper;->writeString8(Landroid/os/Parcel;Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->-$$Nest$mreadValue(Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/os/Parcel;-><init>(J)V
HSPLandroid/os/Parcel;->adoptClassCookies(Landroid/os/Parcel;)V
@@ -12297,21 +12349,21 @@ HSPLandroid/os/Parcel;->createBooleanArray()[Z
HSPLandroid/os/Parcel;->createByteArray()[B
HSPLandroid/os/Parcel;->createException(ILjava/lang/String;)Ljava/lang/Exception;
HSPLandroid/os/Parcel;->createExceptionOrNull(ILjava/lang/String;)Ljava/lang/Exception;
-HSPLandroid/os/Parcel;->createFloatArray()[F+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createFloatArray()[F
HSPLandroid/os/Parcel;->createIntArray()[I+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel;->createLongArray()[J
+HSPLandroid/os/Parcel;->createLongArray()[J+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->createString16Array()[Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->createString8Array()[Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->createStringArray()[Ljava/lang/String;
-HSPLandroid/os/Parcel;->createStringArrayList()Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->createTypedArray(Landroid/os/Parcelable$Creator;)[Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;missing_types
-HSPLandroid/os/Parcel;->createTypedArrayList(Landroid/os/Parcelable$Creator;)Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->createStringArrayList()Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createTypedArray(Landroid/os/Parcelable$Creator;)[Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;missing_types]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createTypedArrayList(Landroid/os/Parcelable$Creator;)Ljava/util/ArrayList;+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->dataAvail()I
HSPLandroid/os/Parcel;->dataPosition()I
HSPLandroid/os/Parcel;->dataSize()I
HSPLandroid/os/Parcel;->destroy()V
HSPLandroid/os/Parcel;->enforceInterface(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->enforceNoDataAvail()V
+HSPLandroid/os/Parcel;->enforceNoDataAvail()V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->ensureReadSquashableParcelables()V
HSPLandroid/os/Parcel;->ensureWithinMemoryLimit(II)V
HSPLandroid/os/Parcel;->finalize()V
@@ -12333,33 +12385,33 @@ HSPLandroid/os/Parcel;->obtain(Landroid/os/IBinder;)Landroid/os/Parcel;
HSPLandroid/os/Parcel;->pushAllowFds(Z)Z
HSPLandroid/os/Parcel;->readArrayList(Ljava/lang/ClassLoader;)Ljava/util/ArrayList;
HSPLandroid/os/Parcel;->readArrayList(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->readArrayListInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;IZZLjava/lang/ClassLoader;)I
+HSPLandroid/os/Parcel;->readArrayListInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;IZZLjava/lang/ClassLoader;)I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;Ljava/lang/ClassLoader;)V
HSPLandroid/os/Parcel;->readArrayMapInternal(Landroid/util/ArrayMap;ILjava/lang/ClassLoader;)V
-HSPLandroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArraySet;Landroid/util/ArraySet;
+HSPLandroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet;
HSPLandroid/os/Parcel;->readBinderList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->readBlob()[B
HSPLandroid/os/Parcel;->readBoolean()Z+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readBooleanArray([Z)V
-HSPLandroid/os/Parcel;->readBundle()Landroid/os/Bundle;
-HSPLandroid/os/Parcel;->readBundle(Ljava/lang/ClassLoader;)Landroid/os/Bundle;
-HSPLandroid/os/Parcel;->readByte()B
+HSPLandroid/os/Parcel;->readBundle()Landroid/os/Bundle;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readBundle(Ljava/lang/ClassLoader;)Landroid/os/Bundle;+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readByte()B+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readByteArray([B)V
HSPLandroid/os/Parcel;->readCallingWorkSourceUid()I
-HSPLandroid/os/Parcel;->readCharSequence()Ljava/lang/CharSequence;
+HSPLandroid/os/Parcel;->readCharSequence()Ljava/lang/CharSequence;+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;
HSPLandroid/os/Parcel;->readCharSequenceArray()[Ljava/lang/CharSequence;
HSPLandroid/os/Parcel;->readDouble()D
-HSPLandroid/os/Parcel;->readException()V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readException()V
HSPLandroid/os/Parcel;->readException(ILjava/lang/String;)V
-HSPLandroid/os/Parcel;->readExceptionCode()I+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readExceptionCode()I
HSPLandroid/os/Parcel;->readFloat()F
HSPLandroid/os/Parcel;->readFloatArray([F)V
HSPLandroid/os/Parcel;->readHashMap(Ljava/lang/ClassLoader;)Ljava/util/HashMap;
HSPLandroid/os/Parcel;->readHashMapInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;Ljava/lang/Class;)Ljava/util/HashMap;
HSPLandroid/os/Parcel;->readInt()I
HSPLandroid/os/Parcel;->readIntArray([I)V
-HSPLandroid/os/Parcel;->readLazyValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;
+HSPLandroid/os/Parcel;->readLazyValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readList(Ljava/util/List;Ljava/lang/ClassLoader;)V
HSPLandroid/os/Parcel;->readList(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)V
HSPLandroid/os/Parcel;->readListInternal(Ljava/util/List;ILjava/lang/ClassLoader;)V
@@ -12373,25 +12425,25 @@ HSPLandroid/os/Parcel;->readParcelable(Ljava/lang/ClassLoader;)Landroid/os/Parce
HSPLandroid/os/Parcel;->readParcelable(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/os/Parcel;->readParcelableArray(Ljava/lang/ClassLoader;)[Landroid/os/Parcelable;
HSPLandroid/os/Parcel;->readParcelableArray(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;
-HSPLandroid/os/Parcel;->readParcelableArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/os/Parcel;->readParcelableArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readParcelableCreator(Ljava/lang/ClassLoader;)Landroid/os/Parcelable$Creator;
-HSPLandroid/os/Parcel;->readParcelableCreatorInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/os/Parcelable$Creator;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/reflect/Field;Ljava/lang/reflect/Field;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/os/Parcel;->readParcelableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types
+HSPLandroid/os/Parcel;->readParcelableCreatorInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/os/Parcelable$Creator;+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Object;Landroid/os/Parcel;]Ljava/lang/reflect/Field;Ljava/lang/reflect/Field;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readParcelableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types]Landroid/os/Parcelable$ClassLoaderCreator;Landroid/content/pm/ParceledListSlice$1;
HSPLandroid/os/Parcel;->readParcelableList(Ljava/util/List;Ljava/lang/ClassLoader;)Ljava/util/List;
HSPLandroid/os/Parcel;->readParcelableList(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;
-HSPLandroid/os/Parcel;->readParcelableListInternal(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->readParcelableListInternal(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;+]Ljava/util/List;Ljava/util/ArrayList;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readPersistableBundle()Landroid/os/PersistableBundle;
HSPLandroid/os/Parcel;->readPersistableBundle(Ljava/lang/ClassLoader;)Landroid/os/PersistableBundle;
HSPLandroid/os/Parcel;->readRawFileDescriptor()Ljava/io/FileDescriptor;
HSPLandroid/os/Parcel;->readSerializable()Ljava/io/Serializable;
-HSPLandroid/os/Parcel;->readSerializableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/io/ObjectInputStream;Landroid/os/Parcel$2;
+HSPLandroid/os/Parcel;->readSerializableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Ljava/io/ObjectInputStream;Landroid/os/Parcel$2;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readSize()Landroid/util/Size;
HSPLandroid/os/Parcel;->readSparseArray(Ljava/lang/ClassLoader;)Landroid/util/SparseArray;
HSPLandroid/os/Parcel;->readSparseArray(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/util/SparseArray;
HSPLandroid/os/Parcel;->readSparseArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/util/SparseArray;
HSPLandroid/os/Parcel;->readSparseIntArray()Landroid/util/SparseIntArray;
HSPLandroid/os/Parcel;->readSparseIntArrayInternal(Landroid/util/SparseIntArray;I)V
-HSPLandroid/os/Parcel;->readSquashed(Landroid/os/Parcel$SquashReadHelper;)Landroid/os/Parcelable;
+HSPLandroid/os/Parcel;->readSquashed(Landroid/os/Parcel$SquashReadHelper;)Landroid/os/Parcelable;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/os/Parcel$SquashReadHelper;Landroid/content/pm/ApplicationInfo$1$$ExternalSyntheticLambda0;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readString()Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readString16()Ljava/lang/String;+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
HSPLandroid/os/Parcel;->readString16Array([Ljava/lang/String;)V
@@ -12402,11 +12454,11 @@ HSPLandroid/os/Parcel;->readStringArray()[Ljava/lang/String;+]Landroid/os/Parcel
HSPLandroid/os/Parcel;->readStringArray([Ljava/lang/String;)V
HSPLandroid/os/Parcel;->readStringList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->readStrongBinder()Landroid/os/IBinder;
-HSPLandroid/os/Parcel;->readTypedArray([Ljava/lang/Object;Landroid/os/Parcelable$Creator;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readTypedArray([Ljava/lang/Object;Landroid/os/Parcelable$Creator;)V
HSPLandroid/os/Parcel;->readTypedList(Ljava/util/List;Landroid/os/Parcelable$Creator;)V
-HSPLandroid/os/Parcel;->readTypedObject(Landroid/os/Parcelable$Creator;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;megamorphic_types
+HSPLandroid/os/Parcel;->readTypedObject(Landroid/os/Parcelable$Creator;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->readValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;
HSPLandroid/os/Parcel;->readValue(Ljava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->recycle()V
@@ -12418,11 +12470,11 @@ HSPLandroid/os/Parcel;->setDataSize(I)V
HSPLandroid/os/Parcel;->setReadWriteHelper(Landroid/os/Parcel$ReadWriteHelper;)V
HSPLandroid/os/Parcel;->unmarshall([BII)V
HSPLandroid/os/Parcel;->writeArrayMap(Landroid/util/ArrayMap;)V
-HSPLandroid/os/Parcel;->writeArrayMapInternal(Landroid/util/ArrayMap;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/Parcel;->writeArrayMapInternal(Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeArraySet(Landroid/util/ArraySet;)V
HSPLandroid/os/Parcel;->writeBinderList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->writeBlob([B)V
-HSPLandroid/os/Parcel;->writeBoolean(Z)V
+HSPLandroid/os/Parcel;->writeBoolean(Z)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeBooleanArray([Z)V
HSPLandroid/os/Parcel;->writeBundle(Landroid/os/Bundle;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeByte(B)V
@@ -12437,38 +12489,38 @@ HSPLandroid/os/Parcel;->writeFloatArray([F)V
HSPLandroid/os/Parcel;->writeInt(I)V
HSPLandroid/os/Parcel;->writeIntArray([I)V
HSPLandroid/os/Parcel;->writeInterfaceToken(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeList(Ljava/util/List;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->writeList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->writeLong(J)V
HSPLandroid/os/Parcel;->writeLongArray([J)V
HSPLandroid/os/Parcel;->writeMap(Ljava/util/Map;)V
HSPLandroid/os/Parcel;->writeMapInternal(Ljava/util/Map;)V
HSPLandroid/os/Parcel;->writeNoException()V
-HSPLandroid/os/Parcel;->writeParcelable(Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable;missing_types
-HSPLandroid/os/Parcel;->writeParcelableArray([Landroid/os/Parcelable;I)V
-HSPLandroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/os/Parcel;->writeParcelable(Landroid/os/Parcelable;I)V+]Landroid/os/Parcelable;missing_types]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeParcelableArray([Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V+]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeParcelableList(Ljava/util/List;I)V
HSPLandroid/os/Parcel;->writePersistableBundle(Landroid/os/PersistableBundle;)V
HSPLandroid/os/Parcel;->writeSerializable(Ljava/io/Serializable;)V
-HSPLandroid/os/Parcel;->writeSparseArray(Landroid/util/SparseArray;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/os/Parcel;->writeSparseArray(Landroid/util/SparseArray;)V
HSPLandroid/os/Parcel;->writeSparseBooleanArray(Landroid/util/SparseBooleanArray;)V
HSPLandroid/os/Parcel;->writeSparseIntArray(Landroid/util/SparseIntArray;)V
HSPLandroid/os/Parcel;->writeString(Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeString16(Ljava/lang/String;)V+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
-HSPLandroid/os/Parcel;->writeString16Array([Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeString16Array([Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeString16NoHelper(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeString8(Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeString8(Ljava/lang/String;)V+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
HSPLandroid/os/Parcel;->writeString8Array([Ljava/lang/String;)V
HSPLandroid/os/Parcel;->writeString8NoHelper(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeStringArray([Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeStringArray([Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeStringList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->writeStrongBinder(Landroid/os/IBinder;)V
-HSPLandroid/os/Parcel;->writeStrongInterface(Landroid/os/IInterface;)V
-HSPLandroid/os/Parcel;->writeTypedArray([Landroid/os/Parcelable;I)V
+HSPLandroid/os/Parcel;->writeStrongInterface(Landroid/os/IInterface;)V+]Landroid/os/IInterface;Landroid/app/LoadedApk$ServiceDispatcher$InnerConnection;,Landroid/app/ActivityThread$ApplicationThread;,Landroid/view/ViewRootImpl$W;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeTypedArray([Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeTypedArrayMap(Landroid/util/ArrayMap;I)V
HSPLandroid/os/Parcel;->writeTypedList(Ljava/util/List;)V
HSPLandroid/os/Parcel;->writeTypedList(Ljava/util/List;I)V
-HSPLandroid/os/Parcel;->writeTypedObject(Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable;Landroid/app/FragmentState;,Landroid/content/Intent;,Landroid/os/Bundle;,Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/os/Parcel;->writeValue(ILjava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Integer;Ljava/lang/Integer;
+HSPLandroid/os/Parcel;->writeTypedObject(Landroid/os/Parcelable;I)V+]Landroid/os/Parcelable;Landroid/view/WindowManager$LayoutParams;,Landroid/content/Intent;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeValue(ILjava/lang/Object;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Long;Ljava/lang/Long;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/Parcel;->writeValue(Ljava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/ParcelFileDescriptor$2;->createFromParcel(Landroid/os/Parcel;)Landroid/os/ParcelFileDescriptor;
HSPLandroid/os/ParcelFileDescriptor$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -12658,7 +12710,7 @@ HSPLandroid/os/ServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinde
HSPLandroid/os/ServiceManager;->getServiceOrThrow(Ljava/lang/String;)Landroid/os/IBinder;
HSPLandroid/os/ServiceManager;->initServiceCache(Ljava/util/Map;)V
HSPLandroid/os/ServiceManager;->isDeclared(Ljava/lang/String;)Z
-HSPLandroid/os/ServiceManager;->rawGetService(Ljava/lang/String;)Landroid/os/IBinder;+]Landroid/os/IServiceManager;Landroid/os/ServiceManagerProxy;]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;
+HSPLandroid/os/ServiceManager;->rawGetService(Ljava/lang/String;)Landroid/os/IBinder;+]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;]Landroid/os/IServiceManager;Landroid/os/ServiceManagerProxy;
HSPLandroid/os/ServiceManager;->waitForDeclaredService(Ljava/lang/String;)Landroid/os/IBinder;
HSPLandroid/os/ServiceManagerProxy;->addService(Ljava/lang/String;Landroid/os/IBinder;ZI)V
HSPLandroid/os/ServiceManagerProxy;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
@@ -12717,7 +12769,7 @@ HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->handleViolationWithTimingAtt
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->lambda$handleViolationWithTimingAttempt$0(Landroid/view/IWindowManager;Ljava/util/ArrayList;)V
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onCustomSlowCall(Ljava/lang/String;)V
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onNetwork()V
-HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onReadFromDisk()V
+HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onReadFromDisk()V+]Landroid/os/StrictMode$AndroidBlockGuardPolicy;Landroid/os/StrictMode$AndroidBlockGuardPolicy;
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onThreadPolicyViolation(Landroid/os/StrictMode$ViolationInfo;)V
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onUnbufferedIO()V
HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onWriteToDisk()V
@@ -12759,7 +12811,7 @@ HSPLandroid/os/StrictMode$ThreadSpanState;-><init>(Landroid/os/StrictMode$Thread
HSPLandroid/os/StrictMode$UnsafeIntentStrictModeCallback;-><init>()V
HSPLandroid/os/StrictMode$UnsafeIntentStrictModeCallback;-><init>(Landroid/os/StrictMode$UnsafeIntentStrictModeCallback-IA;)V
HSPLandroid/os/StrictMode$ViolationInfo;->-$$Nest$fgetmViolation(Landroid/os/StrictMode$ViolationInfo;)Landroid/os/strictmode/Violation;
-HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/Parcel;Z)V
+HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/Parcel;Z)V+]Ljava/util/Deque;Ljava/util/ArrayDeque;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/strictmode/Violation;I)V
HSPLandroid/os/StrictMode$ViolationInfo;->getStackTrace()Ljava/lang/String;
HSPLandroid/os/StrictMode$ViolationInfo;->hashCode()I
@@ -13087,7 +13139,7 @@ HSPLandroid/os/storage/StorageManager;-><init>(Landroid/content/Context;Landroid
HSPLandroid/os/storage/StorageManager;->allocateBytes(Ljava/io/FileDescriptor;JI)V
HSPLandroid/os/storage/StorageManager;->allocateBytes(Ljava/util/UUID;JI)V
HSPLandroid/os/storage/StorageManager;->convert(Ljava/lang/String;)Ljava/util/UUID;
-HSPLandroid/os/storage/StorageManager;->convert(Ljava/util/UUID;)Ljava/lang/String;
+HSPLandroid/os/storage/StorageManager;->convert(Ljava/util/UUID;)Ljava/lang/String;+]Ljava/lang/Object;Ljava/util/UUID;
HSPLandroid/os/storage/StorageManager;->getAllocatableBytes(Ljava/util/UUID;I)J
HSPLandroid/os/storage/StorageManager;->getStorageVolume(Ljava/io/File;I)Landroid/os/storage/StorageVolume;
HSPLandroid/os/storage/StorageManager;->getStorageVolume([Landroid/os/storage/StorageVolume;Ljava/io/File;)Landroid/os/storage/StorageVolume;
@@ -13176,9 +13228,10 @@ HSPLandroid/permission/PermissionManager$SplitPermissionInfo;->getTargetSdk()I
HSPLandroid/permission/PermissionManager;-><clinit>()V
HSPLandroid/permission/PermissionManager;-><init>(Landroid/content/Context;)V
HSPLandroid/permission/PermissionManager;->addOnPermissionsChangeListener(Landroid/content/pm/PackageManager$OnPermissionsChangedListener;)V
-HSPLandroid/permission/PermissionManager;->checkPermissionUncached(Ljava/lang/String;III)I+]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;
+HSPLandroid/permission/PermissionManager;->checkPermissionUncached(Ljava/lang/String;III)I+]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/permission/PermissionManager;->getPermissionFlags(Ljava/lang/String;Ljava/lang/String;Landroid/os/UserHandle;)I
HSPLandroid/permission/PermissionManager;->getPermissionInfo(Ljava/lang/String;I)Landroid/content/pm/PermissionInfo;
+HSPLandroid/permission/PermissionManager;->getPersistentDeviceId(I)Ljava/lang/String;
HSPLandroid/permission/PermissionManager;->getSplitPermissions()Ljava/util/List;
HSPLandroid/permission/PermissionManager;->removeOnPermissionsChangeListener(Landroid/content/pm/PackageManager$OnPermissionsChangedListener;)V
HSPLandroid/permission/PermissionManager;->splitPermissionInfoListToNonParcelableList(Ljava/util/List;)Ljava/util/List;
@@ -13238,15 +13291,15 @@ HSPLandroid/provider/Settings$Global;->getInt(Landroid/content/ContentResolver;L
HSPLandroid/provider/Settings$Global;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
HSPLandroid/provider/Settings$Global;->getLong(Landroid/content/ContentResolver;Ljava/lang/String;J)J
HSPLandroid/provider/Settings$Global;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/provider/Settings$Global;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/provider/Settings$Global;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/provider/Settings$NameValueCache;Landroid/provider/Settings$NameValueCache;]Ljava/util/HashSet;Ljava/util/HashSet;
HSPLandroid/provider/Settings$Global;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/provider/Settings$Global;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
HSPLandroid/provider/Settings$Global;->putLong(Landroid/content/ContentResolver;Ljava/lang/String;J)Z
HSPLandroid/provider/Settings$Global;->putString(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;)Z
HSPLandroid/provider/Settings$Global;->putStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZIZ)Z
HSPLandroid/provider/Settings$NameValueCache$$ExternalSyntheticLambda0;-><init>(Landroid/provider/Settings$NameValueCache;)V
-HSPLandroid/provider/Settings$NameValueCache;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
-HSPLandroid/provider/Settings$NameValueCache;->getStringsForPrefixStripPrefix(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/util/List;)Ljava/util/Map;+]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Landroid/content/IContentProvider;Landroid/content/ContentProvider$Transport;,Landroid/content/ContentProviderProxy;]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/Iterator;Ljava/util/Arrays$ArrayItr;,Ljava/util/HashMap$EntryIterator;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
+HSPLandroid/provider/Settings$NameValueCache;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/content/IContentProvider;Landroid/content/ContentProviderProxy;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
+HSPLandroid/provider/Settings$NameValueCache;->getStringsForPrefixStripPrefix(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/util/List;)Ljava/util/Map;+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;]Ljava/lang/String;Ljava/lang/String;]Landroid/content/IContentProvider;Landroid/content/ContentProviderProxy;,Landroid/content/ContentProvider$Transport;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;,Ljava/util/Arrays$ArrayItr;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
HSPLandroid/provider/Settings$NameValueCache;->isCallerExemptFromReadableRestriction()Z
HSPLandroid/provider/Settings$NameValueCache;->putStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZIZ)Z
HSPLandroid/provider/Settings$NameValueTable;->getUriFor(Landroid/net/Uri;Ljava/lang/String;)Landroid/net/Uri;
@@ -13257,7 +13310,7 @@ HSPLandroid/provider/Settings$Secure;->getIntForUser(Landroid/content/ContentRes
HSPLandroid/provider/Settings$Secure;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)I
HSPLandroid/provider/Settings$Secure;->getLong(Landroid/content/ContentResolver;Ljava/lang/String;J)J
HSPLandroid/provider/Settings$Secure;->getLongForUser(Landroid/content/ContentResolver;Ljava/lang/String;JI)J
-HSPLandroid/provider/Settings$Secure;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/provider/Settings$Secure;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;+]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;
HSPLandroid/provider/Settings$Secure;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
HSPLandroid/provider/Settings$Secure;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/provider/Settings$Secure;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
@@ -13272,7 +13325,7 @@ HSPLandroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;L
HSPLandroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
HSPLandroid/provider/Settings$System;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)I
HSPLandroid/provider/Settings$System;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)I
-HSPLandroid/provider/Settings$System;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/provider/Settings$System;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/provider/Settings$NameValueCache;Landroid/provider/Settings$NameValueCache;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/HashSet;Ljava/util/HashSet;
HSPLandroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
HSPLandroid/provider/Settings$System;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
HSPLandroid/provider/Settings$System;->putIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)Z
@@ -13291,6 +13344,8 @@ HSPLandroid/provider/Settings;->parseLongSettingWithDefault(Ljava/lang/String;J)
HSPLandroid/provider/Telephony$Sms;->getDefaultSmsPackage(Landroid/content/Context;)Ljava/lang/String;
HSPLandroid/renderscript/RenderScriptCacheDir;->setupDiskCache(Ljava/io/File;)V
HSPLandroid/se/omapi/SeServiceManager;-><init>()V
+HSPLandroid/security/FeatureFlagsImpl;-><init>()V
+HSPLandroid/security/Flags;-><clinit>()V
HSPLandroid/security/KeyChain$1;-><init>(Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/CountDownLatch;)V
HSPLandroid/security/KeyChain$1;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
HSPLandroid/security/KeyChain$KeyChainConnection;-><init>(Landroid/content/Context;Landroid/content/ServiceConnection;Landroid/security/IKeyChainService;)V
@@ -13307,6 +13362,7 @@ HSPLandroid/security/KeyStore2;->getKeyEntry(Landroid/system/keystore2/KeyDescri
HSPLandroid/security/KeyStore2;->getKeyStoreException(ILjava/lang/String;)Landroid/security/KeyStoreException;
HSPLandroid/security/KeyStore2;->getService(Z)Landroid/system/keystore2/IKeystoreService;
HSPLandroid/security/KeyStore2;->handleRemoteExceptionWithRetry(Landroid/security/KeyStore2$CheckedRemoteRequest;)Ljava/lang/Object;
+HSPLandroid/security/KeyStore;->getInstance()Landroid/security/KeyStore;
HSPLandroid/security/KeyStoreException;-><init>(ILjava/lang/String;)V
HSPLandroid/security/KeyStoreException;-><init>(ILjava/lang/String;Ljava/lang/String;)V
HSPLandroid/security/KeyStoreException;->getErrorCode()I
@@ -13636,18 +13692,18 @@ HSPLandroid/service/notification/NotificationListenerService$NotificationListene
HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onListenerConnected(Landroid/service/notification/NotificationRankingUpdate;)V
HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationChannelGroupModification(Ljava/lang/String;Landroid/os/UserHandle;Landroid/app/NotificationChannelGroup;I)V
HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationChannelModification(Ljava/lang/String;Landroid/os/UserHandle;Landroid/app/NotificationChannel;I)V
-HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationPosted(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;)V
+HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationPosted(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;)V+]Landroid/os/Handler;Landroid/service/notification/NotificationListenerService$MyHandler;]Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/IStatusBarNotificationHolder$Stub$Proxy;]Landroid/service/notification/StatusBarNotification;Landroid/service/notification/StatusBarNotification;]Landroid/os/Message;Landroid/os/Message;
HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationRankingUpdate(Landroid/service/notification/NotificationRankingUpdate;)V
HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationRemoved(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;Landroid/service/notification/NotificationStats;I)V
HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>()V
-HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Object;Landroid/service/notification/NotificationListenerService$Ranking;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/service/notification/NotificationListenerService$Ranking;->getChannel()Landroid/app/NotificationChannel;
HSPLandroid/service/notification/NotificationListenerService$Ranking;->getKey()Ljava/lang/String;
-HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Landroid/service/notification/NotificationListenerService$Ranking;)V
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Landroid/service/notification/NotificationListenerService$Ranking;)V+]Landroid/service/notification/NotificationListenerService$Ranking;Landroid/service/notification/NotificationListenerService$Ranking;
HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Ljava/lang/String;IZIIILjava/lang/CharSequence;Ljava/lang/String;Landroid/app/NotificationChannel;Ljava/util/ArrayList;Ljava/util/ArrayList;ZIZJZLjava/util/ArrayList;Ljava/util/ArrayList;ZZZLandroid/content/pm/ShortcutInfo;IZIZ)V
HSPLandroid/service/notification/NotificationListenerService$RankingMap$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/NotificationListenerService$RankingMap;
HSPLandroid/service/notification/NotificationListenerService$RankingMap$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/service/notification/NotificationListenerService$RankingMap;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/NotificationListenerService$RankingMap;-><init>(Landroid/os/Parcel;)V+]Landroid/service/notification/NotificationListenerService$Ranking;Landroid/service/notification/NotificationListenerService$Ranking;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;Landroid/service/notification/NotificationListenerService$RankingMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/service/notification/NotificationListenerService$RankingMap;->getOrderedKeys()[Ljava/lang/String;
HSPLandroid/service/notification/NotificationListenerService$RankingMap;->getRanking(Ljava/lang/String;Landroid/service/notification/NotificationListenerService$Ranking;)Z
HSPLandroid/service/notification/NotificationListenerService;-><init>()V
@@ -13676,7 +13732,7 @@ HSPLandroid/service/notification/NotificationRankingUpdate;-><init>(Landroid/os/
HSPLandroid/service/notification/NotificationRankingUpdate;->getRankingMap()Landroid/service/notification/NotificationListenerService$RankingMap;
HSPLandroid/service/notification/StatusBarNotification$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/StatusBarNotification;
HSPLandroid/service/notification/StatusBarNotification$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/service/notification/StatusBarNotification;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/StatusBarNotification;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Lcom/android/internal/logging/InstanceId$1;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/service/notification/StatusBarNotification;->getGroupKey()Ljava/lang/String;
HSPLandroid/service/notification/StatusBarNotification;->getId()I
HSPLandroid/service/notification/StatusBarNotification;->getInstanceId()Lcom/android/internal/logging/InstanceId;
@@ -13695,7 +13751,7 @@ HSPLandroid/service/notification/StatusBarNotification;->groupKey()Ljava/lang/St
HSPLandroid/service/notification/StatusBarNotification;->isAppGroup()Z
HSPLandroid/service/notification/StatusBarNotification;->isGroup()Z
HSPLandroid/service/notification/StatusBarNotification;->isOngoing()Z
-HSPLandroid/service/notification/StatusBarNotification;->key()Ljava/lang/String;
+HSPLandroid/service/notification/StatusBarNotification;->key()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/UserHandle;Landroid/os/UserHandle;
HSPLandroid/service/notification/ZenModeConfig$ZenRule$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/ZenModeConfig$ZenRule;
HSPLandroid/service/notification/ZenModeConfig$ZenRule$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/service/notification/ZenModeConfig$ZenRule;-><init>(Landroid/os/Parcel;)V
@@ -14004,7 +14060,7 @@ HSPLandroid/telecom/PhoneAccountHandle;->getComponentName()Landroid/content/Comp
HSPLandroid/telecom/PhoneAccountHandle;->getId()Ljava/lang/String;
HSPLandroid/telecom/PhoneAccountHandle;->getUserHandle()Landroid/os/UserHandle;
HSPLandroid/telecom/PhoneAccountHandle;->hashCode()I
-HSPLandroid/telecom/PhoneAccountHandle;->toString()Ljava/lang/String;
+HSPLandroid/telecom/PhoneAccountHandle;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ComponentName;Landroid/content/ComponentName;
HSPLandroid/telecom/PhoneAccountHandle;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/telecom/TelecomManager;-><init>(Landroid/content/Context;)V
HSPLandroid/telecom/TelecomManager;-><init>(Landroid/content/Context;Lcom/android/internal/telecom/ITelecomService;)V
@@ -14143,7 +14199,7 @@ HSPLandroid/telephony/ModemActivityInfo;->toString()Ljava/lang/String;
HSPLandroid/telephony/NetworkRegistrationInfo$$ExternalSyntheticLambda0;->apply(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/telephony/NetworkRegistrationInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/NetworkRegistrationInfo;
HSPLandroid/telephony/NetworkRegistrationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/telephony/NetworkRegistrationInfo;)V
HSPLandroid/telephony/NetworkRegistrationInfo;->domainToString(I)Ljava/lang/String;
HSPLandroid/telephony/NetworkRegistrationInfo;->getAccessNetworkTechnology()I
@@ -14167,7 +14223,7 @@ HSPLandroid/telephony/PhoneNumberUtils;->formatNumberToE164(Ljava/lang/String;Lj
HSPLandroid/telephony/PhoneNumberUtils;->getMinMatch()I
HSPLandroid/telephony/PhoneNumberUtils;->isDialable(C)Z
HSPLandroid/telephony/PhoneNumberUtils;->isNonSeparator(C)Z
-HSPLandroid/telephony/PhoneNumberUtils;->normalizeNumber(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/telephony/PhoneNumberUtils;->normalizeNumber(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLandroid/telephony/PhoneNumberUtils;->stripSeparators(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub$$ExternalSyntheticLambda10;->runOrThrow()V
HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub$$ExternalSyntheticLambda19;->runOrThrow()V
@@ -14199,7 +14255,7 @@ HSPLandroid/telephony/Rlog;->d(Ljava/lang/String;Ljava/lang/String;)I
HSPLandroid/telephony/ServiceState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/ServiceState;
HSPLandroid/telephony/ServiceState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/telephony/ServiceState;-><init>()V
-HSPLandroid/telephony/ServiceState;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/telephony/ServiceState;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/telephony/ServiceState;-><init>(Landroid/telephony/ServiceState;)V
HSPLandroid/telephony/ServiceState;->copyFrom(Landroid/telephony/ServiceState;)V
HSPLandroid/telephony/ServiceState;->createLocationInfoSanitizedCopy(Z)Landroid/telephony/ServiceState;
@@ -14239,7 +14295,7 @@ HSPLandroid/telephony/SignalStrength;->getCellSignalStrengths(Ljava/lang/Class;)
HSPLandroid/telephony/SignalStrength;->getLevel()I
HSPLandroid/telephony/SignalStrength;->getPrimary()Landroid/telephony/CellSignalStrength;
HSPLandroid/telephony/SignalStrength;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/SubscriptionInfo;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/telephony/SubscriptionInfo$Builder;Landroid/telephony/SubscriptionInfo$Builder;
+HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/SubscriptionInfo;+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/telephony/SubscriptionInfo$Builder;Landroid/telephony/SubscriptionInfo$Builder;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/telephony/SubscriptionInfo$Builder;->-$$Nest$fgetmAreUiccApplicationsEnabled(Landroid/telephony/SubscriptionInfo$Builder;)Z
HSPLandroid/telephony/SubscriptionInfo$Builder;->-$$Nest$fgetmCardId(Landroid/telephony/SubscriptionInfo$Builder;)I
@@ -14322,6 +14378,8 @@ HSPLandroid/telephony/SubscriptionInfo;->getSubscriptionId()I
HSPLandroid/telephony/SubscriptionInfo;->isEmbedded()Z
HSPLandroid/telephony/SubscriptionInfo;->isOpportunistic()Z
HSPLandroid/telephony/SubscriptionInfo;->toString()Ljava/lang/String;
+HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda10;->applyOrThrow(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda15;->applyOrThrow(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda9;->applyOrThrow(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/telephony/SubscriptionManager$IntegerPropertyInvalidatedCache;->query(Ljava/lang/Integer;)Ljava/lang/Object;
HSPLandroid/telephony/SubscriptionManager$IntegerPropertyInvalidatedCache;->recompute(Ljava/lang/Integer;)Ljava/lang/Object;
@@ -14432,6 +14490,7 @@ HSPLandroid/telephony/TelephonyManager;->getRenouncedPermissions()Ljava/util/Set
HSPLandroid/telephony/TelephonyManager;->getServiceState()Landroid/telephony/ServiceState;
HSPLandroid/telephony/TelephonyManager;->getServiceState(I)Landroid/telephony/ServiceState;
HSPLandroid/telephony/TelephonyManager;->getServiceStateForSubscriber(I)Landroid/telephony/ServiceState;
+HSPLandroid/telephony/TelephonyManager;->getServiceStateForSubscriber(IZZ)Landroid/telephony/ServiceState;
HSPLandroid/telephony/TelephonyManager;->getSignalStrength()Landroid/telephony/SignalStrength;
HSPLandroid/telephony/TelephonyManager;->getSimCarrierId()I
HSPLandroid/telephony/TelephonyManager;->getSimCountryIso()Ljava/lang/String;
@@ -14544,7 +14603,7 @@ HSPLandroid/telephony/data/ApnSetting;->getApnName()Ljava/lang/String;
HSPLandroid/telephony/data/ApnSetting;->getApnTypeBitmask()I
HSPLandroid/telephony/data/ApnSetting;->getApnTypesStringFromBitmask(I)Ljava/lang/String;
HSPLandroid/telephony/data/ApnSetting;->portToString(I)Ljava/lang/String;
-HSPLandroid/telephony/data/ApnSetting;->toString()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Map;Landroid/util/ArrayMap;
+HSPLandroid/telephony/data/ApnSetting;->toString()Ljava/lang/String;
HSPLandroid/telephony/euicc/EuiccManager;->getIEuiccController()Lcom/android/internal/telephony/euicc/IEuiccController;
HSPLandroid/telephony/euicc/EuiccManager;->isEnabled()Z
HSPLandroid/telephony/ims/ImsMmTelManager;->createForSubscriptionId(I)Landroid/telephony/ims/ImsMmTelManager;
@@ -14593,7 +14652,7 @@ HSPLandroid/text/BidiFormatter;->markBefore(Ljava/lang/CharSequence;Landroid/tex
HSPLandroid/text/BidiFormatter;->unicodeWrap(Ljava/lang/CharSequence;Landroid/text/TextDirectionHeuristic;Z)Ljava/lang/CharSequence;
HSPLandroid/text/BoringLayout$Metrics;->-$$Nest$mreset(Landroid/text/BoringLayout$Metrics;)V
HSPLandroid/text/BoringLayout$Metrics;-><init>()V
-HSPLandroid/text/BoringLayout$Metrics;->reset()V+]Landroid/graphics/RectF;Landroid/graphics/RectF;
+HSPLandroid/text/BoringLayout$Metrics;->reset()V
HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;Z)V
HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;ZLandroid/text/TextUtils$TruncateAt;I)V
HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;ZLandroid/text/TextUtils$TruncateAt;IZ)V
@@ -14608,13 +14667,14 @@ HSPLandroid/text/BoringLayout;->getLineCount()I
HSPLandroid/text/BoringLayout;->getLineDescent(I)I
HSPLandroid/text/BoringLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
HSPLandroid/text/BoringLayout;->getLineMax(I)F
-HSPLandroid/text/BoringLayout;->getLineStart(I)I+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/text/BoringLayout;->getLineStart(I)I
HSPLandroid/text/BoringLayout;->getLineTop(I)I
HSPLandroid/text/BoringLayout;->getLineWidth(I)F
HSPLandroid/text/BoringLayout;->getParagraphDirection(I)I
HSPLandroid/text/BoringLayout;->hasAnyInterestingChars(Ljava/lang/CharSequence;I)Z
HSPLandroid/text/BoringLayout;->init(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/Layout$Alignment;Landroid/text/BoringLayout$Metrics;ZZZ)V+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;Landroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;
+HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;ZLandroid/graphics/Paint$FontMetrics;Landroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;+]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Spanned;megamorphic_types]Ljava/lang/CharSequence;megamorphic_types]Landroid/text/TextDirectionHeuristic;Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicLocale;,Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;
HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;ZLandroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;
HSPLandroid/text/BoringLayout;->isFallbackLineSpacingEnabled()Z
HSPLandroid/text/BoringLayout;->make(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;Z)Landroid/text/BoringLayout;
@@ -14629,7 +14689,8 @@ HSPLandroid/text/CharSequenceCharacterIterator;->getEndIndex()I
HSPLandroid/text/CharSequenceCharacterIterator;->getIndex()I
HSPLandroid/text/CharSequenceCharacterIterator;->next()C
HSPLandroid/text/CharSequenceCharacterIterator;->setIndex(I)C
-HSPLandroid/text/DynamicLayout$Builder;->obtain(Ljava/lang/CharSequence;Landroid/text/TextPaint;I)Landroid/text/DynamicLayout$Builder;
+HSPLandroid/text/ClientFlags;->icuBidiMigration()Z
+HSPLandroid/text/DynamicLayout$Builder;->obtain(Ljava/lang/CharSequence;Landroid/text/TextPaint;I)Landroid/text/DynamicLayout$Builder;+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
HSPLandroid/text/DynamicLayout$ChangeWatcher;->afterTextChanged(Landroid/text/Editable;)V
HSPLandroid/text/DynamicLayout$ChangeWatcher;->beforeTextChanged(Ljava/lang/CharSequence;III)V
HSPLandroid/text/DynamicLayout$ChangeWatcher;->onSpanAdded(Landroid/text/Spannable;Ljava/lang/Object;II)V
@@ -14637,29 +14698,29 @@ HSPLandroid/text/DynamicLayout$ChangeWatcher;->onSpanChanged(Landroid/text/Spann
HSPLandroid/text/DynamicLayout$ChangeWatcher;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
HSPLandroid/text/DynamicLayout$ChangeWatcher;->onTextChanged(Ljava/lang/CharSequence;III)V
HSPLandroid/text/DynamicLayout;-><init>(Landroid/text/DynamicLayout$Builder;)V
-HSPLandroid/text/DynamicLayout;->addBlockAtOffset(I)V
-HSPLandroid/text/DynamicLayout;->contentMayProtrudeFromLineTopOrBottom(Ljava/lang/CharSequence;II)Z
+HSPLandroid/text/DynamicLayout;->addBlockAtOffset(I)V+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;
+HSPLandroid/text/DynamicLayout;->contentMayProtrudeFromLineTopOrBottom(Ljava/lang/CharSequence;II)Z+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/graphics/Paint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;
HSPLandroid/text/DynamicLayout;->createBlocks()V
-HSPLandroid/text/DynamicLayout;->generate(Landroid/text/DynamicLayout$Builder;)V
+HSPLandroid/text/DynamicLayout;->generate(Landroid/text/DynamicLayout$Builder;)V+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/method/ReplacementTransformationMethod$SpannedReplacementCharSequence;,Landroid/text/SpannableStringBuilder;]Landroid/text/Spannable;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/DynamicLayout;->getBlockEndLines()[I
HSPLandroid/text/DynamicLayout;->getBlockIndices()[I
HSPLandroid/text/DynamicLayout;->getBlocksAlwaysNeedToBeRedrawn()Landroid/util/ArraySet;
HSPLandroid/text/DynamicLayout;->getEllipsisCount(I)I
HSPLandroid/text/DynamicLayout;->getEllipsisStart(I)I
HSPLandroid/text/DynamicLayout;->getEllipsizedWidth()I
-HSPLandroid/text/DynamicLayout;->getEndHyphenEdit(I)I
+HSPLandroid/text/DynamicLayout;->getEndHyphenEdit(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
HSPLandroid/text/DynamicLayout;->getIndexFirstChangedBlock()I
-HSPLandroid/text/DynamicLayout;->getLineContainsTab(I)Z
-HSPLandroid/text/DynamicLayout;->getLineCount()I
-HSPLandroid/text/DynamicLayout;->getLineDescent(I)I
-HSPLandroid/text/DynamicLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
+HSPLandroid/text/DynamicLayout;->getLineContainsTab(I)Z+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineCount()I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineDescent(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineDirections(I)Landroid/text/Layout$Directions;+]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;
HSPLandroid/text/DynamicLayout;->getLineExtra(I)I
-HSPLandroid/text/DynamicLayout;->getLineStart(I)I
-HSPLandroid/text/DynamicLayout;->getLineTop(I)I
+HSPLandroid/text/DynamicLayout;->getLineStart(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineTop(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
HSPLandroid/text/DynamicLayout;->getNumberOfBlocks()I
-HSPLandroid/text/DynamicLayout;->getParagraphDirection(I)I
-HSPLandroid/text/DynamicLayout;->getStartHyphenEdit(I)I
-HSPLandroid/text/DynamicLayout;->reflow(Ljava/lang/CharSequence;III)V
+HSPLandroid/text/DynamicLayout;->getParagraphDirection(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getStartHyphenEdit(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->reflow(Ljava/lang/CharSequence;III)V+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;]Landroid/text/StaticLayout;Landroid/text/StaticLayout;]Landroid/text/Spanned;Landroid/text/SpannableString;]Ljava/lang/CharSequence;Landroid/text/SpannableString;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;
HSPLandroid/text/DynamicLayout;->setIndexFirstChangedBlock(I)V
HSPLandroid/text/DynamicLayout;->updateAlwaysNeedsToBeRedrawn(I)V
HSPLandroid/text/DynamicLayout;->updateBlocks(III)V
@@ -14674,7 +14735,7 @@ HSPLandroid/text/Html;->fromHtml(Ljava/lang/String;)Landroid/text/Spanned;
HSPLandroid/text/Html;->fromHtml(Ljava/lang/String;I)Landroid/text/Spanned;
HSPLandroid/text/Html;->fromHtml(Ljava/lang/String;ILandroid/text/Html$ImageGetter;Landroid/text/Html$TagHandler;)Landroid/text/Spanned;
HSPLandroid/text/HtmlToSpannedConverter;-><init>(Ljava/lang/String;Landroid/text/Html$ImageGetter;Landroid/text/Html$TagHandler;Lorg/ccil/cowan/tagsoup/Parser;I)V
-HSPLandroid/text/HtmlToSpannedConverter;->characters([CII)V+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/HtmlToSpannedConverter;->characters([CII)V
HSPLandroid/text/HtmlToSpannedConverter;->convert()Landroid/text/Spanned;
HSPLandroid/text/HtmlToSpannedConverter;->end(Landroid/text/Editable;Ljava/lang/Class;Ljava/lang/Object;)V
HSPLandroid/text/HtmlToSpannedConverter;->endA(Landroid/text/Editable;)V
@@ -14683,8 +14744,8 @@ HSPLandroid/text/HtmlToSpannedConverter;->endElement(Ljava/lang/String;Ljava/lan
HSPLandroid/text/HtmlToSpannedConverter;->endPrefixMapping(Ljava/lang/String;)V
HSPLandroid/text/HtmlToSpannedConverter;->getLast(Landroid/text/Spanned;Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/text/HtmlToSpannedConverter;->handleBr(Landroid/text/Editable;)V
-HSPLandroid/text/HtmlToSpannedConverter;->handleEndTag(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/text/HtmlToSpannedConverter;->handleStartTag(Ljava/lang/String;Lorg/xml/sax/Attributes;)V+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/text/HtmlToSpannedConverter;->handleEndTag(Ljava/lang/String;)V
+HSPLandroid/text/HtmlToSpannedConverter;->handleStartTag(Ljava/lang/String;Lorg/xml/sax/Attributes;)V
HSPLandroid/text/HtmlToSpannedConverter;->setDocumentLocator(Lorg/xml/sax/Locator;)V
HSPLandroid/text/HtmlToSpannedConverter;->setSpanFromMark(Landroid/text/Spannable;Ljava/lang/Object;[Ljava/lang/Object;)V
HSPLandroid/text/HtmlToSpannedConverter;->start(Landroid/text/Editable;Ljava/lang/Object;)V
@@ -14702,7 +14763,7 @@ HSPLandroid/text/Layout$Directions;->getRunStart(I)I
HSPLandroid/text/Layout$Directions;->isRunRtl(I)Z
HSPLandroid/text/Layout$Ellipsizer;-><init>(Ljava/lang/CharSequence;)V
HSPLandroid/text/Layout$Ellipsizer;->charAt(I)C
-HSPLandroid/text/Layout$Ellipsizer;->getChars(II[CI)V+]Landroid/text/Layout;Landroid/text/StaticLayout;
+HSPLandroid/text/Layout$Ellipsizer;->getChars(II[CI)V
HSPLandroid/text/Layout$Ellipsizer;->length()I
HSPLandroid/text/Layout$HorizontalMeasurementProvider;->init()V
HSPLandroid/text/Layout$SpannedEllipsizer;->getSpanEnd(Ljava/lang/Object;)I
@@ -14711,12 +14772,13 @@ HSPLandroid/text/Layout$SpannedEllipsizer;->getSpanStart(Ljava/lang/Object;)I
HSPLandroid/text/Layout$SpannedEllipsizer;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
HSPLandroid/text/Layout$SpannedEllipsizer;->nextSpanTransition(IILjava/lang/Class;)I
HSPLandroid/text/Layout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FF)V
+HSPLandroid/text/Layout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;Landroid/text/TextDirectionHeuristic;FFZZILandroid/text/TextUtils$TruncateAt;III[I[IILandroid/graphics/text/LineBreakConfig;ZZLandroid/graphics/Paint$FontMetrics;)V
HSPLandroid/text/Layout;->addSelection(IIIIILandroid/text/Layout$SelectionRectangleConsumer;)V
HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;)V
HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Landroid/graphics/Path;Landroid/graphics/Paint;I)V
-HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;I)V
+HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;I)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
HSPLandroid/text/Layout;->drawBackground(Landroid/graphics/Canvas;II)V
-HSPLandroid/text/Layout;->drawText(Landroid/graphics/Canvas;II)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/Spanned;Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;
+HSPLandroid/text/Layout;->drawText(Landroid/graphics/Canvas;II)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Spanned;Landroid/text/SpannableString;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
HSPLandroid/text/Layout;->drawWithoutText(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;III)V
HSPLandroid/text/Layout;->ellipsize(III[CILandroid/text/TextUtils$TruncateAt;)V
HSPLandroid/text/Layout;->getCursorPath(ILandroid/graphics/Path;Ljava/lang/CharSequence;)V
@@ -14728,30 +14790,30 @@ HSPLandroid/text/Layout;->getHeight(Z)I
HSPLandroid/text/Layout;->getHorizontal(IZ)F
HSPLandroid/text/Layout;->getHorizontal(IZIZ)F
HSPLandroid/text/Layout;->getIndentAdjust(ILandroid/text/Layout$Alignment;)I
-HSPLandroid/text/Layout;->getLineBaseline(I)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineBaseline(I)I
HSPLandroid/text/Layout;->getLineBottom(I)I
HSPLandroid/text/Layout;->getLineBottom(IZ)I
-HSPLandroid/text/Layout;->getLineEnd(I)I
-HSPLandroid/text/Layout;->getLineExtent(ILandroid/text/Layout$TabStops;Z)F+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/text/Layout;->getLineEnd(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineExtent(ILandroid/text/Layout$TabStops;Z)F
HSPLandroid/text/Layout;->getLineExtent(IZ)F
-HSPLandroid/text/Layout;->getLineForOffset(I)I+]Landroid/text/Layout;Landroid/text/StaticLayout;
-HSPLandroid/text/Layout;->getLineForVertical(I)I+]Landroid/text/Layout;Landroid/text/BoringLayout;
+HSPLandroid/text/Layout;->getLineForOffset(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;
+HSPLandroid/text/Layout;->getLineForVertical(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;
HSPLandroid/text/Layout;->getLineLeft(I)F
HSPLandroid/text/Layout;->getLineMax(I)F
-HSPLandroid/text/Layout;->getLineRangeForDraw(Landroid/graphics/Canvas;)J+]Landroid/graphics/Canvas;missing_types]Landroid/text/Layout;Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineRangeForDraw(Landroid/graphics/Canvas;)J+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/text/Layout;->getLineRight(I)F
HSPLandroid/text/Layout;->getLineStartPos(III)I
HSPLandroid/text/Layout;->getLineVisibleEnd(I)I
HSPLandroid/text/Layout;->getLineWidth(I)F
HSPLandroid/text/Layout;->getOffsetAtStartOf(I)I
HSPLandroid/text/Layout;->getOffsetForHorizontal(IF)I
-HSPLandroid/text/Layout;->getOffsetForHorizontal(IFZ)I
+HSPLandroid/text/Layout;->getOffsetForHorizontal(IFZ)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Layout$HorizontalMeasurementProvider;Landroid/text/Layout$HorizontalMeasurementProvider;
HSPLandroid/text/Layout;->getPaint()Landroid/text/TextPaint;
-HSPLandroid/text/Layout;->getParagraphAlignment(I)Landroid/text/Layout$Alignment;
-HSPLandroid/text/Layout;->getParagraphLeadingMargin(I)I
+HSPLandroid/text/Layout;->getParagraphAlignment(I)Landroid/text/Layout$Alignment;+]Landroid/text/Layout;Landroid/text/DynamicLayout;
+HSPLandroid/text/Layout;->getParagraphLeadingMargin(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/text/Spanned;missing_types
HSPLandroid/text/Layout;->getParagraphLeft(I)I
HSPLandroid/text/Layout;->getParagraphRight(I)I
-HSPLandroid/text/Layout;->getParagraphSpans(Landroid/text/Spanned;IILjava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/text/Layout;->getParagraphSpans(Landroid/text/Spanned;IILjava/lang/Class;)[Ljava/lang/Object;+]Landroid/text/Spanned;Landroid/text/SpannableString;
HSPLandroid/text/Layout;->getPrimaryHorizontal(I)F
HSPLandroid/text/Layout;->getPrimaryHorizontal(IZ)F
HSPLandroid/text/Layout;->getSelection(IILandroid/text/Layout$SelectionRectangleConsumer;)V
@@ -14770,7 +14832,8 @@ HSPLandroid/text/Layout;->primaryIsTrailingPrevious(I)Z
HSPLandroid/text/Layout;->replaceWith(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FF)V
HSPLandroid/text/Layout;->shouldClampCursor(I)Z
HSPLandroid/text/MeasuredParagraph;-><init>()V
-HSPLandroid/text/MeasuredParagraph;->applyMetricsAffectingSpan(Landroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;[Landroid/text/style/MetricAffectingSpan;[Landroid/text/style/LineBreakConfigSpan;IILandroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/graphics/text/LineBreakConfig$Builder;Landroid/graphics/text/LineBreakConfig$Builder;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/style/MetricAffectingSpan;missing_types
+HSPLandroid/text/MeasuredParagraph;->applyMetricsAffectingSpan(Landroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;[Landroid/text/style/MetricAffectingSpan;[Landroid/text/style/LineBreakConfigSpan;IILandroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/text/LineBreakConfig$Builder;Landroid/graphics/text/LineBreakConfig$Builder;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/style/MetricAffectingSpan;missing_types
+HSPLandroid/text/MeasuredParagraph;->applyStyleRun(IILandroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;Landroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/text/AutoGrowArray$FloatArray;Landroid/text/AutoGrowArray$FloatArray;]Landroid/graphics/text/MeasuredText$Builder;Landroid/graphics/text/MeasuredText$Builder;]Landroid/text/AutoGrowArray$ByteArray;Landroid/text/AutoGrowArray$ByteArray;]Landroid/text/TextPaint;Landroid/text/TextPaint;
HSPLandroid/text/MeasuredParagraph;->breakText(IZF)I
HSPLandroid/text/MeasuredParagraph;->buildForBidi(Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;Landroid/text/MeasuredParagraph;)Landroid/text/MeasuredParagraph;
HSPLandroid/text/MeasuredParagraph;->buildForMeasurement(Landroid/text/TextPaint;Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;Landroid/text/MeasuredParagraph;)Landroid/text/MeasuredParagraph;
@@ -14789,9 +14852,9 @@ HSPLandroid/text/MeasuredParagraph;->reset()V
HSPLandroid/text/MeasuredParagraph;->resetAndAnalyzeBidi(Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;)V
HSPLandroid/text/PackedIntVector;->adjustValuesBelow(III)V
HSPLandroid/text/PackedIntVector;->deleteAt(II)V
-HSPLandroid/text/PackedIntVector;->getValue(II)I
+HSPLandroid/text/PackedIntVector;->getValue(II)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
HSPLandroid/text/PackedIntVector;->growBuffer()V
-HSPLandroid/text/PackedIntVector;->insertAt(I[I)V
+HSPLandroid/text/PackedIntVector;->insertAt(I[I)V+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
HSPLandroid/text/PackedIntVector;->moveRowGapTo(I)V
HSPLandroid/text/PackedIntVector;->moveValueGapTo(II)V
HSPLandroid/text/PackedIntVector;->size()I
@@ -14799,7 +14862,7 @@ HSPLandroid/text/PackedIntVector;->width()I
HSPLandroid/text/PackedObjectVector;->deleteAt(II)V
HSPLandroid/text/PackedObjectVector;->getValue(II)Ljava/lang/Object;
HSPLandroid/text/PackedObjectVector;->growBuffer()V
-HSPLandroid/text/PackedObjectVector;->insertAt(I[Ljava/lang/Object;)V
+HSPLandroid/text/PackedObjectVector;->insertAt(I[Ljava/lang/Object;)V+]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;
HSPLandroid/text/PackedObjectVector;->moveRowGapTo(I)V
HSPLandroid/text/PackedObjectVector;->setValue(IILjava/lang/Object;)V
HSPLandroid/text/PackedObjectVector;->size()I
@@ -14810,7 +14873,7 @@ HSPLandroid/text/PrecomputedText$Params;->getHyphenationFrequency()I
HSPLandroid/text/PrecomputedText$Params;->getTextDirection()Landroid/text/TextDirectionHeuristic;
HSPLandroid/text/PrecomputedText$Params;->getTextPaint()Landroid/text/TextPaint;
HSPLandroid/text/Selection;->getSelectionEnd(Ljava/lang/CharSequence;)I
-HSPLandroid/text/Selection;->getSelectionStart(Ljava/lang/CharSequence;)I
+HSPLandroid/text/Selection;->getSelectionStart(Ljava/lang/CharSequence;)I+]Landroid/text/Spanned;missing_types
HSPLandroid/text/Selection;->removeMemory(Landroid/text/Spannable;)V
HSPLandroid/text/Selection;->removeSelection(Landroid/text/Spannable;)V
HSPLandroid/text/Selection;->setSelection(Landroid/text/Spannable;I)V
@@ -14820,7 +14883,7 @@ HSPLandroid/text/Selection;->updateMemory(Landroid/text/Spannable;I)V
HSPLandroid/text/SpanSet;-><init>(Ljava/lang/Class;)V
HSPLandroid/text/SpanSet;->getNextTransition(II)I
HSPLandroid/text/SpanSet;->hasSpansIntersecting(II)Z
-HSPLandroid/text/SpanSet;->init(Landroid/text/Spanned;II)V
+HSPLandroid/text/SpanSet;->init(Landroid/text/Spanned;II)V+]Landroid/text/Spanned;Landroid/text/SpannableString;
HSPLandroid/text/SpanSet;->recycle()V
HSPLandroid/text/Spannable$Factory;->getInstance()Landroid/text/Spannable$Factory;
HSPLandroid/text/Spannable$Factory;->newSpannable(Ljava/lang/CharSequence;)Landroid/text/Spannable;
@@ -14838,32 +14901,32 @@ HSPLandroid/text/SpannableString;->setSpan(Ljava/lang/Object;III)V
HSPLandroid/text/SpannableString;->subSequence(II)Ljava/lang/CharSequence;
HSPLandroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;
HSPLandroid/text/SpannableStringBuilder;-><init>()V
-HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;)V
+HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;)V+]Ljava/lang/CharSequence;missing_types
HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;II)V
HSPLandroid/text/SpannableStringBuilder;->append(C)Landroid/text/Editable;
HSPLandroid/text/SpannableStringBuilder;->append(C)Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/Editable;
-HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
+HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->calcMax(I)I
-HSPLandroid/text/SpannableStringBuilder;->change(IILjava/lang/CharSequence;II)V
+HSPLandroid/text/SpannableStringBuilder;->change(IILjava/lang/CharSequence;II)V+]Landroid/text/Spanned;Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->charAt(I)C
-HSPLandroid/text/SpannableStringBuilder;->checkRange(Ljava/lang/String;II)V
+HSPLandroid/text/SpannableStringBuilder;->checkRange(Ljava/lang/String;II)V+]Landroid/text/SpannableStringBuilder;missing_types
HSPLandroid/text/SpannableStringBuilder;->checkSortBuffer([II)[I
HSPLandroid/text/SpannableStringBuilder;->clear()V
HSPLandroid/text/SpannableStringBuilder;->compareSpans(II[I[I)I
-HSPLandroid/text/SpannableStringBuilder;->countSpans(IILjava/lang/Class;I)I
+HSPLandroid/text/SpannableStringBuilder;->countSpans(IILjava/lang/Class;I)I+]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/text/SpannableStringBuilder;->delete(II)Landroid/text/Editable;
HSPLandroid/text/SpannableStringBuilder;->delete(II)Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->drawTextRun(Landroid/graphics/BaseCanvas;IIIIFFZLandroid/graphics/Paint;)V
HSPLandroid/text/SpannableStringBuilder;->equals(Ljava/lang/Object;)Z
HSPLandroid/text/SpannableStringBuilder;->getChars(II[CI)V
-HSPLandroid/text/SpannableStringBuilder;->getSpanEnd(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpanFlags(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpanStart(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/text/SpannableStringBuilder;->getSpanEnd(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpanFlags(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpanStart(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;+]Landroid/text/SpannableStringBuilder;missing_types
HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;Z)[Ljava/lang/Object;
-HSPLandroid/text/SpannableStringBuilder;->getSpansRec(IILjava/lang/Class;I[Ljava/lang/Object;[I[IIZ)I
+HSPLandroid/text/SpannableStringBuilder;->getSpansRec(IILjava/lang/Class;I[Ljava/lang/Object;[I[IIZ)I+]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/text/SpannableStringBuilder;->getTextWatcherDepth()I
HSPLandroid/text/SpannableStringBuilder;->hasNonExclusiveExclusiveSpanAt(Ljava/lang/CharSequence;I)Z
HSPLandroid/text/SpannableStringBuilder;->insert(ILjava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
@@ -14882,48 +14945,48 @@ HSPLandroid/text/SpannableStringBuilder;->removeSpan(Ljava/lang/Object;I)V
HSPLandroid/text/SpannableStringBuilder;->removeSpansForChange(IIZI)Z
HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;)Landroid/text/Editable;
HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
-HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;
+HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->resizeFor(I)V
HSPLandroid/text/SpannableStringBuilder;->resolveGap(I)I
-HSPLandroid/text/SpannableStringBuilder;->restoreInvariants()V
+HSPLandroid/text/SpannableStringBuilder;->restoreInvariants()V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
HSPLandroid/text/SpannableStringBuilder;->rightChild(I)I
HSPLandroid/text/SpannableStringBuilder;->sendAfterTextChanged([Landroid/text/TextWatcher;)V
HSPLandroid/text/SpannableStringBuilder;->sendBeforeTextChanged([Landroid/text/TextWatcher;III)V
-HSPLandroid/text/SpannableStringBuilder;->sendSpanAdded(Ljava/lang/Object;II)V
+HSPLandroid/text/SpannableStringBuilder;->sendSpanAdded(Ljava/lang/Object;II)V+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->sendSpanChanged(Ljava/lang/Object;IIII)V
HSPLandroid/text/SpannableStringBuilder;->sendSpanRemoved(Ljava/lang/Object;II)V
HSPLandroid/text/SpannableStringBuilder;->sendTextChanged([Landroid/text/TextWatcher;III)V
HSPLandroid/text/SpannableStringBuilder;->sendToSpanWatchers(III)V
HSPLandroid/text/SpannableStringBuilder;->setFilters([Landroid/text/InputFilter;)V
HSPLandroid/text/SpannableStringBuilder;->setSpan(Ljava/lang/Object;III)V
-HSPLandroid/text/SpannableStringBuilder;->setSpan(ZLjava/lang/Object;IIIZ)V
+HSPLandroid/text/SpannableStringBuilder;->setSpan(ZLjava/lang/Object;IIIZ)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
HSPLandroid/text/SpannableStringBuilder;->siftDown(I[Ljava/lang/Object;I[I[I)V
HSPLandroid/text/SpannableStringBuilder;->sort([Ljava/lang/Object;[I[I)V
HSPLandroid/text/SpannableStringBuilder;->subSequence(II)Ljava/lang/CharSequence;
-HSPLandroid/text/SpannableStringBuilder;->toString()Ljava/lang/String;
+HSPLandroid/text/SpannableStringBuilder;->toString()Ljava/lang/String;+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringBuilder;->treeRoot()I
HSPLandroid/text/SpannableStringBuilder;->updatedIntervalBound(IIIIZZ)I
-HSPLandroid/text/SpannableStringInternal;-><init>(Ljava/lang/CharSequence;IIZ)V
-HSPLandroid/text/SpannableStringInternal;->charAt(I)C
-HSPLandroid/text/SpannableStringInternal;->checkRange(Ljava/lang/String;II)V
-HSPLandroid/text/SpannableStringInternal;->copySpansFromInternal(Landroid/text/SpannableStringInternal;IIZ)V
-HSPLandroid/text/SpannableStringInternal;->copySpansFromSpanned(Landroid/text/Spanned;IIZ)V
+HSPLandroid/text/SpannableStringInternal;-><init>(Ljava/lang/CharSequence;IIZ)V+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->charAt(I)C+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/text/SpannableStringInternal;->checkRange(Ljava/lang/String;II)V+]Landroid/text/SpannableStringInternal;Landroid/text/SpannedString;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->copySpansFromInternal(Landroid/text/SpannableStringInternal;IIZ)V+]Landroid/text/SpannableStringInternal;Landroid/text/SpannedString;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->copySpansFromSpanned(Landroid/text/Spanned;IIZ)V+]Landroid/text/Spanned;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannableStringInternal;->equals(Ljava/lang/Object;)Z
-HSPLandroid/text/SpannableStringInternal;->getChars(II[CI)V
+HSPLandroid/text/SpannableStringInternal;->getChars(II[CI)V+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/text/SpannableStringInternal;->getSpanEnd(Ljava/lang/Object;)I
HSPLandroid/text/SpannableStringInternal;->getSpanFlags(Ljava/lang/Object;)I
HSPLandroid/text/SpannableStringInternal;->getSpanStart(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringInternal;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
-HSPLandroid/text/SpannableStringInternal;->length()I
+HSPLandroid/text/SpannableStringInternal;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/text/SpannableStringInternal;Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->length()I+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/text/SpannableStringInternal;->nextSpanTransition(IILjava/lang/Class;)I
HSPLandroid/text/SpannableStringInternal;->removeSpan(Ljava/lang/Object;I)V
-HSPLandroid/text/SpannableStringInternal;->sendSpanAdded(Ljava/lang/Object;II)V
+HSPLandroid/text/SpannableStringInternal;->sendSpanAdded(Ljava/lang/Object;II)V+]Landroid/text/SpanWatcher;Landroid/text/DynamicLayout$ChangeWatcher;,Landroid/widget/Editor$SpanController;,Landroid/widget/TextView$ChangeWatcher;]Landroid/text/SpannableStringInternal;Landroid/text/SpannableString;
HSPLandroid/text/SpannableStringInternal;->sendSpanChanged(Ljava/lang/Object;IIII)V
HSPLandroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;III)V
HSPLandroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;IIIZ)V
HSPLandroid/text/SpannableStringInternal;->toString()Ljava/lang/String;
HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;)V
-HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;Z)V
+HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;Z)V+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannableStringBuilder;
HSPLandroid/text/SpannedString;->equals(Ljava/lang/Object;)Z
HSPLandroid/text/SpannedString;->getSpanEnd(Ljava/lang/Object;)I
HSPLandroid/text/SpannedString;->getSpanFlags(Ljava/lang/Object;)I
@@ -14966,8 +15029,9 @@ HSPLandroid/text/StaticLayout$Builder;->setLineSpacing(FF)Landroid/text/StaticLa
HSPLandroid/text/StaticLayout$Builder;->setMaxLines(I)Landroid/text/StaticLayout$Builder;
HSPLandroid/text/StaticLayout$Builder;->setTextDirection(Landroid/text/TextDirectionHeuristic;)Landroid/text/StaticLayout$Builder;
HSPLandroid/text/StaticLayout$Builder;->setUseLineSpacingFromFallbacks(Z)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout;-><init>(Landroid/text/StaticLayout$Builder;ZI)V+]Landroid/text/StaticLayout;Landroid/text/StaticLayout;
HSPLandroid/text/StaticLayout;->calculateEllipsis(IILandroid/text/MeasuredParagraph;IFLandroid/text/TextUtils$TruncateAt;IFLandroid/text/TextPaint;Z)V
-HSPLandroid/text/StaticLayout;->generate(Landroid/text/StaticLayout$Builder;ZZ)V+]Landroid/graphics/text/LineBreaker$Builder;Landroid/graphics/text/LineBreaker$Builder;]Landroid/graphics/text/LineBreaker$ParagraphConstraints;Landroid/graphics/text/LineBreaker$ParagraphConstraints;]Landroid/graphics/text/LineBreaker$Result;Landroid/graphics/text/LineBreaker$Result;]Landroid/graphics/text/LineBreaker;Landroid/graphics/text/LineBreaker;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/text/StaticLayout;->generate(Landroid/text/StaticLayout$Builder;ZZ)V+]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Landroid/graphics/text/LineBreaker$Builder;Landroid/graphics/text/LineBreaker$Builder;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/text/LineBreaker;Landroid/graphics/text/LineBreaker;]Ljava/lang/CharSequence;Landroid/text/SpannableString;]Landroid/graphics/text/LineBreaker$ParagraphConstraints;Landroid/graphics/text/LineBreaker$ParagraphConstraints;]Landroid/graphics/text/LineBreaker$Result;Landroid/graphics/text/LineBreaker$Result;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;
HSPLandroid/text/StaticLayout;->getBottomPadding()I
HSPLandroid/text/StaticLayout;->getEllipsisCount(I)I
HSPLandroid/text/StaticLayout;->getEllipsisStart(I)I
@@ -14977,7 +15041,7 @@ HSPLandroid/text/StaticLayout;->getIndentAdjust(ILandroid/text/Layout$Alignment;
HSPLandroid/text/StaticLayout;->getLineContainsTab(I)Z
HSPLandroid/text/StaticLayout;->getLineCount()I
HSPLandroid/text/StaticLayout;->getLineDescent(I)I
-HSPLandroid/text/StaticLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
+HSPLandroid/text/StaticLayout;->getLineDirections(I)Landroid/text/Layout$Directions;+]Landroid/text/StaticLayout;Landroid/text/StaticLayout;
HSPLandroid/text/StaticLayout;->getLineExtra(I)I
HSPLandroid/text/StaticLayout;->getLineForVertical(I)I
HSPLandroid/text/StaticLayout;->getLineStart(I)I
@@ -14986,38 +15050,43 @@ HSPLandroid/text/StaticLayout;->getParagraphDirection(I)I
HSPLandroid/text/StaticLayout;->getStartHyphenEdit(I)I
HSPLandroid/text/StaticLayout;->getTopPadding()I
HSPLandroid/text/StaticLayout;->getTotalInsets(I)F
-HSPLandroid/text/StaticLayout;->out(Ljava/lang/CharSequence;IIIIIIIFF[Landroid/text/style/LineHeightSpan;[ILandroid/graphics/Paint$FontMetricsInt;ZIZLandroid/text/MeasuredParagraph;IZZZ[CILandroid/text/TextUtils$TruncateAt;FFLandroid/text/TextPaint;Z)I
+HSPLandroid/text/StaticLayout;->out(Ljava/lang/CharSequence;IIIIIIIFF[Landroid/text/style/LineHeightSpan;[ILandroid/graphics/Paint$FontMetricsInt;ZIZLandroid/text/MeasuredParagraph;IZZZ[CILandroid/text/TextUtils$TruncateAt;FFLandroid/text/TextPaint;Z)I+]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
HSPLandroid/text/StaticLayout;->packHyphenEdit(II)I
HSPLandroid/text/StaticLayout;->unpackEndHyphenEdit(I)I
HSPLandroid/text/StaticLayout;->unpackStartHyphenEdit(I)I
HSPLandroid/text/TextDirectionHeuristics$FirstStrong;->checkRtl(Ljava/lang/CharSequence;II)I
-HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->doCheck(Ljava/lang/CharSequence;II)Z+]Landroid/text/TextDirectionHeuristics$TextDirectionAlgorithm;Landroid/text/TextDirectionHeuristics$FirstStrong;]Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;
+HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->doCheck(Ljava/lang/CharSequence;II)Z
HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->isRtl(Ljava/lang/CharSequence;II)Z
HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->isRtl([CII)Z
HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;->defaultIsRtl()Z
HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicLocale;->defaultIsRtl()Z
HSPLandroid/text/TextDirectionHeuristics;->isRtlCodePoint(I)I
HSPLandroid/text/TextFlags;->getKeyForFlag(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextFlags;->isFeatureEnabled(Ljava/lang/String;)Z
HSPLandroid/text/TextLine$DecorationInfo;-><init>()V
HSPLandroid/text/TextLine$DecorationInfo;->copyInfo()Landroid/text/TextLine$DecorationInfo;
HSPLandroid/text/TextLine$DecorationInfo;->hasDecoration()Z
HSPLandroid/text/TextLine;-><init>()V
HSPLandroid/text/TextLine;->adjustEndHyphenEdit(II)I
HSPLandroid/text/TextLine;->adjustStartHyphenEdit(II)I
-HSPLandroid/text/TextLine;->draw(Landroid/graphics/Canvas;FIII)V
+HSPLandroid/text/TextLine;->draw(Landroid/graphics/Canvas;FIII)V+]Landroid/text/Layout$Directions;Landroid/text/Layout$Directions;
HSPLandroid/text/TextLine;->drawStroke(Landroid/text/TextPaint;Landroid/graphics/Canvas;IFFFFF)V
-HSPLandroid/text/TextLine;->drawTextRun(Landroid/graphics/Canvas;Landroid/text/TextPaint;IIIIZFI)V
+HSPLandroid/text/TextLine;->drawTextRun(Landroid/graphics/Canvas;Landroid/text/TextPaint;IIIIZFI)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/text/TextLine;->equalAttributes(Landroid/text/TextPaint;Landroid/text/TextPaint;)Z
-HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/graphics/Paint$FontMetricsInt;Landroid/text/TextPaint;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/graphics/Paint$FontMetricsInt;Landroid/text/TextPaint;)V
HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/text/TextPaint;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
HSPLandroid/text/TextLine;->extractDecorationInfo(Landroid/text/TextPaint;Landroid/text/TextLine$DecorationInfo;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
-HSPLandroid/text/TextLine;->getOffsetBeforeAfter(IIIZIZ)I
+HSPLandroid/text/TextLine;->getOffsetBeforeAfter(IIIZIZ)I+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;
HSPLandroid/text/TextLine;->getOffsetToLeftRightOf(IZ)I
+HSPLandroid/text/TextLine;->getRunAdvance(Landroid/text/TextPaint;IIIIZI[FILandroid/graphics/RectF;Landroid/text/TextLine$LineInfo;)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/PrecomputedText;Landroid/text/PrecomputedText;]Landroid/text/TextPaint;Landroid/text/TextPaint;
HSPLandroid/text/TextLine;->handleReplacement(Landroid/text/style/ReplacementSpan;Landroid/text/TextPaint;IIZLandroid/graphics/Canvas;FIIILandroid/graphics/Paint$FontMetricsInt;Z)F
+HSPLandroid/text/TextLine;->handleRun(IIIZLandroid/graphics/Canvas;Landroid/text/TextShaper$GlyphsConsumer;FIIILandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;Z[FILandroid/text/TextLine$LineInfo;I)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/style/MetricAffectingSpan;megamorphic_types]Landroid/text/style/CharacterStyle;megamorphic_types]Landroid/text/TextPaint;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/text/TextLine$DecorationInfo;Landroid/text/TextLine$DecorationInfo;]Landroid/text/SpanSet;Landroid/text/SpanSet;
+HSPLandroid/text/TextLine;->handleText(Landroid/text/TextPaint;IIIIZLandroid/graphics/Canvas;Landroid/text/TextShaper$GlyphsConsumer;FIIILandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;ZILjava/util/ArrayList;[FILandroid/text/TextLine$LineInfo;I)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;,Landroid/graphics/Canvas;,Landroid/view/Surface$CompatibleCanvas;
HSPLandroid/text/TextLine;->isLineEndSpace(C)Z
+HSPLandroid/text/TextLine;->measure(IZLandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;Landroid/text/TextLine$LineInfo;)F+]Landroid/text/Layout$Directions;Landroid/text/Layout$Directions;]Landroid/text/TextLine;Landroid/text/TextLine;
HSPLandroid/text/TextLine;->obtain()Landroid/text/TextLine;
HSPLandroid/text/TextLine;->recycle(Landroid/text/TextLine;)Landroid/text/TextLine;+]Landroid/text/SpanSet;Landroid/text/SpanSet;
-HSPLandroid/text/TextLine;->set(Landroid/text/TextPaint;Ljava/lang/CharSequence;IIILandroid/text/Layout$Directions;ZLandroid/text/Layout$TabStops;IIZ)V
+HSPLandroid/text/TextLine;->set(Landroid/text/TextPaint;Ljava/lang/CharSequence;IIILandroid/text/Layout$Directions;ZLandroid/text/Layout$TabStops;IIZ)V+]Landroid/text/SpanSet;Landroid/text/SpanSet;
HSPLandroid/text/TextLine;->updateMetrics(Landroid/graphics/Paint$FontMetricsInt;IIIII)V
HSPLandroid/text/TextPaint;-><init>()V
HSPLandroid/text/TextPaint;-><init>(I)V
@@ -15025,8 +15094,8 @@ HSPLandroid/text/TextPaint;-><init>(Landroid/graphics/Paint;)V
HSPLandroid/text/TextPaint;->getUnderlineThickness()F
HSPLandroid/text/TextPaint;->set(Landroid/text/TextPaint;)V
HSPLandroid/text/TextPaint;->setUnderlineText(IF)V
-HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/CharSequence;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/text/TextUtils$1;Landroid/text/TextUtils$1;
HSPLandroid/text/TextUtils$SimpleStringSplitter;-><init>(C)V
HSPLandroid/text/TextUtils$SimpleStringSplitter;->hasNext()Z
HSPLandroid/text/TextUtils$SimpleStringSplitter;->iterator()Ljava/util/Iterator;
@@ -15034,7 +15103,7 @@ HSPLandroid/text/TextUtils$SimpleStringSplitter;->next()Ljava/lang/Object;
HSPLandroid/text/TextUtils$SimpleStringSplitter;->next()Ljava/lang/String;
HSPLandroid/text/TextUtils$SimpleStringSplitter;->setString(Ljava/lang/String;)V
HSPLandroid/text/TextUtils$StringWithRemovedChars;->toString()Ljava/lang/String;
-HSPLandroid/text/TextUtils;->concat([Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
+HSPLandroid/text/TextUtils;->concat([Ljava/lang/CharSequence;)Ljava/lang/CharSequence;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
HSPLandroid/text/TextUtils;->copySpansFrom(Landroid/text/Spanned;IILjava/lang/Class;Landroid/text/Spannable;I)V
HSPLandroid/text/TextUtils;->couldAffectRtl(C)Z
HSPLandroid/text/TextUtils;->doesNotNeedBidi([CII)Z
@@ -15042,23 +15111,23 @@ HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/Tex
HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/TextPaint;FLandroid/text/TextUtils$TruncateAt;ZLandroid/text/TextUtils$EllipsizeCallback;)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/TextPaint;FLandroid/text/TextUtils$TruncateAt;ZLandroid/text/TextUtils$EllipsizeCallback;Landroid/text/TextDirectionHeuristic;Ljava/lang/String;)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->emptyIfNull(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/text/TextUtils;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z
+HSPLandroid/text/TextUtils;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/text/TextUtils;->expandTemplate(Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils;->formatSimple(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;+]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextUtils;->formatSimple(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Boolean;Ljava/lang/Boolean;
HSPLandroid/text/TextUtils;->getCapsMode(Ljava/lang/CharSequence;II)I
-HSPLandroid/text/TextUtils;->getChars(Ljava/lang/CharSequence;II[CI)V+]Landroid/text/GetChars;Landroid/text/Layout$Ellipsizer;,Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;]Ljava/lang/Object;megamorphic_types]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextUtils;->getChars(Ljava/lang/CharSequence;II[CI)V+]Ljava/lang/Object;Landroid/text/SpannableString;]Landroid/text/GetChars;Landroid/text/SpannableString;
HSPLandroid/text/TextUtils;->getEllipsisString(Landroid/text/TextUtils$TruncateAt;)Ljava/lang/String;
HSPLandroid/text/TextUtils;->getLayoutDirectionFromLocale(Ljava/util/Locale;)I
HSPLandroid/text/TextUtils;->getTrimmedLength(Ljava/lang/CharSequence;)I
HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;C)I
HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CI)I
-HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CII)I
+HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CII)I+]Ljava/lang/Object;Landroid/text/SpannableString;
HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;Ljava/lang/CharSequence;II)I
HSPLandroid/text/TextUtils;->isDigitsOnly(Ljava/lang/CharSequence;)Z
-HSPLandroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z+]Ljava/lang/CharSequence;Landroid/text/SpannableStringBuilder;,Ljava/lang/String;
+HSPLandroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z+]Ljava/lang/CharSequence;Ljava/lang/String;
HSPLandroid/text/TextUtils;->isGraphic(Ljava/lang/CharSequence;)Z
-HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;
+HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Iterable;missing_types]Ljava/util/Iterator;missing_types
HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;[Ljava/lang/Object;)Ljava/lang/String;
HSPLandroid/text/TextUtils;->lastIndexOf(Ljava/lang/CharSequence;CI)I
HSPLandroid/text/TextUtils;->lastIndexOf(Ljava/lang/CharSequence;CII)I
@@ -15071,14 +15140,14 @@ HSPLandroid/text/TextUtils;->removeEmptySpans([Ljava/lang/Object;Landroid/text/S
HSPLandroid/text/TextUtils;->safeIntern(Ljava/lang/String;)Ljava/lang/String;
HSPLandroid/text/TextUtils;->split(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
HSPLandroid/text/TextUtils;->stringOrSpannedString(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils;->substring(Ljava/lang/CharSequence;II)Ljava/lang/String;
+HSPLandroid/text/TextUtils;->substring(Ljava/lang/CharSequence;II)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
HSPLandroid/text/TextUtils;->toUpperCase(Ljava/util/Locale;Ljava/lang/CharSequence;Z)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->trimNoCopySpans(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->trimToParcelableSize(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->trimToSize(Ljava/lang/CharSequence;I)Ljava/lang/CharSequence;
HSPLandroid/text/TextUtils;->unpackRangeEndFromLong(J)I
HSPLandroid/text/TextUtils;->unpackRangeStartFromLong(J)I
-HSPLandroid/text/TextUtils;->writeToParcel(Ljava/lang/CharSequence;Landroid/os/Parcel;I)V
+HSPLandroid/text/TextUtils;->writeToParcel(Ljava/lang/CharSequence;Landroid/os/Parcel;I)V+]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;J)Ljava/lang/CharSequence;
HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;Ljava/util/Calendar;)Ljava/lang/CharSequence;
HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;Ljava/util/Date;)Ljava/lang/CharSequence;
@@ -15185,7 +15254,7 @@ HSPLandroid/text/method/TextKeyListener;->onSpanAdded(Landroid/text/Spannable;Lj
HSPLandroid/text/method/TextKeyListener;->onSpanChanged(Landroid/text/Spannable;Ljava/lang/Object;IIII)V
HSPLandroid/text/method/TextKeyListener;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
HSPLandroid/text/method/TextKeyListener;->updatePrefs(Landroid/content/ContentResolver;)V
-HSPLandroid/text/method/Touch;->onTouchEvent(Landroid/widget/TextView;Landroid/text/Spannable;Landroid/view/MotionEvent;)Z
+HSPLandroid/text/method/Touch;->onTouchEvent(Landroid/widget/TextView;Landroid/text/Spannable;Landroid/view/MotionEvent;)Z+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/text/Spannable;Landroid/text/SpannableString;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/text/method/WordIterator;-><init>(Ljava/util/Locale;)V
HSPLandroid/text/method/WordIterator;->checkOffsetIsValid(I)V
HSPLandroid/text/method/WordIterator;->following(I)I
@@ -15204,7 +15273,7 @@ HSPLandroid/text/style/ClickableSpan;->updateDrawState(Landroid/text/TextPaint;)
HSPLandroid/text/style/DynamicDrawableSpan;-><init>(I)V
HSPLandroid/text/style/ForegroundColorSpan;-><init>(I)V
HSPLandroid/text/style/ForegroundColorSpan;->getSpanTypeIdInternal()I
-HSPLandroid/text/style/ForegroundColorSpan;->updateDrawState(Landroid/text/TextPaint;)V
+HSPLandroid/text/style/ForegroundColorSpan;->updateDrawState(Landroid/text/TextPaint;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
HSPLandroid/text/style/ForegroundColorSpan;->writeToParcelInternal(Landroid/os/Parcel;I)V
HSPLandroid/text/style/ImageSpan;-><init>(Landroid/graphics/drawable/Drawable;I)V
HSPLandroid/text/style/ImageSpan;->getDrawable()Landroid/graphics/drawable/Drawable;
@@ -15270,7 +15339,7 @@ HSPLandroid/transition/Transition$2;->onAnimationEnd(Landroid/animation/Animator
HSPLandroid/transition/Transition$2;->onAnimationStart(Landroid/animation/Animator;)V
HSPLandroid/transition/Transition$3;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/transition/Transition;-><init>()V
-HSPLandroid/transition/Transition;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;megamorphic_types
+HSPLandroid/transition/Transition;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Ljava/lang/Object;megamorphic_types]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/transition/Transition;->addListener(Landroid/transition/Transition$TransitionListener;)Landroid/transition/Transition;
HSPLandroid/transition/Transition;->addTarget(Landroid/view/View;)Landroid/transition/Transition;
HSPLandroid/transition/Transition;->addUnmatched(Landroid/util/ArrayMap;Landroid/util/ArrayMap;)V
@@ -15301,7 +15370,7 @@ HSPLandroid/transition/Transition;->setEpicenterCallback(Landroid/transition/Tra
HSPLandroid/transition/Transition;->start()V
HSPLandroid/transition/TransitionInflater;-><init>(Landroid/content/Context;)V
HSPLandroid/transition/TransitionInflater;->createCustom(Landroid/util/AttributeSet;Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/transition/TransitionInflater;->createTransitionFromXml(Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/transition/Transition;)Landroid/transition/Transition;+]Landroid/transition/TransitionSet;Landroid/transition/TransitionSet;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/transition/TransitionInflater;->createTransitionFromXml(Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/transition/Transition;)Landroid/transition/Transition;
HSPLandroid/transition/TransitionInflater;->from(Landroid/content/Context;)Landroid/transition/TransitionInflater;
HSPLandroid/transition/TransitionInflater;->inflateTransition(I)Landroid/transition/Transition;
HSPLandroid/transition/TransitionListenerAdapter;-><init>()V
@@ -15382,7 +15451,7 @@ HSPLandroid/util/ArrayMap;->indexOfNull()I
HSPLandroid/util/ArrayMap;->indexOfValue(Ljava/lang/Object;)I
HSPLandroid/util/ArrayMap;->isEmpty()Z
HSPLandroid/util/ArrayMap;->keyAt(I)Ljava/lang/Object;
-HSPLandroid/util/ArrayMap;->keySet()Ljava/util/Set;
+HSPLandroid/util/ArrayMap;->keySet()Ljava/util/Set;+]Landroid/util/MapCollections;Landroid/util/ArrayMap$1;
HSPLandroid/util/ArrayMap;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;megamorphic_types
HSPLandroid/util/ArrayMap;->putAll(Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
HSPLandroid/util/ArrayMap;->putAll(Ljava/util/Map;)V
@@ -15405,11 +15474,11 @@ HSPLandroid/util/ArraySet;-><init>(IZ)V
HSPLandroid/util/ArraySet;-><init>(Landroid/util/ArraySet;)V
HSPLandroid/util/ArraySet;-><init>(Ljava/util/Collection;)V
HSPLandroid/util/ArraySet;-><init>([Ljava/lang/Object;)V
-HSPLandroid/util/ArraySet;->add(Ljava/lang/Object;)Z
+HSPLandroid/util/ArraySet;->add(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/lang/String;,Landroid/accounts/Account;,Landroid/window/SurfaceSyncGroup$2;,Landroid/net/UidRange;
HSPLandroid/util/ArraySet;->addAll(Landroid/util/ArraySet;)V
HSPLandroid/util/ArraySet;->addAll(Ljava/util/Collection;)Z
HSPLandroid/util/ArraySet;->allocArrays(I)V
-HSPLandroid/util/ArraySet;->append(Ljava/lang/Object;)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/Object;Landroid/app/PendingIntent;,Lcom/android/org/conscrypt/OpenSSLRSAPublicKey;
+HSPLandroid/util/ArraySet;->append(Ljava/lang/Object;)V+]Ljava/lang/Object;Lcom/android/org/conscrypt/OpenSSLRSAPublicKey;,Lcom/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey;
HSPLandroid/util/ArraySet;->binarySearch([II)I
HSPLandroid/util/ArraySet;->clear()V
HSPLandroid/util/ArraySet;->contains(Ljava/lang/Object;)Z
@@ -15447,11 +15516,11 @@ HSPLandroid/util/Base64$Decoder;-><init>(I[B)V
HSPLandroid/util/Base64$Decoder;->process([BIIZ)Z
HSPLandroid/util/Base64$Encoder;-><init>(I[B)V
HSPLandroid/util/Base64$Encoder;->process([BIIZ)Z
-HSPLandroid/util/Base64;->decode(Ljava/lang/String;I)[B+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/util/Base64;->decode(Ljava/lang/String;I)[B
HSPLandroid/util/Base64;->decode([BI)[B
HSPLandroid/util/Base64;->decode([BIII)[B+]Landroid/util/Base64$Decoder;Landroid/util/Base64$Decoder;
HSPLandroid/util/Base64;->encode([BI)[B
-HSPLandroid/util/Base64;->encode([BIII)[B+]Landroid/util/Base64$Encoder;Landroid/util/Base64$Encoder;
+HSPLandroid/util/Base64;->encode([BIII)[B
HSPLandroid/util/Base64;->encodeToString([BI)Ljava/lang/String;
HSPLandroid/util/Base64;->encodeToString([BIII)Ljava/lang/String;
HSPLandroid/util/CloseGuard;-><init>()V
@@ -15467,7 +15536,7 @@ HSPLandroid/util/DisplayMetrics;->setTo(Landroid/util/DisplayMetrics;)V
HSPLandroid/util/DisplayMetrics;->setToDefaults()V
HSPLandroid/util/DisplayUtils;->getDisplayUniqueIdConfigIndex(Landroid/content/res/Resources;Ljava/lang/String;)I
HSPLandroid/util/EventLog$Event;-><init>([B)V
-HSPLandroid/util/EventLog$Event;->decodeObject()Ljava/lang/Object;
+HSPLandroid/util/EventLog$Event;->decodeObject()Ljava/lang/Object;+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
HSPLandroid/util/EventLog$Event;->getData()Ljava/lang/Object;
HSPLandroid/util/EventLog$Event;->getHeaderSize()I
HSPLandroid/util/EventLog$Event;->getUid()I
@@ -15495,7 +15564,7 @@ HSPLandroid/util/IndentingPrintWriter;->write(Ljava/lang/String;II)V
HSPLandroid/util/IndentingPrintWriter;->write([CII)V
HSPLandroid/util/IntArray;-><init>()V
HSPLandroid/util/IntArray;-><init>(I)V
-HSPLandroid/util/IntArray;->add(I)V+]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/util/IntArray;->add(I)V
HSPLandroid/util/IntArray;->add(II)V
HSPLandroid/util/IntArray;->addAll(Landroid/util/IntArray;)V
HSPLandroid/util/IntArray;->binarySearch(I)I
@@ -15552,9 +15621,9 @@ HSPLandroid/util/JsonWriter;->flush()V
HSPLandroid/util/JsonWriter;->name(Ljava/lang/String;)Landroid/util/JsonWriter;
HSPLandroid/util/JsonWriter;->newline()V
HSPLandroid/util/JsonWriter;->open(Landroid/util/JsonScope;Ljava/lang/String;)Landroid/util/JsonWriter;
-HSPLandroid/util/JsonWriter;->peek()Landroid/util/JsonScope;
-HSPLandroid/util/JsonWriter;->replaceTop(Landroid/util/JsonScope;)V
-HSPLandroid/util/JsonWriter;->string(Ljava/lang/String;)V
+HSPLandroid/util/JsonWriter;->peek()Landroid/util/JsonScope;+]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/util/JsonWriter;->replaceTop(Landroid/util/JsonScope;)V+]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/util/JsonWriter;->string(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/io/Writer;Ljava/io/BufferedWriter;
HSPLandroid/util/JsonWriter;->value(J)Landroid/util/JsonWriter;
HSPLandroid/util/JsonWriter;->value(Ljava/lang/String;)Landroid/util/JsonWriter;
HSPLandroid/util/JsonWriter;->value(Z)Landroid/util/JsonWriter;
@@ -15627,21 +15696,21 @@ HSPLandroid/util/LruCache;-><init>(I)V
HSPLandroid/util/LruCache;->create(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/util/LruCache;->entryRemoved(ZLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
HSPLandroid/util/LruCache;->evictAll()V
-HSPLandroid/util/LruCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/util/LruCache;->get(Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;missing_types
HSPLandroid/util/LruCache;->hitCount()I
HSPLandroid/util/LruCache;->maxSize()I
HSPLandroid/util/LruCache;->missCount()I
-HSPLandroid/util/LruCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/util/LruCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;,Landroid/util/LruCache;
HSPLandroid/util/LruCache;->remove(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/util/LruCache;->resize(I)V
HSPLandroid/util/LruCache;->safeSizeOf(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/util/LruCache;->size()I
HSPLandroid/util/LruCache;->sizeOf(Ljava/lang/Object;Ljava/lang/Object;)I
HSPLandroid/util/LruCache;->snapshot()Ljava/util/Map;
-HSPLandroid/util/LruCache;->trimToSize(I)V
-HSPLandroid/util/MapCollections$ArrayIterator;-><init>(Landroid/util/MapCollections;I)V
+HSPLandroid/util/LruCache;->trimToSize(I)V+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
+HSPLandroid/util/MapCollections$ArrayIterator;-><init>(Landroid/util/MapCollections;I)V+]Landroid/util/MapCollections;Landroid/util/ArraySet$1;,Landroid/util/ArrayMap$1;
HSPLandroid/util/MapCollections$ArrayIterator;->hasNext()Z
-HSPLandroid/util/MapCollections$ArrayIterator;->next()Ljava/lang/Object;
+HSPLandroid/util/MapCollections$ArrayIterator;->next()Ljava/lang/Object;+]Landroid/util/MapCollections$ArrayIterator;Landroid/util/MapCollections$ArrayIterator;]Landroid/util/MapCollections;Landroid/util/ArraySet$1;,Landroid/util/ArrayMap$1;
HSPLandroid/util/MapCollections$ArrayIterator;->remove()V
HSPLandroid/util/MapCollections$EntrySet;-><init>(Landroid/util/MapCollections;)V
HSPLandroid/util/MapCollections$EntrySet;->iterator()Ljava/util/Iterator;
@@ -15763,16 +15832,16 @@ HSPLandroid/util/SparseArray;->append(ILjava/lang/Object;)V+]Landroid/util/Spars
HSPLandroid/util/SparseArray;->clear()V
HSPLandroid/util/SparseArray;->clone()Landroid/util/SparseArray;
HSPLandroid/util/SparseArray;->contains(I)Z
-HSPLandroid/util/SparseArray;->contentEquals(Landroid/util/SparseArray;)Z+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->contentEquals(Landroid/util/SparseArray;)Z
HSPLandroid/util/SparseArray;->delete(I)V
HSPLandroid/util/SparseArray;->gc()V
-HSPLandroid/util/SparseArray;->get(I)Ljava/lang/Object;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->get(I)Ljava/lang/Object;+]Landroid/util/SparseArray;missing_types
HSPLandroid/util/SparseArray;->get(ILjava/lang/Object;)Ljava/lang/Object;
HSPLandroid/util/SparseArray;->indexOfKey(I)I
HSPLandroid/util/SparseArray;->indexOfValue(Ljava/lang/Object;)I
HSPLandroid/util/SparseArray;->keyAt(I)I
HSPLandroid/util/SparseArray;->put(ILjava/lang/Object;)V
-HSPLandroid/util/SparseArray;->remove(I)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->remove(I)V
HSPLandroid/util/SparseArray;->removeAt(I)V
HSPLandroid/util/SparseArray;->removeReturnOld(I)Ljava/lang/Object;
HSPLandroid/util/SparseArray;->setValueAt(ILjava/lang/Object;)V
@@ -15938,7 +16007,7 @@ HSPLandroid/view/AbsSavedState$2;->createFromParcel(Landroid/os/Parcel;Ljava/lan
HSPLandroid/view/AbsSavedState$2;->createFromParcel(Landroid/os/Parcel;Ljava/lang/ClassLoader;)Ljava/lang/Object;
HSPLandroid/view/AbsSavedState;-><init>(Landroid/os/Parcelable;)V
HSPLandroid/view/AbsSavedState;->getSuperState()Landroid/os/Parcelable;
-HSPLandroid/view/AbsSavedState;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/view/AbsSavedState;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/view/Choreographer$1;->initialValue()Landroid/view/Choreographer;
HSPLandroid/view/Choreographer$1;->initialValue()Ljava/lang/Object;
HSPLandroid/view/Choreographer$2;->initialValue()Landroid/view/Choreographer;
@@ -15950,8 +16019,8 @@ HSPLandroid/view/Choreographer$CallbackQueue;->extractDueCallbacksLocked(J)Landr
HSPLandroid/view/Choreographer$CallbackQueue;->removeCallbacksLocked(Ljava/lang/Object;Ljava/lang/Object;)V
HSPLandroid/view/Choreographer$CallbackRecord;-><init>()V
HSPLandroid/view/Choreographer$CallbackRecord;-><init>(Landroid/view/Choreographer$CallbackRecord-IA;)V
-HSPLandroid/view/Choreographer$CallbackRecord;->run(J)V+]Landroid/view/Choreographer$FrameCallback;missing_types]Ljava/lang/Runnable;Landroid/view/ViewPropertyAnimator$1;,Landroid/view/ViewRootImpl$ConsumeBatchedInputRunnable;,Landroid/view/ViewRootImpl$TraversalRunnable;,Lcom/android/internal/util/function/pooled/PooledLambdaImpl;
-HSPLandroid/view/Choreographer$CallbackRecord;->run(Landroid/view/Choreographer$FrameData;)V+]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;
+HSPLandroid/view/Choreographer$CallbackRecord;->run(J)V+]Landroid/view/Choreographer$FrameCallback;missing_types]Ljava/lang/Runnable;missing_types
+HSPLandroid/view/Choreographer$CallbackRecord;->run(Landroid/view/Choreographer$FrameData;)V+]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;
HSPLandroid/view/Choreographer$FrameData;->-$$Nest$fgetmFrameTimeNanos(Landroid/view/Choreographer$FrameData;)J
HSPLandroid/view/Choreographer$FrameData;-><init>()V
HSPLandroid/view/Choreographer$FrameData;->allocateFrameTimelines(I)V
@@ -15964,7 +16033,7 @@ HSPLandroid/view/Choreographer$FrameData;->update(JI)V
HSPLandroid/view/Choreographer$FrameData;->update(JLandroid/view/DisplayEventReceiver$VsyncEventData;)Landroid/view/Choreographer$FrameTimeline;+]Landroid/view/Choreographer$FrameTimeline;Landroid/view/Choreographer$FrameTimeline;
HSPLandroid/view/Choreographer$FrameData;->update(JLandroid/view/DisplayEventReceiver;J)Landroid/view/Choreographer$FrameTimeline;
HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;-><init>(Landroid/view/Choreographer;Landroid/os/Looper;IJ)V
-HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->onVsync(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->onVsync(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;
HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->run()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/view/Choreographer$FrameHandler;-><init>(Landroid/view/Choreographer;Landroid/os/Looper;)V
HSPLandroid/view/Choreographer$FrameHandler;->handleMessage(Landroid/os/Message;)V
@@ -15983,13 +16052,13 @@ HSPLandroid/view/Choreographer;-><init>(Landroid/os/Looper;I)V
HSPLandroid/view/Choreographer;-><init>(Landroid/os/Looper;IJ)V
HSPLandroid/view/Choreographer;-><init>(Landroid/os/Looper;ILandroid/view/Choreographer-IA;)V
HSPLandroid/view/Choreographer;->doCallbacks(IJ)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;
-HSPLandroid/view/Choreographer;->doFrame(JILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Landroid/graphics/FrameInfo;Landroid/graphics/FrameInfo;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/Choreographer;->doFrame(JILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/graphics/FrameInfo;Landroid/graphics/FrameInfo;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;
HSPLandroid/view/Choreographer;->doScheduleCallback(I)V
HSPLandroid/view/Choreographer;->doScheduleVsync()V
HSPLandroid/view/Choreographer;->getFrameIntervalNanos()J
-HSPLandroid/view/Choreographer;->getFrameTime()J
+HSPLandroid/view/Choreographer;->getFrameTime()J+]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/view/Choreographer;->getFrameTimeNanos()J
-HSPLandroid/view/Choreographer;->getInstance()Landroid/view/Choreographer;+]Ljava/lang/ThreadLocal;Landroid/view/Choreographer$1;
+HSPLandroid/view/Choreographer;->getInstance()Landroid/view/Choreographer;
HSPLandroid/view/Choreographer;->getMainThreadInstance()Landroid/view/Choreographer;
HSPLandroid/view/Choreographer;->getRefreshRate()F
HSPLandroid/view/Choreographer;->getSfInstance()Landroid/view/Choreographer;
@@ -15998,14 +16067,14 @@ HSPLandroid/view/Choreographer;->isRunningOnLooperThreadLocked()Z
HSPLandroid/view/Choreographer;->obtainCallbackLocked(JLjava/lang/Object;Ljava/lang/Object;)Landroid/view/Choreographer$CallbackRecord;
HSPLandroid/view/Choreographer;->postCallback(ILjava/lang/Runnable;Ljava/lang/Object;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/view/Choreographer;->postCallbackDelayed(ILjava/lang/Runnable;Ljava/lang/Object;J)V
-HSPLandroid/view/Choreographer;->postCallbackDelayedInternal(ILjava/lang/Object;Ljava/lang/Object;J)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->postCallbackDelayedInternal(ILjava/lang/Object;Ljava/lang/Object;J)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
HSPLandroid/view/Choreographer;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/view/Choreographer;->postFrameCallbackDelayed(Landroid/view/Choreographer$FrameCallback;J)V
HSPLandroid/view/Choreographer;->recycleCallbackLocked(Landroid/view/Choreographer$CallbackRecord;)V
HSPLandroid/view/Choreographer;->removeCallbacks(ILjava/lang/Runnable;Ljava/lang/Object;)V
-HSPLandroid/view/Choreographer;->removeCallbacksInternal(ILjava/lang/Object;Ljava/lang/Object;)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->removeCallbacksInternal(ILjava/lang/Object;Ljava/lang/Object;)V
HSPLandroid/view/Choreographer;->removeFrameCallback(Landroid/view/Choreographer$FrameCallback;)V
-HSPLandroid/view/Choreographer;->scheduleFrameLocked(J)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->scheduleFrameLocked(J)V
HSPLandroid/view/Choreographer;->scheduleVsyncLocked()V+]Landroid/view/Choreographer$FrameDisplayEventReceiver;Landroid/view/Choreographer$FrameDisplayEventReceiver;
HSPLandroid/view/Choreographer;->setFPSDivisor(I)V
HSPLandroid/view/ContextThemeWrapper;-><init>()V
@@ -16018,7 +16087,7 @@ HSPLandroid/view/ContextThemeWrapper;->getResources()Landroid/content/res/Resour
HSPLandroid/view/ContextThemeWrapper;->getResourcesInternal()Landroid/content/res/Resources;
HSPLandroid/view/ContextThemeWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
HSPLandroid/view/ContextThemeWrapper;->getTheme()Landroid/content/res/Resources$Theme;+]Landroid/view/ContextThemeWrapper;Landroid/view/ContextThemeWrapper;
-HSPLandroid/view/ContextThemeWrapper;->initializeTheme()V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ContextThemeWrapper;Landroid/view/ContextThemeWrapper;
+HSPLandroid/view/ContextThemeWrapper;->initializeTheme()V
HSPLandroid/view/ContextThemeWrapper;->onApplyThemeResource(Landroid/content/res/Resources$Theme;IZ)V
HSPLandroid/view/ContextThemeWrapper;->setTheme(I)V
HSPLandroid/view/CrossWindowBlurListeners;-><clinit>()V
@@ -16046,7 +16115,7 @@ HSPLandroid/view/Display$Mode;->matches(IIF)Z
HSPLandroid/view/Display$Mode;->toString()Ljava/lang/String;
HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/content/res/Resources;)V
HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;)V
-HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;Landroid/content/res/Resources;)V+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;Landroid/content/res/Resources;)V
HSPLandroid/view/Display;->getAppVsyncOffsetNanos()J
HSPLandroid/view/Display;->getCutout()Landroid/view/DisplayCutout;
HSPLandroid/view/Display;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -16056,7 +16125,7 @@ HSPLandroid/view/Display;->getFlags()I
HSPLandroid/view/Display;->getHdrSdrRatio()F
HSPLandroid/view/Display;->getHeight()I
HSPLandroid/view/Display;->getInstallOrientation()I
-HSPLandroid/view/Display;->getLocalRotation()I
+HSPLandroid/view/Display;->getLocalRotation()I+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/view/Display;->getMetrics(Landroid/util/DisplayMetrics;)V
HSPLandroid/view/Display;->getMode()Landroid/view/Display$Mode;
HSPLandroid/view/Display;->getName()Ljava/lang/String;
@@ -16102,7 +16171,7 @@ HSPLandroid/view/DisplayCutout$Bounds;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/DisplayCutout$Bounds;->getRects()[Landroid/graphics/Rect;
HSPLandroid/view/DisplayCutout$Bounds;->isEmpty()Z
HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;-><init>(IIIIFLjava/lang/String;IFF)V
-HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/DisplayCutout$ParcelableWrapper$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/DisplayCutout$ParcelableWrapper;
HSPLandroid/view/DisplayCutout$ParcelableWrapper$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/view/DisplayCutout$ParcelableWrapper;-><init>()V
@@ -16130,7 +16199,7 @@ HSPLandroid/view/DisplayCutout;->getSafeInsetTop()I
HSPLandroid/view/DisplayCutout;->inset(IIII)Landroid/view/DisplayCutout;
HSPLandroid/view/DisplayCutout;->insetInsets(IIIILandroid/graphics/Rect;)Landroid/graphics/Rect;
HSPLandroid/view/DisplayCutout;->isBoundsEmpty()Z
-HSPLandroid/view/DisplayCutout;->isEmpty()Z
+HSPLandroid/view/DisplayCutout;->isEmpty()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;-><init>()V
HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;-><init>(JJJ)V
HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;->copyFrom(Landroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;)V
@@ -16149,19 +16218,19 @@ HSPLandroid/view/DisplayInfo;-><init>()V
HSPLandroid/view/DisplayInfo;-><init>(Landroid/os/Parcel;)V
HSPLandroid/view/DisplayInfo;-><init>(Landroid/os/Parcel;Landroid/view/DisplayInfo-IA;)V
HSPLandroid/view/DisplayInfo;->copyFrom(Landroid/view/DisplayInfo;)V
-HSPLandroid/view/DisplayInfo;->equals(Landroid/view/DisplayInfo;)Z
+HSPLandroid/view/DisplayInfo;->equals(Landroid/view/DisplayInfo;)Z+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayInfo;Landroid/view/DisplayInfo;
HSPLandroid/view/DisplayInfo;->findMode(I)Landroid/view/Display$Mode;
HSPLandroid/view/DisplayInfo;->flagsToString(I)Ljava/lang/String;
HSPLandroid/view/DisplayInfo;->getAppMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
HSPLandroid/view/DisplayInfo;->getAppMetrics(Landroid/util/DisplayMetrics;Landroid/view/DisplayAdjustments;)V
HSPLandroid/view/DisplayInfo;->getLogicalMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
HSPLandroid/view/DisplayInfo;->getMaxBoundsMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
-HSPLandroid/view/DisplayInfo;->getMetricsWithSize(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;II)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/DisplayInfo;->getMetricsWithSize(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;II)V+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
HSPLandroid/view/DisplayInfo;->getMode()Landroid/view/Display$Mode;
HSPLandroid/view/DisplayInfo;->getRefreshRate()F
HSPLandroid/view/DisplayInfo;->hasAccess(I)Z
HSPLandroid/view/DisplayInfo;->isWideColorGamut()Z
-HSPLandroid/view/DisplayInfo;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/view/Display$Mode$1;
+HSPLandroid/view/DisplayInfo;->readFromParcel(Landroid/os/Parcel;)V
HSPLandroid/view/DisplayInfo;->toString()Ljava/lang/String;
HSPLandroid/view/DisplayInfo;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/view/DisplayShape$1;-><init>()V
@@ -16245,6 +16314,7 @@ HSPLandroid/view/HandwritingInitiator;->onInputConnectionClosed(Landroid/view/Vi
HSPLandroid/view/HandwritingInitiator;->onInputConnectionCreated(Landroid/view/View;)V
HSPLandroid/view/HandwritingInitiator;->onTouchEvent(Landroid/view/MotionEvent;)Z
HSPLandroid/view/HandwritingInitiator;->updateHandwritingAreasForView(Landroid/view/View;)V
+HSPLandroid/view/HdrRenderState;->updateForFrame(J)Z
HSPLandroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
HSPLandroid/view/IGraphicsStats$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/view/IGraphicsStats$Stub$Proxy;->requestBufferForProcess(Ljava/lang/String;Landroid/view/IGraphicsStatsCallback;)Landroid/os/ParcelFileDescriptor;
@@ -16277,7 +16347,8 @@ HSPLandroid/view/IWindowSession$Stub$Proxy;->finishDrawing(Landroid/view/IWindow
HSPLandroid/view/IWindowSession$Stub$Proxy;->getWindowId(Landroid/os/IBinder;)Landroid/view/IWindowId;
HSPLandroid/view/IWindowSession$Stub$Proxy;->onRectangleOnScreenRequested(Landroid/os/IBinder;Landroid/graphics/Rect;)V
HSPLandroid/view/IWindowSession$Stub$Proxy;->pokeDrawLock(Landroid/os/IBinder;)V
-HSPLandroid/view/IWindowSession$Stub$Proxy;->relayoutAsync(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIII)V
+HSPLandroid/view/IWindowSession$Stub$Proxy;->relayout(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIIILandroid/window/ClientWindowFrames;Landroid/util/MergedConfiguration;Landroid/view/SurfaceControl;Landroid/view/InsetsState;Landroid/view/InsetsSourceControl$Array;Landroid/os/Bundle;)I
+HSPLandroid/view/IWindowSession$Stub$Proxy;->relayoutAsync(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIII)V+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/view/IWindowSession$Stub$Proxy;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
HSPLandroid/view/IWindowSession$Stub$Proxy;->reportSystemGestureExclusionChanged(Landroid/view/IWindow;Ljava/util/List;)V
HSPLandroid/view/IWindowSession$Stub$Proxy;->setInsets(Landroid/view/IWindow;ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Region;)V
HSPLandroid/view/IWindowSession$Stub$Proxy;->setOnBackInvokedCallbackInfo(Landroid/view/IWindow;Landroid/window/OnBackInvokedCallbackInfo;)V
@@ -16293,7 +16364,7 @@ HSPLandroid/view/ImeFocusController;->onPostWindowFocus(Landroid/view/View;ZLand
HSPLandroid/view/ImeFocusController;->onPreWindowFocus(ZLandroid/view/WindowManager$LayoutParams;)V
HSPLandroid/view/ImeFocusController;->onProcessImeInputStage(Ljava/lang/Object;Landroid/view/InputEvent;Landroid/view/WindowManager$LayoutParams;Landroid/view/inputmethod/InputMethodManager$FinishedInputEventCallback;)I
HSPLandroid/view/ImeFocusController;->onTraversal(ZLandroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ImeFocusController;->onViewDetachedFromWindow(Landroid/view/View;)V+]Landroid/view/ImeFocusController$InputMethodManagerDelegate;Landroid/view/inputmethod/InputMethodManager$DelegateImpl;
+HSPLandroid/view/ImeFocusController;->onViewDetachedFromWindow(Landroid/view/View;)V
HSPLandroid/view/ImeFocusController;->onViewFocusChanged(Landroid/view/View;Z)V
HSPLandroid/view/ImeFocusController;->onWindowDismissed()V
HSPLandroid/view/ImeInsetsSourceConsumer;-><init>(ILandroid/view/InsetsState;Ljava/util/function/Supplier;Landroid/view/InsetsController;)V
@@ -16325,7 +16396,7 @@ HSPLandroid/view/InputDevice;->getSources()I
HSPLandroid/view/InputDevice;->isVirtual()Z
HSPLandroid/view/InputEvent;-><init>()V
HSPLandroid/view/InputEvent;->getSequenceNumber()I
-HSPLandroid/view/InputEvent;->isFromSource(I)Z
+HSPLandroid/view/InputEvent;->isFromSource(I)Z+]Landroid/view/InputEvent;Landroid/view/MotionEvent;
HSPLandroid/view/InputEvent;->prepareForReuse()V
HSPLandroid/view/InputEvent;->recycle()V
HSPLandroid/view/InputEvent;->recycleIfNeededAfterDispatch()V
@@ -16337,7 +16408,7 @@ HSPLandroid/view/InputEventCompatProcessor;->processInputEventForCompatibility(L
HSPLandroid/view/InputEventConsistencyVerifier;->isInstrumentationEnabled()Z
HSPLandroid/view/InputEventReceiver;-><init>(Landroid/view/InputChannel;Landroid/os/Looper;)V
HSPLandroid/view/InputEventReceiver;->consumeBatchedInputEvents(J)Z
-HSPLandroid/view/InputEventReceiver;->dispatchInputEvent(ILandroid/view/InputEvent;)V+]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Landroid/view/InputEventReceiver;Landroid/view/ViewRootImpl$WindowInputEventReceiver;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/InputEventReceiver;->dispatchInputEvent(ILandroid/view/InputEvent;)V
HSPLandroid/view/InputEventReceiver;->dispose()V
HSPLandroid/view/InputEventReceiver;->dispose(Z)V
HSPLandroid/view/InputEventReceiver;->finalize()V
@@ -16413,6 +16484,9 @@ HSPLandroid/view/InsetsController$3;->onStart(Landroid/view/InsetsState;Landroid
HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda0;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V
HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda3;->getInterpolation(F)F
HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda4;->getInterpolation(F)F
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$1;->initialValue()Landroid/animation/AnimationHandler;
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$1;->initialValue()Ljava/lang/Object;
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$2;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/view/InsetsController$InternalAnimationControlListener;-><init>(ZZIIZILandroid/view/WindowInsetsAnimationControlListener;Landroid/view/inputmethod/ImeTracker$InputMethodJankContext;)V
HSPLandroid/view/InsetsController$InternalAnimationControlListener;->calculateDurationMs()J
HSPLandroid/view/InsetsController$InternalAnimationControlListener;->getAlphaInterpolator()Landroid/view/animation/Interpolator;
@@ -16439,6 +16513,7 @@ HSPLandroid/view/InsetsController;->calculateVisibleInsets(IIII)Landroid/graphic
HSPLandroid/view/InsetsController;->cancelAnimation(Landroid/view/InsetsAnimationControlRunner;Z)V
HSPLandroid/view/InsetsController;->cancelExistingAnimations()V
HSPLandroid/view/InsetsController;->cancelExistingControllers(I)V
+HSPLandroid/view/InsetsController;->captionInsetsUnchanged()Z
HSPLandroid/view/InsetsController;->collectSourceControls(ZILandroid/util/SparseArray;ILandroid/view/inputmethod/ImeTracker$Token;)Landroid/util/Pair;
HSPLandroid/view/InsetsController;->controlAnimationUncheckedInner(ILandroid/os/CancellationSignal;Landroid/view/WindowInsetsAnimationControlListener;Landroid/graphics/Rect;ZJLandroid/view/animation/Interpolator;IIZLandroid/view/inputmethod/ImeTracker$Token;)V
HSPLandroid/view/InsetsController;->dispatchAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
@@ -16456,8 +16531,8 @@ HSPLandroid/view/InsetsController;->lambda$static$1(FLandroid/graphics/Insets;La
HSPLandroid/view/InsetsController;->notifyControlRevoked(Landroid/view/InsetsSourceConsumer;)V
HSPLandroid/view/InsetsController;->notifyFinished(Landroid/view/InsetsAnimationControlRunner;Z)V
HSPLandroid/view/InsetsController;->notifyVisibilityChanged()V
-HSPLandroid/view/InsetsController;->onControlsChanged([Landroid/view/InsetsSourceControl;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceConsumer;Landroid/view/ImeInsetsSourceConsumer;,Landroid/view/InsetsSourceConsumer;]Landroid/view/InsetsSourceControl;Landroid/view/InsetsSourceControl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/InsetsController;->onFrameChanged(Landroid/graphics/Rect;)V
+HSPLandroid/view/InsetsController;->onControlsChanged([Landroid/view/InsetsSourceControl;)V
+HSPLandroid/view/InsetsController;->onFrameChanged(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/view/InsetsController;->onStateChanged(Landroid/view/InsetsState;)Z
HSPLandroid/view/InsetsController;->onWindowFocusGained(Z)V
HSPLandroid/view/InsetsController;->onWindowFocusLost()V
@@ -16470,15 +16545,15 @@ HSPLandroid/view/InsetsController;->updateCompatSysUiVisibility()V
HSPLandroid/view/InsetsController;->updateState(Landroid/view/InsetsState;)V
HSPLandroid/view/InsetsFlags;-><init>()V
HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/view/InsetsSource$1;Landroid/view/InsetsSource$1;
+HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/view/InsetsSource;-><init>(II)V
-HSPLandroid/view/InsetsSource;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/graphics/Rect$1;
+HSPLandroid/view/InsetsSource;-><init>(Landroid/os/Parcel;)V
HSPLandroid/view/InsetsSource;-><init>(Landroid/view/InsetsSource;)V
-HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Landroid/graphics/Rect;Z)Landroid/graphics/Insets;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Landroid/graphics/Rect;Z)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Z)Landroid/graphics/Insets;
HSPLandroid/view/InsetsSource;->calculateVisibleInsets(Landroid/graphics/Rect;)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;)Z+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Ljava/lang/Object;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;)Z
+HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;Z)Z
HSPLandroid/view/InsetsSource;->getFlags()I
HSPLandroid/view/InsetsSource;->getFrame()Landroid/graphics/Rect;
HSPLandroid/view/InsetsSource;->getId()I
@@ -16532,30 +16607,30 @@ HSPLandroid/view/InsetsState;-><init>()V
HSPLandroid/view/InsetsState;-><init>(Landroid/os/Parcel;)V
HSPLandroid/view/InsetsState;-><init>(Landroid/view/InsetsState;Z)V
HSPLandroid/view/InsetsState;->addSource(Landroid/view/InsetsSource;)V
-HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;II)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;IZ)Landroid/graphics/Insets;
+HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;II)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;IZ)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/util/SparseArray;Landroid/util/SparseArray;
HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;Landroid/view/InsetsState;ZIIIIILandroid/util/SparseIntArray;)Landroid/view/WindowInsets;
HSPLandroid/view/InsetsState;->calculateRelativeCutout(Landroid/graphics/Rect;)Landroid/view/DisplayCutout;
HSPLandroid/view/InsetsState;->calculateRelativeDisplayShape(Landroid/graphics/Rect;)Landroid/view/DisplayShape;
HSPLandroid/view/InsetsState;->calculateRelativePrivacyIndicatorBounds(Landroid/graphics/Rect;)Landroid/view/PrivacyIndicatorBounds;
HSPLandroid/view/InsetsState;->calculateRelativeRoundedCorners(Landroid/graphics/Rect;)Landroid/view/RoundedCorners;
-HSPLandroid/view/InsetsState;->calculateUncontrollableInsetsFromFrame(Landroid/graphics/Rect;)I+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->calculateUncontrollableInsetsFromFrame(Landroid/graphics/Rect;)I
HSPLandroid/view/InsetsState;->calculateVisibleInsets(Landroid/graphics/Rect;IIII)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsState;->canControlSource(Landroid/graphics/Rect;Landroid/view/InsetsSource;)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->canControlSource(Landroid/graphics/Rect;Landroid/view/InsetsSource;)Z
HSPLandroid/view/InsetsState;->clearsCompatInsets(IIII)Z
HSPLandroid/view/InsetsState;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/InsetsState;->equals(Ljava/lang/Object;ZZ)Z
-HSPLandroid/view/InsetsState;->getDisplayCutout()Landroid/view/DisplayCutout;
-HSPLandroid/view/InsetsState;->getDisplayCutoutSafe(Landroid/graphics/Rect;)V
+HSPLandroid/view/InsetsState;->getDisplayCutout()Landroid/view/DisplayCutout;+]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;
+HSPLandroid/view/InsetsState;->getDisplayCutoutSafe(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;
HSPLandroid/view/InsetsState;->getDisplayFrame()Landroid/graphics/Rect;
HSPLandroid/view/InsetsState;->getDisplayShape()Landroid/view/DisplayShape;
HSPLandroid/view/InsetsState;->getPrivacyIndicatorBounds()Landroid/view/PrivacyIndicatorBounds;
HSPLandroid/view/InsetsState;->getRoundedCorners()Landroid/view/RoundedCorners;
HSPLandroid/view/InsetsState;->isSourceOrDefaultVisible(II)Z
HSPLandroid/view/InsetsState;->peekSource(I)Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsState;->readFromParcel(Landroid/os/Parcel;)Landroid/util/SparseArray;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->readFromParcel(Landroid/os/Parcel;)Landroid/util/SparseArray;
HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;I)V
-HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/view/InsetsState;Landroid/view/InsetsState;
+HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;Z)V
HSPLandroid/view/InsetsState;->setDisplayCutout(Landroid/view/DisplayCutout;)V
HSPLandroid/view/InsetsState;->setDisplayFrame(Landroid/graphics/Rect;)V
HSPLandroid/view/InsetsState;->setPrivacyIndicatorBounds(Landroid/view/PrivacyIndicatorBounds;)V
@@ -16614,28 +16689,28 @@ HSPLandroid/view/LayoutInflater;-><init>(Landroid/content/Context;)V
HSPLandroid/view/LayoutInflater;-><init>(Landroid/view/LayoutInflater;Landroid/content/Context;)V
HSPLandroid/view/LayoutInflater;->advanceToRootNode(Lorg/xmlpull/v1/XmlPullParser;)V
HSPLandroid/view/LayoutInflater;->consumeChildElements(Lorg/xmlpull/v1/XmlPullParser;)V
-HSPLandroid/view/LayoutInflater;->createView(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;+]Landroid/content/Context;missing_types]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/ViewStub;Landroid/view/ViewStub;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/reflect/Constructor;Ljava/lang/reflect/Constructor;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/view/LayoutInflater;->createView(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->createView(Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;Z)Landroid/view/View;+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;Z)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->from(Landroid/content/Context;)Landroid/view/LayoutInflater;
HSPLandroid/view/LayoutInflater;->getContext()Landroid/content/Context;
HSPLandroid/view/LayoutInflater;->getFactory()Landroid/view/LayoutInflater$Factory;
HSPLandroid/view/LayoutInflater;->getFactory2()Landroid/view/LayoutInflater$Factory2;
HSPLandroid/view/LayoutInflater;->inflate(ILandroid/view/ViewGroup;)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->inflate(ILandroid/view/ViewGroup;Z)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->inflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/ViewGroup;Z)Landroid/view/View;+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/LayoutInflater;->inflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/ViewGroup;Z)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->onCreateView(Landroid/content/Context;Landroid/view/View;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
HSPLandroid/view/LayoutInflater;->onCreateView(Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->parseInclude(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/Context;Landroid/view/View;Landroid/util/AttributeSet;)V
-HSPLandroid/view/LayoutInflater;->rInflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/content/Context;Landroid/util/AttributeSet;Z)V+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
-HSPLandroid/view/LayoutInflater;->rInflateChildren(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/util/AttributeSet;Z)V+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types
+HSPLandroid/view/LayoutInflater;->parseInclude(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/Context;Landroid/view/View;Landroid/util/AttributeSet;)V+]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/widget/FrameLayout;,Landroid/widget/LinearLayout;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Ljava/lang/Object;Ljava/lang/String;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/res/XmlResourceParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/LayoutInflater;->rInflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/content/Context;Landroid/util/AttributeSet;Z)V+]Landroid/view/View;missing_types]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;]Landroid/view/ViewGroup;Landroid/widget/RelativeLayout;,Landroid/widget/FrameLayout;,Landroid/widget/LinearLayout;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/view/LayoutInflater;->rInflateChildren(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/util/AttributeSet;Z)V
HSPLandroid/view/LayoutInflater;->setFactory2(Landroid/view/LayoutInflater$Factory2;)V
HSPLandroid/view/LayoutInflater;->setFilter(Landroid/view/LayoutInflater$Filter;)V
HSPLandroid/view/LayoutInflater;->setPrivateFactory(Landroid/view/LayoutInflater$Factory2;)V
-HSPLandroid/view/LayoutInflater;->tryCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;+]Landroid/view/LayoutInflater$Factory2;missing_types]Ljava/lang/Object;Ljava/lang/String;
-HSPLandroid/view/LayoutInflater;->verifyClassLoader(Ljava/lang/reflect/Constructor;)Z+]Landroid/content/Context;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/reflect/Constructor;Ljava/lang/reflect/Constructor;
+HSPLandroid/view/LayoutInflater;->tryCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
+HSPLandroid/view/LayoutInflater;->verifyClassLoader(Ljava/lang/reflect/Constructor;)Z
HSPLandroid/view/MenuInflater;-><init>(Landroid/content/Context;)V
HSPLandroid/view/MotionEvent$PointerCoords;-><init>()V
HSPLandroid/view/MotionEvent$PointerProperties;-><init>()V
@@ -16676,7 +16751,7 @@ HSPLandroid/view/MotionEvent;->getX(I)F
HSPLandroid/view/MotionEvent;->getY()F
HSPLandroid/view/MotionEvent;->getY(I)F
HSPLandroid/view/MotionEvent;->initialize(IIIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;[Landroid/view/MotionEvent$PointerCoords;)Z
-HSPLandroid/view/MotionEvent;->isTargetAccessibilityFocus()Z
+HSPLandroid/view/MotionEvent;->isTargetAccessibilityFocus()Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/view/MotionEvent;->isTouchEvent()Z
HSPLandroid/view/MotionEvent;->obtain()Landroid/view/MotionEvent;
HSPLandroid/view/MotionEvent;->obtain(JJIFFFFIFFII)Landroid/view/MotionEvent;
@@ -16687,7 +16762,7 @@ HSPLandroid/view/MotionEvent;->offsetLocation(FF)V
HSPLandroid/view/MotionEvent;->recycle()V
HSPLandroid/view/MotionEvent;->setAction(I)V
HSPLandroid/view/MotionEvent;->setLocation(FF)V
-HSPLandroid/view/MotionEvent;->setTargetAccessibilityFocus(Z)V
+HSPLandroid/view/MotionEvent;->setTargetAccessibilityFocus(Z)V+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/view/MotionEvent;->split(I)Landroid/view/MotionEvent;
HSPLandroid/view/MotionEvent;->transform(Landroid/graphics/Matrix;)V
HSPLandroid/view/MotionEvent;->updateCursorPosition()V
@@ -16723,12 +16798,12 @@ HSPLandroid/view/RemoteAccessibilityController;->setRemoteAccessibilityEmbeddedC
HSPLandroid/view/RemoteAnimationAdapter;-><init>(Landroid/view/IRemoteAnimationRunner;JJ)V
HSPLandroid/view/RemoteAnimationAdapter;->writeToParcel(Landroid/os/Parcel;I)V
HSPLandroid/view/RoundedCorner$1;-><init>()V
-HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/RoundedCorner;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/view/RoundedCorner$1;Landroid/view/RoundedCorner$1;
+HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/RoundedCorner;
+HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/view/RoundedCorner;-><clinit>()V
HSPLandroid/view/RoundedCorner;-><init>(I)V
HSPLandroid/view/RoundedCorner;-><init>(IIII)V
-HSPLandroid/view/RoundedCorner;->equals(Ljava/lang/Object;)Z+]Landroid/graphics/Point;Landroid/graphics/Point;
+HSPLandroid/view/RoundedCorner;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/RoundedCorner;->getCenter()Landroid/graphics/Point;
HSPLandroid/view/RoundedCorner;->getRadius()I
HSPLandroid/view/RoundedCorner;->isEmpty()Z
@@ -16791,7 +16866,7 @@ HSPLandroid/view/SurfaceControl$Builder;->setOpaque(Z)Landroid/view/SurfaceContr
HSPLandroid/view/SurfaceControl$Builder;->setParent(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Builder;
HSPLandroid/view/SurfaceControl$Builder;->unsetBufferSize()V
HSPLandroid/view/SurfaceControl$Transaction;-><init>()V
-HSPLandroid/view/SurfaceControl$Transaction;-><init>(J)V
+HSPLandroid/view/SurfaceControl$Transaction;-><init>(J)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
HSPLandroid/view/SurfaceControl$Transaction;->apply()V
HSPLandroid/view/SurfaceControl$Transaction;->apply(Z)V
HSPLandroid/view/SurfaceControl$Transaction;->applyResizedSurfaces()V
@@ -16799,7 +16874,7 @@ HSPLandroid/view/SurfaceControl$Transaction;->checkPreconditions(Landroid/view/S
HSPLandroid/view/SurfaceControl$Transaction;->clear()V
HSPLandroid/view/SurfaceControl$Transaction;->close()V
HSPLandroid/view/SurfaceControl$Transaction;->hide(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/view/SurfaceControl$Transaction;->merge(Landroid/view/SurfaceControl$Transaction;)Landroid/view/SurfaceControl$Transaction;
+HSPLandroid/view/SurfaceControl$Transaction;->merge(Landroid/view/SurfaceControl$Transaction;)Landroid/view/SurfaceControl$Transaction;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
HSPLandroid/view/SurfaceControl$Transaction;->notifyReparentedSurfaces()V
HSPLandroid/view/SurfaceControl$Transaction;->remove(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->reparent(Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
@@ -16809,7 +16884,7 @@ HSPLandroid/view/SurfaceControl$Transaction;->setBufferSize(Landroid/view/Surfac
HSPLandroid/view/SurfaceControl$Transaction;->setColor(Landroid/view/SurfaceControl;[F)Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->setCornerRadius(Landroid/view/SurfaceControl;F)Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->setDesintationFrame(Landroid/view/SurfaceControl;II)Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/view/SurfaceControl$Transaction;->setExtendedRangeBrightness(Landroid/view/SurfaceControl;FF)Landroid/view/SurfaceControl$Transaction;
+HSPLandroid/view/SurfaceControl$Transaction;->setExtendedRangeBrightness(Landroid/view/SurfaceControl;FF)Landroid/view/SurfaceControl$Transaction;+]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->setFrameTimelineVsync(J)Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->setLayer(Landroid/view/SurfaceControl;I)Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/SurfaceControl$Transaction;->setMatrix(Landroid/view/SurfaceControl;FFFF)Landroid/view/SurfaceControl$Transaction;
@@ -16877,6 +16952,7 @@ HSPLandroid/view/SurfaceView;->onMeasure(II)V
HSPLandroid/view/SurfaceView;->onSetSurfacePositionAndScale(Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl;IIFF)V
HSPLandroid/view/SurfaceView;->onWindowVisibilityChanged(I)V
HSPLandroid/view/SurfaceView;->performDrawFinished()V
+HSPLandroid/view/SurfaceView;->performSurfaceTransaction(Landroid/view/ViewRootImpl;Landroid/content/res/CompatibilityInfo$Translator;ZZZZLandroid/view/SurfaceControl$Transaction;)Z
HSPLandroid/view/SurfaceView;->releaseSurfaces(Z)V
HSPLandroid/view/SurfaceView;->replacePositionUpdateListener(II)V
HSPLandroid/view/SurfaceView;->requiresSurfaceControlCreation(ZZ)Z
@@ -16917,8 +16993,8 @@ HSPLandroid/view/TextureView;->updateLayer()V
HSPLandroid/view/ThreadedRenderer$1$$ExternalSyntheticLambda0;-><init>(Ljava/util/ArrayList;)V
HSPLandroid/view/ThreadedRenderer$1$$ExternalSyntheticLambda0;->onFrameCommit(Z)V
HSPLandroid/view/ThreadedRenderer$1;-><init>(Landroid/view/ThreadedRenderer;Ljava/util/ArrayList;)V
-HSPLandroid/view/ThreadedRenderer$1;->lambda$onFrameDraw$0(Ljava/util/ArrayList;Z)V
-HSPLandroid/view/ThreadedRenderer$1;->onFrameDraw(IJ)Landroid/graphics/HardwareRenderer$FrameCommitCallback;
+HSPLandroid/view/ThreadedRenderer$1;->lambda$onFrameDraw$0(Ljava/util/ArrayList;Z)V+]Landroid/graphics/HardwareRenderer$FrameCommitCallback;Landroid/view/ViewRootImpl$7$$ExternalSyntheticLambda0;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ThreadedRenderer$1;->onFrameDraw(IJ)Landroid/graphics/HardwareRenderer$FrameCommitCallback;+]Landroid/graphics/HardwareRenderer$FrameDrawingCallback;Landroid/view/ViewRootImpl$3;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;->-$$Nest$fgetmSurfaceControl(Landroid/view/ThreadedRenderer$WebViewOverlayProvider;)Landroid/view/SurfaceControl;
HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;-><clinit>()V
HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;-><init>()V
@@ -16933,7 +17009,7 @@ HSPLandroid/view/ThreadedRenderer;->create(Landroid/content/Context;ZLjava/lang/
HSPLandroid/view/ThreadedRenderer;->destroy()V
HSPLandroid/view/ThreadedRenderer;->destroyHardwareResources(Landroid/view/View;)V
HSPLandroid/view/ThreadedRenderer;->destroyResources(Landroid/view/View;)V
-HSPLandroid/view/ThreadedRenderer;->draw(Landroid/view/View;Landroid/view/View$AttachInfo;Landroid/view/ThreadedRenderer$DrawCallbacks;)V
+HSPLandroid/view/ThreadedRenderer;->draw(Landroid/view/View;Landroid/view/View$AttachInfo;Landroid/view/ThreadedRenderer$DrawCallbacks;)V+]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ThreadedRenderer;->dumpArgsToFlags([Ljava/lang/String;)I
HSPLandroid/view/ThreadedRenderer;->getHeight()I
HSPLandroid/view/ThreadedRenderer;->getWidth()I
@@ -16944,20 +17020,20 @@ HSPLandroid/view/ThreadedRenderer;->invalidateRoot()V
HSPLandroid/view/ThreadedRenderer;->isEnabled()Z
HSPLandroid/view/ThreadedRenderer;->isRequested()Z
HSPLandroid/view/ThreadedRenderer;->loadSystemProperties()Z
-HSPLandroid/view/ThreadedRenderer;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V
+HSPLandroid/view/ThreadedRenderer;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ThreadedRenderer;->rendererOwnsSurfaceControlOpacity()Z
HSPLandroid/view/ThreadedRenderer;->setEnabled(Z)V
HSPLandroid/view/ThreadedRenderer;->setLightCenter(Landroid/view/View$AttachInfo;)V
HSPLandroid/view/ThreadedRenderer;->setRequested(Z)V
HSPLandroid/view/ThreadedRenderer;->setSurface(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->setSurfaceControl(Landroid/view/SurfaceControl;Landroid/graphics/BLASTBufferQueue;)V
+HSPLandroid/view/ThreadedRenderer;->setSurfaceControl(Landroid/view/SurfaceControl;Landroid/graphics/BLASTBufferQueue;)V+]Landroid/view/ThreadedRenderer$WebViewOverlayProvider;Landroid/view/ThreadedRenderer$WebViewOverlayProvider;
HSPLandroid/view/ThreadedRenderer;->setSurfaceControlOpaque(Z)Z
HSPLandroid/view/ThreadedRenderer;->setup(IILandroid/view/View$AttachInfo;Landroid/graphics/Rect;)V
HSPLandroid/view/ThreadedRenderer;->updateEnabledState(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->updateRootDisplayList(Landroid/view/View;Landroid/view/ThreadedRenderer$DrawCallbacks;)V
+HSPLandroid/view/ThreadedRenderer;->updateRootDisplayList(Landroid/view/View;Landroid/view/ThreadedRenderer$DrawCallbacks;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ThreadedRenderer$DrawCallbacks;Landroid/view/ViewRootImpl;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/view/ThreadedRenderer;->updateSurface(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->updateViewTreeDisplayList(Landroid/view/View;)V
-HSPLandroid/view/ThreadedRenderer;->updateWebViewOverlayCallbacks()V
+HSPLandroid/view/ThreadedRenderer;->updateViewTreeDisplayList(Landroid/view/View;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ThreadedRenderer;->updateWebViewOverlayCallbacks()V+]Landroid/view/ThreadedRenderer$WebViewOverlayProvider;Landroid/view/ThreadedRenderer$WebViewOverlayProvider;
HSPLandroid/view/TouchDelegate;-><init>(Landroid/graphics/Rect;Landroid/view/View;)V
HSPLandroid/view/VelocityTracker;-><init>(I)V
HSPLandroid/view/VelocityTracker;->addMovement(Landroid/view/MotionEvent;)V
@@ -16979,7 +17055,7 @@ HSPLandroid/view/View$$ExternalSyntheticLambda7;->run()V
HSPLandroid/view/View$12;->get(Landroid/view/View;)Ljava/lang/Float;
HSPLandroid/view/View$12;->get(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/view/View$12;->setValue(Landroid/view/View;F)V
-HSPLandroid/view/View$12;->setValue(Ljava/lang/Object;F)V
+HSPLandroid/view/View$12;->setValue(Ljava/lang/Object;F)V+]Landroid/view/View$12;Landroid/view/View$12;
HSPLandroid/view/View$13;->get(Landroid/view/View;)Ljava/lang/Float;
HSPLandroid/view/View$13;->get(Ljava/lang/Object;)Ljava/lang/Object;
HSPLandroid/view/View$13;->setValue(Landroid/view/View;F)V
@@ -17033,31 +17109,31 @@ HSPLandroid/view/View$MeasureSpec;->makeMeasureSpec(II)I
HSPLandroid/view/View$MeasureSpec;->makeSafeMeasureSpec(II)I
HSPLandroid/view/View$PerformClick;->run()V
HSPLandroid/view/View$ScrollabilityCache;-><init>(Landroid/view/ViewConfiguration;Landroid/view/View;)V
-HSPLandroid/view/View$ScrollabilityCache;->run()V
+HSPLandroid/view/View$ScrollabilityCache;->run()V+]Landroid/graphics/Interpolator;Landroid/graphics/Interpolator;]Landroid/view/View;missing_types
HSPLandroid/view/View$TintInfo;-><init>()V
HSPLandroid/view/View$TransformationInfo;-><init>()V
HSPLandroid/view/View$UnsetPressedState;->run()V
HSPLandroid/view/View$VisibilityChangeForAutofillHandler;->handleMessage(Landroid/os/Message;)V
-HSPLandroid/view/View;-><init>(Landroid/content/Context;)V+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/view/View;-><init>(Landroid/content/Context;)V+]Landroid/view/View;missing_types]Ljava/lang/Object;missing_types]Landroid/content/Context;missing_types]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/view/View;missing_types]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/view/View;->addFocusables(Ljava/util/ArrayList;I)V
HSPLandroid/view/View;->addFocusables(Ljava/util/ArrayList;II)V
HSPLandroid/view/View;->addFrameMetricsListener(Landroid/view/Window;Landroid/view/Window$OnFrameMetricsAvailableListener;Landroid/os/Handler;)V
HSPLandroid/view/View;->addOnAttachStateChangeListener(Landroid/view/View$OnAttachStateChangeListener;)V
-HSPLandroid/view/View;->addOnLayoutChangeListener(Landroid/view/View$OnLayoutChangeListener;)V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/View;->addOnLayoutChangeListener(Landroid/view/View$OnLayoutChangeListener;)V
HSPLandroid/view/View;->animate()Landroid/view/ViewPropertyAnimator;
HSPLandroid/view/View;->announceForAccessibility(Ljava/lang/CharSequence;)V
HSPLandroid/view/View;->appendId(Ljava/lang/StringBuilder;)V
HSPLandroid/view/View;->applyBackgroundTint()V
HSPLandroid/view/View;->applyForegroundTint()V
HSPLandroid/view/View;->applyInsets(Landroid/graphics/Rect;)V
-HSPLandroid/view/View;->applyLegacyAnimation(Landroid/view/ViewGroup;JLandroid/view/animation/Animation;Z)Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
+HSPLandroid/view/View;->applyLegacyAnimation(Landroid/view/ViewGroup;JLandroid/view/animation/Animation;Z)Z
HSPLandroid/view/View;->areDrawablesResolved()Z
HSPLandroid/view/View;->assignParent(Landroid/view/ViewParent;)V
HSPLandroid/view/View;->awakenScrollBars()Z
-HSPLandroid/view/View;->awakenScrollBars(IZ)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->awakenScrollBars(IZ)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/View;Landroid/widget/ImageView;,Landroid/widget/TextView;,Landroid/widget/LinearLayout;
HSPLandroid/view/View;->bringToFront()V
HSPLandroid/view/View;->buildDrawingCache(Z)V
HSPLandroid/view/View;->buildDrawingCacheImpl(Z)V
@@ -17065,7 +17141,7 @@ HSPLandroid/view/View;->buildLayer()V
HSPLandroid/view/View;->calculateAccessibilityDataSensitive()V
HSPLandroid/view/View;->calculateIsImportantForContentCapture()Z
HSPLandroid/view/View;->canHaveDisplayList()Z
-HSPLandroid/view/View;->canNotifyAutofillEnterExitEvent()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->canNotifyAutofillEnterExitEvent()Z
HSPLandroid/view/View;->canReceivePointerEvents()Z
HSPLandroid/view/View;->canResolveLayoutDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
HSPLandroid/view/View;->canResolveTextDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
@@ -17077,8 +17153,8 @@ HSPLandroid/view/View;->cancelLongPress()V
HSPLandroid/view/View;->cancelPendingInputEvents()V
HSPLandroid/view/View;->checkForLongClick(JFFI)V
HSPLandroid/view/View;->checkInputConnectionProxy(Landroid/view/View;)Z
-HSPLandroid/view/View;->cleanupDraw()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
-HSPLandroid/view/View;->clearAccessibilityFocus()V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->cleanupDraw()V
+HSPLandroid/view/View;->clearAccessibilityFocus()V
HSPLandroid/view/View;->clearAccessibilityFocusNoCallbacks(I)V
HSPLandroid/view/View;->clearAccessibilityThrottles()V
HSPLandroid/view/View;->clearAnimation()V
@@ -17087,7 +17163,7 @@ HSPLandroid/view/View;->clearFocusInternal(Landroid/view/View;ZZ)V
HSPLandroid/view/View;->clearParentsWantFocus()V
HSPLandroid/view/View;->clearTranslationState()V
HSPLandroid/view/View;->clearViewTranslationResponse()V
-HSPLandroid/view/View;->collectPreferKeepClearRects()Ljava/util/List;+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->collectPreferKeepClearRects()Ljava/util/List;
HSPLandroid/view/View;->collectUnrestrictedPreferKeepClearRects()Ljava/util/List;
HSPLandroid/view/View;->combineMeasuredStates(II)I
HSPLandroid/view/View;->combineVisibility(II)I
@@ -17095,21 +17171,21 @@ HSPLandroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/
HSPLandroid/view/View;->computeHorizontalScrollExtent()I
HSPLandroid/view/View;->computeHorizontalScrollOffset()I
HSPLandroid/view/View;->computeHorizontalScrollRange()I
-HSPLandroid/view/View;->computeOpaqueFlags()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->computeOpaqueFlags()V
HSPLandroid/view/View;->computeScroll()V
HSPLandroid/view/View;->computeSystemWindowInsets(Landroid/view/WindowInsets;Landroid/graphics/Rect;)Landroid/view/WindowInsets;
-HSPLandroid/view/View;->computeVerticalScrollExtent()I
+HSPLandroid/view/View;->computeVerticalScrollExtent()I+]Landroid/view/View;missing_types
HSPLandroid/view/View;->computeVerticalScrollOffset()I
-HSPLandroid/view/View;->computeVerticalScrollRange()I
-HSPLandroid/view/View;->damageInParent()V+]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->computeVerticalScrollRange()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->damageInParent()V
HSPLandroid/view/View;->destroyDrawingCache()V
HSPLandroid/view/View;->destroyHardwareResources()V
-HSPLandroid/view/View;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/View;missing_types]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
-HSPLandroid/view/View;->dispatchCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
+HSPLandroid/view/View;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/View;missing_types]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;
+HSPLandroid/view/View;->dispatchCancelPendingInputEvents()V
HSPLandroid/view/View;->dispatchCollectViewAttributes(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->dispatchConfigurationChanged(Landroid/content/res/Configuration;)V
-HSPLandroid/view/View;->dispatchDetachedFromWindow()V+]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/view/ViewOverlay$OverlayViewGroup;]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;]Ljava/util/List;Ljava/util/Collections$EmptyList;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
+HSPLandroid/view/View;->dispatchDetachedFromWindow()V+]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/View;->dispatchDraw(Landroid/graphics/Canvas;)V
HSPLandroid/view/View;->dispatchDrawableHotspotChanged(FF)V
HSPLandroid/view/View;->dispatchFinishTemporaryDetach()V
@@ -17125,7 +17201,7 @@ HSPLandroid/view/View;->dispatchProvideAutofillStructure(Landroid/view/ViewStruc
HSPLandroid/view/View;->dispatchProvideContentCaptureStructure()V
HSPLandroid/view/View;->dispatchProvideStructure(Landroid/view/ViewStructure;II)V
HSPLandroid/view/View;->dispatchRestoreInstanceState(Landroid/util/SparseArray;)V
-HSPLandroid/view/View;->dispatchSaveInstanceState(Landroid/util/SparseArray;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/View;->dispatchSaveInstanceState(Landroid/util/SparseArray;)V
HSPLandroid/view/View;->dispatchScreenStateChanged(I)V
HSPLandroid/view/View;->dispatchSetActivated(Z)V
HSPLandroid/view/View;->dispatchSetPressed(Z)V
@@ -17134,18 +17210,18 @@ HSPLandroid/view/View;->dispatchStartTemporaryDetach()V
HSPLandroid/view/View;->dispatchSystemUiVisibilityChanged(I)V
HSPLandroid/view/View;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
HSPLandroid/view/View;->dispatchVisibilityAggregated(Z)Z+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->dispatchVisibilityChanged(Landroid/view/View;I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchVisibilityChanged(Landroid/view/View;I)V
HSPLandroid/view/View;->dispatchWindowFocusChanged(Z)V
HSPLandroid/view/View;->dispatchWindowInsetsAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
HSPLandroid/view/View;->dispatchWindowSystemUiVisiblityChanged(I)V
-HSPLandroid/view/View;->dispatchWindowVisibilityChanged(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchWindowVisibilityChanged(I)V
HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;Landroid/view/ViewGroup;J)Z+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/AnimationSet;,Landroid/view/animation/RotateAnimation;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
-HSPLandroid/view/View;->drawAutofilledHighlight(Landroid/graphics/Canvas;)V
-HSPLandroid/view/View;->drawBackground(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;Landroid/view/ViewGroup;J)Z+]Landroid/view/View;missing_types]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/view/ViewGroup;Landroid/widget/FrameLayout;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;]Landroid/view/animation/Animation;Landroid/view/animation/TranslateAnimation;,Landroid/view/animation/AlphaAnimation;
+HSPLandroid/view/View;->drawAutofilledHighlight(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->drawBackground(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/view/View;->drawDefaultFocusHighlight(Landroid/graphics/Canvas;)V
HSPLandroid/view/View;->drawableHotspotChanged(FF)V
-HSPLandroid/view/View;->drawableStateChanged()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->drawableStateChanged()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/view/View;missing_types]Landroid/graphics/drawable/Drawable;Landroid/widget/ScrollBarDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/StateListDrawable;,Landroid/graphics/drawable/ColorDrawable;
HSPLandroid/view/View;->drawsWithRenderNode(Landroid/graphics/Canvas;)Z+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/view/View;->ensureTransformationInfo()V
HSPLandroid/view/View;->findAccessibilityFocusHost(Z)Landroid/view/View;
@@ -17155,7 +17231,7 @@ HSPLandroid/view/View;->findKeyboardNavigationCluster()Landroid/view/View;
HSPLandroid/view/View;->findOnBackInvokedDispatcher()Landroid/window/OnBackInvokedDispatcher;
HSPLandroid/view/View;->findUserSetNextFocus(Landroid/view/View;I)Landroid/view/View;
HSPLandroid/view/View;->findViewByAutofillIdTraversal(I)Landroid/view/View;
-HSPLandroid/view/View;->findViewById(I)Landroid/view/View;+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->findViewById(I)Landroid/view/View;
HSPLandroid/view/View;->findViewTraversal(I)Landroid/view/View;
HSPLandroid/view/View;->findViewWithTag(Ljava/lang/Object;)Landroid/view/View;
HSPLandroid/view/View;->findViewWithTagTraversal(Ljava/lang/Object;)Landroid/view/View;
@@ -17190,7 +17266,7 @@ HSPLandroid/view/View;->getContentDescription()Ljava/lang/CharSequence;
HSPLandroid/view/View;->getContext()Landroid/content/Context;
HSPLandroid/view/View;->getDefaultSize(II)I
HSPLandroid/view/View;->getDisplay()Landroid/view/Display;
-HSPLandroid/view/View;->getDrawableRenderNode(Landroid/graphics/drawable/Drawable;Landroid/graphics/RenderNode;)Landroid/graphics/RenderNode;+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/drawable/Drawable;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/view/View;->getDrawableRenderNode(Landroid/graphics/drawable/Drawable;Landroid/graphics/RenderNode;)Landroid/graphics/RenderNode;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;
HSPLandroid/view/View;->getDrawableState()[I+]Landroid/view/View;missing_types
HSPLandroid/view/View;->getDrawingCache(Z)Landroid/graphics/Bitmap;
HSPLandroid/view/View;->getDrawingRect(Landroid/graphics/Rect;)V
@@ -17220,16 +17296,16 @@ HSPLandroid/view/View;->getImportantForContentCapture()I
HSPLandroid/view/View;->getInverseMatrix()Landroid/graphics/Matrix;
HSPLandroid/view/View;->getKeyDispatcherState()Landroid/view/KeyEvent$DispatcherState;
HSPLandroid/view/View;->getLayerType()I
-HSPLandroid/view/View;->getLayoutDirection()I+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getLayoutDirection()I+]Landroid/view/View;missing_types]Landroid/content/Context;missing_types
HSPLandroid/view/View;->getLayoutParams()Landroid/view/ViewGroup$LayoutParams;
HSPLandroid/view/View;->getLeft()I
HSPLandroid/view/View;->getListenerInfo()Landroid/view/View$ListenerInfo;
HSPLandroid/view/View;->getLocalVisibleRect(Landroid/graphics/Rect;)Z
HSPLandroid/view/View;->getLocationInSurface([I)V
-HSPLandroid/view/View;->getLocationInWindow([I)V
+HSPLandroid/view/View;->getLocationInWindow([I)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->getLocationOnScreen()[I
-HSPLandroid/view/View;->getLocationOnScreen([I)V
-HSPLandroid/view/View;->getMatrix()Landroid/graphics/Matrix;
+HSPLandroid/view/View;->getLocationOnScreen([I)V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->getMatrix()Landroid/graphics/Matrix;+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->getMeasuredHeight()I
HSPLandroid/view/View;->getMeasuredState()I
HSPLandroid/view/View;->getMeasuredWidth()I
@@ -17241,9 +17317,9 @@ HSPLandroid/view/View;->getOutlineProvider()Landroid/view/ViewOutlineProvider;
HSPLandroid/view/View;->getOverScrollMode()I
HSPLandroid/view/View;->getPaddingBottom()I
HSPLandroid/view/View;->getPaddingEnd()I
-HSPLandroid/view/View;->getPaddingLeft()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getPaddingLeft()I
HSPLandroid/view/View;->getPaddingRight()I
-HSPLandroid/view/View;->getPaddingStart()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getPaddingStart()I
HSPLandroid/view/View;->getPaddingTop()I
HSPLandroid/view/View;->getParent()Landroid/view/ViewParent;
HSPLandroid/view/View;->getPivotX()F
@@ -17261,8 +17337,8 @@ HSPLandroid/view/View;->getRotation()F
HSPLandroid/view/View;->getRotationX()F
HSPLandroid/view/View;->getRotationY()F
HSPLandroid/view/View;->getRunQueue()Landroid/view/HandlerActionQueue;
-HSPLandroid/view/View;->getScaleX()F
-HSPLandroid/view/View;->getScaleY()F
+HSPLandroid/view/View;->getScaleX()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->getScaleY()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->getScrollX()I
HSPLandroid/view/View;->getScrollY()I
HSPLandroid/view/View;->getSolidColor()I
@@ -17281,7 +17357,7 @@ HSPLandroid/view/View;->getTop()I
HSPLandroid/view/View;->getTransitionAlpha()F
HSPLandroid/view/View;->getTransitionName()Ljava/lang/String;
HSPLandroid/view/View;->getTranslationX()F
-HSPLandroid/view/View;->getTranslationY()F
+HSPLandroid/view/View;->getTranslationY()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->getTranslationZ()F
HSPLandroid/view/View;->getVerticalFadingEdgeLength()I
HSPLandroid/view/View;->getVerticalScrollbarWidth()I+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
@@ -17292,11 +17368,11 @@ HSPLandroid/view/View;->getVisibility()I
HSPLandroid/view/View;->getWidth()I
HSPLandroid/view/View;->getWindowAttachCount()I
HSPLandroid/view/View;->getWindowId()Landroid/view/WindowId;
-HSPLandroid/view/View;->getWindowInsetsController()Landroid/view/WindowInsetsController;
+HSPLandroid/view/View;->getWindowInsetsController()Landroid/view/WindowInsetsController;+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/View;->getWindowSystemUiVisibility()I
HSPLandroid/view/View;->getWindowToken()Landroid/os/IBinder;
HSPLandroid/view/View;->getWindowVisibility()I
-HSPLandroid/view/View;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V
HSPLandroid/view/View;->getX()F
HSPLandroid/view/View;->getY()F
HSPLandroid/view/View;->getZ()F
@@ -17314,7 +17390,7 @@ HSPLandroid/view/View;->hasListenersForAccessibility()Z
HSPLandroid/view/View;->hasNestedScrollingParent()Z
HSPLandroid/view/View;->hasOnClickListeners()Z
HSPLandroid/view/View;->hasOverlappingRendering()Z
-HSPLandroid/view/View;->hasRtlSupport()Z+]Landroid/content/Context;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;
+HSPLandroid/view/View;->hasRtlSupport()Z
HSPLandroid/view/View;->hasSize()Z
HSPLandroid/view/View;->hasTransientState()Z
HSPLandroid/view/View;->hasTranslationTransientState()Z
@@ -17327,22 +17403,22 @@ HSPLandroid/view/View;->includeForAccessibility()Z
HSPLandroid/view/View;->includeForAccessibility(Z)Z
HSPLandroid/view/View;->inflate(Landroid/content/Context;ILandroid/view/ViewGroup;)Landroid/view/View;
HSPLandroid/view/View;->initScrollCache()V
-HSPLandroid/view/View;->initialAwakenScrollBars()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->initialAwakenScrollBars()Z+]Landroid/view/View;Landroid/widget/ScrollView;
HSPLandroid/view/View;->initializeFadingEdgeInternal(Landroid/content/res/TypedArray;)V
HSPLandroid/view/View;->initializeScrollIndicatorsInternal()V
HSPLandroid/view/View;->initializeScrollbarsInternal(Landroid/content/res/TypedArray;)V
-HSPLandroid/view/View;->internalSetPadding(IIII)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidate()V
+HSPLandroid/view/View;->internalSetPadding(IIII)V
+HSPLandroid/view/View;->invalidate()V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->invalidate(IIII)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidate(Landroid/graphics/Rect;)V
+HSPLandroid/view/View;->invalidate(Landroid/graphics/Rect;)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->invalidate(Z)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidateInternal(IIIIZZ)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
-HSPLandroid/view/View;->invalidateOutline()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/View;missing_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->invalidateInternal(IIIIZZ)V+]Landroid/view/View;megamorphic_types]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewParent;missing_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->invalidateOutline()V
HSPLandroid/view/View;->invalidateParentCaches()V
HSPLandroid/view/View;->invalidateParentIfNeeded()V
HSPLandroid/view/View;->invalidateParentIfNeededAndWasQuickRejected()V
-HSPLandroid/view/View;->invalidateViewProperty(ZZ)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->invalidateViewProperty(ZZ)V
HSPLandroid/view/View;->isAccessibilityFocused()Z
HSPLandroid/view/View;->isAccessibilityFocusedViewOrHost()Z
HSPLandroid/view/View;->isAccessibilityPane()Z
@@ -17377,7 +17453,7 @@ HSPLandroid/view/View;->isInScrollingContainer()Z
HSPLandroid/view/View;->isInTouchMode()Z
HSPLandroid/view/View;->isKeyboardNavigationCluster()Z
HSPLandroid/view/View;->isLaidOut()Z
-HSPLandroid/view/View;->isLayoutDirectionInherited()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->isLayoutDirectionInherited()Z
HSPLandroid/view/View;->isLayoutDirectionResolved()Z
HSPLandroid/view/View;->isLayoutModeOptical(Ljava/lang/Object;)Z+]Landroid/view/ViewGroup;missing_types
HSPLandroid/view/View;->isLayoutRequested()Z
@@ -17390,7 +17466,7 @@ HSPLandroid/view/View;->isPaddingResolved()Z
HSPLandroid/view/View;->isPressed()Z
HSPLandroid/view/View;->isProjectionReceiver()Z
HSPLandroid/view/View;->isRootNamespace()Z
-HSPLandroid/view/View;->isRtlCompatibilityMode()Z+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->isRtlCompatibilityMode()Z
HSPLandroid/view/View;->isSelected()Z
HSPLandroid/view/View;->isShowingLayoutBounds()Z
HSPLandroid/view/View;->isShown()Z
@@ -17406,44 +17482,44 @@ HSPLandroid/view/View;->isVerticalScrollBarHidden()Z
HSPLandroid/view/View;->isViewIdGenerated(I)Z
HSPLandroid/view/View;->isVisibleToUser()Z
HSPLandroid/view/View;->isVisibleToUser(Landroid/graphics/Rect;)Z
-HSPLandroid/view/View;->jumpDrawablesToCurrentState()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/view/View;->layout(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->jumpDrawablesToCurrentState()V
+HSPLandroid/view/View;->layout(IIII)V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/View;->makeFrameworkOptionalFitsSystemWindows()V
HSPLandroid/view/View;->makeOptionalFitsSystemWindows()V
HSPLandroid/view/View;->mapRectFromViewToScreenCoords(Landroid/graphics/RectF;Z)V
HSPLandroid/view/View;->mapRectFromViewToWindowCoords(Landroid/graphics/RectF;Z)V
-HSPLandroid/view/View;->measure(II)V+]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->measure(II)V+]Landroid/view/View;megamorphic_types]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;
HSPLandroid/view/View;->mergeDrawableStates([I[I)[I
HSPLandroid/view/View;->needGlobalAttributesUpdate(Z)V
HSPLandroid/view/View;->needRtlPropertiesResolution()Z
HSPLandroid/view/View;->notifyAppearedOrDisappearedForContentCaptureIfNeeded(Z)V
HSPLandroid/view/View;->notifyAutofillManagerOnClick()V
-HSPLandroid/view/View;->notifyEnterOrExitForAutoFillIfNeeded(Z)V+]Landroid/view/View;missing_types]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/View;->notifyEnterOrExitForAutoFillIfNeeded(Z)V
HSPLandroid/view/View;->notifyGlobalFocusCleared(Landroid/view/View;)V
HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedByParentIfNeeded()V
-HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedIfNeeded()V+]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
-HSPLandroid/view/View;->notifyViewAccessibilityStateChangedIfNeeded(I)V+]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
+HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedIfNeeded()V
+HSPLandroid/view/View;->notifyViewAccessibilityStateChangedIfNeeded(I)V
HSPLandroid/view/View;->offsetLeftAndRight(I)V
HSPLandroid/view/View;->offsetTopAndBottom(I)V
HSPLandroid/view/View;->onAnimationEnd()V
HSPLandroid/view/View;->onAnimationStart()V
HSPLandroid/view/View;->onApplyFrameworkOptionalFitSystemWindows(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
HSPLandroid/view/View;->onApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
-HSPLandroid/view/View;->onAttachedToWindow()V+]Landroid/view/View;missing_types]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;
-HSPLandroid/view/View;->onCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onAttachedToWindow()V+]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onCancelPendingInputEvents()V
HSPLandroid/view/View;->onCheckIsTextEditor()Z
HSPLandroid/view/View;->onCloseSystemDialogs(Ljava/lang/String;)V
HSPLandroid/view/View;->onConfigurationChanged(Landroid/content/res/Configuration;)V
HSPLandroid/view/View;->onCreateDrawableState(I)[I+]Landroid/view/View;missing_types
HSPLandroid/view/View;->onCreateInputConnection(Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection;
HSPLandroid/view/View;->onDetachedFromWindow()V
-HSPLandroid/view/View;->onDetachedFromWindowInternal()V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;
+HSPLandroid/view/View;->onDetachedFromWindowInternal()V+]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->onDraw(Landroid/graphics/Canvas;)V
HSPLandroid/view/View;->onDrawForeground(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->onDrawHorizontalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
-HSPLandroid/view/View;->onDrawScrollBars(Landroid/graphics/Canvas;)V
+HSPLandroid/view/View;->onDrawScrollBars(Landroid/graphics/Canvas;)V+]Landroid/graphics/Interpolator;Landroid/graphics/Interpolator;]Landroid/view/View;missing_types]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
HSPLandroid/view/View;->onDrawScrollIndicators(Landroid/graphics/Canvas;)V
-HSPLandroid/view/View;->onDrawVerticalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
+HSPLandroid/view/View;->onDrawVerticalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V+]Landroid/graphics/drawable/Drawable;Landroid/widget/ScrollBarDrawable;
HSPLandroid/view/View;->onFilterTouchEventForSecurity(Landroid/view/MotionEvent;)Z
HSPLandroid/view/View;->onFinishInflate()V
HSPLandroid/view/View;->onFinishTemporaryDetach()V
@@ -17453,7 +17529,7 @@ HSPLandroid/view/View;->onKeyDown(ILandroid/view/KeyEvent;)Z
HSPLandroid/view/View;->onKeyPreIme(ILandroid/view/KeyEvent;)Z
HSPLandroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z
HSPLandroid/view/View;->onLayout(ZIIII)V
-HSPLandroid/view/View;->onMeasure(II)V+]Landroid/view/View;Landroid/view/View;
+HSPLandroid/view/View;->onMeasure(II)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->onProvideAutofillStructure(Landroid/view/ViewStructure;I)V
HSPLandroid/view/View;->onProvideAutofillVirtualStructure(Landroid/view/ViewStructure;I)V
HSPLandroid/view/View;->onProvideContentCaptureStructure(Landroid/view/ViewStructure;I)V
@@ -17463,14 +17539,14 @@ HSPLandroid/view/View;->onRestoreInstanceState(Landroid/os/Parcelable;)V
HSPLandroid/view/View;->onRtlPropertiesChanged(I)V
HSPLandroid/view/View;->onSaveInstanceState()Landroid/os/Parcelable;
HSPLandroid/view/View;->onScreenStateChanged(I)V
-HSPLandroid/view/View;->onScrollChanged(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onScrollChanged(IIII)V
HSPLandroid/view/View;->onSetAlpha(I)Z
HSPLandroid/view/View;->onSizeChanged(IIII)V
HSPLandroid/view/View;->onStartTemporaryDetach()V
HSPLandroid/view/View;->onTouchEvent(Landroid/view/MotionEvent;)Z
-HSPLandroid/view/View;->onVisibilityAggregated(Z)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/view/View;->onVisibilityAggregated(Z)V+]Landroid/view/View;megamorphic_types]Ljava/util/List;Ljava/util/Collections$EmptyList;,Ljava/util/ArrayList;]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/view/View;->onVisibilityChanged(Landroid/view/View;I)V
-HSPLandroid/view/View;->onWindowFocusChanged(Z)V+]Landroid/view/View;megamorphic_types
+HSPLandroid/view/View;->onWindowFocusChanged(Z)V
HSPLandroid/view/View;->onWindowSystemUiVisibilityChanged(I)V
HSPLandroid/view/View;->onWindowVisibilityChanged(I)V
HSPLandroid/view/View;->overScrollBy(IIIIIIIIZ)Z
@@ -17494,9 +17570,9 @@ HSPLandroid/view/View;->postOnAnimation(Ljava/lang/Runnable;)V
HSPLandroid/view/View;->postOnAnimationDelayed(Ljava/lang/Runnable;J)V
HSPLandroid/view/View;->postSendViewScrolledAccessibilityEventCallback(II)V
HSPLandroid/view/View;->postUpdate(Ljava/lang/Runnable;)V
-HSPLandroid/view/View;->rebuildOutline()V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/ViewOutlineProvider;missing_types
+HSPLandroid/view/View;->rebuildOutline()V+]Landroid/view/ViewOutlineProvider;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/Outline;Landroid/graphics/Outline;
HSPLandroid/view/View;->recomputePadding()V
-HSPLandroid/view/View;->refreshDrawableState()V+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->refreshDrawableState()V
HSPLandroid/view/View;->registerPendingFrameMetricsObservers()V
HSPLandroid/view/View;->removeCallbacks(Ljava/lang/Runnable;)Z
HSPLandroid/view/View;->removeFrameMetricsListener(Landroid/view/Window$OnFrameMetricsAvailableListener;)V
@@ -17512,30 +17588,30 @@ HSPLandroid/view/View;->requestFocus()Z
HSPLandroid/view/View;->requestFocus(I)Z
HSPLandroid/view/View;->requestFocus(ILandroid/graphics/Rect;)Z
HSPLandroid/view/View;->requestFocusNoSearch(ILandroid/graphics/Rect;)Z
-HSPLandroid/view/View;->requestLayout()V+]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->requestLayout()V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/ViewParent;missing_types
HSPLandroid/view/View;->requestRectangleOnScreen(Landroid/graphics/Rect;)Z
HSPLandroid/view/View;->requestRectangleOnScreen(Landroid/graphics/Rect;Z)Z
HSPLandroid/view/View;->requireViewById(I)Landroid/view/View;
-HSPLandroid/view/View;->resetDisplayList()V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->resetDisplayList()V
HSPLandroid/view/View;->resetPressedState()V
-HSPLandroid/view/View;->resetResolvedDrawables()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetResolvedDrawables()V
HSPLandroid/view/View;->resetResolvedDrawablesInternal()V
HSPLandroid/view/View;->resetResolvedLayoutDirection()V
-HSPLandroid/view/View;->resetResolvedPadding()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetResolvedPadding()V
HSPLandroid/view/View;->resetResolvedPaddingInternal()V
HSPLandroid/view/View;->resetResolvedTextAlignment()V
HSPLandroid/view/View;->resetResolvedTextDirection()V
-HSPLandroid/view/View;->resetRtlProperties()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetRtlProperties()V
HSPLandroid/view/View;->resetSubtreeAccessibilityStateChanged()V
-HSPLandroid/view/View;->resolveDrawables()V+]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/view/View;missing_types
-HSPLandroid/view/View;->resolveLayoutDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->resolveDrawables()V
+HSPLandroid/view/View;->resolveLayoutDirection()Z
HSPLandroid/view/View;->resolveLayoutParams()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup$LayoutParams;missing_types
-HSPLandroid/view/View;->resolvePadding()V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
+HSPLandroid/view/View;->resolvePadding()V+]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/ColorDrawable;
HSPLandroid/view/View;->resolveRtlPropertiesIfNeeded()Z+]Landroid/view/View;missing_types
HSPLandroid/view/View;->resolveSize(II)I
HSPLandroid/view/View;->resolveSizeAndState(III)I
-HSPLandroid/view/View;->resolveTextAlignment()Z+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->resolveTextDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->resolveTextAlignment()Z
+HSPLandroid/view/View;->resolveTextDirection()Z
HSPLandroid/view/View;->restoreHierarchyState(Landroid/util/SparseArray;)V
HSPLandroid/view/View;->retrieveExplicitStyle(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;)V
HSPLandroid/view/View;->rootViewRequestFocus()Z
@@ -17557,53 +17633,53 @@ HSPLandroid/view/View;->setAccessibilityTraversalBefore(I)V
HSPLandroid/view/View;->setActivated(Z)V
HSPLandroid/view/View;->setAlpha(F)V
HSPLandroid/view/View;->setAlphaInternal(F)V
-HSPLandroid/view/View;->setAlphaNoInvalidation(F)Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setAlphaNoInvalidation(F)Z
HSPLandroid/view/View;->setAnimation(Landroid/view/animation/Animation;)V
HSPLandroid/view/View;->setAutoHandwritingEnabled(Z)V
HSPLandroid/view/View;->setAutofilled(ZZ)V
HSPLandroid/view/View;->setBackground(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/view/View;->setBackgroundBounds()V+]Landroid/graphics/drawable/Drawable;missing_types
HSPLandroid/view/View;->setBackgroundColor(I)V
-HSPLandroid/view/View;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
+HSPLandroid/view/View;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/ColorDrawable;
HSPLandroid/view/View;->setBackgroundRenderNodeProperties(Landroid/graphics/RenderNode;)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->setBackgroundResource(I)V
HSPLandroid/view/View;->setBackgroundTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/view/View;->setBottom(I)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setBottom(I)V
HSPLandroid/view/View;->setClickable(Z)V
HSPLandroid/view/View;->setClipBounds(Landroid/graphics/Rect;)V
HSPLandroid/view/View;->setClipToOutline(Z)V
HSPLandroid/view/View;->setContentDescription(Ljava/lang/CharSequence;)V
HSPLandroid/view/View;->setDefaultFocusHighlightEnabled(Z)V
HSPLandroid/view/View;->setDetached(Z)V
-HSPLandroid/view/View;->setDisplayListProperties(Landroid/graphics/RenderNode;)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setDisplayListProperties(Landroid/graphics/RenderNode;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->setDrawingCacheEnabled(Z)V
HSPLandroid/view/View;->setElevation(F)V
HSPLandroid/view/View;->setEnabled(Z)V
HSPLandroid/view/View;->setFitsSystemWindows(Z)V
-HSPLandroid/view/View;->setFlags(II)V+]Landroid/view/View;megamorphic_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewParent;missing_types]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
+HSPLandroid/view/View;->setFlags(II)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/view/ViewParent;missing_types
HSPLandroid/view/View;->setFocusable(I)V
HSPLandroid/view/View;->setFocusable(Z)V
HSPLandroid/view/View;->setFocusableInTouchMode(Z)V
HSPLandroid/view/View;->setForeground(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/view/View;->setForegroundGravity(I)V
-HSPLandroid/view/View;->setFrame(IIII)Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setFrame(IIII)Z+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->setHandwritingArea(Landroid/graphics/Rect;)V
HSPLandroid/view/View;->setHapticFeedbackEnabled(Z)V
HSPLandroid/view/View;->setHasTransientState(Z)V
HSPLandroid/view/View;->setHorizontalFadingEdgeEnabled(Z)V
HSPLandroid/view/View;->setHorizontalScrollBarEnabled(Z)V
HSPLandroid/view/View;->setId(I)V
-HSPLandroid/view/View;->setImportantForAccessibility(I)V+]Landroid/view/View;megamorphic_types
+HSPLandroid/view/View;->setImportantForAccessibility(I)V
HSPLandroid/view/View;->setImportantForAutofill(I)V
HSPLandroid/view/View;->setImportantForContentCapture(I)V
HSPLandroid/view/View;->setIsRootNamespace(Z)V
HSPLandroid/view/View;->setKeepScreenOn(Z)V
HSPLandroid/view/View;->setKeyboardNavigationCluster(Z)V
-HSPLandroid/view/View;->setKeyedTag(ILjava/lang/Object;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/View;->setKeyedTag(ILjava/lang/Object;)V
HSPLandroid/view/View;->setLayerPaint(Landroid/graphics/Paint;)V
HSPLandroid/view/View;->setLayerType(ILandroid/graphics/Paint;)V
HSPLandroid/view/View;->setLayoutDirection(I)V
-HSPLandroid/view/View;->setLayoutParams(Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/View;->setLayoutParams(Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Lcom/android/internal/policy/DecorView;
HSPLandroid/view/View;->setLeft(I)V
HSPLandroid/view/View;->setLeftTopRightBottom(IIII)V
HSPLandroid/view/View;->setLongClickable(Z)V
@@ -17628,21 +17704,21 @@ HSPLandroid/view/View;->setOutlineProvider(Landroid/view/ViewOutlineProvider;)V
HSPLandroid/view/View;->setOutlineProviderFromAttribute(I)V
HSPLandroid/view/View;->setOutlineSpotShadowColor(I)V
HSPLandroid/view/View;->setOverScrollMode(I)V
-HSPLandroid/view/View;->setPadding(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setPadding(IIII)V
HSPLandroid/view/View;->setPaddingRelative(IIII)V
HSPLandroid/view/View;->setPivotX(F)V
HSPLandroid/view/View;->setPivotY(F)V
HSPLandroid/view/View;->setPointerIcon(Landroid/view/PointerIcon;)V
HSPLandroid/view/View;->setPressed(Z)V
HSPLandroid/view/View;->setRenderEffect(Landroid/graphics/RenderEffect;)V
-HSPLandroid/view/View;->setRight(I)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setRight(I)V
HSPLandroid/view/View;->setRotation(F)V
HSPLandroid/view/View;->setRotationX(F)V
HSPLandroid/view/View;->setRotationY(F)V
HSPLandroid/view/View;->setSaveEnabled(Z)V
HSPLandroid/view/View;->setSaveFromParentEnabled(Z)V
-HSPLandroid/view/View;->setScaleX(F)V
-HSPLandroid/view/View;->setScaleY(F)V
+HSPLandroid/view/View;->setScaleX(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setScaleY(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->setScrollContainer(Z)V
HSPLandroid/view/View;->setScrollIndicators(II)V
HSPLandroid/view/View;->setScrollX(I)V
@@ -17665,40 +17741,41 @@ HSPLandroid/view/View;->setTransitionName(Ljava/lang/String;)V
HSPLandroid/view/View;->setTransitionVisibility(I)V
HSPLandroid/view/View;->setTranslationX(F)V
HSPLandroid/view/View;->setTranslationY(F)V
-HSPLandroid/view/View;->setTranslationZ(F)V
+HSPLandroid/view/View;->setTranslationZ(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->setVerticalScrollBarEnabled(Z)V
-HSPLandroid/view/View;->setVisibility(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setVisibility(I)V
HSPLandroid/view/View;->setWillNotDraw(Z)V
HSPLandroid/view/View;->setX(F)V
HSPLandroid/view/View;->setY(F)V
-HSPLandroid/view/View;->shouldDrawRoundScrollbar()Z+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/Resources;Landroid/content/res/Resources;
-HSPLandroid/view/View;->sizeChange(IIII)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/View;->shouldDrawRoundScrollbar()Z+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;
+HSPLandroid/view/View;->sizeChange(IIII)V
HSPLandroid/view/View;->skipInvalidate()Z+]Landroid/view/ViewGroup;missing_types
HSPLandroid/view/View;->startAnimation(Landroid/view/animation/Animation;)V
HSPLandroid/view/View;->startNestedScroll(I)Z
HSPLandroid/view/View;->stopNestedScroll()V
HSPLandroid/view/View;->switchDefaultFocusHighlight()V
HSPLandroid/view/View;->toString()Ljava/lang/String;
-HSPLandroid/view/View;->transformFromViewToWindowSpace([I)V
+HSPLandroid/view/View;->transformFromViewToWindowSpace([I)V+]Landroid/view/View;missing_types
HSPLandroid/view/View;->unFocus(Landroid/view/View;)V
-HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
+HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;Ljava/lang/Runnable;)V
-HSPLandroid/view/View;->updateDisplayListIfDirty()Landroid/graphics/RenderNode;+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/view/ViewOverlay$OverlayViewGroup;]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/View;->updateDisplayListIfDirty()Landroid/graphics/RenderNode;+]Landroid/view/View;megamorphic_types]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/view/View;->updateFocusedInCluster(Landroid/view/View;I)V
HSPLandroid/view/View;->updateHandwritingArea()V
HSPLandroid/view/View;->updateKeepClearRects()V
HSPLandroid/view/View;->updateLocalSystemUiVisibility(II)Z
HSPLandroid/view/View;->updatePflags3AndNotifyA11yIfChanged(IZ)V
-HSPLandroid/view/View;->updatePositionUpdateListener()V+]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/view/View;->updatePositionUpdateListener()V
HSPLandroid/view/View;->updatePreferKeepClearForFocus()V
HSPLandroid/view/View;->updateSystemGestureExclusionRects()V
HSPLandroid/view/View;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
HSPLandroid/view/View;->willNotDraw()Z
HSPLandroid/view/ViewAnimationHostBridge;-><init>(Landroid/view/View;)V
HSPLandroid/view/ViewAnimationHostBridge;->isAttached()Z
+HSPLandroid/view/ViewAnimationHostBridge;->registerAnimatingRenderNode(Landroid/graphics/RenderNode;)V
HSPLandroid/view/ViewAnimationHostBridge;->registerVectorDrawableAnimator(Landroid/view/NativeVectorDrawableAnimator;)V
HSPLandroid/view/ViewConfiguration;-><init>(Landroid/content/Context;)V
-HSPLandroid/view/ViewConfiguration;->get(Landroid/content/Context;)Landroid/view/ViewConfiguration;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/ViewConfiguration;->get(Landroid/content/Context;)Landroid/view/ViewConfiguration;
HSPLandroid/view/ViewConfiguration;->getDoubleTapTimeout()I
HSPLandroid/view/ViewConfiguration;->getLongPressTimeout()I
HSPLandroid/view/ViewConfiguration;->getPressedStateDuration()I
@@ -17745,9 +17822,9 @@ HSPLandroid/view/ViewGroup$LayoutParams;-><init>(II)V
HSPLandroid/view/ViewGroup$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/view/ViewGroup$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup$LayoutParams;->resolveLayoutDirection(I)V
-HSPLandroid/view/ViewGroup$LayoutParams;->setBaseAttributes(Landroid/content/res/TypedArray;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/view/ViewGroup$LayoutParams;->setBaseAttributes(Landroid/content/res/TypedArray;II)V
HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(II)V
-HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/ViewGroup$MarginLayoutParams;missing_types
+HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/view/ViewGroup$MarginLayoutParams;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/view/ViewGroup$MarginLayoutParams;)V
HSPLandroid/view/ViewGroup$MarginLayoutParams;->doResolveMargins()V
@@ -17773,12 +17850,12 @@ HSPLandroid/view/ViewGroup;->addTouchTarget(Landroid/view/View;I)Landroid/view/V
HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;I)V
HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;II)V
-HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup;->addViewInLayout(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)Z
HSPLandroid/view/ViewGroup;->addViewInLayout(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)Z
-HSPLandroid/view/ViewGroup;->addViewInner(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)V+]Landroid/animation/LayoutTransition;Landroid/animation/LayoutTransition;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->attachViewToParent(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->addViewInner(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->attachViewToParent(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup;->bringChildToFront(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->buildOrderedChildList()Ljava/util/ArrayList;
HSPLandroid/view/ViewGroup;->buildTouchDispatchChildList()Ljava/util/ArrayList;
@@ -17795,20 +17872,20 @@ HSPLandroid/view/ViewGroup;->clearDisappearingChildren()V
HSPLandroid/view/ViewGroup;->clearFocus()V
HSPLandroid/view/ViewGroup;->clearFocusedInCluster()V
HSPLandroid/view/ViewGroup;->clearTouchTargets()V
-HSPLandroid/view/ViewGroup;->destroyHardwareResources()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->destroyHardwareResources()V
HSPLandroid/view/ViewGroup;->detachAllViewsFromParent()V
HSPLandroid/view/ViewGroup;->detachViewFromParent(I)V
HSPLandroid/view/ViewGroup;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
-HSPLandroid/view/ViewGroup;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->dispatchCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V
+HSPLandroid/view/ViewGroup;->dispatchCancelPendingInputEvents()V
HSPLandroid/view/ViewGroup;->dispatchCollectViewAttributes(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types
HSPLandroid/view/ViewGroup;->dispatchConfigurationChanged(Landroid/content/res/Configuration;)V
HSPLandroid/view/ViewGroup;->dispatchDetachedFromWindow()V
-HSPLandroid/view/ViewGroup;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/animation/LayoutAnimationController;Landroid/view/animation/LayoutAnimationController;
+HSPLandroid/view/ViewGroup;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/view/ViewGroup;->dispatchDrawableHotspotChanged(FF)V
HSPLandroid/view/ViewGroup;->dispatchFinishTemporaryDetach()V
HSPLandroid/view/ViewGroup;->dispatchFreezeSelfOnly(Landroid/util/SparseArray;)V
-HSPLandroid/view/ViewGroup;->dispatchGetDisplayList()V+]Landroid/view/View;missing_types]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/ViewGroup;->dispatchGetDisplayList()V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewGroup;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
HSPLandroid/view/ViewGroup;->dispatchKeyEventPreIme(Landroid/view/KeyEvent;)Z
HSPLandroid/view/ViewGroup;->dispatchProvideAutofillStructure(Landroid/view/ViewStructure;I)V
@@ -17822,17 +17899,17 @@ HSPLandroid/view/ViewGroup;->dispatchSetSelected(Z)V
HSPLandroid/view/ViewGroup;->dispatchStartTemporaryDetach()V
HSPLandroid/view/ViewGroup;->dispatchSystemUiVisibilityChanged(I)V
HSPLandroid/view/ViewGroup;->dispatchThawSelfOnly(Landroid/util/SparseArray;)V
-HSPLandroid/view/ViewGroup;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/ViewGroup;->dispatchTransformedTouchEvent(Landroid/view/MotionEvent;ZLandroid/view/View;I)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/ViewGroup$TouchTarget;Landroid/view/ViewGroup$TouchTarget;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
+HSPLandroid/view/ViewGroup;->dispatchTransformedTouchEvent(Landroid/view/MotionEvent;ZLandroid/view/View;I)Z+]Landroid/view/View;missing_types]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/view/ViewGroup;->dispatchUnhandledKeyEvent(Landroid/view/KeyEvent;)Landroid/view/View;
-HSPLandroid/view/ViewGroup;->dispatchViewAdded(Landroid/view/View;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->dispatchViewAdded(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->dispatchViewRemoved(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->dispatchVisibilityAggregated(Z)Z+]Landroid/view/View;missing_types
-HSPLandroid/view/ViewGroup;->dispatchVisibilityChanged(Landroid/view/View;I)V+]Landroid/view/View;missing_types
-HSPLandroid/view/ViewGroup;->dispatchWindowFocusChanged(Z)V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchVisibilityChanged(Landroid/view/View;I)V
+HSPLandroid/view/ViewGroup;->dispatchWindowFocusChanged(Z)V
HSPLandroid/view/ViewGroup;->dispatchWindowInsetsAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
HSPLandroid/view/ViewGroup;->dispatchWindowSystemUiVisiblityChanged(I)V
-HSPLandroid/view/ViewGroup;->dispatchWindowVisibilityChanged(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchWindowVisibilityChanged(I)V
HSPLandroid/view/ViewGroup;->drawChild(Landroid/graphics/Canvas;Landroid/view/View;J)Z+]Landroid/view/View;missing_types
HSPLandroid/view/ViewGroup;->drawableStateChanged()V
HSPLandroid/view/ViewGroup;->endViewTransition(Landroid/view/View;)V
@@ -17842,7 +17919,7 @@ HSPLandroid/view/ViewGroup;->findFocus()Landroid/view/View;
HSPLandroid/view/ViewGroup;->findOnBackInvokedDispatcherForChild(Landroid/view/View;Landroid/view/View;)Landroid/window/OnBackInvokedDispatcher;
HSPLandroid/view/ViewGroup;->findViewByAutofillIdTraversal(I)Landroid/view/View;
HSPLandroid/view/ViewGroup;->findViewByPredicateTraversal(Ljava/util/function/Predicate;Landroid/view/View;)Landroid/view/View;
-HSPLandroid/view/ViewGroup;->findViewTraversal(I)Landroid/view/View;+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->findViewTraversal(I)Landroid/view/View;
HSPLandroid/view/ViewGroup;->findViewWithTagTraversal(Ljava/lang/Object;)Landroid/view/View;
HSPLandroid/view/ViewGroup;->finishAnimatingView(Landroid/view/View;Landroid/view/animation/Animation;)V
HSPLandroid/view/ViewGroup;->focusSearch(Landroid/view/View;I)Landroid/view/View;
@@ -17858,7 +17935,7 @@ HSPLandroid/view/ViewGroup;->getChildCount()I
HSPLandroid/view/ViewGroup;->getChildMeasureSpec(III)I
HSPLandroid/view/ViewGroup;->getChildTransformation()Landroid/view/animation/Transformation;
HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
-HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewParent;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;Z)Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewParent;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewGroup;->getChildrenForAutofill(I)Landroid/view/ViewGroup$ChildListForAutoFillOrContentCapture;
HSPLandroid/view/ViewGroup;->getChildrenForContentCapture()Landroid/view/ViewGroup$ChildListForAutoFillOrContentCapture;
HSPLandroid/view/ViewGroup;->getClipChildren()Z
@@ -17884,8 +17961,8 @@ HSPLandroid/view/ViewGroup;->hasTransientState()Z
HSPLandroid/view/ViewGroup;->hasUnhandledKeyListener()Z
HSPLandroid/view/ViewGroup;->hasWindowInsetsAnimationCallback()Z
HSPLandroid/view/ViewGroup;->indexOfChild(Landroid/view/View;)I
-HSPLandroid/view/ViewGroup;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->initViewGroup()V+]Landroid/content/Context;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V
+HSPLandroid/view/ViewGroup;->initViewGroup()V
HSPLandroid/view/ViewGroup;->internalSetPadding(IIII)V
HSPLandroid/view/ViewGroup;->invalidateChild(Landroid/view/View;Landroid/graphics/Rect;)V+]Landroid/view/ViewGroup;missing_types
HSPLandroid/view/ViewGroup;->invalidateChildInParent([ILandroid/graphics/Rect;)Landroid/view/ViewParent;
@@ -17894,7 +17971,7 @@ HSPLandroid/view/ViewGroup;->isLayoutModeOptical()Z
HSPLandroid/view/ViewGroup;->isLayoutSuppressed()Z
HSPLandroid/view/ViewGroup;->isTransformedTouchPointInView(FFLandroid/view/View;Landroid/graphics/PointF;)Z
HSPLandroid/view/ViewGroup;->isViewTransitioning(Landroid/view/View;)Z
-HSPLandroid/view/ViewGroup;->jumpDrawablesToCurrentState()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->jumpDrawablesToCurrentState()V
HSPLandroid/view/ViewGroup;->layout(IIII)V
HSPLandroid/view/ViewGroup;->makeFrameworkOptionalFitsSystemWindows()V
HSPLandroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V
@@ -17911,9 +17988,9 @@ HSPLandroid/view/ViewGroup;->onCreateDrawableState(I)[I
HSPLandroid/view/ViewGroup;->onDescendantInvalidated(Landroid/view/View;Landroid/view/View;)V+]Landroid/view/ViewParent;missing_types
HSPLandroid/view/ViewGroup;->onDescendantUnbufferedRequested()V
HSPLandroid/view/ViewGroup;->onDetachedFromWindow()V
-HSPLandroid/view/ViewGroup;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z
+HSPLandroid/view/ViewGroup;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/view/ViewGroup;->onRequestFocusInDescendants(ILandroid/graphics/Rect;)Z
-HSPLandroid/view/ViewGroup;->onSetLayoutParams(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->onSetLayoutParams(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/view/ViewGroup;->onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z
HSPLandroid/view/ViewGroup;->onViewAdded(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->onViewRemoved(Landroid/view/View;)V
@@ -17934,22 +18011,22 @@ HSPLandroid/view/ViewGroup;->removeViewInternal(ILandroid/view/View;)V
HSPLandroid/view/ViewGroup;->removeViewInternal(Landroid/view/View;)Z
HSPLandroid/view/ViewGroup;->requestChildFocus(Landroid/view/View;Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->requestChildRectangleOnScreen(Landroid/view/View;Landroid/graphics/Rect;Z)Z
-HSPLandroid/view/ViewGroup;->requestDisallowInterceptTouchEvent(Z)V
+HSPLandroid/view/ViewGroup;->requestDisallowInterceptTouchEvent(Z)V+]Landroid/view/ViewParent;missing_types
HSPLandroid/view/ViewGroup;->requestFocus(ILandroid/graphics/Rect;)Z
HSPLandroid/view/ViewGroup;->requestTransitionStart(Landroid/animation/LayoutTransition;)V
HSPLandroid/view/ViewGroup;->requestTransparentRegion(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->resetCancelNextUpFlag(Landroid/view/View;)Z
-HSPLandroid/view/ViewGroup;->resetResolvedDrawables()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedLayoutDirection()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedPadding()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedTextAlignment()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedTextDirection()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetSubtreeAccessibilityStateChanged()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->resetResolvedDrawables()V
+HSPLandroid/view/ViewGroup;->resetResolvedLayoutDirection()V
+HSPLandroid/view/ViewGroup;->resetResolvedPadding()V
+HSPLandroid/view/ViewGroup;->resetResolvedTextAlignment()V
+HSPLandroid/view/ViewGroup;->resetResolvedTextDirection()V
+HSPLandroid/view/ViewGroup;->resetSubtreeAccessibilityStateChanged()V
HSPLandroid/view/ViewGroup;->resetTouchState()V
HSPLandroid/view/ViewGroup;->resolveDrawables()V
HSPLandroid/view/ViewGroup;->resolveLayoutDirection()Z
HSPLandroid/view/ViewGroup;->resolveLayoutParams()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resolvePadding()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->resolvePadding()V
HSPLandroid/view/ViewGroup;->resolveRtlPropertiesIfNeeded()Z+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
HSPLandroid/view/ViewGroup;->resolveTextAlignment()Z
HSPLandroid/view/ViewGroup;->resolveTextDirection()Z
@@ -17970,7 +18047,7 @@ HSPLandroid/view/ViewGroup;->shouldBlockFocusForTouchscreen()Z
HSPLandroid/view/ViewGroup;->shouldDelayChildPressedState()Z
HSPLandroid/view/ViewGroup;->startViewTransition(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->suppressLayout(Z)V
-HSPLandroid/view/ViewGroup;->touchAccessibilityNodeProviderIfNeeded(Landroid/view/View;)V+]Landroid/content/Context;missing_types
+HSPLandroid/view/ViewGroup;->touchAccessibilityNodeProviderIfNeeded(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->transformPointToViewLocal([FLandroid/view/View;)V
HSPLandroid/view/ViewGroup;->unFocus(Landroid/view/View;)V
HSPLandroid/view/ViewGroup;->updateLocalSystemUiVisibility(II)Z
@@ -18002,7 +18079,7 @@ HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;-><init>(Landroid/vi
HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationCancel(Landroid/animation/Animator;)V
HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationEnd(Landroid/animation/Animator;)V
HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationStart(Landroid/animation/Animator;)V
-HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/view/View;Landroid/widget/LinearLayout;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
HSPLandroid/view/ViewPropertyAnimator$NameValuesHolder;-><init>(IFF)V
HSPLandroid/view/ViewPropertyAnimator$PropertyBundle;-><init>(ILjava/util/ArrayList;)V
HSPLandroid/view/ViewPropertyAnimator$PropertyBundle;->cancel(I)Z
@@ -18026,6 +18103,7 @@ HSPLandroid/view/ViewPropertyAnimator;->translationY(F)Landroid/view/ViewPropert
HSPLandroid/view/ViewPropertyAnimator;->withEndAction(Ljava/lang/Runnable;)Landroid/view/ViewPropertyAnimator;
HSPLandroid/view/ViewPropertyAnimator;->withLayer()Landroid/view/ViewPropertyAnimator;
HSPLandroid/view/ViewPropertyAnimator;->withStartAction(Ljava/lang/Runnable;)Landroid/view/ViewPropertyAnimator;
+HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda0;->run()V
HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda17;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda3;->run()V
HSPLandroid/view/ViewRootImpl$AccessibilityInteractionConnectionManager;-><init>(Landroid/view/ViewRootImpl;)V
@@ -18042,13 +18120,13 @@ HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;-><init>(Landroid/view/View
HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processKeyEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processMotionEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
-HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$HighContrastTextManager;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$ImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;Ljava/lang/String;)V
HSPLandroid/view/ViewRootImpl$ImeInputStage;->onFinishedInputEvent(Ljava/lang/Object;Z)V
HSPLandroid/view/ViewRootImpl$ImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$InputMetricsListener;-><init>(Landroid/view/ViewRootImpl;)V
-HSPLandroid/view/ViewRootImpl$InputMetricsListener;->onFrameMetricsAvailable(I)V
+HSPLandroid/view/ViewRootImpl$InputMetricsListener;->onFrameMetricsAvailable(I)V+]Landroid/view/ViewRootImpl$WindowInputEventReceiver;Landroid/view/ViewRootImpl$WindowInputEventReceiver;
HSPLandroid/view/ViewRootImpl$InputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;)V
HSPLandroid/view/ViewRootImpl$InputStage;->apply(Landroid/view/ViewRootImpl$QueuedInputEvent;I)V
HSPLandroid/view/ViewRootImpl$InputStage;->deliver(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
@@ -18057,12 +18135,12 @@ HSPLandroid/view/ViewRootImpl$InputStage;->forward(Landroid/view/ViewRootImpl$Qu
HSPLandroid/view/ViewRootImpl$InputStage;->onDeliverToNext(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
HSPLandroid/view/ViewRootImpl$InputStage;->onDetachedFromWindow()V
HSPLandroid/view/ViewRootImpl$InputStage;->onWindowFocusChanged(Z)V
-HSPLandroid/view/ViewRootImpl$InputStage;->shouldDropInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)Z+]Landroid/view/InputEvent;Landroid/view/MotionEvent;
-HSPLandroid/view/ViewRootImpl$InputStage;->traceEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;J)V+]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/view/ViewRootImpl$EarlyPostImeInputStage;,Landroid/view/ViewRootImpl$NativePostImeInputStage;,Landroid/view/ViewRootImpl$SyntheticInputStage;,Landroid/view/ViewRootImpl$ViewPostImeInputStage;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl$InputStage;->shouldDropInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)Z
+HSPLandroid/view/ViewRootImpl$InputStage;->traceEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;J)V
HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->addView(Landroid/view/View;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->postIfNeededLocked()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
-HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->removeView(Landroid/view/View;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->removeView(Landroid/view/View;)V
HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->run()V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewRootImpl$NativePostImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;Ljava/lang/String;)V
HSPLandroid/view/ViewRootImpl$NativePostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
@@ -18081,6 +18159,7 @@ HSPLandroid/view/ViewRootImpl$SyntheticJoystickHandler$JoystickAxesState;->reset
HSPLandroid/view/ViewRootImpl$SyntheticJoystickHandler;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$SyntheticJoystickHandler;->cancel()V
HSPLandroid/view/ViewRootImpl$SyntheticKeyboardHandler;-><init>(Landroid/view/ViewRootImpl;)V
+HSPLandroid/view/ViewRootImpl$SyntheticTouchNavigationHandler$1;-><init>(Landroid/view/ViewRootImpl$SyntheticTouchNavigationHandler;)V
HSPLandroid/view/ViewRootImpl$SyntheticTouchNavigationHandler;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$SyntheticTrackballHandler;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$SystemUiVisibilityInfo;-><init>()V
@@ -18097,7 +18176,7 @@ HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->maybeUpdatePointerIcon(Lan
HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->onDeliverToNext(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processKeyEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
-HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I+]Landroid/view/HandwritingInitiator;Landroid/view/HandwritingInitiator;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$ViewPreImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;)V
HSPLandroid/view/ViewRootImpl$ViewPreImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
HSPLandroid/view/ViewRootImpl$ViewRootHandler;-><init>(Landroid/view/ViewRootImpl;)V
@@ -18109,6 +18188,7 @@ HSPLandroid/view/ViewRootImpl$W;-><init>(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/ViewRootImpl$W;->closeSystemDialogs(Ljava/lang/String;)V
HSPLandroid/view/ViewRootImpl$W;->dispatchAppVisibility(Z)V
HSPLandroid/view/ViewRootImpl$W;->dispatchWindowShown()V
+HSPLandroid/view/ViewRootImpl$W;->insetsControlChanged(Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
HSPLandroid/view/ViewRootImpl$W;->moved(II)V
HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;-><init>(Landroid/view/ViewRootImpl;Landroid/view/InputChannel;Landroid/os/Looper;)V
HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;->dispose()V
@@ -18117,27 +18197,29 @@ HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;->onFocusEvent(Z)V
HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;->onInputEvent(Landroid/view/InputEvent;)V
HSPLandroid/view/ViewRootImpl;->-$$Nest$fgetmBlastBufferQueue(Landroid/view/ViewRootImpl;)Landroid/graphics/BLASTBufferQueue;
HSPLandroid/view/ViewRootImpl;->-$$Nest$fputmProfileRendering(Landroid/view/ViewRootImpl;Z)V
+HSPLandroid/view/ViewRootImpl;->-$$Nest$mdispatchInsetsControlChanged(Landroid/view/ViewRootImpl;Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
HSPLandroid/view/ViewRootImpl;->-$$Nest$mprofileRendering(Landroid/view/ViewRootImpl;Z)V
HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;)V
-HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;Landroid/view/IWindowSession;Landroid/view/WindowLayout;)V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowLeaked;Landroid/view/WindowLeaked;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Optional;Ljava/util/Optional;
+HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;Landroid/view/IWindowSession;Landroid/view/WindowLayout;)V
HSPLandroid/view/ViewRootImpl;->addConfigCallback(Landroid/view/ViewRootImpl$ConfigChangedCallback;)V
-HSPLandroid/view/ViewRootImpl;->addFrameCommitCallbackIfNeeded()V
+HSPLandroid/view/ViewRootImpl;->addFrameCommitCallbackIfNeeded()V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->addSurfaceChangedCallback(Landroid/view/ViewRootImpl$SurfaceChangedCallback;)V
HSPLandroid/view/ViewRootImpl;->addWindowCallbacks(Landroid/view/WindowCallbacks;)V
+HSPLandroid/view/ViewRootImpl;->adjustLayoutParamsForCompatibility(Landroid/view/WindowManager$LayoutParams;)V
HSPLandroid/view/ViewRootImpl;->applyKeepScreenOnFlag(Landroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ViewRootImpl;->applyTransactionOnDraw(Landroid/view/SurfaceControl$Transaction;)Z
+HSPLandroid/view/ViewRootImpl;->applyTransactionOnDraw(Landroid/view/SurfaceControl$Transaction;)Z+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->canResolveTextDirection()Z
-HSPLandroid/view/ViewRootImpl;->cancelInvalidate(Landroid/view/View;)V+]Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;
+HSPLandroid/view/ViewRootImpl;->cancelInvalidate(Landroid/view/View;)V
HSPLandroid/view/ViewRootImpl;->checkForLeavingTouchModeAndConsume(Landroid/view/KeyEvent;)Z
HSPLandroid/view/ViewRootImpl;->checkThread()V
HSPLandroid/view/ViewRootImpl;->childDrawableStateChanged(Landroid/view/View;)V
HSPLandroid/view/ViewRootImpl;->childHasTransientStateChanged(Landroid/view/View;Z)V
HSPLandroid/view/ViewRootImpl;->clearChildFocus(Landroid/view/View;)V
HSPLandroid/view/ViewRootImpl;->clearLowProfileModeIfNeeded(IZ)V
-HSPLandroid/view/ViewRootImpl;->collectViewAttributes()Z+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->collectViewAttributes()Z+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
HSPLandroid/view/ViewRootImpl;->controlInsetsForCompatibility(Landroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ViewRootImpl;->createSyncIfNeeded()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/view/ViewRootImpl;->deliverInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V+]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Landroid/view/ViewRootImpl$InputStage;Landroid/view/ViewRootImpl$EarlyPostImeInputStage;]Landroid/view/ViewRootImpl$QueuedInputEvent;Landroid/view/ViewRootImpl$QueuedInputEvent;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl;->createSyncIfNeeded()V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;
+HSPLandroid/view/ViewRootImpl;->deliverInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
HSPLandroid/view/ViewRootImpl;->destroyHardwareRenderer()V
HSPLandroid/view/ViewRootImpl;->destroyHardwareResources()V
HSPLandroid/view/ViewRootImpl;->destroySurface()V
@@ -18149,14 +18231,15 @@ HSPLandroid/view/ViewRootImpl;->dispatchCheckFocus()V
HSPLandroid/view/ViewRootImpl;->dispatchDetachedFromWindow()V
HSPLandroid/view/ViewRootImpl;->dispatchDispatchSystemUiVisibilityChanged()V
HSPLandroid/view/ViewRootImpl;->dispatchFocusEvent(ZZ)V
+HSPLandroid/view/ViewRootImpl;->dispatchInsetsControlChanged(Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
HSPLandroid/view/ViewRootImpl;->dispatchInvalidateDelayed(Landroid/view/View;J)V
-HSPLandroid/view/ViewRootImpl;->dispatchInvalidateOnAnimation(Landroid/view/View;)V
+HSPLandroid/view/ViewRootImpl;->dispatchInvalidateOnAnimation(Landroid/view/View;)V+]Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;
HSPLandroid/view/ViewRootImpl;->dispatchMoved(II)V
HSPLandroid/view/ViewRootImpl;->doConsumeBatchedInput(J)Z
HSPLandroid/view/ViewRootImpl;->doDie()V
-HSPLandroid/view/ViewRootImpl;->doProcessInputEvents()V+]Landroid/view/InputEventAssigner;Landroid/view/InputEventAssigner;]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;
-HSPLandroid/view/ViewRootImpl;->doTraversal()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;
-HSPLandroid/view/ViewRootImpl;->draw(ZLandroid/window/SurfaceSyncGroup;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;
+HSPLandroid/view/ViewRootImpl;->doProcessInputEvents()V
+HSPLandroid/view/ViewRootImpl;->doTraversal()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
+HSPLandroid/view/ViewRootImpl;->draw(ZLandroid/window/SurfaceSyncGroup;Z)Z+]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;
HSPLandroid/view/ViewRootImpl;->drawAccessibilityFocusedDrawableIfNeeded(Landroid/graphics/Canvas;)V
HSPLandroid/view/ViewRootImpl;->drawSoftware(Landroid/view/Surface;Landroid/view/View$AttachInfo;IIZLandroid/graphics/Rect;Landroid/graphics/Rect;)Z
HSPLandroid/view/ViewRootImpl;->enableHardwareAcceleration(Landroid/view/WindowManager$LayoutParams;)V
@@ -18178,10 +18261,10 @@ HSPLandroid/view/ViewRootImpl;->getAutofillManager()Landroid/view/autofill/Autof
HSPLandroid/view/ViewRootImpl;->getBufferTransformHint()I
HSPLandroid/view/ViewRootImpl;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
HSPLandroid/view/ViewRootImpl;->getCompatWindowConfiguration()Landroid/app/WindowConfiguration;
-HSPLandroid/view/ViewRootImpl;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/view/ViewRootImpl;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;
HSPLandroid/view/ViewRootImpl;->getDisplayId()I
HSPLandroid/view/ViewRootImpl;->getHandwritingInitiator()Landroid/view/HandwritingInitiator;
-HSPLandroid/view/ViewRootImpl;->getHostVisibility()I+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->getHostVisibility()I+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
HSPLandroid/view/ViewRootImpl;->getImeFocusController()Landroid/view/ImeFocusController;
HSPLandroid/view/ViewRootImpl;->getImpliedSystemUiVisibility(Landroid/view/WindowManager$LayoutParams;)I
HSPLandroid/view/ViewRootImpl;->getInsetsController()Landroid/view/InsetsController;
@@ -18195,14 +18278,14 @@ HSPLandroid/view/ViewRootImpl;->getSurfaceControl()Landroid/view/SurfaceControl;
HSPLandroid/view/ViewRootImpl;->getSurfaceSequenceId()I
HSPLandroid/view/ViewRootImpl;->getTextDirection()I
HSPLandroid/view/ViewRootImpl;->getTitle()Ljava/lang/CharSequence;
-HSPLandroid/view/ViewRootImpl;->getUpdatedFrameInfo()Landroid/graphics/FrameInfo;
+HSPLandroid/view/ViewRootImpl;->getUpdatedFrameInfo()Landroid/graphics/FrameInfo;+]Landroid/view/InputEventAssigner;Landroid/view/InputEventAssigner;]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;
HSPLandroid/view/ViewRootImpl;->getValidLayoutRequesters(Ljava/util/ArrayList;Z)Ljava/util/ArrayList;
HSPLandroid/view/ViewRootImpl;->getView()Landroid/view/View;
HSPLandroid/view/ViewRootImpl;->getViewBoundsSandboxingEnabled()Z
HSPLandroid/view/ViewRootImpl;->getWindowBoundsInsetSystemBars()Landroid/graphics/Rect;
HSPLandroid/view/ViewRootImpl;->getWindowFlags()I
-HSPLandroid/view/ViewRootImpl;->getWindowInsets(Z)Landroid/view/WindowInsets;+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/Insets;Landroid/graphics/Insets;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;
-HSPLandroid/view/ViewRootImpl;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->getWindowInsets(Z)Landroid/view/WindowInsets;
+HSPLandroid/view/ViewRootImpl;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V
HSPLandroid/view/ViewRootImpl;->handleAppVisibility(Z)V
HSPLandroid/view/ViewRootImpl;->handleContentCaptureFlush()V
HSPLandroid/view/ViewRootImpl;->handleDispatchSystemUiVisibilityChanged()V
@@ -18211,6 +18294,7 @@ HSPLandroid/view/ViewRootImpl;->invalidate()V+]Landroid/graphics/Rect;Landroid/g
HSPLandroid/view/ViewRootImpl;->invalidateChild(Landroid/view/View;Landroid/graphics/Rect;)V
HSPLandroid/view/ViewRootImpl;->invalidateChildInParent([ILandroid/graphics/Rect;)Landroid/view/ViewParent;
HSPLandroid/view/ViewRootImpl;->invalidateRectOnScreen(Landroid/graphics/Rect;)V
+HSPLandroid/view/ViewRootImpl;->isAccessibilityFocusDirty()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
HSPLandroid/view/ViewRootImpl;->isContentCaptureEnabled()Z
HSPLandroid/view/ViewRootImpl;->isContentCaptureReallyEnabled()Z
HSPLandroid/view/ViewRootImpl;->isHardwareEnabled()Z+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
@@ -18228,10 +18312,10 @@ HSPLandroid/view/ViewRootImpl;->lambda$new$1(Landroid/view/View;)Ljava/util/List
HSPLandroid/view/ViewRootImpl;->lambda$new$2(Landroid/view/View;)Ljava/util/List;
HSPLandroid/view/ViewRootImpl;->loadSystemProperties()V
HSPLandroid/view/ViewRootImpl;->maybeFireAccessibilityWindowStateChangedEvent()V
-HSPLandroid/view/ViewRootImpl;->maybeHandleWindowMove(Landroid/graphics/Rect;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->maybeHandleWindowMove(Landroid/graphics/Rect;)V
HSPLandroid/view/ViewRootImpl;->maybeUpdateTooltip(Landroid/view/MotionEvent;)V
-HSPLandroid/view/ViewRootImpl;->measureHierarchy(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/content/res/Resources;IIZ)Z+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
-HSPLandroid/view/ViewRootImpl;->mergeWithNextTransaction(Landroid/view/SurfaceControl$Transaction;J)V
+HSPLandroid/view/ViewRootImpl;->measureHierarchy(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/content/res/Resources;IIZ)Z+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->mergeWithNextTransaction(Landroid/view/SurfaceControl$Transaction;J)V+]Landroid/graphics/BLASTBufferQueue;Landroid/graphics/BLASTBufferQueue;
HSPLandroid/view/ViewRootImpl;->notifyContentCaptureEvents()V
HSPLandroid/view/ViewRootImpl;->notifyDrawStarted(Z)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewRootImpl;->notifyInsetsChanged()V
@@ -18246,24 +18330,24 @@ HSPLandroid/view/ViewRootImpl;->onPostDraw(Landroid/graphics/RecordingCanvas;)V
HSPLandroid/view/ViewRootImpl;->onPreDraw(Landroid/graphics/RecordingCanvas;)V
HSPLandroid/view/ViewRootImpl;->onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z
HSPLandroid/view/ViewRootImpl;->performContentCaptureInitialReport()V
-HSPLandroid/view/ViewRootImpl;->performDraw(Landroid/window/SurfaceSyncGroup;)Z+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/view/ViewRootImpl;->performLayout(Landroid/view/WindowManager$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/ViewRootImpl;->performMeasure(II)V+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
-HSPLandroid/view/ViewRootImpl;->performTraversals()V+]Landroid/content/Context;missing_types]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/Region;Landroid/graphics/Region;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Landroid/window/WindowOnBackInvokedDispatcher;Landroid/window/WindowOnBackInvokedDispatcher;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl;->performDraw(Landroid/window/SurfaceSyncGroup;)Z+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->performLayout(Landroid/view/WindowManager$LayoutParams;II)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl;->performMeasure(II)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->performTraversals()V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/View;missing_types]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Landroid/graphics/Region;Landroid/graphics/Region;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Landroid/window/WindowOnBackInvokedDispatcher;Landroid/window/WindowOnBackInvokedDispatcher;
HSPLandroid/view/ViewRootImpl;->playSoundEffect(I)V
HSPLandroid/view/ViewRootImpl;->pokeDrawLockIfNeeded()V
-HSPLandroid/view/ViewRootImpl;->prepareSurfaces()V
+HSPLandroid/view/ViewRootImpl;->prepareSurfaces()V+]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->profileRendering(Z)V
HSPLandroid/view/ViewRootImpl;->recomputeViewAttributes(Landroid/view/View;)V
HSPLandroid/view/ViewRootImpl;->recycleQueuedInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
HSPLandroid/view/ViewRootImpl;->registerAnimatingRenderNode(Landroid/graphics/RenderNode;)V
HSPLandroid/view/ViewRootImpl;->registerBackCallbackOnWindow()V
-HSPLandroid/view/ViewRootImpl;->registerCallbackForPendingTransactions()V
+HSPLandroid/view/ViewRootImpl;->registerCallbackForPendingTransactions()V+]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->registerCallbacksForSync(ZLandroid/window/SurfaceSyncGroup;)V
HSPLandroid/view/ViewRootImpl;->registerCompatOnBackInvokedCallback()V
HSPLandroid/view/ViewRootImpl;->registerListeners()V
-HSPLandroid/view/ViewRootImpl;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V
-HSPLandroid/view/ViewRootImpl;->relayoutWindow(Landroid/view/WindowManager$LayoutParams;IZ)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/view/Display;Landroid/view/Display;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->relayoutWindow(Landroid/view/WindowManager$LayoutParams;IZ)I+]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/view/Display;Landroid/view/Display;
HSPLandroid/view/ViewRootImpl;->removeSendWindowContentChangedCallback()V
HSPLandroid/view/ViewRootImpl;->removeSurfaceChangedCallback(Landroid/view/ViewRootImpl$SurfaceChangedCallback;)V
HSPLandroid/view/ViewRootImpl;->removeWindowCallbacks(Landroid/view/WindowCallbacks;)V
@@ -18276,28 +18360,31 @@ HSPLandroid/view/ViewRootImpl;->requestFitSystemWindows()V
HSPLandroid/view/ViewRootImpl;->requestLayout()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->requestLayoutDuringLayout(Landroid/view/View;)Z
HSPLandroid/view/ViewRootImpl;->requestTransparentRegion(Landroid/view/View;)V
-HSPLandroid/view/ViewRootImpl;->scheduleConsumeBatchedInput()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
-HSPLandroid/view/ViewRootImpl;->scheduleTraversals()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->scheduleConsumeBatchedInput()V
+HSPLandroid/view/ViewRootImpl;->scheduleTraversals()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/Choreographer;Landroid/view/Choreographer;
HSPLandroid/view/ViewRootImpl;->scrollToRectOrFocus(Landroid/graphics/Rect;Z)Z
HSPLandroid/view/ViewRootImpl;->sendBackKeyEvent(I)V
HSPLandroid/view/ViewRootImpl;->setAccessibilityFocus(Landroid/view/View;Landroid/view/accessibility/AccessibilityNodeInfo;)V
HSPLandroid/view/ViewRootImpl;->setAccessibilityWindowAttributesIfNeeded()V
HSPLandroid/view/ViewRootImpl;->setActivityConfigCallback(Landroid/view/ViewRootImpl$ActivityConfigCallback;)V
HSPLandroid/view/ViewRootImpl;->setBoundsLayerCrop(Landroid/view/SurfaceControl$Transaction;)V
-HSPLandroid/view/ViewRootImpl;->setFrame(Landroid/graphics/Rect;Z)V
-HSPLandroid/view/ViewRootImpl;->setLayoutParams(Landroid/view/WindowManager$LayoutParams;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;
+HSPLandroid/view/ViewRootImpl;->setFrame(Landroid/graphics/Rect;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsController;Landroid/view/InsetsController;
+HSPLandroid/view/ViewRootImpl;->setLayoutParams(Landroid/view/WindowManager$LayoutParams;Z)V+]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
HSPLandroid/view/ViewRootImpl;->setOnContentApplyWindowInsetsListener(Landroid/view/Window$OnContentApplyWindowInsetsListener;)V
HSPLandroid/view/ViewRootImpl;->setTag()V
-HSPLandroid/view/ViewRootImpl;->setView(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/view/View;I)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/Display;Landroid/view/Display;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/view/FallbackEventHandler;Lcom/android/internal/policy/PhoneFallbackEventHandler;]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/PendingInsetsController;Landroid/view/PendingInsetsController;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl;->setView(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/view/View;I)V+]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/PendingInsetsController;Landroid/view/PendingInsetsController;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Landroid/view/FallbackEventHandler;Lcom/android/internal/policy/PhoneFallbackEventHandler;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/view/Display;Landroid/view/Display;
HSPLandroid/view/ViewRootImpl;->setWindowStopped(Z)V
HSPLandroid/view/ViewRootImpl;->shouldDispatchCutout()Z
HSPLandroid/view/ViewRootImpl;->shouldOptimizeMeasure(Landroid/view/WindowManager$LayoutParams;)Z
+HSPLandroid/view/ViewRootImpl;->shouldSetFrameRate()Z+]Landroid/view/Surface;Landroid/view/Surface;
+HSPLandroid/view/ViewRootImpl;->shouldSetFrameRateCategory()Z+]Landroid/view/Surface;Landroid/view/Surface;
HSPLandroid/view/ViewRootImpl;->shouldUseDisplaySize(Landroid/view/WindowManager$LayoutParams;)Z
HSPLandroid/view/ViewRootImpl;->systemGestureExclusionChanged()V
HSPLandroid/view/ViewRootImpl;->unscheduleConsumeBatchedInput()V
HSPLandroid/view/ViewRootImpl;->unscheduleTraversals()V
-HSPLandroid/view/ViewRootImpl;->updateBlastSurfaceIfNeeded()V
+HSPLandroid/view/ViewRootImpl;->updateBlastSurfaceIfNeeded()V+]Landroid/graphics/BLASTBufferQueue;Landroid/graphics/BLASTBufferQueue;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;
HSPLandroid/view/ViewRootImpl;->updateBoundsLayer(Landroid/view/SurfaceControl$Transaction;)Z
+HSPLandroid/view/ViewRootImpl;->updateCaptionInsets()Z
HSPLandroid/view/ViewRootImpl;->updateCompatSysUiVisibility(III)V
HSPLandroid/view/ViewRootImpl;->updateCompatSystemUiVisibilityInfo(IIII)V
HSPLandroid/view/ViewRootImpl;->updateConfiguration(I)V
@@ -18320,6 +18407,7 @@ HSPLandroid/view/ViewRootInsetsControllerHost;->getSystemBarsBehavior()I
HSPLandroid/view/ViewRootInsetsControllerHost;->getTranslator()Landroid/content/res/CompatibilityInfo$Translator;
HSPLandroid/view/ViewRootInsetsControllerHost;->getWindowToken()Landroid/os/IBinder;
HSPLandroid/view/ViewRootInsetsControllerHost;->hasAnimationCallbacks()Z
+HSPLandroid/view/ViewRootInsetsControllerHost;->isSystemBarsAppearanceControlled()Z
HSPLandroid/view/ViewRootInsetsControllerHost;->notifyInsetsChanged()V
HSPLandroid/view/ViewRootInsetsControllerHost;->updateCompatSysUiVisibility(III)V
HSPLandroid/view/ViewRootRectTracker$ViewInfo;-><init>(Landroid/view/ViewRootRectTracker;Landroid/view/View;)V
@@ -18342,16 +18430,16 @@ HSPLandroid/view/ViewStub;->setLayoutResource(I)V
HSPLandroid/view/ViewStub;->setOnInflateListener(Landroid/view/ViewStub$OnInflateListener;)V
HSPLandroid/view/ViewStub;->setVisibility(I)V
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;-><init>()V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->get(I)Ljava/lang/Object;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->get(I)Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->size()I
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;-><init>()V
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->add(Ljava/lang/Object;)V
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->addAll(Landroid/view/ViewTreeObserver$CopyOnWriteArray;)V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->end()V
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->end()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->getArray()Ljava/util/ArrayList;
HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->remove(Ljava/lang/Object;)V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->size()I
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->start()Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->size()I+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->start()Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;-><init>()V
HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;->isEmpty()Z
@@ -18367,10 +18455,10 @@ HSPLandroid/view/ViewTreeObserver;->addOnScrollChangedListener(Landroid/view/Vie
HSPLandroid/view/ViewTreeObserver;->captureFrameCommitCallbacks()Ljava/util/ArrayList;
HSPLandroid/view/ViewTreeObserver;->checkIsAlive()V
HSPLandroid/view/ViewTreeObserver;->dispatchOnComputeInternalInsets(Landroid/view/ViewTreeObserver$InternalInsetsInfo;)V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnDraw()V
+HSPLandroid/view/ViewTreeObserver;->dispatchOnDraw()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/view/ViewTreeObserver$OnDrawListener;Landroid/widget/Editor$2;
HSPLandroid/view/ViewTreeObserver;->dispatchOnEnterAnimationComplete()V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnGlobalLayout()V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnPreDraw()Z
+HSPLandroid/view/ViewTreeObserver;->dispatchOnGlobalLayout()V+]Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;]Landroid/view/ViewTreeObserver$CopyOnWriteArray;Landroid/view/ViewTreeObserver$CopyOnWriteArray;
+HSPLandroid/view/ViewTreeObserver;->dispatchOnPreDraw()Z+]Landroid/view/ViewTreeObserver$OnPreDrawListener;missing_types]Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;]Landroid/view/ViewTreeObserver$CopyOnWriteArray;Landroid/view/ViewTreeObserver$CopyOnWriteArray;
HSPLandroid/view/ViewTreeObserver;->dispatchOnScrollChanged()V
HSPLandroid/view/ViewTreeObserver;->dispatchOnSystemGestureExclusionRectsChanged(Ljava/util/List;)V
HSPLandroid/view/ViewTreeObserver;->dispatchOnTouchModeChanged(Z)V
@@ -18418,7 +18506,7 @@ HSPLandroid/view/Window;->makeActive()V
HSPLandroid/view/Window;->onDrawLegacyNavigationBarBackgroundChanged(Z)Z
HSPLandroid/view/Window;->removeOnFrameMetricsAvailableListener(Landroid/view/Window$OnFrameMetricsAvailableListener;)V
HSPLandroid/view/Window;->requestFeature(I)Z
-HSPLandroid/view/Window;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V
+HSPLandroid/view/Window;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V+]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/Window;Lcom/android/internal/policy/PhoneWindow;
HSPLandroid/view/Window;->setBackgroundBlurRadius(I)V
HSPLandroid/view/Window;->setCallback(Landroid/view/Window$Callback;)V
HSPLandroid/view/Window;->setCloseOnTouchOutside(Z)V
@@ -18453,6 +18541,7 @@ HSPLandroid/view/WindowInsets$Type;->statusBars()I
HSPLandroid/view/WindowInsets$Type;->systemBars()I
HSPLandroid/view/WindowInsets$Type;->systemGestures()I
HSPLandroid/view/WindowInsets$Type;->toString(I)Ljava/lang/String;
+HSPLandroid/view/WindowInsets;-><init>([Landroid/graphics/Insets;[Landroid/graphics/Insets;[ZZIILandroid/view/DisplayCutout;Landroid/view/RoundedCorners;Landroid/view/PrivacyIndicatorBounds;Landroid/view/DisplayShape;IZ[[Landroid/graphics/Rect;[[Landroid/graphics/Rect;II)V+]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;][Landroid/graphics/Insets;[Landroid/graphics/Insets;][[Landroid/graphics/Rect;[[Landroid/graphics/Rect;
HSPLandroid/view/WindowInsets;->assignCompatInsets([Landroid/graphics/Insets;Landroid/graphics/Rect;)V
HSPLandroid/view/WindowInsets;->consumeDisplayCutout()Landroid/view/WindowInsets;
HSPLandroid/view/WindowInsets;->consumeStableInsets()Landroid/view/WindowInsets;
@@ -18474,13 +18563,13 @@ HSPLandroid/view/WindowInsets;->getSystemWindowInsetBottom()I
HSPLandroid/view/WindowInsets;->getSystemWindowInsetLeft()I
HSPLandroid/view/WindowInsets;->getSystemWindowInsetRight()I
HSPLandroid/view/WindowInsets;->getSystemWindowInsetTop()I
-HSPLandroid/view/WindowInsets;->getSystemWindowInsets()Landroid/graphics/Insets;+]Landroid/view/WindowInsets;Landroid/view/WindowInsets;
+HSPLandroid/view/WindowInsets;->getSystemWindowInsets()Landroid/graphics/Insets;
HSPLandroid/view/WindowInsets;->getSystemWindowInsetsAsRect()Landroid/graphics/Rect;
HSPLandroid/view/WindowInsets;->inset(IIII)Landroid/view/WindowInsets;
HSPLandroid/view/WindowInsets;->inset(Landroid/graphics/Insets;)Landroid/view/WindowInsets;
HSPLandroid/view/WindowInsets;->insetInsets(Landroid/graphics/Insets;IIII)Landroid/graphics/Insets;
HSPLandroid/view/WindowInsets;->insetInsets([Landroid/graphics/Insets;IIII)[Landroid/graphics/Insets;
-HSPLandroid/view/WindowInsets;->insetUnchecked(IIII)Landroid/view/WindowInsets;+]Landroid/view/PrivacyIndicatorBounds;Landroid/view/PrivacyIndicatorBounds;]Landroid/view/RoundedCorners;Landroid/view/RoundedCorners;
+HSPLandroid/view/WindowInsets;->insetUnchecked(IIII)Landroid/view/WindowInsets;
HSPLandroid/view/WindowInsets;->isConsumed()Z
HSPLandroid/view/WindowInsets;->isRound()Z
HSPLandroid/view/WindowInsets;->replaceSystemWindowInsets(IIII)Landroid/view/WindowInsets;
@@ -18491,8 +18580,8 @@ HSPLandroid/view/WindowInsetsAnimation;->getTypeMask()I
HSPLandroid/view/WindowInsetsAnimation;->setAlpha(F)V
HSPLandroid/view/WindowLayout;-><clinit>()V
HSPLandroid/view/WindowLayout;-><init>()V
-HSPLandroid/view/WindowLayout;->computeFrames(Landroid/view/WindowManager$LayoutParams;Landroid/view/InsetsState;Landroid/graphics/Rect;Landroid/graphics/Rect;IIIIFLandroid/window/ClientWindowFrames;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;
-HSPLandroid/view/WindowLayout;->computeSurfaceSize(Landroid/view/WindowManager$LayoutParams;Landroid/graphics/Rect;IILandroid/graphics/Rect;ZLandroid/graphics/Point;)V
+HSPLandroid/view/WindowLayout;->computeFrames(Landroid/view/WindowManager$LayoutParams;Landroid/view/InsetsState;Landroid/graphics/Rect;Landroid/graphics/Rect;IIIIFLandroid/window/ClientWindowFrames;)V+]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/WindowLayout;->computeSurfaceSize(Landroid/view/WindowManager$LayoutParams;Landroid/graphics/Rect;IILandroid/graphics/Rect;ZLandroid/graphics/Point;)V+]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;
HSPLandroid/view/WindowLeaked;-><init>(Ljava/lang/String;)V
HSPLandroid/view/WindowManager$LayoutParams$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/WindowManager$LayoutParams;
HSPLandroid/view/WindowManager$LayoutParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -18527,7 +18616,7 @@ HSPLandroid/view/WindowManagerGlobal;->closeAll(Landroid/os/IBinder;Ljava/lang/S
HSPLandroid/view/WindowManagerGlobal;->closeAllExceptView(Landroid/os/IBinder;Landroid/view/View;Ljava/lang/String;Ljava/lang/String;)V
HSPLandroid/view/WindowManagerGlobal;->doRemoveView(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/WindowManagerGlobal;->dumpGfxInfo(Ljava/io/FileDescriptor;[Ljava/lang/String;)V
-HSPLandroid/view/WindowManagerGlobal;->findViewLocked(Landroid/view/View;Z)I
+HSPLandroid/view/WindowManagerGlobal;->findViewLocked(Landroid/view/View;Z)I+]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/WindowManagerGlobal;->getInstance()Landroid/view/WindowManagerGlobal;
HSPLandroid/view/WindowManagerGlobal;->getRootViews(Landroid/os/IBinder;)Ljava/util/ArrayList;
HSPLandroid/view/WindowManagerGlobal;->getWindowManagerService()Landroid/view/IWindowManager;
@@ -18537,9 +18626,9 @@ HSPLandroid/view/WindowManagerGlobal;->initialize()V
HSPLandroid/view/WindowManagerGlobal;->peekWindowSession()Landroid/view/IWindowSession;
HSPLandroid/view/WindowManagerGlobal;->removeView(Landroid/view/View;Z)V
HSPLandroid/view/WindowManagerGlobal;->removeViewLocked(IZ)V
-HSPLandroid/view/WindowManagerGlobal;->setStoppedState(Landroid/os/IBinder;Z)V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowManagerGlobal;Landroid/view/WindowManagerGlobal;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/WindowManagerGlobal;->setStoppedState(Landroid/os/IBinder;Z)V
HSPLandroid/view/WindowManagerGlobal;->trimMemory(I)V
-HSPLandroid/view/WindowManagerGlobal;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
+HSPLandroid/view/WindowManagerGlobal;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/view/WindowManagerImpl;-><init>(Landroid/content/Context;)V
HSPLandroid/view/WindowManagerImpl;-><init>(Landroid/content/Context;Landroid/view/Window;Landroid/os/IBinder;)V
HSPLandroid/view/WindowManagerImpl;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
@@ -18552,7 +18641,7 @@ HSPLandroid/view/WindowManagerImpl;->getDefaultDisplay()Landroid/view/Display;
HSPLandroid/view/WindowManagerImpl;->getMaximumWindowMetrics()Landroid/view/WindowMetrics;
HSPLandroid/view/WindowManagerImpl;->removeView(Landroid/view/View;)V
HSPLandroid/view/WindowManagerImpl;->removeViewImmediate(Landroid/view/View;)V
-HSPLandroid/view/WindowManagerImpl;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
+HSPLandroid/view/WindowManagerImpl;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/WindowManagerGlobal;Landroid/view/WindowManagerGlobal;
HSPLandroid/view/WindowMetrics;-><init>(Landroid/graphics/Rect;Landroid/view/WindowInsets;)V
HSPLandroid/view/WindowMetrics;-><init>(Landroid/graphics/Rect;Ljava/util/function/Supplier;F)V
HSPLandroid/view/WindowMetrics;->getBounds()Landroid/graphics/Rect;
@@ -18594,8 +18683,8 @@ HSPLandroid/view/accessibility/AccessibilityManager;->updateFocusAppearanceLocke
HSPLandroid/view/accessibility/AccessibilityManager;->updateUiTimeout(J)V
HSPLandroid/view/accessibility/AccessibilityNodeIdManager;-><init>()V
HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->getInstance()Landroid/view/accessibility/AccessibilityNodeIdManager;
-HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->registerViewWithId(Landroid/view/View;I)V+]Landroid/view/accessibility/WeakSparseArray;Landroid/view/accessibility/WeakSparseArray;
-HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->unregisterViewWithId(I)V+]Landroid/view/accessibility/WeakSparseArray;Landroid/view/accessibility/WeakSparseArray;
+HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->registerViewWithId(Landroid/view/View;I)V
+HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->unregisterViewWithId(I)V
HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;-><init>(ILjava/lang/CharSequence;)V
HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;->equals(Ljava/lang/Object;)Z
HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;->getId()I
@@ -18635,9 +18724,9 @@ HSPLandroid/view/accessibility/IAccessibilityManagerClient$Stub;->getTransaction
HSPLandroid/view/accessibility/IAccessibilityManagerClient$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
HSPLandroid/view/accessibility/WeakSparseArray$WeakReferenceWithId;-><init>(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;I)V
HSPLandroid/view/accessibility/WeakSparseArray;-><init>()V
-HSPLandroid/view/accessibility/WeakSparseArray;->append(ILjava/lang/Object;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
-HSPLandroid/view/accessibility/WeakSparseArray;->remove(I)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
-HSPLandroid/view/accessibility/WeakSparseArray;->removeUnreachableValues()V+]Ljava/lang/ref/ReferenceQueue;Ljava/lang/ref/ReferenceQueue;
+HSPLandroid/view/accessibility/WeakSparseArray;->append(ILjava/lang/Object;)V
+HSPLandroid/view/accessibility/WeakSparseArray;->remove(I)V
+HSPLandroid/view/accessibility/WeakSparseArray;->removeUnreachableValues()V
HSPLandroid/view/animation/AccelerateDecelerateInterpolator;-><init>()V
HSPLandroid/view/animation/AccelerateDecelerateInterpolator;->createNativeInterpolator()J
HSPLandroid/view/animation/AccelerateDecelerateInterpolator;->getInterpolation(F)F
@@ -18647,7 +18736,7 @@ HSPLandroid/view/animation/AccelerateInterpolator;-><init>(Landroid/content/res/
HSPLandroid/view/animation/AccelerateInterpolator;->getInterpolation(F)F
HSPLandroid/view/animation/AlphaAnimation;-><init>(FF)V
HSPLandroid/view/animation/AlphaAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-HSPLandroid/view/animation/AlphaAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V+]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/AlphaAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V
HSPLandroid/view/animation/AlphaAnimation;->hasAlpha()Z
HSPLandroid/view/animation/AlphaAnimation;->willChangeBounds()Z
HSPLandroid/view/animation/AlphaAnimation;->willChangeTransformationMatrix()Z
@@ -18656,7 +18745,7 @@ HSPLandroid/view/animation/Animation$3;->run()V
HSPLandroid/view/animation/Animation$Description;-><init>()V
HSPLandroid/view/animation/Animation$Description;->parseValue(Landroid/util/TypedValue;Landroid/content/Context;)Landroid/view/animation/Animation$Description;
HSPLandroid/view/animation/Animation;-><init>()V
-HSPLandroid/view/animation/Animation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
+HSPLandroid/view/animation/Animation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/view/animation/Animation;->cancel()V
HSPLandroid/view/animation/Animation;->detach()V
HSPLandroid/view/animation/Animation;->dispatchAnimationEnd()V
@@ -18665,12 +18754,12 @@ HSPLandroid/view/animation/Animation;->ensureInterpolator()V
HSPLandroid/view/animation/Animation;->finalize()V
HSPLandroid/view/animation/Animation;->getDuration()J
HSPLandroid/view/animation/Animation;->getFillAfter()Z
-HSPLandroid/view/animation/Animation;->getInvalidateRegion(IIIILandroid/graphics/RectF;Landroid/view/animation/Transformation;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/Animation;->getInvalidateRegion(IIIILandroid/graphics/RectF;Landroid/view/animation/Transformation;)V
HSPLandroid/view/animation/Animation;->getScaleFactor()F
HSPLandroid/view/animation/Animation;->getStartOffset()J
-HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;)Z+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
-HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;F)Z+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
-HSPLandroid/view/animation/Animation;->getTransformationAt(FLandroid/view/animation/Transformation;)V+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;]Landroid/view/animation/Interpolator;Landroid/view/animation/AccelerateDecelerateInterpolator;,Landroid/view/animation/LinearInterpolator;
+HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;)Z
+HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;F)Z
+HSPLandroid/view/animation/Animation;->getTransformationAt(FLandroid/view/animation/Transformation;)V
HSPLandroid/view/animation/Animation;->hasAlpha()Z
HSPLandroid/view/animation/Animation;->hasEnded()Z
HSPLandroid/view/animation/Animation;->hasStarted()Z
@@ -18727,7 +18816,7 @@ HSPLandroid/view/animation/AnimationUtils$AnimationState;-><init>()V
HSPLandroid/view/animation/AnimationUtils$AnimationState;-><init>(Landroid/view/animation/AnimationUtils$AnimationState-IA;)V
HSPLandroid/view/animation/AnimationUtils;->createAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Animation;
HSPLandroid/view/animation/AnimationUtils;->createAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;Landroid/view/animation/AnimationSet;Landroid/util/AttributeSet;)Landroid/view/animation/Animation;
-HSPLandroid/view/animation/AnimationUtils;->createInterpolatorFromXml(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Interpolator;+]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/animation/AnimationUtils;->createInterpolatorFromXml(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Interpolator;
HSPLandroid/view/animation/AnimationUtils;->currentAnimationTimeMillis()J
HSPLandroid/view/animation/AnimationUtils;->loadAnimation(Landroid/content/Context;I)Landroid/view/animation/Animation;
HSPLandroid/view/animation/AnimationUtils;->loadInterpolator(Landroid/content/Context;I)Landroid/view/animation/Interpolator;
@@ -18753,7 +18842,7 @@ HSPLandroid/view/animation/PathInterpolator;-><init>(Landroid/content/res/Resour
HSPLandroid/view/animation/PathInterpolator;->createNativeInterpolator()J
HSPLandroid/view/animation/PathInterpolator;->getInterpolation(F)F
HSPLandroid/view/animation/PathInterpolator;->initCubic(FFFF)V
-HSPLandroid/view/animation/PathInterpolator;->initPath(Landroid/graphics/Path;)V
+HSPLandroid/view/animation/PathInterpolator;->initPath(Landroid/graphics/Path;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
HSPLandroid/view/animation/PathInterpolator;->parseInterpolatorFromTypeArray(Landroid/content/res/TypedArray;)V
HSPLandroid/view/animation/ScaleAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/view/animation/ScaleAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V
@@ -18761,13 +18850,13 @@ HSPLandroid/view/animation/ScaleAnimation;->initialize(IIII)V
HSPLandroid/view/animation/ScaleAnimation;->initializePivotPoint()V
HSPLandroid/view/animation/ScaleAnimation;->resolveScale(FIIII)F
HSPLandroid/view/animation/Transformation;-><init>()V
-HSPLandroid/view/animation/Transformation;->clear()V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/animation/Transformation;->clear()V
HSPLandroid/view/animation/Transformation;->compose(Landroid/view/animation/Transformation;)V
HSPLandroid/view/animation/Transformation;->getAlpha()F
HSPLandroid/view/animation/Transformation;->getInsets()Landroid/graphics/Insets;
HSPLandroid/view/animation/Transformation;->getMatrix()Landroid/graphics/Matrix;
HSPLandroid/view/animation/Transformation;->getTransformationType()I
-HSPLandroid/view/animation/Transformation;->set(Landroid/view/animation/Transformation;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/Transformation;->set(Landroid/view/animation/Transformation;)V
HSPLandroid/view/animation/Transformation;->setAlpha(F)V
HSPLandroid/view/animation/Transformation;->setInsets(Landroid/graphics/Insets;)V
HSPLandroid/view/animation/TranslateAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
@@ -18840,7 +18929,7 @@ HSPLandroid/view/autofill/AutofillManager;->hasFillDialogUiFeature()Z
HSPLandroid/view/autofill/AutofillManager;->isActiveLocked()Z
HSPLandroid/view/autofill/AutofillManager;->isDisabledByServiceLocked()Z
HSPLandroid/view/autofill/AutofillManager;->isEnabled()Z
-HSPLandroid/view/autofill/AutofillManager;->notifyValueChanged(Landroid/view/View;)V+]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/autofill/AutofillManager;->notifyValueChanged(Landroid/view/View;)V
HSPLandroid/view/autofill/AutofillManager;->notifyViewEntered(Landroid/view/View;I)V
HSPLandroid/view/autofill/AutofillManager;->notifyViewEnteredForAugmentedAutofill(Landroid/view/View;)V
HSPLandroid/view/autofill/AutofillManager;->notifyViewEnteredForFillDialog(Landroid/view/View;)V
@@ -18872,6 +18961,7 @@ HSPLandroid/view/autofill/IAugmentedAutofillManagerClient$Stub;-><init>()V
HSPLandroid/view/autofill/IAugmentedAutofillManagerClient$Stub;->asBinder()Landroid/os/IBinder;
HSPLandroid/view/autofill/IAugmentedAutofillManagerClient$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->addClient(Landroid/view/autofill/IAutoFillManagerClient;Landroid/content/ComponentName;ILcom/android/internal/os/IResultReceiver;)V
HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->cancelSession(II)V
HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->getAutofillServiceComponentName(Lcom/android/internal/os/IResultReceiver;)V
@@ -19112,7 +19202,7 @@ HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;-><init>(Landroid/v
HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onPostWindowGainedFocus(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;)V
HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onPreWindowGainedFocus(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onScheduledCheckFocus(Landroid/view/ViewRootImpl;)V
-HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onViewDetachedFromWindow(Landroid/view/View;Landroid/view/ViewRootImpl;)V+]Landroid/view/View;missing_types
+HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onViewDetachedFromWindow(Landroid/view/View;Landroid/view/ViewRootImpl;)V
HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onWindowDismissed(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->setCurrentRootViewLocked(Landroid/view/ViewRootImpl;)V
HSPLandroid/view/inputmethod/InputMethodManager$H$$ExternalSyntheticLambda0;->run()V
@@ -19439,17 +19529,17 @@ HSPLandroid/widget/AbsListView$AdapterDataSetObserver;->onChanged()V
HSPLandroid/widget/AbsListView$DeviceConfigChangeListener;-><init>()V
HSPLandroid/widget/AbsListView$DeviceConfigChangeListener;-><init>(Landroid/widget/AbsListView$DeviceConfigChangeListener-IA;)V
HSPLandroid/widget/AbsListView$PerformClick;->run()V
-HSPLandroid/widget/AbsListView$RecycleBin;->addScrapView(Landroid/view/View;I)V+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;]Landroid/widget/AbsListView;Landroid/widget/ListView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/AbsListView$RecycleBin;->addScrapView(Landroid/view/View;I)V
HSPLandroid/widget/AbsListView$RecycleBin;->clear()V
HSPLandroid/widget/AbsListView$RecycleBin;->clearTransientStateViews()V
HSPLandroid/widget/AbsListView$RecycleBin;->fillActiveViews(II)V
HSPLandroid/widget/AbsListView$RecycleBin;->getActiveView(I)Landroid/view/View;
-HSPLandroid/widget/AbsListView$RecycleBin;->getScrapView(I)Landroid/view/View;+]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView$RecycleBin;->getScrapView(I)Landroid/view/View;
HSPLandroid/widget/AbsListView$RecycleBin;->getTransientStateView(I)Landroid/view/View;
HSPLandroid/widget/AbsListView$RecycleBin;->markChildrenDirty()V
HSPLandroid/widget/AbsListView$RecycleBin;->pruneScrapViews()V
HSPLandroid/widget/AbsListView$RecycleBin;->removeSkippedScrap()V
-HSPLandroid/widget/AbsListView$RecycleBin;->retrieveFromScrap(Ljava/util/ArrayList;I)Landroid/view/View;+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/ListAdapter;Landroid/preference/PreferenceGroupAdapter;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/AbsListView$RecycleBin;->retrieveFromScrap(Ljava/util/ArrayList;I)Landroid/view/View;
HSPLandroid/widget/AbsListView$RecycleBin;->scrapActiveViews()V
HSPLandroid/widget/AbsListView$RecycleBin;->setViewTypeCount(I)V
HSPLandroid/widget/AbsListView$RecycleBin;->shouldRecycleViewType(I)Z
@@ -19459,12 +19549,12 @@ HSPLandroid/widget/AbsListView$WindowRunnnable;->sameWindow()Z
HSPLandroid/widget/AbsListView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
HSPLandroid/widget/AbsListView;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
HSPLandroid/widget/AbsListView;->clearChoices()V
-HSPLandroid/widget/AbsListView;->computeVerticalScrollExtent()I+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types
-HSPLandroid/widget/AbsListView;->computeVerticalScrollOffset()I+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types
+HSPLandroid/widget/AbsListView;->computeVerticalScrollExtent()I
+HSPLandroid/widget/AbsListView;->computeVerticalScrollOffset()I
HSPLandroid/widget/AbsListView;->computeVerticalScrollRange()I
HSPLandroid/widget/AbsListView;->dispatchDraw(Landroid/graphics/Canvas;)V
HSPLandroid/widget/AbsListView;->dispatchSetPressed(Z)V
-HSPLandroid/widget/AbsListView;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/widget/AbsListView;missing_types]Landroid/widget/EdgeEffect;Landroid/widget/EdgeEffect;
+HSPLandroid/widget/AbsListView;->draw(Landroid/graphics/Canvas;)V
HSPLandroid/widget/AbsListView;->drawableStateChanged()V
HSPLandroid/widget/AbsListView;->generateDefaultLayoutParams()Landroid/view/ViewGroup$LayoutParams;
HSPLandroid/widget/AbsListView;->generateLayoutParams(Landroid/util/AttributeSet;)Landroid/view/ViewGroup$LayoutParams;
@@ -19482,7 +19572,7 @@ HSPLandroid/widget/AbsListView;->isFastScrollEnabled()Z
HSPLandroid/widget/AbsListView;->isInFilterMode()Z
HSPLandroid/widget/AbsListView;->isVerticalScrollBarHidden()Z
HSPLandroid/widget/AbsListView;->jumpDrawablesToCurrentState()V
-HSPLandroid/widget/AbsListView;->obtainView(I[Z)Landroid/view/View;+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView;->obtainView(I[Z)Landroid/view/View;
HSPLandroid/widget/AbsListView;->onAttachedToWindow()V
HSPLandroid/widget/AbsListView;->onCancelPendingInputEvents()V
HSPLandroid/widget/AbsListView;->onDetachedFromWindow()V
@@ -19492,9 +19582,9 @@ HSPLandroid/widget/AbsListView;->onMeasure(II)V
HSPLandroid/widget/AbsListView;->onRtlPropertiesChanged(I)V
HSPLandroid/widget/AbsListView;->onSaveInstanceState()Landroid/os/Parcelable;
HSPLandroid/widget/AbsListView;->onTouchDown(Landroid/view/MotionEvent;)V
-HSPLandroid/widget/AbsListView;->onTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/VelocityTracker;Landroid/view/VelocityTracker;]Landroid/widget/AbsListView;Landroid/widget/ListView;
+HSPLandroid/widget/AbsListView;->onTouchEvent(Landroid/view/MotionEvent;)Z
HSPLandroid/widget/AbsListView;->onTouchModeChanged(Z)V
-HSPLandroid/widget/AbsListView;->onTouchMove(Landroid/view/MotionEvent;Landroid/view/MotionEvent;)V+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;Landroid/widget/ListView;
+HSPLandroid/widget/AbsListView;->onTouchMove(Landroid/view/MotionEvent;Landroid/view/MotionEvent;)V
HSPLandroid/widget/AbsListView;->onTouchUp(Landroid/view/MotionEvent;)V
HSPLandroid/widget/AbsListView;->onWindowFocusChanged(Z)V
HSPLandroid/widget/AbsListView;->performItemClick(Landroid/view/View;IJ)Z
@@ -19509,7 +19599,7 @@ HSPLandroid/widget/AbsListView;->setFastScrollAlwaysVisible(Z)V
HSPLandroid/widget/AbsListView;->setFastScrollEnabled(Z)V
HSPLandroid/widget/AbsListView;->setFastScrollStyle(I)V
HSPLandroid/widget/AbsListView;->setFrame(IIII)Z
-HSPLandroid/widget/AbsListView;->setItemViewLayoutParams(Landroid/view/View;I)V+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView;->setItemViewLayoutParams(Landroid/view/View;I)V
HSPLandroid/widget/AbsListView;->setOnScrollListener(Landroid/widget/AbsListView$OnScrollListener;)V
HSPLandroid/widget/AbsListView;->setScrollingCacheEnabled(Z)V
HSPLandroid/widget/AbsListView;->setSelectionFromTop(II)V
@@ -19649,7 +19739,7 @@ HSPLandroid/widget/EdgeEffect;->isAtEquilibrium()Z
HSPLandroid/widget/EdgeEffect;->isFinished()Z
HSPLandroid/widget/EdgeEffect;->onAbsorb(I)V
HSPLandroid/widget/EdgeEffect;->onPull(FF)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/widget/EdgeEffect;->onPullDistance(FF)F+]Landroid/widget/EdgeEffect;Landroid/widget/EdgeEffect;
+HSPLandroid/widget/EdgeEffect;->onPullDistance(FF)F
HSPLandroid/widget/EdgeEffect;->onRelease()V
HSPLandroid/widget/EdgeEffect;->setSize(II)V
HSPLandroid/widget/EdgeEffect;->update()V
@@ -19674,7 +19764,7 @@ HSPLandroid/widget/Editor$AccessibilitySmartActions;-><init>(Landroid/widget/Tex
HSPLandroid/widget/Editor$Blink;->cancel()V
HSPLandroid/widget/Editor$Blink;->run()V
HSPLandroid/widget/Editor$Blink;->uncancel()V
-HSPLandroid/widget/Editor$CursorAnchorInfoNotifier;->updatePosition(IIZZ)V
+HSPLandroid/widget/Editor$CursorAnchorInfoNotifier;->updatePosition(IIZZ)V+]Landroid/view/inputmethod/InputMethodManager;Landroid/view/inputmethod/InputMethodManager;
HSPLandroid/widget/Editor$EditOperation;-><init>(Landroid/widget/Editor;Ljava/lang/String;ILjava/lang/String;Z)V
HSPLandroid/widget/Editor$EditOperation;->commit()V
HSPLandroid/widget/Editor$EditOperation;->forceMergeWith(Landroid/widget/Editor$EditOperation;)V
@@ -19718,10 +19808,10 @@ HSPLandroid/widget/Editor$InsertionPointCursorController;->onDetached()V
HSPLandroid/widget/Editor$InsertionPointCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V
HSPLandroid/widget/Editor$InsertionPointCursorController;->show()V
HSPLandroid/widget/Editor$PositionListener;->addSubscriber(Landroid/widget/Editor$TextViewPositionListener;Z)V
-HSPLandroid/widget/Editor$PositionListener;->onPreDraw()Z
+HSPLandroid/widget/Editor$PositionListener;->onPreDraw()Z+]Landroid/widget/Editor$TextViewPositionListener;Landroid/widget/Editor$CursorAnchorInfoNotifier;,Landroid/widget/Editor$InsertionHandleView;
HSPLandroid/widget/Editor$PositionListener;->onScrollChanged()V
HSPLandroid/widget/Editor$PositionListener;->removeSubscriber(Landroid/widget/Editor$TextViewPositionListener;)V
-HSPLandroid/widget/Editor$PositionListener;->updatePosition()V
+HSPLandroid/widget/Editor$PositionListener;->updatePosition()V+]Landroid/widget/TextView;Landroid/widget/EditText;
HSPLandroid/widget/Editor$ProcessTextIntentActionsHandler;-><init>(Landroid/widget/Editor;)V
HSPLandroid/widget/Editor$SelectionModifierCursorController;->getMinTouchOffset()I
HSPLandroid/widget/Editor$SelectionModifierCursorController;->hide()V
@@ -19730,7 +19820,7 @@ HSPLandroid/widget/Editor$SelectionModifierCursorController;->isCursorBeingModif
HSPLandroid/widget/Editor$SelectionModifierCursorController;->isDragAcceleratorActive()Z
HSPLandroid/widget/Editor$SelectionModifierCursorController;->isSelectionStartDragged()Z
HSPLandroid/widget/Editor$SelectionModifierCursorController;->onDetached()V
-HSPLandroid/widget/Editor$SelectionModifierCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V
+HSPLandroid/widget/Editor$SelectionModifierCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V+]Landroid/widget/EditorTouchState;Landroid/widget/EditorTouchState;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/widget/Editor$SelectionModifierCursorController;Landroid/widget/Editor$SelectionModifierCursorController;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/widget/Editor$SelectionModifierCursorController;->resetDragAcceleratorState()V
HSPLandroid/widget/Editor$SelectionModifierCursorController;->resetTouchOffsets()V
HSPLandroid/widget/Editor$SelectionModifierCursorController;->updateSelection(Landroid/view/MotionEvent;)V
@@ -19738,7 +19828,7 @@ HSPLandroid/widget/Editor$SpanController;->hide()V
HSPLandroid/widget/Editor$SpanController;->onSpanAdded(Landroid/text/Spannable;Ljava/lang/Object;II)V
HSPLandroid/widget/Editor$SpanController;->onSpanChanged(Landroid/text/Spannable;Ljava/lang/Object;IIII)V
HSPLandroid/widget/Editor$SpanController;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
-HSPLandroid/widget/Editor$TextRenderNode;->needsRecord()Z
+HSPLandroid/widget/Editor$TextRenderNode;->needsRecord()Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
HSPLandroid/widget/Editor$UndoInputFilter;->beginBatchEdit()V
HSPLandroid/widget/Editor$UndoInputFilter;->canUndoEdit(Ljava/lang/CharSequence;IILandroid/text/Spanned;II)Z
HSPLandroid/widget/Editor$UndoInputFilter;->endBatchEdit()V
@@ -19759,7 +19849,7 @@ HSPLandroid/widget/Editor;->createInputContentTypeIfNeeded()V
HSPLandroid/widget/Editor;->createInputMethodStateIfNeeded()V
HSPLandroid/widget/Editor;->discardTextDisplayLists()V
HSPLandroid/widget/Editor;->downgradeEasyCorrectionSpans()V
-HSPLandroid/widget/Editor;->drawHardwareAcceleratedInner(Landroid/graphics/Canvas;Landroid/text/Layout;Landroid/graphics/Path;Landroid/graphics/Paint;I[I[IIII)I
+HSPLandroid/widget/Editor;->drawHardwareAcceleratedInner(Landroid/graphics/Canvas;Landroid/text/Layout;Landroid/graphics/Path;Landroid/graphics/Paint;I[I[IIII)I+]Landroid/widget/Editor$TextRenderNode;Landroid/widget/Editor$TextRenderNode;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
HSPLandroid/widget/Editor;->endBatchEdit()V
HSPLandroid/widget/Editor;->ensureEndedBatchEdit()V
HSPLandroid/widget/Editor;->ensureNoSelectionIfNonSelectable()V
@@ -19795,10 +19885,10 @@ HSPLandroid/widget/Editor;->onFocusChanged(ZI)V
HSPLandroid/widget/Editor;->onLocaleChanged()V
HSPLandroid/widget/Editor;->onScreenStateChanged(I)V
HSPLandroid/widget/Editor;->onScrollChanged()V
-HSPLandroid/widget/Editor;->onTouchEvent(Landroid/view/MotionEvent;)V
+HSPLandroid/widget/Editor;->onTouchEvent(Landroid/view/MotionEvent;)V+]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/EditorTouchState;Landroid/widget/EditorTouchState;]Landroid/widget/Editor$SelectionModifierCursorController;Landroid/widget/Editor$SelectionModifierCursorController;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/widget/Editor;->onTouchUpEvent(Landroid/view/MotionEvent;)V
HSPLandroid/widget/Editor;->onWindowFocusChanged(Z)V
-HSPLandroid/widget/Editor;->prepareCursorControllers()V
+HSPLandroid/widget/Editor;->prepareCursorControllers()V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/widget/Editor;Landroid/widget/Editor;
HSPLandroid/widget/Editor;->refreshTextActionMode()V
HSPLandroid/widget/Editor;->reportExtractedText()Z
HSPLandroid/widget/Editor;->restoreInstanceState(Landroid/os/ParcelableParcel;)V
@@ -19823,19 +19913,19 @@ HSPLandroid/widget/EditorTouchState;->getLastDownY()F
HSPLandroid/widget/EditorTouchState;->isMovedEnoughForDrag()Z
HSPLandroid/widget/EditorTouchState;->isMultiTap()Z
HSPLandroid/widget/EditorTouchState;->isMultiTapInSameArea()Z
-HSPLandroid/widget/EditorTouchState;->update(Landroid/view/MotionEvent;Landroid/view/ViewConfiguration;)V
+HSPLandroid/widget/EditorTouchState;->update(Landroid/view/MotionEvent;Landroid/view/ViewConfiguration;)V+]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/widget/Filter;-><init>()V
HSPLandroid/widget/ForwardingListener;-><init>(Landroid/view/View;)V
HSPLandroid/widget/ForwardingListener;->onViewAttachedToWindow(Landroid/view/View;)V
HSPLandroid/widget/ForwardingListener;->onViewDetachedFromWindow(Landroid/view/View;)V
HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(II)V
HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(III)V
-HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;)V
HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/FrameLayout;missing_types
+HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
HSPLandroid/widget/FrameLayout;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
HSPLandroid/widget/FrameLayout;->generateDefaultLayoutParams()Landroid/view/ViewGroup$LayoutParams;
HSPLandroid/widget/FrameLayout;->generateDefaultLayoutParams()Landroid/widget/FrameLayout$LayoutParams;
@@ -19849,7 +19939,7 @@ HSPLandroid/widget/FrameLayout;->getPaddingRightWithForeground()I+]Landroid/widg
HSPLandroid/widget/FrameLayout;->getPaddingTopWithForeground()I+]Landroid/widget/FrameLayout;missing_types
HSPLandroid/widget/FrameLayout;->layoutChildren(IIIIZ)V+]Landroid/view/View;missing_types]Landroid/widget/FrameLayout;missing_types
HSPLandroid/widget/FrameLayout;->onLayout(ZIIII)V+]Landroid/widget/FrameLayout;missing_types
-HSPLandroid/widget/FrameLayout;->onMeasure(II)V+]Landroid/view/View;missing_types]Landroid/widget/FrameLayout;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/FrameLayout;->onMeasure(II)V+]Landroid/widget/FrameLayout;missing_types]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
HSPLandroid/widget/FrameLayout;->setForegroundGravity(I)V
HSPLandroid/widget/FrameLayout;->setMeasureAllChildren(Z)V
HSPLandroid/widget/FrameLayout;->shouldDelayChildPressedState()Z
@@ -19946,13 +20036,13 @@ HSPLandroid/widget/ImageView$ScaleType;->values()[Landroid/widget/ImageView$Scal
HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;)V
HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/widget/ImageView;->applyAlpha()V
HSPLandroid/widget/ImageView;->applyColorFilter()V
-HSPLandroid/widget/ImageView;->applyImageTint()V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/widget/ImageView;->applyImageTint()V
HSPLandroid/widget/ImageView;->applyXfermode()V
HSPLandroid/widget/ImageView;->clearColorFilter()V
-HSPLandroid/widget/ImageView;->configureBounds()V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->configureBounds()V
HSPLandroid/widget/ImageView;->drawableHotspotChanged(FF)V
HSPLandroid/widget/ImageView;->drawableStateChanged()V
HSPLandroid/widget/ImageView;->getAccessibilityClassName()Ljava/lang/CharSequence;
@@ -19961,21 +20051,21 @@ HSPLandroid/widget/ImageView;->getDrawable()Landroid/graphics/drawable/Drawable;
HSPLandroid/widget/ImageView;->getImageMatrix()Landroid/graphics/Matrix;
HSPLandroid/widget/ImageView;->getScaleType()Landroid/widget/ImageView$ScaleType;
HSPLandroid/widget/ImageView;->hasOverlappingRendering()Z
-HSPLandroid/widget/ImageView;->initImageView()V+]Landroid/widget/ImageView;missing_types
-HSPLandroid/widget/ImageView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->initImageView()V
+HSPLandroid/widget/ImageView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/ImageView;->isFilledByImage()Z
-HSPLandroid/widget/ImageView;->isOpaque()Z+]Landroid/graphics/drawable/Drawable;megamorphic_types
-HSPLandroid/widget/ImageView;->jumpDrawablesToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/ImageView;->isOpaque()Z
+HSPLandroid/widget/ImageView;->jumpDrawablesToCurrentState()V
HSPLandroid/widget/ImageView;->onAttachedToWindow()V
HSPLandroid/widget/ImageView;->onCreateDrawableState(I)[I
HSPLandroid/widget/ImageView;->onDetachedFromWindow()V
-HSPLandroid/widget/ImageView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/widget/ImageView;->onMeasure(II)V+]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->onDraw(Landroid/graphics/Canvas;)V
+HSPLandroid/widget/ImageView;->onMeasure(II)V
HSPLandroid/widget/ImageView;->onRtlPropertiesChanged(I)V
-HSPLandroid/widget/ImageView;->onVisibilityAggregated(Z)V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/ImageView;->onVisibilityAggregated(Z)V
HSPLandroid/widget/ImageView;->resizeFromDrawable()V
HSPLandroid/widget/ImageView;->resolveAdjustedSize(III)I
-HSPLandroid/widget/ImageView;->resolveUri()V+]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->resolveUri()V
HSPLandroid/widget/ImageView;->scaleTypeToScaleToFit(Landroid/widget/ImageView$ScaleType;)Landroid/graphics/Matrix$ScaleToFit;
HSPLandroid/widget/ImageView;->setAdjustViewBounds(Z)V
HSPLandroid/widget/ImageView;->setAlpha(I)V
@@ -19986,9 +20076,9 @@ HSPLandroid/widget/ImageView;->setCropToPadding(Z)V
HSPLandroid/widget/ImageView;->setFrame(IIII)Z
HSPLandroid/widget/ImageView;->setImageAlpha(I)V
HSPLandroid/widget/ImageView;->setImageBitmap(Landroid/graphics/Bitmap;)V
-HSPLandroid/widget/ImageView;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ImageView;missing_types
-HSPLandroid/widget/ImageView;->setImageMatrix(Landroid/graphics/Matrix;)V
-HSPLandroid/widget/ImageView;->setImageResource(I)V+]Landroid/widget/ImageView;Landroid/widget/ImageView;
+HSPLandroid/widget/ImageView;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ImageView;->setImageMatrix(Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/widget/ImageView;->setImageResource(I)V
HSPLandroid/widget/ImageView;->setImageTintBlendMode(Landroid/graphics/BlendMode;)V
HSPLandroid/widget/ImageView;->setImageTintList(Landroid/content/res/ColorStateList;)V
HSPLandroid/widget/ImageView;->setMaxHeight(I)V
@@ -19996,16 +20086,16 @@ HSPLandroid/widget/ImageView;->setMaxWidth(I)V
HSPLandroid/widget/ImageView;->setScaleType(Landroid/widget/ImageView$ScaleType;)V
HSPLandroid/widget/ImageView;->setSelected(Z)V
HSPLandroid/widget/ImageView;->setVisibility(I)V
-HSPLandroid/widget/ImageView;->updateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->updateDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/ImageView;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(II)V
HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(IIF)V
-HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;)V
HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/LinearLayout;missing_types
+HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
HSPLandroid/widget/LinearLayout;->allViewsAreGoneBefore(I)Z
HSPLandroid/widget/LinearLayout;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
HSPLandroid/widget/LinearLayout;->forceUniformHeight(II)V
@@ -20027,8 +20117,8 @@ HSPLandroid/widget/LinearLayout;->getOrientation()I
HSPLandroid/widget/LinearLayout;->getVirtualChildAt(I)Landroid/view/View;+]Landroid/widget/LinearLayout;missing_types
HSPLandroid/widget/LinearLayout;->getVirtualChildCount()I+]Landroid/widget/LinearLayout;missing_types
HSPLandroid/widget/LinearLayout;->hasDividerBeforeChildAt(I)Z
-HSPLandroid/widget/LinearLayout;->layoutHorizontal(IIII)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
-HSPLandroid/widget/LinearLayout;->layoutVertical(IIII)V+]Landroid/view/View;megamorphic_types]Landroid/widget/LinearLayout;missing_types
+HSPLandroid/widget/LinearLayout;->layoutHorizontal(IIII)V
+HSPLandroid/widget/LinearLayout;->layoutVertical(IIII)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;missing_types
HSPLandroid/widget/LinearLayout;->measureChildBeforeLayout(Landroid/view/View;IIIII)V+]Landroid/widget/LinearLayout;missing_types
HSPLandroid/widget/LinearLayout;->measureHorizontal(II)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
HSPLandroid/widget/LinearLayout;->measureVertical(II)V+]Landroid/view/View;megamorphic_types]Landroid/widget/LinearLayout;missing_types
@@ -20061,7 +20151,7 @@ HSPLandroid/widget/ListView;-><init>(Landroid/content/Context;Landroid/util/Attr
HSPLandroid/widget/ListView;->adjustViewsUpOrDown()V
HSPLandroid/widget/ListView;->clearRecycledState(Ljava/util/ArrayList;)V
HSPLandroid/widget/ListView;->correctTooHigh(I)V
-HSPLandroid/widget/ListView;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/ListAdapter;Landroid/preference/PreferenceGroupAdapter;]Landroid/widget/ListView;Landroid/widget/ListView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/ListView;->dispatchDraw(Landroid/graphics/Canvas;)V
HSPLandroid/widget/ListView;->drawChild(Landroid/graphics/Canvas;Landroid/view/View;J)Z
HSPLandroid/widget/ListView;->fillDown(II)Landroid/view/View;
HSPLandroid/widget/ListView;->fillFromTop(I)Landroid/view/View;
@@ -20077,8 +20167,8 @@ HSPLandroid/widget/ListView;->isOpaque()Z
HSPLandroid/widget/ListView;->layoutChildren()V
HSPLandroid/widget/ListView;->lookForSelectablePosition(IZ)I
HSPLandroid/widget/ListView;->makeAndAddView(IIZIZ)Landroid/view/View;
-HSPLandroid/widget/ListView;->measureHeightOfChildren(IIIII)I+]Landroid/view/View;Landroid/widget/CheckedTextView;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;
-HSPLandroid/widget/ListView;->measureScrapChild(Landroid/view/View;III)V+]Landroid/view/View;Landroid/widget/CheckedTextView;
+HSPLandroid/widget/ListView;->measureHeightOfChildren(IIIII)I
+HSPLandroid/widget/ListView;->measureScrapChild(Landroid/view/View;III)V
HSPLandroid/widget/ListView;->onDetachedFromWindow()V
HSPLandroid/widget/ListView;->onFinishInflate()V
HSPLandroid/widget/ListView;->onMeasure(II)V
@@ -20090,8 +20180,8 @@ HSPLandroid/widget/ListView;->setAdapter(Landroid/widget/ListAdapter;)V
HSPLandroid/widget/ListView;->setCacheColorHint(I)V
HSPLandroid/widget/ListView;->setDivider(Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/ListView;->setSelection(I)V
-HSPLandroid/widget/ListView;->setupChild(Landroid/view/View;IIZIZZ)V+]Landroid/util/SparseBooleanArray;Landroid/util/SparseBooleanArray;]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/Checkable;Landroid/widget/CheckedTextView;]Landroid/widget/ListAdapter;missing_types]Landroid/widget/ListView;missing_types
-HSPLandroid/widget/OverScroller$SplineOverScroller;-><init>(Landroid/content/Context;)V
+HSPLandroid/widget/ListView;->setupChild(Landroid/view/View;IIZIZZ)V
+HSPLandroid/widget/OverScroller$SplineOverScroller;-><init>(Landroid/content/Context;)V+]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLandroid/widget/OverScroller$SplineOverScroller;->adjustDuration(III)V
HSPLandroid/widget/OverScroller$SplineOverScroller;->continueWhenFinished()Z
HSPLandroid/widget/OverScroller$SplineOverScroller;->finish()V
@@ -20103,13 +20193,14 @@ HSPLandroid/widget/OverScroller$SplineOverScroller;->springback(III)Z
HSPLandroid/widget/OverScroller$SplineOverScroller;->startScroll(III)V
HSPLandroid/widget/OverScroller$SplineOverScroller;->startSpringback(III)V
HSPLandroid/widget/OverScroller$SplineOverScroller;->update()Z
+HSPLandroid/widget/OverScroller$SplineOverScroller;->updateScroll(F)V
HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;)V
HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;Landroid/view/animation/Interpolator;)V
HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;Landroid/view/animation/Interpolator;Z)V
HSPLandroid/widget/OverScroller;->abortAnimation()V
HSPLandroid/widget/OverScroller;->computeScrollOffset()Z
HSPLandroid/widget/OverScroller;->fling(IIIIIIII)V
-HSPLandroid/widget/OverScroller;->fling(IIIIIIIIII)V
+HSPLandroid/widget/OverScroller;->fling(IIIIIIIIII)V+]Landroid/widget/OverScroller;Landroid/widget/OverScroller;]Landroid/widget/OverScroller$SplineOverScroller;Landroid/widget/OverScroller$SplineOverScroller;
HSPLandroid/widget/OverScroller;->forceFinished(Z)V
HSPLandroid/widget/OverScroller;->getCurrVelocity()F
HSPLandroid/widget/OverScroller;->getCurrX()I
@@ -20197,7 +20288,7 @@ HSPLandroid/widget/ProgressBar;->getMin()I
HSPLandroid/widget/ProgressBar;->getProgress()I
HSPLandroid/widget/ProgressBar;->getProgressDrawable()Landroid/graphics/drawable/Drawable;
HSPLandroid/widget/ProgressBar;->initProgressBar()V
-HSPLandroid/widget/ProgressBar;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ProgressBar;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
HSPLandroid/widget/ProgressBar;->isIndeterminate()Z
HSPLandroid/widget/ProgressBar;->jumpDrawablesToCurrentState()V
HSPLandroid/widget/ProgressBar;->needsTileify(Landroid/graphics/drawable/Drawable;)Z
@@ -20237,8 +20328,8 @@ HSPLandroid/widget/RelativeLayout$DependencyGraph$Node;->release()V
HSPLandroid/widget/RelativeLayout$DependencyGraph;-><init>()V
HSPLandroid/widget/RelativeLayout$DependencyGraph;->add(Landroid/view/View;)V
HSPLandroid/widget/RelativeLayout$DependencyGraph;->clear()V
-HSPLandroid/widget/RelativeLayout$DependencyGraph;->findRoots([I)Ljava/util/ArrayDeque;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/widget/RelativeLayout$DependencyGraph;->getSortedViews([Landroid/view/View;[I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;
+HSPLandroid/widget/RelativeLayout$DependencyGraph;->findRoots([I)Ljava/util/ArrayDeque;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/RelativeLayout$DependencyGraph;->getSortedViews([Landroid/view/View;[I)V
HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmBottom(Landroid/widget/RelativeLayout$LayoutParams;)I
HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmLeft(Landroid/widget/RelativeLayout$LayoutParams;)I
HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmRight(Landroid/widget/RelativeLayout$LayoutParams;)I
@@ -20246,7 +20337,7 @@ HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmTop(Landroid/widge
HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fputmBottom(Landroid/widget/RelativeLayout$LayoutParams;I)V
HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fputmTop(Landroid/widget/RelativeLayout$LayoutParams;I)V
HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(II)V
-HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
HSPLandroid/widget/RelativeLayout$LayoutParams;->addRule(I)V
HSPLandroid/widget/RelativeLayout$LayoutParams;->addRule(II)V
HSPLandroid/widget/RelativeLayout$LayoutParams;->getRules()[I
@@ -20273,21 +20364,21 @@ HSPLandroid/widget/RelativeLayout;->generateLayoutParams(Landroid/view/ViewGroup
HSPLandroid/widget/RelativeLayout;->getAccessibilityClassName()Ljava/lang/CharSequence;
HSPLandroid/widget/RelativeLayout;->getBaseline()I
HSPLandroid/widget/RelativeLayout;->getChildMeasureSpec(IIIIIIII)I
-HSPLandroid/widget/RelativeLayout;->getRelatedView([II)Landroid/view/View;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;
+HSPLandroid/widget/RelativeLayout;->getRelatedView([II)Landroid/view/View;
HSPLandroid/widget/RelativeLayout;->getRelatedViewBaselineOffset([I)I
HSPLandroid/widget/RelativeLayout;->getRelatedViewParams([II)Landroid/widget/RelativeLayout$LayoutParams;
HSPLandroid/widget/RelativeLayout;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V
-HSPLandroid/widget/RelativeLayout;->measureChild(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/TextView;
-HSPLandroid/widget/RelativeLayout;->measureChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/TextView;
+HSPLandroid/widget/RelativeLayout;->measureChild(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V
+HSPLandroid/widget/RelativeLayout;->measureChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V
HSPLandroid/widget/RelativeLayout;->onLayout(ZIIII)V
-HSPLandroid/widget/RelativeLayout;->onMeasure(II)V+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
+HSPLandroid/widget/RelativeLayout;->onMeasure(II)V+]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;
HSPLandroid/widget/RelativeLayout;->positionAtEdge(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;I)V
-HSPLandroid/widget/RelativeLayout;->positionChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
-HSPLandroid/widget/RelativeLayout;->positionChildVertical(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;
+HSPLandroid/widget/RelativeLayout;->positionChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z
+HSPLandroid/widget/RelativeLayout;->positionChildVertical(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z
HSPLandroid/widget/RelativeLayout;->queryCompatibilityModes(Landroid/content/Context;)V
HSPLandroid/widget/RelativeLayout;->requestLayout()V
HSPLandroid/widget/RelativeLayout;->shouldDelayChildPressedState()Z
-HSPLandroid/widget/RelativeLayout;->sortChildren()V+]Landroid/widget/RelativeLayout$DependencyGraph;Landroid/widget/RelativeLayout$DependencyGraph;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
+HSPLandroid/widget/RelativeLayout;->sortChildren()V+]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;]Landroid/widget/RelativeLayout$DependencyGraph;Landroid/widget/RelativeLayout$DependencyGraph;
HSPLandroid/widget/RemoteViews$2;->createFromParcel(Landroid/os/Parcel;)Landroid/widget/RemoteViews;
HSPLandroid/widget/RemoteViews$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLandroid/widget/RemoteViews$Action;-><init>()V
@@ -20363,15 +20454,15 @@ HSPLandroid/widget/RtlSpacingHelper;->setAbsolute(II)V
HSPLandroid/widget/RtlSpacingHelper;->setDirection(Z)V
HSPLandroid/widget/RtlSpacingHelper;->setRelative(II)V
HSPLandroid/widget/ScrollBarDrawable;-><init>()V
-HSPLandroid/widget/ScrollBarDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
-HSPLandroid/widget/ScrollBarDrawable;->drawThumb(Landroid/graphics/Canvas;Landroid/graphics/Rect;IIZ)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
-HSPLandroid/widget/ScrollBarDrawable;->getSize(Z)I
-HSPLandroid/widget/ScrollBarDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
-HSPLandroid/widget/ScrollBarDrawable;->isStateful()Z
-HSPLandroid/widget/ScrollBarDrawable;->mutate()Landroid/widget/ScrollBarDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/widget/ScrollBarDrawable;->drawThumb(Landroid/graphics/Canvas;Landroid/graphics/Rect;IIZ)V
+HSPLandroid/widget/ScrollBarDrawable;->getSize(Z)I+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->isStateful()Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->mutate()Landroid/widget/ScrollBarDrawable;+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
HSPLandroid/widget/ScrollBarDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
HSPLandroid/widget/ScrollBarDrawable;->onStateChange([I)Z
-HSPLandroid/widget/ScrollBarDrawable;->propagateCurrentState(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ScrollBarDrawable;->propagateCurrentState(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
HSPLandroid/widget/ScrollBarDrawable;->setAlpha(I)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
HSPLandroid/widget/ScrollBarDrawable;->setAlwaysDrawVerticalTrack(Z)V
HSPLandroid/widget/ScrollBarDrawable;->setHorizontalThumbDrawable(Landroid/graphics/drawable/Drawable;)V
@@ -20486,34 +20577,34 @@ HSPLandroid/widget/TextView$TextAppearanceAttributes;-><init>(Landroid/widget/Te
HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;)V
HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/Context;missing_types]Landroid/widget/TextView;missing_types
HSPLandroid/widget/TextView;->addSearchHighlightPaths()V
HSPLandroid/widget/TextView;->addTextChangedListener(Landroid/text/TextWatcher;)V
HSPLandroid/widget/TextView;->applyCompoundDrawableTint()V
HSPLandroid/widget/TextView;->applySingleLine(ZZZZ)V
-HSPLandroid/widget/TextView;->applyTextAppearance(Landroid/widget/TextView$TextAppearanceAttributes;)V+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->applyTextAppearance(Landroid/widget/TextView$TextAppearanceAttributes;)V
HSPLandroid/widget/TextView;->assumeLayout()V
HSPLandroid/widget/TextView;->autoSizeText()V
HSPLandroid/widget/TextView;->beginBatchEdit()V
HSPLandroid/widget/TextView;->bringPointIntoView(I)Z
HSPLandroid/widget/TextView;->bringPointIntoView(IZ)Z
-HSPLandroid/widget/TextView;->bringTextIntoView()Z+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->bringTextIntoView()Z
HSPLandroid/widget/TextView;->canMarquee()Z
HSPLandroid/widget/TextView;->cancelLongPress()V
-HSPLandroid/widget/TextView;->checkForRelayout()V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->checkForRelayout()V
HSPLandroid/widget/TextView;->checkForResize()V
HSPLandroid/widget/TextView;->cleanupAutoSizePresetSizes([I)[I
-HSPLandroid/widget/TextView;->compressText(F)Z+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;Landroid/widget/CheckedTextView;,Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->compressText(F)Z
HSPLandroid/widget/TextView;->computeHorizontalScrollRange()I
HSPLandroid/widget/TextView;->computeScroll()V
-HSPLandroid/widget/TextView;->computeVerticalScrollExtent()I
-HSPLandroid/widget/TextView;->computeVerticalScrollRange()I
+HSPLandroid/widget/TextView;->computeVerticalScrollExtent()I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->computeVerticalScrollRange()I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;
HSPLandroid/widget/TextView;->convertToLocalHorizontalCoordinate(F)F
HSPLandroid/widget/TextView;->createEditorIfNeeded()V
HSPLandroid/widget/TextView;->didTouchFocusSelect()Z
HSPLandroid/widget/TextView;->doKeyDown(ILandroid/view/KeyEvent;Landroid/view/KeyEvent;)I
HSPLandroid/widget/TextView;->drawableHotspotChanged(FF)V
-HSPLandroid/widget/TextView;->drawableStateChanged()V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->drawableStateChanged()V
HSPLandroid/widget/TextView;->endBatchEdit()V
HSPLandroid/widget/TextView;->findLargestTextSizeWhichFits(Landroid/graphics/RectF;)I
HSPLandroid/widget/TextView;->fixFocusableAndClickableSettings()V
@@ -20522,10 +20613,10 @@ HSPLandroid/widget/TextView;->getAutoSizeStepGranularity()I
HSPLandroid/widget/TextView;->getAutofillHints()[Ljava/lang/String;
HSPLandroid/widget/TextView;->getAutofillType()I
HSPLandroid/widget/TextView;->getAutofillValue()Landroid/view/autofill/AutofillValue;
-HSPLandroid/widget/TextView;->getBaseline()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getBaselineOffset()I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getBaseline()I
+HSPLandroid/widget/TextView;->getBaselineOffset()I
HSPLandroid/widget/TextView;->getBottomVerticalOffset(Z)I
-HSPLandroid/widget/TextView;->getBoxHeight(Landroid/text/Layout;)I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getBoxHeight(Landroid/text/Layout;)I+]Landroid/widget/TextView;Landroid/widget/EditText;,Landroid/widget/Button;
HSPLandroid/widget/TextView;->getBreakStrategy()I
HSPLandroid/widget/TextView;->getCompoundDrawablePadding()I
HSPLandroid/widget/TextView;->getCompoundDrawables()[Landroid/graphics/drawable/Drawable;
@@ -20538,12 +20629,12 @@ HSPLandroid/widget/TextView;->getCurrentTextColor()I
HSPLandroid/widget/TextView;->getDefaultEditable()Z
HSPLandroid/widget/TextView;->getDefaultMovementMethod()Landroid/text/method/MovementMethod;
HSPLandroid/widget/TextView;->getDesiredHeight()I
-HSPLandroid/widget/TextView;->getDesiredHeight(Landroid/text/Layout;Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getDesiredHeight(Landroid/text/Layout;Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;Landroid/widget/TextView;
HSPLandroid/widget/TextView;->getEditableText()Landroid/text/Editable;
HSPLandroid/widget/TextView;->getEllipsize()Landroid/text/TextUtils$TruncateAt;
HSPLandroid/widget/TextView;->getError()Ljava/lang/CharSequence;
-HSPLandroid/widget/TextView;->getExtendedPaddingBottom()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getExtendedPaddingTop()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getExtendedPaddingBottom()I+]Landroid/text/Layout;Landroid/text/StaticLayout;]Landroid/widget/TextView;Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->getExtendedPaddingTop()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/widget/TextView;Landroid/widget/TextView;,Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/Button;
HSPLandroid/widget/TextView;->getFilters()[Landroid/text/InputFilter;
HSPLandroid/widget/TextView;->getFocusedRect(Landroid/graphics/Rect;)V
HSPLandroid/widget/TextView;->getFreezesText()Z
@@ -20559,7 +20650,7 @@ HSPLandroid/widget/TextView;->getInterestingRect(Landroid/graphics/Rect;I)V
HSPLandroid/widget/TextView;->getJustificationMode()I
HSPLandroid/widget/TextView;->getKeyListener()Landroid/text/method/KeyListener;
HSPLandroid/widget/TextView;->getLayout()Landroid/text/Layout;
-HSPLandroid/widget/TextView;->getLayoutAlignment()Landroid/text/Layout$Alignment;+]Landroid/widget/TextView;Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->getLayoutAlignment()Landroid/text/Layout$Alignment;
HSPLandroid/widget/TextView;->getLineAtCoordinate(F)I
HSPLandroid/widget/TextView;->getLineAtCoordinateUnclamped(F)I
HSPLandroid/widget/TextView;->getLineCount()I
@@ -20575,14 +20666,14 @@ HSPLandroid/widget/TextView;->getOffsetForPosition(FF)I
HSPLandroid/widget/TextView;->getPaint()Landroid/text/TextPaint;
HSPLandroid/widget/TextView;->getSelectionEnd()I
HSPLandroid/widget/TextView;->getSelectionEndTransformed()I
-HSPLandroid/widget/TextView;->getSelectionStart()I
+HSPLandroid/widget/TextView;->getSelectionStart()I+]Landroid/widget/TextView;missing_types
HSPLandroid/widget/TextView;->getSelectionStartTransformed()I
HSPLandroid/widget/TextView;->getServiceManagerForUser(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroid/widget/TextView;->getSpellCheckerLocale()Ljava/util/Locale;
HSPLandroid/widget/TextView;->getText()Ljava/lang/CharSequence;
HSPLandroid/widget/TextView;->getTextColors()Landroid/content/res/ColorStateList;
HSPLandroid/widget/TextView;->getTextCursorDrawable()Landroid/graphics/drawable/Drawable;
-HSPLandroid/widget/TextView;->getTextDirectionHeuristic()Landroid/text/TextDirectionHeuristic;+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getTextDirectionHeuristic()Landroid/text/TextDirectionHeuristic;
HSPLandroid/widget/TextView;->getTextLocale()Ljava/util/Locale;
HSPLandroid/widget/TextView;->getTextLocales()Landroid/os/LocaleList;
HSPLandroid/widget/TextView;->getTextSelectHandle()Landroid/graphics/drawable/Drawable;
@@ -20596,53 +20687,53 @@ HSPLandroid/widget/TextView;->getTotalPaddingTop()I
HSPLandroid/widget/TextView;->getTransformationMethod()Landroid/text/method/TransformationMethod;
HSPLandroid/widget/TextView;->getTypeface()Landroid/graphics/Typeface;
HSPLandroid/widget/TextView;->getTypefaceStyle()I
-HSPLandroid/widget/TextView;->getUpdatedHighlightPath()Landroid/graphics/Path;+]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getVerticalOffset(Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/widget/TextView;->getUpdatedHighlightPath()Landroid/graphics/Path;
+HSPLandroid/widget/TextView;->getVerticalOffset(Z)I
HSPLandroid/widget/TextView;->handleBackInTextActionModeIfNeeded(Landroid/view/KeyEvent;)Z
HSPLandroid/widget/TextView;->handleTextChanged(Ljava/lang/CharSequence;III)V
HSPLandroid/widget/TextView;->hasGesturePreviewHighlight()Z
-HSPLandroid/widget/TextView;->hasOverlappingRendering()Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/widget/TextView;->hasOverlappingRendering()Z
HSPLandroid/widget/TextView;->hasPasswordTransformationMethod()Z
HSPLandroid/widget/TextView;->hasSelection()Z
HSPLandroid/widget/TextView;->hideErrorIfUnchanged()V
HSPLandroid/widget/TextView;->invalidateCursor()V
HSPLandroid/widget/TextView;->invalidateCursorPath()V
-HSPLandroid/widget/TextView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/RippleDrawable;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/Button;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/VectorDrawable;
HSPLandroid/widget/TextView;->invalidateRegion(IIZ)V
HSPLandroid/widget/TextView;->isAnyPasswordInputType()Z
HSPLandroid/widget/TextView;->isAutoSizeEnabled()Z
HSPLandroid/widget/TextView;->isAutofillable()Z
HSPLandroid/widget/TextView;->isFallbackLineSpacingForStaticLayout()Z
-HSPLandroid/widget/TextView;->isFromPrimePointer(Landroid/view/MotionEvent;Z)Z
+HSPLandroid/widget/TextView;->isFromPrimePointer(Landroid/view/MotionEvent;Z)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
HSPLandroid/widget/TextView;->isInBatchEditMode()Z
HSPLandroid/widget/TextView;->isInExtractedMode()Z
HSPLandroid/widget/TextView;->isInputMethodTarget()Z
HSPLandroid/widget/TextView;->isMarqueeFadeEnabled()Z
HSPLandroid/widget/TextView;->isMultilineInputType(I)Z
HSPLandroid/widget/TextView;->isPasswordInputType(I)Z
-HSPLandroid/widget/TextView;->isPositionVisible(FF)Z
+HSPLandroid/widget/TextView;->isPositionVisible(FF)Z+]Landroid/view/View;missing_types]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
HSPLandroid/widget/TextView;->isShowingHint()Z
HSPLandroid/widget/TextView;->isSuggestionsEnabled()Z
HSPLandroid/widget/TextView;->isTextAutofillable()Z
HSPLandroid/widget/TextView;->isTextEditable()Z
HSPLandroid/widget/TextView;->isTextSelectable()Z
HSPLandroid/widget/TextView;->isVisibleToAccessibility()Z
-HSPLandroid/widget/TextView;->jumpDrawablesToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/TextView;->jumpDrawablesToCurrentState()V
HSPLandroid/widget/TextView;->length()I
-HSPLandroid/widget/TextView;->makeNewLayout(IILandroid/text/BoringLayout$Metrics;Landroid/text/BoringLayout$Metrics;IZ)V+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->makeSingleLayout(ILandroid/text/BoringLayout$Metrics;ILandroid/text/Layout$Alignment;ZLandroid/text/TextUtils$TruncateAt;Z)Landroid/text/Layout;+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/widget/TextView;->maybeUpdateHighlightPaths()V+]Landroid/widget/TextView;missing_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/widget/TextView;->makeNewLayout(IILandroid/text/BoringLayout$Metrics;Landroid/text/BoringLayout$Metrics;IZ)V+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;,Landroid/widget/Button;
+HSPLandroid/widget/TextView;->makeSingleLayout(ILandroid/text/BoringLayout$Metrics;ILandroid/text/Layout$Alignment;ZLandroid/text/TextUtils$TruncateAt;Z)Landroid/text/Layout;+]Landroid/text/DynamicLayout$Builder;Landroid/text/DynamicLayout$Builder;]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;
+HSPLandroid/widget/TextView;->maybeUpdateHighlightPaths()V
HSPLandroid/widget/TextView;->notifyContentCaptureTextChanged()V
-HSPLandroid/widget/TextView;->notifyListeningManagersAfterTextChanged()V+]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->notifyListeningManagersAfterTextChanged()V
HSPLandroid/widget/TextView;->nullLayouts()V
HSPLandroid/widget/TextView;->onAttachedToWindow()V
HSPLandroid/widget/TextView;->onBeginBatchEdit()V
HSPLandroid/widget/TextView;->onCheckIsTextEditor()Z
HSPLandroid/widget/TextView;->onConfigurationChanged(Landroid/content/res/Configuration;)V
-HSPLandroid/widget/TextView;->onCreateDrawableState(I)[I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onCreateDrawableState(I)[I
HSPLandroid/widget/TextView;->onCreateInputConnection(Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection;
HSPLandroid/widget/TextView;->onDetachedFromWindowInternal()V
-HSPLandroid/widget/TextView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/widget/TextView;missing_types]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/widget/Editor;Landroid/widget/Editor;]Ljava/lang/CharSequence;Landroid/text/SpannableStringBuilder;
HSPLandroid/widget/TextView;->onEditorAction(I)V
HSPLandroid/widget/TextView;->onEndBatchEdit()V
HSPLandroid/widget/TextView;->onFocusChanged(ZILandroid/graphics/Rect;)V
@@ -20653,7 +20744,7 @@ HSPLandroid/widget/TextView;->onKeyPreIme(ILandroid/view/KeyEvent;)Z
HSPLandroid/widget/TextView;->onKeyUp(ILandroid/view/KeyEvent;)Z
HSPLandroid/widget/TextView;->onLayout(ZIIII)V
HSPLandroid/widget/TextView;->onLocaleChanged()V
-HSPLandroid/widget/TextView;->onMeasure(II)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/DynamicLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onMeasure(II)V+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;,Landroid/widget/Button;
HSPLandroid/widget/TextView;->onPreDraw()Z
HSPLandroid/widget/TextView;->onProvideStructure(Landroid/view/ViewStructure;II)V
HSPLandroid/widget/TextView;->onResolveDrawables(I)V
@@ -20670,7 +20761,7 @@ HSPLandroid/widget/TextView;->onVisibilityChanged(Landroid/view/View;I)V
HSPLandroid/widget/TextView;->onWindowFocusChanged(Z)V
HSPLandroid/widget/TextView;->originalToTransformed(II)I
HSPLandroid/widget/TextView;->preloadFontCache()V
-HSPLandroid/widget/TextView;->readTextAppearance(Landroid/content/Context;Landroid/content/res/TypedArray;Landroid/widget/TextView$TextAppearanceAttributes;Z)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/util/TypedValue;Landroid/util/TypedValue;
+HSPLandroid/widget/TextView;->readTextAppearance(Landroid/content/Context;Landroid/content/res/TypedArray;Landroid/widget/TextView$TextAppearanceAttributes;Z)V+]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/Context;missing_types
HSPLandroid/widget/TextView;->registerForPreDraw()V
HSPLandroid/widget/TextView;->removeAdjacentSuggestionSpans(I)V
HSPLandroid/widget/TextView;->removeIntersectingNonAdjacentSpans(IILjava/lang/Class;)V
@@ -20690,7 +20781,7 @@ HSPLandroid/widget/TextView;->setAutoSizeTextTypeUniformWithPresetSizes([II)V
HSPLandroid/widget/TextView;->setBreakStrategy(I)V
HSPLandroid/widget/TextView;->setCompoundDrawablePadding(I)V
HSPLandroid/widget/TextView;->setCompoundDrawableTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/widget/TextView;->setCompoundDrawables(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->setCompoundDrawables(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/TextView;->setCompoundDrawablesRelative(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/TextView;->setCompoundDrawablesRelativeWithIntrinsicBounds(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/TextView;->setCompoundDrawablesWithIntrinsicBounds(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
@@ -20720,7 +20811,7 @@ HSPLandroid/widget/TextView;->setInputTypeFromEditor()V
HSPLandroid/widget/TextView;->setInputTypeSingleLine(Z)V
HSPLandroid/widget/TextView;->setKeyListener(Landroid/text/method/KeyListener;)V
HSPLandroid/widget/TextView;->setKeyListenerOnly(Landroid/text/method/KeyListener;)V
-HSPLandroid/widget/TextView;->setLetterSpacing(F)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/widget/TextView;->setLetterSpacing(F)V
HSPLandroid/widget/TextView;->setLineHeight(I)V
HSPLandroid/widget/TextView;->setLineSpacing(FF)V
HSPLandroid/widget/TextView;->setLines(I)V
@@ -20737,7 +20828,7 @@ HSPLandroid/widget/TextView;->setPadding(IIII)V
HSPLandroid/widget/TextView;->setPaddingRelative(IIII)V
HSPLandroid/widget/TextView;->setPrivateImeOptions(Ljava/lang/String;)V
HSPLandroid/widget/TextView;->setRawInputType(I)V
-HSPLandroid/widget/TextView;->setRawTextSize(FZ)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/widget/TextView;->setRawTextSize(FZ)V
HSPLandroid/widget/TextView;->setRelativeDrawablesIfNeeded(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
HSPLandroid/widget/TextView;->setSelected(Z)V
HSPLandroid/widget/TextView;->setShadowLayer(FFFI)V
@@ -20746,7 +20837,7 @@ HSPLandroid/widget/TextView;->setSingleLine(Z)V
HSPLandroid/widget/TextView;->setText(I)V
HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;)V
-HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V+]Landroid/text/Editable$Factory;Landroid/text/Editable$Factory;]Landroid/text/InputFilter;Landroid/text/InputFilter$LengthFilter;]Landroid/text/Spannable$Factory;Landroid/text/Spannable$Factory;]Landroid/text/Spannable;Landroid/text/SpannableString;,Landroid/text/SpannableStringBuilder;]Landroid/text/Spanned;Landroid/text/SpannableStringBuilder;,Landroid/text/SpannedString;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/method/MovementMethod;Landroid/text/method/ArrowKeyMovementMethod;,Landroid/text/method/LinkMovementMethod;]Landroid/text/method/TransformationMethod;Landroid/text/method/AllCapsTransformationMethod;,Landroid/text/method/SingleLineTransformationMethod;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Landroid/text/SpannableString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannedString;,Ljava/lang/String;
+HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V+]Landroid/text/Editable$Factory;Landroid/text/Editable$Factory;]Landroid/text/method/MovementMethod;Landroid/text/method/ArrowKeyMovementMethod;,Landroid/text/method/ScrollingMovementMethod;]Landroid/text/method/TransformationMethod;Landroid/text/method/SingleLineTransformationMethod;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/text/InputFilter;Landroid/text/InputFilter$LengthFilter;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;]Landroid/text/Spannable$Factory;Landroid/text/Spannable$Factory;]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/text/Spannable;Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;
HSPLandroid/widget/TextView;->setTextAppearance(I)V
HSPLandroid/widget/TextView;->setTextAppearance(Landroid/content/Context;I)V
HSPLandroid/widget/TextView;->setTextColor(I)V
@@ -20758,14 +20849,14 @@ HSPLandroid/widget/TextView;->setTextSize(IF)V
HSPLandroid/widget/TextView;->setTextSizeInternal(IFZ)V
HSPLandroid/widget/TextView;->setTransformationMethod(Landroid/text/method/TransformationMethod;)V
HSPLandroid/widget/TextView;->setTransformationMethodInternal(Landroid/text/method/TransformationMethod;Z)V
-HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
-HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;I)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;)V
+HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;I)V
HSPLandroid/widget/TextView;->setTypefaceFromAttrs(Landroid/graphics/Typeface;Ljava/lang/String;III)V
HSPLandroid/widget/TextView;->setupAutoSizeText()Z
HSPLandroid/widget/TextView;->setupAutoSizeUniformPresetSizesConfiguration()Z
HSPLandroid/widget/TextView;->shouldAdvanceFocusOnEnter()Z
HSPLandroid/widget/TextView;->spanChange(Landroid/text/Spanned;Ljava/lang/Object;IIII)V
-HSPLandroid/widget/TextView;->startMarquee()V+]Landroid/widget/TextView;Landroid/widget/CheckedTextView;,Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->startMarquee()V
HSPLandroid/widget/TextView;->startStopMarquee(Z)V
HSPLandroid/widget/TextView;->stopMarquee()V
HSPLandroid/widget/TextView;->stopTextActionMode()V
@@ -20775,8 +20866,8 @@ HSPLandroid/widget/TextView;->textCanBeSelected()Z
HSPLandroid/widget/TextView;->unregisterForPreDraw()V
HSPLandroid/widget/TextView;->updateAfterEdit()V
HSPLandroid/widget/TextView;->updateCursorVisibleInternal()V
-HSPLandroid/widget/TextView;->updateTextColors()V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/widget/TextView;->useDynamicLayout()Z+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->updateTextColors()V
+HSPLandroid/widget/TextView;->useDynamicLayout()Z
HSPLandroid/widget/TextView;->validateAndSetAutoSizeTextTypeUniformConfiguration(FFF)V
HSPLandroid/widget/TextView;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
HSPLandroid/widget/TextView;->viewClicked(Landroid/view/inputmethod/InputMethodManager;)V
@@ -20837,6 +20928,7 @@ HSPLandroid/widget/inline/InlinePresentationSpec$1;->createFromParcel(Landroid/o
HSPLandroid/widget/inline/InlinePresentationSpec;-><clinit>()V
HSPLandroid/widget/inline/InlinePresentationSpec;-><init>(Landroid/os/Parcel;)V
HSPLandroid/widget/inline/InlinePresentationSpec;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/window/BackProgressAnimator;-><init>()V+]Lcom/android/internal/dynamicanimation/animation/SpringAnimation;Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Lcom/android/internal/dynamicanimation/animation/SpringForce;Lcom/android/internal/dynamicanimation/animation/SpringForce;
HSPLandroid/window/ClientWindowFrames$1;-><init>()V
HSPLandroid/window/ClientWindowFrames$1;->createFromParcel(Landroid/os/Parcel;)Landroid/window/ClientWindowFrames;
HSPLandroid/window/ClientWindowFrames$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -20954,6 +21046,8 @@ HSPLandroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;->
HSPLandroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;->onBackCancelled()V
HSPLandroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;->onBackInvoked()V
HSPLandroid/window/WindowOnBackInvokedDispatcher;-><clinit>()V
+HSPLandroid/window/WindowOnBackInvokedDispatcher;-><init>(Landroid/content/Context;)V
+HSPLandroid/window/WindowOnBackInvokedDispatcher;->attachToWindow(Landroid/view/IWindowSession;Landroid/view/IWindow;)V
HSPLandroid/window/WindowOnBackInvokedDispatcher;->clear()V
HSPLandroid/window/WindowOnBackInvokedDispatcher;->detachFromWindow()V
HSPLandroid/window/WindowOnBackInvokedDispatcher;->getTopCallback()Landroid/window/OnBackInvokedCallback;
@@ -20989,12 +21083,12 @@ HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getMetadataForRegion(Ljava/l
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getMetadataForRegionOrCallingCode(ILjava/lang/String;)Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNationalSignificantNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberDescByType(Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;)Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberTypeHelper(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberTypeHelper(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;+]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;]Lcom/android/i18n/phonenumbers/PhoneNumberUtil;Lcom/android/i18n/phonenumbers/PhoneNumberUtil;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForCountryCode(I)Ljava/lang/String;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumberFromRegionList(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/util/List;)Ljava/lang/String;
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumberFromRegionList(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/util/List;)Ljava/lang/String;+]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;]Ljava/util/List;Ljava/util/ArrayList;]Lcom/android/i18n/phonenumbers/PhoneNumberUtil;Lcom/android/i18n/phonenumbers/PhoneNumberUtil;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->hasFormattingPatternForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isNumberMatchingDesc(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;)Z
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isNumberMatchingDesc(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;)Z+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/i18n/phonenumbers/internal/MatcherApi;Lcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;]Ljava/util/List;Ljava/util/ArrayList;
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidNumberForRegion(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/lang/String;)Z
HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidRegionCode(Ljava/lang/String;)Z
@@ -21099,8 +21193,8 @@ HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setCountryCode(I)Lco
HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setCountryCodeSource(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setNationalNumber(J)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setRawInput(Ljava/lang/String;)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
-HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->match(Ljava/lang/CharSequence;Ljava/util/regex/Pattern;Z)Z
-HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->matchNationalNumber(Ljava/lang/CharSequence;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Z)Z
+HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->match(Ljava/lang/CharSequence;Ljava/util/regex/Pattern;Z)Z+]Ljava/util/regex/Matcher;Ljava/util/regex/Matcher;]Ljava/util/regex/Pattern;Ljava/util/regex/Pattern;
+HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->matchNationalNumber(Ljava/lang/CharSequence;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Z)Z+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;]Lcom/android/i18n/phonenumbers/internal/RegexCache;Lcom/android/i18n/phonenumbers/internal/RegexCache;
HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z
HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache;->put(Ljava/lang/Object;Ljava/lang/Object;)V
@@ -21178,10 +21272,10 @@ HSPLcom/android/i18n/timezone/internal/NioBufferIterator;->readInt()I
HSPLcom/android/i18n/timezone/internal/NioBufferIterator;->readLongArray([JII)V
HSPLcom/android/i18n/timezone/internal/NioBufferIterator;->skip(I)V
HSPLcom/android/icu/charset/CharsetDecoderICU;-><init>(Ljava/nio/charset/Charset;FJ)V
-HSPLcom/android/icu/charset/CharsetDecoderICU;->decodeLoop(Ljava/nio/ByteBuffer;Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;
-HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/ByteBuffer;)I
-HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/CharBuffer;)I
-HSPLcom/android/icu/charset/CharsetDecoderICU;->implFlush(Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->decodeLoop(Ljava/nio/ByteBuffer;Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/ByteBuffer;)I+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/CharBuffer;)I+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->implFlush(Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;+]Lcom/android/icu/charset/CharsetDecoderICU;Lcom/android/icu/charset/CharsetDecoderICU;
HSPLcom/android/icu/charset/CharsetDecoderICU;->implOnMalformedInput(Ljava/nio/charset/CodingErrorAction;)V
HSPLcom/android/icu/charset/CharsetDecoderICU;->implOnUnmappableCharacter(Ljava/nio/charset/CodingErrorAction;)V
HSPLcom/android/icu/charset/CharsetDecoderICU;->implReplaceWith(Ljava/lang/String;)V
@@ -21191,16 +21285,16 @@ HSPLcom/android/icu/charset/CharsetDecoderICU;->setPosition(Ljava/nio/ByteBuffer
HSPLcom/android/icu/charset/CharsetDecoderICU;->setPosition(Ljava/nio/CharBuffer;)V
HSPLcom/android/icu/charset/CharsetDecoderICU;->updateCallback()V
HSPLcom/android/icu/charset/CharsetEncoderICU;-><init>(Ljava/nio/charset/Charset;FF[BJ)V
-HSPLcom/android/icu/charset/CharsetEncoderICU;->encodeLoop(Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;
-HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/ByteBuffer;)I
-HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/CharBuffer;)I
+HSPLcom/android/icu/charset/CharsetEncoderICU;->encodeLoop(Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
+HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/ByteBuffer;)I+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/CharBuffer;)I+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
HSPLcom/android/icu/charset/CharsetEncoderICU;->implFlush(Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;
HSPLcom/android/icu/charset/CharsetEncoderICU;->implOnMalformedInput(Ljava/nio/charset/CodingErrorAction;)V
HSPLcom/android/icu/charset/CharsetEncoderICU;->implOnUnmappableCharacter(Ljava/nio/charset/CodingErrorAction;)V
HSPLcom/android/icu/charset/CharsetEncoderICU;->implReset()V
HSPLcom/android/icu/charset/CharsetEncoderICU;->makeReplacement(Ljava/lang/String;J)[B
HSPLcom/android/icu/charset/CharsetEncoderICU;->newInstance(Ljava/nio/charset/Charset;Ljava/lang/String;)Lcom/android/icu/charset/CharsetEncoderICU;
-HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/ByteBuffer;)V
+HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/ByteBuffer;)V+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/CharBuffer;)V
HSPLcom/android/icu/charset/CharsetEncoderICU;->updateCallback()V
HSPLcom/android/icu/charset/CharsetFactory;->create(Ljava/lang/String;)Ljava/nio/charset/Charset;
@@ -21240,7 +21334,7 @@ HSPLcom/android/icu/util/ExtendedTimeZone;->utcStartTime(JLandroid/icu/util/Time
HSPLcom/android/icu/util/LocaleNative;->getDisplayCountry(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String;
HSPLcom/android/icu/util/LocaleNative;->getDisplayLanguage(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String;
HSPLcom/android/icu/util/LocaleNative;->setDefault(Ljava/lang/String;)V
-HSPLcom/android/icu/util/regex/MatcherNative;-><init>(Lcom/android/icu/util/regex/PatternNative;)V
+HSPLcom/android/icu/util/regex/MatcherNative;-><init>(Lcom/android/icu/util/regex/PatternNative;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;]Lcom/android/icu/util/regex/PatternNative;Lcom/android/icu/util/regex/PatternNative;
HSPLcom/android/icu/util/regex/MatcherNative;->create(Lcom/android/icu/util/regex/PatternNative;)Lcom/android/icu/util/regex/MatcherNative;
HSPLcom/android/icu/util/regex/MatcherNative;->find(I[I)Z
HSPLcom/android/icu/util/regex/MatcherNative;->findNext([I)Z
@@ -21252,7 +21346,7 @@ HSPLcom/android/icu/util/regex/MatcherNative;->requireEnd()Z
HSPLcom/android/icu/util/regex/MatcherNative;->setInput(Ljava/lang/String;II)V
HSPLcom/android/icu/util/regex/MatcherNative;->useAnchoringBounds(Z)V
HSPLcom/android/icu/util/regex/MatcherNative;->useTransparentBounds(Z)V
-HSPLcom/android/icu/util/regex/PatternNative;-><init>(Ljava/lang/String;I)V
+HSPLcom/android/icu/util/regex/PatternNative;-><init>(Ljava/lang/String;I)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
HSPLcom/android/icu/util/regex/PatternNative;->create(Ljava/lang/String;I)Lcom/android/icu/util/regex/PatternNative;
HSPLcom/android/icu/util/regex/PatternNative;->openMatcher()J
HSPLcom/android/internal/app/AlertController;-><init>(Landroid/content/Context;Landroid/content/DialogInterface;Landroid/view/Window;)V
@@ -21336,6 +21430,8 @@ HSPLcom/android/internal/content/ReferrerIntent$1;->createFromParcel(Landroid/os
HSPLcom/android/internal/content/ReferrerIntent$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
HSPLcom/android/internal/display/BrightnessSynchronizer;-><clinit>()V
HSPLcom/android/internal/display/BrightnessSynchronizer;->floatEquals(FF)Z
+HSPLcom/android/internal/dynamicanimation/animation/DynamicAnimation;-><init>(Ljava/lang/Object;Landroid/util/FloatProperty;)V
+HSPLcom/android/internal/dynamicanimation/animation/SpringForce;-><init>()V
HSPLcom/android/internal/graphics/ColorUtils;->HSLToColor([F)I
HSPLcom/android/internal/graphics/ColorUtils;->RGBToHSL(III[F)V
HSPLcom/android/internal/graphics/ColorUtils;->colorToHSL(I[F)V
@@ -21464,7 +21560,7 @@ HSPLcom/android/internal/listeners/ListenerExecutor$ListenerOperation;->onComple
HSPLcom/android/internal/listeners/ListenerExecutor$ListenerOperation;->onPostExecute(Z)V
HSPLcom/android/internal/listeners/ListenerExecutor$ListenerOperation;->onPreExecute()V
HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;)V
-HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V+]Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda2;,Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda3;]Ljava/util/concurrent/Executor;Landroid/net/connectivity/com/android/modules/utils/HandlerExecutor;,Landroid/os/HandlerExecutor;,Lcom/android/wifi/x/com/android/modules/utils/HandlerExecutor;]Ljava/util/function/Supplier;Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda1;
+HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V
HSPLcom/android/internal/listeners/ListenerExecutor;->lambda$executeSafely$0(Ljava/lang/Object;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V
HSPLcom/android/internal/logging/AndroidConfig;-><init>()V
HSPLcom/android/internal/logging/AndroidHandler$1;->format(Ljava/util/logging/LogRecord;)Ljava/lang/String;
@@ -21705,33 +21801,42 @@ HSPLcom/android/internal/policy/DecorView$ColorViewAttributes;->isPresent(ZIZ)Z
HSPLcom/android/internal/policy/DecorView$ColorViewAttributes;->isVisible(ZIIZ)Z
HSPLcom/android/internal/policy/DecorView$ColorViewState;-><init>(Lcom/android/internal/policy/DecorView$ColorViewAttributes;)V
HSPLcom/android/internal/policy/DecorView;-><init>(Landroid/content/Context;ILcom/android/internal/policy/PhoneWindow;Landroid/view/WindowManager$LayoutParams;)V
-HSPLcom/android/internal/policy/DecorView;->calculateNavigationBarColor(I)I
-HSPLcom/android/internal/policy/DecorView;->calculateStatusBarColor(I)I
+HSPLcom/android/internal/policy/DecorView;->calculateNavigationBarColor(I)I+]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->calculateStatusBarColor(I)I+]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->createDecorCaptionView(Landroid/view/LayoutInflater;)Lcom/android/internal/widget/DecorCaptionView;
HSPLcom/android/internal/policy/DecorView;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
HSPLcom/android/internal/policy/DecorView;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
HSPLcom/android/internal/policy/DecorView;->draw(Landroid/graphics/Canvas;)V
HSPLcom/android/internal/policy/DecorView;->drawLegacyNavigationBarBackground(Landroid/graphics/RecordingCanvas;)V
HSPLcom/android/internal/policy/DecorView;->drawableChanged()V
+HSPLcom/android/internal/policy/DecorView;->enableCaption(Z)V
+HSPLcom/android/internal/policy/DecorView;->enforceNonTranslucentBackground(Landroid/graphics/drawable/Drawable;Z)Landroid/graphics/drawable/Drawable;
HSPLcom/android/internal/policy/DecorView;->finishChanging()V
+HSPLcom/android/internal/policy/DecorView;->gatherTransparentRegion(Landroid/graphics/Region;)Z
+HSPLcom/android/internal/policy/DecorView;->gatherTransparentRegion(Lcom/android/internal/policy/DecorView$ColorViewState;Landroid/graphics/Region;)Z
HSPLcom/android/internal/policy/DecorView;->getAccessibilityViewId()I
HSPLcom/android/internal/policy/DecorView;->getBackground()Landroid/graphics/drawable/Drawable;
+HSPLcom/android/internal/policy/DecorView;->getCaptionHeight()I
+HSPLcom/android/internal/policy/DecorView;->getCaptionInsetsHeight()I
HSPLcom/android/internal/policy/DecorView;->getNavBarSize(III)I
-HSPLcom/android/internal/policy/DecorView;->getResources()Landroid/content/res/Resources;+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->getTitleSuffix(Landroid/view/WindowManager$LayoutParams;)Ljava/lang/String;
-HSPLcom/android/internal/policy/DecorView;->getWindowInsetsController()Landroid/view/WindowInsetsController;
+HSPLcom/android/internal/policy/DecorView;->getResources()Landroid/content/res/Resources;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;
+HSPLcom/android/internal/policy/DecorView;->getTitleSuffix(Landroid/view/WindowManager$LayoutParams;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLcom/android/internal/policy/DecorView;->getWindowInsetsController()Landroid/view/WindowInsetsController;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
HSPLcom/android/internal/policy/DecorView;->initializeElevation()V
HSPLcom/android/internal/policy/DecorView;->isNavBarToLeftEdge(II)Z
HSPLcom/android/internal/policy/DecorView;->isNavBarToRightEdge(II)Z
+HSPLcom/android/internal/policy/DecorView;->isResizing()Z
+HSPLcom/android/internal/policy/DecorView;->isShowingCaption()Z
HSPLcom/android/internal/policy/DecorView;->onApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
HSPLcom/android/internal/policy/DecorView;->onAttachedToWindow()V
HSPLcom/android/internal/policy/DecorView;->onCloseSystemDialogs(Ljava/lang/String;)V
HSPLcom/android/internal/policy/DecorView;->onConfigurationChanged(Landroid/content/res/Configuration;)V
HSPLcom/android/internal/policy/DecorView;->onContentDrawn(IIII)Z
HSPLcom/android/internal/policy/DecorView;->onDetachedFromWindow()V
-HSPLcom/android/internal/policy/DecorView;->onDraw(Landroid/graphics/Canvas;)V
+HSPLcom/android/internal/policy/DecorView;->onDraw(Landroid/graphics/Canvas;)V+]Lcom/android/internal/widget/BackgroundFallback;Lcom/android/internal/widget/BackgroundFallback;
HSPLcom/android/internal/policy/DecorView;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z
-HSPLcom/android/internal/policy/DecorView;->onLayout(ZIIII)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->onMeasure(II)V+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->onLayout(ZIIII)V
+HSPLcom/android/internal/policy/DecorView;->onMeasure(II)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;
HSPLcom/android/internal/policy/DecorView;->onPostDraw(Landroid/graphics/RecordingCanvas;)V
HSPLcom/android/internal/policy/DecorView;->onResourcesLoaded(Landroid/view/LayoutInflater;I)V
HSPLcom/android/internal/policy/DecorView;->onRootViewScrollYChanged(I)V
@@ -21740,12 +21845,13 @@ HSPLcom/android/internal/policy/DecorView;->onTouchEvent(Landroid/view/MotionEve
HSPLcom/android/internal/policy/DecorView;->onWindowFocusChanged(Z)V
HSPLcom/android/internal/policy/DecorView;->onWindowSystemUiVisibilityChanged(I)V
HSPLcom/android/internal/policy/DecorView;->providePendingInsetsController()Landroid/view/PendingInsetsController;
+HSPLcom/android/internal/policy/DecorView;->releaseThreadedRenderer()V
HSPLcom/android/internal/policy/DecorView;->removeBackgroundBlurDrawable()V
HSPLcom/android/internal/policy/DecorView;->sendAccessibilityEvent(I)V
HSPLcom/android/internal/policy/DecorView;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLcom/android/internal/policy/DecorView;->setBackgroundFallback(Landroid/graphics/drawable/Drawable;)V
HSPLcom/android/internal/policy/DecorView;->setColor(Landroid/view/View;IIZZ)V
-HSPLcom/android/internal/policy/DecorView;->setFrame(IIII)Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
+HSPLcom/android/internal/policy/DecorView;->setFrame(IIII)Z+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;
HSPLcom/android/internal/policy/DecorView;->setWindow(Lcom/android/internal/policy/PhoneWindow;)V
HSPLcom/android/internal/policy/DecorView;->setWindowBackground(Landroid/graphics/drawable/Drawable;)V
HSPLcom/android/internal/policy/DecorView;->setWindowFrame(Landroid/graphics/drawable/Drawable;)V
@@ -21753,12 +21859,13 @@ HSPLcom/android/internal/policy/DecorView;->startChanging()V
HSPLcom/android/internal/policy/DecorView;->superDispatchKeyEvent(Landroid/view/KeyEvent;)Z
HSPLcom/android/internal/policy/DecorView;->superDispatchTouchEvent(Landroid/view/MotionEvent;)Z
HSPLcom/android/internal/policy/DecorView;->updateBackgroundBlurRadius()V
-HSPLcom/android/internal/policy/DecorView;->updateBackgroundDrawable()V
-HSPLcom/android/internal/policy/DecorView;->updateColorViewInt(Lcom/android/internal/policy/DecorView$ColorViewState;IIIZZIZZI)V+]Landroid/view/View;Landroid/view/View;]Landroid/view/ViewPropertyAnimator;Landroid/view/ViewPropertyAnimator;]Lcom/android/internal/policy/DecorView$ColorViewAttributes;Lcom/android/internal/policy/DecorView$ColorViewAttributes;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->updateBackgroundDrawable()V+]Landroid/graphics/Insets;Landroid/graphics/Insets;
+HSPLcom/android/internal/policy/DecorView;->updateColorViewInt(Lcom/android/internal/policy/DecorView$ColorViewState;IIIZZIZZI)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Landroid/view/View;Landroid/view/View;]Landroid/view/ViewPropertyAnimator;Landroid/view/ViewPropertyAnimator;]Lcom/android/internal/policy/DecorView$ColorViewAttributes;Lcom/android/internal/policy/DecorView$ColorViewAttributes;
HSPLcom/android/internal/policy/DecorView;->updateColorViewTranslations()V
-HSPLcom/android/internal/policy/DecorView;->updateColorViews(Landroid/view/WindowInsets;Z)Landroid/view/WindowInsets;+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ViewGroup;Landroid/widget/LinearLayout;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;]Landroid/view/WindowInsetsController;Landroid/view/InsetsController;,Landroid/view/PendingInsetsController;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
-HSPLcom/android/internal/policy/DecorView;->updateElevation()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->updateLogTag(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/DecorView;->updateColorViews(Landroid/view/WindowInsets;Z)Landroid/view/WindowInsets;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Landroid/view/ViewGroup;Landroid/widget/LinearLayout;]Landroid/view/WindowInsetsController;Landroid/view/InsetsController;,Landroid/view/PendingInsetsController;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLcom/android/internal/policy/DecorView;->updateDecorCaptionStatus(Landroid/content/res/Configuration;)V
+HSPLcom/android/internal/policy/DecorView;->updateElevation()V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLcom/android/internal/policy/DecorView;->updateLogTag(Landroid/view/WindowManager$LayoutParams;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
HSPLcom/android/internal/policy/DecorView;->updateStatusGuard(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
HSPLcom/android/internal/policy/DecorView;->willYouTakeTheInputQueue()Landroid/view/InputQueue$Callback;
HSPLcom/android/internal/policy/DecorView;->willYouTakeTheSurface()Landroid/view/SurfaceHolder$Callback2;
@@ -21792,10 +21899,10 @@ HSPLcom/android/internal/policy/PhoneWindow;->applyDecorFitsSystemWindows()V
HSPLcom/android/internal/policy/PhoneWindow;->closeAllPanels()V
HSPLcom/android/internal/policy/PhoneWindow;->closeContextMenu()V
HSPLcom/android/internal/policy/PhoneWindow;->closePanel(Lcom/android/internal/policy/PhoneWindow$PanelFeatureState;Z)V
-HSPLcom/android/internal/policy/PhoneWindow;->dispatchWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/PhoneWindow;->dispatchWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
HSPLcom/android/internal/policy/PhoneWindow;->doInvalidatePanelMenu(I)V
HSPLcom/android/internal/policy/PhoneWindow;->generateDecor(I)Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/PhoneWindow;->generateLayout(Lcom/android/internal/policy/DecorView;)Landroid/view/ViewGroup;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Ljava/lang/Boolean;Ljava/lang/Boolean;
+HSPLcom/android/internal/policy/PhoneWindow;->generateLayout(Lcom/android/internal/policy/DecorView;)Landroid/view/ViewGroup;
HSPLcom/android/internal/policy/PhoneWindow;->getCurrentFocus()Landroid/view/View;
HSPLcom/android/internal/policy/PhoneWindow;->getDecorView()Landroid/view/View;
HSPLcom/android/internal/policy/PhoneWindow;->getLayoutInflater()Landroid/view/LayoutInflater;
@@ -21823,7 +21930,7 @@ HSPLcom/android/internal/policy/PhoneWindow;->peekDecorView()Landroid/view/View;
HSPLcom/android/internal/policy/PhoneWindow;->requestFeature(I)Z
HSPLcom/android/internal/policy/PhoneWindow;->restoreHierarchyState(Landroid/os/Bundle;)V
HSPLcom/android/internal/policy/PhoneWindow;->saveHierarchyState()Landroid/os/Bundle;
-HSPLcom/android/internal/policy/PhoneWindow;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/PhoneWindow;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
HSPLcom/android/internal/policy/PhoneWindow;->setBackgroundBlurRadius(I)V
HSPLcom/android/internal/policy/PhoneWindow;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLcom/android/internal/policy/PhoneWindow;->setContentView(I)V
@@ -21896,6 +22003,7 @@ HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getAvailableSubscriptionInf
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultDataSubId()I
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSmsSubId()I
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSubId()I
+HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSubIdAsUser(I)I
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultVoiceSubId()I
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getPhoneId(I)I
HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getSlotIndex(I)I
@@ -21981,7 +22089,7 @@ HSPLcom/android/internal/util/ArrayUtils;->convertToIntArray(Ljava/util/List;)[I
HSPLcom/android/internal/util/ArrayUtils;->deepToString(Ljava/lang/Object;)Ljava/lang/String;
HSPLcom/android/internal/util/ArrayUtils;->defeatNullable([Ljava/io/File;)[Ljava/io/File;
HSPLcom/android/internal/util/ArrayUtils;->defeatNullable([Ljava/lang/String;)[Ljava/lang/String;
-HSPLcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/Class;]Ljava/lang/Class;Ljava/lang/Class;
HSPLcom/android/internal/util/ArrayUtils;->emptyIfNull([Ljava/lang/Object;Ljava/lang/Class;)[Ljava/lang/Object;
HSPLcom/android/internal/util/ArrayUtils;->filter([Ljava/lang/Object;Ljava/util/function/IntFunction;Ljava/util/function/Predicate;)[Ljava/lang/Object;
HSPLcom/android/internal/util/ArrayUtils;->getOrNull([Ljava/lang/Object;I)Ljava/lang/Object;
@@ -21989,14 +22097,14 @@ HSPLcom/android/internal/util/ArrayUtils;->indexOf([Ljava/lang/Object;Ljava/lang
HSPLcom/android/internal/util/ArrayUtils;->isEmpty(Ljava/util/Collection;)Z
HSPLcom/android/internal/util/ArrayUtils;->isEmpty([I)Z
HSPLcom/android/internal/util/ArrayUtils;->isEmpty([Ljava/lang/Object;)Z
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object;+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedBooleanArray(I)[Z
HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedByteArray(I)[B
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedCharArray(I)[C
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedCharArray(I)[C+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedFloatArray(I)[F
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedLongArray(I)[J
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedObjectArray(I)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedObjectArray(I)[Ljava/lang/Object;+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
HSPLcom/android/internal/util/ArrayUtils;->remove(Ljava/util/ArrayList;Ljava/lang/Object;)Ljava/util/ArrayList;
HSPLcom/android/internal/util/ArrayUtils;->removeElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
HSPLcom/android/internal/util/ArrayUtils;->size([Ljava/lang/Object;)I
@@ -22037,13 +22145,13 @@ HSPLcom/android/internal/util/FastPrintWriter;->print(J)V
HSPLcom/android/internal/util/FastPrintWriter;->print(Ljava/lang/String;)V
HSPLcom/android/internal/util/FastPrintWriter;->println()V
HSPLcom/android/internal/util/FastPrintWriter;->write(I)V
-HSPLcom/android/internal/util/FastPrintWriter;->write(Ljava/lang/String;)V
+HSPLcom/android/internal/util/FastPrintWriter;->write(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
HSPLcom/android/internal/util/FastPrintWriter;->write([CII)V
HSPLcom/android/internal/util/FastXmlSerializer;-><init>()V
HSPLcom/android/internal/util/FastXmlSerializer;-><init>(I)V
HSPLcom/android/internal/util/FastXmlSerializer;->append(C)V
HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
-HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;II)V+]Ljava/lang/String;Ljava/lang/String;
+HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;II)V+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/internal/util/FastXmlSerializer;Lcom/android/internal/util/FastXmlSerializer;
HSPLcom/android/internal/util/FastXmlSerializer;->appendIndent(I)V+]Ljava/lang/String;Ljava/lang/String;
HSPLcom/android/internal/util/FastXmlSerializer;->attribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
HSPLcom/android/internal/util/FastXmlSerializer;->endDocument()V
@@ -22065,12 +22173,12 @@ HSPLcom/android/internal/util/FrameworkStatsLog;->write(ILjava/lang/String;I)V
HSPLcom/android/internal/util/FrameworkStatsLog;->write(ILjava/lang/String;IIF)V
HSPLcom/android/internal/util/GrowingArrayUtils;->append([III)[I
HSPLcom/android/internal/util/GrowingArrayUtils;->append([JIJ)[J
-HSPLcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;
+HSPLcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;
HSPLcom/android/internal/util/GrowingArrayUtils;->append([ZIZ)[Z
HSPLcom/android/internal/util/GrowingArrayUtils;->growSize(I)I
HSPLcom/android/internal/util/GrowingArrayUtils;->insert([IIII)[I
HSPLcom/android/internal/util/GrowingArrayUtils;->insert([JIIJ)[J
-HSPLcom/android/internal/util/GrowingArrayUtils;->insert([Ljava/lang/Object;IILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;[Ljava/lang/Object;
+HSPLcom/android/internal/util/GrowingArrayUtils;->insert([Ljava/lang/Object;IILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Object;[Ljava/lang/Object;]Ljava/lang/Class;Ljava/lang/Class;
HSPLcom/android/internal/util/GrowingArrayUtils;->insert([ZIIZ)[Z
HSPLcom/android/internal/util/IndentingPrintWriter;->decreaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
HSPLcom/android/internal/util/IndentingPrintWriter;->increaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
@@ -22140,7 +22248,7 @@ HSPLcom/android/internal/util/Preconditions;->checkStringNotEmpty(Ljava/lang/Cha
HSPLcom/android/internal/util/ProcFileReader;->finishLine()V
HSPLcom/android/internal/util/ScreenshotHelper;-><init>(Landroid/content/Context;)V
HSPLcom/android/internal/util/StatLogger;->getTime()J
-HSPLcom/android/internal/util/StatLogger;->logDurationStat(IJ)J+]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;
+HSPLcom/android/internal/util/StatLogger;->logDurationStat(IJ)J
HSPLcom/android/internal/util/State;-><init>()V
HSPLcom/android/internal/util/State;->enter()V
HSPLcom/android/internal/util/StateMachine$LogRecords;->add(Lcom/android/internal/util/StateMachine;Landroid/os/Message;Ljava/lang/String;Lcom/android/internal/util/IState;Lcom/android/internal/util/IState;Lcom/android/internal/util/IState;)V
@@ -22192,7 +22300,7 @@ HSPLcom/android/internal/util/XmlSerializerWrapper;->endTag(Ljava/lang/String;Lj
HSPLcom/android/internal/util/XmlSerializerWrapper;->setFeature(Ljava/lang/String;Z)V
HSPLcom/android/internal/util/XmlSerializerWrapper;->setOutput(Ljava/io/OutputStream;Ljava/lang/String;)V
HSPLcom/android/internal/util/XmlSerializerWrapper;->startDocument(Ljava/lang/String;Ljava/lang/Boolean;)V
-HSPLcom/android/internal/util/XmlSerializerWrapper;->startTag(Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;+]Lorg/xmlpull/v1/XmlSerializer;Lcom/android/internal/util/FastXmlSerializer;
+HSPLcom/android/internal/util/XmlSerializerWrapper;->startTag(Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
HSPLcom/android/internal/util/XmlSerializerWrapper;->text(Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
HSPLcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;-><init>(Lorg/xmlpull/v1/XmlPullParser;)V
HSPLcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;->getAttributeBoolean(I)Z
@@ -22215,19 +22323,19 @@ HSPLcom/android/internal/util/XmlUtils;->readLongAttribute(Lorg/xmlpull/v1/XmlPu
HSPLcom/android/internal/util/XmlUtils;->readLongAttribute(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;J)J
HSPLcom/android/internal/util/XmlUtils;->readMapXml(Ljava/io/InputStream;)Ljava/util/HashMap;
HSPLcom/android/internal/util/XmlUtils;->readStringAttribute(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;)Ljava/lang/String;
-HSPLcom/android/internal/util/XmlUtils;->readThisMapXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;)Ljava/util/HashMap;
-HSPLcom/android/internal/util/XmlUtils;->readThisPrimitiveValueXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;)Ljava/lang/Object;
+HSPLcom/android/internal/util/XmlUtils;->readThisMapXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;)Ljava/util/HashMap;+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
+HSPLcom/android/internal/util/XmlUtils;->readThisPrimitiveValueXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
HSPLcom/android/internal/util/XmlUtils;->readThisSetXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/util/HashSet;
-HSPLcom/android/internal/util/XmlUtils;->readThisValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/lang/Object;
+HSPLcom/android/internal/util/XmlUtils;->readThisValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Lcom/android/internal/util/XmlUtils$ReadMapCallback;Landroid/os/PersistableBundle$MyReadMapCallback;
HSPLcom/android/internal/util/XmlUtils;->readValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;)Ljava/lang/Object;
HSPLcom/android/internal/util/XmlUtils;->skipCurrentTag(Lorg/xmlpull/v1/XmlPullParser;)V
-HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/util/Map;Ljava/util/HashMap;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
+HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V
HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/io/OutputStream;)V
HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V
HSPLcom/android/internal/util/XmlUtils;->writeSetXml(Ljava/util/Set;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
-HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlSerializer;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/Object;Ljava/lang/String;
+HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlSerializer;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/Float;Ljava/lang/Float;
HSPLcom/android/internal/util/function/pooled/OmniFunction;->run()V
HSPLcom/android/internal/util/function/pooled/PooledLambda;->obtainMessage(Lcom/android/internal/util/function/HexConsumer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
HSPLcom/android/internal/util/function/pooled/PooledLambda;->obtainMessage(Lcom/android/internal/util/function/QuadConsumer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
@@ -22263,6 +22371,7 @@ HSPLcom/android/internal/view/AppearanceRegion;->equals(Ljava/lang/Object;)Z
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->addClient(Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/inputmethod/IRemoteInputConnection;I)V
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getEnabledInputMethodList(I)Ljava/util/List;
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getImeTrackerService()Lcom/android/internal/inputmethod/IImeTracker;
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->isImeTraceEnabled()Z
HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->removeImeSurfaceFromWindowAsync(Landroid/os/IBinder;)V
@@ -22307,7 +22416,7 @@ HSPLcom/android/internal/widget/AlertDialogLayout;->onMeasure(II)V
HSPLcom/android/internal/widget/AlertDialogLayout;->setChildFrame(Landroid/view/View;IIII)V
HSPLcom/android/internal/widget/AlertDialogLayout;->tryOnMeasure(II)Z
HSPLcom/android/internal/widget/BackgroundFallback;-><init>()V
-HSPLcom/android/internal/widget/BackgroundFallback;->draw(Landroid/view/ViewGroup;Landroid/view/ViewGroup;Landroid/graphics/Canvas;Landroid/view/View;Landroid/view/View;Landroid/view/View;)V
+HSPLcom/android/internal/widget/BackgroundFallback;->draw(Landroid/view/ViewGroup;Landroid/view/ViewGroup;Landroid/graphics/Canvas;Landroid/view/View;Landroid/view/View;Landroid/view/View;)V+]Lcom/android/internal/widget/BackgroundFallback;Lcom/android/internal/widget/BackgroundFallback;
HSPLcom/android/internal/widget/BackgroundFallback;->hasFallback()Z
HSPLcom/android/internal/widget/BackgroundFallback;->setDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLcom/android/internal/widget/ButtonBarLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
@@ -22326,6 +22435,7 @@ HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker;->handleStron
HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker;->isNonStrongBiometricAllowedAfterIdleTimeout(I)Z
HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker;->onIsNonStrongBiometricAllowedChanged(I)V
HSPLcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;)V
+HSPLcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;Lcom/android/internal/widget/ILockSettings;)V+]Landroid/content/Context;Landroid/app/ContextImpl;,Landroid/app/ReceiverRestrictedContext;
HSPLcom/android/internal/widget/LockPatternUtils;->credentialTypeToPasswordQuality(I)I
HSPLcom/android/internal/widget/LockPatternUtils;->getBoolean(Ljava/lang/String;ZI)Z
HSPLcom/android/internal/widget/LockPatternUtils;->getCredentialTypeForUser(I)I
@@ -22341,8 +22451,8 @@ HSPLcom/android/internal/widget/LockPatternUtils;->isOwnerInfoEnabled(I)Z
HSPLcom/android/internal/widget/LockPatternUtils;->isSecure(I)Z
HSPLcom/android/internal/widget/LockPatternUtils;->isSeparateProfileChallengeEnabled(I)Z
HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeBoolean(Ljava/lang/String;Ljava/lang/String;)Z+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
-HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeFloat(Ljava/lang/String;Ljava/lang/String;)F+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
-HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndex(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;]Ljava/lang/Object;Ljava/lang/String;
+HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeFloat(Ljava/lang/String;Ljava/lang/String;)F
+HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndex(Ljava/lang/String;Ljava/lang/String;)I+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndexOrThrow(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeInt(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeLong(Ljava/lang/String;Ljava/lang/String;)J+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
@@ -23291,6 +23401,12 @@ HSPLcom/android/telephony/Rlog;->e(Ljava/lang/String;Ljava/lang/String;)I
HSPLcom/android/telephony/Rlog;->log(ILjava/lang/String;Ljava/lang/String;)I
HSPLcom/android/telephony/Rlog;->pii(ZLjava/lang/Object;)Ljava/lang/String;
HSPLcom/android/telephony/Rlog;->w(Ljava/lang/String;Ljava/lang/String;)I
+HSPLcom/android/text/flags/FeatureFlagsImpl;-><init>()V
+HSPLcom/android/text/flags/Flags;-><clinit>()V
+HSPLcom/android/window/flags/FeatureFlagsImpl;-><init>()V
+HSPLcom/android/window/flags/FeatureFlagsImpl;->bundleClientTransactionFlag()Z
+HSPLcom/android/window/flags/Flags;-><clinit>()V
+HSPLcom/android/window/flags/Flags;->bundleClientTransactionFlag()Z+]Lcom/android/window/flags/FeatureFlags;Lcom/android/window/flags/FeatureFlagsImpl;
HSPLcom/google/android/collect/Lists;->newArrayList()Ljava/util/ArrayList;
HSPLcom/google/android/collect/Lists;->newArrayList([Ljava/lang/Object;)Ljava/util/ArrayList;
HSPLcom/google/android/collect/Maps;->newHashMap()Ljava/util/HashMap;
@@ -24968,7 +25084,7 @@ HSPLjava/lang/UNIXProcess;->waitFor()I
HSPLjava/lang/UnsatisfiedLinkError;-><init>(Ljava/lang/String;)V
HSPLjava/lang/UnsupportedOperationException;-><init>()V
HSPLjava/lang/UnsupportedOperationException;-><init>(Ljava/lang/String;)V
-HSPLjava/lang/VMClassLoader;->createBootClassPathUrlHandlers()[Llibcore/io/ClassPathURLStreamHandler;
+HPLjava/lang/VMClassLoader;->createBootClassPathUrlHandlers()[Llibcore/io/ClassPathURLStreamHandler;
HSPLjava/lang/VMClassLoader;->getResource(Ljava/lang/String;)Ljava/net/URL;
HSPLjava/lang/VMClassLoader;->getResources(Ljava/lang/String;)Ljava/util/List;
HSPLjava/lang/invoke/FieldVarHandle;-><init>(Ljava/lang/reflect/Field;Ljava/lang/Class;)V
@@ -25880,7 +25996,7 @@ HSPLjava/nio/ByteBuffer;->order(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;
HSPLjava/nio/ByteBuffer;->position(I)Ljava/nio/Buffer;
HSPLjava/nio/ByteBuffer;->put(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;
HSPLjava/nio/ByteBuffer;->put([B)Ljava/nio/ByteBuffer;
-HSPLjava/nio/ByteBuffer;->putBuffer(ILjava/nio/ByteBuffer;II)V
+HSPLjava/nio/ByteBuffer;->putBuffer(ILjava/nio/ByteBuffer;II)V+]Ljava/nio/ByteBuffer;Ljava/nio/DirectByteBuffer;,Ljava/nio/HeapByteBuffer;
HSPLjava/nio/ByteBuffer;->reset()Ljava/nio/Buffer;
HSPLjava/nio/ByteBuffer;->rewind()Ljava/nio/Buffer;
HSPLjava/nio/ByteBuffer;->wrap([B)Ljava/nio/ByteBuffer;
@@ -26888,12 +27004,12 @@ HSPLjava/time/ZonedDateTime;->toLocalTime()Ljava/time/LocalTime;
HSPLjava/time/chrono/AbstractChronology;->equals(Ljava/lang/Object;)Z
HSPLjava/time/chrono/AbstractChronology;->resolveDate(Ljava/util/Map;Ljava/time/format/ResolverStyle;)Ljava/time/chrono/ChronoLocalDate;
HSPLjava/time/chrono/ChronoLocalDate;->isSupported(Ljava/time/temporal/TemporalField;)Z
-HSPLjava/time/chrono/ChronoLocalDateTime;->getChronology()Ljava/time/chrono/Chronology;+]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;]Ljava/time/chrono/ChronoLocalDateTime;Ljava/time/LocalDateTime;
+HSPLjava/time/chrono/ChronoLocalDateTime;->getChronology()Ljava/time/chrono/Chronology;
HSPLjava/time/chrono/ChronoLocalDateTime;->query(Ljava/time/temporal/TemporalQuery;)Ljava/lang/Object;
-HSPLjava/time/chrono/ChronoLocalDateTime;->toEpochSecond(Ljava/time/ZoneOffset;)J+]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;]Ljava/time/chrono/ChronoLocalDateTime;Ljava/time/LocalDateTime;
-HSPLjava/time/chrono/ChronoZonedDateTime;->getChronology()Ljava/time/chrono/Chronology;+]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;]Ljava/time/chrono/ChronoZonedDateTime;Ljava/time/ZonedDateTime;
+HSPLjava/time/chrono/ChronoLocalDateTime;->toEpochSecond(Ljava/time/ZoneOffset;)J+]Ljava/time/chrono/ChronoLocalDateTime;Ljava/time/LocalDateTime;]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;
+HSPLjava/time/chrono/ChronoZonedDateTime;->getChronology()Ljava/time/chrono/Chronology;+]Ljava/time/chrono/ChronoZonedDateTime;Ljava/time/ZonedDateTime;]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;
HSPLjava/time/chrono/ChronoZonedDateTime;->query(Ljava/time/temporal/TemporalQuery;)Ljava/lang/Object;
-HSPLjava/time/chrono/ChronoZonedDateTime;->toEpochSecond()J+]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;]Ljava/time/chrono/ChronoZonedDateTime;Ljava/time/ZonedDateTime;
+HSPLjava/time/chrono/ChronoZonedDateTime;->toEpochSecond()J+]Ljava/time/chrono/ChronoZonedDateTime;Ljava/time/ZonedDateTime;]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;
HSPLjava/time/chrono/ChronoZonedDateTime;->toInstant()Ljava/time/Instant;+]Ljava/time/chrono/ChronoZonedDateTime;Ljava/time/ZonedDateTime;
HSPLjava/time/chrono/IsoChronology;->isLeapYear(J)Z
HSPLjava/time/chrono/IsoChronology;->resolveDate(Ljava/util/Map;Ljava/time/format/ResolverStyle;)Ljava/time/LocalDate;
@@ -27302,7 +27418,7 @@ HSPLjava/util/Arrays$ArrayList;->sort(Ljava/util/Comparator;)V
HSPLjava/util/Arrays$ArrayList;->spliterator()Ljava/util/Spliterator;
HSPLjava/util/Arrays$ArrayList;->toArray()[Ljava/lang/Object;
HSPLjava/util/Arrays$ArrayList;->toArray([Ljava/lang/Object;)[Ljava/lang/Object;
-HSPLjava/util/Arrays$ArrayList;->toArrayPreserveComponentType()[Ljava/lang/Object;
+HSPLjava/util/Arrays$ArrayList;->toArrayPreserveComponentType()[Ljava/lang/Object;+][Ljava/lang/Object;missing_types
HSPLjava/util/Arrays;->asList([Ljava/lang/Object;)Ljava/util/List;
HSPLjava/util/Arrays;->binarySearch([CC)I
HSPLjava/util/Arrays;->binarySearch([II)I
@@ -27464,7 +27580,7 @@ HSPLjava/util/Calendar;->setTimeZone(Ljava/util/TimeZone;)V
HSPLjava/util/Calendar;->setWeekCountData(Ljava/util/Locale;)V
HSPLjava/util/Calendar;->setZoneShared(Z)V
HSPLjava/util/Calendar;->updateTime()V
-HSPLjava/util/Collection;->removeIf(Ljava/util/function/Predicate;)Z+]Ljava/util/Collection;megamorphic_types]Ljava/util/Iterator;megamorphic_types]Ljava/util/function/Predicate;Lcom/android/internal/telephony/data/DataNetworkController$$ExternalSyntheticLambda32;,Lcom/android/internal/telephony/data/DataNetworkController$$ExternalSyntheticLambda43;
+HSPLjava/util/Collection;->removeIf(Ljava/util/function/Predicate;)Z+]Ljava/util/Collection;Landroid/util/MapCollections$ValuesCollection;,Landroid/util/MapCollections$EntrySet;,Ljava/util/LinkedHashMap$LinkedEntrySet;,Ljava/util/LinkedList;,Landroid/util/MapCollections$KeySet;,Ljava/util/HashSet;,Ljava/util/LinkedHashMap$LinkedValues;,Ljava/util/LinkedHashSet;,Ljava/util/HashMap$EntrySet;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;,Landroid/util/MapCollections$MapIterator;,Ljava/util/LinkedList$ListItr;,Ljava/util/LinkedHashMap$LinkedEntryIterator;,Ljava/util/HashMap$KeyIterator;,Ljava/util/LinkedHashMap$LinkedValueIterator;,Ljava/util/LinkedHashMap$LinkedKeyIterator;,Ljava/util/HashMap$EntryIterator;
HSPLjava/util/Collection;->spliterator()Ljava/util/Spliterator;
HSPLjava/util/Collection;->stream()Ljava/util/stream/Stream;+]Ljava/util/Collection;megamorphic_types
HSPLjava/util/Collections$1;-><init>(Ljava/lang/Object;)V
@@ -27652,7 +27768,7 @@ HSPLjava/util/Collections;->rotate(Ljava/util/List;I)V
HSPLjava/util/Collections;->rotate1(Ljava/util/List;I)V
HSPLjava/util/Collections;->shuffle(Ljava/util/List;)V
HSPLjava/util/Collections;->shuffle(Ljava/util/List;Ljava/util/Random;)V
-HSPLjava/util/Collections;->shuffle(Ljava/util/List;Ljava/util/random/RandomGenerator;)V
+HSPLjava/util/Collections;->shuffle(Ljava/util/List;Ljava/util/random/RandomGenerator;)V+]Ljava/util/random/RandomGenerator;Ljava/util/Random;]Ljava/util/List;missing_types
HSPLjava/util/Collections;->singleton(Ljava/lang/Object;)Ljava/util/Set;
HSPLjava/util/Collections;->singletonIterator(Ljava/lang/Object;)Ljava/util/Iterator;
HSPLjava/util/Collections;->singletonList(Ljava/lang/Object;)Ljava/util/List;
@@ -27824,7 +27940,7 @@ HSPLjava/util/Formatter$Flags;->valueOf()I
HSPLjava/util/Formatter$FormatSpecifier;-><init>(Ljava/util/Formatter;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
HSPLjava/util/Formatter$FormatSpecifier;->addZeros(Ljava/lang/StringBuilder;I)V
HSPLjava/util/Formatter$FormatSpecifier;->adjustWidth(ILjava/util/Formatter$Flags;Z)I
-HSPLjava/util/Formatter$FormatSpecifier;->appendJustified(Ljava/lang/Appendable;Ljava/lang/CharSequence;)V
+HSPLjava/util/Formatter$FormatSpecifier;->appendJustified(Ljava/lang/Appendable;Ljava/lang/CharSequence;)V+]Ljava/util/Formatter$Flags;Ljava/util/Formatter$Flags;]Ljava/lang/CharSequence;Ljava/lang/String;,Ljava/lang/StringBuilder;]Ljava/lang/Appendable;megamorphic_types
HSPLjava/util/Formatter$FormatSpecifier;->checkBadFlags([Ljava/util/Formatter$Flags;)V
HSPLjava/util/Formatter$FormatSpecifier;->checkCharacter()V
HSPLjava/util/Formatter$FormatSpecifier;->checkDateTime()V
@@ -27887,7 +28003,7 @@ HSPLjava/util/Formatter;->nonNullAppendable(Ljava/lang/Appendable;)Ljava/lang/Ap
HSPLjava/util/Formatter;->out()Ljava/lang/Appendable;
HSPLjava/util/Formatter;->parse(Ljava/lang/String;)Ljava/util/List;
HSPLjava/util/Formatter;->toString()Ljava/lang/String;
-HSPLjava/util/Formatter;->zero()C
+HSPLjava/util/Formatter;->zero()C+]Llibcore/icu/DecimalFormatData;Llibcore/icu/DecimalFormatData;
HSPLjava/util/GregorianCalendar;-><init>()V
HSPLjava/util/GregorianCalendar;-><init>(IIIIII)V
HSPLjava/util/GregorianCalendar;-><init>(IIIIIII)V
@@ -28043,8 +28159,8 @@ HSPLjava/util/HashSet;->readObject(Ljava/io/ObjectInputStream;)V
HSPLjava/util/HashSet;->remove(Ljava/lang/Object;)Z
HSPLjava/util/HashSet;->size()I
HSPLjava/util/HashSet;->spliterator()Ljava/util/Spliterator;
-HSPLjava/util/HashSet;->toArray()[Ljava/lang/Object;
-HSPLjava/util/HashSet;->toArray([Ljava/lang/Object;)[Ljava/lang/Object;
+HSPLjava/util/HashSet;->toArray()[Ljava/lang/Object;+]Ljava/util/HashMap;Ljava/util/HashMap;,Ljava/util/LinkedHashMap;
+HSPLjava/util/HashSet;->toArray([Ljava/lang/Object;)[Ljava/lang/Object;+]Ljava/util/HashMap;Ljava/util/HashMap;,Ljava/util/LinkedHashMap;
HSPLjava/util/HashSet;->writeObject(Ljava/io/ObjectOutputStream;)V
HSPLjava/util/Hashtable$EntrySet;-><init>(Ljava/util/Hashtable;)V
HSPLjava/util/Hashtable$EntrySet;->iterator()Ljava/util/Iterator;
@@ -28068,7 +28184,6 @@ HSPLjava/util/Hashtable;->-$$Nest$fgettable(Ljava/util/Hashtable;)[Ljava/util/Ha
HSPLjava/util/Hashtable;-><init>()V
HSPLjava/util/Hashtable;-><init>(I)V
HSPLjava/util/Hashtable;-><init>(IF)V
-HSPLjava/util/Hashtable;-><init>(Ljava/lang/Void;)V
HSPLjava/util/Hashtable;->addEntry(ILjava/lang/Object;Ljava/lang/Object;I)V
HSPLjava/util/Hashtable;->clear()V
HSPLjava/util/Hashtable;->clone()Ljava/lang/Object;
@@ -28154,14 +28269,13 @@ HSPLjava/util/ImmutableCollections$MapN;-><init>([Ljava/lang/Object;)V
HSPLjava/util/ImmutableCollections$MapN;->containsKey(Ljava/lang/Object;)Z
HSPLjava/util/ImmutableCollections$MapN;->get(Ljava/lang/Object;)Ljava/lang/Object;
HSPLjava/util/ImmutableCollections$MapN;->probe(Ljava/lang/Object;)I
-HSPLjava/util/ImmutableCollections$Set12;-><init>(Ljava/lang/Object;Ljava/lang/Object;)V+]Ljava/lang/Object;missing_types
HSPLjava/util/ImmutableCollections$SetN;-><init>([Ljava/lang/Object;)V
HSPLjava/util/ImmutableCollections$SetN;->contains(Ljava/lang/Object;)Z
HSPLjava/util/ImmutableCollections$SetN;->probe(Ljava/lang/Object;)I
HSPLjava/util/ImmutableCollections;-><clinit>()V
HSPLjava/util/ImmutableCollections;->listCopy(Ljava/util/Collection;)Ljava/util/List;
HSPLjava/util/ImmutableCollections;->listFromTrustedArray([Ljava/lang/Object;)Ljava/util/List;
-HSPLjava/util/Iterator;->forEachRemaining(Ljava/util/function/Consumer;)V+]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;,Landroid/util/MapCollections$MapIterator;,Ljava/util/AbstractList$Itr;,Ljava/util/AbstractMap$2$1;]Ljava/util/function/Consumer;megamorphic_types
+HSPLjava/util/Iterator;->forEachRemaining(Ljava/util/function/Consumer;)V+]Ljava/util/function/Consumer;megamorphic_types]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;,Ljava/util/AbstractMap$2$1;,Ljava/util/AbstractList$Itr;,Ljava/util/LinkedHashMap$LinkedValueIterator;
HSPLjava/util/JumboEnumSet$EnumSetIterator;-><init>(Ljava/util/JumboEnumSet;)V
HSPLjava/util/JumboEnumSet$EnumSetIterator;->hasNext()Z
HSPLjava/util/JumboEnumSet$EnumSetIterator;->next()Ljava/lang/Enum;
@@ -28289,7 +28403,7 @@ HSPLjava/util/List;->of(Ljava/lang/Object;)Ljava/util/List;
HSPLjava/util/List;->of(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List;
HSPLjava/util/List;->of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List;
HSPLjava/util/List;->of([Ljava/lang/Object;)Ljava/util/List;
-HSPLjava/util/List;->sort(Ljava/util/Comparator;)V+]Ljava/util/List;Ljava/util/ArrayList$SubList;,Ljava/util/LinkedList;]Ljava/util/ListIterator;Ljava/util/ArrayList$SubList$1;,Ljava/util/LinkedList$ListItr;
+HSPLjava/util/List;->sort(Ljava/util/Comparator;)V+]Ljava/util/ListIterator;Ljava/util/ArrayList$SubList$1;,Ljava/util/LinkedList$ListItr;]Ljava/util/List;Ljava/util/ArrayList$SubList;,Ljava/util/LinkedList;
HSPLjava/util/List;->spliterator()Ljava/util/Spliterator;
HSPLjava/util/Locale$Builder;-><init>()V
HSPLjava/util/Locale$Builder;->build()Ljava/util/Locale;
@@ -28350,7 +28464,7 @@ HSPLjava/util/Locale;->toString()Ljava/lang/String;
HSPLjava/util/Locale;->writeObject(Ljava/io/ObjectOutputStream;)V
HSPLjava/util/Map;->computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;+]Ljava/util/Map;Landroid/util/ArrayMap;]Ljava/util/function/Function;missing_types
HSPLjava/util/Map;->entry(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/Map$Entry;
-HSPLjava/util/Map;->forEach(Ljava/util/function/BiConsumer;)V
+HSPLjava/util/Map;->forEach(Ljava/util/function/BiConsumer;)V+]Ljava/util/Map$Entry;Ljava/util/KeyValueHolder;]Ljava/util/Map;Ljava/util/ImmutableCollections$MapN;]Ljava/util/Iterator;Ljava/util/ImmutableCollections$MapN$MapNIterator;]Ljava/util/Set;Ljava/util/ImmutableCollections$MapN$1;
HSPLjava/util/Map;->getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/Map;Landroid/util/ArrayMap;
HSPLjava/util/Map;->of(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/Map;
HSPLjava/util/Map;->ofEntries([Ljava/util/Map$Entry;)Ljava/util/Map;
@@ -28548,7 +28662,7 @@ HSPLjava/util/SimpleTimeZone;->getOffset(J)I
HSPLjava/util/SimpleTimeZone;->getOffsets(J[I)I
HSPLjava/util/SimpleTimeZone;->getRawOffset()I
HSPLjava/util/SimpleTimeZone;->hasSameRules(Ljava/util/TimeZone;)Z
-HSPLjava/util/Spliterator$OfInt;->forEachRemaining(Ljava/util/function/Consumer;)V+]Ljava/util/Spliterator$OfInt;Ljava/lang/StringUTF16$CodePointsSpliteratorForString;,Ljava/util/Spliterators$EmptySpliterator$OfInt;,Ljava/util/Spliterators$IntArraySpliterator;,Ljava/util/stream/Streams$RangeIntSpliterator;
+HSPLjava/util/Spliterator$OfInt;->forEachRemaining(Ljava/util/function/Consumer;)V+]Ljava/util/Spliterator$OfInt;Ljava/util/Spliterators$IntArraySpliterator;,Ljava/util/Spliterators$EmptySpliterator$OfInt;,Ljava/util/stream/Streams$RangeIntSpliterator;,Ljava/lang/StringUTF16$CodePointsSpliteratorForString;
HSPLjava/util/Spliterator;->getExactSizeIfKnown()J+]Ljava/util/Spliterator;megamorphic_types
HSPLjava/util/Spliterators$ArraySpliterator;-><init>([Ljava/lang/Object;I)V
HSPLjava/util/Spliterators$ArraySpliterator;-><init>([Ljava/lang/Object;III)V
@@ -29941,7 +30055,7 @@ HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda20;->accept(Ljava/lang/O
HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda25;-><init>()V
HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda25;->get()Ljava/lang/Object;
HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda26;-><init>()V
-HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda26;->accept(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda26;->accept(Ljava/lang/Object;Ljava/lang/Object;)V+]Ljava/util/List;Ljava/util/ArrayList;
HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda27;-><init>()V
HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda28;-><init>()V
HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda28;->apply(Ljava/lang/Object;)Ljava/lang/Object;
@@ -29968,7 +30082,7 @@ HSPLjava/util/stream/Collectors;->groupingBy(Ljava/util/function/Function;Ljava/
HSPLjava/util/stream/Collectors;->joining(Ljava/lang/CharSequence;)Ljava/util/stream/Collector;
HSPLjava/util/stream/Collectors;->joining(Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/util/stream/Collector;
HSPLjava/util/stream/Collectors;->lambda$joining$11(Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/util/StringJoiner;
-HSPLjava/util/stream/Collectors;->lambda$toUnmodifiableList$6(Ljava/util/ArrayList;)Ljava/util/List;
+HSPLjava/util/stream/Collectors;->lambda$toUnmodifiableList$6(Ljava/util/ArrayList;)Ljava/util/List;+]Ljdk/internal/access/JavaUtilCollectionAccess;Ljava/util/ImmutableCollections$Access$1;
HSPLjava/util/stream/Collectors;->lambda$uniqKeysMapAccumulator$1(Ljava/util/function/Function;Ljava/util/function/Function;Ljava/util/Map;Ljava/lang/Object;)V
HSPLjava/util/stream/Collectors;->mapMerger(Ljava/util/function/BinaryOperator;)Ljava/util/function/BinaryOperator;
HSPLjava/util/stream/Collectors;->toCollection(Ljava/util/function/Supplier;)Ljava/util/stream/Collector;
@@ -30012,7 +30126,7 @@ HSPLjava/util/stream/IntPipeline$$ExternalSyntheticLambda12;->apply(I)Ljava/lang
HSPLjava/util/stream/IntPipeline$$ExternalSyntheticLambda7;-><init>()V
HSPLjava/util/stream/IntPipeline$$ExternalSyntheticLambda8;-><init>()V
HSPLjava/util/stream/IntPipeline$1$1;-><init>(Ljava/util/stream/IntPipeline$1;Ljava/util/stream/Sink;)V
-HSPLjava/util/stream/IntPipeline$1$1;->accept(I)V
+HSPLjava/util/stream/IntPipeline$1$1;->accept(I)V+]Ljava/util/function/IntFunction;megamorphic_types]Ljava/util/stream/Sink;megamorphic_types
HSPLjava/util/stream/IntPipeline$1;-><init>(Ljava/util/stream/IntPipeline;Ljava/util/stream/AbstractPipeline;Ljava/util/stream/StreamShape;ILjava/util/function/IntFunction;)V
HSPLjava/util/stream/IntPipeline$1;->opWrapSink(ILjava/util/stream/Sink;)Ljava/util/stream/Sink;
HSPLjava/util/stream/IntPipeline$4$1;-><init>(Ljava/util/stream/IntPipeline$4;Ljava/util/stream/Sink;)V
@@ -30141,7 +30255,7 @@ HSPLjava/util/stream/ReduceOps;->makeLong(JLjava/util/function/LongBinaryOperato
HSPLjava/util/stream/ReduceOps;->makeRef(Ljava/util/function/BinaryOperator;)Ljava/util/stream/TerminalOp;
HSPLjava/util/stream/ReduceOps;->makeRef(Ljava/util/stream/Collector;)Ljava/util/stream/TerminalOp;
HSPLjava/util/stream/ReferencePipeline$15$1;-><init>(Ljava/util/stream/ReferencePipeline$15;Ljava/util/stream/Sink;)V
-HSPLjava/util/stream/ReferencePipeline$15$1;->accept(Ljava/lang/Object;)V
+HSPLjava/util/stream/ReferencePipeline$15$1;->accept(Ljava/lang/Object;)V+]Ljava/util/stream/Sink;Ljava/util/stream/ReduceOps$3ReducingSink;]Ljava/util/function/Consumer;Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;
HSPLjava/util/stream/ReferencePipeline$15;-><init>(Ljava/util/stream/ReferencePipeline;Ljava/util/stream/AbstractPipeline;Ljava/util/stream/StreamShape;ILjava/util/function/Consumer;)V
HSPLjava/util/stream/ReferencePipeline$15;->opWrapSink(ILjava/util/stream/Sink;)Ljava/util/stream/Sink;
HSPLjava/util/stream/ReferencePipeline$2$1;-><init>(Ljava/util/stream/ReferencePipeline$2;Ljava/util/stream/Sink;)V
@@ -30272,7 +30386,7 @@ HSPLjava/util/zip/CheckedInputStream;->read([BII)I
HSPLjava/util/zip/Deflater$DeflaterZStreamRef;-><init>(Ljava/util/zip/Deflater;J)V
HSPLjava/util/zip/Deflater$DeflaterZStreamRef;-><init>(Ljava/util/zip/Deflater;JLjava/util/zip/Deflater$DeflaterZStreamRef-IA;)V
HSPLjava/util/zip/Deflater$DeflaterZStreamRef;->address()J
-HSPLjava/util/zip/Deflater$DeflaterZStreamRef;->clean()V
+HSPLjava/util/zip/Deflater$DeflaterZStreamRef;->clean()V+]Ljava/lang/ref/Cleaner$Cleanable;Ljdk/internal/ref/CleanerImpl$PhantomCleanableRef;
HSPLjava/util/zip/Deflater$DeflaterZStreamRef;->run()V
HSPLjava/util/zip/Deflater;->-$$Nest$smend(J)V
HSPLjava/util/zip/Deflater;-><init>()V
@@ -30319,7 +30433,7 @@ HSPLjava/util/zip/GZIPOutputStream;->writeInt(I[BI)V
HSPLjava/util/zip/GZIPOutputStream;->writeShort(I[BI)V
HSPLjava/util/zip/GZIPOutputStream;->writeTrailer([BI)V
HSPLjava/util/zip/Inflater$InflaterZStreamRef;->address()J
-HSPLjava/util/zip/Inflater$InflaterZStreamRef;->clean()V
+HSPLjava/util/zip/Inflater$InflaterZStreamRef;->clean()V+]Ljava/lang/ref/Cleaner$Cleanable;Ljdk/internal/ref/CleanerImpl$PhantomCleanableRef;
HSPLjava/util/zip/Inflater$InflaterZStreamRef;->run()V
HSPLjava/util/zip/Inflater;->-$$Nest$smend(J)V
HSPLjava/util/zip/Inflater;-><init>()V
@@ -30367,15 +30481,15 @@ HSPLjava/util/zip/ZipEntry;->getSize()J
HSPLjava/util/zip/ZipEntry;->isDirectory()Z
HSPLjava/util/zip/ZipEntry;->setExtra0([BZZ)V
HSPLjava/util/zip/ZipFile$CleanableResource;-><init>(Ljava/util/zip/ZipFile;Ljava/util/zip/ZipCoder;Ljava/io/File;IZ)V
-HSPLjava/util/zip/ZipFile$CleanableResource;->clean()V
-HSPLjava/util/zip/ZipFile$CleanableResource;->getInflater()Ljava/util/zip/Inflater;
-HSPLjava/util/zip/ZipFile$CleanableResource;->releaseInflater(Ljava/util/zip/Inflater;)V
-HSPLjava/util/zip/ZipFile$CleanableResource;->run()V
-HSPLjava/util/zip/ZipFile$InflaterCleanupAction;->run()V
+HSPLjava/util/zip/ZipFile$CleanableResource;->clean()V+]Ljava/lang/ref/Cleaner$Cleanable;Ljdk/internal/ref/CleanerImpl$PhantomCleanableRef;
+HSPLjava/util/zip/ZipFile$CleanableResource;->getInflater()Ljava/util/zip/Inflater;+]Ljava/util/Deque;Ljava/util/ArrayDeque;
+HSPLjava/util/zip/ZipFile$CleanableResource;->releaseInflater(Ljava/util/zip/Inflater;)V+]Ljava/util/Deque;Ljava/util/ArrayDeque;]Ljava/util/zip/Inflater;Ljava/util/zip/Inflater;
+HSPLjava/util/zip/ZipFile$CleanableResource;->run()V+]Ljava/util/Deque;Ljava/util/ArrayDeque;]Ljava/util/Set;Ljava/util/Collections$SetFromMap;]Ljava/util/zip/Inflater;Ljava/util/zip/Inflater;
+HSPLjava/util/zip/ZipFile$InflaterCleanupAction;->run()V+]Ljava/util/zip/ZipFile$CleanableResource;Ljava/util/zip/ZipFile$CleanableResource;
HSPLjava/util/zip/ZipFile$Source$End;-><init>()V
HSPLjava/util/zip/ZipFile$Source$End;-><init>(Ljava/util/zip/ZipFile$Source$End-IA;)V
HSPLjava/util/zip/ZipFile$Source$Key;-><init>(Ljava/io/File;Ljava/nio/file/attribute/BasicFileAttributes;Ljava/util/zip/ZipCoder;Z)V
-HSPLjava/util/zip/ZipFile$Source$Key;->equals(Ljava/lang/Object;)Z
+HSPLjava/util/zip/ZipFile$Source$Key;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Lsun/nio/fs/UnixFileKey;]Ljava/nio/file/attribute/BasicFileAttributes;Lsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;
HSPLjava/util/zip/ZipFile$Source$Key;->hashCode()I
HSPLjava/util/zip/ZipFile$Source;->-$$Nest$fgetlocpos(Ljava/util/zip/ZipFile$Source;)J
HSPLjava/util/zip/ZipFile$Source;->-$$Nest$mgetEntryPos(Ljava/util/zip/ZipFile$Source;Ljava/lang/String;Z)I
@@ -30383,7 +30497,7 @@ HSPLjava/util/zip/ZipFile$Source;->-$$Nest$mreadAt(Ljava/util/zip/ZipFile$Source
HSPLjava/util/zip/ZipFile$Source;->-$$Nest$mreadFullyAt(Ljava/util/zip/ZipFile$Source;[BIIJ)I
HSPLjava/util/zip/ZipFile$Source;-><init>(Ljava/util/zip/ZipFile$Source$Key;ZLjava/util/zip/ZipCoder;)V
HSPLjava/util/zip/ZipFile$Source;->checkAndAddEntry(II)I
-HSPLjava/util/zip/ZipFile$Source;->close()V
+HSPLjava/util/zip/ZipFile$Source;->close()V+]Ljava/io/RandomAccessFile;Ljava/io/RandomAccessFile;
HSPLjava/util/zip/ZipFile$Source;->findEND()Ljava/util/zip/ZipFile$Source$End;
HSPLjava/util/zip/ZipFile$Source;->get(Ljava/io/File;ZLjava/util/zip/ZipCoder;Z)Ljava/util/zip/ZipFile$Source;
HSPLjava/util/zip/ZipFile$Source;->getEntryPos(Ljava/lang/String;Z)I
@@ -30393,9 +30507,9 @@ HSPLjava/util/zip/ZipFile$Source;->isManifestName(II)Z
HSPLjava/util/zip/ZipFile$Source;->isMetaName([BII)Z
HSPLjava/util/zip/ZipFile$Source;->isSignatureRelated(II)Z
HSPLjava/util/zip/ZipFile$Source;->nextEntryPos(III)I
-HSPLjava/util/zip/ZipFile$Source;->readAt([BIIJ)I
+HSPLjava/util/zip/ZipFile$Source;->readAt([BIIJ)I+]Ljava/io/RandomAccessFile;Ljava/io/RandomAccessFile;
HSPLjava/util/zip/ZipFile$Source;->readFullyAt([BIIJ)I
-HSPLjava/util/zip/ZipFile$Source;->release(Ljava/util/zip/ZipFile$Source;)V
+HSPLjava/util/zip/ZipFile$Source;->release(Ljava/util/zip/ZipFile$Source;)V+]Ljava/util/HashMap;Ljava/util/HashMap;
HSPLjava/util/zip/ZipFile$Source;->zipCoderForPos(I)Ljava/util/zip/ZipCoder;
HSPLjava/util/zip/ZipFile$ZipEntryIterator;->hasMoreElements()Z
HSPLjava/util/zip/ZipFile$ZipEntryIterator;->hasNext()Z
@@ -30770,10 +30884,10 @@ HSPLjdk/internal/misc/Unsafe;->weakCompareAndSetReference(Ljava/lang/Object;JLja
HSPLjdk/internal/misc/VM;->getSavedProperty(Ljava/lang/String;)Ljava/lang/String;
HSPLjdk/internal/ref/CleanerFactory;->cleaner()Ljava/lang/ref/Cleaner;
HSPLjdk/internal/ref/CleanerImpl$PhantomCleanableRef;-><init>(Ljava/lang/Object;Ljava/lang/ref/Cleaner;Ljava/lang/Runnable;)V
-HSPLjdk/internal/ref/CleanerImpl$PhantomCleanableRef;->performCleanup()V
+HSPLjdk/internal/ref/CleanerImpl$PhantomCleanableRef;->performCleanup()V+]Ljava/lang/Runnable;megamorphic_types
HSPLjdk/internal/ref/CleanerImpl;->getCleanerImpl(Ljava/lang/ref/Cleaner;)Ljdk/internal/ref/CleanerImpl;
HSPLjdk/internal/ref/PhantomCleanable;-><init>(Ljava/lang/Object;Ljava/lang/ref/Cleaner;)V
-HSPLjdk/internal/ref/PhantomCleanable;->clean()V
+HSPLjdk/internal/ref/PhantomCleanable;->clean()V+]Ljdk/internal/ref/PhantomCleanable;Ljdk/internal/ref/CleanerImpl$PhantomCleanableRef;
HSPLjdk/internal/ref/PhantomCleanable;->insert()V
HSPLjdk/internal/ref/PhantomCleanable;->remove()Z
HSPLjdk/internal/reflect/Reflection;->getCallerClass()Ljava/lang/Class;
@@ -30832,6 +30946,7 @@ HSPLlibcore/icu/ICU;->localeFromIcuLocaleId(Ljava/lang/String;)Ljava/util/Locale
HSPLlibcore/icu/ICU;->localesFromStrings([Ljava/lang/String;)[Ljava/util/Locale;
HSPLlibcore/icu/ICU;->parseLangScriptRegionAndVariants(Ljava/lang/String;[Ljava/lang/String;)V
HSPLlibcore/icu/ICU;->setDefaultLocale(Ljava/lang/String;)V
+HSPLlibcore/icu/ICU;->transformIcuDateTimePattern(Ljava/lang/String;)Ljava/lang/String;
HSPLlibcore/icu/ICU;->transformIcuDateTimePattern_forJavaText(Ljava/lang/String;)Ljava/lang/String;
HSPLlibcore/icu/LocaleData;->get(Ljava/util/Locale;)Llibcore/icu/LocaleData;
HSPLlibcore/icu/LocaleData;->getCompatibleLocaleForBug159514442(Ljava/util/Locale;)Ljava/util/Locale;
@@ -31122,7 +31237,6 @@ HSPLlibcore/util/NativeAllocationRegistry;->registerNativeFree(J)V
HSPLlibcore/util/SneakyThrow;->sneakyThrow(Ljava/lang/Throwable;)V
HSPLlibcore/util/SneakyThrow;->sneakyThrow_(Ljava/lang/Throwable;)V
HSPLlibcore/util/XmlObjectFactory;->newXmlPullParser()Lorg/xmlpull/v1/XmlPullParser;
-HSPLlibcore/util/ZoneInfo;-><clinit>()V
HSPLlibcore/util/ZoneInfo;-><init>(Lcom/android/i18n/timezone/ZoneInfoData;IZ)V
HSPLlibcore/util/ZoneInfo;->clone()Ljava/lang/Object;
HSPLlibcore/util/ZoneInfo;->createZoneInfo(Lcom/android/i18n/timezone/ZoneInfoData;)Llibcore/util/ZoneInfo;
@@ -31228,8 +31342,8 @@ HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->getURI(I)Ljava/lang/String;
HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->getValue(I)Ljava/lang/String;
HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->getValue(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->removeAttribute(I)V
-HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->setAttributes(Lorg/xml/sax/Attributes;)V+]Lorg/ccil/cowan/tagsoup/AttributesImpl;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;
-HSPLorg/ccil/cowan/tagsoup/Element;-><init>(Lorg/ccil/cowan/tagsoup/ElementType;Z)V+]Lorg/ccil/cowan/tagsoup/ElementType;Lorg/ccil/cowan/tagsoup/ElementType;
+HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->setAttributes(Lorg/xml/sax/Attributes;)V
+HSPLorg/ccil/cowan/tagsoup/Element;-><init>(Lorg/ccil/cowan/tagsoup/ElementType;Z)V
HSPLorg/ccil/cowan/tagsoup/Element;->atts()Lorg/ccil/cowan/tagsoup/AttributesImpl;
HSPLorg/ccil/cowan/tagsoup/Element;->canContain(Lorg/ccil/cowan/tagsoup/Element;)Z
HSPLorg/ccil/cowan/tagsoup/Element;->clean()V
@@ -31258,10 +31372,10 @@ HSPLorg/ccil/cowan/tagsoup/HTMLScanner;-><init>()V
HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->mark()V
HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->resetDocumentLocator(Ljava/lang/String;Ljava/lang/String;)V
HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->save(ILorg/ccil/cowan/tagsoup/ScanHandler;)V
-HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->scan(Ljava/io/Reader;Lorg/ccil/cowan/tagsoup/ScanHandler;)V+]Ljava/io/PushbackReader;Ljava/io/PushbackReader;]Lorg/ccil/cowan/tagsoup/ScanHandler;Lorg/ccil/cowan/tagsoup/Parser;
+HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->scan(Ljava/io/Reader;Lorg/ccil/cowan/tagsoup/ScanHandler;)V
HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->unread(Ljava/io/PushbackReader;I)V
HSPLorg/ccil/cowan/tagsoup/Parser$1;-><init>(Lorg/ccil/cowan/tagsoup/Parser;)V
-HSPLorg/ccil/cowan/tagsoup/Parser;-><init>()V+]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLorg/ccil/cowan/tagsoup/Parser;-><init>()V
HSPLorg/ccil/cowan/tagsoup/Parser;->aname([CII)V
HSPLorg/ccil/cowan/tagsoup/Parser;->aval([CII)V
HSPLorg/ccil/cowan/tagsoup/Parser;->entity([CII)V
@@ -31276,16 +31390,16 @@ HSPLorg/ccil/cowan/tagsoup/Parser;->getReader(Lorg/xml/sax/InputSource;)Ljava/io
HSPLorg/ccil/cowan/tagsoup/Parser;->gi([CII)V
HSPLorg/ccil/cowan/tagsoup/Parser;->lookupEntity([CII)I
HSPLorg/ccil/cowan/tagsoup/Parser;->makeName([CII)Ljava/lang/String;
-HSPLorg/ccil/cowan/tagsoup/Parser;->parse(Lorg/xml/sax/InputSource;)V+]Ljava/lang/Object;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Scanner;Lorg/ccil/cowan/tagsoup/HTMLScanner;]Lorg/ccil/cowan/tagsoup/Schema;Lorg/ccil/cowan/tagsoup/HTMLSchema;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;]Lorg/xml/sax/InputSource;Lorg/xml/sax/InputSource;
+HSPLorg/ccil/cowan/tagsoup/Parser;->parse(Lorg/xml/sax/InputSource;)V
HSPLorg/ccil/cowan/tagsoup/Parser;->pcdata([CII)V
-HSPLorg/ccil/cowan/tagsoup/Parser;->pop()V+]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;
+HSPLorg/ccil/cowan/tagsoup/Parser;->pop()V
HSPLorg/ccil/cowan/tagsoup/Parser;->prefixOf(Ljava/lang/String;)Ljava/lang/String;
-HSPLorg/ccil/cowan/tagsoup/Parser;->push(Lorg/ccil/cowan/tagsoup/Element;)V+]Ljava/lang/String;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;
-HSPLorg/ccil/cowan/tagsoup/Parser;->rectify(Lorg/ccil/cowan/tagsoup/Element;)V+]Ljava/lang/Object;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;
+HSPLorg/ccil/cowan/tagsoup/Parser;->push(Lorg/ccil/cowan/tagsoup/Element;)V
+HSPLorg/ccil/cowan/tagsoup/Parser;->rectify(Lorg/ccil/cowan/tagsoup/Element;)V
HSPLorg/ccil/cowan/tagsoup/Parser;->restart(Lorg/ccil/cowan/tagsoup/Element;)V
HSPLorg/ccil/cowan/tagsoup/Parser;->setContentHandler(Lorg/xml/sax/ContentHandler;)V
HSPLorg/ccil/cowan/tagsoup/Parser;->setProperty(Ljava/lang/String;Ljava/lang/Object;)V
-HSPLorg/ccil/cowan/tagsoup/Parser;->setup()V+]Lorg/ccil/cowan/tagsoup/Schema;Lorg/ccil/cowan/tagsoup/HTMLSchema;
+HSPLorg/ccil/cowan/tagsoup/Parser;->setup()V
HSPLorg/ccil/cowan/tagsoup/Parser;->stagc([CII)V
HSPLorg/ccil/cowan/tagsoup/Parser;->truthValue(Z)Ljava/lang/Boolean;
HSPLorg/ccil/cowan/tagsoup/Schema;->getElementType(Ljava/lang/String;)Lorg/ccil/cowan/tagsoup/ElementType;
@@ -31652,7 +31766,7 @@ HSPLsun/nio/cs/StreamEncoder;->forOutputStreamWriter(Ljava/io/OutputStream;Ljava
HSPLsun/nio/cs/StreamEncoder;->implClose()V
HSPLsun/nio/cs/StreamEncoder;->implFlush()V
HSPLsun/nio/cs/StreamEncoder;->implFlushBuffer()V
-HSPLsun/nio/cs/StreamEncoder;->implWrite(Ljava/nio/CharBuffer;)V
+HSPLsun/nio/cs/StreamEncoder;->implWrite(Ljava/nio/CharBuffer;)V+]Ljava/nio/charset/CoderResult;Ljava/nio/charset/CoderResult;
HSPLsun/nio/cs/StreamEncoder;->implWrite([CII)V
HSPLsun/nio/cs/StreamEncoder;->write(I)V
HSPLsun/nio/cs/StreamEncoder;->write(Ljava/lang/String;II)V
@@ -31717,7 +31831,7 @@ HSPLsun/nio/fs/UnixFileAttributeViews$Basic;->readAttributes()Ljava/nio/file/att
HSPLsun/nio/fs/UnixFileAttributeViews;->createBasicView(Lsun/nio/fs/UnixPath;Z)Lsun/nio/fs/UnixFileAttributeViews$Basic;
HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;-><init>(Lsun/nio/fs/UnixFileAttributes;)V
HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->creationTime()Ljava/nio/file/attribute/FileTime;
-HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->fileKey()Ljava/lang/Object;
+HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->fileKey()Ljava/lang/Object;+]Lsun/nio/fs/UnixFileAttributes;Lsun/nio/fs/UnixFileAttributes;
HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->isDirectory()Z
HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->isRegularFile()Z
HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->isSymbolicLink()Z
@@ -32108,7 +32222,7 @@ HSPLsun/security/util/DerValue;->length()I
HSPLsun/security/util/DerValue;->resetTag(B)V
HSPLsun/security/util/DerValue;->toByteArray()[B
HSPLsun/security/util/DerValue;->toDerInputStream()Lsun/security/util/DerInputStream;
-HSPLsun/security/util/DisabledAlgorithmConstraints$Constraints;-><init>([Ljava/lang/String;)V
+HPLsun/security/util/DisabledAlgorithmConstraints$Constraints;-><init>([Ljava/lang/String;)V
HSPLsun/security/util/DisabledAlgorithmConstraints$Constraints;->getConstraints(Ljava/lang/String;)Ljava/util/Set;
HSPLsun/security/util/DisabledAlgorithmConstraints$Constraints;->permits(Ljava/security/Key;)Z
HSPLsun/security/util/DisabledAlgorithmConstraints$Constraints;->permits(Lsun/security/util/CertConstraintParameters;)V
@@ -32577,6 +32691,7 @@ Landroid/accounts/AuthenticatorDescription$1;
Landroid/accounts/AuthenticatorDescription-IA;
Landroid/accounts/AuthenticatorDescription;
Landroid/accounts/AuthenticatorException;
+Landroid/accounts/IAccountAuthenticator$Stub$Proxy;
Landroid/accounts/IAccountAuthenticator$Stub;
Landroid/accounts/IAccountAuthenticator;
Landroid/accounts/IAccountAuthenticatorResponse$Stub$Proxy;
@@ -32585,6 +32700,7 @@ Landroid/accounts/IAccountAuthenticatorResponse;
Landroid/accounts/IAccountManager$Stub$Proxy;
Landroid/accounts/IAccountManager$Stub;
Landroid/accounts/IAccountManager;
+Landroid/accounts/IAccountManagerResponse$Stub$Proxy;
Landroid/accounts/IAccountManagerResponse$Stub;
Landroid/accounts/IAccountManagerResponse;
Landroid/accounts/NetworkErrorException;
@@ -32713,6 +32829,7 @@ Landroid/app/ActivityClient$ActivityClientControllerSingleton-IA;
Landroid/app/ActivityClient$ActivityClientControllerSingleton;
Landroid/app/ActivityClient-IA;
Landroid/app/ActivityClient;
+Landroid/app/ActivityManager$1;
Landroid/app/ActivityManager$2;
Landroid/app/ActivityManager$3;
Landroid/app/ActivityManager$AppTask;
@@ -32745,7 +32862,6 @@ Landroid/app/ActivityManagerInternal;
Landroid/app/ActivityOptions$1;
Landroid/app/ActivityOptions$2;
Landroid/app/ActivityOptions$OnAnimationStartedListener;
-Landroid/app/ActivityOptions$SceneTransitionInfo$1;
Landroid/app/ActivityOptions$SceneTransitionInfo;
Landroid/app/ActivityOptions$SourceInfo$1;
Landroid/app/ActivityOptions$SourceInfo;
@@ -32807,7 +32923,6 @@ Landroid/app/AlarmManager;
Landroid/app/AlertDialog$Builder;
Landroid/app/AlertDialog;
Landroid/app/AppCompatCallbacks;
-Landroid/app/AppCompatTaskInfo$1;
Landroid/app/AppCompatTaskInfo;
Landroid/app/AppComponentFactory;
Landroid/app/AppDetailsActivity;
@@ -32820,6 +32935,7 @@ Landroid/app/AppOpsManager$$ExternalSyntheticLambda4;
Landroid/app/AppOpsManager$$ExternalSyntheticLambda5;
Landroid/app/AppOpsManager$$ExternalSyntheticLambda6;
Landroid/app/AppOpsManager$1;
+Landroid/app/AppOpsManager$2;
Landroid/app/AppOpsManager$3;
Landroid/app/AppOpsManager$4;
Landroid/app/AppOpsManager$AppOpsCollector;
@@ -32896,11 +33012,9 @@ Landroid/app/BackStackRecord$Op;
Landroid/app/BackStackRecord;
Landroid/app/BackStackState$1;
Landroid/app/BackStackState;
-Landroid/app/BackgroundInstallControlManager;
Landroid/app/BackgroundServiceStartNotAllowedException$1;
Landroid/app/BackgroundServiceStartNotAllowedException;
Landroid/app/BroadcastOptions;
-Landroid/app/CameraCompatTaskInfo;
Landroid/app/ClientTransactionHandler;
Landroid/app/ComponentCaller;
Landroid/app/ComponentOptions;
@@ -33045,6 +33159,7 @@ Landroid/app/IServiceConnection;
Landroid/app/IStopUserCallback$Stub$Proxy;
Landroid/app/IStopUserCallback$Stub;
Landroid/app/IStopUserCallback;
+Landroid/app/ITaskStackListener$Stub$Proxy;
Landroid/app/ITaskStackListener$Stub;
Landroid/app/ITaskStackListener;
Landroid/app/ITransientNotification$Stub$Proxy;
@@ -33167,6 +33282,7 @@ Landroid/app/PendingIntent$$ExternalSyntheticLambda3;
Landroid/app/PendingIntent$1;
Landroid/app/PendingIntent$CancelListener;
Landroid/app/PendingIntent$CanceledException;
+Landroid/app/PendingIntent$FinishedDispatcher;
Landroid/app/PendingIntent$OnFinished;
Landroid/app/PendingIntent$OnMarshaledListener;
Landroid/app/PendingIntent;
@@ -33216,7 +33332,6 @@ Landroid/app/ResourcesManager$ActivityResources-IA;
Landroid/app/ResourcesManager$ActivityResources;
Landroid/app/ResourcesManager$ApkAssetsSupplier;
Landroid/app/ResourcesManager$ApkKey;
-Landroid/app/ResourcesManager$SharedLibraryAssets;
Landroid/app/ResourcesManager$UpdateHandler-IA;
Landroid/app/ResourcesManager$UpdateHandler;
Landroid/app/ResourcesManager;
@@ -33248,6 +33363,7 @@ Landroid/app/SharedPreferencesImpl$EditorImpl;
Landroid/app/SharedPreferencesImpl$MemoryCommitResult-IA;
Landroid/app/SharedPreferencesImpl$MemoryCommitResult;
Landroid/app/SharedPreferencesImpl$SharedPreferencesThreadFactory;
+Landroid/app/SharedPreferencesImpl;
Landroid/app/StackTrace;
Landroid/app/StatusBarManager;
Landroid/app/SyncNotedAppOp$1;
@@ -33298,12 +33414,8 @@ Landroid/app/SystemServiceRegistry$138;
Landroid/app/SystemServiceRegistry$139;
Landroid/app/SystemServiceRegistry$13;
Landroid/app/SystemServiceRegistry$140;
-Landroid/app/SystemServiceRegistry$141;
-Landroid/app/SystemServiceRegistry$142;
Landroid/app/SystemServiceRegistry$143;
Landroid/app/SystemServiceRegistry$144;
-Landroid/app/SystemServiceRegistry$145;
-Landroid/app/SystemServiceRegistry$146;
Landroid/app/SystemServiceRegistry$14;
Landroid/app/SystemServiceRegistry$15;
Landroid/app/SystemServiceRegistry$16;
@@ -33611,13 +33723,13 @@ Landroid/app/contentsuggestions/SelectionsRequest$1;
Landroid/app/contentsuggestions/SelectionsRequest$Builder;
Landroid/app/contentsuggestions/SelectionsRequest-IA;
Landroid/app/contentsuggestions/SelectionsRequest;
-Landroid/app/contextualsearch/ContextualSearchManager;
Landroid/app/job/IJobCallback$Stub$Proxy;
Landroid/app/job/IJobCallback$Stub;
Landroid/app/job/IJobCallback;
Landroid/app/job/IJobScheduler$Stub$Proxy;
Landroid/app/job/IJobScheduler$Stub;
Landroid/app/job/IJobScheduler;
+Landroid/app/job/IJobService$Stub$Proxy;
Landroid/app/job/IJobService$Stub;
Landroid/app/job/IJobService;
Landroid/app/job/IUserVisibleJobObserver;
@@ -33636,14 +33748,15 @@ Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda0;
Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda1;
Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda2;
Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda3;
+Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda4;
Landroid/app/job/JobSchedulerFrameworkInitializer;
Landroid/app/job/JobService$1;
Landroid/app/job/JobService;
Landroid/app/job/JobServiceEngine$JobHandler;
+Landroid/app/job/JobServiceEngine$JobInterface;
Landroid/app/job/JobServiceEngine;
Landroid/app/job/JobWorkItem$1;
Landroid/app/job/JobWorkItem;
-Landroid/app/ondeviceintelligence/OnDeviceIntelligenceManager;
Landroid/app/people/IPeopleManager$Stub$Proxy;
Landroid/app/people/IPeopleManager$Stub;
Landroid/app/people/IPeopleManager;
@@ -33723,6 +33836,7 @@ Landroid/app/servertransaction/TopResumedActivityChangeItem-IA;
Landroid/app/servertransaction/TopResumedActivityChangeItem;
Landroid/app/servertransaction/TransactionExecutor;
Landroid/app/servertransaction/TransactionExecutorHelper;
+Landroid/app/servertransaction/WindowStateResizeItem$ResizeListener;
Landroid/app/slice/ISliceManager$Stub$Proxy;
Landroid/app/slice/ISliceManager$Stub;
Landroid/app/slice/ISliceManager;
@@ -33774,6 +33888,7 @@ Landroid/app/smartspace/uitemplatedata/TapAction$1;
Landroid/app/smartspace/uitemplatedata/TapAction;
Landroid/app/smartspace/uitemplatedata/Text$1;
Landroid/app/smartspace/uitemplatedata/Text;
+Landroid/app/tare/EconomyManager;
Landroid/app/time/ITimeZoneDetectorListener$Stub$Proxy;
Landroid/app/time/ITimeZoneDetectorListener$Stub;
Landroid/app/time/ITimeZoneDetectorListener;
@@ -33835,8 +33950,6 @@ Landroid/app/usage/ConfigurationStats;
Landroid/app/usage/EventList;
Landroid/app/usage/ExternalStorageStats$1;
Landroid/app/usage/ExternalStorageStats;
-Landroid/app/usage/FeatureFlags;
-Landroid/app/usage/FeatureFlagsImpl;
Landroid/app/usage/Flags;
Landroid/app/usage/ICacheQuotaService$Stub$Proxy;
Landroid/app/usage/ICacheQuotaService$Stub;
@@ -33876,8 +33989,6 @@ Landroid/appwidget/AppWidgetProviderInfo$1;
Landroid/appwidget/AppWidgetProviderInfo;
Landroid/appwidget/PendingHostUpdate$1;
Landroid/appwidget/PendingHostUpdate;
-Landroid/appwidget/flags/FeatureFlags;
-Landroid/appwidget/flags/FeatureFlagsImpl;
Landroid/appwidget/flags/Flags;
Landroid/attention/AttentionManagerInternal$AttentionCallbackInternal;
Landroid/attention/AttentionManagerInternal;
@@ -33896,7 +34007,6 @@ Landroid/companion/virtual/IVirtualDevice;
Landroid/companion/virtual/IVirtualDeviceManager$Stub$Proxy;
Landroid/companion/virtual/IVirtualDeviceManager$Stub;
Landroid/companion/virtual/IVirtualDeviceManager;
-Landroid/companion/virtual/VirtualDevice;
Landroid/companion/virtual/VirtualDeviceManager;
Landroid/companion/virtual/flags/FeatureFlags;
Landroid/companion/virtual/flags/FeatureFlagsImpl;
@@ -33948,8 +34058,8 @@ Landroid/content/ComponentName$1;
Landroid/content/ComponentName$WithComponentName;
Landroid/content/ComponentName;
Landroid/content/ContentCaptureOptions$1;
+Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda0;
Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;
-Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;
Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
Landroid/content/ContentCaptureOptions;
Landroid/content/ContentInterface;
@@ -33970,10 +34080,12 @@ Landroid/content/ContentProviderOperation$Builder-IA;
Landroid/content/ContentProviderOperation$Builder;
Landroid/content/ContentProviderOperation-IA;
Landroid/content/ContentProviderOperation;
+Landroid/content/ContentProviderProxy;
Landroid/content/ContentProviderResult$1;
Landroid/content/ContentProviderResult;
Landroid/content/ContentResolver$1;
Landroid/content/ContentResolver$2;
+Landroid/content/ContentResolver$CursorWrapperInner;
Landroid/content/ContentResolver$OpenResourceIdResult;
Landroid/content/ContentResolver$ParcelFileDescriptorInner;
Landroid/content/ContentResolver$ResultListener-IA;
@@ -34025,6 +34137,7 @@ Landroid/content/ISyncAdapterUnsyncableAccountCallback;
Landroid/content/ISyncContext$Stub$Proxy;
Landroid/content/ISyncContext$Stub;
Landroid/content/ISyncContext;
+Landroid/content/ISyncStatusObserver$Stub$Proxy;
Landroid/content/ISyncStatusObserver$Stub;
Landroid/content/ISyncStatusObserver;
Landroid/content/Intent$1;
@@ -34127,7 +34240,6 @@ Landroid/content/pm/ApplicationInfo$1$$ExternalSyntheticLambda0;
Landroid/content/pm/ApplicationInfo$1;
Landroid/content/pm/ApplicationInfo-IA;
Landroid/content/pm/ApplicationInfo;
-Landroid/content/pm/ArchivedPackageParcel$1;
Landroid/content/pm/ArchivedPackageParcel;
Landroid/content/pm/Attribution$1;
Landroid/content/pm/Attribution;
@@ -34151,6 +34263,8 @@ Landroid/content/pm/DataLoaderParams;
Landroid/content/pm/DataLoaderParamsParcel$1;
Landroid/content/pm/DataLoaderParamsParcel;
Landroid/content/pm/FallbackCategoryProvider;
+Landroid/content/pm/FeatureFlags;
+Landroid/content/pm/FeatureFlagsImpl;
Landroid/content/pm/FeatureGroupInfo$1;
Landroid/content/pm/FeatureGroupInfo;
Landroid/content/pm/FeatureInfo$1;
@@ -34158,6 +34272,7 @@ Landroid/content/pm/FeatureInfo-IA;
Landroid/content/pm/FeatureInfo;
Landroid/content/pm/FileSystemControlParcel$1;
Landroid/content/pm/FileSystemControlParcel;
+Landroid/content/pm/Flags;
Landroid/content/pm/ICrossProfileApps$Stub$Proxy;
Landroid/content/pm/ICrossProfileApps$Stub;
Landroid/content/pm/ICrossProfileApps;
@@ -34174,6 +34289,7 @@ Landroid/content/pm/IDexModuleRegisterCallback;
Landroid/content/pm/ILauncherApps$Stub$Proxy;
Landroid/content/pm/ILauncherApps$Stub;
Landroid/content/pm/ILauncherApps;
+Landroid/content/pm/IOnAppsChangedListener$Stub$Proxy;
Landroid/content/pm/IOnAppsChangedListener$Stub;
Landroid/content/pm/IOnAppsChangedListener;
Landroid/content/pm/IOnChecksumsReadyListener$Stub$Proxy;
@@ -34541,7 +34657,6 @@ Landroid/content/rollback/RollbackManagerFrameworkInitializer;
Landroid/content/type/DefaultMimeMapFactory$$ExternalSyntheticLambda0;
Landroid/content/type/DefaultMimeMapFactory;
Landroid/credentials/CredentialManager;
-Landroid/credentials/GetCredentialResponse$1;
Landroid/credentials/GetCredentialResponse;
Landroid/database/AbstractCursor$SelfContentObserver;
Landroid/database/AbstractCursor;
@@ -34606,6 +34721,7 @@ Landroid/database/sqlite/SQLiteConnectionPool$ConnectionWaiter;
Landroid/database/sqlite/SQLiteConnectionPool$IdleConnectionHandler;
Landroid/database/sqlite/SQLiteConnectionPool;
Landroid/database/sqlite/SQLiteConstraintException;
+Landroid/database/sqlite/SQLiteCursor;
Landroid/database/sqlite/SQLiteCursorDriver;
Landroid/database/sqlite/SQLiteCustomFunction;
Landroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;
@@ -34778,7 +34894,6 @@ Landroid/graphics/LightingColorFilter;
Landroid/graphics/LinearGradient;
Landroid/graphics/MaskFilter;
Landroid/graphics/Matrix$1;
-Landroid/graphics/Matrix$ExtraNatives;
Landroid/graphics/Matrix$NoImagePreloadHolder;
Landroid/graphics/Matrix$ScaleToFit;
Landroid/graphics/Matrix;
@@ -34802,7 +34917,6 @@ Landroid/graphics/Paint;
Landroid/graphics/PaintFlagsDrawFilter;
Landroid/graphics/Path$Direction;
Landroid/graphics/Path$FillType;
-Landroid/graphics/Path$NoImagePreloadHolder;
Landroid/graphics/Path$Op;
Landroid/graphics/Path;
Landroid/graphics/PathDashPathEffect;
@@ -35013,7 +35127,6 @@ Landroid/graphics/drawable/shapes/RectShape;
Landroid/graphics/drawable/shapes/RoundRectShape;
Landroid/graphics/drawable/shapes/Shape;
Landroid/graphics/fonts/Font$Builder;
-Landroid/graphics/fonts/Font$NoImagePreloadHolder;
Landroid/graphics/fonts/Font;
Landroid/graphics/fonts/FontCustomizationParser$Result;
Landroid/graphics/fonts/FontCustomizationParser;
@@ -35058,7 +35171,6 @@ Landroid/hardware/CameraSessionStats;
Landroid/hardware/CameraStatus$1;
Landroid/hardware/CameraStatus;
Landroid/hardware/ConsumerIrManager;
-Landroid/hardware/DataSpace;
Landroid/hardware/GeomagneticField$LegendreTable;
Landroid/hardware/GeomagneticField;
Landroid/hardware/HardwareBuffer$1;
@@ -35106,6 +35218,7 @@ Landroid/hardware/SyncFence;
Landroid/hardware/SystemSensorManager$BaseEventQueue;
Landroid/hardware/SystemSensorManager$SensorEventQueue;
Landroid/hardware/SystemSensorManager$TriggerEventQueue;
+Landroid/hardware/SystemSensorManager;
Landroid/hardware/TriggerEvent;
Landroid/hardware/TriggerEventListener;
Landroid/hardware/biometrics/BiometricAuthenticator$AuthenticationCallback;
@@ -35172,10 +35285,13 @@ Landroid/hardware/camera2/CameraCharacteristics;
Landroid/hardware/camera2/CameraDevice$StateCallback;
Landroid/hardware/camera2/CameraDevice;
Landroid/hardware/camera2/CameraManager$AvailabilityCallback;
-Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$$ExternalSyntheticLambda0;
Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$$ExternalSyntheticLambda2;
Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;
-Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$DeviceCameraInfo;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$3;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$4;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$5;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$6;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$7;
Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;
Landroid/hardware/camera2/CameraManager$DeviceStateListener;
Landroid/hardware/camera2/CameraManager$FoldStateListener$$ExternalSyntheticLambda0;
@@ -35332,7 +35448,6 @@ Landroid/hardware/contexthub/V1_0/MemRange;
Landroid/hardware/contexthub/V1_0/NanoAppBinary;
Landroid/hardware/contexthub/V1_0/PhysicalSensor;
Landroid/hardware/contexthub/V1_1/Setting;
-Landroid/hardware/devicestate/DeviceState$Configuration;
Landroid/hardware/devicestate/DeviceState;
Landroid/hardware/devicestate/DeviceStateInfo$1;
Landroid/hardware/devicestate/DeviceStateInfo;
@@ -35447,9 +35562,12 @@ Landroid/hardware/fingerprint/Fingerprint$1;
Landroid/hardware/fingerprint/Fingerprint;
Landroid/hardware/fingerprint/FingerprintManager$1;
Landroid/hardware/fingerprint/FingerprintManager$2;
+Landroid/hardware/fingerprint/FingerprintManager$3;
Landroid/hardware/fingerprint/FingerprintManager$AuthenticationCallback;
Landroid/hardware/fingerprint/FingerprintManager$AuthenticationResult;
Landroid/hardware/fingerprint/FingerprintManager$LockoutResetCallback;
+Landroid/hardware/fingerprint/FingerprintManager$MyHandler-IA;
+Landroid/hardware/fingerprint/FingerprintManager$MyHandler;
Landroid/hardware/fingerprint/FingerprintManager;
Landroid/hardware/fingerprint/FingerprintSensorPropertiesInternal$1;
Landroid/hardware/fingerprint/FingerprintSensorPropertiesInternal;
@@ -35935,9 +36053,13 @@ Landroid/icu/impl/CacheValue;
Landroid/icu/impl/CalType;
Landroid/icu/impl/CalendarAstronomer$1;
Landroid/icu/impl/CalendarAstronomer$2;
+Landroid/icu/impl/CalendarAstronomer$3;
+Landroid/icu/impl/CalendarAstronomer$4;
Landroid/icu/impl/CalendarAstronomer$AngleFunc;
+Landroid/icu/impl/CalendarAstronomer$CoordFunc;
Landroid/icu/impl/CalendarAstronomer$Ecliptic;
Landroid/icu/impl/CalendarAstronomer$Equatorial;
+Landroid/icu/impl/CalendarAstronomer$Horizon;
Landroid/icu/impl/CalendarAstronomer$MoonAge;
Landroid/icu/impl/CalendarAstronomer$SolarLongitude;
Landroid/icu/impl/CalendarAstronomer;
@@ -35974,7 +36096,6 @@ Landroid/icu/impl/DayPeriodRules$DayPeriodRulesDataSink;
Landroid/icu/impl/DayPeriodRules-IA;
Landroid/icu/impl/DayPeriodRules;
Landroid/icu/impl/DontCareFieldPosition;
-Landroid/icu/impl/EmojiProps$IsAcceptable;
Landroid/icu/impl/EmojiProps;
Landroid/icu/impl/EraRules;
Landroid/icu/impl/FormattedStringBuilder$FieldWrapper;
@@ -36250,8 +36371,6 @@ Landroid/icu/impl/UCharacterProperty$24;
Landroid/icu/impl/UCharacterProperty$25;
Landroid/icu/impl/UCharacterProperty$26;
Landroid/icu/impl/UCharacterProperty$27;
-Landroid/icu/impl/UCharacterProperty$28;
-Landroid/icu/impl/UCharacterProperty$29;
Landroid/icu/impl/UCharacterProperty$2;
Landroid/icu/impl/UCharacterProperty$3;
Landroid/icu/impl/UCharacterProperty$4;
@@ -36269,7 +36388,6 @@ Landroid/icu/impl/UCharacterProperty$IntProperty;
Landroid/icu/impl/UCharacterProperty$IsAcceptable;
Landroid/icu/impl/UCharacterProperty$LayoutProps$IsAcceptable;
Landroid/icu/impl/UCharacterProperty$LayoutProps;
-Landroid/icu/impl/UCharacterProperty$MathCompatBinaryProperty;
Landroid/icu/impl/UCharacterProperty$NormInertBinaryProperty;
Landroid/icu/impl/UCharacterProperty$NormQuickCheckIntProperty;
Landroid/icu/impl/UCharacterProperty;
@@ -36454,15 +36572,8 @@ Landroid/icu/impl/locale/KeyTypeData$Type;
Landroid/icu/impl/locale/KeyTypeData$TypeInfoType;
Landroid/icu/impl/locale/KeyTypeData$ValueType;
Landroid/icu/impl/locale/KeyTypeData;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda0;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda1;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda2;
-Landroid/icu/impl/locale/LSR$CachedDecoder;
Landroid/icu/impl/locale/LSR;
Landroid/icu/impl/locale/LanguageTag;
-Landroid/icu/impl/locale/LikelySubtags$1;
-Landroid/icu/impl/locale/LikelySubtags$Data;
-Landroid/icu/impl/locale/LikelySubtags;
Landroid/icu/impl/locale/LocaleDistance$Data;
Landroid/icu/impl/locale/LocaleDistance;
Landroid/icu/impl/locale/LocaleExtensions;
@@ -36493,6 +36604,9 @@ Landroid/icu/impl/locale/XCldrStub$ReusableEntry;
Landroid/icu/impl/locale/XCldrStub$Splitter;
Landroid/icu/impl/locale/XCldrStub$TreeMultimap;
Landroid/icu/impl/locale/XCldrStub;
+Landroid/icu/impl/locale/XLikelySubtags$1;
+Landroid/icu/impl/locale/XLikelySubtags$Data;
+Landroid/icu/impl/locale/XLikelySubtags;
Landroid/icu/impl/number/AdoptingModifierStore$1;
Landroid/icu/impl/number/AdoptingModifierStore;
Landroid/icu/impl/number/AffixPatternProvider$Flags;
@@ -36623,7 +36737,6 @@ Landroid/icu/lang/UCharacter$DummyValueIterator;
Landroid/icu/lang/UCharacter$EastAsianWidth;
Landroid/icu/lang/UCharacter$GraphemeClusterBreak;
Landroid/icu/lang/UCharacter$HangulSyllableType;
-Landroid/icu/lang/UCharacter$IdentifierType;
Landroid/icu/lang/UCharacter$IndicPositionalCategory;
Landroid/icu/lang/UCharacter$IndicSyllabicCategory;
Landroid/icu/lang/UCharacter$JoiningGroup;
@@ -37169,7 +37282,6 @@ Landroid/icu/text/TitlecaseTransliterator;
Landroid/icu/text/Transform;
Landroid/icu/text/TransliterationRule;
Landroid/icu/text/TransliterationRuleSet;
-Landroid/icu/text/Transliterator$$ExternalSyntheticLambda0;
Landroid/icu/text/Transliterator$Factory;
Landroid/icu/text/Transliterator$Position;
Landroid/icu/text/Transliterator;
@@ -37216,7 +37328,6 @@ Landroid/icu/text/UnicodeSet$EntryRangeIterable;
Landroid/icu/text/UnicodeSet$EntryRangeIterator;
Landroid/icu/text/UnicodeSet$Filter;
Landroid/icu/text/UnicodeSet$GeneralCategoryMaskFilter;
-Landroid/icu/text/UnicodeSet$IdentifierTypeFilter;
Landroid/icu/text/UnicodeSet$IntPropertyFilter;
Landroid/icu/text/UnicodeSet$NumericValueFilter;
Landroid/icu/text/UnicodeSet$ScriptExtensionsFilter;
@@ -37323,12 +37434,7 @@ Landroid/icu/util/ICUUncheckedIOException;
Landroid/icu/util/IllformedLocaleException;
Landroid/icu/util/IndianCalendar;
Landroid/icu/util/InitialTimeZoneRule;
-Landroid/icu/util/IslamicCalendar$Algorithm;
Landroid/icu/util/IslamicCalendar$CalculationType;
-Landroid/icu/util/IslamicCalendar$CivilAlgorithm;
-Landroid/icu/util/IslamicCalendar$IslamicAlgorithm;
-Landroid/icu/util/IslamicCalendar$TBLAAlgorithm;
-Landroid/icu/util/IslamicCalendar$UmalquraAlgorithm;
Landroid/icu/util/IslamicCalendar;
Landroid/icu/util/JapaneseCalendar;
Landroid/icu/util/LocaleData$MeasurementSystem;
@@ -37678,8 +37784,6 @@ Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;
Landroid/media/ImageWriter$WriterSurfaceImage;
Landroid/media/ImageWriter;
Landroid/media/JetPlayer;
-Landroid/media/MediaCodec$$ExternalSyntheticLambda6;
-Landroid/media/MediaCodec$$ExternalSyntheticLambda7;
Landroid/media/MediaCodec$BufferInfo;
Landroid/media/MediaCodec$BufferMap$CodecBuffer-IA;
Landroid/media/MediaCodec$BufferMap$CodecBuffer;
@@ -37904,8 +38008,6 @@ Landroid/media/VolumeShaper$Operation;
Landroid/media/VolumeShaper$State$1;
Landroid/media/VolumeShaper$State;
Landroid/media/VolumeShaper;
-Landroid/media/audio/FeatureFlags;
-Landroid/media/audio/FeatureFlagsImpl;
Landroid/media/audio/Flags;
Landroid/media/audio/common/AidlConversion;
Landroid/media/audio/common/HeadTracking$SensorData$Tag;
@@ -38354,7 +38456,6 @@ Landroid/net/wifi/nl80211/WifiNl80211Manager$ScanEventHandler;
Landroid/net/wifi/nl80211/WifiNl80211Manager$SignalPollResult;
Landroid/net/wifi/nl80211/WifiNl80211Manager;
Landroid/net/wifi/sharedconnectivity/app/SharedConnectivityManager;
-Landroid/nfc/NfcAdapter;
Landroid/nfc/NfcFrameworkInitializer$$ExternalSyntheticLambda0;
Landroid/nfc/NfcFrameworkInitializer;
Landroid/nfc/NfcManager;
@@ -38605,6 +38706,7 @@ Landroid/os/IIncidentCompanion;
Landroid/os/IIncidentManager$Stub$Proxy;
Landroid/os/IIncidentManager$Stub;
Landroid/os/IIncidentManager;
+Landroid/os/IInstalld$Stub$Proxy;
Landroid/os/IInstalld$Stub;
Landroid/os/IInstalld;
Landroid/os/IInterface;
@@ -38827,6 +38929,7 @@ Landroid/os/StrictMode$1;
Landroid/os/StrictMode$2;
Landroid/os/StrictMode$3;
Landroid/os/StrictMode$4;
+Landroid/os/StrictMode$5;
Landroid/os/StrictMode$6;
Landroid/os/StrictMode$7;
Landroid/os/StrictMode$8;
@@ -38857,6 +38960,7 @@ Landroid/os/StrictMode;
Landroid/os/SynchronousResultReceiver$Result;
Landroid/os/SynchronousResultReceiver;
Landroid/os/SystemClock$2;
+Landroid/os/SystemClock$3;
Landroid/os/SystemClock;
Landroid/os/SystemConfigManager;
Landroid/os/SystemProperties$Handle-IA;
@@ -39015,8 +39119,6 @@ Landroid/os/strictmode/UnsafeIntentLaunchViolation;
Landroid/os/strictmode/UntaggedSocketViolation;
Landroid/os/strictmode/Violation;
Landroid/os/strictmode/WebViewMethodCalledOnWrongThreadViolation;
-Landroid/os/vibrator/FeatureFlags;
-Landroid/os/vibrator/FeatureFlagsImpl;
Landroid/os/vibrator/Flags;
Landroid/os/vibrator/PrebakedSegment$1;
Landroid/os/vibrator/PrebakedSegment;
@@ -39050,13 +39152,15 @@ Landroid/permission/PermissionControllerManager$1;
Landroid/permission/PermissionControllerManager;
Landroid/permission/PermissionManager$1;
Landroid/permission/PermissionManager$2;
-Landroid/permission/PermissionManager$OnPermissionsChangeListenerDelegate;
Landroid/permission/PermissionManager$PackageNamePermissionQuery;
Landroid/permission/PermissionManager$PermissionQuery;
Landroid/permission/PermissionManager$SplitPermissionInfo-IA;
Landroid/permission/PermissionManager$SplitPermissionInfo;
Landroid/permission/PermissionManager;
Landroid/permission/PermissionManagerInternal;
+Landroid/permission/flags/FeatureFlags;
+Landroid/permission/flags/FeatureFlagsImpl;
+Landroid/permission/flags/Flags;
Landroid/preference/DialogPreference;
Landroid/preference/GenericInflater$Parent;
Landroid/preference/GenericInflater;
@@ -39285,6 +39389,7 @@ Landroid/security/KeyStore2$$ExternalSyntheticLambda4;
Landroid/security/KeyStore2$$ExternalSyntheticLambda8;
Landroid/security/KeyStore2$CheckedRemoteRequest;
Landroid/security/KeyStore2;
+Landroid/security/KeyStore;
Landroid/security/KeyStoreException$PublicErrorInformation;
Landroid/security/KeyStoreException;
Landroid/security/KeyStoreOperation$$ExternalSyntheticLambda0;
@@ -39455,8 +39560,6 @@ Landroid/service/appprediction/IPredictionService;
Landroid/service/autofill/AutofillServiceInfo;
Landroid/service/autofill/Dataset$1;
Landroid/service/autofill/Dataset;
-Landroid/service/autofill/FeatureFlags;
-Landroid/service/autofill/FeatureFlagsImpl;
Landroid/service/autofill/FieldClassificationUserData;
Landroid/service/autofill/FillContext$1;
Landroid/service/autofill/FillContext;
@@ -39593,7 +39696,6 @@ Landroid/service/media/MediaBrowserService$Result;
Landroid/service/media/MediaBrowserService$ServiceBinder$$ExternalSyntheticLambda1;
Landroid/service/media/MediaBrowserService$ServiceBinder-IA;
Landroid/service/media/MediaBrowserService$ServiceBinder;
-Landroid/service/media/MediaBrowserService$ServiceState-IA;
Landroid/service/media/MediaBrowserService$ServiceState;
Landroid/service/media/MediaBrowserService;
Landroid/service/notification/Adjustment$1;
@@ -39632,7 +39734,6 @@ Landroid/service/notification/SnoozeCriterion$1;
Landroid/service/notification/SnoozeCriterion;
Landroid/service/notification/StatusBarNotification$1;
Landroid/service/notification/StatusBarNotification;
-Landroid/service/notification/ZenDeviceEffects$1;
Landroid/service/notification/ZenDeviceEffects;
Landroid/service/notification/ZenModeConfig$1;
Landroid/service/notification/ZenModeConfig$EventInfo;
@@ -40046,6 +40147,7 @@ Landroid/telephony/ICellBroadcastService;
Landroid/telephony/ICellInfoCallback$Stub$Proxy;
Landroid/telephony/ICellInfoCallback$Stub;
Landroid/telephony/ICellInfoCallback;
+Landroid/telephony/INetworkService$Stub$Proxy;
Landroid/telephony/INetworkService$Stub;
Landroid/telephony/INetworkService;
Landroid/telephony/INetworkServiceCallback$Stub$Proxy;
@@ -40081,6 +40183,7 @@ Landroid/telephony/NetworkRegistrationInfo;
Landroid/telephony/NetworkScan;
Landroid/telephony/NetworkScanRequest$1;
Landroid/telephony/NetworkScanRequest;
+Landroid/telephony/NetworkService$INetworkServiceWrapper;
Landroid/telephony/NetworkService$NetworkServiceHandler;
Landroid/telephony/NetworkService$NetworkServiceProvider;
Landroid/telephony/NetworkService;
@@ -40217,7 +40320,6 @@ Landroid/telephony/TelephonyCallback$CallDisconnectCauseListener;
Landroid/telephony/TelephonyCallback$CallForwardingIndicatorListener;
Landroid/telephony/TelephonyCallback$CallStateListener;
Landroid/telephony/TelephonyCallback$CarrierNetworkListener;
-Landroid/telephony/TelephonyCallback$CarrierRoamingNtnModeListener;
Landroid/telephony/TelephonyCallback$CellInfoListener;
Landroid/telephony/TelephonyCallback$CellLocationListener;
Landroid/telephony/TelephonyCallback$DataActivationStateListener;
@@ -40518,6 +40620,7 @@ Landroid/telephony/ims/aidl/IImsConfig;
Landroid/telephony/ims/aidl/IImsConfigCallback$Stub$Proxy;
Landroid/telephony/ims/aidl/IImsConfigCallback$Stub;
Landroid/telephony/ims/aidl/IImsConfigCallback;
+Landroid/telephony/ims/aidl/IImsMmTelFeature$Stub$Proxy;
Landroid/telephony/ims/aidl/IImsMmTelFeature$Stub;
Landroid/telephony/ims/aidl/IImsMmTelFeature;
Landroid/telephony/ims/aidl/IImsMmTelListener$Stub$Proxy;
@@ -40527,6 +40630,7 @@ Landroid/telephony/ims/aidl/IImsRcsController$Stub;
Landroid/telephony/ims/aidl/IImsRcsController;
Landroid/telephony/ims/aidl/IImsRcsFeature$Stub;
Landroid/telephony/ims/aidl/IImsRcsFeature;
+Landroid/telephony/ims/aidl/IImsRegistration$Stub$Proxy;
Landroid/telephony/ims/aidl/IImsRegistration$Stub;
Landroid/telephony/ims/aidl/IImsRegistration;
Landroid/telephony/ims/aidl/IImsRegistrationCallback$Stub$Proxy;
@@ -40665,7 +40769,6 @@ Landroid/text/Layout$SpannedEllipsizer;
Landroid/text/Layout$TabStops;
Landroid/text/Layout$TextInclusionStrategy;
Landroid/text/Layout;
-Landroid/text/MeasuredParagraph$StyleRunCallback;
Landroid/text/MeasuredParagraph;
Landroid/text/NoCopySpan$Concrete;
Landroid/text/NoCopySpan;
@@ -40706,7 +40809,6 @@ Landroid/text/TextDirectionHeuristics;
Landroid/text/TextFlags;
Landroid/text/TextLine$DecorationInfo-IA;
Landroid/text/TextLine$DecorationInfo;
-Landroid/text/TextLine$LineInfo;
Landroid/text/TextLine;
Landroid/text/TextPaint;
Landroid/text/TextShaper$GlyphsConsumer;
@@ -40791,7 +40893,6 @@ Landroid/text/style/LeadingMarginSpan$Standard;
Landroid/text/style/LeadingMarginSpan;
Landroid/text/style/LineBackgroundSpan$Standard;
Landroid/text/style/LineBackgroundSpan;
-Landroid/text/style/LineBreakConfigSpan$1;
Landroid/text/style/LineBreakConfigSpan;
Landroid/text/style/LineHeightSpan$Standard;
Landroid/text/style/LineHeightSpan$WithDensity;
@@ -40845,7 +40946,6 @@ Landroid/timezone/TelephonyLookup;
Landroid/timezone/TelephonyNetwork;
Landroid/timezone/TelephonyNetworkFinder;
Landroid/timezone/TimeZoneFinder;
-Landroid/tracing/Flags;
Landroid/tracing/perfetto/CreateIncrementalStateArgs;
Landroid/tracing/perfetto/CreateTlsStateArgs;
Landroid/tracing/perfetto/DataSource;
@@ -41045,6 +41145,7 @@ Landroid/util/SparseIntArray;
Landroid/util/SparseLongArray;
Landroid/util/SparseSetArray;
Landroid/util/Spline$LinearSpline;
+Landroid/util/Spline$MonotoneCubicSpline;
Landroid/util/Spline;
Landroid/util/StateSet;
Landroid/util/StringBuilderPrinter;
@@ -41271,7 +41372,6 @@ Landroid/view/IScrollCaptureCallbacks;
Landroid/view/IScrollCaptureResponseListener$Stub$Proxy;
Landroid/view/IScrollCaptureResponseListener$Stub;
Landroid/view/IScrollCaptureResponseListener;
-Landroid/view/ISensitiveContentProtectionManager$Stub$Proxy;
Landroid/view/ISensitiveContentProtectionManager$Stub;
Landroid/view/ISensitiveContentProtectionManager;
Landroid/view/ISurfaceControlViewHost;
@@ -41298,7 +41398,6 @@ Landroid/view/IWindowSession;
Landroid/view/IWindowSessionCallback$Stub$Proxy;
Landroid/view/IWindowSessionCallback$Stub;
Landroid/view/IWindowSessionCallback;
-Landroid/view/ImeBackAnimationController;
Landroid/view/ImeFocusController$InputMethodManagerDelegate;
Landroid/view/ImeFocusController;
Landroid/view/ImeInsetsSourceConsumer;
@@ -41360,6 +41459,7 @@ Landroid/view/InsetsController$InternalAnimationControlListener$$ExternalSynthet
Landroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda3;
Landroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda4;
Landroid/view/InsetsController$InternalAnimationControlListener$1;
+Landroid/view/InsetsController$InternalAnimationControlListener$2;
Landroid/view/InsetsController$InternalAnimationControlListener;
Landroid/view/InsetsController$PendingControlRequest;
Landroid/view/InsetsController$RunningAnimation;
@@ -41448,7 +41548,6 @@ Landroid/view/ScaleGestureDetector$1;
Landroid/view/ScaleGestureDetector$OnScaleGestureListener;
Landroid/view/ScaleGestureDetector$SimpleOnScaleGestureListener;
Landroid/view/ScaleGestureDetector;
-Landroid/view/ScrollCaptureSearchResults$$ExternalSyntheticLambda0;
Landroid/view/ScrollCaptureSearchResults;
Landroid/view/ScrollFeedbackProvider;
Landroid/view/SearchEvent;
@@ -41467,7 +41566,6 @@ Landroid/view/SurfaceControl$DesiredDisplayModeSpecs;
Landroid/view/SurfaceControl$DisplayMode;
Landroid/view/SurfaceControl$DisplayPrimaries;
Landroid/view/SurfaceControl$DynamicDisplayInfo;
-Landroid/view/SurfaceControl$IdleScreenRefreshRateConfig;
Landroid/view/SurfaceControl$JankData;
Landroid/view/SurfaceControl$OnJankDataListener;
Landroid/view/SurfaceControl$OnReparentListener;
@@ -41776,14 +41874,12 @@ Landroid/view/WindowManager;
Landroid/view/WindowManagerGlobal$$ExternalSyntheticLambda0;
Landroid/view/WindowManagerGlobal$1;
Landroid/view/WindowManagerGlobal$2;
-Landroid/view/WindowManagerGlobal$TrustedPresentationListener-IA;
Landroid/view/WindowManagerGlobal$TrustedPresentationListener;
Landroid/view/WindowManagerGlobal;
Landroid/view/WindowManagerImpl;
Landroid/view/WindowManagerPolicyConstants$PointerEventListener;
Landroid/view/WindowManagerPolicyConstants;
Landroid/view/WindowMetrics;
-Landroid/view/WindowRelayoutResult;
Landroid/view/WindowlessWindowLayout;
Landroid/view/WindowlessWindowManager;
Landroid/view/accessibility/AccessibilityCache$AccessibilityNodeRefresher;
@@ -41827,8 +41923,6 @@ Landroid/view/accessibility/CaptioningManager$CaptioningChangeListener;
Landroid/view/accessibility/CaptioningManager$MyContentObserver;
Landroid/view/accessibility/CaptioningManager;
Landroid/view/accessibility/DirectAccessibilityConnection;
-Landroid/view/accessibility/FeatureFlags;
-Landroid/view/accessibility/FeatureFlagsImpl;
Landroid/view/accessibility/Flags;
Landroid/view/accessibility/IAccessibilityEmbeddedConnection;
Landroid/view/accessibility/IAccessibilityInteractionConnection$Stub$Proxy;
@@ -41954,6 +42048,7 @@ Landroid/view/contentcapture/IContentCaptureManager$Stub;
Landroid/view/contentcapture/IContentCaptureManager;
Landroid/view/contentcapture/IContentCaptureOptionsCallback$Stub;
Landroid/view/contentcapture/IContentCaptureOptionsCallback;
+Landroid/view/contentcapture/IDataShareWriteAdapter$Stub$Proxy;
Landroid/view/contentcapture/IDataShareWriteAdapter$Stub;
Landroid/view/contentcapture/IDataShareWriteAdapter;
Landroid/view/contentcapture/MainContentCaptureSession$$ExternalSyntheticLambda0;
@@ -42008,8 +42103,6 @@ Landroid/view/inputmethod/ExtractedText$1;
Landroid/view/inputmethod/ExtractedText;
Landroid/view/inputmethod/ExtractedTextRequest$1;
Landroid/view/inputmethod/ExtractedTextRequest;
-Landroid/view/inputmethod/FeatureFlags;
-Landroid/view/inputmethod/FeatureFlagsImpl;
Landroid/view/inputmethod/Flags;
Landroid/view/inputmethod/HandwritingGesture;
Landroid/view/inputmethod/IAccessibilityInputMethodSessionInvoker$$ExternalSyntheticLambda0;
@@ -42610,7 +42703,6 @@ Landroid/widget/RemoteViews$BaseReflectionAction;
Landroid/widget/RemoteViews$BitmapCache;
Landroid/widget/RemoteViews$BitmapReflectionAction;
Landroid/widget/RemoteViews$ComplexUnitDimensionReflectionAction;
-Landroid/widget/RemoteViews$DrawInstructions;
Landroid/widget/RemoteViews$HierarchyRootData;
Landroid/widget/RemoteViews$InteractionHandler;
Landroid/widget/RemoteViews$LayoutParamAction;
@@ -42769,12 +42861,10 @@ Landroid/widget/ViewFlipper$1;
Landroid/widget/ViewFlipper;
Landroid/widget/ViewSwitcher;
Landroid/widget/WrapperListAdapter;
-Landroid/widget/flags/Flags;
Landroid/widget/inline/InlinePresentationSpec$1;
Landroid/widget/inline/InlinePresentationSpec$BaseBuilder;
Landroid/widget/inline/InlinePresentationSpec$Builder;
Landroid/widget/inline/InlinePresentationSpec;
-Landroid/window/ActivityWindowInfo$1;
Landroid/window/ActivityWindowInfo;
Landroid/window/BackAnimationAdapter$1;
Landroid/window/BackAnimationAdapter;
@@ -42783,12 +42873,9 @@ Landroid/window/BackMotionEvent$1;
Landroid/window/BackMotionEvent;
Landroid/window/BackNavigationInfo$1;
Landroid/window/BackNavigationInfo;
-Landroid/window/BackProgressAnimator$$ExternalSyntheticLambda0;
Landroid/window/BackProgressAnimator$1;
Landroid/window/BackProgressAnimator$ProgressCallback;
Landroid/window/BackProgressAnimator;
-Landroid/window/BackTouchTracker$TouchTrackerState;
-Landroid/window/BackTouchTracker;
Landroid/window/ClientWindowFrames$1;
Landroid/window/ClientWindowFrames-IA;
Landroid/window/ClientWindowFrames;
@@ -42822,6 +42909,7 @@ Landroid/window/ITaskFragmentOrganizer$Stub;
Landroid/window/ITaskFragmentOrganizer;
Landroid/window/ITaskFragmentOrganizerController$Stub;
Landroid/window/ITaskFragmentOrganizerController;
+Landroid/window/ITaskOrganizer$Stub$Proxy;
Landroid/window/ITaskOrganizer$Stub;
Landroid/window/ITaskOrganizer;
Landroid/window/ITaskOrganizerController$Stub$Proxy;
@@ -42845,11 +42933,8 @@ Landroid/window/IWindowOrganizerController;
Landroid/window/ImeOnBackInvokedDispatcher$$ExternalSyntheticLambda0;
Landroid/window/ImeOnBackInvokedDispatcher$1;
Landroid/window/ImeOnBackInvokedDispatcher$2;
-Landroid/window/ImeOnBackInvokedDispatcher$DefaultImeOnBackAnimationCallback;
Landroid/window/ImeOnBackInvokedDispatcher$ImeOnBackInvokedCallback;
Landroid/window/ImeOnBackInvokedDispatcher;
-Landroid/window/InputTransferToken$1;
-Landroid/window/InputTransferToken;
Landroid/window/OnBackAnimationCallback;
Landroid/window/OnBackInvokedCallback;
Landroid/window/OnBackInvokedCallbackInfo$1;
@@ -42873,7 +42958,6 @@ Landroid/window/SizeConfigurationBuckets$1;
Landroid/window/SizeConfigurationBuckets;
Landroid/window/SplashScreen$SplashScreenManagerGlobal$1;
Landroid/window/SplashScreen$SplashScreenManagerGlobal;
-Landroid/window/SplashScreen;
Landroid/window/SplashScreenView$SplashScreenViewParcelable$1;
Landroid/window/SplashScreenView$SplashScreenViewParcelable;
Landroid/window/SplashScreenView;
@@ -42901,7 +42985,6 @@ Landroid/window/TaskFragmentOrganizer$1;
Landroid/window/TaskFragmentOrganizer;
Landroid/window/TaskFragmentOrganizerToken$1;
Landroid/window/TaskFragmentOrganizerToken;
-Landroid/window/TaskFragmentTransaction$1;
Landroid/window/TaskFragmentTransaction;
Landroid/window/TaskOrganizer$1;
Landroid/window/TaskOrganizer;
@@ -42936,6 +43019,7 @@ Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$Exte
Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda2;
Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda3;
Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda4;
+Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda5;
Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$CallbackRef;
Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;
Landroid/window/WindowOnBackInvokedDispatcher;
@@ -43020,9 +43104,6 @@ Lcom/android/framework/protobuf/nano/InternalNano;
Lcom/android/framework/protobuf/nano/InvalidProtocolBufferNanoException;
Lcom/android/framework/protobuf/nano/MessageNano;
Lcom/android/framework/protobuf/nano/WireFormatNano;
-Lcom/android/graphics/flags/Flags;
-Lcom/android/graphics/hwui/flags/FeatureFlags;
-Lcom/android/graphics/hwui/flags/FeatureFlagsImpl;
Lcom/android/graphics/hwui/flags/Flags;
Lcom/android/i18n/phonenumbers/AlternateFormatsCountryCodeSet;
Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;
@@ -43142,7 +43223,6 @@ Lcom/android/i18n/timezone/internal/Memory;
Lcom/android/i18n/timezone/internal/MemoryMappedFile;
Lcom/android/i18n/timezone/internal/NioBufferIterator;
Lcom/android/i18n/util/Log;
-Lcom/android/icu/charset/CharsetDecoderICU;
Lcom/android/icu/charset/CharsetEncoderICU;
Lcom/android/icu/charset/CharsetFactory;
Lcom/android/icu/charset/NativeConverter;
@@ -43212,6 +43292,7 @@ Lcom/android/ims/ImsManager$$ExternalSyntheticLambda2;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda3;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda4;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda5;
+Lcom/android/ims/ImsManager$$ExternalSyntheticLambda6;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda7;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda8;
Lcom/android/ims/ImsManager$$ExternalSyntheticLambda9;
@@ -43290,6 +43371,7 @@ Lcom/android/ims/internal/IImsRegistrationListener$Stub;
Lcom/android/ims/internal/IImsRegistrationListener;
Lcom/android/ims/internal/IImsServiceController$Stub;
Lcom/android/ims/internal/IImsServiceController;
+Lcom/android/ims/internal/IImsServiceFeatureCallback$Stub$Proxy;
Lcom/android/ims/internal/IImsServiceFeatureCallback$Stub;
Lcom/android/ims/internal/IImsServiceFeatureCallback;
Lcom/android/ims/internal/IImsStreamMediaSession;
@@ -43544,8 +43626,6 @@ Lcom/android/ims/rcs/uce/util/FeatureTags$$ExternalSyntheticLambda0;
Lcom/android/ims/rcs/uce/util/FeatureTags;
Lcom/android/ims/rcs/uce/util/NetworkSipCode;
Lcom/android/ims/rcs/uce/util/UceUtils;
-Lcom/android/input/flags/FeatureFlags;
-Lcom/android/input/flags/FeatureFlagsImpl;
Lcom/android/input/flags/Flags;
Lcom/android/internal/R$attr;
Lcom/android/internal/R$dimen;
@@ -43573,6 +43653,7 @@ Lcom/android/internal/app/IAppOpsActiveCallback$Stub;
Lcom/android/internal/app/IAppOpsActiveCallback;
Lcom/android/internal/app/IAppOpsAsyncNotedCallback$Stub;
Lcom/android/internal/app/IAppOpsAsyncNotedCallback;
+Lcom/android/internal/app/IAppOpsCallback$Stub$Proxy;
Lcom/android/internal/app/IAppOpsCallback$Stub;
Lcom/android/internal/app/IAppOpsCallback;
Lcom/android/internal/app/IAppOpsNotedCallback$Stub;
@@ -43667,7 +43748,6 @@ Lcom/android/internal/colorextraction/types/Tonal$ConfigParser;
Lcom/android/internal/colorextraction/types/Tonal$TonalPalette;
Lcom/android/internal/colorextraction/types/Tonal;
Lcom/android/internal/compat/AndroidBuildClassifier;
-Lcom/android/internal/compat/ChangeReporter$$ExternalSyntheticLambda0;
Lcom/android/internal/compat/ChangeReporter$ChangeReport;
Lcom/android/internal/compat/ChangeReporter;
Lcom/android/internal/compat/CompatibilityChangeConfig$1;
@@ -43681,9 +43761,6 @@ Lcom/android/internal/compat/IPlatformCompat$Stub;
Lcom/android/internal/compat/IPlatformCompat;
Lcom/android/internal/compat/IPlatformCompatNative$Stub;
Lcom/android/internal/compat/IPlatformCompatNative;
-Lcom/android/internal/compat/flags/FeatureFlags;
-Lcom/android/internal/compat/flags/FeatureFlagsImpl;
-Lcom/android/internal/compat/flags/Flags;
Lcom/android/internal/config/appcloning/AppCloningDeviceConfigHelper$$ExternalSyntheticLambda0;
Lcom/android/internal/config/appcloning/AppCloningDeviceConfigHelper;
Lcom/android/internal/config/sysui/SystemUiSystemPropertiesFlags$DebugResolver;
@@ -43732,7 +43809,6 @@ Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$7;
Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$8;
Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$9;
Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$MassState;
-Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$OnAnimationEndListener;
Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$ViewProperty;
Lcom/android/internal/dynamicanimation/animation/DynamicAnimation;
Lcom/android/internal/dynamicanimation/animation/Force;
@@ -43752,15 +43828,6 @@ Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable$Aggregator;
Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable$BlurRegion;
Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable-IA;
Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable;
-Lcom/android/internal/hidden_from_bootclasspath/android/app/job/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/FeatureFlagsImpl;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/FeatureFlagsImpl;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/FeatureFlagsImpl;
Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/Flags;
Lcom/android/internal/infra/AbstractMultiplePendingRequestsRemoteService;
Lcom/android/internal/infra/AbstractRemoteService$AsyncRequest;
@@ -43924,7 +43991,8 @@ Lcom/android/internal/os/BinderCallsStats;
Lcom/android/internal/os/BinderDeathDispatcher$RecipientsInfo-IA;
Lcom/android/internal/os/BinderDeathDispatcher$RecipientsInfo;
Lcom/android/internal/os/BinderDeathDispatcher;
-Lcom/android/internal/os/BinderInternal$BinderProxyCountEventListenerDelegate;
+Lcom/android/internal/os/BinderInternal$BinderProxyLimitListener;
+Lcom/android/internal/os/BinderInternal$BinderProxyLimitListenerDelegate;
Lcom/android/internal/os/BinderInternal$CallSession;
Lcom/android/internal/os/BinderInternal$CallStatsObserver;
Lcom/android/internal/os/BinderInternal$GcWatcher;
@@ -43943,9 +44011,6 @@ Lcom/android/internal/os/CachedDeviceState$TimeInStateStopwatch;
Lcom/android/internal/os/CachedDeviceState;
Lcom/android/internal/os/ClassLoaderFactory;
Lcom/android/internal/os/Clock;
-Lcom/android/internal/os/FeatureFlags;
-Lcom/android/internal/os/FeatureFlagsImpl;
-Lcom/android/internal/os/Flags;
Lcom/android/internal/os/FuseAppLoop$1;
Lcom/android/internal/os/FuseAppLoop;
Lcom/android/internal/os/FuseUnavailableMountException;
@@ -44052,11 +44117,10 @@ Lcom/android/internal/os/ZygoteServer;
Lcom/android/internal/os/logging/MetricsLoggerWrapper;
Lcom/android/internal/pm/parsing/PackageParser2$Callback;
Lcom/android/internal/pm/parsing/PackageParserException;
-Lcom/android/internal/pm/pkg/component/flags/FeatureFlags;
-Lcom/android/internal/pm/pkg/component/flags/FeatureFlagsImpl;
Lcom/android/internal/pm/pkg/component/flags/Flags;
Lcom/android/internal/pm/pkg/parsing/ParsingPackageUtils$Callback;
Lcom/android/internal/policy/AttributeCache;
+Lcom/android/internal/policy/BackdropFrameRenderer;
Lcom/android/internal/policy/DecorContext;
Lcom/android/internal/policy/DecorView$$ExternalSyntheticLambda0;
Lcom/android/internal/policy/DecorView$$ExternalSyntheticLambda1;
@@ -44123,6 +44187,7 @@ Lcom/android/internal/protolog/common/IProtoLogGroup;
Lcom/android/internal/protolog/common/LogDataType;
Lcom/android/internal/security/VerityUtils;
Lcom/android/internal/statusbar/IAddTileResultCallback;
+Lcom/android/internal/statusbar/IStatusBar$Stub$Proxy;
Lcom/android/internal/statusbar/IStatusBar$Stub;
Lcom/android/internal/statusbar/IStatusBar;
Lcom/android/internal/statusbar/IStatusBarService$Stub$Proxy;
@@ -44205,8 +44270,6 @@ Lcom/android/internal/telephony/CarrierAppUtils;
Lcom/android/internal/telephony/CarrierInfoManager;
Lcom/android/internal/telephony/CarrierKeyDownloadManager$1;
Lcom/android/internal/telephony/CarrierKeyDownloadManager$2;
-Lcom/android/internal/telephony/CarrierKeyDownloadManager$3;
-Lcom/android/internal/telephony/CarrierKeyDownloadManager$DefaultNetworkCallback;
Lcom/android/internal/telephony/CarrierKeyDownloadManager;
Lcom/android/internal/telephony/CarrierPrivilegesTracker$1;
Lcom/android/internal/telephony/CarrierPrivilegesTracker;
@@ -44361,6 +44424,7 @@ Lcom/android/internal/telephony/IState;
Lcom/android/internal/telephony/ISub$Stub$Proxy;
Lcom/android/internal/telephony/ISub$Stub;
Lcom/android/internal/telephony/ISub;
+Lcom/android/internal/telephony/ITelephony$Stub$Proxy;
Lcom/android/internal/telephony/ITelephony$Stub;
Lcom/android/internal/telephony/ITelephony;
Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;
@@ -44535,6 +44599,7 @@ Lcom/android/internal/telephony/RIL;
Lcom/android/internal/telephony/RILConstants$$ExternalSyntheticLambda0;
Lcom/android/internal/telephony/RILConstants$$ExternalSyntheticLambda1;
Lcom/android/internal/telephony/RILConstants;
+Lcom/android/internal/telephony/RILRequest$$ExternalSyntheticLambda0;
Lcom/android/internal/telephony/RILRequest;
Lcom/android/internal/telephony/RadioBugDetector;
Lcom/android/internal/telephony/RadioCapability;
@@ -45186,7 +45251,6 @@ Lcom/android/internal/telephony/nano/PersistAtomsProto$CarrierIdMismatch;
Lcom/android/internal/telephony/nano/PersistAtomsProto$CellularDataServiceSwitch;
Lcom/android/internal/telephony/nano/PersistAtomsProto$CellularServiceState;
Lcom/android/internal/telephony/nano/PersistAtomsProto$DataCallSession;
-Lcom/android/internal/telephony/nano/PersistAtomsProto$DataNetworkValidation;
Lcom/android/internal/telephony/nano/PersistAtomsProto$EmergencyNumbersInfo;
Lcom/android/internal/telephony/nano/PersistAtomsProto$GbaEvent;
Lcom/android/internal/telephony/nano/PersistAtomsProto$ImsDedicatedBearerEvent;
@@ -45842,6 +45906,7 @@ Lcom/android/internal/widget/CachingIconView;
Lcom/android/internal/widget/ConversationLayout$1;
Lcom/android/internal/widget/ConversationLayout$TouchDelegateComposite;
Lcom/android/internal/widget/ConversationLayout;
+Lcom/android/internal/widget/DecorCaptionView;
Lcom/android/internal/widget/DecorContentParent;
Lcom/android/internal/widget/DecorToolbar;
Lcom/android/internal/widget/DialogTitle;
@@ -45906,11 +45971,8 @@ Lcom/android/internal/widget/floatingtoolbar/FloatingToolbar$$ExternalSyntheticL
Lcom/android/internal/widget/floatingtoolbar/FloatingToolbar$$ExternalSyntheticLambda1;
Lcom/android/internal/widget/floatingtoolbar/FloatingToolbar;
Lcom/android/internal/widget/floatingtoolbar/FloatingToolbarPopup;
-Lcom/android/media/flags/FeatureFlags;
-Lcom/android/media/flags/FeatureFlagsImpl;
Lcom/android/media/flags/Flags;
Lcom/android/modules/expresslog/Counter;
-Lcom/android/modules/expresslog/MetricIds$MetricInfo;
Lcom/android/modules/expresslog/MetricIds;
Lcom/android/modules/expresslog/StatsExpressLog;
Lcom/android/modules/utils/BasicShellCommandHandler;
@@ -45965,7 +46027,6 @@ Lcom/android/okhttp/HttpUrl$1;
Lcom/android/okhttp/HttpUrl$Builder$ParseResult;
Lcom/android/okhttp/HttpUrl$Builder;
Lcom/android/okhttp/HttpUrl;
-Lcom/android/okhttp/HttpsHandler;
Lcom/android/okhttp/Interceptor$Chain;
Lcom/android/okhttp/MediaType;
Lcom/android/okhttp/OkCacheContainer;
@@ -46046,7 +46107,6 @@ Lcom/android/okhttp/internal/http/StatusLine;
Lcom/android/okhttp/internal/http/StreamAllocation;
Lcom/android/okhttp/internal/huc/DelegatingHttpsURLConnection;
Lcom/android/okhttp/internal/huc/HttpURLConnectionImpl;
-Lcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;
Lcom/android/okhttp/internal/io/FileSystem$1;
Lcom/android/okhttp/internal/io/FileSystem;
Lcom/android/okhttp/internal/io/RealConnection;
@@ -46079,7 +46139,6 @@ Lcom/android/okhttp/okio/Okio$3;
Lcom/android/okhttp/okio/Okio;
Lcom/android/okhttp/okio/RealBufferedSink$1;
Lcom/android/okhttp/okio/RealBufferedSink;
-Lcom/android/okhttp/okio/RealBufferedSource$1;
Lcom/android/okhttp/okio/RealBufferedSource;
Lcom/android/okhttp/okio/Segment;
Lcom/android/okhttp/okio/SegmentPool;
@@ -46272,7 +46331,6 @@ Lcom/android/org/bouncycastle/jcajce/provider/keystore/PKCS12$Mappings;
Lcom/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi$Std;
Lcom/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi$StoreEntry;
Lcom/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi;
-Lcom/android/org/bouncycastle/jcajce/provider/symmetric/AES$ECB;
Lcom/android/org/bouncycastle/jcajce/provider/symmetric/AES$Mappings;
Lcom/android/org/bouncycastle/jcajce/provider/symmetric/AES;
Lcom/android/org/bouncycastle/jcajce/provider/symmetric/ARC4$Mappings;
@@ -46357,16 +46415,12 @@ Lcom/android/phone/ecc/nano/ProtobufEccData$CountryInfo;
Lcom/android/phone/ecc/nano/ProtobufEccData$EccInfo;
Lcom/android/phone/ecc/nano/UnknownFieldData;
Lcom/android/phone/ecc/nano/WireFormatNano;
-Lcom/android/sdksandbox/flags/FeatureFlags;
-Lcom/android/sdksandbox/flags/FeatureFlagsImpl;
Lcom/android/sdksandbox/flags/Flags;
Lcom/android/server/AppWidgetBackupBridge;
Lcom/android/server/LocalServices;
Lcom/android/server/WidgetBackupProvider;
Lcom/android/server/am/nano/Capabilities;
Lcom/android/server/am/nano/Capability;
-Lcom/android/server/am/nano/FrameworkCapability;
-Lcom/android/server/am/nano/VMCapability;
Lcom/android/server/backup/AccountManagerBackupHelper;
Lcom/android/server/backup/AccountSyncSettingsBackupHelper;
Lcom/android/server/backup/NotificationBackupHelper;
@@ -46395,7 +46449,6 @@ Lcom/android/server/connectivity/metrics/nano/IpConnectivityLogClass$WakeupStats
Lcom/android/server/criticalevents/nano/CriticalEventLogProto;
Lcom/android/server/criticalevents/nano/CriticalEventLogStorageProto;
Lcom/android/server/criticalevents/nano/CriticalEventProto$AppNotResponding;
-Lcom/android/server/criticalevents/nano/CriticalEventProto$ExcessiveBinderCalls;
Lcom/android/server/criticalevents/nano/CriticalEventProto$HalfWatchdog;
Lcom/android/server/criticalevents/nano/CriticalEventProto$InstallPackages;
Lcom/android/server/criticalevents/nano/CriticalEventProto$JavaCrash;
@@ -46446,9 +46499,6 @@ Lcom/android/server/sip/SipWakeLock;
Lcom/android/server/sip/SipWakeupTimer$MyEvent;
Lcom/android/server/sip/SipWakeupTimer$MyEventComparator;
Lcom/android/server/sip/SipWakeupTimer;
-Lcom/android/server/telecom/flags/FeatureFlags;
-Lcom/android/server/telecom/flags/FeatureFlagsImpl;
-Lcom/android/server/telecom/flags/Flags;
Lcom/android/server/usage/AppStandbyInternal$AppIdleStateChangeListener;
Lcom/android/server/usage/AppStandbyInternal;
Lcom/android/server/wm/nano/WindowManagerProtos$TaskSnapshotProto;
@@ -46509,7 +46559,6 @@ Ldalvik/system/AppSpecializationHooks;
Ldalvik/system/BaseDexClassLoader$Reporter;
Ldalvik/system/BaseDexClassLoader;
Ldalvik/system/BlockGuard$2;
-Ldalvik/system/BlockGuard$3;
Ldalvik/system/BlockGuard$BlockGuardPolicyException;
Ldalvik/system/BlockGuard$Policy;
Ldalvik/system/BlockGuard$VmPolicy;
@@ -46967,7 +47016,6 @@ Ljava/awt/font/NumericShaper;
Ljava/awt/font/TextAttribute;
Ljava/io/Bits;
Ljava/io/BufferedInputStream;
-Ljava/io/BufferedOutputStream;
Ljava/io/BufferedReader;
Ljava/io/BufferedWriter;
Ljava/io/ByteArrayInputStream;
@@ -47029,7 +47077,6 @@ Ljava/io/ObjectInputStream$ValidationList;
Ljava/io/ObjectInputStream;
Ljava/io/ObjectOutput;
Ljava/io/ObjectOutputStream$1;
-Ljava/io/ObjectOutputStream$BlockDataOutputStream;
Ljava/io/ObjectOutputStream$Caches;
Ljava/io/ObjectOutputStream$DebugTraceInfoStack;
Ljava/io/ObjectOutputStream$HandleTable;
@@ -47083,7 +47130,6 @@ Ljava/io/StringWriter;
Ljava/io/SyncFailedException;
Ljava/io/UTFDataFormatException;
Ljava/io/UncheckedIOException;
-Ljava/io/UnixFileSystem;
Ljava/io/UnsupportedEncodingException;
Ljava/io/WriteAbortedException;
Ljava/io/Writer;
@@ -47220,7 +47266,6 @@ Ljava/lang/String$$ExternalSyntheticLambda1;
Ljava/lang/String$$ExternalSyntheticLambda2;
Ljava/lang/String$$ExternalSyntheticLambda3;
Ljava/lang/String$CaseInsensitiveComparator-IA;
-Ljava/lang/String$CaseInsensitiveComparator;
Ljava/lang/String;
Ljava/lang/StringBuffer;
Ljava/lang/StringBuilder;
@@ -47247,7 +47292,6 @@ Ljava/lang/ThreadGroup;
Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
Ljava/lang/ThreadLocal$ThreadLocalMap-IA;
Ljava/lang/ThreadLocal$ThreadLocalMap;
-Ljava/lang/ThreadLocal;
Ljava/lang/Throwable$PrintStreamOrWriter-IA;
Ljava/lang/Throwable$PrintStreamOrWriter;
Ljava/lang/Throwable$SentinelHolder;
@@ -47482,9 +47526,7 @@ Ljava/net/Inet4Address;
Ljava/net/Inet6Address$Inet6AddressHolder-IA;
Ljava/net/Inet6Address$Inet6AddressHolder;
Ljava/net/Inet6Address;
-Ljava/net/Inet6AddressImpl;
Ljava/net/InetAddress$1;
-Ljava/net/InetAddress$InetAddressHolder;
Ljava/net/InetAddress;
Ljava/net/InetAddressImpl;
Ljava/net/InetSocketAddress$InetSocketAddressHolder-IA;
@@ -47547,6 +47589,7 @@ Ljava/nio/BufferUnderflowException;
Ljava/nio/ByteBuffer;
Ljava/nio/ByteBufferAsCharBuffer;
Ljava/nio/ByteBufferAsDoubleBuffer;
+Ljava/nio/ByteBufferAsLongBuffer;
Ljava/nio/ByteBufferAsShortBuffer;
Ljava/nio/ByteOrder;
Ljava/nio/CharBuffer;
@@ -47733,7 +47776,6 @@ Ljava/security/Security$1;
Ljava/security/Security;
Ljava/security/SecurityPermission;
Ljava/security/Signature$CipherAdapter;
-Ljava/security/Signature$Delegate;
Ljava/security/Signature;
Ljava/security/SignatureException;
Ljava/security/SignatureSpi;
@@ -48038,11 +48080,9 @@ Ljava/util/Collections$EmptySet-IA;
Ljava/util/Collections$ReverseComparator2;
Ljava/util/Collections$ReverseComparator;
Ljava/util/Collections$SequencedSetFromMap;
-Ljava/util/Collections$SetFromMap;
Ljava/util/Collections$SynchronizedList;
Ljava/util/Collections$SynchronizedNavigableMap;
Ljava/util/Collections$SynchronizedNavigableSet;
-Ljava/util/Collections$SynchronizedRandomAccessList;
Ljava/util/Collections$SynchronizedSet;
Ljava/util/Collections$SynchronizedSortedMap;
Ljava/util/Collections$SynchronizedSortedSet;
@@ -48058,7 +48098,6 @@ Ljava/util/Collections$UnmodifiableSequencedSet;
Ljava/util/Collections$UnmodifiableSortedMap;
Ljava/util/Collections;
Ljava/util/ComparableTimSort;
-Ljava/util/Comparator$$ExternalSyntheticLambda0;
Ljava/util/Comparator$$ExternalSyntheticLambda1;
Ljava/util/Comparator$$ExternalSyntheticLambda2;
Ljava/util/Comparator$$ExternalSyntheticLambda3;
@@ -48146,7 +48185,6 @@ Ljava/util/IdentityHashMap$ValueIterator;
Ljava/util/IdentityHashMap$Values-IA;
Ljava/util/IdentityHashMap$Values;
Ljava/util/IdentityHashMap;
-Ljava/util/IllegalFormatArgumentIndexException;
Ljava/util/IllegalFormatCodePointException;
Ljava/util/IllegalFormatConversionException;
Ljava/util/IllegalFormatException;
@@ -48170,9 +48208,6 @@ Ljava/util/Iterator;
Ljava/util/JumboEnumSet$EnumSetIterator;
Ljava/util/JumboEnumSet;
Ljava/util/KeyValueHolder;
-Ljava/util/LinkedHashMap$Entry;
-Ljava/util/LinkedHashMap$LinkedEntryIterator;
-Ljava/util/LinkedHashMap$LinkedEntrySet;
Ljava/util/LinkedHashMap$LinkedHashIterator;
Ljava/util/LinkedHashMap$ReversedLinkedHashMapView;
Ljava/util/LinkedHashMap;
@@ -48286,7 +48321,6 @@ Ljava/util/TooManyListenersException;
Ljava/util/TreeMap$AscendingSubMap$AscendingEntrySetView;
Ljava/util/TreeMap$AscendingSubMap;
Ljava/util/TreeMap$DescendingSubMap;
-Ljava/util/TreeMap$KeySet;
Ljava/util/TreeMap$NavigableSubMap$DescendingSubMapKeyIterator;
Ljava/util/TreeMap$NavigableSubMap$EntrySetView;
Ljava/util/TreeMap$NavigableSubMap$SubMapEntryIterator;
@@ -48460,7 +48494,6 @@ Ljava/util/concurrent/ThreadFactory;
Ljava/util/concurrent/ThreadLocalRandom;
Ljava/util/concurrent/ThreadPoolExecutor$AbortPolicy;
Ljava/util/concurrent/ThreadPoolExecutor$DiscardPolicy;
-Ljava/util/concurrent/ThreadPoolExecutor$Worker;
Ljava/util/concurrent/TimeUnit$1;
Ljava/util/concurrent/TimeUnit;
Ljava/util/concurrent/TimeoutException;
@@ -48773,7 +48806,6 @@ Ljava/util/stream/ReduceOps;
Ljava/util/stream/ReferencePipeline$$ExternalSyntheticLambda0;
Ljava/util/stream/ReferencePipeline$$ExternalSyntheticLambda1;
Ljava/util/stream/ReferencePipeline$15$1;
-Ljava/util/stream/ReferencePipeline$15;
Ljava/util/stream/ReferencePipeline$2$1;
Ljava/util/stream/ReferencePipeline$3$1;
Ljava/util/stream/ReferencePipeline$4$1;
@@ -48833,12 +48865,10 @@ Ljava/util/zip/CheckedInputStream;
Ljava/util/zip/Checksum$1;
Ljava/util/zip/Checksum;
Ljava/util/zip/DataFormatException;
-Ljava/util/zip/Deflater$DeflaterZStreamRef-IA;
Ljava/util/zip/Deflater$DeflaterZStreamRef;
Ljava/util/zip/Deflater;
Ljava/util/zip/DeflaterOutputStream;
Ljava/util/zip/GZIPInputStream$1;
-Ljava/util/zip/GZIPInputStream;
Ljava/util/zip/GZIPOutputStream;
Ljava/util/zip/Inflater$InflaterZStreamRef-IA;
Ljava/util/zip/Inflater$InflaterZStreamRef;
@@ -49100,13 +49130,10 @@ Ljdk/internal/access/JavaUtilCollectionAccess;
Ljdk/internal/access/SharedSecrets;
Ljdk/internal/math/FDBigInteger;
Ljdk/internal/math/FloatingDecimal$1;
-Ljdk/internal/math/FloatingDecimal$ASCIIToBinaryBuffer;
Ljdk/internal/math/FloatingDecimal$ASCIIToBinaryConverter;
-Ljdk/internal/math/FloatingDecimal$BinaryToASCIIBuffer;
Ljdk/internal/math/FloatingDecimal$BinaryToASCIIConverter;
Ljdk/internal/math/FloatingDecimal$ExceptionalBinaryToASCIIBuffer;
Ljdk/internal/math/FloatingDecimal$HexFloatPattern;
-Ljdk/internal/math/FloatingDecimal$PreparedASCIIToBinaryBuffer;
Ljdk/internal/math/FloatingDecimal;
Ljdk/internal/math/FormattedFloatingDecimal$1;
Ljdk/internal/math/FormattedFloatingDecimal$Form;
@@ -49117,6 +49144,7 @@ Ljdk/internal/misc/Unsafe;
Ljdk/internal/misc/UnsafeConstants;
Ljdk/internal/misc/VM;
Ljdk/internal/ref/CleanerFactory;
+Ljdk/internal/ref/CleanerImpl$PhantomCleanableRef;
Ljdk/internal/ref/CleanerImpl;
Ljdk/internal/ref/PhantomCleanable;
Ljdk/internal/reflect/Reflection;
@@ -49142,7 +49170,6 @@ Llibcore/icu/TimeZoneNames$ZoneStringsCache;
Llibcore/icu/TimeZoneNames;
Llibcore/internal/StringPool;
Llibcore/io/AsynchronousCloseMonitor;
-Llibcore/io/BlockGuardOs;
Llibcore/io/BufferIterator;
Llibcore/io/ClassPathURLStreamHandler$ClassPathURLConnection$1;
Llibcore/io/ClassPathURLStreamHandler$ClassPathURLConnection;
@@ -49192,7 +49219,6 @@ Llibcore/util/FP16;
Llibcore/util/HexEncoding;
Llibcore/util/NativeAllocationRegistry$CleanerRunner;
Llibcore/util/NativeAllocationRegistry$CleanerThunk;
-Llibcore/util/NativeAllocationRegistry;
Llibcore/util/Objects;
Llibcore/util/SneakyThrow;
Llibcore/util/XmlObjectFactory;
@@ -49214,9 +49240,7 @@ Lorg/apache/harmony/xml/dom/CDATASectionImpl;
Lorg/apache/harmony/xml/dom/CharacterDataImpl;
Lorg/apache/harmony/xml/dom/CommentImpl;
Lorg/apache/harmony/xml/dom/DOMImplementationImpl;
-Lorg/apache/harmony/xml/dom/DocumentImpl;
Lorg/apache/harmony/xml/dom/DocumentTypeImpl;
-Lorg/apache/harmony/xml/dom/ElementImpl;
Lorg/apache/harmony/xml/dom/EntityReferenceImpl;
Lorg/apache/harmony/xml/dom/InnerNodeImpl;
Lorg/apache/harmony/xml/dom/LeafNodeImpl;
@@ -49224,7 +49248,6 @@ Lorg/apache/harmony/xml/dom/NodeImpl$1;
Lorg/apache/harmony/xml/dom/NodeImpl;
Lorg/apache/harmony/xml/dom/NodeListImpl;
Lorg/apache/harmony/xml/dom/ProcessingInstructionImpl;
-Lorg/apache/harmony/xml/dom/TextImpl;
Lorg/apache/harmony/xml/parsers/DocumentBuilderFactoryImpl;
Lorg/apache/harmony/xml/parsers/DocumentBuilderImpl;
Lorg/apache/harmony/xml/parsers/SAXParserFactoryImpl;
@@ -49412,7 +49435,6 @@ Lsun/nio/fs/AbstractPath;
Lsun/nio/fs/DefaultFileSystemProvider;
Lsun/nio/fs/DynamicFileAttributeView;
Lsun/nio/fs/FileOwnerAttributeViewImpl;
-Lsun/nio/fs/LinuxFileSystem;
Lsun/nio/fs/LinuxFileSystemProvider;
Lsun/nio/fs/NativeBuffer$Deallocator;
Lsun/nio/fs/NativeBuffer;
@@ -49518,7 +49540,6 @@ Lsun/security/util/DerInputStream;
Lsun/security/util/DerOutputStream;
Lsun/security/util/DerValue;
Lsun/security/util/DisabledAlgorithmConstraints$Constraint$Operator;
-Lsun/security/util/DisabledAlgorithmConstraints$Constraint-IA;
Lsun/security/util/DisabledAlgorithmConstraints$Constraint;
Lsun/security/util/DisabledAlgorithmConstraints$Constraints;
Lsun/security/util/DisabledAlgorithmConstraints$KeySizeConstraint;
@@ -49759,8 +49780,6 @@ Lsun/util/logging/PlatformLogger;
[Landroid/graphics/fonts/FontVariationAxis;
[Landroid/hardware/CameraStatus;
[Landroid/hardware/biometrics/BiometricSourceType;
-[Landroid/hardware/camera2/CameraCharacteristics$Key;
-[Landroid/hardware/camera2/marshal/MarshalQueryable;
[Landroid/hardware/camera2/params/Capability;
[Landroid/hardware/camera2/params/Face;
[Landroid/hardware/camera2/params/HighSpeedVideoConfiguration;
@@ -49822,7 +49841,6 @@ Lsun/util/logging/PlatformLogger;
[Landroid/icu/impl/units/MeasureUnitImpl$InitialCompoundPart;
[Landroid/icu/impl/units/MeasureUnitImpl$PowerPart;
[Landroid/icu/impl/units/MeasureUnitImpl$UnitsParser$Token$Type;
-[Landroid/icu/lang/UCharacter$IdentifierType;
[Landroid/icu/lang/UCharacter$UnicodeBlock;
[Landroid/icu/lang/UScript$ScriptUsage;
[Landroid/icu/lang/UScriptRun$ParenStackEntry;
@@ -50080,7 +50098,6 @@ Lsun/util/logging/PlatformLogger;
[Landroid/widget/SpellChecker$SpellParser;
[Landroid/widget/TextView$BufferType;
[Landroid/widget/TextView$ChangeWatcher;
-[Landroid/window/BackTouchTracker$TouchTrackerState;
[Landroid/window/TransitionFilter$Requirement;
[Lcom/android/framework/protobuf/GeneratedMessageLite$MethodToInvoke;
[Lcom/android/framework/protobuf/MessageInfoFactory;
@@ -50180,7 +50197,6 @@ Lsun/util/logging/PlatformLogger;
[Lgov/nist/javax/sip/DialogTimeoutEvent$Reason;
[Ljava/io/File$PathStatus;
[Ljava/io/File;
-[Ljava/io/InputStream;
[Ljava/io/ObjectInputStream$HandleTable$HandleList;
[Ljava/io/ObjectStreamClass$ClassDataSlot;
[Ljava/io/ObjectStreamClass$MemberSignature;
diff --git a/core/api/current.txt b/core/api/current.txt
index 5456c15040ce..0f237212c768 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1058,7 +1058,7 @@ package android {
field public static final int label = 16842753; // 0x1010001
field public static final int labelFor = 16843718; // 0x10103c6
field @Deprecated public static final int labelTextSize = 16843317; // 0x1010235
- field @FlaggedApi("android.view.inputmethod.ime_switcher_revamp") public static final int languageSettingsActivity;
+ field @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") public static final int languageSettingsActivity;
field public static final int languageTag = 16844040; // 0x1010508
field public static final int largeHeap = 16843610; // 0x101035a
field public static final int largeScreens = 16843398; // 0x1010286
@@ -6844,6 +6844,9 @@ package android.app {
method public android.app.Notification.MessagingStyle.Message setData(String, android.net.Uri);
}
+ @FlaggedApi("android.app.api_rich_ongoing") public abstract static class Notification.RichOngoingStyle extends android.app.Notification.Style {
+ }
+
public abstract static class Notification.Style {
ctor @Deprecated public Notification.Style();
method public android.app.Notification build();
@@ -11394,7 +11397,7 @@ package android.content {
field public static final String EXTRA_LOCALE_LIST = "android.intent.extra.LOCALE_LIST";
field public static final String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY";
field public static final String EXTRA_LOCUS_ID = "android.intent.extra.LOCUS_ID";
- field @FlaggedApi("android.service.chooser.enable_sharesheet_metadata_extra") public static final String EXTRA_METADATA_TEXT = "android.intent.extra.METADATA_TEXT";
+ field public static final String EXTRA_METADATA_TEXT = "android.intent.extra.METADATA_TEXT";
field public static final String EXTRA_MIME_TYPES = "android.intent.extra.MIME_TYPES";
field public static final String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE";
field public static final String EXTRA_ORIGINATING_URI = "android.intent.extra.ORIGINATING_URI";
@@ -11603,6 +11606,7 @@ package android.content {
method public static android.content.IntentSender readIntentSenderOrNullFromParcel(android.os.Parcel);
method public void sendIntent(android.content.Context, int, android.content.Intent, android.content.IntentSender.OnFinished, android.os.Handler) throws android.content.IntentSender.SendIntentException;
method public void sendIntent(android.content.Context, int, android.content.Intent, android.content.IntentSender.OnFinished, android.os.Handler, String) throws android.content.IntentSender.SendIntentException;
+ method @FlaggedApi("com.android.window.flags.bal_send_intent_with_options") public void sendIntent(@Nullable android.content.Context, int, @Nullable android.content.Intent, @Nullable String, @Nullable android.os.Bundle, @Nullable java.util.concurrent.Executor, @Nullable android.content.IntentSender.OnFinished) throws android.content.IntentSender.SendIntentException;
method public static void writeIntentSenderOrNullToParcel(android.content.IntentSender, android.os.Parcel);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.IntentSender> CREATOR;
@@ -12043,6 +12047,7 @@ package android.content.pm {
field public static final int COLOR_MODE_DEFAULT = 0; // 0x0
field public static final int COLOR_MODE_HDR = 2; // 0x2
field public static final int COLOR_MODE_WIDE_COLOR_GAMUT = 1; // 0x1
+ field @FlaggedApi("android.content.res.handle_all_config_changes") public static final int CONFIG_ASSETS_PATHS = -2147483648; // 0x80000000
field public static final int CONFIG_COLOR_MODE = 16384; // 0x4000
field public static final int CONFIG_DENSITY = 4096; // 0x1000
field public static final int CONFIG_FONT_SCALE = 1073741824; // 0x40000000
@@ -12056,6 +12061,7 @@ package android.content.pm {
field public static final int CONFIG_MNC = 2; // 0x2
field public static final int CONFIG_NAVIGATION = 64; // 0x40
field public static final int CONFIG_ORIENTATION = 128; // 0x80
+ field @FlaggedApi("android.content.res.handle_all_config_changes") public static final int CONFIG_RESOURCES_UNUSED = 134217728; // 0x8000000
field public static final int CONFIG_SCREEN_LAYOUT = 256; // 0x100
field public static final int CONFIG_SCREEN_SIZE = 1024; // 0x400
field public static final int CONFIG_SMALLEST_SCREEN_SIZE = 2048; // 0x800
@@ -12494,6 +12500,7 @@ package android.content.pm {
method @FlaggedApi("android.os.allow_private_profile") @Nullable @RequiresPermission(conditional=true, anyOf={"android.permission.ACCESS_HIDDEN_PROFILES_FULL", android.Manifest.permission.ACCESS_HIDDEN_PROFILES}) public final android.content.pm.LauncherUserInfo getLauncherUserInfo(@NonNull android.os.UserHandle);
method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent);
method @FlaggedApi("android.os.allow_private_profile") @NonNull @RequiresPermission(conditional=true, anyOf={"android.permission.ACCESS_HIDDEN_PROFILES_FULL", android.Manifest.permission.ACCESS_HIDDEN_PROFILES}) public java.util.List<java.lang.String> getPreInstalledSystemPackages(@NonNull android.os.UserHandle);
+ method @FlaggedApi("android.os.get_private_space_settings") @Nullable @RequiresPermission(conditional=true, anyOf={"android.permission.ACCESS_HIDDEN_PROFILES_FULL", android.Manifest.permission.ACCESS_HIDDEN_PROFILES}) public android.content.IntentSender getPrivateSpaceSettingsIntent();
method @RequiresPermission(conditional=true, anyOf={"android.permission.ACCESS_HIDDEN_PROFILES_FULL", android.Manifest.permission.ACCESS_HIDDEN_PROFILES}) public java.util.List<android.os.UserHandle> getProfiles();
method public android.graphics.drawable.Drawable getShortcutBadgedIconDrawable(android.content.pm.ShortcutInfo, int);
method @Nullable public android.content.IntentSender getShortcutConfigActivityIntent(@NonNull android.content.pm.LauncherActivityInfo);
@@ -20355,6 +20362,7 @@ package android.hardware.display {
method public android.view.Surface getSurface();
method public void release();
method public void resize(int, int, int);
+ method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_rotation_api") public void setRotation(int);
method public void setSurface(android.view.Surface);
}
@@ -26585,7 +26593,7 @@ package android.media.projection {
public final class MediaProjectionManager {
method @NonNull public android.content.Intent createScreenCaptureIntent();
method @NonNull public android.content.Intent createScreenCaptureIntent(@NonNull android.media.projection.MediaProjectionConfig);
- method public android.media.projection.MediaProjection getMediaProjection(int, @NonNull android.content.Intent);
+ method @Nullable public android.media.projection.MediaProjection getMediaProjection(int, @NonNull android.content.Intent);
}
}
@@ -56330,7 +56338,7 @@ package android.view.inputmethod {
public final class InputMethodInfo implements android.os.Parcelable {
ctor public InputMethodInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
ctor public InputMethodInfo(String, String, CharSequence, String);
- method @FlaggedApi("android.view.inputmethod.ime_switcher_revamp") @Nullable public android.content.Intent createImeLanguageSettingsActivityIntent();
+ method @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") @Nullable public android.content.Intent createImeLanguageSettingsActivityIntent();
method @Nullable public android.content.Intent createStylusHandwritingSettingsActivityIntent();
method public int describeContents();
method public void dump(android.util.Printer, String);
@@ -56351,7 +56359,7 @@ package android.view.inputmethod {
method public boolean supportsStylusHandwriting();
method public boolean suppressesSpellChecker();
method public void writeToParcel(android.os.Parcel, int);
- field @FlaggedApi("android.view.inputmethod.ime_switcher_revamp") public static final String ACTION_IME_LANGUAGE_SETTINGS = "android.view.inputmethod.action.IME_LANGUAGE_SETTINGS";
+ field @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") public static final String ACTION_IME_LANGUAGE_SETTINGS = "android.view.inputmethod.action.IME_LANGUAGE_SETTINGS";
field public static final String ACTION_STYLUS_HANDWRITING_SETTINGS = "android.view.inputmethod.action.STYLUS_HANDWRITING_SETTINGS";
field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.InputMethodInfo> CREATOR;
}
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index e4a840745ab3..7ae5d1be9773 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -674,7 +674,7 @@ package android.webkit {
method @Nullable public String getCurrentWebViewPackageName();
method @FlaggedApi("android.webkit.update_service_v2") @NonNull public android.webkit.WebViewProviderInfo getDefaultWebViewPackage();
method @Nullable public static android.webkit.WebViewUpdateManager getInstance();
- method @NonNull public android.webkit.WebViewProviderInfo[] getValidWebViewPackages();
+ method @NonNull @RequiresPermission(allOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.QUERY_ALL_PACKAGES}) public android.webkit.WebViewProviderInfo[] getValidWebViewPackages();
method @NonNull public android.webkit.WebViewProviderResponse waitForAndGetProvider();
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index cd2c9ca55959..36a335e97d33 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3775,6 +3775,7 @@ package android.content {
method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public android.content.Intent registerReceiverForAllUsers(@Nullable android.content.BroadcastReceiver, @NonNull android.content.IntentFilter, @Nullable String, @Nullable android.os.Handler, int);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, @Nullable android.os.Bundle);
method public void sendBroadcastMultiplePermissions(@NonNull android.content.Intent, @NonNull String[], @Nullable android.app.BroadcastOptions);
+ method @FlaggedApi("android.os.ordered_broadcast_multiple_permissions") public void sendOrderedBroadcastMultiplePermissions(@NonNull android.content.Intent, @NonNull String[], @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle, @Nullable android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
field public static final String AMBIENT_CONTEXT_SERVICE = "ambient_context";
@@ -5161,10 +5162,12 @@ package android.hardware.display {
}
public final class VirtualDisplayConfig implements android.os.Parcelable {
+ method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_insets") @Nullable public android.view.DisplayCutout getDisplayCutout();
method @FlaggedApi("android.companion.virtual.flags.vdm_custom_home") public boolean isHomeSupported();
}
public static final class VirtualDisplayConfig.Builder {
+ method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_insets") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setDisplayCutout(@Nullable android.view.DisplayCutout);
method @FlaggedApi("android.companion.virtual.flags.vdm_custom_home") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setHomeSupported(boolean);
}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index b7de93aaaee3..44c4ab4e1b57 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1796,8 +1796,10 @@ package android.hardware.input {
public class InputSettings {
method @FlaggedApi("com.android.hardware.input.keyboard_a11y_bounce_keys_flag") public static int getAccessibilityBounceKeysThreshold(@NonNull android.content.Context);
method @FlaggedApi("com.android.hardware.input.keyboard_a11y_slow_keys_flag") public static int getAccessibilitySlowKeysThreshold(@NonNull android.content.Context);
+ method @FlaggedApi("com.android.hardware.input.keyboard_a11y_mouse_keys") public static boolean isAccessibilityMouseKeysEnabled(@NonNull android.content.Context);
method @FlaggedApi("com.android.hardware.input.keyboard_a11y_sticky_keys_flag") public static boolean isAccessibilityStickyKeysEnabled(@NonNull android.content.Context);
method @FlaggedApi("com.android.hardware.input.keyboard_a11y_bounce_keys_flag") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilityBounceKeysThreshold(@NonNull android.content.Context, int);
+ method @FlaggedApi("com.android.hardware.input.keyboard_a11y_mouse_keys") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilityMouseKeysEnabled(@NonNull android.content.Context, boolean);
method @FlaggedApi("com.android.hardware.input.keyboard_a11y_slow_keys_flag") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilitySlowKeysThreshold(@NonNull android.content.Context, int);
method @FlaggedApi("com.android.hardware.input.keyboard_a11y_sticky_keys_flag") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilityStickyKeysEnabled(@NonNull android.content.Context, boolean);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static void setMaximumObscuringOpacityForTouch(@NonNull android.content.Context, @FloatRange(from=0, to=1) float);
@@ -1982,6 +1984,7 @@ package android.media {
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public float getRs2Value();
method public int getStreamMinVolumeInt(int);
method @NonNull public java.util.Map<java.lang.Integer,java.lang.Boolean> getSurroundFormats();
+ method @NonNull public android.media.VolumePolicy getVolumePolicy();
method public boolean hasRegisteredDynamicPolicy();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public boolean isCsdEnabled();
method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public boolean isFullVolumeDevice();
@@ -2073,6 +2076,20 @@ package android.media {
method public android.media.PlaybackParams setAudioStretchMode(int);
}
+ public final class VolumePolicy implements android.os.Parcelable {
+ ctor public VolumePolicy(boolean, boolean, boolean, int);
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int A11Y_MODE_INDEPENDENT_A11Y_VOLUME = 1; // 0x1
+ field public static final int A11Y_MODE_MEDIA_A11Y_VOLUME = 0; // 0x0
+ field @NonNull public static final android.os.Parcelable.Creator<android.media.VolumePolicy> CREATOR;
+ field @NonNull public static final android.media.VolumePolicy DEFAULT;
+ field public final boolean doNotDisturbWhenSilent;
+ field public final int vibrateToSilentDebounce;
+ field public final boolean volumeDownToEnterSilent;
+ field public final boolean volumeUpToExitSilent;
+ }
+
public static final class VolumeShaper.Configuration.Builder {
method @NonNull public android.media.VolumeShaper.Configuration.Builder setOptionFlags(int);
}
@@ -2775,12 +2792,6 @@ package android.os.vibrator.persistence {
@FlaggedApi("android.os.vibrator.vibration_xml_apis") public final class ParsedVibration {
ctor public ParsedVibration(@NonNull java.util.List<android.os.VibrationEffect>);
- method @FlaggedApi("android.os.vibrator.vibration_xml_apis") @Nullable public android.os.VibrationEffect resolve(@NonNull android.os.Vibrator);
- }
-
- @FlaggedApi("android.os.vibrator.vibration_xml_apis") public final class VibrationXmlParser {
- method @FlaggedApi("android.os.vibrator.vibration_xml_apis") @NonNull public static android.os.vibrator.persistence.ParsedVibration parse(@NonNull java.io.InputStream) throws java.io.IOException;
- method @FlaggedApi("android.os.vibrator.vibration_xml_apis") @NonNull public static android.os.VibrationEffect parseVibrationEffect(@NonNull java.io.InputStream) throws java.io.IOException;
}
public static final class VibrationXmlParser.ParseFailedException extends java.io.IOException {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 0947e33cb4d1..85b6e51bbe9b 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -21,6 +21,7 @@ import static android.Manifest.permission.DETECT_SCREEN_CAPTURE;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+import static android.app.Instrumentation.DEBUG_FINISH_ACTIVITY;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.inMultiWindowMode;
import static android.os.Process.myUid;
@@ -5822,7 +5823,8 @@ public class Activity extends ContextThemeWrapper
*
* @param intent The intent to start.
* @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits.
+ * onActivityResult() when the activity exits;
+ * If < 0, no result will return when the activity exits.
*
* @throws android.content.ActivityNotFoundException
*
@@ -5857,7 +5859,8 @@ public class Activity extends ContextThemeWrapper
*
* @param intent The intent to start.
* @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits.
+ * onActivityResult() when the activity exits;
+ * If < 0, no result will return when the activity exits.
* @param options Additional options for how the Activity should be started.
* See {@link android.content.Context#startActivity(Intent, Bundle)}
* Context.startActivity(Intent, Bundle)} for more details.
@@ -5965,7 +5968,8 @@ public class Activity extends ContextThemeWrapper
*
* @param intent The intent to start.
* @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits.
+ * onActivityResult() when the activity exits;
+ * If < 0, no result will return when the activity exits.
* @param user The user to start the intent as.
* @hide Implement to provide correct calling token.
*/
@@ -6001,7 +6005,8 @@ public class Activity extends ContextThemeWrapper
*
* @param intent The intent to start.
* @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits.
+ * onActivityResult() when the activity exits;
+ * If < 0, no result will return when the activity exits.
* @param options Additional options for how the Activity should be started. See {@link
* android.content.Context#startActivity(Intent, Bundle)} for more details.
* @param user The user to start the intent as.
@@ -6039,7 +6044,8 @@ public class Activity extends ContextThemeWrapper
*
* @param intent The intent to start.
* @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits.
+ * onActivityResult() when the activity exits;
+ * If < 0, no result will return when the activity exits.
* @param options Additional options for how the Activity should be started. See {@link
* android.content.Context#startActivity(Intent, Bundle)} for more details.
* @param user The user to start the intent as.
@@ -6165,7 +6171,8 @@ public class Activity extends ContextThemeWrapper
*
* @param intent The IntentSender to launch.
* @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits.
+ * onActivityResult() when the activity exits;
+ * If < 0, no result will return when the activity exits.
* @param fillInIntent If non-null, this will be provided as the
* intent parameter to {@link IntentSender#sendIntent}.
* @param flagsMask Intent flags in the original IntentSender that you
@@ -6204,7 +6211,8 @@ public class Activity extends ContextThemeWrapper
*
* @param intent The IntentSender to launch.
* @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits.
+ * onActivityResult() when the activity exits;
+ * If < 0, no result will return when the activity exits.
* @param fillInIntent If non-null, this will be provided as the
* intent parameter to {@link IntentSender#sendIntent}.
* @param flagsMask Intent flags in the original IntentSender that you
@@ -6436,8 +6444,8 @@ public class Activity extends ContextThemeWrapper
*
* @param intent The intent to start.
* @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits, as described in
- * {@link #startActivityForResult}.
+ * onActivityResult() when the activity exits; If < 0, no result will
+ * return when the activity exits, as described in {@link #startActivityForResult}.
*
* @return If a new activity was launched then true is returned; otherwise
* false is returned and you must handle the Intent yourself.
@@ -6468,7 +6476,8 @@ public class Activity extends ContextThemeWrapper
*
* @param intent The intent to start.
* @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits, as described in
+ * onActivityResult() when the activity exits; If < 0, no result
+ * will return when the activity exits, as described in
* {@link #startActivityForResult}.
* @param options Additional options for how the Activity should be started.
* See {@link android.content.Context#startActivity(Intent, Bundle)}
@@ -7297,6 +7306,9 @@ public class Activity extends ContextThemeWrapper
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private void finish(int finishTask) {
+ if (DEBUG_FINISH_ACTIVITY) {
+ Log.d("Instrumentation", "finishActivity: finishTask=" + finishTask, new Throwable());
+ }
if (mParent == null) {
int resultCode;
Intent resultData;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b384326201fc..36b1eaba89df 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -30,6 +30,7 @@ import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP;
import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE;
import static android.content.ContentResolver.DEPRECATE_DATA_COLUMNS;
import static android.content.ContentResolver.DEPRECATE_DATA_PREFIX;
+import static android.content.pm.ActivityInfo.CONFIG_RESOURCES_UNUSED;
import static android.content.res.Configuration.UI_MODE_TYPE_DESK;
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -41,7 +42,6 @@ import static android.window.ConfigurationHelper.shouldUpdateResources;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.internal.os.SafeZipPathValidatorCallback.VALIDATE_ZIP_PATH_FOR_PATH_TRAVERSAL;
import static com.android.sdksandbox.flags.Flags.sandboxActivitySdkBasedContext;
-import static com.android.window.flags.Flags.activityWindowInfoFlag;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -6520,6 +6520,13 @@ public final class ActivityThread extends ClientTransactionHandler
return true;
}
+ if (android.content.res.Flags.handleAllConfigChanges()) {
+ if ((handledConfigChanges & CONFIG_RESOURCES_UNUSED) != 0) {
+ // Report the change if activities claim they do not use resources at all.
+ return true;
+ }
+ }
+
final int diffWithBucket = SizeConfigurationBuckets.filterDiff(publicDiff, currentConfig,
newConfig, sizeBuckets);
// Compare to the diff which filter the change without crossing size buckets with
@@ -6846,9 +6853,6 @@ public final class ActivityThread extends ClientTransactionHandler
}
private void handleActivityWindowInfoChanged(@NonNull ActivityClientRecord r) {
- if (!activityWindowInfoFlag()) {
- return;
- }
if (r.mActivityWindowInfo.equals(r.mLastReportedActivityWindowInfo)) {
return;
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index baed4fd02e5b..7e2a580bec73 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1552,6 +1552,17 @@ class ContextImpl extends Context {
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+ String[] receiverPermissions = receiverPermission == null ? null
+ : new String[] {receiverPermission};
+ sendOrderedBroadcastAsUserMultiplePermissions(intent, user, receiverPermissions, appOp,
+ options, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+
+ @Override
+ public void sendOrderedBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
+ String[] receiverPermissions, int appOp, Bundle options,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
IIntentReceiver rd = null;
if (resultReceiver != null) {
if (mPackageInfo != null) {
@@ -1571,8 +1582,6 @@ class ContextImpl extends Context {
}
}
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
- String[] receiverPermissions = receiverPermission == null ? null
- : new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess(this);
ActivityManager.getService().broadcastIntentWithFeature(
@@ -1599,6 +1608,20 @@ class ContextImpl extends Context {
}
@Override
+ public void sendOrderedBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions,
+ String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
+ int initialCode, String initialData, @Nullable Bundle initialExtras,
+ @Nullable Bundle options) {
+ int intAppOp = AppOpsManager.OP_NONE;
+ if (!TextUtils.isEmpty(receiverAppOp)) {
+ intAppOp = AppOpsManager.strOpToOp(receiverAppOp);
+ }
+ sendOrderedBroadcastAsUserMultiplePermissions(intent, getUser(), receiverPermissions,
+ intAppOp, options, resultReceiver, scheduler, initialCode, initialData,
+ initialExtras);
+ }
+
+ @Override
public void sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission,
String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
String initialData, @Nullable Bundle initialExtras, Bundle options) {
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index db216b1af974..be270463e576 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -107,6 +107,8 @@ public class Instrumentation {
// If set, will print the stack trace for activity starts within the process
static final boolean DEBUG_START_ACTIVITY = Build.IS_DEBUGGABLE &&
SystemProperties.getBoolean("persist.wm.debug.start_activity", false);
+ static final boolean DEBUG_FINISH_ACTIVITY = Build.IS_DEBUGGABLE &&
+ SystemProperties.getBoolean("persist.wm.debug.finish_activity", false);
/**
* @hide
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index aea15e13e5d6..ef09dc45d423 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -762,6 +762,16 @@ public class Notification implements Parcelable
@FlaggedApi(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR)
public static final int FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY = 0x00010000;
+ /**
+ * Bit to be bitwise-ored into the {@link #flags} field that should be
+ * set by the system if this notification is silent.
+ *
+ * This flag is for internal use only; applications cannot set this flag directly.
+ * @hide
+ */
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+ public static final int FLAG_SILENT = 1 << 17; //0x00020000
+
private static final List<Class<? extends Style>> PLATFORM_STYLE_CLASSES = Arrays.asList(
BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class,
DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class,
@@ -784,7 +794,8 @@ public class Notification implements Parcelable
FLAG_BUBBLE,
FLAG_NO_DISMISS,
FLAG_FSI_REQUESTED_BUT_DENIED,
- FLAG_USER_INITIATED_JOB
+ FLAG_USER_INITIATED_JOB,
+ FLAG_SILENT
})
@Retention(RetentionPolicy.SOURCE)
public @interface NotificationFlags{};
@@ -1692,6 +1703,7 @@ public class Notification implements Parcelable
*
* @hide
*/
+ @Deprecated
public static final String GROUP_KEY_SILENT = "silent";
private int mGroupAlertBehavior = GROUP_ALERT_ALL;
@@ -3984,6 +3996,13 @@ public class Notification implements Parcelable
}
}
+ if (android.service.notification.Flags.notificationSilentFlag()) {
+ if ((flags & FLAG_SILENT) != 0) {
+ flagStrings.add("SILENT");
+ flags &= ~FLAG_SILENT;
+ }
+ }
+
if (flagStrings.isEmpty()) {
return "0";
}
@@ -4123,6 +4142,17 @@ public class Notification implements Parcelable
}
/**
+ * Sets which type of notifications in a group are responsible for audibly alerting the
+ * user. See {@link #GROUP_ALERT_ALL}, {@link #GROUP_ALERT_CHILDREN},
+ * {@link #GROUP_ALERT_SUMMARY}.
+ * @param groupAlertBehavior
+ * @hide
+ */
+ public void setGroupAlertBehavior(@GroupAlertBehavior int groupAlertBehavior) {
+ mGroupAlertBehavior = groupAlertBehavior;
+ }
+
+ /**
* Returns the bubble metadata that will be used to display app content in a floating window
* over the existing foreground activity.
*/
@@ -4309,6 +4339,31 @@ public class Notification implements Parcelable
}
/**
+ * Sets the FLAG_SILENT flag to mark the notification as silent and clears the group key.
+ * @hide
+ */
+ public void fixSilentGroup() {
+ if (android.service.notification.Flags.notificationSilentFlag()) {
+ if (GROUP_KEY_SILENT.equals(mGroupKey)) {
+ mGroupKey = null;
+ flags |= FLAG_SILENT;
+ }
+ }
+ }
+
+ /**
+ * @return whether this notification is silent. See {@link Builder#setSilent()}
+ * @hide
+ */
+ public boolean isSilent() {
+ if (android.service.notification.Flags.notificationSilentFlag()) {
+ return (flags & Notification.FLAG_SILENT) != 0;
+ } else {
+ return GROUP_KEY_SILENT.equals(getGroup()) && suppressAlertingDueToGrouping();
+ }
+ }
+
+ /**
* Builder class for {@link Notification} objects.
*
* Provides a convenient way to set the various fields of a {@link Notification} and generate
@@ -4759,8 +4814,12 @@ public class Notification implements Parcelable
mN.defaults &= ~DEFAULT_VIBRATE;
setDefaults(mN.defaults);
- if (TextUtils.isEmpty(mN.mGroupKey)) {
- setGroup(GROUP_KEY_SILENT);
+ if (android.service.notification.Flags.notificationSilentFlag()) {
+ mN.flags |= FLAG_SILENT;
+ } else {
+ if (TextUtils.isEmpty(mN.mGroupKey)) {
+ setGroup(GROUP_KEY_SILENT);
+ }
}
return this;
}
@@ -10920,6 +10979,18 @@ public class Notification implements Parcelable
}
/**
+ * An object that can apply a rich ongoing notification style to a {@link Notification.Builder}
+ * object.
+ */
+ @FlaggedApi(Flags.FLAG_API_RICH_ONGOING)
+ public abstract static class RichOngoingStyle extends Notification.Style {
+ /**
+ * @hide
+ */
+ public RichOngoingStyle() {}
+ }
+
+ /**
* Notification style for custom views that are decorated by the system
*
* <p>Instead of providing a notification that is completely custom, a developer can set this
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 1050e1d4b30f..fd4d8e90adf9 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -74,7 +74,7 @@ public class ResourcesManager {
static final String TAG = "ResourcesManager";
private static final boolean DEBUG = false;
- private static ResourcesManager sResourcesManager;
+ private static volatile ResourcesManager sResourcesManager;
/**
* Internal lock object
@@ -359,17 +359,20 @@ public class ResourcesManager {
sResourcesManager = resourcesManager;
return oldResourceManager;
}
-
}
@UnsupportedAppUsage
public static ResourcesManager getInstance() {
- synchronized (ResourcesManager.class) {
- if (sResourcesManager == null) {
- sResourcesManager = new ResourcesManager();
+ var rm = sResourcesManager;
+ if (rm == null) {
+ synchronized (ResourcesManager.class) {
+ rm = sResourcesManager;
+ if (rm == null) {
+ sResourcesManager = rm = new ResourcesManager();
+ }
}
- return sResourcesManager;
}
+ return rm;
}
/**
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index ef8501f563dc..531537c374ce 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -30,6 +30,7 @@ import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
+import android.net.Uri;
import android.os.Build;
import android.os.IBinder;
import android.os.Parcel;
@@ -297,6 +298,25 @@ public class TaskInfo {
public boolean isTopActivityTransparent;
/**
+ * Whether the top activity has specified style floating.
+ * @hide
+ */
+ public boolean isTopActivityStyleFloating;
+
+ /**
+ * The URI of the intent that generated the top-most activity opened using a URL.
+ * @hide
+ */
+ @Nullable
+ public Uri capturedLink;
+
+ /**
+ * The time of the last launch of the activity opened using the {@link #capturedLink}.
+ * @hide
+ */
+ public long capturedLinkTimestamp;
+
+ /**
* Encapsulate specific App Compat information.
* @hide
*/
@@ -429,6 +449,9 @@ public class TaskInfo {
&& parentTaskId == that.parentTaskId
&& Objects.equals(topActivity, that.topActivity)
&& isTopActivityTransparent == that.isTopActivityTransparent
+ && isTopActivityStyleFloating == that.isTopActivityStyleFloating
+ && Objects.equals(capturedLink, that.capturedLink)
+ && capturedLinkTimestamp == that.capturedLinkTimestamp
&& appCompatTaskInfo.equalsForTaskOrganizer(that.appCompatTaskInfo);
}
@@ -498,6 +521,9 @@ public class TaskInfo {
mTopActivityLocusId = source.readTypedObject(LocusId.CREATOR);
displayAreaFeatureId = source.readInt();
isTopActivityTransparent = source.readBoolean();
+ isTopActivityStyleFloating = source.readBoolean();
+ capturedLink = source.readTypedObject(Uri.CREATOR);
+ capturedLinkTimestamp = source.readLong();
appCompatTaskInfo = source.readTypedObject(AppCompatTaskInfo.CREATOR);
}
@@ -545,6 +571,9 @@ public class TaskInfo {
dest.writeTypedObject(mTopActivityLocusId, flags);
dest.writeInt(displayAreaFeatureId);
dest.writeBoolean(isTopActivityTransparent);
+ dest.writeBoolean(isTopActivityStyleFloating);
+ dest.writeTypedObject(capturedLink, flags);
+ dest.writeLong(capturedLinkTimestamp);
dest.writeTypedObject(appCompatTaskInfo, flags);
}
@@ -582,6 +611,9 @@ public class TaskInfo {
+ " locusId=" + mTopActivityLocusId
+ " displayAreaFeatureId=" + displayAreaFeatureId
+ " isTopActivityTransparent=" + isTopActivityTransparent
+ + " isTopActivityStyleFloating=" + isTopActivityStyleFloating
+ + " capturedLink=" + capturedLink
+ + " capturedLinkTimestamp=" + capturedLinkTimestamp
+ " appCompatTaskInfo=" + appCompatTaskInfo
+ "}";
}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 257aff04a09f..1a72df10fbd6 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -262,13 +262,6 @@ public class WallpaperManager {
public static final String COMMAND_GOING_TO_SLEEP = "android.wallpaper.goingtosleep";
/**
- * Command for {@link #sendWallpaperCommand}: reported when a physical display switch event
- * happens, e.g. fold and unfold.
- * @hide
- */
- public static final String COMMAND_DISPLAY_SWITCH = "android.wallpaper.displayswitch";
-
- /**
* Command for {@link #sendWallpaperCommand}: reported when the wallpaper that was already
* set is re-applied by the user.
* @hide
diff --git a/core/java/android/app/admin/OWNERS b/core/java/android/app/admin/OWNERS
index 308f1d622c25..4f3f5d9c3535 100644
--- a/core/java/android/app/admin/OWNERS
+++ b/core/java/android/app/admin/OWNERS
@@ -1,7 +1,6 @@
# Bug component: 142675
# Assign bugs to device-policy-manager-triage@google.com
-file:WorkDeviceExperience_OWNERS
file:EnterprisePlatformSecurity_OWNERS
yamasani@google.com #{LAST_RESORT_SUGGESTION} \ No newline at end of file
diff --git a/core/java/android/app/assist/OWNERS b/core/java/android/app/assist/OWNERS
index e4ffd7f41aa0..b53bdc202a89 100644
--- a/core/java/android/app/assist/OWNERS
+++ b/core/java/android/app/assist/OWNERS
@@ -1,2 +1 @@
-hackz@google.com
-volnov@google.com \ No newline at end of file
+srazdan@google.com
diff --git a/core/java/android/app/servertransaction/ClientTransactionListenerController.java b/core/java/android/app/servertransaction/ClientTransactionListenerController.java
index 0c1e7a32ae5e..c281533ee299 100644
--- a/core/java/android/app/servertransaction/ClientTransactionListenerController.java
+++ b/core/java/android/app/servertransaction/ClientTransactionListenerController.java
@@ -19,8 +19,6 @@ package android.app.servertransaction;
import static android.app.WindowConfiguration.areConfigurationsEqualForDisplay;
import static android.view.Display.INVALID_DISPLAY;
-import static com.android.window.flags.Flags.activityWindowInfoFlag;
-
import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
@@ -102,9 +100,6 @@ public class ClientTransactionListenerController {
*/
public void registerActivityWindowInfoChangedListener(
@NonNull BiConsumer<IBinder, ActivityWindowInfo> listener) {
- if (!activityWindowInfoFlag()) {
- return;
- }
synchronized (mLock) {
mActivityWindowInfoChangedListeners.add(listener);
}
@@ -116,9 +111,6 @@ public class ClientTransactionListenerController {
*/
public void unregisterActivityWindowInfoChangedListener(
@NonNull BiConsumer<IBinder, ActivityWindowInfo> listener) {
- if (!activityWindowInfoFlag()) {
- return;
- }
synchronized (mLock) {
mActivityWindowInfoChangedListeners.remove(listener);
}
@@ -130,9 +122,6 @@ public class ClientTransactionListenerController {
*/
public void onActivityWindowInfoChanged(@NonNull IBinder activityToken,
@NonNull ActivityWindowInfo activityWindowInfo) {
- if (!activityWindowInfoFlag()) {
- return;
- }
final Object[] activityWindowInfoChangedListeners;
synchronized (mLock) {
if (mActivityWindowInfoChangedListeners.isEmpty()) {
diff --git a/core/java/android/audio/policy/configuration/V7_0/package-info.java b/core/java/android/audio/policy/configuration/V7_0/package-info.java
new file mode 100644
index 000000000000..8f7425fc2b5b
--- /dev/null
+++ b/core/java/android/audio/policy/configuration/V7_0/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Hide the android.audio.policy.configuration.V7_0 API as that is managed
+ * separately.
+ *
+ * @hide
+ */
+package android.audio.policy.configuration.V7_0;
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index 64d20817d050..55278f617ba9 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -33,6 +33,20 @@ flag {
flag {
namespace: "virtual_devices"
+ name: "media_projection_keyguard_restrictions"
+ description: "Auto-stop MP when the device locks"
+ bug: "348335290"
+}
+
+flag {
+ namespace: "virtual_devices"
+ name: "virtual_display_insets"
+ description: "APIs for specifying virtual display insets (via cutout)"
+ bug: "350007135"
+}
+
+flag {
+ namespace: "virtual_devices"
name: "metrics_collection"
description: "Enable collection of VDM-related metrics"
bug: "324842215"
@@ -89,3 +103,17 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ namespace: "virtual_devices"
+ name: "virtual_display_rotation_api"
+ description: "API for on-demand rotation of virtual displays"
+ bug: "291748430"
+}
+
+flag {
+ namespace: "virtual_devices"
+ name: "high_resolution_scroll"
+ description: "Enable high resolution scroll"
+ bug: "335160780"
+}
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index 5953890ad85f..93724bb4949d 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -136,6 +136,14 @@ public class ClipDescription implements Parcelable {
"android.intent.extra.LOGGING_INSTANCE_ID";
/**
+ * The id of the task containing the window that initiated the drag that should be hidden.
+ * Only provided to internal drag handlers as a part of the DRAG_START event.
+ * @hide
+ */
+ public static final String EXTRA_HIDE_DRAG_SOURCE_TASK_ID =
+ "android.intent.extra.HIDE_DRAG_SOURCE_TASK_ID";
+
+ /**
* Indicates that a ClipData contains potentially sensitive information, such as a
* password or credit card number.
* <p>
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 87fb84331af3..385d6cfd14a0 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -61,6 +61,7 @@ import android.os.storage.StorageManager;
import android.permission.PermissionCheckerManager;
import android.provider.MediaStore;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.Log;
import android.util.SparseBooleanArray;
@@ -486,6 +487,8 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
validateIncomingAuthority(authority);
int numOperations = operations.size();
final int[] userIds = new int[numOperations];
+ final ArraySet<String> readPermissions = new ArraySet<String>();
+ final ArraySet<String> writePermissions = new ArraySet<String>();
for (int i = 0; i < numOperations; i++) {
ContentProviderOperation operation = operations.get(i);
Uri uri = operation.getUri();
@@ -499,17 +502,19 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
}
final AttributionSource accessAttributionSource =
attributionSource;
- if (operation.isReadOperation()) {
+ if (operation.isReadOperation() && !readPermissions.contains(uri.toString())) {
if (enforceReadPermission(accessAttributionSource, uri)
!= PermissionChecker.PERMISSION_GRANTED) {
throw new OperationApplicationException("App op not allowed", 0);
}
+ readPermissions.add(uri.toString());
}
- if (operation.isWriteOperation()) {
+ if (operation.isWriteOperation() && !writePermissions.contains(uri.toString())) {
if (enforceWritePermission(accessAttributionSource, uri)
!= PermissionChecker.PERMISSION_GRANTED) {
throw new OperationApplicationException("App op not allowed", 0);
}
+ writePermissions.add(uri.toString());
}
}
traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "applyBatch: ", authority);
@@ -2774,6 +2779,10 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
+ " provider from user:" + mContext.getUserId());
}
if (userId != UserHandle.USER_CURRENT
+ // getUserIdFromAuthority can return USER_NULL when can't cast the userId to
+ // an int, which can cause high volume of binder calls.
+ && (!android.multiuser.Flags.fixGetUserPropertyCache()
+ || userId != UserHandle.USER_NULL)
&& userId != mContext.getUserId()
// Since userId specified in content uri, the provider userId would be
// determined from it.
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 24fd000c3cd4..8365840b1efb 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2916,6 +2916,23 @@ public abstract class Context {
@Nullable String initialData, @Nullable Bundle initialExtras);
/**
+ * Similar to above but takes array of names of permissions that a receiver must hold in order
+ * to receive your broadcast. If empty, no permissions are required.
+ *
+ * @see #sendOrderedBroadcastAsUser(Intent, UserHandle, String,
+ * BroadcastReceiver, Handler, int, String, Bundle)
+ * @hide
+ */
+ @SuppressWarnings("HiddenAbstractMethod")
+ @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
+ public void sendOrderedBroadcastAsUserMultiplePermissions(Intent intent,
+ UserHandle user, String[] receiverPermissions, int appOp, Bundle options,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
+
+ /**
* Version of
* {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String,
* Bundle)} that allows you to specify the App Op to enforce restrictions on which receivers
@@ -2997,6 +3014,21 @@ public abstract class Context {
}
/**
+ * Like {@link #sendOrderedBroadcast(Intent, String, String, BroadcastReceiver, Handler, int,
+ * String, Bundle)}, but also allows specification of a list of multiple permissions.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_ORDERED_BROADCAST_MULTIPLE_PERMISSIONS)
+ @SystemApi
+ public void sendOrderedBroadcastMultiplePermissions(
+ @NonNull Intent intent, @NonNull String[] receiverPermissions,
+ @Nullable String receiverAppOp, @Nullable BroadcastReceiver resultReceiver,
+ @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+ @Nullable Bundle initialExtras, @Nullable Bundle options) {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
+
+ /**
* <p>Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the
* Intent you are sending stays around after the broadcast is complete,
* so that others can quickly retrieve that data through the return
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index a475c2925881..79fa6ea4d157 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -652,6 +652,16 @@ public class ContextWrapper extends Context {
resultReceiver, scheduler, initialCode, initialData, initialExtras);
}
+ /** @hide */
+ @Override
+ public void sendOrderedBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
+ @Nullable String[] receiverPermission, int appOp, @Nullable Bundle options,
+ @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler,
+ int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras) {
+ mBase.sendOrderedBroadcastAsUserMultiplePermissions(intent, user, receiverPermission, appOp,
+ options, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+
@Override
public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent,
@Nullable String receiverPermission, @Nullable String receiverAppOp,
@@ -661,6 +671,17 @@ public class ContextWrapper extends Context {
scheduler, initialCode, initialData, initialExtras);
}
+ /** @hide */
+ @Override
+ public void sendOrderedBroadcastMultiplePermissions(
+ @NonNull Intent intent, @NonNull String[] receiverPermissions,
+ @Nullable String receiverAppOp, @Nullable BroadcastReceiver resultReceiver,
+ @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+ @Nullable Bundle initialExtras, @Nullable Bundle options) {
+ mBase.sendOrderedBroadcastMultiplePermissions(intent, receiverPermissions, receiverAppOp,
+ resultReceiver, scheduler, initialCode, initialData, initialExtras, options);
+ }
+
@Override
public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent, int initialCode,
@Nullable String receiverPermission, @Nullable String receiverAppOp,
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 112507e00e85..97404dcdea0c 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -20,7 +20,6 @@ import static android.app.sdksandbox.SdkSandboxManager.ACTION_START_SANDBOXED_AC
import static android.content.ContentProvider.maybeAddUserId;
import static android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE;
import static android.security.Flags.FLAG_FRP_ENFORCEMENT;
-import static android.service.chooser.Flags.FLAG_ENABLE_SHARESHEET_METADATA_EXTRA;
import android.Manifest;
import android.accessibilityservice.AccessibilityService;
@@ -6252,7 +6251,6 @@ public class Intent implements Parcelable, Cloneable {
* <p>e.g. When sharing a photo, metadata could inform the user that location data is included
* in the photo they are sharing.</p>
*/
- @FlaggedApi(FLAG_ENABLE_SHARESHEET_METADATA_EXTRA)
public static final String EXTRA_METADATA_TEXT = "android.intent.extra.METADATA_TEXT";
/**
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index 2e252c12c51d..32d1964dd4f0 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -16,6 +16,7 @@
package android.content;
+import android.annotation.FlaggedApi;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.PendingIntentInfo;
@@ -32,6 +33,10 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.AndroidException;
+import com.android.window.flags.Flags;
+
+import java.util.concurrent.Executor;
+
/**
* A description of an Intent and target action to perform with it.
* The returned object can be
@@ -114,15 +119,15 @@ public class IntentSender implements Parcelable {
implements Runnable {
private final IntentSender mIntentSender;
private final OnFinished mWho;
- private final Handler mHandler;
+ private final Executor mExecutor;
private Intent mIntent;
private int mResultCode;
private String mResultData;
private Bundle mResultExtras;
- FinishedDispatcher(IntentSender pi, OnFinished who, Handler handler) {
+ FinishedDispatcher(IntentSender pi, OnFinished who, Executor executor) {
mIntentSender = pi;
mWho = who;
- mHandler = handler;
+ mExecutor = executor;
}
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean serialized, boolean sticky, int sendingUser) {
@@ -130,10 +135,10 @@ public class IntentSender implements Parcelable {
mResultCode = resultCode;
mResultData = data;
mResultExtras = extras;
- if (mHandler == null) {
+ if (mExecutor == null) {
run();
} else {
- mHandler.post(this);
+ mExecutor.execute(this);
}
}
public void run() {
@@ -147,16 +152,16 @@ public class IntentSender implements Parcelable {
* caller to specify information about the Intent to use and be notified
* when the send has completed.
*
- * @param context The Context of the caller. This may be null if
- * <var>intent</var> is also null.
+ * @param context The Context of the caller. This may be {@code null} if
+ * <var>intent</var> is also {@code null}.
* @param code Result code to supply back to the IntentSender's target.
* @param intent Additional Intent data. See {@link Intent#fillIn
* Intent.fillIn()} for information on how this is applied to the
- * original Intent. Use null to not modify the original Intent.
+ * original Intent. Use {@code null} to not modify the original Intent.
* @param onFinished The object to call back on when the send has
- * completed, or null for no callback.
+ * completed, or {@code null} for no callback.
* @param handler Handler identifying the thread on which the callback
- * should happen. If null, the callback will happen from the thread
+ * should happen. If {@code null}, the callback will happen from the thread
* pool of the process.
*
*
@@ -165,8 +170,8 @@ public class IntentSender implements Parcelable {
*/
public void sendIntent(Context context, int code, Intent intent,
OnFinished onFinished, Handler handler) throws SendIntentException {
- sendIntent(context, code, intent, onFinished, handler, null,
- SEND_INTENT_DEFAULT_OPTIONS);
+ sendIntent(context, code, intent, null, SEND_INTENT_DEFAULT_OPTIONS,
+ handler == null ? null : handler::post, onFinished);
}
/**
@@ -174,22 +179,22 @@ public class IntentSender implements Parcelable {
* caller to specify information about the Intent to use and be notified
* when the send has completed.
*
- * @param context The Context of the caller. This may be null if
- * <var>intent</var> is also null.
+ * @param context The Context of the caller. This may be {@code null} if
+ * <var>intent</var> is also {@code null}.
* @param code Result code to supply back to the IntentSender's target.
* @param intent Additional Intent data. See {@link Intent#fillIn
* Intent.fillIn()} for information on how this is applied to the
- * original Intent. Use null to not modify the original Intent.
+ * original Intent. Use {@code null} to not modify the original Intent.
* @param onFinished The object to call back on when the send has
- * completed, or null for no callback.
+ * completed, or {@code null} for no callback.
* @param handler Handler identifying the thread on which the callback
- * should happen. If null, the callback will happen from the thread
+ * should happen. If {@code null}, the callback will happen from the thread
* pool of the process.
* @param requiredPermission Name of permission that a recipient of the PendingIntent
* is required to hold. This is only valid for broadcast intents, and
* corresponds to the permission argument in
* {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
- * If null, no permission is required.
+ * If {@code null}, no permission is required.
*
*
* @throws SendIntentException Throws CanceledIntentException if the IntentSender
@@ -198,8 +203,8 @@ public class IntentSender implements Parcelable {
public void sendIntent(Context context, int code, Intent intent,
OnFinished onFinished, Handler handler, String requiredPermission)
throws SendIntentException {
- sendIntent(context, code, intent, onFinished, handler, requiredPermission,
- SEND_INTENT_DEFAULT_OPTIONS);
+ sendIntent(context, code, intent, requiredPermission, SEND_INTENT_DEFAULT_OPTIONS,
+ handler == null ? null : handler::post, onFinished);
}
/**
@@ -207,32 +212,32 @@ public class IntentSender implements Parcelable {
* caller to specify information about the Intent to use and be notified
* when the send has completed.
*
- * @param context The Context of the caller. This may be null if
- * <var>intent</var> is also null.
+ * @param context The Context of the caller. This may be {@code null} if
+ * <var>intent</var> is also {@code null}.
* @param code Result code to supply back to the IntentSender's target.
* @param intent Additional Intent data. See {@link Intent#fillIn
* Intent.fillIn()} for information on how this is applied to the
- * original Intent. Use null to not modify the original Intent.
+ * original Intent. Use {@code null} to not modify the original Intent.
* @param onFinished The object to call back on when the send has
- * completed, or null for no callback.
- * @param handler Handler identifying the thread on which the callback
- * should happen. If null, the callback will happen from the thread
+ * completed, or {@code null} for no callback.
+ * @param executor Executor identifying the thread on which the callback
+ * should happen. If {@code null}, the callback will happen from the thread
* pool of the process.
* @param requiredPermission Name of permission that a recipient of the PendingIntent
* is required to hold. This is only valid for broadcast intents, and
* corresponds to the permission argument in
* {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
- * If null, no permission is required.
+ * If {@code null}, no permission is required.
* @param options Additional options the caller would like to provide to modify the sending
- * behavior. May be built from an {@link ActivityOptions} to apply to an activity start.
+ * behavior. Typically built from using {@link ActivityOptions} to apply to an activity start.
*
* @throws SendIntentException Throws CanceledIntentException if the IntentSender
* is no longer allowing more intents to be sent through it.
- * @hide
*/
- public void sendIntent(Context context, int code, Intent intent,
- OnFinished onFinished, Handler handler, String requiredPermission,
- @Nullable Bundle options)
+ @FlaggedApi(Flags.FLAG_BAL_SEND_INTENT_WITH_OPTIONS)
+ public void sendIntent(@Nullable Context context, int code, @Nullable Intent intent,
+ @Nullable String requiredPermission, @Nullable Bundle options,
+ @Nullable Executor executor, @Nullable OnFinished onFinished)
throws SendIntentException {
try {
String resolvedType = intent != null ?
@@ -243,7 +248,7 @@ public class IntentSender implements Parcelable {
int res = ActivityManager.getService().sendIntentSender(app, mTarget, mWhitelistToken,
code, intent, resolvedType,
onFinished != null
- ? new FinishedDispatcher(this, onFinished, handler)
+ ? new FinishedDispatcher(this, onFinished, executor)
: null,
requiredPermission, options);
if (res < 0) {
@@ -268,7 +273,7 @@ public class IntentSender implements Parcelable {
* sending the Intent. The returned string is supplied by the system, so
* that an application can not spoof its package.
*
- * @return The package name of the PendingIntent, or null if there is
+ * @return The package name of the PendingIntent, or {@code null} if there is
* none associated with it.
*/
public String getCreatorPackage() {
@@ -296,7 +301,7 @@ public class IntentSender implements Parcelable {
* {@link android.os.Process#myUserHandle() Process.myUserHandle()} for
* more explanation of user handles.
*
- * @return The user handle of the PendingIntent, or null if there is
+ * @return The user handle of the PendingIntent, {@code null} if there is
* none associated with it.
*/
public UserHandle getCreatorUserHandle() {
@@ -355,11 +360,11 @@ public class IntentSender implements Parcelable {
};
/**
- * Convenience function for writing either a IntentSender or null pointer to
+ * Convenience function for writing either a IntentSender or {@code null} pointer to
* a Parcel. You must use this with {@link #readIntentSenderOrNullFromParcel}
* for later reading it.
*
- * @param sender The IntentSender to write, or null.
+ * @param sender The IntentSender to write, or {@code null}.
* @param out Where to write the IntentSender.
*/
public static void writeIntentSenderOrNullToParcel(IntentSender sender,
@@ -369,13 +374,13 @@ public class IntentSender implements Parcelable {
}
/**
- * Convenience function for reading either a Messenger or null pointer from
+ * Convenience function for reading either a Messenger or {@code null} pointer from
* a Parcel. You must have previously written the Messenger with
* {@link #writeIntentSenderOrNullToParcel}.
*
* @param in The Parcel containing the written Messenger.
*
- * @return Returns the Messenger read from the Parcel, or null if null had
+ * @return Returns the Messenger read from the Parcel, or @code null} if @code null} had
* been written.
*/
public static IntentSender readIntentSenderOrNullFromParcel(Parcel in) {
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 57ffed47bbe3..6952a09f2d90 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -941,6 +941,8 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
CONFIG_COLOR_MODE,
CONFIG_FONT_SCALE,
CONFIG_GRAMMATICAL_GENDER,
+ CONFIG_ASSETS_PATHS,
+ CONFIG_RESOURCES_UNUSED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Config {}
@@ -1060,8 +1062,8 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
* can itself handle asset path changes. Set from the {@link android.R.attr#configChanges}
* attribute. This is not a core resource configuration, but a higher-level value, so its
* constant starts at the high bits.
- * @hide We do not want apps handling this yet, but we do need some kind of bit for diffs.
*/
+ @FlaggedApi(android.content.res.Flags.FLAG_HANDLE_ALL_CONFIG_CHANGES)
public static final int CONFIG_ASSETS_PATHS = 0x80000000;
/**
* Bit in {@link #configChanges} that indicates that the activity
@@ -1088,6 +1090,30 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
*/
public static final int CONFIG_FONT_WEIGHT_ADJUSTMENT = 0x10000000;
+ /**
+ * <p>This is probably not the constant you want, the resources compiler supports a less
+ * dangerous version of it, 'allKnown', that only suppresses all currently existing
+ * configuration change restarts depending on your target SDK rather than whatever the latest
+ * SDK supports, allowing the application to work with resources on future Platform versions.
+ *
+ * <p>Bit in {@link #configChanges} that indicates that the activity doesn't use Android
+ * Resources at all and doesn't need to be restarted on any configuration changes. This bit
+ * disables all restarts for configuration dimensions available in the current target SDK as
+ * well as dimensions introduced in future SDKs. Use it only if the activity doesn't need
+ * anything from its resources, and doesn't depend on any libraries that may provide resources
+ * and need to respond to configuration changes. When set,
+ * {@link Activity#onConfigurationChanged(Configuration)} will be called instead of a restart,
+ * and it’s up to the implementation to ensure that no stale resource values remain loaded
+ * anywhere in the code.
+ *
+ * <p>This overrides all other bits, and this is recommended to be used individually.
+ *
+ * <p>This is not a core resource configuration, but a higher-level value, so its constant
+ * starts at the high bits.
+ */
+ @FlaggedApi(android.content.res.Flags.FLAG_HANDLE_ALL_CONFIG_CHANGES)
+ public static final int CONFIG_RESOURCES_UNUSED = 0x8000000;
+
/** @hide
* Unfortunately the constants for config changes in native code are
* different from ActivityInfo. :( Here are the values we should use for the
@@ -1657,7 +1683,8 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
* {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION},
* {@link #CONFIG_ORIENTATION}, {@link #CONFIG_SCREEN_LAYOUT},
* {@link #CONFIG_DENSITY}, {@link #CONFIG_LAYOUT_DIRECTION},
- * {@link #CONFIG_COLOR_MODE}, and {link #CONFIG_GRAMMATICAL_GENDER}.
+ * {@link #CONFIG_COLOR_MODE}, {@link #CONFIG_GRAMMATICAL_GENDER},
+ * {@link #CONFIG_ASSETS_PATHS}, and {@link #CONFIG_RESOURCES_UNUSED}.
* Set from the {@link android.R.attr#configChanges} attribute.
*/
public int configChanges;
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index df27f9d4e457..52c84dc0ac5d 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -935,12 +935,11 @@ public class LauncherApps {
*
* @return {@link IntentSender} object which launches the Private Space Settings Activity, if
* successful, null otherwise.
- * @hide
*/
// Alternatively, a system app can access this api for private profile if they've been granted
// with the {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL} permission.
@Nullable
- @FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE)
+ @FlaggedApi(Flags.FLAG_GET_PRIVATE_SPACE_SETTINGS)
@RequiresPermission(conditional = true,
anyOf = {ACCESS_HIDDEN_PROFILES_FULL, ACCESS_HIDDEN_PROFILES})
public IntentSender getPrivateSpaceSettingsIntent() {
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index 55d0bc1deedc..c811a47e5b05 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -91,6 +91,9 @@ public abstract class ShortcutServiceInternal {
public abstract void addShortcutChangeCallback(
@NonNull LauncherApps.ShortcutChangeCallback callback);
+ public abstract void removeShortcutChangeCallback(
+ @NonNull LauncherApps.ShortcutChangeCallback callback);
+
public abstract int getShortcutIconResId(int launcherUserId, @NonNull String callingPackage,
@NonNull String packageName, @NonNull String shortcutId, int userId);
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 6f5bb4ad724f..c2c7b81871df 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -151,6 +151,36 @@ flag {
}
flag {
+ name: "fix_get_user_property_cache"
+ namespace: "multiuser"
+ description: "Cache is not optimised for getUserProperty for values below 0, eg. UserHandler.USER_NULL or UserHandle.USER_ALL"
+ bug: "350416200"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "cache_profile_parent"
+ namespace: "multiuser"
+ description: "Cache getProfileParent to avoid unnecessary binder calls"
+ bug: "350417399"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "cache_quiet_mode_state"
+ namespace: "multiuser"
+ description: "Optimise quiet mode state retrieval"
+ bug: "350420769"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "cache_user_serial_number"
namespace: "multiuser"
description: "Optimise user serial number retrieval"
@@ -160,7 +190,6 @@ flag {
}
}
-
# This flag guards the private space feature and all its implementations excluding the APIs. APIs are guarded by android.os.Flags.allow_private_profile.
flag {
name: "enable_private_space_features"
@@ -288,3 +317,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "modify_private_space_secondary_unlock_setup_flow"
+ namespace: "profile_experiences"
+ description: "Updates to setting up secondary unlock factor from Settings for the first time"
+ bug: "332850595"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/android/content/res/flags.aconfig b/core/java/android/content/res/flags.aconfig
index a475cc85e921..a5f8199c9a07 100644
--- a/core/java/android/content/res/flags.aconfig
+++ b/core/java/android/content/res/flags.aconfig
@@ -56,3 +56,13 @@ flag {
# This flag is read in ResourcesImpl at boot time.
is_fixed_read_only: true
}
+
+flag {
+ name: "handle_all_config_changes"
+ is_exported: true
+ namespace: "resource_manager"
+ description: "Feature flag for allowing activities to handle all kinds of configuration changes"
+ bug: "180625460"
+ # This flag is read at boot time.
+ is_fixed_read_only: true
+}
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index ba356bb55194..65148726224e 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -16,6 +16,8 @@
package android.database;
+import static java.util.Objects.requireNonNull;
+
import android.annotation.BytesLong;
import android.annotation.IntRange;
import android.compat.annotation.UnsupportedAppUsage;
@@ -640,6 +642,7 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
*/
public boolean putBlob(byte[] value,
@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
+ requireNonNull(value);
acquireReference();
try {
return nativePutBlob(mWindowPtr, value, row - mStartPos, column);
@@ -658,6 +661,7 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
*/
public boolean putString(String value,
@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
+ requireNonNull(value);
acquireReference();
try {
return nativePutString(mWindowPtr, value, row - mStartPos, column);
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index cbac912e33e8..ca3e3d2ad61b 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -569,7 +569,6 @@ public class Camera {
return native_setup(
new WeakReference<>(this),
cameraId,
- ActivityThread.currentOpPackageName(),
rotationOverride,
forceSlowJpegMode,
clientAttribution.getParcel(),
@@ -660,7 +659,6 @@ public class Camera {
private native int native_setup(
Object cameraThis,
int cameraId,
- String packageName,
int rotationOverride,
boolean forceSlowJpegMode,
Parcel clientAttributionParcel,
diff --git a/core/java/android/hardware/OWNERS b/core/java/android/hardware/OWNERS
index 51ad1519941b..43d3f5466ccf 100644
--- a/core/java/android/hardware/OWNERS
+++ b/core/java/android/hardware/OWNERS
@@ -5,7 +5,7 @@ michaelwr@google.com
sumir@google.com
# Camera
-per-file *Camera*=cychen@google.com,epeev@google.com,etalvala@google.com,shuzhenwang@google.com,zhijunhe@google.com,jchowdhary@google.com
+per-file *Camera*=file:platform/frameworks/av:/camera/OWNERS
# Sensor Privacy
per-file *SensorPrivacy* = file:platform/frameworks/native:/libs/sensorprivacy/OWNERS
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 50d976f683cb..49353893965d 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -1423,7 +1423,9 @@ public abstract class CameraDevice implements AutoCloseable {
* {@code false} otherwise.
* @throws UnsupportedOperationException if the query operation is not supported by the camera
* device
- * @throws IllegalArgumentException if the session configuration is invalid
+ * @throws IllegalArgumentException if the session configuration is invalid, including, if it
+ * contains certain non-supported features queryable via
+ * CameraCharacteristics.
* @throws CameraAccessException if the camera device is no longer connected or has
* encountered a fatal error
* @throws IllegalStateException if the camera device has been closed
@@ -1691,12 +1693,11 @@ public abstract class CameraDevice implements AutoCloseable {
*
* <p><b>IMPORTANT:</b></p>
* <ul>
- * <li>If feature support can be queried via
- * {@link CameraCharacteristics#SCALER_MANDATORY_STREAM_COMBINATIONS} or
- * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}, applications should
- * directly use that route rather than calling this function as: (1) using
- * {@code CameraCharacteristics} is more efficient, and (2) calling this function with
- * certain non-supported features will throw a {@link IllegalArgumentException}.</li>
+ * <li>If feature support can be queried via {@link CameraCharacteristics}, applications
+ * should directly use that route rather than calling this function as: (1) using
+ * {@code CameraCharacteristics} is more efficient, and (2) querying a feature explicitly
+ * deemed unsupported by CameraCharacteristics may throw a
+ * {@link IllegalArgumentException}.</li>
*
* <li>To minimize {@link SessionConfiguration} creation latency due to its dependency on
* output surfaces, the application can call this method before acquiring valid
@@ -1724,7 +1725,8 @@ public abstract class CameraDevice implements AutoCloseable {
*
* @throws CameraAccessException if the camera device is no longer connected or has
* encountered a fatal error
- * @throws IllegalArgumentException if the session configuration is invalid
+ * @throws IllegalArgumentException if the session configuration is invalid, including,
+ * if it contains certain non-supported features queryable via CameraCharacteristics.
*
* @see CameraCharacteristics#INFO_SESSION_CONFIGURATION_QUERY_VERSION
* @see SessionConfiguration
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 2dbd4b81fe6c..6a7ee7fcb26a 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -56,6 +56,8 @@ import android.hardware.camera2.utils.ConcurrentCameraIdCombination;
import android.hardware.camera2.utils.ExceptionUtils;
import android.hardware.devicestate.DeviceState;
import android.hardware.devicestate.DeviceStateManager;
+import android.hardware.devicestate.feature.flags.FeatureFlags;
+import android.hardware.devicestate.feature.flags.FeatureFlagsImpl;
import android.hardware.display.DisplayManager;
import android.os.Binder;
import android.os.Handler;
@@ -247,14 +249,22 @@ public final class CameraManager {
private ArrayList<WeakReference<DeviceStateListener>> mDeviceStateListeners =
new ArrayList<>();
private boolean mFoldedDeviceState;
+ private final FeatureFlags mDeviceStateManagerFlags;
public FoldStateListener(Context context) {
mFoldedDeviceStates = context.getResources().getIntArray(
com.android.internal.R.array.config_foldedDeviceStates);
+ mDeviceStateManagerFlags = new FeatureFlagsImpl();
}
- private synchronized void handleStateChange(int state) {
- boolean folded = ArrayUtils.contains(mFoldedDeviceStates, state);
+ private synchronized void handleStateChange(DeviceState state) {
+ final boolean folded;
+ if (mDeviceStateManagerFlags.deviceStatePropertyMigration()) {
+ folded = state.hasProperty(
+ DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY);
+ } else {
+ folded = ArrayUtils.contains(mFoldedDeviceStates, state.getIdentifier());
+ }
mFoldedDeviceState = folded;
Iterator<WeakReference<DeviceStateListener>> it = mDeviceStateListeners.iterator();
@@ -276,10 +286,8 @@ public final class CameraManager {
@SuppressWarnings("FlaggedApi")
@Override
- public void onDeviceStateChanged(DeviceState state) {
- // Suppressing the FlaggedAPI warning as this specific API isn't new, just moved to
- // system API which requires it to be flagged.
- handleStateChange(state.getIdentifier());
+ public void onDeviceStateChanged(@NonNull DeviceState state) {
+ handleStateChange(state);
}
}
@@ -980,6 +988,8 @@ public final class CameraManager {
clientAttribution.uid = USE_CALLING_UID;
clientAttribution.pid = USE_CALLING_PID;
clientAttribution.deviceId = contextAttribution.deviceId;
+ clientAttribution.packageName = mContext.getOpPackageName();
+ clientAttribution.attributionTag = mContext.getAttributionTag();
clientAttribution.next = new AttributionSourceState[0];
return clientAttribution;
}
@@ -1041,8 +1051,6 @@ public final class CameraManager {
cameraService.connectDevice(
callbacks,
cameraId,
- mContext.getOpPackageName(),
- mContext.getAttributionTag(),
oomScoreOffset,
mContext.getApplicationInfo().targetSdkVersion,
rotationOverride,
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index 978a8f9200ba..e3dbb2bbbf90 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -747,6 +747,10 @@ public final class StreamConfigurationMap {
* {@link android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession#createHighSpeedRequestList}.
* </p>
*
+ * <p>This function returns an empty array if
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO}
+ * is not supported.</p>
+ *
* @return an array of supported high speed video recording sizes
* @see #getHighSpeedVideoFpsRangesFor(Size)
* @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO
@@ -836,6 +840,10 @@ public final class StreamConfigurationMap {
* supported for the same recording rate.</li>
* </p>
*
+ * <p>This function returns an empty array if
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO}
+ * is not supported.</p>
+ *
* @return an array of supported high speed video recording FPS ranges The upper bound of
* returned ranges is guaranteed to be larger or equal to 120.
* @see #getHighSpeedVideoSizesFor
diff --git a/core/java/android/hardware/devicestate/DeviceStateManager.java b/core/java/android/hardware/devicestate/DeviceStateManager.java
index febc24c1465a..5b511cc94ac0 100644
--- a/core/java/android/hardware/devicestate/DeviceStateManager.java
+++ b/core/java/android/hardware/devicestate/DeviceStateManager.java
@@ -67,6 +67,14 @@ public final class DeviceStateManager {
public static final int MAXIMUM_DEVICE_STATE_IDENTIFIER = 10000;
/**
+ * {@link DeviceState} to represent an invalid device state.
+ * @hide
+ */
+ public static final DeviceState INVALID_DEVICE_STATE = new DeviceState(
+ new DeviceState.Configuration.Builder(INVALID_DEVICE_STATE_IDENTIFIER,
+ "INVALID").build());
+
+ /**
* Intent needed to launch the rear display overlay activity from SysUI
*
* @hide
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 4894fb1ec452..97f6899ff141 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -395,7 +395,7 @@ public final class DisplayManager {
* the display is removed.
*
* Public virtual displays without this flag will move their content to main display
- * stack once they're removed. Private vistual displays will always destroy their
+ * stack once they're removed. Private virtual displays will always destroy their
* content on removal even without this flag.
*
* @see #createVirtualDisplay
@@ -1669,6 +1669,46 @@ public final class DisplayManager {
}
/**
+ * Gets the mapping between the doze brightness sensor values and brightness values. The doze
+ * brightness sensor is a light sensor used to determine the brightness while the device is
+ * dozing. Light sensor values are typically integers in the rage of 0-4. The returned values
+ * are between {@link PowerManager#BRIGHTNESS_MIN} and {@link PowerManager#BRIGHTNESS_MAX}, or
+ * -1 meaning that the current brightness should be kept.
+ * <p>
+ * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS}
+ * permission.
+ * </p>
+ *
+ * @param displayId The ID of the display
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
+ @Nullable
+ public float[] getDozeBrightnessSensorValueToBrightness(int displayId) {
+ return mGlobal.getDozeBrightnessSensorValueToBrightness(displayId);
+ }
+
+ /**
+ * Gets the default doze brightness.
+ * The returned values are between {@link PowerManager#BRIGHTNESS_MIN} and
+ * {@link PowerManager#BRIGHTNESS_MAX}.
+ * <p>
+ * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS}
+ * permission.
+ * </p>
+ *
+ * @param displayId The ID of the display
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
+ @FloatRange(from = 0f, to = 1f)
+ public float getDefaultDozeBrightness(int displayId) {
+ return mGlobal.getDefaultDozeBrightness(displayId);
+ }
+
+ /**
* Listens for changes in available display devices.
*/
public interface DisplayListener {
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 85197221e651..cae33d05b6ed 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -21,6 +21,7 @@ import static android.hardware.display.DisplayManager.EventsMask;
import static android.view.Display.HdrCapabilities.HdrType;
import android.Manifest;
+import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -549,15 +550,20 @@ public final class DisplayManagerGlobal {
}
/**
- * Request to power a display ON or OFF.
+ * Request to power a display OFF or reset it to a power state it supposed to have.
+ * @param displayId the id of the display
+ * @param state one of {@link android.view.Display#STATE_UNKNOWN} (to reset the state to
+ * the one the display should have had now), {@link android.view.Display#STATE_OFF}.
+ * @return true if successful, false otherwise
* @hide
*/
@RequiresPermission("android.permission.MANAGE_DISPLAYS")
- public boolean requestDisplayPower(int displayId, boolean on) {
+ public boolean requestDisplayPower(int displayId, int state) {
try {
- return mDm.requestDisplayPower(displayId, on);
+ return mDm.requestDisplayPower(displayId, state);
} catch (RemoteException ex) {
- Log.e(TAG, "Error trying to request display power " + on, ex);
+ Log.e(TAG, "Error trying to request display power:"
+ + " state=" + state, ex);
return false;
}
}
@@ -812,6 +818,14 @@ public final class DisplayManagerGlobal {
}
}
+ void setVirtualDisplayRotation(IVirtualDisplayCallback token, @Surface.Rotation int rotation) {
+ try {
+ mDm.setVirtualDisplayRotation(token, rotation);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
/**
* Gets the stable device display size, in pixels.
*/
@@ -1213,6 +1227,32 @@ public final class DisplayManagerGlobal {
}
}
+ /**
+ * @see DisplayManager#getDozeBrightnessSensorValueToBrightness
+ */
+ @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
+ @Nullable
+ public float[] getDozeBrightnessSensorValueToBrightness(int displayId) {
+ try {
+ return mDm.getDozeBrightnessSensorValueToBrightness(displayId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see DisplayManager#getDefaultDozeBrightness
+ */
+ @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
+ @FloatRange(from = 0f, to = 1f)
+ public float getDefaultDozeBrightness(int displayId) {
+ try {
+ return mDm.getDefaultDozeBrightness(displayId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub {
@Override
public void onDisplayEvent(int displayId, @DisplayEvent int event) {
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 91caedc0b9a9..811a834dff47 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -686,8 +686,12 @@ public abstract class DisplayManagerInternal {
public RefreshRateRange range;
public RefreshRateLimitation(@RefreshRateLimitType int type, float min, float max) {
+ this(type, new RefreshRateRange(min, max));
+ }
+
+ public RefreshRateLimitation(@RefreshRateLimitType int type, RefreshRateRange range) {
this.type = type;
- range = new RefreshRateRange(min, max);
+ this.range = range;
}
@Override
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index b7c02b0d0720..f3c21e9f7a43 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -117,6 +117,9 @@ interface IDisplayManager {
// No permissions required but must be same Uid as the creator.
void setVirtualDisplayState(in IVirtualDisplayCallback token, boolean isOn);
+ // No permissions required but must be same Uid as the creator.
+ void setVirtualDisplayRotation(in IVirtualDisplayCallback token, int rotation);
+
// Get a stable metric for the device's display size. No permissions required.
Point getStableDisplaySize();
@@ -236,11 +239,19 @@ interface IDisplayManager {
@EnforcePermission("MANAGE_DISPLAYS")
void disableConnectedDisplay(int displayId);
- // Request to power display ON or OFF.
+ // Request to power display OFF or reset it to a power state it supposed to have.
@EnforcePermission("MANAGE_DISPLAYS")
- boolean requestDisplayPower(int displayId, boolean on);
+ boolean requestDisplayPower(int displayId, int state);
// Restricts display modes to specified modeIds.
@EnforcePermission("RESTRICT_DISPLAY_MODES")
void requestDisplayModes(in IBinder token, int displayId, in @nullable int[] modeIds);
+
+ // Get the mapping between the doze brightness sensor values and brightness values
+ @EnforcePermission("CONTROL_DISPLAY_BRIGHTNESS")
+ float[] getDozeBrightnessSensorValueToBrightness(int displayId);
+
+ // Get the default doze brightness
+ @EnforcePermission("CONTROL_DISPLAY_BRIGHTNESS")
+ float getDefaultDozeBrightness(int displayId);
}
diff --git a/core/java/android/hardware/display/VirtualDisplay.java b/core/java/android/hardware/display/VirtualDisplay.java
index 051ce636484c..6cc938f5e6f8 100644
--- a/core/java/android/hardware/display/VirtualDisplay.java
+++ b/core/java/android/hardware/display/VirtualDisplay.java
@@ -15,6 +15,7 @@
*/
package android.hardware.display;
+import android.annotation.FlaggedApi;
import android.view.Display;
import android.view.Surface;
@@ -122,6 +123,28 @@ public final class VirtualDisplay {
}
}
+ /**
+ * Sets the rotation of the virtual display.
+ *
+ * @param rotation the new rotation of the display. May be one of {@link Surface#ROTATION_0},
+ * {@link Surface#ROTATION_90}, {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}.
+ * Upon creation, the rotation of the virtual display is always {@link Surface#ROTATION_0}.
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIRTUAL_DISPLAY_ROTATION_API)
+ public void setRotation(@Surface.Rotation int rotation) {
+ if (!android.companion.virtualdevice.flags.Flags.virtualDisplayRotationApi()) {
+ return;
+ }
+ if (rotation != Surface.ROTATION_0 && rotation != Surface.ROTATION_90
+ && rotation != Surface.ROTATION_180 && rotation != Surface.ROTATION_270) {
+ throw new IllegalArgumentException(
+ "Invalid virtual display rotation value: " + rotation);
+ }
+ if (mToken != null && mDisplay.getRotation() != rotation) {
+ mGlobal.setVirtualDisplayRotation(mToken, rotation);
+ }
+ }
+
@Override
public String toString() {
return "VirtualDisplay{display=" + mDisplay + ", token=" + mToken
diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java
index 56f69a67c0b5..b0994e6145ef 100644
--- a/core/java/android/hardware/display/VirtualDisplayConfig.java
+++ b/core/java/android/hardware/display/VirtualDisplayConfig.java
@@ -31,6 +31,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;
import android.view.Display;
+import android.view.DisplayCutout;
import android.view.Surface;
import java.util.Collections;
@@ -55,9 +56,10 @@ public final class VirtualDisplayConfig implements Parcelable {
private final String mUniqueId;
private final int mDisplayIdToMirror;
private final boolean mWindowManagerMirroringEnabled;
- private ArraySet<String> mDisplayCategories = null;
+ private final ArraySet<String> mDisplayCategories;
private final float mRequestedRefreshRate;
private final boolean mIsHomeSupported;
+ private final DisplayCutout mDisplayCutout;
private VirtualDisplayConfig(
@NonNull String name,
@@ -71,7 +73,8 @@ public final class VirtualDisplayConfig implements Parcelable {
boolean windowManagerMirroringEnabled,
@NonNull ArraySet<String> displayCategories,
float requestedRefreshRate,
- boolean isHomeSupported) {
+ boolean isHomeSupported,
+ @Nullable DisplayCutout displayCutout) {
mName = name;
mWidth = width;
mHeight = height;
@@ -84,6 +87,7 @@ public final class VirtualDisplayConfig implements Parcelable {
mDisplayCategories = displayCategories;
mRequestedRefreshRate = requestedRefreshRate;
mIsHomeSupported = isHomeSupported;
+ mDisplayCutout = displayCutout;
}
/**
@@ -135,6 +139,21 @@ public final class VirtualDisplayConfig implements Parcelable {
}
/**
+ * Returns the cutout of this display.
+ *
+ * @return the cutout of the display or {@code null} if none is specified.
+ *
+ * @see Builder#setDisplayCutout
+ * @hide
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIRTUAL_DISPLAY_INSETS)
+ @SystemApi
+ @Nullable
+ public DisplayCutout getDisplayCutout() {
+ return mDisplayCutout;
+ }
+
+ /**
* Returns the unique identifier for the display. Shouldn't be displayed to the user.
* @hide
*/
@@ -207,6 +226,7 @@ public final class VirtualDisplayConfig implements Parcelable {
dest.writeArraySet(mDisplayCategories);
dest.writeFloat(mRequestedRefreshRate);
dest.writeBoolean(mIsHomeSupported);
+ DisplayCutout.ParcelableWrapper.writeCutoutToParcel(mDisplayCutout, dest, flags);
}
@Override
@@ -232,7 +252,8 @@ public final class VirtualDisplayConfig implements Parcelable {
&& mWindowManagerMirroringEnabled == that.mWindowManagerMirroringEnabled
&& Objects.equals(mDisplayCategories, that.mDisplayCategories)
&& mRequestedRefreshRate == that.mRequestedRefreshRate
- && mIsHomeSupported == that.mIsHomeSupported;
+ && mIsHomeSupported == that.mIsHomeSupported
+ && Objects.equals(mDisplayCutout, that.mDisplayCutout);
}
@Override
@@ -240,7 +261,7 @@ public final class VirtualDisplayConfig implements Parcelable {
int hashCode = Objects.hash(
mName, mWidth, mHeight, mDensityDpi, mFlags, mSurface, mUniqueId,
mDisplayIdToMirror, mWindowManagerMirroringEnabled, mDisplayCategories,
- mRequestedRefreshRate, mIsHomeSupported);
+ mRequestedRefreshRate, mIsHomeSupported, mDisplayCutout);
return hashCode;
}
@@ -260,6 +281,7 @@ public final class VirtualDisplayConfig implements Parcelable {
+ " mDisplayCategories=" + mDisplayCategories
+ " mRequestedRefreshRate=" + mRequestedRefreshRate
+ " mIsHomeSupported=" + mIsHomeSupported
+ + " mDisplayCutout=" + mDisplayCutout
+ ")";
}
@@ -276,6 +298,7 @@ public final class VirtualDisplayConfig implements Parcelable {
mDisplayCategories = (ArraySet<String>) in.readArraySet(null);
mRequestedRefreshRate = in.readFloat();
mIsHomeSupported = in.readBoolean();
+ mDisplayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(in);
}
@NonNull
@@ -308,6 +331,7 @@ public final class VirtualDisplayConfig implements Parcelable {
private ArraySet<String> mDisplayCategories = new ArraySet<>();
private float mRequestedRefreshRate = 0.0f;
private boolean mIsHomeSupported = false;
+ private DisplayCutout mDisplayCutout = null;
/**
* Creates a new Builder.
@@ -469,6 +493,19 @@ public final class VirtualDisplayConfig implements Parcelable {
}
/**
+ * Sets the cutout of this display.
+ *
+ * @hide
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIRTUAL_DISPLAY_INSETS)
+ @SystemApi
+ @NonNull
+ public Builder setDisplayCutout(@Nullable DisplayCutout displayCutout) {
+ mDisplayCutout = displayCutout;
+ return this;
+ }
+
+ /**
* Builds the {@link VirtualDisplayConfig} instance.
*/
@NonNull
@@ -485,7 +522,8 @@ public final class VirtualDisplayConfig implements Parcelable {
mWindowManagerMirroringEnabled,
mDisplayCategories,
mRequestedRefreshRate,
- mIsHomeSupported);
+ mIsHomeSupported,
+ mDisplayCutout);
}
}
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 2ded615580fd..903e91646332 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -699,6 +699,25 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
}
/**
+ * Set whether the HAL should ignore display touches.
+ * Only applies to sensors where the HAL is reponsible for handling touches.
+ * @hide
+ */
+ @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+ public void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouch) {
+ if (mService == null) {
+ Slog.w(TAG, "setIgnoreDisplayTouches: no fingerprint service");
+ return;
+ }
+
+ try {
+ mService.setIgnoreDisplayTouches(requestId, sensorId, ignoreTouch);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Request fingerprint enrollment. This call warms up the fingerprint hardware
* and starts scanning for fingerprints. Progress will be indicated by callbacks to the
* {@link EnrollmentCallback} object. It terminates when
diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
index f701ec3ec367..d84d29292ed5 100644
--- a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
+++ b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
@@ -120,6 +120,14 @@ public class FingerprintSensorPropertiesInternal extends SensorPropertiesInterna
}
/**
+ * Returns if sensor type is ultrasonic Udfps
+ * @return true if sensor is ultrasonic Udfps, false otherwise
+ */
+ public boolean isUltrasonicUdfps() {
+ return sensorType == TYPE_UDFPS_ULTRASONIC;
+ }
+
+ /**
* Returns if sensor type is side-FPS
* @return true if sensor is side-fps, false otherwise
*/
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 742fa570bad7..370f097b6850 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -195,6 +195,9 @@ interface IFingerprintService {
@EnforcePermission("USE_BIOMETRIC_INTERNAL")
void onUdfpsUiEvent(int event, long requestId, int sensorId);
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
+ void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouches);
+
// Sets the controller for managing the UDFPS overlay.
@EnforcePermission("USE_BIOMETRIC_INTERNAL")
void setUdfpsOverlayController(in IUdfpsOverlayController controller);
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 40d4fb6df4bc..1767d6438999 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -32,6 +32,7 @@ import android.hardware.input.TouchCalibration;
import android.os.CombinedVibration;
import android.hardware.input.IInputSensorEventListener;
import android.hardware.input.InputSensorInfo;
+import android.hardware.input.KeyGlyphMap;
import android.hardware.lights.Light;
import android.hardware.lights.LightState;
import android.os.IBinder;
@@ -236,4 +237,6 @@ interface IInputManager {
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.MONITOR_STICKY_MODIFIER_STATE)")
void unregisterStickyModifierStateListener(IStickyModifierStateListener listener);
+
+ KeyGlyphMap getKeyGlyphMap(int deviceId);
}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 21c900260d2e..d7952eb26f7e 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -19,6 +19,7 @@ package android.hardware.input;
import static com.android.input.flags.Flags.FLAG_INPUT_DEVICE_VIEW_BEHAVIOR_API;
import static com.android.input.flags.Flags.FLAG_DEVICE_ASSOCIATIONS;
import static com.android.hardware.input.Flags.keyboardLayoutPreviewFlag;
+import static com.android.hardware.input.Flags.keyboardGlyphMap;
import android.Manifest;
import android.annotation.FlaggedApi;
@@ -158,6 +159,34 @@ public final class InputManager {
"android.hardware.input.metadata.KEYBOARD_LAYOUTS";
/**
+ * Broadcast Action: Query available keyboard glyph maps.
+ * <p>
+ * The input manager service locates available keyboard glyph maps
+ * by querying broadcast receivers that are registered for this action.
+ * An application can offer additional keyboard glyph maps to the user
+ * by declaring a suitable broadcast receiver in its manifest.
+ * </p>
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_QUERY_KEYBOARD_GLYPH_MAPS =
+ "android.hardware.input.action.QUERY_KEYBOARD_GLYPH_MAPS";
+
+ /**
+ * Metadata Key: Keyboard glyph map metadata associated with
+ * {@link #ACTION_QUERY_KEYBOARD_GLYPH_MAPS}.
+ * <p>
+ * Specifies the resource id of a XML resource that describes the keyboard
+ * glyph maps that are provided by the application.
+ * </p>
+ *
+ * @hide
+ */
+ public static final String META_DATA_KEYBOARD_GLYPH_MAPS =
+ "android.hardware.input.metadata.KEYBOARD_GLYPH_MAPS";
+
+ /**
* Prevent touches from being consumed by apps if these touches passed through a non-trusted
* window from a different UID and are considered unsafe.
*
@@ -898,6 +927,23 @@ public final class InputManager {
}
/**
+ * Provides associated glyph map for the keyboard device (if available)
+ *
+ * @hide
+ */
+ @Nullable
+ public KeyGlyphMap getKeyGlyphMap(int deviceId) {
+ if (!keyboardGlyphMap()) {
+ return null;
+ }
+ try {
+ return mIm.getKeyGlyphMap(deviceId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Injects an input event into the event system, targeting windows owned by the provided uid.
*
* If a valid targetUid is provided, the system will only consider injecting the input event
@@ -1205,8 +1251,22 @@ public final class InputManager {
* canceled. Only the pilfering window will continue to receive events for the affected pointers
* until the pointer is lifted.
*
- * This method should be used with caution as unexpected pilfering can break fundamental user
- * interactions.
+ * Furthermore, if any new pointers go down within the touchable region of the pilfering window
+ * and are part of the same gesture, those new pointers will be pilfered as well, and will not
+ * be sent to any other windows.
+ *
+ * Pilfering is designed to be used only once per gesture. Once the gesture is complete
+ * (i.e. on {@link MotionEvent#ACTION_UP}, {@link MotionEvent#ACTION_CANCEL},
+ * or {@link MotionEvent#ACTION_HOVER_EXIT}), the system will resume dispatching pointers
+ * to the appropriately touched windows.
+ *
+ * NOTE: This method should be used with caution as unexpected pilfering can break fundamental
+ * user interactions.
+ *
+ * NOTE: Since this method pilfers pointers based on gesture stream that is
+ * currently active for the window, the behavior will depend on the state of the system, and
+ * is inherently racy. For example, a pilfer request on a quick tap may not be successful if
+ * the tap is already complete by the time the pilfer request is received by the system.
*
* @see android.os.InputConfig#SPY
* @hide
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index 4c5ebe786b24..bec1c9ef8059 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -17,11 +17,13 @@
package android.hardware.input;
import static com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_BOUNCE_KEYS_FLAG;
+import static com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_MOUSE_KEYS;
import static com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_SLOW_KEYS_FLAG;
import static com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_STICKY_KEYS_FLAG;
import static com.android.hardware.input.Flags.keyboardA11yBounceKeysFlag;
import static com.android.hardware.input.Flags.keyboardA11ySlowKeysFlag;
import static com.android.hardware.input.Flags.keyboardA11yStickyKeysFlag;
+import static com.android.hardware.input.Flags.keyboardA11yMouseKeys;
import static com.android.hardware.input.Flags.touchpadTapDragging;
import static com.android.input.flags.Flags.enableInputFilterRustImpl;
@@ -662,4 +664,64 @@ public class InputSettings {
UserHandle.USER_CURRENT);
}
+ /**
+ * Whether Accessibility mouse keys feature flag is enabled.
+ *
+ * <p>
+ * ‘Mouse keys’ is an accessibility feature to aid users who have physical disabilities,
+ * that allows the user to use the keys on the keyboard to control the mouse pointer and
+ * other perform other mouse functionality.
+ * </p>
+ *
+ * @hide
+ */
+ public static boolean isAccessibilityMouseKeysFeatureFlagEnabled() {
+ return keyboardA11yMouseKeys();
+ }
+
+ /**
+ * Whether Accessibility mouse keys is enabled.
+ *
+ * <p>
+ * ‘Mouse keys’ is an accessibility feature to aid users who have physical disabilities,
+ * that allows the user to use the keys on the keyboard to control the mouse pointer and
+ * other perform other mouse functionality.
+ * </p>
+ *
+ * @hide
+ */
+ @TestApi
+ @FlaggedApi(FLAG_KEYBOARD_A11Y_MOUSE_KEYS)
+ public static boolean isAccessibilityMouseKeysEnabled(@NonNull Context context) {
+ if (!isAccessibilityMouseKeysFeatureFlagEnabled()) {
+ return false;
+ }
+ return Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED, 0, UserHandle.USER_CURRENT)
+ != 0;
+ }
+
+ /**
+ * Set Accessibility mouse keys feature enabled/disabled.
+ *
+ * <p>
+ * ‘Mouse keys’ is an accessibility feature to aid users who have physical disabilities,
+ * that allows the user to use the keys on the keyboard to control the mouse pointer and
+ * other perform other mouse functionality.
+ * </p>
+ *
+ * @hide
+ */
+ @TestApi
+ @FlaggedApi(FLAG_KEYBOARD_A11Y_MOUSE_KEYS)
+ @RequiresPermission(Manifest.permission.WRITE_SETTINGS)
+ public static void setAccessibilityMouseKeysEnabled(@NonNull Context context,
+ boolean enabled) {
+ if (!isAccessibilityMouseKeysFeatureFlagEnabled()) {
+ return;
+ }
+ Settings.Secure.putIntForUser(context.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED, enabled ? 1 : 0,
+ UserHandle.USER_CURRENT);
+ }
}
diff --git a/core/java/android/hardware/input/KeyGlyphMap.aidl b/core/java/android/hardware/input/KeyGlyphMap.aidl
new file mode 100644
index 000000000000..104f1e47dcc8
--- /dev/null
+++ b/core/java/android/hardware/input/KeyGlyphMap.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright 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.hardware.input;
+
+parcelable KeyGlyphMap; \ No newline at end of file
diff --git a/core/java/android/hardware/input/KeyGlyphMap.java b/core/java/android/hardware/input/KeyGlyphMap.java
new file mode 100644
index 000000000000..49c47a2ad4c4
--- /dev/null
+++ b/core/java/android/hardware/input/KeyGlyphMap.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 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.hardware.input;
+
+import android.annotation.DrawableRes;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+import android.util.SparseIntArray;
+import android.view.KeyEvent;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class provides access to device specific key glyphs, modifier glyphs and device specific
+ * shortcuts and keys
+ *
+ * @hide
+ */
+public final class KeyGlyphMap implements Parcelable {
+ private static final String TAG = "KeyGlyphMap";
+
+ @NonNull
+ private final ComponentName mComponentName;
+ @NonNull
+ private final SparseIntArray mKeyGlyphs;
+ @NonNull
+ private final SparseIntArray mModifierGlyphs;
+ @NonNull
+ private final int[] mFunctionRowKeys;
+ @NonNull
+ private final Map<KeyCombination, Integer> mHardwareShortcuts;
+
+ public static final @NonNull Parcelable.Creator<KeyGlyphMap> CREATOR =
+ new Parcelable.Creator<>() {
+ public KeyGlyphMap createFromParcel(Parcel in) {
+ return new KeyGlyphMap(in);
+ }
+
+ public KeyGlyphMap[] newArray(int size) {
+ return new KeyGlyphMap[size];
+ }
+ };
+
+ public KeyGlyphMap(@NonNull ComponentName componentName,
+ @NonNull SparseIntArray keyGlyphs, @NonNull SparseIntArray modifierGlyphs,
+ @NonNull int[] functionRowKeys,
+ @NonNull Map<KeyCombination, Integer> hardwareShortcuts) {
+ mComponentName = componentName;
+ mKeyGlyphs = keyGlyphs;
+ mModifierGlyphs = modifierGlyphs;
+ mFunctionRowKeys = functionRowKeys;
+ mHardwareShortcuts = hardwareShortcuts;
+ }
+
+ public KeyGlyphMap(Parcel in) {
+ mComponentName = in.readParcelable(getClass().getClassLoader(), ComponentName.class);
+ mKeyGlyphs = in.readSparseIntArray();
+ mModifierGlyphs = in.readSparseIntArray();
+ mFunctionRowKeys = new int[in.readInt()];
+ in.readIntArray(mFunctionRowKeys);
+ mHardwareShortcuts = new HashMap<>(in.readInt());
+ in.readMap(mHardwareShortcuts, getClass().getClassLoader(), KeyCombination.class,
+ Integer.class);
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeParcelable(mComponentName, 0);
+ dest.writeSparseIntArray(mKeyGlyphs);
+ dest.writeSparseIntArray(mModifierGlyphs);
+ dest.writeInt(mFunctionRowKeys.length);
+ dest.writeIntArray(mFunctionRowKeys);
+ dest.writeInt(mHardwareShortcuts.size());
+ dest.writeMap(mHardwareShortcuts);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Defines a key combination that includes a keycode and modifier state.
+ */
+ public record KeyCombination(int modifierState, int keycode) {}
+
+ /**
+ * Returns keycodes generated from the functional row defined for the keyboard.
+ */
+ public int[] getFunctionRowKeys() {
+ return mFunctionRowKeys;
+ }
+
+ /**
+ * Returns hardware defined shortcuts that are handled in the firmware of a particular
+ * keyboard (e.g. Fn+Backspace = Back, etc.)
+ *
+ * @return a map of (modifier + key) combinations to keycode mappings that are handled by the
+ * device hardware/firmware.
+ */
+ public Map<KeyCombination, Integer> getHardwareShortcuts() {
+ return mHardwareShortcuts;
+ }
+
+ /**
+ * Provides the drawable resource for the glyph for a keycode.
+ * Returns null if not available.
+ */
+ @Nullable
+ public Drawable getDrawableForKeycode(Context context, int keycode) {
+ return getDrawable(context, mKeyGlyphs.get(keycode, 0));
+ }
+
+ /**
+ * Provides the drawable resource for the glyph for a modifier key.
+ * Returns null if not available.
+ */
+ @Nullable
+ public Drawable getDrawableForModifier(Context context, int modifierKeycode) {
+ int modifier = switch (modifierKeycode) {
+ case KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_META_RIGHT -> KeyEvent.META_META_ON;
+ case KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.KEYCODE_CTRL_RIGHT -> KeyEvent.META_CTRL_ON;
+ case KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_ALT_RIGHT -> KeyEvent.META_ALT_ON;
+ case KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SHIFT_RIGHT ->
+ KeyEvent.META_SHIFT_ON;
+ case KeyEvent.KEYCODE_FUNCTION -> KeyEvent.META_FUNCTION_ON;
+ case KeyEvent.KEYCODE_SYM -> KeyEvent.META_SYM_ON;
+ case KeyEvent.KEYCODE_CAPS_LOCK -> KeyEvent.META_CAPS_LOCK_ON;
+ case KeyEvent.KEYCODE_NUM_LOCK -> KeyEvent.META_NUM_LOCK_ON;
+ case KeyEvent.KEYCODE_SCROLL_LOCK -> KeyEvent.META_SCROLL_LOCK_ON;
+ default -> 0;
+ };
+ return getDrawable(context, mModifierGlyphs.get(modifier, 0));
+ }
+
+ @Nullable
+ private Drawable getDrawable(Context context, @DrawableRes int drawableRes) {
+ PackageManager pm = context.getPackageManager();
+ try {
+ ActivityInfo receiver = pm.getReceiverInfo(mComponentName,
+ PackageManager.GET_META_DATA
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
+ Resources resources = pm.getResourcesForApplication(receiver.applicationInfo);
+ return resources.getDrawable(drawableRes, null);
+ } catch (PackageManager.NameNotFoundException ignored) {
+ Log.e(TAG, "Package name not found for " + mComponentName);
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return "KeyGlyphMap{"
+ + "mComponentName=" + mComponentName
+ + ", mKeyGlyphs=" + mKeyGlyphs
+ + ", mModifierGlyphs=" + mModifierGlyphs
+ + ", mFunctionRowKeys=" + Arrays.toString(mFunctionRowKeys)
+ + ", mHardwareShortcuts=" + mHardwareShortcuts
+ + '}';
+ }
+}
diff --git a/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.java b/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.java
index 3be911abe732..8c98abd6dbfe 100644
--- a/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.java
+++ b/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.java
@@ -107,7 +107,8 @@ public final class VirtualRotaryEncoderScrollEvent implements Parcelable {
}
/**
- * Sets the scroll amount, normalized from -1.0 to 1.0, inclusive.
+ * Sets the scroll amount, normalized from -1.0 to 1.0, inclusive. By default, the scroll
+ * amount is 0, which results in no scroll.
* <p>
* Positive values indicate scrolling forward (e.g. down in a vertical list); negative
* values, backward.
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index ed536cee7274..0cd280002dbf 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -53,4 +53,25 @@ flag {
name: "touchpad_tap_dragging"
description: "Offers a setting to enable touchpad tap dragging"
bug: "321978150"
-} \ No newline at end of file
+}
+
+flag {
+ namespace: "input_native"
+ name: "keyboard_glyph_map"
+ description: "Allows system to provide keyboard specific key drawables and shortcuts via config files"
+ bug: "345440920"
+}
+
+flag {
+ namespace: "input_native"
+ name: "keyboard_a11y_mouse_keys"
+ description: "Controls if the mouse keys accessibility feature for physical keyboard is available to the user"
+ bug: "341799888"
+}
+
+flag {
+ namespace: "input_native"
+ name: "touchpad_visualizer"
+ description: "Enables a developer overlay that displays raw touchpad input data and gesture recognition status in real-time."
+ bug: "286551975"
+}
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java
index 5012a792af74..d9349701bf7d 100644
--- a/core/java/android/hardware/location/ContextHubInfo.java
+++ b/core/java/android/hardware/location/ContextHubInfo.java
@@ -26,6 +26,7 @@ import android.os.Parcelable;
import android.util.proto.ProtoOutputStream;
import java.util.Arrays;
+import java.util.Objects;
/**
* @hide
@@ -294,24 +295,38 @@ public class ContextHubInfo implements Parcelable {
@NonNull
@Override
public String toString() {
- String retVal = "";
- retVal += "ID/handle : " + mId;
- retVal += ", Name : " + mName;
- retVal += "\n\tVendor : " + mVendor;
- retVal += ", Toolchain : " + mToolchain;
- retVal += ", Toolchain version: 0x" + Integer.toHexString(mToolchainVersion);
- retVal += "\n\tPlatformVersion : 0x" + Integer.toHexString(mPlatformVersion);
- retVal += ", SwVersion : "
- + Byte.toUnsignedInt(mChreApiMajorVersion) + "." + Byte.toUnsignedInt(
- mChreApiMinorVersion) + "." + Short.toUnsignedInt(mChrePatchVersion);
- retVal += ", CHRE platform ID: 0x" + Long.toHexString(mChrePlatformId);
- retVal += "\n\tPeakMips : " + mPeakMips;
- retVal += ", StoppedPowerDraw : " + mStoppedPowerDrawMw + " mW";
- retVal += ", PeakPowerDraw : " + mPeakPowerDrawMw + " mW";
- retVal += ", MaxPacketLength : " + mMaxPacketLengthBytes + " Bytes";
- retVal += ", SupportsReliableMessage : " + mSupportsReliableMessages;
-
- return retVal;
+ StringBuilder out = new StringBuilder();
+ out.append("ID/handle : ");
+ out.append(mId);
+ out.append(", Name : ");
+ out.append(mName);
+ out.append("\n\tVendor : ");
+ out.append(mVendor);
+ out.append(", Toolchain : ");
+ out.append(mToolchain);
+ out.append(", Toolchain version: 0x");
+ out.append(Integer.toHexString(mToolchainVersion));
+ out.append("\n\tPlatformVersion : 0x");
+ out.append(Integer.toHexString(mPlatformVersion));
+ out.append(", SwVersion : ");
+ out.append(Byte.toUnsignedInt(mChreApiMajorVersion));
+ out.append(".");
+ out.append(Byte.toUnsignedInt(mChreApiMinorVersion));
+ out.append(".");
+ out.append(Short.toUnsignedInt(mChrePatchVersion));
+ out.append(", CHRE platform ID: 0x");
+ out.append(Long.toHexString(mChrePlatformId));
+ out.append("\n\tPeakMips : ");
+ out.append(mPeakMips);
+ out.append(", StoppedPowerDraw : ");
+ out.append(mStoppedPowerDrawMw);
+ out.append(" mW, PeakPowerDraw : ");
+ out.append(mPeakPowerDrawMw);
+ out.append(" mW, MaxPacketLength : ");
+ out.append(mMaxPacketLengthBytes);
+ out.append(" Bytes, SupportsReliableMessages : ");
+ out.append(mSupportsReliableMessages);
+ return out.toString();
}
/**
@@ -370,6 +385,20 @@ public class ContextHubInfo implements Parcelable {
return isEqual;
}
+ @Override
+ public int hashCode() {
+ if (!Flags.fixApiCheck()) {
+ return super.hashCode();
+ }
+
+ return Objects.hash(mId, mName, mVendor, mToolchain, mToolchainVersion,
+ getStaticSwVersion(), mChrePlatformId, mPeakMips,
+ mStoppedPowerDrawMw, mSleepPowerDrawMw, mPeakPowerDrawMw,
+ mMaxPacketLengthBytes, mSupportsReliableMessages,
+ Arrays.hashCode(mSupportedSensors),
+ Arrays.hashCode(mMemoryRegions));
+ }
+
private ContextHubInfo(Parcel in) {
mId = in.readInt();
mName = in.readString();
diff --git a/core/java/android/hardware/location/ContextHubIntentEvent.java b/core/java/android/hardware/location/ContextHubIntentEvent.java
index 06c533401e27..002c683831da 100644
--- a/core/java/android/hardware/location/ContextHubIntentEvent.java
+++ b/core/java/android/hardware/location/ContextHubIntentEvent.java
@@ -19,6 +19,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.PendingIntent;
+import android.chre.flags.Flags;
import android.content.Intent;
import java.util.Objects;
@@ -275,6 +276,16 @@ public class ContextHubIntentEvent {
return isEqual;
}
+ @Override
+ public int hashCode() {
+ if (!Flags.fixApiCheck()) {
+ return super.hashCode();
+ }
+
+ return Objects.hash(mEventType, mContextHubInfo, mNanoAppId,
+ mNanoAppMessage, mNanoAppAbortCode, mClientAuthorizationState);
+ }
+
private static void hasExtraOrThrow(Intent intent, String extra) {
if (!intent.hasExtra(extra)) {
throw new IllegalArgumentException("Intent did not have extra: " + extra);
diff --git a/core/java/android/hardware/location/MemoryRegion.java b/core/java/android/hardware/location/MemoryRegion.java
index c033228441b1..d95894fca217 100644
--- a/core/java/android/hardware/location/MemoryRegion.java
+++ b/core/java/android/hardware/location/MemoryRegion.java
@@ -19,9 +19,12 @@ package android.hardware.location;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.chre.flags.Flags;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.Objects;
+
/**
* @hide
*/
@@ -128,6 +131,16 @@ public class MemoryRegion implements Parcelable{
}
@Override
+ public int hashCode() {
+ if (!Flags.fixApiCheck()) {
+ return super.hashCode();
+ }
+
+ return Objects.hash(mSizeBytes, mSizeBytesFree, mIsReadable,
+ mIsWritable, mIsExecutable);
+ }
+
+ @Override
public int describeContents() {
return 0;
}
diff --git a/core/java/android/hardware/location/NanoAppMessage.java b/core/java/android/hardware/location/NanoAppMessage.java
index 905caf02fc46..ec0adda38d10 100644
--- a/core/java/android/hardware/location/NanoAppMessage.java
+++ b/core/java/android/hardware/location/NanoAppMessage.java
@@ -26,6 +26,7 @@ import android.os.Parcelable;
import libcore.util.HexEncoding;
import java.util.Arrays;
+import java.util.Objects;
/**
* A class describing messages send to or from nanoapps through the Context Hub Service.
@@ -229,27 +230,38 @@ public final class NanoAppMessage implements Parcelable {
public String toString() {
int length = mMessageBody.length;
- String ret = "NanoAppMessage[type = " + mMessageType + ", length = " + mMessageBody.length
- + " bytes, " + (mIsBroadcasted ? "broadcast" : "unicast") + ", nanoapp = 0x"
- + Long.toHexString(mNanoAppId) + ", isReliable = "
- + (mIsReliable ? "true" : "false") + ", messageSequenceNumber = "
- + mMessageSequenceNumber + "](";
+ StringBuilder out = new StringBuilder();
+ out.append( "NanoAppMessage[type = ");
+ out.append(mMessageType);
+ out.append(", length = ");
+ out.append(mMessageBody.length);
+ out.append(" bytes, ");
+ out.append(mIsBroadcasted ? "broadcast" : "unicast");
+ out.append(", nanoapp = 0x");
+ out.append(Long.toHexString(mNanoAppId));
+ out.append(", isReliable = ");
+ out.append(mIsReliable ? "true" : "false");
+ out.append(", messageSequenceNumber = ");
+ out.append(mMessageSequenceNumber);
+ out.append("](");
+
if (length > 0) {
- ret += "data = 0x";
+ out.append("data = 0x");
}
for (int i = 0; i < Math.min(length, DEBUG_LOG_NUM_BYTES); i++) {
- ret += HexEncoding.encodeToString(mMessageBody[i], true /* upperCase */);
+ out.append(HexEncoding.encodeToString(mMessageBody[i],
+ true /* upperCase */));
if ((i + 1) % 4 == 0) {
- ret += " ";
+ out.append(" ");
}
}
if (length > DEBUG_LOG_NUM_BYTES) {
- ret += "...";
+ out.append("...");
}
- ret += ")";
+ out.append(")");
- return ret;
+ return out.toString();
}
@Override
@@ -273,4 +285,15 @@ public final class NanoAppMessage implements Parcelable {
return isEqual;
}
+
+ @Override
+ public int hashCode() {
+ if (!Flags.fixApiCheck()) {
+ return super.hashCode();
+ }
+
+ return Objects.hash(mNanoAppId, mMessageType, mIsBroadcasted,
+ Arrays.hashCode(mMessageBody), mIsReliable,
+ mMessageSequenceNumber);
+ }
}
diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java
index e2d215ebfed4..4bc5bd2427ea 100644
--- a/core/java/android/inputmethodservice/AbstractInputMethodService.java
+++ b/core/java/android/inputmethodservice/AbstractInputMethodService.java
@@ -29,6 +29,7 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import android.view.inputmethod.Flags;
import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodSession;
import android.window.WindowProviderService;
@@ -186,6 +187,10 @@ public abstract class AbstractInputMethodService extends WindowProviderService
if (callback != null) {
callback.finishedEvent(seq, handled);
}
+ if (Flags.imeSwitcherRevamp() && !handled && event.getAction() == KeyEvent.ACTION_DOWN
+ && event.getUnicodeChar() > 0 && mInputMethodServiceInternal != null) {
+ mInputMethodServiceInternal.notifyUserActionIfNecessary();
+ }
}
/**
diff --git a/core/java/android/inputmethodservice/ImsConfigurationTracker.java b/core/java/android/inputmethodservice/ImsConfigurationTracker.java
index 30ef0a2a6f7f..17a5ffcb1081 100644
--- a/core/java/android/inputmethodservice/ImsConfigurationTracker.java
+++ b/core/java/android/inputmethodservice/ImsConfigurationTracker.java
@@ -16,6 +16,8 @@
package android.inputmethodservice;
+import static android.content.pm.ActivityInfo.CONFIG_RESOURCES_UNUSED;
+
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -88,12 +90,16 @@ public final class ImsConfigurationTracker {
if (!mInitialized) {
return;
}
+ // Don't restart InputMethodService that claims it does not use resources at all.
+ boolean neverReset = android.content.res.Flags.handleAllConfigChanges()
+ && (mHandledConfigChanges & CONFIG_RESOURCES_UNUSED) != 0;
+
final int diff = mLastKnownConfig != null
? mLastKnownConfig.diffPublicOnly(newConfig) : CONFIG_CHANGED;
// If the new config is the same as the config this Service is already running with,
// then don't bother calling resetStateForNewConfiguration.
final int unhandledDiff = (diff & ~mHandledConfigChanges);
- if (unhandledDiff != 0) {
+ if (unhandledDiff != 0 && !neverReset) {
resetStateForNewConfigurationRunner.run();
}
if (diff != 0) {
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 943b04f517f3..855c3098c9e7 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -16,7 +16,6 @@
package android.inputmethodservice;
-import static android.view.inputmethod.Flags.predictiveBackIme;
import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VIEW_STARTED;
import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VISIBILITY;
import static android.inputmethodservice.InputMethodServiceProto.CONFIGURATION;
@@ -57,6 +56,7 @@ import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECT
import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED;
import static android.view.inputmethod.Flags.FLAG_CONNECTIONLESS_HANDWRITING;
import static android.view.inputmethod.Flags.ctrlShiftShortcut;
+import static android.view.inputmethod.Flags.predictiveBackIme;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -4341,6 +4341,16 @@ public class InputMethodService extends AbstractInputMethodService {
}
/**
+ * Called when the IME switch button was clicked from the client. This will show the input
+ * method picker dialog.
+ *
+ * @hide
+ */
+ final void onImeSwitchButtonClickFromClient() {
+ mPrivOps.onImeSwitchButtonClickFromClient(getDisplayId());
+ }
+
+ /**
* Used to inject custom {@link InputMethodServiceInternal}.
*
* @return the {@link InputMethodServiceInternal} to be used.
diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java
index de67e06ddda7..3ce67b0e0ec1 100644
--- a/core/java/android/inputmethodservice/NavigationBarController.java
+++ b/core/java/android/inputmethodservice/NavigationBarController.java
@@ -42,6 +42,7 @@ import android.view.WindowInsets;
import android.view.WindowInsetsController.Appearance;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
+import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout;
import com.android.internal.inputmethod.InputMethodNavButtonFlags;
@@ -145,7 +146,8 @@ final class NavigationBarController {
return mImpl.toDebugString();
}
- private static final class Impl implements Callback, Window.DecorCallback {
+ private static final class Impl implements Callback, Window.DecorCallback,
+ NavigationBarView.ButtonClickListener {
private static final int DEFAULT_COLOR_ADAPT_TRANSITION_TIME = 1700;
// Copied from com.android.systemui.animation.Interpolators#LEGACY_DECELERATE
@@ -241,6 +243,7 @@ final class NavigationBarController {
? StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN
: 0);
navigationBarView.setNavigationIconHints(hints);
+ navigationBarView.prepareNavButtons(this);
}
} else {
mNavigationBarFrame.setLayoutParams(new FrameLayout.LayoutParams(
@@ -592,6 +595,17 @@ final class NavigationBarController {
return drawLegacyNavigationBarBackground;
}
+ @Override
+ public void onImeSwitchButtonClick(View v) {
+ mService.onImeSwitchButtonClickFromClient();
+ }
+
+ @Override
+ public boolean onImeSwitchButtonLongClick(View v) {
+ v.getContext().getSystemService(InputMethodManager.class).showInputMethodPicker();
+ return true;
+ }
+
/**
* Returns the height of the IME caption bar if this should be shown, or {@code 0} instead.
*/
diff --git a/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java b/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java
index f423672c5490..540243c4fe92 100644
--- a/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java
+++ b/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java
@@ -41,6 +41,7 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.inputmethod.Flags;
import android.view.inputmethod.InputConnection;
import android.widget.ImageView;
@@ -58,12 +59,30 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
private int mTouchDownY;
private AudioManager mAudioManager;
private boolean mGestureAborted;
+ /**
+ * Whether the long click action has been invoked. The short click action is invoked on the up
+ * event while a long click is invoked as soon as the long press duration is reached, so a long
+ * click could be performed before the short click is checked, in which case the short click's
+ * action should not be invoked.
+ *
+ * @see View#mHasPerformedLongPress
+ */
+ private boolean mLongClicked;
private OnClickListener mOnClickListener;
private final KeyButtonRipple mRipple;
private final Paint mOvalBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
private float mDarkIntensity;
private boolean mHasOvalBg = false;
+ /** Runnable for checking whether the long click action should be performed. */
+ private final Runnable mCheckLongPress = new Runnable() {
+ public void run() {
+ if (isPressed() && performLongClick()) {
+ mLongClicked = true;
+ }
+ }
+ };
+
public KeyButtonView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -159,6 +178,7 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
switch (action) {
case MotionEvent.ACTION_DOWN:
mDownTime = SystemClock.uptimeMillis();
+ mLongClicked = false;
setPressed(true);
// Use raw X and Y to detect gestures in case a parent changes the x and y values
@@ -173,6 +193,10 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
if (!showSwipeUI) {
playSoundEffect(SoundEffectConstants.CLICK);
}
+ if (Flags.imeSwitcherRevamp() && isLongClickable()) {
+ removeCallbacks(mCheckLongPress);
+ postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
+ }
break;
case MotionEvent.ACTION_MOVE:
x = (int) ev.getRawX();
@@ -183,6 +207,9 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
// When quick step is enabled, prevent animating the ripple triggered by
// setPressed and decide to run it on touch up
setPressed(false);
+ if (isLongClickable()) {
+ removeCallbacks(mCheckLongPress);
+ }
}
break;
case MotionEvent.ACTION_CANCEL:
@@ -190,9 +217,12 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
if (mCode != KEYCODE_UNKNOWN) {
sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
}
+ if (isLongClickable()) {
+ removeCallbacks(mCheckLongPress);
+ }
break;
case MotionEvent.ACTION_UP:
- final boolean doIt = isPressed();
+ final boolean doIt = isPressed() && !mLongClicked;
setPressed(false);
final boolean doHapticFeedback = (SystemClock.uptimeMillis() - mDownTime) > 150;
if (showSwipeUI) {
@@ -201,7 +231,7 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
playSoundEffect(SoundEffectConstants.CLICK);
}
- } else if (doHapticFeedback) {
+ } else if (doHapticFeedback && !mLongClicked) {
// Always send a release ourselves because it doesn't seem to be sent elsewhere
// and it feels weird to sometimes get a release haptic and other times not.
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
@@ -221,6 +251,9 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
}
}
+ if (isLongClickable()) {
+ removeCallbacks(mCheckLongPress);
+ }
break;
}
diff --git a/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java b/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java
index e28f34528f42..a3beaf427226 100644
--- a/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java
+++ b/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java
@@ -26,6 +26,7 @@ import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.annotation.DrawableRes;
import android.annotation.FloatRange;
+import android.annotation.NonNull;
import android.app.StatusBarManager;
import android.content.Context;
import android.content.res.Configuration;
@@ -39,6 +40,7 @@ import android.view.Surface;
import android.view.View;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
+import android.view.inputmethod.Flags;
import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout;
@@ -79,6 +81,28 @@ public final class NavigationBarView extends FrameLayout {
private NavigationBarInflaterView mNavigationInflaterView;
+ /**
+ * Interface definition for callbacks to be invoked when navigation bar buttons are clicked.
+ */
+ public interface ButtonClickListener {
+
+ /**
+ * Called when the IME switch button is clicked.
+ *
+ * @param v The view that was clicked.
+ */
+ void onImeSwitchButtonClick(View v);
+
+ /**
+ * Called when the IME switch button has been clicked and held.
+ *
+ * @param v The view that was clicked and held.
+ *
+ * @return true if the callback consumed the long click, false otherwise.
+ */
+ boolean onImeSwitchButtonLongClick(View v);
+ }
+
public NavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -98,13 +122,27 @@ public final class NavigationBarView extends FrameLayout {
new ButtonDispatcher(com.android.internal.R.id.input_method_nav_home_handle));
mDeadZone = new android.inputmethodservice.navigationbar.DeadZone(this);
+ }
+ /**
+ * Prepares the navigation bar buttons to be used and sets the on click listeners.
+ *
+ * @param listener The listener used to handle the clicks on the navigation bar buttons.
+ */
+ public void prepareNavButtons(@NonNull ButtonClickListener listener) {
getBackButton().setLongClickable(false);
- final ButtonDispatcher imeSwitchButton = getImeSwitchButton();
- imeSwitchButton.setLongClickable(false);
- imeSwitchButton.setOnClickListener(view -> view.getContext()
- .getSystemService(InputMethodManager.class).showInputMethodPicker());
+ if (Flags.imeSwitcherRevamp()) {
+ final var imeSwitchButton = getImeSwitchButton();
+ imeSwitchButton.setLongClickable(true);
+ imeSwitchButton.setOnClickListener(listener::onImeSwitchButtonClick);
+ imeSwitchButton.setOnLongClickListener(listener::onImeSwitchButtonLongClick);
+ } else {
+ final ButtonDispatcher imeSwitchButton = getImeSwitchButton();
+ imeSwitchButton.setLongClickable(false);
+ imeSwitchButton.setOnClickListener(view -> view.getContext()
+ .getSystemService(InputMethodManager.class).showInputMethodPicker());
+ }
}
@Override
diff --git a/core/java/android/os/IVibratorManagerService.aidl b/core/java/android/os/IVibratorManagerService.aidl
index 8b1577cb4b1c..97993b609fda 100644
--- a/core/java/android/os/IVibratorManagerService.aidl
+++ b/core/java/android/os/IVibratorManagerService.aidl
@@ -41,5 +41,5 @@ interface IVibratorManagerService {
// There is no order guarantee with respect to the two-way APIs above like
// vibrate/isVibrating/cancel.
oneway void performHapticFeedback(int uid, int deviceId, String opPkg, int constant,
- boolean always, String reason, boolean fromIme);
+ String reason, int flags, int privFlags);
}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 406a1a6795ab..026013c34e30 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -564,8 +564,7 @@ public final class PowerManager {
BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM,
BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM,
BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT,
- BRIGHTNESS_CONSTRAINT_TYPE_DIM,
- BRIGHTNESS_CONSTRAINT_TYPE_DOZE
+ BRIGHTNESS_CONSTRAINT_TYPE_DIM
})
@Retention(RetentionPolicy.SOURCE)
public @interface BrightnessConstraint{}
@@ -594,12 +593,6 @@ public final class PowerManager {
public static final int BRIGHTNESS_CONSTRAINT_TYPE_DIM = 3;
/**
- * Brightness constraint type: minimum allowed value.
- * @hide
- */
- public static final int BRIGHTNESS_CONSTRAINT_TYPE_DOZE = 4;
-
- /**
* @hide
*/
@IntDef(prefix = { "WAKE_REASON_" }, value = {
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index 2a62c24a86e1..5339d7331426 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -206,13 +206,12 @@ public class SystemVibrator extends Vibrator {
}
@Override
- public void performHapticFeedback(
- int constant, boolean always, String reason, boolean fromIme) {
+ public void performHapticFeedback(int constant, String reason, int flags, int privFlags) {
if (mVibratorManager == null) {
Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager.");
return;
}
- mVibratorManager.performHapticFeedback(constant, always, reason, fromIme);
+ mVibratorManager.performHapticFeedback(constant, reason, flags, privFlags);
}
@Override
diff --git a/core/java/android/os/SystemVibratorManager.java b/core/java/android/os/SystemVibratorManager.java
index c80bcac2624f..a9846ba7e264 100644
--- a/core/java/android/os/SystemVibratorManager.java
+++ b/core/java/android/os/SystemVibratorManager.java
@@ -147,15 +147,14 @@ public class SystemVibratorManager extends VibratorManager {
}
@Override
- public void performHapticFeedback(int constant, boolean always, String reason,
- boolean fromIme) {
+ public void performHapticFeedback(int constant, String reason, int flags, int privFlags) {
if (mService == null) {
Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager service.");
return;
}
try {
- mService.performHapticFeedback(
- mUid, mContext.getDeviceId(), mPackageName, constant, always, reason, fromIme);
+ mService.performHapticFeedback(mUid, mContext.getDeviceId(), mPackageName, constant,
+ reason, flags, privFlags);
} catch (RemoteException e) {
Log.w(TAG, "Failed to perform haptic feedback.", e);
}
@@ -245,9 +244,8 @@ public class SystemVibratorManager extends VibratorManager {
}
@Override
- public void performHapticFeedback(int effectId, boolean always, String reason,
- boolean fromIme) {
- SystemVibratorManager.this.performHapticFeedback(effectId, always, reason, fromIme);
+ public void performHapticFeedback(int effectId, String reason, int flags, int privFlags) {
+ SystemVibratorManager.this.performHapticFeedback(effectId, reason, flags, privFlags);
}
@Override
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index f30a9f5411ee..3aa42c6bb594 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -3927,7 +3927,12 @@ public class UserManager {
android.Manifest.permission.QUERY_USERS,
android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
public @NonNull UserProperties getUserProperties(@NonNull UserHandle userHandle) {
- return mUserPropertiesCache.query(userHandle.getIdentifier());
+ final int userId = userHandle.getIdentifier();
+ // Avoid calling into system server for invalid user ids.
+ if (android.multiuser.Flags.fixGetUserPropertyCache() && userId < 0) {
+ throw new IllegalArgumentException("Cannot access properties for user " + userId);
+ }
+ return mUserPropertiesCache.query(userId);
}
/**
@@ -5663,6 +5668,33 @@ public class UserManager {
}
}
+ private static final String CACHE_KEY_QUIET_MODE_ENABLED_PROPERTY =
+ PropertyInvalidatedCache.createPropertyName(
+ PropertyInvalidatedCache.MODULE_SYSTEM, "quiet_mode_enabled");
+
+ private final PropertyInvalidatedCache<Integer, Boolean> mQuietModeEnabledCache =
+ new PropertyInvalidatedCache<Integer, Boolean>(
+ 32, CACHE_KEY_QUIET_MODE_ENABLED_PROPERTY) {
+ @Override
+ public Boolean recompute(Integer query) {
+ try {
+ return mService.isQuietModeEnabled(query);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+ @Override
+ public boolean bypass(Integer query) {
+ return query < 0;
+ }
+ };
+
+
+ /** @hide */
+ public static final void invalidateQuietModeEnabledCache() {
+ PropertyInvalidatedCache.invalidateCache(CACHE_KEY_QUIET_MODE_ENABLED_PROPERTY);
+ }
+
/**
* Returns whether the given profile is in quiet mode or not.
*
@@ -5670,6 +5702,13 @@ public class UserManager {
* @return true if the profile is in quiet mode, false otherwise.
*/
public boolean isQuietModeEnabled(UserHandle userHandle) {
+ if (android.multiuser.Flags.cacheQuietModeState()){
+ final int userId = userHandle.getIdentifier();
+ if (userId < 0) {
+ return false;
+ }
+ return mQuietModeEnabledCache.query(userId);
+ }
try {
return mService.isQuietModeEnabled(userHandle.getIdentifier());
} catch (RemoteException re) {
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 4b2d4eb833ff..71c83f20741d 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -33,6 +33,7 @@ import android.media.AudioAttributes;
import android.os.vibrator.VibrationConfig;
import android.os.vibrator.VibratorFrequencyProfile;
import android.util.Log;
+import android.view.HapticFeedbackConstants;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -184,16 +185,6 @@ public abstract class Vibrator {
}
/**
- * Whether the keyboard vibration is enabled by default.
- *
- * @return {@code true} if the keyboard vibration is default enabled, {@code false} otherwise.
- * @hide
- */
- public boolean isDefaultKeyboardVibrationEnabled() {
- return getConfig().isDefaultKeyboardVibrationEnabled();
- }
-
- /**
* Return the ID of this vibrator.
*
* @return A non-negative integer representing the id of the vibrator controlled by this
@@ -529,17 +520,15 @@ public abstract class Vibrator {
*
* @param constant the ID for the haptic feedback. This should be one of the constants defined
* in {@link HapticFeedbackConstants}.
- * @param always {@code true} if the haptic feedback should be played regardless of the user
- * vibration intensity settings applicable to the corresponding vibration.
- * {@code false} if the vibration for the haptic feedback should respect the applicable
- * vibration intensity settings.
* @param reason the reason for this haptic feedback.
- * @param fromIme the haptic feedback is performed from an IME.
+ * @param flags Additional flags as per {@link HapticFeedbackConstants}.
+ * @param privFlags Additional private flags as per {@link HapticFeedbackConstants}.
*
* @hide
*/
- public void performHapticFeedback(int constant, boolean always, String reason,
- boolean fromIme) {
+ public void performHapticFeedback(int constant, String reason,
+ @HapticFeedbackConstants.Flags int flags,
+ @HapticFeedbackConstants.PrivateFlags int privFlags) {
Log.w(TAG, "performHapticFeedback is not supported");
}
diff --git a/core/java/android/os/VibratorManager.java b/core/java/android/os/VibratorManager.java
index 513c4bd7ec0c..2c7a852cf29f 100644
--- a/core/java/android/os/VibratorManager.java
+++ b/core/java/android/os/VibratorManager.java
@@ -23,6 +23,7 @@ import android.annotation.SystemService;
import android.app.ActivityThread;
import android.content.Context;
import android.util.Log;
+import android.view.HapticFeedbackConstants;
/**
* Provides access to all vibrators from the device, as well as the ability to run them
@@ -142,15 +143,14 @@ public abstract class VibratorManager {
*
* @param constant the ID of the requested haptic feedback. Should be one of the constants
* defined in {@link HapticFeedbackConstants}.
- * @param always {@code true} if the haptic feedback should be played regardless of the user
- * vibration intensity settings applicable to the corresponding vibration.
- * {@code false} otherwise.
* @param reason the reason for this haptic feedback.
- * @param fromIme the haptic feedback is performed from an IME.
+ * @param flags Additional flags as per {@link HapticFeedbackConstants}.
+ * @param privFlags Additional private flags as per {@link HapticFeedbackConstants}.
* @hide
*/
- public void performHapticFeedback(int constant, boolean always, String reason,
- boolean fromIme) {
+ public void performHapticFeedback(int constant, String reason,
+ @HapticFeedbackConstants.Flags int flags,
+ @HapticFeedbackConstants.PrivateFlags int privFlags) {
Log.w(TAG, "performHapticFeedback is not supported");
}
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 76cf901ff30d..f026997bcc57 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -76,6 +76,14 @@ flag {
}
flag {
+ name: "ordered_broadcast_multiple_permissions"
+ is_exported: true
+ namespace: "bluetooth"
+ description: "Guards the Context.sendOrderedBroadcastMultiplePermissions API"
+ bug: "345802719"
+}
+
+flag {
name: "battery_saver_supported_check_api"
is_exported: true
namespace: "backstage_power"
@@ -208,3 +216,11 @@ flag {
description: "Allow privileged apps to call bugreport generation without enforcing user consent and delegate it to the calling app instead"
bug: "324046728"
}
+
+flag {
+ name: "get_private_space_settings"
+ namespace: "profile_experiences"
+ description: "Guards a new Private Profile API in LauncherApps"
+ bug: "346294653"
+ is_exported: true
+}
diff --git a/core/java/android/os/vibrator/VibrationConfig.java b/core/java/android/os/vibrator/VibrationConfig.java
index 555a1204c8a7..f6e73b39f84b 100644
--- a/core/java/android/os/vibrator/VibrationConfig.java
+++ b/core/java/android/os/vibrator/VibrationConfig.java
@@ -68,9 +68,7 @@ public class VibrationConfig {
@VibrationIntensity
private final int mDefaultRingVibrationIntensity;
- private final boolean mDefaultKeyboardVibrationEnabled;
-
- private final boolean mHasFixedKeyboardAmplitude;
+ private final boolean mKeyboardVibrationSettingsSupported;
/** @hide */
public VibrationConfig(@Nullable Resources resources) {
@@ -87,10 +85,8 @@ public class VibrationConfig {
mIgnoreVibrationsOnWirelessCharger = loadBoolean(resources,
com.android.internal.R.bool.config_ignoreVibrationsOnWirelessCharger, false);
- mDefaultKeyboardVibrationEnabled = loadBoolean(resources,
- com.android.internal.R.bool.config_defaultKeyboardVibrationEnabled, true);
- mHasFixedKeyboardAmplitude = loadFloat(resources,
- com.android.internal.R.dimen.config_keyboardHapticFeedbackFixedAmplitude, -1) > 0;
+ mKeyboardVibrationSettingsSupported = loadBoolean(resources,
+ com.android.internal.R.bool.config_keyboardVibrationSettingsSupported, false);
mDefaultAlarmVibrationIntensity = loadDefaultIntensity(resources,
com.android.internal.R.integer.config_defaultAlarmVibrationIntensity);
@@ -194,19 +190,11 @@ public class VibrationConfig {
}
/**
- * Whether keyboard vibration settings is enabled by default.
- * @hide
- */
- public boolean isDefaultKeyboardVibrationEnabled() {
- return mDefaultKeyboardVibrationEnabled;
- }
-
- /**
- * Whether the device has a fixed amplitude for keyboard.
+ * Whether the device support keyboard vibration settings.
* @hide
*/
- public boolean hasFixedKeyboardAmplitude() {
- return mHasFixedKeyboardAmplitude;
+ public boolean isKeyboardVibrationSettingsSupported() {
+ return mKeyboardVibrationSettingsSupported;
}
/** Get the default vibration intensity for given usage. */
@@ -248,7 +236,7 @@ public class VibrationConfig {
+ ", mDefaultMediaIntensity=" + mDefaultMediaVibrationIntensity
+ ", mDefaultNotificationIntensity=" + mDefaultNotificationVibrationIntensity
+ ", mDefaultRingIntensity=" + mDefaultRingVibrationIntensity
- + ", mDefaultKeyboardVibrationEnabled=" + mDefaultKeyboardVibrationEnabled
+ + ", mKeyboardVibrationSettingsSupported=" + mKeyboardVibrationSettingsSupported
+ "}";
}
diff --git a/core/java/android/os/vibrator/flags.aconfig b/core/java/android/os/vibrator/flags.aconfig
index c73a422d931b..ad2f59db46ff 100644
--- a/core/java/android/os/vibrator/flags.aconfig
+++ b/core/java/android/os/vibrator/flags.aconfig
@@ -46,6 +46,7 @@ flag {
flag {
namespace: "haptics"
name: "vibration_xml_apis"
+ is_exported: true
description: "Enabled System APIs for vibration effect XML parser and serializer"
bug: "347273158"
metadata {
diff --git a/core/java/android/os/vibrator/persistence/ParsedVibration.java b/core/java/android/os/vibrator/persistence/ParsedVibration.java
index e5543ab6c6f7..19162699a2ef 100644
--- a/core/java/android/os/vibrator/persistence/ParsedVibration.java
+++ b/core/java/android/os/vibrator/persistence/ParsedVibration.java
@@ -27,6 +27,7 @@ import android.os.VibrationEffect;
import android.os.Vibrator;
import android.os.VibratorInfo;
+import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -37,21 +38,21 @@ import java.util.Objects;
*
* @hide
*/
-@TestApi // This was used in CTS before the flag was introduced.
@SystemApi
@FlaggedApi(FLAG_VIBRATION_XML_APIS)
public final class ParsedVibration {
- private final List<VibrationEffect> mEffects;
+ private final ArrayList<VibrationEffect> mEffects;
/** @hide */
@TestApi
public ParsedVibration(@NonNull List<VibrationEffect> effects) {
- mEffects = effects;
+ mEffects = new ArrayList<>(effects);
}
/** @hide */
public ParsedVibration(@NonNull VibrationEffect effect) {
- mEffects = List.of(effect);
+ mEffects = new ArrayList<>(1);
+ mEffects.add(effect);
}
/**
@@ -60,7 +61,6 @@ public final class ParsedVibration {
*
* @hide
*/
- @TestApi // This was used in CTS before the flag was introduced.
@SystemApi
@FlaggedApi(FLAG_VIBRATION_XML_APIS)
@Nullable
@@ -100,4 +100,11 @@ public final class ParsedVibration {
public int hashCode() {
return Objects.hashCode(mEffects);
}
+
+ @Override
+ public String toString() {
+ return "ParsedVibration{"
+ + "effects=" + mEffects
+ + '}';
+ }
}
diff --git a/core/java/android/os/vibrator/persistence/VibrationXmlParser.java b/core/java/android/os/vibrator/persistence/VibrationXmlParser.java
index e2312e0c96c4..7d9624c25c12 100644
--- a/core/java/android/os/vibrator/persistence/VibrationXmlParser.java
+++ b/core/java/android/os/vibrator/persistence/VibrationXmlParser.java
@@ -121,7 +121,6 @@ import java.util.List;
*
* @hide
*/
-@TestApi // This was used in CTS before the flag was introduced.
@SystemApi
@FlaggedApi(FLAG_VIBRATION_XML_APIS)
public final class VibrationXmlParser {
@@ -195,7 +194,6 @@ public final class VibrationXmlParser {
*
* @hide
*/
- @TestApi // Replacing test APIs used in CTS before the flagged system APIs was introduced.
@SystemApi
@FlaggedApi(FLAG_VIBRATION_XML_APIS)
@NonNull
@@ -217,7 +215,6 @@ public final class VibrationXmlParser {
*
* @hide
*/
- @TestApi // Replacing test APIs used in CTS before the flagged system APIs was introduced.
@SystemApi
@FlaggedApi(FLAG_VIBRATION_XML_APIS)
@NonNull
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index e029e520f1b1..5ef597d7104a 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -213,3 +213,11 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "location_bypass_privacy_dashboard_enabled"
+ is_exported: true
+ namespace: "permissions"
+ description: "Show access entry of location bypass permission in the Privacy Dashboard"
+ bug: "325536053"
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 94c769293bff..2562c8e31095 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6178,6 +6178,15 @@ public final class Settings {
public static final String POINTER_FILL_STYLE = "pointer_fill_style";
/**
+ * Pointer stroke style, specified by
+ * {@link android.view.PointerIcon.PointerIconVectorStyleStroke} constants.
+ *
+ * @hide
+ */
+ @Readable
+ public static final String POINTER_STROKE_STYLE = "pointer_stroke_style";
+
+ /**
* Whether lock-to-app will be triggered by long-press on recents.
* @hide
*/
@@ -6380,6 +6389,7 @@ public final class Settings {
PRIVATE_SETTINGS.add(SIP_ASK_ME_EACH_TIME);
PRIVATE_SETTINGS.add(POINTER_SPEED);
PRIVATE_SETTINGS.add(POINTER_FILL_STYLE);
+ PRIVATE_SETTINGS.add(POINTER_STROKE_STYLE);
PRIVATE_SETTINGS.add(POINTER_SCALE);
PRIVATE_SETTINGS.add(LOCK_TO_APP_ENABLED);
PRIVATE_SETTINGS.add(EGG_MODE);
@@ -12314,6 +12324,18 @@ public final class Settings {
"accessibility_force_invert_color_enabled";
/**
+ * Whether to enable mouse keys for Physical Keyboard accessibility.
+ *
+ * If set to true, key presses (of the mouse keys) on
+ * physical keyboard will control mouse pointer on the display.
+ *
+ * @hide
+ */
+ @Readable
+ public static final String ACCESSIBILITY_MOUSE_KEYS_ENABLED =
+ "accessibility_mouse_keys_enabled";
+
+ /**
* Whether the Adaptive connectivity option is enabled.
*
* @hide
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 3954bc2318cb..f6f0eff918e3 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -92,3 +92,10 @@ flag {
description: "Add a dump capability for attestation_verification service"
bug: "335498868"
}
+
+flag {
+ name: "should_trust_manager_listen_for_primary_auth"
+ namespace: "biometrics"
+ description: "Causes TrustManagerService to listen for credential attempts and ignore reports from upstream"
+ bug: "323086607"
+}
diff --git a/core/java/android/service/chooser/flags.aconfig b/core/java/android/service/chooser/flags.aconfig
index 82c16138f967..1f1a35117f72 100644
--- a/core/java/android/service/chooser/flags.aconfig
+++ b/core/java/android/service/chooser/flags.aconfig
@@ -2,14 +2,6 @@ package: "android.service.chooser"
container: "system"
flag {
- name: "enable_sharesheet_metadata_extra"
- is_exported: true
- namespace: "intentresolver"
- description: "This flag enables sharesheet metadata to be displayed to users."
- bug: "318942069"
-}
-
-flag {
name: "chooser_payload_toggling"
is_exported: true
namespace: "intentresolver"
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 2948129ae956..6b0d301c3baf 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -1405,7 +1405,8 @@ public class DreamService extends Service implements Window.Callback {
convertToComponentName(
rawMetadata.getString(
com.android.internal.R.styleable.Dream_settingsActivity),
- serviceInfo),
+ serviceInfo,
+ packageManager),
rawMetadata.getDrawable(
com.android.internal.R.styleable.Dream_previewImage),
rawMetadata.getBoolean(R.styleable.Dream_showClockAndComplications,
@@ -1420,26 +1421,38 @@ public class DreamService extends Service implements Window.Callback {
}
@Nullable
- private static ComponentName convertToComponentName(@Nullable String flattenedString,
- ServiceInfo serviceInfo) {
+ private static ComponentName convertToComponentName(
+ @Nullable String flattenedString,
+ ServiceInfo serviceInfo,
+ PackageManager packageManager) {
if (flattenedString == null) {
return null;
}
- if (!flattenedString.contains("/")) {
- return new ComponentName(serviceInfo.packageName, flattenedString);
+ final ComponentName cn =
+ flattenedString.contains("/")
+ ? ComponentName.unflattenFromString(flattenedString)
+ : new ComponentName(serviceInfo.packageName, flattenedString);
+
+ if (cn == null) {
+ return null;
}
// Ensure that the component is from the same package as the dream service. If not,
// treat the component as invalid and return null instead.
- final ComponentName cn = ComponentName.unflattenFromString(flattenedString);
- if (cn == null) return null;
if (!cn.getPackageName().equals(serviceInfo.packageName)) {
Log.w(TAG,
"Inconsistent package name in component: " + cn.getPackageName()
+ ", should be: " + serviceInfo.packageName);
return null;
}
+
+ // Ensure that the activity exists. If not, treat the component as invalid and return null.
+ if (new Intent().setComponent(cn).resolveActivityInfo(packageManager, 0) == null) {
+ Log.w(TAG, "Dream settings activity not found: " + cn);
+ return null;
+ }
+
return cn;
}
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 264b53c6ee40..146c2b6fa46e 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -176,7 +176,11 @@ public class StatusBarNotification implements Parcelable {
private String groupKey() {
if (overrideGroupKey != null) {
- return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey;
+ if (Flags.notificationForceGrouping()) {
+ return overrideGroupKey;
+ } else {
+ return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey;
+ }
}
final String group = getNotification().getGroup();
final String sortKey = getNotification().getSortKey();
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 863a99adacca..e16a6a1197ae 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -2941,7 +2941,7 @@ public class ZenModeConfig implements Parcelable {
long latestEndTime = -1;
// DND turned on by manual rule
- if (config.manualRule != null) {
+ if (config.isManualActive()) {
final Uri id = config.manualRule.conditionId;
if (config.manualRule.enabler != null) {
// app triggered manual rule
@@ -2950,7 +2950,7 @@ public class ZenModeConfig implements Parcelable {
secondaryText = appName;
}
} else {
- if (id == null) {
+ if (id == null || Uri.EMPTY.equals(id)) {
// Do not disturb manually triggered to remain on forever until turned off
if (describeForeverCondition) {
return context.getString(R.string.zen_mode_forever);
diff --git a/core/java/android/service/notification/flags.aconfig b/core/java/android/service/notification/flags.aconfig
index bdef04164b36..51961a85d307 100644
--- a/core/java/android/service/notification/flags.aconfig
+++ b/core/java/android/service/notification/flags.aconfig
@@ -43,4 +43,18 @@ flag {
namespace: "systemui"
description: "Allows the NAS to classify notifications"
bug: "343988084"
+}
+
+flag {
+ name: "notification_force_grouping"
+ namespace: "systemui"
+ description: "This flag controls the forced auto-grouping feature"
+ bug: "336488844"
+}
+
+flag {
+ name: "notification_silent_flag"
+ namespace: "systemui"
+ description: "Guards the new FLAG_SILENT Notification flag"
+ bug: "336488844"
} \ No newline at end of file
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 3161ff1e4c00..46b222baecd1 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -16,7 +16,6 @@
package android.service.wallpaper;
-import static android.app.WallpaperManager.COMMAND_DISPLAY_SWITCH;
import static android.app.WallpaperManager.COMMAND_FREEZE;
import static android.app.WallpaperManager.COMMAND_UNFREEZE;
import static android.app.WallpaperManager.SetWallpaperFlags;
@@ -161,7 +160,6 @@ public abstract class WallpaperService extends Service {
static final boolean DEBUG = false;
static final float MIN_PAGE_ALLOWED_MARGIN = .05f;
private static final int MIN_BITMAP_SCREENSHOT_WIDTH = 64;
- private static final long PRESERVE_VISIBLE_TIMEOUT_MS = 1000;
private static final long DEFAULT_UPDATE_SCREENSHOT_DURATION = 60 * 1000; //Once per minute
private static final @NonNull RectF LOCAL_COLOR_BOUNDS =
new RectF(0, 0, 1, 1);
@@ -174,7 +172,6 @@ public abstract class WallpaperService extends Service {
private static final int MSG_UPDATE_SURFACE = 10000;
private static final int MSG_VISIBILITY_CHANGED = 10010;
- private static final int MSG_REFRESH_VISIBILITY = 10011;
private static final int MSG_WALLPAPER_OFFSETS = 10020;
private static final int MSG_WALLPAPER_COMMAND = 10025;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -258,11 +255,6 @@ public abstract class WallpaperService extends Service {
*/
private boolean mIsScreenTurningOn;
boolean mReportedVisible;
- /**
- * This is used with {@link #PRESERVE_VISIBLE_TIMEOUT_MS} to avoid intermediate visibility
- * changes if the display may be toggled in a short time, e.g. display switch.
- */
- boolean mPreserveVisible;
boolean mDestroyed;
// Set to true after receiving WallpaperManager#COMMAND_FREEZE. It's reset back to false
// after receiving WallpaperManager#COMMAND_UNFREEZE. COMMAND_FREEZE is fully applied once
@@ -1107,9 +1099,6 @@ public abstract class WallpaperService extends Service {
if (pendingCount != 0) {
out.print(prefix); out.print("mPendingResizeCount="); out.println(pendingCount);
}
- if (mPreserveVisible) {
- out.print(prefix); out.print("mPreserveVisible=true");
- }
synchronized (mLock) {
out.print(prefix); out.print("mPendingXOffset="); out.print(mPendingXOffset);
out.print(" mPendingXOffset="); out.println(mPendingXOffset);
@@ -1672,8 +1661,7 @@ public abstract class WallpaperService extends Service {
? false
: mIWallpaperEngine.mInfo.supportsAmbientMode();
// Report visibility only if display is fully on or wallpaper supports ambient mode.
- final boolean visible = (mVisible && (displayFullyOn || supportsAmbientMode))
- || mPreserveVisible;
+ final boolean visible = mVisible && (displayFullyOn || supportsAmbientMode);
if (DEBUG) {
Log.v(
TAG,
@@ -2110,9 +2098,6 @@ public abstract class WallpaperService extends Service {
if (!mDestroyed) {
if (COMMAND_FREEZE.equals(cmd.action) || COMMAND_UNFREEZE.equals(cmd.action)) {
updateFrozenState(/* frozenRequested= */ !COMMAND_UNFREEZE.equals(cmd.action));
- } else if (COMMAND_DISPLAY_SWITCH.equals(cmd.action)) {
- handleDisplaySwitch(cmd.z == 1 /* startToSwitch */);
- return;
}
result = onCommand(cmd.action, cmd.x, cmd.y, cmd.z,
cmd.extras, cmd.sync);
@@ -2128,23 +2113,6 @@ public abstract class WallpaperService extends Service {
}
}
- private void handleDisplaySwitch(boolean startToSwitch) {
- if (startToSwitch && mReportedVisible) {
- // The display may be off/on in a short time when the display is switching.
- // Keep the visible state until onScreenTurnedOn or !startToSwitch is received, so
- // the rendering thread can be active to redraw in time when receiving size change.
- mPreserveVisible = true;
- mCaller.removeMessages(MSG_REFRESH_VISIBILITY);
- mCaller.sendMessageDelayed(mCaller.obtainMessage(MSG_REFRESH_VISIBILITY),
- PRESERVE_VISIBLE_TIMEOUT_MS);
- } else if (!startToSwitch && mPreserveVisible) {
- // The switch is finished, so restore to actual visibility.
- mPreserveVisible = false;
- mCaller.removeMessages(MSG_REFRESH_VISIBILITY);
- reportVisibility(false /* forceReport */);
- }
- }
-
private void updateFrozenState(boolean frozenRequested) {
if (mIWallpaperEngine.mInfo == null
// Procees the unfreeze command in case the wallaper became static while
@@ -2691,10 +2659,6 @@ public abstract class WallpaperService extends Service {
+ ": " + message.arg1);
mEngine.doVisibilityChanged(message.arg1 != 0);
break;
- case MSG_REFRESH_VISIBILITY:
- mEngine.mPreserveVisible = false;
- mEngine.reportVisibility(false /* forceReport */);
- break;
case MSG_UPDATE_SCREEN_TURNING_ON:
if (DEBUG) {
Log.v(TAG,
diff --git a/core/java/android/tracing/flags.aconfig b/core/java/android/tracing/flags.aconfig
index be60c2504f38..04dba462bc1f 100644
--- a/core/java/android/tracing/flags.aconfig
+++ b/core/java/android/tracing/flags.aconfig
@@ -46,3 +46,11 @@ flag {
is_fixed_read_only: true
bug: "323165543"
}
+
+flag {
+ name: "client_side_proto_logging"
+ namespace: "windowing_tools"
+ description: "Add support for client side protologging"
+ is_fixed_read_only: true
+ bug: "352538294"
+}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 0714285c43f6..d8a88b83df99 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -138,12 +138,6 @@ public class FeatureFlagUtils {
"settings_show_stylus_preferences";
/**
- * Flag to enable/disable biometrics enrollment v2
- * @hide
- */
- public static final String SETTINGS_BIOMETRICS2_ENROLLMENT = "settings_biometrics2_enrollment";
-
- /**
* Flag to enable/disable FingerprintSettings v2
* @hide
*/
@@ -223,7 +217,6 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put(SETTINGS_ENABLE_SPA_METRICS, "true");
DEFAULT_FLAGS.put(SETTINGS_ADB_METRICS_WRITER, "false");
DEFAULT_FLAGS.put(SETTINGS_SHOW_STYLUS_PREFERENCES, "true");
- DEFAULT_FLAGS.put(SETTINGS_BIOMETRICS2_ENROLLMENT, "false");
DEFAULT_FLAGS.put(SETTINGS_PREFER_ACCESSIBILITY_MENU_IN_SYSTEM, "false");
DEFAULT_FLAGS.put(SETTINGS_AUDIO_ROUTING, "false");
DEFAULT_FLAGS.put(SETTINGS_FLASH_NOTIFICATIONS, "true");
diff --git a/core/java/android/util/SequenceUtils.java b/core/java/android/util/SequenceUtils.java
index f833ce314c91..4f8db0fb260b 100644
--- a/core/java/android/util/SequenceUtils.java
+++ b/core/java/android/util/SequenceUtils.java
@@ -25,8 +25,8 @@ package android.util;
* {@link #getInitSeq}.
* 2. Whenever a newer info needs to be sent to the client side, the system server should first
* update its seq with {@link #getNextSeq}, then send the new info with the new seq to the client.
- * 3. On the client side, when receiving a new info, it should only consume it if it is newer than
- * the last received info seq by checking {@link #isIncomingSeqNewer}.
+ * 3. On the client side, when receiving a new info, it should only consume it if it is not stale by
+ * checking {@link #isIncomingSeqStale}.
*
* @hide
*/
@@ -36,15 +36,22 @@ public final class SequenceUtils {
}
/**
- * Returns {@code true} if the incomingSeq is newer than the curSeq.
+ * Returns {@code true} if the incomingSeq is stale, which means the client should not consume
+ * it.
*/
- public static boolean isIncomingSeqNewer(int curSeq, int incomingSeq) {
+ public static boolean isIncomingSeqStale(int curSeq, int incomingSeq) {
+ if (curSeq == getInitSeq()) {
+ // curSeq can be set to the initial seq in the following cases:
+ // 1. The client process/field is newly created/recreated.
+ // 2. The field is not managed by the system server, such as WindowlessWindowManager.
+ // The client should always consume the incoming in these cases.
+ return false;
+ }
// Convert to long for comparison.
final long diff = (long) incomingSeq - curSeq;
- // If there has been a sufficiently large jump, assume the sequence has wrapped around.
- // For example, when the last seq is MAX_VALUE, the incoming seq will be MIN_VALUE + 1.
- // diff = MIN_VALUE + 1 - MAX_VALUE. It is smaller than 0, but should be treated as newer.
- return diff > 0 || diff < Integer.MIN_VALUE;
+ // When diff is 0, allow client to consume.
+ // When there has been a sufficiently large jump, assume the sequence has wrapped around.
+ return (diff < 0 && diff > Integer.MIN_VALUE) || diff > Integer.MAX_VALUE;
}
/** Returns the initial seq. */
diff --git a/core/java/android/util/StateSet.java b/core/java/android/util/StateSet.java
index 16d6082649a7..17adb32fb846 100644
--- a/core/java/android/util/StateSet.java
+++ b/core/java/android/util/StateSet.java
@@ -288,6 +288,9 @@ public class StateSet {
case R.attr.state_activated:
sb.append("A ");
break;
+ case R.attr.state_hovered:
+ sb.append("H ");
+ break;
}
}
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 8b9d876f6bf1..12dbc5afd0a3 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -24,6 +24,7 @@ import static android.view.DisplayInfoProto.FLAGS;
import static android.view.DisplayInfoProto.LOGICAL_HEIGHT;
import static android.view.DisplayInfoProto.LOGICAL_WIDTH;
import static android.view.DisplayInfoProto.NAME;
+import static android.view.DisplayInfoProto.TYPE;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -961,6 +962,7 @@ public final class DisplayInfo implements Parcelable {
protoOutputStream.write(APP_HEIGHT, appHeight);
protoOutputStream.write(NAME, name);
protoOutputStream.write(FLAGS, flags);
+ protoOutputStream.write(TYPE, type);
if (displayCutout != null) {
displayCutout.dumpDebug(protoOutputStream, CUTOUT);
}
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
index 69228cafa34b..1fe06d474803 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -16,11 +16,30 @@
package android.view;
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Constants to be used to perform haptic feedback effects via
* {@link View#performHapticFeedback(int)}
*/
public class HapticFeedbackConstants {
+ /** @hide **/
+ @IntDef(flag = true, prefix = "FLAG_", value = {
+ FLAG_IGNORE_VIEW_SETTING,
+ FLAG_IGNORE_GLOBAL_SETTING,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Flags {}
+
+ /** @hide **/
+ @IntDef(flag = true, prefix = "PRIVATE_FLAG_", value = {
+ PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PrivateFlags {}
private HapticFeedbackConstants() {}
@@ -258,4 +277,14 @@ public class HapticFeedbackConstants {
*/
@Deprecated
public static final int FLAG_IGNORE_GLOBAL_SETTING = 0x0002;
+
+ /**
+ * Flag for {@link android.os.Vibrator#performHapticFeedback(int, boolean, String, int, int)} or
+ * {@link ViewRootImpl#performHapticFeedback(int, boolean, int, int)}: Perform the haptic
+ * feedback with the input method vibration settings, e.g. applying the keyboard vibration
+ * user settings to the KEYBOARD_* constants.
+ *
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS = 0x0001;
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index cb5a885bd0a0..e5be53191e9e 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -53,6 +53,7 @@ import android.view.IWallpaperVisibilityListener;
import android.view.IWindow;
import android.view.IWindowSession;
import android.view.IWindowSessionCallback;
+import android.view.KeyboardShortcutGroup;
import android.view.KeyEvent;
import android.view.InputEvent;
import android.view.InsetsState;
@@ -1095,4 +1096,11 @@ interface IWindowManager
boolean transferTouchGesture(in InputTransferToken transferFromToken,
in InputTransferToken transferToToken);
+
+ /**
+ * Request the application launch keyboard shortcuts the system has defined.
+ *
+ * @param deviceId The id of the {@link InputDevice} that will handle the shortcut.
+ */
+ KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId);
}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 070d33bb9be6..14407ca32388 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -140,13 +140,13 @@ interface IWindowSession {
int seqId);
@UnsupportedAppUsage
- boolean performHapticFeedback(int effectId, boolean always, boolean fromIme);
+ boolean performHapticFeedback(int effectId, int flags, int privFlags);
/**
* Called by attached views to perform predefined haptic feedback without requiring VIBRATE
* permission.
*/
- oneway void performHapticFeedbackAsync(int effectId, boolean always, boolean fromIme);
+ oneway void performHapticFeedbackAsync(int effectId, int flags, int privFlags);
/**
* Initiate the drag operation itself
diff --git a/core/java/android/view/InputMonitor.java b/core/java/android/view/InputMonitor.java
index 2302dc7bd8c8..ea4abc1b8bc6 100644
--- a/core/java/android/view/InputMonitor.java
+++ b/core/java/android/view/InputMonitor.java
@@ -50,13 +50,12 @@ public final class InputMonitor implements Parcelable {
private final SurfaceControl mSurface;
/**
- * Takes all of the current pointer events streams that are currently being sent to this
- * monitor and generates appropriate cancellations for the windows that would normally get
- * them.
+ * Pilfer pointers from this input monitor.
*
- * This method should be used with caution as unexpected pilfering can break fundamental user
- * interactions.
+ * @see android.hardware.input.InputManager#pilferPointers(IBinder)
+ * @deprecated
*/
+ @Deprecated
public void pilferPointers() {
try {
mHost.pilferPointers();
@@ -197,10 +196,10 @@ public final class InputMonitor implements Parcelable {
};
@DataClass.Generated(
- time = 1679692514588L,
+ time = 1720819824835L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/view/InputMonitor.java",
- inputSignatures = "private static final java.lang.String TAG\nprivate static final boolean DEBUG\nprivate final @android.annotation.NonNull android.view.InputChannel mInputChannel\nprivate final @android.annotation.NonNull android.view.IInputMonitorHost mHost\nprivate final @android.annotation.NonNull android.view.SurfaceControl mSurface\npublic void pilferPointers()\npublic void dispose()\nclass InputMonitor extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true)")
+ inputSignatures = "private static final java.lang.String TAG\nprivate static final boolean DEBUG\nprivate final @android.annotation.NonNull android.view.InputChannel mInputChannel\nprivate final @android.annotation.NonNull android.view.IInputMonitorHost mHost\nprivate final @android.annotation.NonNull android.view.SurfaceControl mSurface\npublic @java.lang.Deprecated void pilferPointers()\npublic void dispose()\nclass InputMonitor extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/view/InsetsFrameProvider.java b/core/java/android/view/InsetsFrameProvider.java
index fe98faba98c3..075571cb2890 100644
--- a/core/java/android/view/InsetsFrameProvider.java
+++ b/core/java/android/view/InsetsFrameProvider.java
@@ -162,6 +162,12 @@ public class InsetsFrameProvider implements Parcelable {
return mSource;
}
+ /** Set the flags of this provider. */
+ public InsetsFrameProvider setFlags(@Flags int flags) {
+ mFlags = flags;
+ return this;
+ }
+
public InsetsFrameProvider setFlags(@Flags int flags, @Flags int mask) {
mFlags = (mFlags & ~mask) | (flags & mask);
return this;
diff --git a/core/java/android/view/KeyboardShortcutGroup.aidl b/core/java/android/view/KeyboardShortcutGroup.aidl
new file mode 100644
index 000000000000..6f219dbda7ef
--- /dev/null
+++ b/core/java/android/view/KeyboardShortcutGroup.aidl
@@ -0,0 +1,3 @@
+package android.view;
+
+@JavaOnlyStableParcelable parcelable KeyboardShortcutGroup;
diff --git a/core/java/android/view/KeyboardShortcutInfo.java b/core/java/android/view/KeyboardShortcutInfo.java
index 3f6fd646994c..3f49bf3380c1 100644
--- a/core/java/android/view/KeyboardShortcutInfo.java
+++ b/core/java/android/view/KeyboardShortcutInfo.java
@@ -81,12 +81,29 @@ public final class KeyboardShortcutInfo implements Parcelable {
* {@link KeyEvent#META_SYM_ON}.
*/
public KeyboardShortcutInfo(CharSequence label, char baseCharacter, int modifiers) {
+ this(label, null, baseCharacter, modifiers);
+ }
+
+ /**
+ * @param label The label that identifies the action performed by this shortcut.
+ * @param icon An icon that identifies the action performed by this shortcut.
+ * @param baseCharacter The character that triggers the shortcut.
+ * @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
+ * These should be a combination of {@link KeyEvent#META_CTRL_ON},
+ * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON},
+ * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_FUNCTION_ON} and
+ * {@link KeyEvent#META_SYM_ON}.
+ *
+ * @hide
+ */
+ public KeyboardShortcutInfo(
+ CharSequence label, @Nullable Icon icon, char baseCharacter, int modifiers) {
mLabel = label;
checkArgument(baseCharacter != MIN_VALUE);
mBaseCharacter = baseCharacter;
mKeycode = KeyEvent.KEYCODE_UNKNOWN;
mModifiers = modifiers;
- mIcon = null;
+ mIcon = icon;
}
private KeyboardShortcutInfo(Parcel source) {
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index c30212657c57..15351453a151 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -193,6 +193,25 @@ public final class PointerIcon implements Parcelable {
/** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_FILL_END =
POINTER_ICON_VECTOR_STYLE_FILL_BLUE;
+ /** @hide */
+ @IntDef(prefix = {"POINTER_ICON_VECTOR_STYLE_STROKE_"}, value = {
+ POINTER_ICON_VECTOR_STYLE_STROKE_WHITE,
+ POINTER_ICON_VECTOR_STYLE_STROKE_BLACK,
+ POINTER_ICON_VECTOR_STYLE_STROKE_NONE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PointerIconVectorStyleStroke {}
+
+ /** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_STROKE_WHITE = 0;
+ /** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_STROKE_BLACK = 1;
+ /** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_STROKE_NONE = 2;
+
+ // If adding PointerIconVectorStyleStroke, update END value for {@link SystemSettingsValidators}
+ /** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_STROKE_BEGIN =
+ POINTER_ICON_VECTOR_STYLE_STROKE_WHITE;
+ /** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_STROKE_END =
+ POINTER_ICON_VECTOR_STYLE_STROKE_NONE;
+
/** @hide */ public static final float DEFAULT_POINTER_SCALE = 1f;
/** @hide */ public static final float LARGE_POINTER_SCALE = 2.5f;
@@ -712,6 +731,23 @@ public final class PointerIcon implements Parcelable {
}
/**
+ * Convert stroke style constant to resource ID.
+ *
+ * @hide
+ */
+ public static int vectorStrokeStyleToResource(@PointerIconVectorStyleStroke int strokeStyle) {
+ return switch (strokeStyle) {
+ case POINTER_ICON_VECTOR_STYLE_STROKE_BLACK ->
+ com.android.internal.R.style.PointerIconVectorStyleStrokeBlack;
+ case POINTER_ICON_VECTOR_STYLE_STROKE_WHITE ->
+ com.android.internal.R.style.PointerIconVectorStyleStrokeWhite;
+ case POINTER_ICON_VECTOR_STYLE_STROKE_NONE ->
+ com.android.internal.R.style.PointerIconVectorStyleStrokeNone;
+ default -> com.android.internal.R.style.PointerIconVectorStyleStrokeWhite;
+ };
+ }
+
+ /**
* Sets whether drop shadow will draw in the native code.
*
* @hide
diff --git a/core/java/android/view/SurfaceControlRegistry.java b/core/java/android/view/SurfaceControlRegistry.java
index 117b200d054e..a806bd226c36 100644
--- a/core/java/android/view/SurfaceControlRegistry.java
+++ b/core/java/android/view/SurfaceControlRegistry.java
@@ -295,16 +295,7 @@ public class SurfaceControlRegistry {
}
sCallStackDebuggingInitialized = true;
- sCallStackDebuggingMatchCall =
- SystemProperties.get("persist.wm.debug.sc.tx.log_match_call", null)
- .toLowerCase();
- sCallStackDebuggingMatchName =
- SystemProperties.get("persist.wm.debug.sc.tx.log_match_name", null)
- .toLowerCase();
- sLogAllTxCallsOnApply = sCallStackDebuggingMatchCall.contains("apply");
- // Only enable stack debugging if any of the match filters are set
- sCallStackDebuggingEnabled = !sCallStackDebuggingMatchCall.isEmpty()
- || !sCallStackDebuggingMatchName.isEmpty();
+ updateCallStackDebuggingParams();
if (sCallStackDebuggingEnabled) {
Log.d(TAG, "Enabling transaction call stack debugging:"
+ " matchCall=" + sCallStackDebuggingMatchCall
@@ -325,6 +316,11 @@ public class SurfaceControlRegistry {
final void checkCallStackDebugging(@NonNull String call,
@Nullable SurfaceControl.Transaction tx, @Nullable SurfaceControl sc,
@Nullable String details) {
+
+ if (sCallStackDebuggingInitialized && sCallStackDebuggingEnabled) {
+ updateCallStackDebuggingParams();
+ }
+
if (!sCallStackDebuggingEnabled) {
return;
}
@@ -356,6 +352,22 @@ public class SurfaceControlRegistry {
}
/**
+ * Updates the call stack debugging params from the system properties.
+ */
+ private static void updateCallStackDebuggingParams() {
+ sCallStackDebuggingMatchCall =
+ SystemProperties.get("persist.wm.debug.sc.tx.log_match_call", null)
+ .toLowerCase();
+ sCallStackDebuggingMatchName =
+ SystemProperties.get("persist.wm.debug.sc.tx.log_match_name", null)
+ .toLowerCase();
+ sLogAllTxCallsOnApply = sCallStackDebuggingMatchCall.contains("apply");
+ // Only enable stack debugging if any of the match filters are set
+ sCallStackDebuggingEnabled = !sCallStackDebuggingMatchCall.isEmpty()
+ || !sCallStackDebuggingMatchName.isEmpty();
+ }
+
+ /**
* Tests whether the given surface control name/method call matches the filters set for the
* call stack debugging.
*/
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 766e02bf3198..2edbcc2592cc 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -22,6 +22,7 @@ import static android.os.Trace.TRACE_TAG_VIEW;
import static android.service.autofill.Flags.FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION;
import static android.view.ContentInfo.SOURCE_DRAG_AND_DROP;
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
+import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT;
import static android.view.Surface.FRAME_RATE_CATEGORY_LOW;
import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
@@ -5512,6 +5513,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public static final int DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG = 1 << 13;
/**
+ * Flag indicating that this drag will result in the caller activity's task to be hidden for the
+ * duration of the drag, this means that the source activity will not receive drag events for
+ * the current drag gesture. Only the current voice interaction service may use this flag.
+ * @hide
+ */
+ public static final int DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START = 1 << 14;
+
+ /**
* Vertical scroll factor cached by {@link #getVerticalScrollFactor}.
*/
private float mVerticalScrollFactor;
@@ -13859,11 +13868,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
})
@ResolvedLayoutDir
public int getLayoutDirection() {
- final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
- if (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR1) {
- mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
- return LAYOUT_DIRECTION_RESOLVED_DEFAULT;
- }
return ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ==
PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR;
}
@@ -19635,7 +19639,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public final void setLeft(int left) {
if (left != mLeft) {
- mPrivateFlags4 |= PFLAG4_HAS_MOVED;
final boolean matrixIsIdentity = hasIdentityMatrix();
if (matrixIsIdentity) {
if (mAttachInfo != null) {
@@ -25589,6 +25592,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
? FRAME_RATE_CATEGORY_NORMAL : FRAME_RATE_CATEGORY_HIGH;
mSizeBasedFrameRateCategoryAndReason = category | FRAME_RATE_CATEGORY_REASON_LARGE;
}
+ mPrivateFlags4 |= PFLAG4_HAS_MOVED;
}
onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
@@ -28632,20 +28636,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return false;
}
- final boolean always = (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0;
- boolean fromIme = false;
- if (mAttachInfo.mViewRootImpl != null) {
- fromIme = mAttachInfo.mViewRootImpl.mWindowAttributes.type == TYPE_INPUT_METHOD;
+ int privFlags = 0;
+ if (mAttachInfo.mViewRootImpl != null
+ && mAttachInfo.mViewRootImpl.mWindowAttributes.type == TYPE_INPUT_METHOD) {
+ privFlags = HapticFeedbackConstants.PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS;
}
if (Flags.useVibratorHapticFeedback()) {
if (!mAttachInfo.canPerformHapticFeedback()) {
return false;
}
- getSystemVibrator().performHapticFeedback(
- feedbackConstant, always, "View#performHapticFeedback", fromIme);
+ getSystemVibrator().performHapticFeedback(feedbackConstant,
+ "View#performHapticFeedback", flags, privFlags);
return true;
}
- return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant, always, fromIme);
+ return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant, flags, privFlags);
}
private Vibrator getSystemVibrator() {
@@ -31680,7 +31684,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
interface Callbacks {
void playSoundEffect(int effectId);
- boolean performHapticFeedback(int effectId, boolean always, boolean fromIme);
+
+ boolean performHapticFeedback(int effectId,
+ @HapticFeedbackConstants.Flags int flags,
+ @HapticFeedbackConstants.PrivateFlags int privFlags);
}
/**
@@ -33902,8 +33909,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
protected int calculateFrameRateCategory() {
+ ViewRootImpl viewRootImpl = getViewRootImpl();
+ ViewParent parent = mParent;
+ boolean isInputMethodWindowType =
+ viewRootImpl.mWindowAttributes.type == TYPE_INPUT_METHOD;
+
+ // boost frame rate when the position or the size changed.
+ if (((mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
+ PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN) || mLastFrameLeft != mLeft
+ || mLastFrameTop != mTop)
+ && viewRootImpl.shouldCheckFrameRateCategory()
+ && parent instanceof View
+ && ((View) parent).mFrameContentVelocity <= 0
+ && !isInputMethodWindowType) {
+
+ return FRAME_RATE_CATEGORY_HIGH_HINT | FRAME_RATE_CATEGORY_REASON_BOOST;
+ }
int category;
- switch (getViewRootImpl().intermittentUpdateState()) {
+ switch (viewRootImpl.intermittentUpdateState()) {
case ViewRootImpl.INTERMITTENT_STATE_INTERMITTENT -> {
if (!sToolkitFrameRateBySizeReadOnlyFlagValue) {
category = FRAME_RATE_CATEGORY_NORMAL;
@@ -33937,66 +33960,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
float velocity = mFrameContentVelocity;
final float frameRate = mPreferredFrameRate;
- ViewParent parent = mParent;
- boolean isInputMethodWindowType = false;
- if (mAttachInfo != null && mAttachInfo.mViewRootImpl != null) {
- isInputMethodWindowType =
- mAttachInfo.mViewRootImpl.mWindowAttributes.type == TYPE_INPUT_METHOD;
- }
- if (velocity <= 0 && Float.isNaN(frameRate)) {
- // The most common case is when nothing is set, so this special case is called
- // often.
- if (mAttachInfo.mViewVelocityApi
- && ((mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
- PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN) || mLastFrameLeft != mLeft
- || mLastFrameTop != mTop)
- && viewRootImpl.shouldCheckFrameRate(false)
- && parent instanceof View
- && ((View) parent).mFrameContentVelocity <= 0
- && !isInputMethodWindowType) {
- viewRootImpl.votePreferredFrameRate(MAX_FRAME_RATE, FRAME_RATE_COMPATIBILITY_GTE);
- }
- if (viewRootImpl.shouldCheckFrameRateCategory()) {
- int frameRateCategory = calculateFrameRateCategory();
- int category = frameRateCategory & ~FRAME_RATE_CATEGORY_REASON_MASK;
- int reason = frameRateCategory & FRAME_RATE_CATEGORY_REASON_MASK;
- viewRootImpl.votePreferredFrameRateCategory(category, reason, this);
- mLastFrameRateCategory = frameRateCategory;
- }
- mLastFrameLeft = mLeft;
- mLastFrameTop = mTop;
- return;
- }
- if (viewRootImpl.shouldCheckFrameRate(frameRate > 0f)) {
+
+ if (viewRootImpl.shouldCheckFrameRate(frameRate > 0f)
+ && (frameRate > 0 || (mAttachInfo.mViewVelocityApi && velocity > 0f))) {
float velocityFrameRate = 0f;
- if (mAttachInfo.mViewVelocityApi) {
- if (velocity < 0f
- && ((mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
- PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN) || mLastFrameLeft != mLeft
- || mLastFrameTop != mTop)
- && mParent instanceof View
- && ((View) mParent).mFrameContentVelocity <= 0
- && !isInputMethodWindowType
- ) {
- // This current calculation is very simple. If something on the screen
- // moved, then it votes for the highest velocity.
- velocityFrameRate = MAX_FRAME_RATE;
- } else if (velocity > 0f) {
- velocityFrameRate = convertVelocityToFrameRate(velocity);
- }
- }
- if (velocityFrameRate > 0f || frameRate > 0f) {
- int compatibility;
- float frameRateToSet;
- if (frameRate >= velocityFrameRate) {
- compatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
- frameRateToSet = frameRate;
- } else {
- compatibility = FRAME_RATE_COMPATIBILITY_GTE;
- frameRateToSet = velocityFrameRate;
- }
- viewRootImpl.votePreferredFrameRate(frameRateToSet, compatibility);
+ if (mAttachInfo.mViewVelocityApi && velocity > 0f) {
+ velocityFrameRate = convertVelocityToFrameRate(velocity);
+ }
+ int compatibility;
+ float frameRateToSet;
+ if (frameRate >= velocityFrameRate) {
+ compatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
+ frameRateToSet = frameRate;
+ } else {
+ compatibility = FRAME_RATE_COMPATIBILITY_GTE;
+ frameRateToSet = velocityFrameRate;
}
+ viewRootImpl.votePreferredFrameRate(frameRateToSet, compatibility);
}
if (viewRootImpl.shouldCheckFrameRateCategory()) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1525bd1d4af7..596726f83c15 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -23,7 +23,7 @@ import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUN
import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID;
import static android.os.Trace.TRACE_TAG_VIEW;
import static android.util.SequenceUtils.getInitSeq;
-import static android.util.SequenceUtils.isIncomingSeqNewer;
+import static android.util.SequenceUtils.isIncomingSeqStale;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.DragEvent.ACTION_DRAG_LOCATION;
@@ -128,8 +128,8 @@ import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodCl
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.text.flags.Flags.disableHandwritingInitiatorForIme;
-import static com.android.window.flags.Flags.activityWindowInfoFlag;
import static com.android.window.flags.Flags.enableBufferTransformHintFromDisplay;
+import static com.android.window.flags.Flags.enableCaptionCompatInsetForceConsumption;
import static com.android.window.flags.Flags.insetsControlChangedItem;
import static com.android.window.flags.Flags.insetsControlSeq;
import static com.android.window.flags.Flags.setScPropertiesInClient;
@@ -1207,6 +1207,8 @@ public final class ViewRootImpl implements ViewParent,
private final Rect mChildBoundingInsets = new Rect();
private boolean mChildBoundingInsetsChanged = false;
+ private final boolean mDisableDrawWakeLock;
+
private String mTag = TAG;
private String mFpsTraceName;
private String mLargestViewTraceName;
@@ -1336,6 +1338,10 @@ public final class ViewRootImpl implements ViewParent,
}
mAppStartInfoTimestampsFlagValue = android.app.Flags.appStartInfoTimestamps();
+
+ // Disable DRAW_WAKE_LOCK starting U.
+ mDisableDrawWakeLock =
+ CompatChanges.isChangeEnabled(DISABLE_DRAW_WAKE_LOCK) && disableDrawWakeLock();
}
public static void addFirstDrawHandler(Runnable callback) {
@@ -1367,9 +1373,6 @@ public final class ViewRootImpl implements ViewParent,
*/
public void setActivityConfigCallback(@Nullable ActivityConfigCallback callback) {
mActivityConfigCallback = callback;
- if (!activityWindowInfoFlag()) {
- return;
- }
if (callback == null) {
mPendingActivityWindowInfo = null;
mLastReportedActivityWindowInfo = null;
@@ -2329,23 +2332,23 @@ public final class ViewRootImpl implements ViewParent,
if (mLastReportedFrames == null) {
return;
}
- if (isIncomingSeqNewer(mLastReportedFrames.seq, inOutFrames.seq)) {
+ if (isIncomingSeqStale(mLastReportedFrames.seq, inOutFrames.seq)) {
+ // If the incoming is stale, use the last reported instead.
+ inOutFrames.setTo(mLastReportedFrames);
+ } else {
// Keep track of the latest.
mLastReportedFrames.setTo(inOutFrames);
- } else {
- // If the last reported frames is newer, use the last reported instead.
- inOutFrames.setTo(mLastReportedFrames);
}
}
private void onInsetsStateChanged(@NonNull InsetsState insetsState) {
if (insetsControlSeq()) {
- if (isIncomingSeqNewer(mLastReportedInsetsStateSeq, insetsState.getSeq())) {
- mLastReportedInsetsStateSeq = insetsState.getSeq();
- } else {
- // The last reported InsetsState is newer. Skip.
+ if (isIncomingSeqStale(mLastReportedInsetsStateSeq, insetsState.getSeq())) {
+ // The incoming is stale. Skip.
return;
}
+ // Keep track of the latest.
+ mLastReportedInsetsStateSeq = insetsState.getSeq();
}
if (mTranslator != null) {
@@ -2362,13 +2365,13 @@ public final class ViewRootImpl implements ViewParent,
}
if (insetsControlSeq()) {
- if (isIncomingSeqNewer(mLastReportedActiveControlsSeq, activeControls.getSeq())) {
- mLastReportedActiveControlsSeq = activeControls.getSeq();
- } else {
- // The last reported controls is newer. Skip.
+ if (isIncomingSeqStale(mLastReportedActiveControlsSeq, activeControls.getSeq())) {
+ // The incoming is stale. Skip.
activeControls.release();
return;
}
+ // Keep track of the latest.
+ mLastReportedActiveControlsSeq = activeControls.getSeq();
}
final InsetsSourceControl[] controls = activeControls.get();
@@ -2472,12 +2475,10 @@ public final class ViewRootImpl implements ViewParent,
void pokeDrawLockIfNeeded() {
// Disable DRAW_WAKE_LOCK starting U. Otherwise, only need to acquire it for DOZE state.
- if (CompatChanges.isChangeEnabled(DISABLE_DRAW_WAKE_LOCK) && disableDrawWakeLock()) {
- return;
- }
-
- if (!Display.isDozeState(mAttachInfo.mDisplayState)) {
- // Only need to acquire wake lock for DOZE state.
+ if (mDisableDrawWakeLock || mAttachInfo.mDisplayState != Display.STATE_DOZE) {
+ // In DOZE_SUSPEND, Android shouldn't control the display; therefore we only poke the
+ // draw wake lock when display state is DOZE. Noted that Display#isDozeState includes
+ // DOZE_SUSPEND as well, so, it's not feasible here.
return;
}
if (mWindowAttributes.type != WindowManager.LayoutParams.TYPE_BASE_APPLICATION) {
@@ -3185,7 +3186,9 @@ public final class ViewRootImpl implements ViewParent,
inOutParams.privateFlags &= ~PRIVATE_FLAG_FIT_INSETS_CONTROLLED;
}
- private void controlInsetsForCompatibility(WindowManager.LayoutParams params) {
+ /** Updates the {@link InsetsType}s to hide or show based on layout params. */
+ @VisibleForTesting
+ public void controlInsetsForCompatibility(WindowManager.LayoutParams params) {
final int sysUiVis = params.systemUiVisibility | params.subtreeSystemUiVisibility;
final int flags = params.flags;
final boolean matchParent = params.width == MATCH_PARENT && params.height == MATCH_PARENT;
@@ -3196,6 +3199,9 @@ public final class ViewRootImpl implements ViewParent,
|| ((flags & FLAG_FULLSCREEN) != 0 && matchParent && nonAttachedAppWindow);
final boolean navWasHiddenByFlags = (mTypesHiddenByFlags & Type.navigationBars()) != 0;
final boolean navIsHiddenByFlags = (sysUiVis & SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
+ final boolean captionWasHiddenByFlags = (mTypesHiddenByFlags & Type.captionBar()) != 0;
+ final boolean captionIsHiddenByFlags = (sysUiVis & SYSTEM_UI_FLAG_FULLSCREEN) != 0
+ || ((flags & FLAG_FULLSCREEN) != 0 && matchParent && nonAttachedAppWindow);
@InsetsType int typesToHide = 0;
@InsetsType int typesToShow = 0;
@@ -3209,6 +3215,13 @@ public final class ViewRootImpl implements ViewParent,
} else if (!navIsHiddenByFlags && navWasHiddenByFlags) {
typesToShow |= Type.navigationBars();
}
+ if (captionIsHiddenByFlags && !captionWasHiddenByFlags
+ && enableCaptionCompatInsetForceConsumption()) {
+ typesToHide |= Type.captionBar();
+ } else if (!captionIsHiddenByFlags && captionWasHiddenByFlags
+ && enableCaptionCompatInsetForceConsumption()) {
+ typesToShow |= Type.captionBar();
+ }
if (typesToHide != 0) {
getInsetsController().hide(typesToHide);
}
@@ -4420,6 +4433,8 @@ public final class ViewRootImpl implements ViewParent,
}
mFrameRateCategoryHighCount = mFrameRateCategoryHighCount > 0
? mFrameRateCategoryHighCount - 1 : mFrameRateCategoryHighCount;
+ mFrameRateCategoryHighHintCount = mFrameRateCategoryHighHintCount > 0
+ ? mFrameRateCategoryHighHintCount - 1 : mFrameRateCategoryHighHintCount;
mFrameRateCategoryNormalCount = mFrameRateCategoryNormalCount > 0
? mFrameRateCategoryNormalCount - 1 : mFrameRateCategoryNormalCount;
mFrameRateCategoryLowCount = mFrameRateCategoryLowCount > 0
@@ -9341,7 +9356,7 @@ public final class ViewRootImpl implements ViewParent,
onClientWindowFramesChanged(mTmpFrames);
- if (activityWindowInfoFlag() && mPendingActivityWindowInfo != null) {
+ if (mPendingActivityWindowInfo != null) {
final ActivityWindowInfo outInfo = mRelayoutResult.activityWindowInfo;
if (outInfo != null) {
mPendingActivityWindowInfo.set(outInfo);
@@ -9651,18 +9666,18 @@ public final class ViewRootImpl implements ViewParent,
* {@inheritDoc}
*/
@Override
- public boolean performHapticFeedback(int effectId, boolean always, boolean fromIme) {
+ public boolean performHapticFeedback(int effectId, int flags, int privFlags) {
if ((mDisplay.getFlags() & Display.FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
return false;
}
try {
if (USE_ASYNC_PERFORM_HAPTIC_FEEDBACK) {
- mWindowSession.performHapticFeedbackAsync(effectId, always, fromIme);
+ mWindowSession.performHapticFeedbackAsync(effectId, flags, privFlags);
return true;
} else {
// Original blocking binder call path.
- return mWindowSession.performHapticFeedback(effectId, always, fromIme);
+ return mWindowSession.performHapticFeedback(effectId, flags, privFlags);
}
} catch (RemoteException e) {
return false;
diff --git a/core/java/android/view/ViewTraversalTracingStrings.java b/core/java/android/view/ViewTraversalTracingStrings.java
index 7dde87bad26e..e95205b79c56 100644
--- a/core/java/android/view/ViewTraversalTracingStrings.java
+++ b/core/java/android/view/ViewTraversalTracingStrings.java
@@ -58,6 +58,6 @@ class ViewTraversalTracingStrings {
out.append(" ");
out.append(className);
v.appendId(out);
- return out.substring(0, Math.min(out.length() - 1, Trace.MAX_SECTION_NAME_LEN - 1));
+ return out.substring(0, Math.min(out.length(), Trace.MAX_SECTION_NAME_LEN));
}
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 18006bb7866a..14978ede88cc 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1668,6 +1668,15 @@ public interface WindowManager extends ViewManager {
public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver, int deviceId);
/**
+ * Request the application launch keyboard shortcuts the system has defined.
+ *
+ * @param deviceId The id of the {@link InputDevice} that will handle the shortcut.
+ *
+ * @hide
+ */
+ KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId);
+
+ /**
* Request for ime's keyboard shortcuts to be retrieved asynchronously.
*
* @param receiver The callback to be triggered when the result is ready.
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index b667427fd2c5..330e46af6381 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -237,6 +237,16 @@ public final class WindowManagerImpl implements WindowManager {
}
@Override
+ public KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId) {
+ try {
+ return WindowManagerGlobal.getWindowManagerService()
+ .getApplicationLaunchKeyboardShortcuts(deviceId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ @Override
public void requestImeKeyboardShortcuts(
final KeyboardShortcutsReceiver receiver, int deviceId) {
IResultReceiver resultReceiver = new IResultReceiver.Stub() {
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 55f22a631c3b..78718586329e 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -503,13 +503,13 @@ public class WindowlessWindowManager implements IWindowSession {
}
@Override
- public boolean performHapticFeedback(int effectId, boolean always, boolean fromIme) {
+ public boolean performHapticFeedback(int effectId, int flags, int privFlags) {
return false;
}
@Override
- public void performHapticFeedbackAsync(int effectId, boolean always, boolean fromIme) {
- performHapticFeedback(effectId, always, fromIme);
+ public void performHapticFeedbackAsync(int effectId, int flags, int privFlags) {
+ performHapticFeedback(effectId, flags, privFlags);
}
@Override
diff --git a/core/java/android/view/accessibility/a11ychecker/Android.bp b/core/java/android/view/accessibility/a11ychecker/Android.bp
deleted file mode 100644
index e5a577c16421..000000000000
--- a/core/java/android/view/accessibility/a11ychecker/Android.bp
+++ /dev/null
@@ -1,7 +0,0 @@
-java_library_static {
- name: "A11yChecker",
- srcs: [
- "*.java",
- ],
- visibility: ["//visibility:public"],
-}
diff --git a/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java b/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
index e7a2fb92a382..07a97948e7fd 100644
--- a/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
+++ b/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
@@ -465,6 +465,20 @@ final class IInputMethodManagerGlobalInvoker {
}
@AnyThread
+ @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+ static void onImeSwitchButtonClickFromSystem(int displayId) {
+ final IInputMethodManager service = getService();
+ if (service == null) {
+ return;
+ }
+ try {
+ service.onImeSwitchButtonClickFromSystem(displayId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ @AnyThread
@Nullable
@RequiresPermission(value = Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)
static InputMethodSubtype getCurrentInputMethodSubtype(@UserIdInt int userId) {
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 11ee286652a1..098f65575928 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -92,7 +92,7 @@ public final class InputMethodInfo implements Parcelable {
*
* @see #createImeLanguageSettingsActivityIntent()
*/
- @FlaggedApi(android.view.inputmethod.Flags.FLAG_IME_SWITCHER_REVAMP)
+ @FlaggedApi(android.view.inputmethod.Flags.FLAG_IME_SWITCHER_REVAMP_API)
public static final String ACTION_IME_LANGUAGE_SETTINGS =
"android.view.inputmethod.action.IME_LANGUAGE_SETTINGS";
@@ -298,7 +298,7 @@ public final class InputMethodInfo implements Parcelable {
com.android.internal.R.styleable.InputMethod);
settingsActivityComponent = sa.getString(
com.android.internal.R.styleable.InputMethod_settingsActivity);
- if (Flags.imeSwitcherRevamp()) {
+ if (Flags.imeSwitcherRevampApi()) {
languageSettingsActivityComponent = sa.getString(
com.android.internal.R.styleable.InputMethod_languageSettingsActivity);
}
@@ -888,7 +888,7 @@ public final class InputMethodInfo implements Parcelable {
*
* @attr ref R.styleable#InputMethod_languageSettingsActivity
*/
- @FlaggedApi(android.view.inputmethod.Flags.FLAG_IME_SWITCHER_REVAMP)
+ @FlaggedApi(android.view.inputmethod.Flags.FLAG_IME_SWITCHER_REVAMP_API)
@Nullable
public Intent createImeLanguageSettingsActivityIntent() {
if (TextUtils.isEmpty(mLanguageSettingsActivityName)) {
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 0c63e583f326..dbbfff04f436 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -4354,6 +4354,19 @@ public final class InputMethodManager {
}
/**
+ * Called when the IME switch button was clicked from the system. This will show the input
+ * method picker dialog.
+ *
+ * @param displayId The ID of the display where the input method picker dialog should be shown.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+ public void onImeSwitchButtonClickFromSystem(int displayId) {
+ IInputMethodManagerGlobalInvoker.onImeSwitchButtonClickFromSystem(displayId);
+ }
+
+ /**
* A test API for CTS to check whether there are any pending IME visibility requests.
*
* @return {@code true} iff there are pending IME visibility requests.
diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig
index 56e5bcf79933..e294ee2d3a91 100644
--- a/core/java/android/view/inputmethod/flags.aconfig
+++ b/core/java/android/view/inputmethod/flags.aconfig
@@ -82,6 +82,15 @@ flag {
}
flag {
+ name: "ime_switcher_revamp_api"
+ is_exported: true
+ namespace: "input_method"
+ description: "Feature flag for APIs for revamping the Input Method Switcher menu"
+ bug: "311791923"
+ is_fixed_read_only: true
+}
+
+flag {
name: "initiation_without_input_connection"
namespace: "input_method"
description: "Feature flag for initiating handwriting without InputConnection"
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 10344792eee2..c53a0e158dea 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -36,6 +36,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.Trace;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.ArraySet;
@@ -339,10 +340,10 @@ public final class WebViewFactory {
if (sProviderInstance != null) return sProviderInstance;
sTimestamps.mWebViewLoadStart = SystemClock.uptimeMillis();
- final int uid = android.os.Process.myUid();
- if (uid == android.os.Process.ROOT_UID || uid == android.os.Process.SYSTEM_UID
- || uid == android.os.Process.PHONE_UID || uid == android.os.Process.NFC_UID
- || uid == android.os.Process.BLUETOOTH_UID) {
+ final int appId = UserHandle.getAppId(android.os.Process.myUid());
+ if (appId == android.os.Process.ROOT_UID || appId == android.os.Process.SYSTEM_UID
+ || appId == android.os.Process.PHONE_UID || appId == android.os.Process.NFC_UID
+ || appId == android.os.Process.BLUETOOTH_UID) {
throw new UnsupportedOperationException(
"For security reasons, WebView is not allowed in privileged processes");
}
diff --git a/core/java/android/webkit/WebViewUpdateManager.java b/core/java/android/webkit/WebViewUpdateManager.java
index 07576a2e89e4..dd48df975906 100644
--- a/core/java/android/webkit/WebViewUpdateManager.java
+++ b/core/java/android/webkit/WebViewUpdateManager.java
@@ -101,6 +101,8 @@ public final class WebViewUpdateManager {
* enabled for all users.
*/
@SuppressLint({"ParcelableList", "ArrayReturn"})
+ @RequiresPermission(allOf = {android.Manifest.permission.INTERACT_ACROSS_USERS,
+ android.Manifest.permission.QUERY_ALL_PACKAGES})
public @NonNull WebViewProviderInfo[] getValidWebViewPackages() {
try {
return mService.getValidWebViewPackages();
diff --git a/core/java/android/window/ActivityWindowInfo.java b/core/java/android/window/ActivityWindowInfo.java
index 946bb823398c..71c500cd1bfa 100644
--- a/core/java/android/window/ActivityWindowInfo.java
+++ b/core/java/android/window/ActivityWindowInfo.java
@@ -18,6 +18,8 @@ package android.window;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.Activity;
+import android.app.ActivityThread;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
@@ -144,4 +146,15 @@ public final class ActivityWindowInfo implements Parcelable {
+ ", taskFragmentBounds=" + mTaskFragmentBounds
+ "}";
}
+
+ /** Gets the {@link ActivityWindowInfo} of the given activity. */
+ @Nullable
+ public static ActivityWindowInfo getActivityWindowInfo(@NonNull Activity activity) {
+ if (activity.isFinishing()) {
+ return null;
+ }
+ final ActivityThread.ActivityClientRecord record = ActivityThread.currentActivityThread()
+ .getActivityClient(activity.getActivityToken());
+ return record != null ? record.getActivityWindowInfo() : null;
+ }
}
diff --git a/core/java/android/window/BackProgressAnimator.java b/core/java/android/window/BackProgressAnimator.java
index d28500c0a1ea..12d4ab8bc963 100644
--- a/core/java/android/window/BackProgressAnimator.java
+++ b/core/java/android/window/BackProgressAnimator.java
@@ -16,12 +16,15 @@
package android.window;
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.FloatProperty;
import android.util.TimeUtils;
import android.view.Choreographer;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.dynamicanimation.animation.DynamicAnimation;
import com.android.internal.dynamicanimation.animation.FlingAnimation;
import com.android.internal.dynamicanimation.animation.FloatValueHolder;
@@ -210,7 +213,8 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL
}
/** Returns true if the back animation is in progress. */
- boolean isBackAnimationInProgress() {
+ @VisibleForTesting(visibility = PACKAGE)
+ public boolean isBackAnimationInProgress() {
return mBackAnimationInProgress;
}
diff --git a/core/java/android/window/ITaskFragmentOrganizerController.aidl b/core/java/android/window/ITaskFragmentOrganizerController.aidl
index 4706dfd1a76c..ac57c0056c2b 100644
--- a/core/java/android/window/ITaskFragmentOrganizerController.aidl
+++ b/core/java/android/window/ITaskFragmentOrganizerController.aidl
@@ -39,25 +39,6 @@ interface ITaskFragmentOrganizerController {
void unregisterOrganizer(in ITaskFragmentOrganizer organizer);
/**
- * Registers remote animations per transition type for the organizer. It will override the
- * animations if the transition only contains windows that belong to the organized
- * TaskFragments in the given Task.
- */
- void registerRemoteAnimations(in ITaskFragmentOrganizer organizer,
- in RemoteAnimationDefinition definition);
-
- /**
- * Unregisters remote animations per transition type for the organizer.
- */
- void unregisterRemoteAnimations(in ITaskFragmentOrganizer organizer);
-
- /**
- * Checks if an activity organized by a {@link android.window.TaskFragmentOrganizer} and
- * only occupies a portion of Task bounds.
- */
- boolean isActivityEmbedded(in IBinder activityToken);
-
- /**
* Notifies the server that the organizer has finished handling the given transaction. The
* server should apply the given {@link WindowContainerTransaction} for the necessary changes.
*/
diff --git a/core/java/android/window/TaskFragmentAnimationParams.java b/core/java/android/window/TaskFragmentAnimationParams.java
index 85e96c9c0290..67b22f9eb9c8 100644
--- a/core/java/android/window/TaskFragmentAnimationParams.java
+++ b/core/java/android/window/TaskFragmentAnimationParams.java
@@ -171,7 +171,7 @@ public final class TaskFragmentAnimationParams implements Parcelable {
*/
public boolean hasOverrideAnimation() {
return mOpenAnimationResId != DEFAULT_ANIMATION_RESOURCES_ID
- || mChangeAnimationResId != DEFAULT_ANIMATION_BACKGROUND_COLOR
+ || mChangeAnimationResId != DEFAULT_ANIMATION_RESOURCES_ID
|| mCloseAnimationResId != DEFAULT_ANIMATION_RESOURCES_ID;
}
diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java
index 461eab61e393..8e429cb376a6 100644
--- a/core/java/android/window/TaskFragmentOrganizer.java
+++ b/core/java/android/window/TaskFragmentOrganizer.java
@@ -21,6 +21,7 @@ import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FIRST_CUSTOM;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.window.ActivityWindowInfo.getActivityWindowInfo;
import android.annotation.CallSuper;
import android.annotation.FlaggedApi;
@@ -29,16 +30,17 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
+import android.app.Activity;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
-import android.view.RemoteAnimationDefinition;
import android.view.WindowManager;
import com.android.window.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -205,34 +207,6 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
}
/**
- * Registers remote animations per transition type for the organizer. It will override the
- * animations if the transition only contains windows that belong to the organized
- * TaskFragments, and at least one of the transition window is embedded (not filling the Task).
- * @hide
- */
- @CallSuper
- public void registerRemoteAnimations(@NonNull RemoteAnimationDefinition definition) {
- try {
- getController().registerRemoteAnimations(mInterface, definition);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Unregisters remote animations per transition type for the organizer.
- * @hide
- */
- @CallSuper
- public void unregisterRemoteAnimations() {
- try {
- getController().unregisterRemoteAnimations(mInterface);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Notifies the server that the organizer has finished handling the given transaction. The
* server should apply the given {@link WindowContainerTransaction} for the necessary changes.
*
@@ -353,15 +327,15 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
}
/**
- * Checks if an activity organized by a {@link android.window.TaskFragmentOrganizer} and
+ * Checks if an activity is organized by a {@link android.window.TaskFragmentOrganizer} and
* only occupies a portion of Task bounds.
+ *
+ * @see ActivityWindowInfo for additional window info.
* @hide
*/
- public boolean isActivityEmbedded(@NonNull IBinder activityToken) {
- try {
- return getController().isActivityEmbedded(activityToken);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ public static boolean isActivityEmbedded(@NonNull Activity activity) {
+ Objects.requireNonNull(activity);
+ final ActivityWindowInfo activityWindowInfo = getActivityWindowInfo(activity);
+ return activityWindowInfo != null && activityWindowInfo.isEmbedded();
}
}
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 8ded608b71e1..1083f64513b1 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -205,7 +205,7 @@ public final class TransitionInfo implements Parcelable {
FLAG_SYNC,
FLAG_CONFIG_AT_END,
FLAG_FIRST_CUSTOM
- })
+ }, flag = true)
public @interface ChangeFlags {}
private final @TransitionType int mType;
diff --git a/core/java/android/window/TransitionRequestInfo.java b/core/java/android/window/TransitionRequestInfo.java
index cc225767bd49..253337b553da 100644
--- a/core/java/android/window/TransitionRequestInfo.java
+++ b/core/java/android/window/TransitionRequestInfo.java
@@ -471,7 +471,7 @@ public final class TransitionRequestInfo implements Parcelable {
"pipTask = " + mPipTask + ", " +
"remoteTransition = " + mRemoteTransition + ", " +
"displayChange = " + mDisplayChange + ", " +
- "flags = " + mFlags + ", " +
+ "flags = " + Integer.toHexString(mFlags) + ", " +
"debugId = " + mDebugId +
" }";
}
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index f4f6c8aa3636..e9d77f8aaf80 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -25,6 +25,7 @@ import static android.window.TaskFragmentOperation.OP_TYPE_SET_ADJACENT_TASK_FRA
import static android.window.TaskFragmentOperation.OP_TYPE_SET_COMPANION_TASK_FRAGMENT;
import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
@@ -41,9 +42,12 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
import android.view.InsetsFrameProvider;
+import android.view.InsetsSource;
import android.view.SurfaceControl;
import android.view.WindowInsets.Type.InsetsType;
+import com.android.window.flags.Flags;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -711,14 +715,16 @@ public final class WindowContainerTransaction implements Parcelable {
@NonNull
public WindowContainerTransaction addInsetsSource(
@NonNull WindowContainerToken receiver,
- IBinder owner, int index, @InsetsType int type, Rect frame, Rect[] boundingRects) {
+ IBinder owner, int index, @InsetsType int type, Rect frame, Rect[] boundingRects,
+ @InsetsSource.Flags int flags) {
final HierarchyOp hierarchyOp =
new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER)
.setContainer(receiver.asBinder())
.setInsetsFrameProvider(new InsetsFrameProvider(owner, index, type)
.setSource(InsetsFrameProvider.SOURCE_ARBITRARY_RECTANGLE)
.setArbitraryRectangle(frame)
- .setBoundingRects(boundingRects))
+ .setBoundingRects(boundingRects)
+ .setFlags(flags))
.setInsetsFrameOwner(owner)
.build();
mHierarchyOps.add(hierarchyOp);
@@ -962,6 +968,23 @@ public final class WindowContainerTransaction implements Parcelable {
}
/**
+ * Sets the task as trimmable or not. This can be used to prevent the task from being trimmed by
+ * recents. This attribute is set to true on task creation by default.
+ *
+ * @param isTrimmableFromRecents When {@code true}, task is set as trimmable from recents.
+ * @hide
+ */
+ @NonNull
+ public WindowContainerTransaction setTaskTrimmableFromRecents(
+ @NonNull WindowContainerToken container,
+ boolean isTrimmableFromRecents) {
+ mHierarchyOps.add(
+ HierarchyOp.createForSetTaskTrimmableFromRecents(container.asBinder(),
+ isTrimmableFromRecents));
+ return this;
+ }
+
+ /**
* Merges another WCT into this one.
* @param transfer When true, this will transfer everything from other potentially leaving
* other in an unusable state. When false, other is left alone, but
@@ -1412,6 +1435,7 @@ public final class WindowContainerTransaction implements Parcelable {
public static final int HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH = 16;
public static final int HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION = 17;
public static final int HIERARCHY_OP_TYPE_MOVE_PIP_ACTIVITY_TO_PINNED_TASK = 18;
+ public static final int HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE = 19;
// The following key(s) are for use with mLaunchOptions:
// When launching a task (eg. from recents), this is the taskId to be launched.
@@ -1473,6 +1497,8 @@ public final class WindowContainerTransaction implements Parcelable {
private boolean mReparentLeafTaskIfRelaunch;
+ private boolean mIsTrimmableFromRecents;
+
public static HierarchyOp createForReparent(
@NonNull IBinder container, @Nullable IBinder reparent, boolean toTop) {
return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_REPARENT)
@@ -1575,6 +1601,16 @@ public final class WindowContainerTransaction implements Parcelable {
.build();
}
+ /** Create a hierarchy op for setting a task non-trimmable by recents. */
+ @FlaggedApi(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ public static HierarchyOp createForSetTaskTrimmableFromRecents(@NonNull IBinder container,
+ boolean isTrimmableFromRecents) {
+ return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE)
+ .setContainer(container)
+ .setIsTrimmableFromRecents(isTrimmableFromRecents)
+ .build();
+ }
+
/** Only creates through {@link Builder}. */
private HierarchyOp(int type) {
mType = type;
@@ -1599,6 +1635,7 @@ public final class WindowContainerTransaction implements Parcelable {
mShortcutInfo = copy.mShortcutInfo;
mAlwaysOnTop = copy.mAlwaysOnTop;
mReparentLeafTaskIfRelaunch = copy.mReparentLeafTaskIfRelaunch;
+ mIsTrimmableFromRecents = copy.mIsTrimmableFromRecents;
}
protected HierarchyOp(Parcel in) {
@@ -1620,6 +1657,7 @@ public final class WindowContainerTransaction implements Parcelable {
mShortcutInfo = in.readTypedObject(ShortcutInfo.CREATOR);
mAlwaysOnTop = in.readBoolean();
mReparentLeafTaskIfRelaunch = in.readBoolean();
+ mIsTrimmableFromRecents = in.readBoolean();
}
public int getType() {
@@ -1715,6 +1753,12 @@ public final class WindowContainerTransaction implements Parcelable {
return mIncludingParents;
}
+ /** Set the task to be trimmable */
+ @NonNull
+ public boolean isTrimmableFromRecents() {
+ return mIsTrimmableFromRecents;
+ }
+
/** Gets a string representation of a hierarchy-op type. */
public static String hopToString(int type) {
switch (type) {
@@ -1811,6 +1855,10 @@ public final class WindowContainerTransaction implements Parcelable {
sb.append("fragmentToken= ").append(mContainer)
.append(" operation= ").append(mTaskFragmentOperation);
break;
+ case HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE:
+ sb.append("container= ").append(mContainer)
+ .append(" isTrimmable= ")
+ .append(mIsTrimmableFromRecents);
default:
sb.append("container=").append(mContainer)
.append(" reparent=").append(mReparent)
@@ -1841,6 +1889,7 @@ public final class WindowContainerTransaction implements Parcelable {
dest.writeTypedObject(mShortcutInfo, flags);
dest.writeBoolean(mAlwaysOnTop);
dest.writeBoolean(mReparentLeafTaskIfRelaunch);
+ dest.writeBoolean(mIsTrimmableFromRecents);
}
@Override
@@ -1910,6 +1959,8 @@ public final class WindowContainerTransaction implements Parcelable {
private boolean mReparentLeafTaskIfRelaunch;
+ private boolean mIsTrimmableFromRecents;
+
Builder(int type) {
mType = type;
}
@@ -2000,6 +2051,11 @@ public final class WindowContainerTransaction implements Parcelable {
return this;
}
+ Builder setIsTrimmableFromRecents(boolean isTrimmableFromRecents) {
+ mIsTrimmableFromRecents = isTrimmableFromRecents;
+ return this;
+ }
+
HierarchyOp build() {
final HierarchyOp hierarchyOp = new HierarchyOp(mType);
hierarchyOp.mContainer = mContainer;
@@ -2023,6 +2079,7 @@ public final class WindowContainerTransaction implements Parcelable {
hierarchyOp.mBounds = mBounds;
hierarchyOp.mIncludingParents = mIncludingParents;
hierarchyOp.mReparentLeafTaskIfRelaunch = mReparentLeafTaskIfRelaunch;
+ hierarchyOp.mIsTrimmableFromRecents = mIsTrimmableFromRecents;
return hierarchyOp;
}
diff --git a/core/java/android/window/WindowMetricsController.java b/core/java/android/window/WindowMetricsController.java
index 739cf0eeca0c..0d5e37e19916 100644
--- a/core/java/android/window/WindowMetricsController.java
+++ b/core/java/android/window/WindowMetricsController.java
@@ -75,8 +75,8 @@ public final class WindowMetricsController {
/**
* The core implementation to obtain {@link WindowMetrics}
*
- * @param isMaximum {@code true} to obtain {@link WindowManager#getCurrentWindowMetrics()}.
- * {@code false} to obtain {@link WindowManager#getMaximumWindowMetrics()}.
+ * @param isMaximum {@code false} to obtain {@link WindowManager#getCurrentWindowMetrics()}.
+ * {@code true} to obtain {@link WindowManager#getMaximumWindowMetrics()}.
*/
private WindowMetrics getWindowMetricsInternal(boolean isMaximum) {
final Rect bounds;
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 9b87e2351e3f..7bbc3dbb29db 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -244,6 +244,7 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
// We should call onBackCancelled() when an active callback is removed from
// dispatcher.
sendCancelledIfInProgress(callback);
+ mHandler.post(mProgressAnimator::reset);
setTopOnBackInvokedCallback(getTopCallback());
}
}
diff --git a/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig b/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
index 5b99ff9703e0..48fb2b3ab129 100644
--- a/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
+++ b/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
@@ -91,6 +91,13 @@ flag {
}
flag {
+ name: "camera_compat_fullscreen_pick_same_task_activity"
+ namespace: "large_screen_experiences_app_compat"
+ description: "Limit undo of camera compat treatment to the same task that started the treatment."
+ bug: "350495350"
+}
+
+flag {
name: "app_compat_refactoring"
namespace: "large_screen_experiences_app_compat"
description: "Whether the changes about app compat refactoring are enabled./n"
@@ -113,4 +120,12 @@ flag {
namespace: "large_screen_experiences_app_compat"
description: "Enables sysui animation for user aspect ratio button"
bug: "300357441"
+}
+
+flag {
+ name: "app_compat_ui_framework"
+ namespace: "large_screen_experiences_app_compat"
+ description: "Whether the declarative compat UI framework is enabled"
+ bug: "270361630"
+ is_fixed_read_only: true
} \ No newline at end of file
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index d0ab674a0e62..3f1c06ac7e10 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -40,8 +40,8 @@ flag {
flag {
name: "enable_windowing_edge_drag_resize"
namespace: "lse_desktop_experience"
- description: "Enables edge drag resizing for all input sources"
- bug: "323383067"
+ description: "Enables edge drag resizing for stylus input (cursor is enabled by default)"
+ bug: "337782092"
}
flag {
@@ -122,8 +122,64 @@ flag {
}
flag {
+ name: "enable_caption_compat_inset_force_consumption"
+ namespace: "lse_desktop_experience"
+ description: "Enables force-consumption of caption bar insets for immersive apps in freeform"
+ bug: "316231589"
+}
+
+flag {
name: "show_desktop_windowing_dev_option"
namespace: "lse_desktop_experience"
description: "Whether to show developer option for enabling desktop windowing mode"
bug: "348193756"
}
+
+flag {
+ name: "enable_desktop_windowing_app_to_web"
+ namespace: "lse_desktop_experience"
+ description: "Whether to enable the app-to-web feature and show the open in browser button in the header menu"
+ bug: "349695493"
+}
+
+flag {
+ name: "enable_windowing_transition_handlers_observers"
+ namespace: "lse_desktop_experience"
+ description: "Whether to enable desktop windowing transition handler and observer instead of task listeners."
+ bug: "332682201"
+}
+
+flag {
+ name: "enable_caption_compat_inset_conversion"
+ namespace: "lse_desktop_experience"
+ description: "Enables compatibility mitigation for apps that don't support caption insets well"
+ bug: "316231589"
+}
+
+flag {
+ name: "enable_desktop_windowing_multi_instance_features"
+ namespace: "lse_desktop_experience"
+ description: "Whether to enable multi-instance support in desktop windowing."
+ bug: "336289597"
+}
+
+flag {
+ name: "enable_desktop_windowing_back_navigation"
+ namespace: "lse_desktop_experience"
+ description: "Whether to enable back navigation treatment in desktop windowing."
+ bug: "350421096"
+}
+
+flag {
+ name: "enable_desktop_windowing_app_handle_education"
+ namespace: "lse_desktop_experience"
+ description: "Enables desktop windowing app handle education"
+ bug: "348208342"
+}
+
+flag {
+ name: "enable_compat_ui_visibility_status"
+ namespace: "lse_desktop_experience"
+ description: "Enables the tracking of the status for compat ui elements."
+ bug: "350953004"
+}
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
index 94f6503f8a97..6ce9725f95b0 100644
--- a/core/java/android/window/flags/responsible_apis.aconfig
+++ b/core/java/android/window/flags/responsible_apis.aconfig
@@ -58,6 +58,13 @@ flag {
}
flag {
+ name: "bal_additional_start_modes"
+ namespace: "responsible_apis"
+ description: "Introduce additional start modes."
+ bug: "352182359"
+}
+
+flag {
name: "bal_send_intent_with_options"
namespace: "responsible_apis"
description: "Add options parameter to IntentSender.sendIntent."
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index b5bc572724b7..5397e91bd249 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -19,6 +19,16 @@ flag {
}
flag {
+ name: "apply_lifecycle_on_pip_change"
+ namespace: "windowing_frontend"
+ description: "Make pip activity lifecyle change with windowing mode"
+ bug: "333452456"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "blast_sync_notification_shade_on_display_switch"
namespace: "windowing_frontend"
description: "Make the buffer content of notification shade synchronize with display switch"
@@ -60,17 +70,6 @@ flag {
}
flag {
- name: "skip_sleeping_when_switching_display"
- namespace: "windowing_frontend"
- description: "Reduce unnecessary visibility or lifecycle changes when changing fold state"
- bug: "303241079"
- is_fixed_read_only: true
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "introduce_smoother_dimmer"
namespace: "windowing_frontend"
description: "Refactor dim to fix flickers"
@@ -142,6 +141,13 @@ flag {
}
flag {
+ name: "respect_non_top_visible_fixed_orientation"
+ namespace: "windowing_frontend"
+ description: "If top activity is not opaque, respect the fixed orientation of activity behind it"
+ bug: "283514860"
+}
+
+flag {
name: "insets_decoupled_configuration"
namespace: "windowing_frontend"
description: "Configuration decoupled from insets"
@@ -200,3 +206,22 @@ flag {
}
}
+flag {
+ name: "enforce_shell_thread_model"
+ namespace: "windowing_frontend"
+ description: "Crash the shell process if someone calls in from the wrong thread"
+ bug: "351189446"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+flag {
+ name: "custom_animations_behind_translucent"
+ namespace: "windowing_frontend"
+ description: "A change can use its own layer parameters to animate behind a translucent activity"
+ bug: "327332488"
+ 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 68e33c61f71f..ae9d757e1e0b 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -93,16 +93,6 @@ flag {
flag {
namespace: "windowing_sdk"
- name: "always_defer_transition_when_apply_wct"
- description: "Report error when defer transition fails when it should not"
- bug: "335562144"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
- namespace: "windowing_sdk"
name: "fix_pip_restore_to_overlay"
description: "Restore exit-pip activity back to ActivityEmbedding overlay"
bug: "297887697"
diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java
index 7a8a47e5f9fc..9d5704141c93 100644
--- a/core/java/com/android/internal/app/SuspendedAppActivity.java
+++ b/core/java/com/android/internal/app/SuspendedAppActivity.java
@@ -342,8 +342,8 @@ public class SuspendedAppActivity extends AlertActivity
.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
.toBundle();
try {
- mOnUnsuspend.sendIntent(this, 0, null, null, null, null,
- activityOptions);
+ mOnUnsuspend.sendIntent(this, 0, null, null, activityOptions,
+ null, null);
} catch (IntentSender.SendIntentException e) {
Slog.e(TAG, "Error while starting intent " + mOnUnsuspend, e);
}
diff --git a/core/java/com/android/internal/display/RefreshRateSettingsUtils.java b/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
index c23a5012923b..47e4943a035b 100644
--- a/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
+++ b/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
@@ -83,4 +83,32 @@ public class RefreshRateSettingsUtils {
}
return maxRefreshRate;
}
+
+ /**
+ * Find the highest refresh rate among all the modes of all the built-in/physical displays.
+ *
+ * This method will acquire DisplayManager.mLock, so calling it while holding other locks
+ * should be done with care.
+ * @param context The context
+ * @return The highest refresh rate
+ */
+ public static float findHighestRefreshRateAmongAllBuiltInDisplays(Context context) {
+ final DisplayManager dm = context.getSystemService(DisplayManager.class);
+ final Display[] displays = dm.getDisplays(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED);
+ if (displays.length == 0) {
+ Log.w(TAG, "No valid display devices");
+ return DEFAULT_REFRESH_RATE;
+ }
+
+ float maxRefreshRate = DEFAULT_REFRESH_RATE;
+ for (Display display : displays) {
+ if (display.getType() != Display.TYPE_INTERNAL) continue;
+ for (Display.Mode mode : display.getSupportedModes()) {
+ if (mode.getRefreshRate() > maxRefreshRate) {
+ maxRefreshRate = mode.getRefreshRate();
+ }
+ }
+ }
+ return maxRefreshRate;
+ }
}
diff --git a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
index 63623c767694..ac4c066a992f 100644
--- a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
+++ b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
@@ -43,6 +43,7 @@ oneway interface IInputMethodPrivilegedOperations {
void switchToPreviousInputMethod(in AndroidFuture future /* T=Boolean */);
void switchToNextInputMethod(boolean onlyCurrentIme, in AndroidFuture future /* T=Boolean */);
void shouldOfferSwitchingToNextInputMethod(in AndroidFuture future /* T=Boolean */);
+ void onImeSwitchButtonClickFromClient(int displayId);
void notifyUserActionAsync();
void applyImeVisibilityAsync(IBinder showOrHideInputToken, boolean setVisible,
in ImeTracker.Token statsToken);
diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
index 72c41bed4436..2daf0fd1f61c 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
@@ -378,6 +378,22 @@ public final class InputMethodPrivilegedOperations {
}
/**
+ * Calls {@link IInputMethodPrivilegedOperations#onImeSwitchButtonClickFromClient(int)}
+ */
+ @AnyThread
+ public void onImeSwitchButtonClickFromClient(int displayId) {
+ final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
+ if (ops == null) {
+ return;
+ }
+ try {
+ ops.onImeSwitchButtonClickFromClient(displayId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Calls {@link IInputMethodPrivilegedOperations#notifyUserActionAsync()}
*/
@AnyThread
diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java
index ab0485175665..3e6f18e8e24b 100644
--- a/core/java/com/android/internal/jank/Cuj.java
+++ b/core/java/com/android/internal/jank/Cuj.java
@@ -160,8 +160,13 @@ public class Cuj {
*/
public static final int CUJ_DESKTOP_MODE_RESIZE_WINDOW = 106;
- /** Track entering desktop mode interaction. */
- public static final int CUJ_DESKTOP_MODE_ENTER_MODE = 107;
+ /**
+ * Track entering desktop mode interaction via app handle drag.
+ *
+ * <p>Tracking starts when the app handle is dragged and
+ * finishes when the window animation to desktop ends after app handle release.
+ */
+ public static final int CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG = 107;
/** Track exiting desktop mode interaction. */
public static final int CUJ_DESKTOP_MODE_EXIT_MODE = 108;
@@ -172,8 +177,28 @@ public class Cuj {
/** Track window drag interaction in desktop mode. */
public static final int CUJ_DESKTOP_MODE_DRAG_WINDOW = 110;
+ /** Track launching a dialog from a status bar chip. */
+ public static final int CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP = 111;
+
+ /**
+ * Track entering desktop mode interaction via app handle menu.
+ *
+ * <p>Tracking starts after windowing mode option in the app handle menu is clicked and
+ * finishes when the window animation to desktop ends.
+ */
+ public static final int CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU = 112;
+
+ /** Track Launcher Keyboard Quick Switch View opening animation */
+ public static final int CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_OPEN = 113;
+
+ /** Track Launcher Keyboard Quick Switch View closing animation */
+ public static final int CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE = 114;
+
+ /** Track launching an app through the Launcher Keyboard Quick Switch View */
+ public static final int CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH = 115;
+
// When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE.
- @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_DRAG_WINDOW;
+ @VisibleForTesting static final int LAST_CUJ = CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH;
/** @hide */
@IntDef({
@@ -272,10 +297,15 @@ public class Cuj {
CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW,
CUJ_FOLD_ANIM,
CUJ_DESKTOP_MODE_RESIZE_WINDOW,
- CUJ_DESKTOP_MODE_ENTER_MODE,
+ CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG,
+ CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU,
CUJ_DESKTOP_MODE_EXIT_MODE,
CUJ_DESKTOP_MODE_MINIMIZE_WINDOW,
- CUJ_DESKTOP_MODE_DRAG_WINDOW
+ CUJ_DESKTOP_MODE_DRAG_WINDOW,
+ CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP,
+ CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_OPEN,
+ CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE,
+ CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {}
@@ -384,10 +414,15 @@ public class Cuj {
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_MAXIMIZE_WINDOW;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_FOLD_ANIM] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__FOLD_ANIM;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_RESIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_RESIZE_WINDOW;
- CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_ENTER_MODE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_ENTER_MODE;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_EXIT_MODE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_EXIT_MODE;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_MINIMIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_MINIMIZE_WINDOW;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_DRAG_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_DRAG_WINDOW;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_OPEN] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_KEYBOARD_QUICK_SWITCH_OPEN;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH;
}
private Cuj() {
@@ -596,14 +631,24 @@ public class Cuj {
return "FOLD_ANIM";
case CUJ_DESKTOP_MODE_RESIZE_WINDOW:
return "DESKTOP_MODE_RESIZE_WINDOW";
- case CUJ_DESKTOP_MODE_ENTER_MODE:
- return "DESKTOP_MODE_ENTER_MODE";
+ case CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG:
+ return "DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG";
+ case CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU:
+ return "DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU";
case CUJ_DESKTOP_MODE_EXIT_MODE:
return "DESKTOP_MODE_EXIT_MODE";
case CUJ_DESKTOP_MODE_MINIMIZE_WINDOW:
return "DESKTOP_MODE_MINIMIZE_WINDOW";
case CUJ_DESKTOP_MODE_DRAG_WINDOW:
return "DESKTOP_MODE_DRAG_WINDOW";
+ case CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP:
+ return "STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP";
+ case CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_OPEN:
+ return "LAUNCHER_KEYBOARD_QUICK_SWITCH_OPEN";
+ case CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE:
+ return "LAUNCHER_KEYBOARD_QUICK_SWITCH_CLOSE";
+ case CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH:
+ return "LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH";
}
return "UNKNOWN";
}
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index b86cbfb69490..33610a09b7c8 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -325,6 +325,48 @@ public class InteractionJankMonitor {
/**
* Begins a trace session.
*
+ * @param surface a handle for the surface to begin tracing for.
+ * @param context context to provide display and handler information.
+ * @param cujType the specific {@link Cuj.CujType}.
+ * @return boolean true if the tracker is started successfully, false otherwise.
+ */
+ public boolean begin(SurfaceControl surface, Context context, @Cuj.CujType int cujType) {
+ try {
+ return begin(Configuration.Builder.withSurface(cujType, context, surface));
+ } catch (IllegalArgumentException ex) {
+ Log.d(TAG, "Build configuration failed!", ex);
+ return false;
+ }
+ }
+
+ /**
+ * Begins a trace session.
+ *
+ * @param surface a handle for the surface to begin tracing for.
+ * @param context context to provide display and handler information.
+ * @param cujType the specific {@link Cuj.CujType}.
+ * @param tag a tag containing extra information about the interaction.
+ * @return boolean true if the tracker is started successfully, false otherwise.
+ */
+ public boolean begin(SurfaceControl surface, Context context, @Cuj.CujType int cujType,
+ String tag) {
+ try {
+ final Configuration.Builder builder =
+ Configuration.Builder.withSurface(cujType, context, surface);
+ if (!TextUtils.isEmpty(tag)) {
+ builder.setTag(tag);
+ }
+ return begin(builder);
+ } catch (IllegalArgumentException ex) {
+ Log.d(TAG, "Build configuration failed!", ex);
+ return false;
+ }
+ }
+
+
+ /**
+ * Begins a trace session.
+ *
* @param builder the builder of the configurations for instrumenting the CUJ.
* @return boolean true if the tracker is begun successfully, false otherwise.
*/
diff --git a/core/java/com/android/internal/os/BinderTransactionNameResolver.java b/core/java/com/android/internal/os/BinderTransactionNameResolver.java
index 5f6f427d344c..f1dc1f286bce 100644
--- a/core/java/com/android/internal/os/BinderTransactionNameResolver.java
+++ b/core/java/com/android/internal/os/BinderTransactionNameResolver.java
@@ -17,6 +17,7 @@
package com.android.internal.os;
import android.os.Binder;
+import android.text.TextUtils;
import com.android.internal.annotations.VisibleForTesting;
@@ -37,6 +38,8 @@ import java.util.HashMap;
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public class BinderTransactionNameResolver {
private static final Method NO_GET_DEFAULT_TRANSACTION_NAME_METHOD;
+ private static final boolean USE_TRANSACTION_CODES_FOR_UNKNOWN_METHODS =
+ Flags.useTransactionCodesForUnknownMethods();
/**
* Generates the default transaction method name, which is just the transaction code.
@@ -81,7 +84,14 @@ public class BinderTransactionNameResolver {
}
try {
- return (String) method.invoke(null, transactionCode);
+ String methodName = (String) method.invoke(null, transactionCode);
+ if (USE_TRANSACTION_CODES_FOR_UNKNOWN_METHODS) {
+ return TextUtils.isEmpty(methodName)
+ ? String.valueOf(transactionCode)
+ : methodName;
+ } else {
+ return methodName;
+ }
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
diff --git a/core/java/com/android/internal/os/flags.aconfig b/core/java/com/android/internal/os/flags.aconfig
index c8d6810e274a..2ad665181e70 100644
--- a/core/java/com/android/internal/os/flags.aconfig
+++ b/core/java/com/android/internal/os/flags.aconfig
@@ -9,3 +9,14 @@ flag {
is_fixed_read_only: true
bug: "241474956"
}
+
+flag {
+ name: "use_transaction_codes_for_unknown_methods"
+ namespace: "stability"
+ description: "Use transaction codes when the method names is unknown"
+ bug: "350041302"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+} \ No newline at end of file
diff --git a/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java b/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
index f306b0b02677..b873175451e1 100644
--- a/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
+++ b/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
@@ -60,7 +60,13 @@ public class AconfigFlags {
"/product/etc/aconfig_flags.pb",
"/vendor/etc/aconfig_flags.pb");
+ public enum Permission {
+ READ_WRITE,
+ READ_ONLY
+ }
+
private final ArrayMap<String, Boolean> mFlagValues = new ArrayMap<>();
+ private final ArrayMap<String, Permission> mFlagPermissions = new ArrayMap<>();
public AconfigFlags() {
if (!Flags.manifestFlagging()) {
@@ -184,6 +190,12 @@ public class AconfigFlags {
Slog.v(LOG_TAG, "Read Aconfig default flag value "
+ flagPackageAndName + " = " + flagValue);
mFlagValues.put(flagPackageAndName, flagValue);
+
+ Permission permission = flag.permission == Aconfig.READ_ONLY
+ ? Permission.READ_ONLY
+ : Permission.READ_WRITE;
+
+ mFlagPermissions.put(flagPackageAndName, permission);
}
}
@@ -200,6 +212,17 @@ public class AconfigFlags {
}
/**
+ * Get the flag permission, or null if the flag doesn't exist.
+ * @param flagPackageAndName Full flag name formatted as 'package.flag'
+ * @return the current permission of the given Aconfig flag, or null if there is no such flag
+ */
+ @Nullable
+ public Permission getFlagPermission(@NonNull String flagPackageAndName) {
+ Permission permission = mFlagPermissions.get(flagPackageAndName);
+ return permission;
+ }
+
+ /**
* Check if the element in {@code parser} should be skipped because of the feature flag.
* @param parser XML parser object currently parsing an element
* @return true if the element is disabled because of its feature flag
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 63ff598bae61..87e22ed42cbd 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -109,6 +109,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.function.Consumer;
@@ -1193,7 +1194,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
// If we should always consume system bars, only consume that if the app wanted to go to
// fullscreen, as otherwise we can expect the app to handle it.
boolean fullscreen = (sysUiVisibility & SYSTEM_UI_FLAG_FULLSCREEN) != 0
- || (attrs.flags & FLAG_FULLSCREEN) != 0
+ || (attrs.flags & FLAG_FULLSCREEN) != 0;
+ final boolean hideStatusBar = fullscreen
|| (requestedVisibleTypes & WindowInsets.Type.statusBars()) == 0;
boolean consumingStatusBar =
((sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0
@@ -1203,9 +1205,20 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
&& mForceWindowDrawsBarBackgrounds
&& mLastTopInset != 0)
|| ((mLastForceConsumingTypes & WindowInsets.Type.statusBars()) != 0
- && fullscreen);
+ && hideStatusBar);
- int consumedTop = consumingStatusBar ? mLastTopInset : 0;
+ final boolean hideCaptionBar = fullscreen
+ || (requestedVisibleTypes & WindowInsets.Type.captionBar()) == 0;
+ final boolean consumingCaptionBar =
+ ((mLastForceConsumingTypes & WindowInsets.Type.captionBar()) != 0
+ && hideCaptionBar);
+
+ final int consumedTop;
+ if (Flags.enableCaptionCompatInsetForceConsumption()) {
+ consumedTop = (consumingStatusBar || consumingCaptionBar) ? mLastTopInset : 0;
+ } else {
+ consumedTop = consumingStatusBar ? mLastTopInset : 0;
+ }
int consumedRight = consumingNavBar ? mLastRightInset : 0;
int consumedBottom = consumingNavBar ? mLastBottomInset : 0;
int consumedLeft = consumingNavBar ? mLastLeftInset : 0;
diff --git a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
index d24487412313..572a599dc8f5 100644
--- a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
@@ -48,6 +48,7 @@ import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
@@ -65,7 +66,7 @@ public class LegacyProtoLogImpl implements IProtoLog {
private final String mLegacyViewerConfigFilename;
private final TraceBuffer mBuffer;
private final LegacyProtoLogViewerConfigReader mViewerConfig;
- private final TreeMap<String, IProtoLogGroup> mLogGroups;
+ private final Map<String, IProtoLogGroup> mLogGroups = new TreeMap<>();
private final Runnable mCacheUpdater;
private final int mPerChunkSize;
@@ -74,20 +75,19 @@ public class LegacyProtoLogImpl implements IProtoLog {
private final Object mProtoLogEnabledLock = new Object();
public LegacyProtoLogImpl(String outputFile, String viewerConfigFilename,
- TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
+ Runnable cacheUpdater) {
this(new File(outputFile), viewerConfigFilename, BUFFER_CAPACITY,
- new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, logGroups, cacheUpdater);
+ new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, cacheUpdater);
}
public LegacyProtoLogImpl(File file, String viewerConfigFilename, int bufferCapacity,
LegacyProtoLogViewerConfigReader viewerConfig, int perChunkSize,
- TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
+ Runnable cacheUpdater) {
mLogFile = file;
mBuffer = new TraceBuffer(bufferCapacity);
mLegacyViewerConfigFilename = viewerConfigFilename;
mViewerConfig = viewerConfig;
mPerChunkSize = perChunkSize;
- mLogGroups = logGroups;
mCacheUpdater = cacheUpdater;
}
@@ -97,21 +97,26 @@ public class LegacyProtoLogImpl implements IProtoLog {
@VisibleForTesting
@Override
public void log(LogLevel level, IProtoLogGroup group, long messageHash, int paramsMask,
- @Nullable String messageString, Object[] args) {
+ @Nullable Object[] args) {
if (group.isLogToProto()) {
logToProto(messageHash, paramsMask, args);
}
if (group.isLogToLogcat()) {
- logToLogcat(group.getTag(), level, messageHash, messageString, args);
+ logToLogcat(group.getTag(), level, messageHash, args);
}
}
+ @Override
+ public void log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object... args) {
+ // This will be removed very soon so no point implementing it here.
+ throw new IllegalStateException(
+ "Not implemented. Only implemented for PerfettoProtoLogImpl.");
+ }
+
private void logToLogcat(String tag, LogLevel level, long messageHash,
- @Nullable String messageString, Object[] args) {
+ @Nullable Object[] args) {
String message = null;
- if (messageString == null) {
- messageString = mViewerConfig.getViewerString(messageHash);
- }
+ final String messageString = mViewerConfig.getViewerString(messageHash);
if (messageString != null) {
if (args != null) {
try {
@@ -125,8 +130,10 @@ public class LegacyProtoLogImpl implements IProtoLog {
}
if (message == null) {
StringBuilder builder = new StringBuilder("UNKNOWN MESSAGE (" + messageHash + ")");
- for (Object o : args) {
- builder.append(" ").append(o);
+ if (args != null) {
+ for (Object o : args) {
+ builder.append(" ").append(o);
+ }
}
message = builder.toString();
}
@@ -410,5 +417,12 @@ public class LegacyProtoLogImpl implements IProtoLog {
// so we ignore the level argument to this function.
return group.isLogToLogcat() || (group.isLogToProto() && isProtoEnabled());
}
+
+ @Override
+ public void registerGroups(IProtoLogGroup... protoLogGroups) {
+ for (IProtoLogGroup group : protoLogGroups) {
+ mLogGroups.put(group.name(), group);
+ }
+ }
}
diff --git a/core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java b/core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java
new file mode 100644
index 000000000000..ebdad6d52933
--- /dev/null
+++ b/core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java
@@ -0,0 +1,87 @@
+/*
+ * 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.internal.protolog;
+
+import static com.android.internal.protolog.ProtoLog.REQUIRE_PROTOLOGTOOL;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.protolog.common.ILogger;
+import com.android.internal.protolog.common.IProtoLog;
+import com.android.internal.protolog.common.IProtoLogGroup;
+import com.android.internal.protolog.common.LogLevel;
+
+/**
+ * Class only create and used to server temporarily for when there is source code pre-processing by
+ * the ProtoLog tool, when the tracing to Perfetto flag is off, and the static REQUIRE_PROTOLOGTOOL
+ * boolean is false. In which case we simply want to log protolog message to logcat. Note, that this
+ * means that in such cases there is no real advantage of using protolog over logcat.
+ *
+ * @deprecated Should not be used. This is just a temporary class to support a legacy behavior.
+ */
+@Deprecated
+public class LogcatOnlyProtoLogImpl implements IProtoLog {
+ @Override
+ public void log(LogLevel logLevel, IProtoLogGroup group, long messageHash, int paramsMask,
+ Object[] args) {
+ throw new RuntimeException("Not supported when using LogcatOnlyProtoLogImpl");
+ }
+
+ @Override
+ public void log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object[] args) {
+ if (REQUIRE_PROTOLOGTOOL) {
+ throw new RuntimeException(
+ "REQUIRE_PROTOLOGTOOL not set to false before the first log call.");
+ }
+
+ String formattedString = TextUtils.formatSimple(messageString, args);
+ switch (logLevel) {
+ case VERBOSE -> Log.v(group.getTag(), formattedString);
+ case INFO -> Log.i(group.getTag(), formattedString);
+ case DEBUG -> Log.d(group.getTag(), formattedString);
+ case WARN -> Log.w(group.getTag(), formattedString);
+ case ERROR -> Log.e(group.getTag(), formattedString);
+ case WTF -> Log.wtf(group.getTag(), formattedString);
+ }
+ }
+
+ @Override
+ public boolean isProtoEnabled() {
+ return false;
+ }
+
+ @Override
+ public int startLoggingToLogcat(String[] groups, ILogger logger) {
+ return 0;
+ }
+
+ @Override
+ public int stopLoggingToLogcat(String[] groups, ILogger logger) {
+ return 0;
+ }
+
+ @Override
+ public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
+ return true;
+ }
+
+ @Override
+ public void registerGroups(IProtoLogGroup... protoLogGroups) {
+ // Does nothing
+ }
+}
diff --git a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
index 42fa6ac0407d..652cba7ed00d 100644
--- a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
@@ -42,11 +42,11 @@ import static android.internal.perfetto.protos.TracePacketOuterClass.TracePacket
import static android.internal.perfetto.protos.TracePacketOuterClass.TracePacket.SEQ_NEEDS_INCREMENTAL_STATE;
import static android.internal.perfetto.protos.TracePacketOuterClass.TracePacket.TIMESTAMP;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData;
import android.os.ShellCommand;
import android.os.SystemClock;
-import android.os.Trace;
import android.text.TextUtils;
import android.tracing.perfetto.DataSourceParams;
import android.tracing.perfetto.InitArguments;
@@ -72,37 +72,46 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
/**
* A service for the ProtoLog logging system.
*/
public class PerfettoProtoLogImpl implements IProtoLog {
private static final String LOG_TAG = "ProtoLog";
+ public static final String NULL_STRING = "null";
private final AtomicInteger mTracingInstances = new AtomicInteger();
private final ProtoLogDataSource mDataSource = new ProtoLogDataSource(
this::onTracingInstanceStart,
- this::dumpTransitionTraceConfig,
+ this::onTracingFlush,
this::onTracingInstanceStop
);
+ @Nullable
private final ProtoLogViewerConfigReader mViewerConfigReader;
private final ViewerConfigInputStreamProvider mViewerConfigInputStreamProvider;
- private final TreeMap<String, IProtoLogGroup> mLogGroups;
+ private final TreeMap<String, IProtoLogGroup> mLogGroups = new TreeMap<>();
private final Runnable mCacheUpdater;
- private final Map<LogLevel, Integer> mDefaultLogLevelCounts = new ArrayMap<>();
- private final Map<IProtoLogGroup, Map<LogLevel, Integer>> mLogLevelCounts = new ArrayMap<>();
+ private final int[] mDefaultLogLevelCounts = new int[LogLevel.values().length];
+ private final Map<String, int[]> mLogLevelCounts = new ArrayMap<>();
+ private final Map<String, Integer> mCollectStackTraceGroupCounts = new ArrayMap<>();
- private final ExecutorService mBackgroundLoggingService = Executors.newSingleThreadExecutor();
+ private final Lock mBackgroundServiceLock = new ReentrantLock();
+ private ExecutorService mBackgroundLoggingService = Executors.newSingleThreadExecutor();
- public PerfettoProtoLogImpl(String viewerConfigFilePath,
- TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
+ public PerfettoProtoLogImpl(String viewerConfigFilePath, Runnable cacheUpdater) {
this(() -> {
try {
return new ProtoInputStream(new FileInputStream(viewerConfigFilePath));
@@ -110,24 +119,26 @@ public class PerfettoProtoLogImpl implements IProtoLog {
Slog.w(LOG_TAG, "Failed to load viewer config file " + viewerConfigFilePath, e);
return null;
}
- }, logGroups, cacheUpdater);
+ }, cacheUpdater);
+ }
+
+ public PerfettoProtoLogImpl() {
+ this(null, null, () -> {});
}
public PerfettoProtoLogImpl(
- ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
- TreeMap<String, IProtoLogGroup> logGroups,
+ @Nullable ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
Runnable cacheUpdater
) {
this(viewerConfigInputStreamProvider,
- new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider), logGroups,
+ new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider),
cacheUpdater);
}
@VisibleForTesting
public PerfettoProtoLogImpl(
- ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
- ProtoLogViewerConfigReader viewerConfigReader,
- TreeMap<String, IProtoLogGroup> logGroups,
+ @Nullable ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
+ @Nullable ProtoLogViewerConfigReader viewerConfigReader,
Runnable cacheUpdater
) {
Producer.init(InitArguments.DEFAULTS);
@@ -140,7 +151,6 @@ public class PerfettoProtoLogImpl implements IProtoLog {
mDataSource.register(params);
this.mViewerConfigInputStreamProvider = viewerConfigInputStreamProvider;
this.mViewerConfigReader = viewerConfigReader;
- this.mLogGroups = logGroups;
this.mCacheUpdater = cacheUpdater;
}
@@ -149,23 +159,182 @@ public class PerfettoProtoLogImpl implements IProtoLog {
*/
@VisibleForTesting
@Override
- public void log(LogLevel level, IProtoLogGroup group, long messageHash, int paramsMask,
- @Nullable String messageString, Object[] args) {
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "log");
+ public void log(LogLevel logLevel, IProtoLogGroup group, long messageHash, int paramsMask,
+ @Nullable Object[] args) {
+ log(logLevel, group, new Message(messageHash, paramsMask), args);
+ }
- long tsNanos = SystemClock.elapsedRealtimeNanos();
- try {
- mBackgroundLoggingService.submit(() ->
- logToProto(level, group.name(), messageHash, paramsMask, args, tsNanos));
- if (group.isLogToLogcat()) {
- logToLogcat(group.getTag(), level, messageHash, messageString, args);
+ @Override
+ public void log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object... args) {
+ log(logLevel, group, new Message(messageString), args);
+ }
+
+ /**
+ * SLog wrapper.
+ */
+ @VisibleForTesting
+ public void passToLogcat(String tag, LogLevel level, String message) {
+ switch (level) {
+ case DEBUG:
+ Slog.d(tag, message);
+ break;
+ case VERBOSE:
+ Slog.v(tag, message);
+ break;
+ case INFO:
+ Slog.i(tag, message);
+ break;
+ case WARN:
+ Slog.w(tag, message);
+ break;
+ case ERROR:
+ Slog.e(tag, message);
+ break;
+ case WTF:
+ Slog.wtf(tag, message);
+ break;
+ }
+ }
+
+ /**
+ * Returns {@code true} iff logging to proto is enabled.
+ */
+ public boolean isProtoEnabled() {
+ return mTracingInstances.get() > 0;
+ }
+
+ /**
+ * Start text logging
+ * @param groups Groups to start text logging for
+ * @param logger A logger to write status updates to
+ * @return status code
+ */
+ public int startLoggingToLogcat(String[] groups, ILogger logger) {
+ if (mViewerConfigReader != null) {
+ mViewerConfigReader.loadViewerConfig(groups, logger);
+ }
+ return setTextLogging(true, logger, groups);
+ }
+
+ /**
+ * Stop text logging
+ * @param groups Groups to start text logging for
+ * @param logger A logger to write status updates to
+ * @return status code
+ */
+ public int stopLoggingToLogcat(String[] groups, ILogger logger) {
+ if (mViewerConfigReader != null) {
+ mViewerConfigReader.unloadViewerConfig(groups, logger);
+ }
+ return setTextLogging(false, logger, groups);
+ }
+
+ @Override
+ public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
+ final int[] groupLevelCount = mLogLevelCounts.get(group.name());
+ return (groupLevelCount == null && mDefaultLogLevelCounts[level.ordinal()] > 0)
+ || (groupLevelCount != null && groupLevelCount[level.ordinal()] > 0)
+ || group.isLogToLogcat();
+ }
+
+ @Override
+ public void registerGroups(IProtoLogGroup... protoLogGroups) {
+ for (IProtoLogGroup protoLogGroup : protoLogGroups) {
+ mLogGroups.put(protoLogGroup.name(), protoLogGroup);
+ }
+ }
+
+ /**
+ * Responds to a shell command.
+ */
+ public int onShellCommand(ShellCommand shell) {
+ PrintWriter pw = shell.getOutPrintWriter();
+ String cmd = shell.getNextArg();
+ if (cmd == null) {
+ return unknownCommand(pw);
+ }
+ ArrayList<String> args = new ArrayList<>();
+ String arg;
+ while ((arg = shell.getNextArg()) != null) {
+ args.add(arg);
+ }
+ final ILogger logger = (msg) -> logAndPrintln(pw, msg);
+ String[] groups = args.toArray(new String[0]);
+ switch (cmd) {
+ case "start", "stop" -> {
+ pw.println("Command not supported. "
+ + "Please start and stop ProtoLog tracing with Perfetto.");
+ return -1;
+ }
+ case "enable-text" -> {
+ if (mViewerConfigReader != null) {
+ mViewerConfigReader.loadViewerConfig(groups, logger);
+ }
+ return setTextLogging(true, logger, groups);
+ }
+ case "disable-text" -> {
+ return setTextLogging(false, logger, groups);
+ }
+ default -> {
+ return unknownCommand(pw);
+ }
+ }
+ }
+
+ private void log(LogLevel logLevel, IProtoLogGroup group, Message message,
+ @Nullable Object[] args) {
+ if (isProtoEnabled()) {
+ long tsNanos = SystemClock.elapsedRealtimeNanos();
+ final String stacktrace;
+ if (mCollectStackTraceGroupCounts.getOrDefault(group.name(), 0) > 0) {
+ stacktrace = collectStackTrace();
+ } else {
+ stacktrace = null;
+ }
+ try {
+ mBackgroundServiceLock.lock();
+ mBackgroundLoggingService.execute(() ->
+ logToProto(logLevel, group, message, args, tsNanos,
+ stacktrace));
+ } finally {
+ mBackgroundServiceLock.unlock();
}
+ }
+ if (group.isLogToLogcat()) {
+ logToLogcat(group.getTag(), logLevel, message, args);
+ }
+ }
+
+ private void onTracingFlush() {
+ final ExecutorService loggingService;
+ try {
+ mBackgroundServiceLock.lock();
+ loggingService = mBackgroundLoggingService;
+ mBackgroundLoggingService = Executors.newSingleThreadExecutor();
} finally {
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ mBackgroundServiceLock.unlock();
+ }
+
+ try {
+ loggingService.shutdown();
+ boolean finished = loggingService.awaitTermination(10, TimeUnit.SECONDS);
+
+ if (!finished) {
+ Log.e(LOG_TAG, "ProtoLog background tracing service didn't finish gracefully.");
+ }
+ } catch (InterruptedException e) {
+ Log.e(LOG_TAG, "Failed to wait for tracing to finish", e);
}
+
+ dumpTransitionTraceConfig();
}
private void dumpTransitionTraceConfig() {
+ if (mViewerConfigInputStreamProvider == null) {
+ // No viewer config available
+ return;
+ }
+
ProtoInputStream pis = mViewerConfigInputStreamProvider.getInputStream();
if (pis == null) {
@@ -256,89 +425,58 @@ public class PerfettoProtoLogImpl implements IProtoLog {
os.end(outMessagesToken);
}
- private void logToLogcat(String tag, LogLevel level, long messageHash,
- @Nullable String messageString, Object[] args) {
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "logToLogcat");
- try {
- doLogToLogcat(tag, level, messageHash, messageString, args);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ private void logToLogcat(String tag, LogLevel level, Message message,
+ @Nullable Object[] args) {
+ String messageString;
+ if (mViewerConfigReader == null) {
+ messageString = message.getMessage();
+ } else {
+ messageString = message.getMessage(mViewerConfigReader);
}
- }
- private void doLogToLogcat(String tag, LogLevel level, long messageHash,
- @androidx.annotation.Nullable String messageString, Object[] args) {
- String message = null;
if (messageString == null) {
- messageString = mViewerConfigReader.getViewerString(messageHash);
- }
- if (messageString != null) {
+ StringBuilder builder = new StringBuilder("UNKNOWN MESSAGE");
if (args != null) {
- try {
- message = TextUtils.formatSimple(messageString, args);
- } catch (Exception ex) {
- Slog.w(LOG_TAG, "Invalid ProtoLog format string.", ex);
- }
- } else {
- message = messageString;
- }
- }
- if (message == null) {
- StringBuilder builder = new StringBuilder("UNKNOWN MESSAGE (" + messageHash + ")");
- for (Object o : args) {
- builder.append(" ").append(o);
+ builder.append(" args = (");
+ builder.append(String.join(", ", Arrays.stream(args)
+ .map(it -> {
+ if (it == null) {
+ return "null";
+ } else {
+ return it.toString();
+ }
+ }).toList()));
+ builder.append(")");
}
- message = builder.toString();
+ messageString = builder.toString();
+ args = new Object[0];
}
- passToLogcat(tag, level, message);
- }
- /**
- * SLog wrapper.
- */
- @VisibleForTesting
- public void passToLogcat(String tag, LogLevel level, String message) {
- switch (level) {
- case DEBUG:
- Slog.d(tag, message);
- break;
- case VERBOSE:
- Slog.v(tag, message);
- break;
- case INFO:
- Slog.i(tag, message);
- break;
- case WARN:
- Slog.w(tag, message);
- break;
- case ERROR:
- Slog.e(tag, message);
- break;
- case WTF:
- Slog.wtf(tag, message);
- break;
- }
+ logToLogcat(tag, level, messageString, args);
}
- private void logToProto(LogLevel level, String groupName, long messageHash, int paramsMask,
- Object[] args, long tsNanos) {
- if (!isProtoEnabled()) {
- return;
- }
-
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "logToProto");
- try {
- doLogToProto(level, groupName, messageHash, paramsMask, args, tsNanos);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ private void logToLogcat(String tag, LogLevel level, String messageString,
+ @Nullable Object[] args) {
+ String message;
+ if (args != null) {
+ try {
+ message = TextUtils.formatSimple(messageString, args);
+ } catch (IllegalArgumentException e) {
+ message = "FORMAT_ERROR \"" + messageString + "\", args=("
+ + String.join(
+ ", ", Arrays.stream(args).map(Object::toString).toList()) + ")";
+ }
+ } else {
+ message = messageString;
}
+ passToLogcat(tag, level, message);
}
- private void doLogToProto(LogLevel level, String groupName, long messageHash, int paramsMask,
- Object[] args, long tsNanos) {
+ private void logToProto(LogLevel level, IProtoLogGroup logGroup, Message message, Object[] args,
+ long tsNanos, @Nullable String stacktrace) {
mDataSource.trace(ctx -> {
final ProtoLogDataSource.TlsState tlsState = ctx.getCustomTlsState();
- final LogLevel logFrom = tlsState.getLogFromLevel(groupName);
+ final LogLevel logFrom = tlsState.getLogFromLevel(logGroup.name());
if (level.ordinal() < logFrom.ordinal()) {
return;
@@ -350,29 +488,43 @@ public class PerfettoProtoLogImpl implements IProtoLog {
// trace processing easier.
int argIndex = 0;
for (Object o : args) {
- int type = LogDataType.bitmaskToLogDataType(paramsMask, argIndex);
+ int type = LogDataType.bitmaskToLogDataType(message.getMessageMask(), argIndex);
if (type == LogDataType.STRING) {
- internStringArg(ctx, o.toString());
+ if (o == null) {
+ internStringArg(ctx, NULL_STRING);
+ } else {
+ internStringArg(ctx, o.toString());
+ }
}
argIndex++;
}
}
int internedStacktrace = 0;
- if (tlsState.getShouldCollectStacktrace(groupName)) {
+ if (tlsState.getShouldCollectStacktrace(logGroup.name())) {
// Intern stackstraces before creating the trace packet for the proto message so
// that the interned stacktrace strings appear before in the trace to make the
// trace processing easier.
- String stacktrace = collectStackTrace();
internedStacktrace = internStacktraceString(ctx, stacktrace);
}
+ boolean needsIncrementalState = false;
+
+ long messageHash = 0;
+ if (message.mMessageHash != null) {
+ messageHash = message.mMessageHash;
+ }
+ if (message.mMessageString != null) {
+ needsIncrementalState = true;
+ messageHash =
+ internProtoMessage(ctx, level, logGroup, message.mMessageString);
+ }
+
final ProtoOutputStream os = ctx.newTracePacket();
os.write(TIMESTAMP, tsNanos);
long token = os.start(PROTOLOG_MESSAGE);
- os.write(MESSAGE_ID, messageHash);
- boolean needsIncrementalState = false;
+ os.write(MESSAGE_ID, messageHash);
if (args != null) {
@@ -381,22 +533,39 @@ public class PerfettoProtoLogImpl implements IProtoLog {
ArrayList<Double> doubleParams = new ArrayList<>();
ArrayList<Boolean> booleanParams = new ArrayList<>();
for (Object o : args) {
- int type = LogDataType.bitmaskToLogDataType(paramsMask, argIndex);
+ int type = LogDataType.bitmaskToLogDataType(message.getMessageMask(), argIndex);
try {
switch (type) {
case LogDataType.STRING:
- final int internedStringId = internStringArg(ctx, o.toString());
+ final int internedStringId;
+ if (o == null) {
+ internedStringId = internStringArg(ctx, NULL_STRING);
+ } else {
+ internedStringId = internStringArg(ctx, o.toString());
+ }
os.write(STR_PARAM_IIDS, internedStringId);
needsIncrementalState = true;
break;
case LogDataType.LONG:
- longParams.add(((Number) o).longValue());
+ if (o == null) {
+ longParams.add(0);
+ } else {
+ longParams.add(((Number) o).longValue());
+ }
break;
case LogDataType.DOUBLE:
- doubleParams.add(((Number) o).doubleValue());
+ if (o == null) {
+ doubleParams.add(0d);
+ } else {
+ doubleParams.add(((Number) o).doubleValue());
+ }
break;
case LogDataType.BOOLEAN:
- booleanParams.add((boolean) o);
+ if (o == null) {
+ booleanParams.add(false);
+ } else {
+ booleanParams.add((boolean) o);
+ }
break;
}
} catch (ClassCastException ex) {
@@ -414,7 +583,7 @@ public class PerfettoProtoLogImpl implements IProtoLog {
booleanParams.forEach(it -> os.write(BOOLEAN_PARAMS, it ? 1 : 0));
}
- if (tlsState.getShouldCollectStacktrace(groupName)) {
+ if (tlsState.getShouldCollectStacktrace(logGroup.name())) {
os.write(STACKTRACE_IID, internedStacktrace);
}
@@ -427,6 +596,63 @@ public class PerfettoProtoLogImpl implements IProtoLog {
});
}
+ private long internProtoMessage(
+ TracingContext<ProtoLogDataSource.Instance, ProtoLogDataSource.TlsState,
+ ProtoLogDataSource.IncrementalState> ctx, LogLevel level,
+ IProtoLogGroup logGroup, String message) {
+ final ProtoLogDataSource.IncrementalState incrementalState = ctx.getIncrementalState();
+
+ if (!incrementalState.clearReported) {
+ final ProtoOutputStream os = ctx.newTracePacket();
+ os.write(SEQUENCE_FLAGS, SEQ_INCREMENTAL_STATE_CLEARED);
+ incrementalState.clearReported = true;
+ }
+
+
+ if (!incrementalState.protologGroupInterningSet.contains(logGroup.getId())) {
+ incrementalState.protologGroupInterningSet.add(logGroup.getId());
+
+ final ProtoOutputStream os = ctx.newTracePacket();
+ final long protologViewerConfigToken = os.start(PROTOLOG_VIEWER_CONFIG);
+ final long groupConfigToken = os.start(GROUPS);
+
+ os.write(ID, logGroup.getId());
+ os.write(NAME, logGroup.name());
+ os.write(TAG, logGroup.getTag());
+
+ os.end(groupConfigToken);
+ os.end(protologViewerConfigToken);
+ }
+
+ final Long messageHash = hash(level, logGroup.name(), message);
+ if (!incrementalState.protologMessageInterningSet.contains(messageHash)) {
+ incrementalState.protologMessageInterningSet.add(messageHash);
+
+ final ProtoOutputStream os = ctx.newTracePacket();
+ final long protologViewerConfigToken = os.start(PROTOLOG_VIEWER_CONFIG);
+ final long messageConfigToken = os.start(MESSAGES);
+
+ os.write(MessageData.MESSAGE_ID, messageHash);
+ os.write(MESSAGE, message);
+ os.write(LEVEL, level.ordinal());
+ os.write(GROUP_ID, logGroup.getId());
+
+ os.end(messageConfigToken);
+ os.end(protologViewerConfigToken);
+ }
+
+ return messageHash;
+ }
+
+ private Long hash(
+ LogLevel logLevel,
+ String logGroup,
+ String messageString
+ ) {
+ final String fullStringIdentifier = messageString + logLevel + logGroup;
+ return UUID.nameUUIDFromBytes(fullStringIdentifier.getBytes()).getMostSignificantBits();
+ }
+
private static final int STACK_SIZE_TO_PROTO_LOG_ENTRY_CALL = 12;
private String collectStackTrace() {
@@ -466,7 +692,7 @@ public class PerfettoProtoLogImpl implements IProtoLog {
ProtoLogDataSource.IncrementalState> ctx,
Map<String, Integer> internMap,
long fieldId,
- String string
+ @NonNull String string
) {
final ProtoLogDataSource.IncrementalState incrementalState = ctx.getIncrementalState();
@@ -492,74 +718,6 @@ public class PerfettoProtoLogImpl implements IProtoLog {
return internMap.get(string);
}
- /**
- * Returns {@code true} iff logging to proto is enabled.
- */
- public boolean isProtoEnabled() {
- return mTracingInstances.get() > 0;
- }
-
- /**
- * Start text logging
- * @param groups Groups to start text logging for
- * @param logger A logger to write status updates to
- * @return status code
- */
- public int startLoggingToLogcat(String[] groups, ILogger logger) {
- mViewerConfigReader.loadViewerConfig(logger);
- return setTextLogging(true, logger, groups);
- }
-
- /**
- * Stop text logging
- * @param groups Groups to start text logging for
- * @param logger A logger to write status updates to
- * @return status code
- */
- public int stopLoggingToLogcat(String[] groups, ILogger logger) {
- mViewerConfigReader.unloadViewerConfig();
- return setTextLogging(false, logger, groups);
- }
-
- @Override
- public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
- return group.isLogToLogcat() || getLogFromLevel(group).ordinal() <= level.ordinal();
- }
-
- private LogLevel getLogFromLevel(IProtoLogGroup group) {
- if (mLogLevelCounts.containsKey(group)) {
- for (LogLevel logLevel : LogLevel.values()) {
- if (mLogLevelCounts.get(group).getOrDefault(logLevel, 0) > 0) {
- return logLevel;
- }
- }
- } else {
- for (LogLevel logLevel : LogLevel.values()) {
- if (mDefaultLogLevelCounts.getOrDefault(logLevel, 0) > 0) {
- return logLevel;
- }
- }
- }
-
- return LogLevel.WTF;
- }
-
- /**
- * Start logging the stack trace of the when the log message happened for target groups
- * @return status code
- */
- public int startLoggingStackTrace(String[] groups, ILogger logger) {
- return -1;
- }
-
- /**
- * Stop logging the stack trace of the when the log message happened for target groups
- * @return status code
- */
- public int stopLoggingStackTrace() {
- return -1;
- }
-
private int setTextLogging(boolean value, ILogger logger, String... groups) {
for (int i = 0; i < groups.length; i++) {
String group = groups[i];
@@ -576,41 +734,6 @@ public class PerfettoProtoLogImpl implements IProtoLog {
return 0;
}
- /**
- * Responds to a shell command.
- */
- public int onShellCommand(ShellCommand shell) {
- PrintWriter pw = shell.getOutPrintWriter();
- String cmd = shell.getNextArg();
- if (cmd == null) {
- return unknownCommand(pw);
- }
- ArrayList<String> args = new ArrayList<>();
- String arg;
- while ((arg = shell.getNextArg()) != null) {
- args.add(arg);
- }
- final ILogger logger = (msg) -> logAndPrintln(pw, msg);
- String[] groups = args.toArray(new String[0]);
- switch (cmd) {
- case "start", "stop" -> {
- pw.println("Command not supported. "
- + "Please start and stop ProtoLog tracing with Perfetto.");
- return -1;
- }
- case "enable-text" -> {
- mViewerConfigReader.loadViewerConfig(logger);
- return setTextLogging(true, logger, groups);
- }
- case "disable-text" -> {
- return setTextLogging(false, logger, groups);
- }
- default -> {
- return unknownCommand(pw);
- }
- }
- }
-
private int unknownCommand(PrintWriter pw) {
pw.println("Unknown command");
pw.println("Window manager logging options:");
@@ -620,66 +743,113 @@ public class PerfettoProtoLogImpl implements IProtoLog {
}
private synchronized void onTracingInstanceStart(ProtoLogDataSource.ProtoLogConfig config) {
- this.mTracingInstances.incrementAndGet();
-
final LogLevel defaultLogFrom = config.getDefaultGroupConfig().logFrom;
- mDefaultLogLevelCounts.put(defaultLogFrom,
- mDefaultLogLevelCounts.getOrDefault(defaultLogFrom, 0) + 1);
+ for (int i = defaultLogFrom.ordinal(); i < LogLevel.values().length; i++) {
+ mDefaultLogLevelCounts[i]++;
+ }
final Set<String> overriddenGroupTags = config.getGroupTagsWithOverriddenConfigs();
for (String overriddenGroupTag : overriddenGroupTags) {
- IProtoLogGroup group = mLogGroups.get(overriddenGroupTag);
-
- mLogLevelCounts.putIfAbsent(group, new ArrayMap<>());
- final Map<LogLevel, Integer> logLevelsCountsForGroup = mLogLevelCounts.get(group);
+ mLogLevelCounts.putIfAbsent(overriddenGroupTag, new int[LogLevel.values().length]);
+ final int[] logLevelsCountsForGroup = mLogLevelCounts.get(overriddenGroupTag);
final LogLevel logFromLevel = config.getConfigFor(overriddenGroupTag).logFrom;
- logLevelsCountsForGroup.put(logFromLevel,
- logLevelsCountsForGroup.getOrDefault(logFromLevel, 0) + 1);
+ for (int i = logFromLevel.ordinal(); i < LogLevel.values().length; i++) {
+ logLevelsCountsForGroup[i]++;
+ }
+
+ if (config.getConfigFor(overriddenGroupTag).collectStackTrace) {
+ mCollectStackTraceGroupCounts.put(overriddenGroupTag,
+ mCollectStackTraceGroupCounts.getOrDefault(overriddenGroupTag, 0) + 1);
+ }
+
+ if (config.getConfigFor(overriddenGroupTag).collectStackTrace) {
+ mCollectStackTraceGroupCounts.put(overriddenGroupTag,
+ mCollectStackTraceGroupCounts.getOrDefault(overriddenGroupTag, 0) + 1);
+ }
}
mCacheUpdater.run();
+
+ this.mTracingInstances.incrementAndGet();
}
private synchronized void onTracingInstanceStop(ProtoLogDataSource.ProtoLogConfig config) {
this.mTracingInstances.decrementAndGet();
final LogLevel defaultLogFrom = config.getDefaultGroupConfig().logFrom;
- mDefaultLogLevelCounts.put(defaultLogFrom,
- mDefaultLogLevelCounts.get(defaultLogFrom) - 1);
- if (mDefaultLogLevelCounts.get(defaultLogFrom) <= 0) {
- mDefaultLogLevelCounts.remove(defaultLogFrom);
+ for (int i = defaultLogFrom.ordinal(); i < LogLevel.values().length; i++) {
+ mDefaultLogLevelCounts[i]--;
}
final Set<String> overriddenGroupTags = config.getGroupTagsWithOverriddenConfigs();
for (String overriddenGroupTag : overriddenGroupTags) {
- IProtoLogGroup group = mLogGroups.get(overriddenGroupTag);
-
- mLogLevelCounts.putIfAbsent(group, new ArrayMap<>());
- final Map<LogLevel, Integer> logLevelsCountsForGroup = mLogLevelCounts.get(group);
+ final int[] logLevelsCountsForGroup = mLogLevelCounts.get(overriddenGroupTag);
final LogLevel logFromLevel = config.getConfigFor(overriddenGroupTag).logFrom;
- logLevelsCountsForGroup.put(logFromLevel,
- logLevelsCountsForGroup.get(logFromLevel) - 1);
- if (logLevelsCountsForGroup.get(logFromLevel) <= 0) {
- logLevelsCountsForGroup.remove(logFromLevel);
+ for (int i = logFromLevel.ordinal(); i < LogLevel.values().length; i++) {
+ logLevelsCountsForGroup[i]--;
+ }
+ if (Arrays.stream(logLevelsCountsForGroup).allMatch(it -> it == 0)) {
+ mLogLevelCounts.remove(overriddenGroupTag);
}
- if (logLevelsCountsForGroup.isEmpty()) {
- mLogLevelCounts.remove(group);
+
+ if (config.getConfigFor(overriddenGroupTag).collectStackTrace) {
+ mCollectStackTraceGroupCounts.put(overriddenGroupTag,
+ mCollectStackTraceGroupCounts.get(overriddenGroupTag) - 1);
+
+ if (mCollectStackTraceGroupCounts.get(overriddenGroupTag) == 0) {
+ mCollectStackTraceGroupCounts.remove(overriddenGroupTag);
+ }
}
}
mCacheUpdater.run();
}
- static void logAndPrintln(@Nullable PrintWriter pw, String msg) {
+ private static void logAndPrintln(@Nullable PrintWriter pw, String msg) {
Slog.i(LOG_TAG, msg);
if (pw != null) {
pw.println(msg);
pw.flush();
}
}
+
+ private static class Message {
+ private final Long mMessageHash;
+ private final Integer mMessageMask;
+ private final String mMessageString;
+
+ private Message(Long messageHash, int messageMask) {
+ this.mMessageHash = messageHash;
+ this.mMessageMask = messageMask;
+ this.mMessageString = null;
+ }
+
+ private Message(String messageString) {
+ this.mMessageHash = null;
+ final List<Integer> argTypes = LogDataType.parseFormatString(messageString);
+ this.mMessageMask = LogDataType.logDataTypesToBitMask(argTypes);
+ this.mMessageString = messageString;
+ }
+
+ private int getMessageMask() {
+ return mMessageMask;
+ }
+
+ private String getMessage() {
+ return mMessageString;
+ }
+
+ private String getMessage(@NonNull ProtoLogViewerConfigReader viewerConfigReader) {
+ if (mMessageString != null) {
+ return mMessageString;
+ }
+
+ return viewerConfigReader.getViewerString(mMessageHash);
+ }
+ }
}
diff --git a/core/java/com/android/internal/protolog/ProtoLog.java b/core/java/com/android/internal/protolog/ProtoLog.java
index 0118c056d682..87678e5922f9 100644
--- a/core/java/com/android/internal/protolog/ProtoLog.java
+++ b/core/java/com/android/internal/protolog/ProtoLog.java
@@ -44,21 +44,23 @@ public class ProtoLog {
// LINT.ThenChange(frameworks/base/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt)
// Needs to be set directly otherwise the protologtool tries to transform the method call
+ @Deprecated
public static boolean REQUIRE_PROTOLOGTOOL = true;
+ private static IProtoLog sProtoLogInstance;
+
/**
* DEBUG level log.
*
* @param group {@code IProtoLogGroup} controlling this log call.
* @param messageString constant format string for the logged message.
* @param args parameters to be used with the format string.
+ *
+ * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+ * executed. Check generated code for actual call.
*/
public static void d(IProtoLogGroup group, String messageString, Object... args) {
- // Stub, replaced by the ProtoLogTool.
- if (REQUIRE_PROTOLOGTOOL) {
- throw new UnsupportedOperationException(
- "ProtoLog calls MUST be processed with ProtoLogTool");
- }
+ logStringMessage(LogLevel.DEBUG, group, messageString, args);
}
/**
@@ -67,13 +69,12 @@ public class ProtoLog {
* @param group {@code IProtoLogGroup} controlling this log call.
* @param messageString constant format string for the logged message.
* @param args parameters to be used with the format string.
+ *
+ * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+ * executed. Check generated code for actual call.
*/
public static void v(IProtoLogGroup group, String messageString, Object... args) {
- // Stub, replaced by the ProtoLogTool.
- if (REQUIRE_PROTOLOGTOOL) {
- throw new UnsupportedOperationException(
- "ProtoLog calls MUST be processed with ProtoLogTool");
- }
+ logStringMessage(LogLevel.VERBOSE, group, messageString, args);
}
/**
@@ -82,13 +83,12 @@ public class ProtoLog {
* @param group {@code IProtoLogGroup} controlling this log call.
* @param messageString constant format string for the logged message.
* @param args parameters to be used with the format string.
+ *
+ * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+ * executed. Check generated code for actual call.
*/
public static void i(IProtoLogGroup group, String messageString, Object... args) {
- // Stub, replaced by the ProtoLogTool.
- if (REQUIRE_PROTOLOGTOOL) {
- throw new UnsupportedOperationException(
- "ProtoLog calls MUST be processed with ProtoLogTool");
- }
+ logStringMessage(LogLevel.INFO, group, messageString, args);
}
/**
@@ -97,13 +97,12 @@ public class ProtoLog {
* @param group {@code IProtoLogGroup} controlling this log call.
* @param messageString constant format string for the logged message.
* @param args parameters to be used with the format string.
+ *
+ * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+ * executed. Check generated code for actual call.
*/
public static void w(IProtoLogGroup group, String messageString, Object... args) {
- // Stub, replaced by the ProtoLogTool.
- if (REQUIRE_PROTOLOGTOOL) {
- throw new UnsupportedOperationException(
- "ProtoLog calls MUST be processed with ProtoLogTool");
- }
+ logStringMessage(LogLevel.WARN, group, messageString, args);
}
/**
@@ -112,13 +111,12 @@ public class ProtoLog {
* @param group {@code IProtoLogGroup} controlling this log call.
* @param messageString constant format string for the logged message.
* @param args parameters to be used with the format string.
+ *
+ * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+ * executed. Check generated code for actual call.
*/
public static void e(IProtoLogGroup group, String messageString, Object... args) {
- // Stub, replaced by the ProtoLogTool.
- if (REQUIRE_PROTOLOGTOOL) {
- throw new UnsupportedOperationException(
- "ProtoLog calls MUST be processed with ProtoLogTool");
- }
+ logStringMessage(LogLevel.ERROR, group, messageString, args);
}
/**
@@ -127,13 +125,12 @@ public class ProtoLog {
* @param group {@code IProtoLogGroup} controlling this log call.
* @param messageString constant format string for the logged message.
* @param args parameters to be used with the format string.
+ *
+ * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+ * executed. Check generated code for actual call.
*/
public static void wtf(IProtoLogGroup group, String messageString, Object... args) {
- // Stub, replaced by the ProtoLogTool.
- if (REQUIRE_PROTOLOGTOOL) {
- throw new UnsupportedOperationException(
- "ProtoLog calls MUST be processed with ProtoLogTool");
- }
+ logStringMessage(LogLevel.WTF, group, messageString, args);
}
/**
@@ -142,11 +139,7 @@ public class ProtoLog {
* @return true iff this is being logged.
*/
public static boolean isEnabled(IProtoLogGroup group, LogLevel level) {
- if (REQUIRE_PROTOLOGTOOL) {
- throw new UnsupportedOperationException(
- "ProtoLog calls MUST be processed with ProtoLogTool");
- }
- return false;
+ return sProtoLogInstance.isEnabled(group, level);
}
/**
@@ -154,10 +147,36 @@ public class ProtoLog {
* @return A singleton instance of ProtoLog.
*/
public static IProtoLog getSingleInstance() {
- if (REQUIRE_PROTOLOGTOOL) {
- throw new UnsupportedOperationException(
- "ProtoLog calls MUST be processed with ProtoLogTool");
+ return sProtoLogInstance;
+ }
+
+ /**
+ * Registers available protolog groups. A group must be registered before it can be used.
+ * @param protoLogGroups The groups to register for use in protolog.
+ */
+ public static void registerGroups(IProtoLogGroup... protoLogGroups) {
+ sProtoLogInstance.registerGroups(protoLogGroups);
+ }
+
+ private static void logStringMessage(LogLevel logLevel, IProtoLogGroup group,
+ String stringMessage, Object... args) {
+ if (sProtoLogInstance == null) {
+ throw new IllegalStateException(
+ "Trying to use ProtoLog before it is initialized in this process.");
+ }
+
+ if (sProtoLogInstance.isEnabled(group, logLevel)) {
+ sProtoLogInstance.log(logLevel, group, stringMessage, args);
+ }
+ }
+
+ static {
+ if (android.tracing.Flags.perfettoProtologTracing()) {
+ sProtoLogInstance = new PerfettoProtoLogImpl();
+ } else {
+ // The first call to ProtoLog is likely to flip REQUIRE_PROTOLOGTOOL, which is when this
+ // static block will be executed before REQUIRE_PROTOLOGTOOL is actually set.
+ sProtoLogInstance = new LogcatOnlyProtoLogImpl();
}
- return null;
}
}
diff --git a/core/java/com/android/internal/protolog/ProtoLogDataSource.java b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
index 6ab79b92784e..84f3237142b8 100644
--- a/core/java/com/android/internal/protolog/ProtoLogDataSource.java
+++ b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
@@ -40,6 +40,7 @@ import com.android.internal.protolog.common.LogLevel;
import java.io.IOException;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
@@ -138,6 +139,8 @@ public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
}
public static class IncrementalState {
+ public final Set<Integer> protologGroupInterningSet = new HashSet<>();
+ public final Set<Long> protologMessageInterningSet = new HashSet<>();
public final Map<String, Integer> argumentInterningMap = new HashMap<>();
public final Map<String, Integer> stacktraceInterningMap = new HashMap<>();
public boolean clearReported = false;
diff --git a/core/java/com/android/internal/protolog/ProtoLogImpl.java b/core/java/com/android/internal/protolog/ProtoLogImpl.java
index 6d142afce626..3082295a522c 100644
--- a/core/java/com/android/internal/protolog/ProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/ProtoLogImpl.java
@@ -54,48 +54,33 @@ public class ProtoLogImpl {
private static Runnable sCacheUpdater;
/** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
- public static void d(IProtoLogGroup group, long messageHash, int paramsMask,
- @Nullable String messageString,
- Object... args) {
- getSingleInstance()
- .log(LogLevel.DEBUG, group, messageHash, paramsMask, messageString, args);
+ public static void d(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+ getSingleInstance().log(LogLevel.DEBUG, group, messageHash, paramsMask, args);
}
/** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
- public static void v(IProtoLogGroup group, long messageHash, int paramsMask,
- @Nullable String messageString,
- Object... args) {
- getSingleInstance().log(LogLevel.VERBOSE, group, messageHash, paramsMask, messageString,
- args);
+ public static void v(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+ getSingleInstance().log(LogLevel.VERBOSE, group, messageHash, paramsMask, args);
}
/** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
- public static void i(IProtoLogGroup group, long messageHash, int paramsMask,
- @Nullable String messageString,
- Object... args) {
- getSingleInstance().log(LogLevel.INFO, group, messageHash, paramsMask, messageString, args);
+ public static void i(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+ getSingleInstance().log(LogLevel.INFO, group, messageHash, paramsMask, args);
}
/** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
- public static void w(IProtoLogGroup group, long messageHash, int paramsMask,
- @Nullable String messageString,
- Object... args) {
- getSingleInstance().log(LogLevel.WARN, group, messageHash, paramsMask, messageString, args);
+ public static void w(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+ getSingleInstance().log(LogLevel.WARN, group, messageHash, paramsMask, args);
}
/** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
- public static void e(IProtoLogGroup group, long messageHash, int paramsMask,
- @Nullable String messageString,
- Object... args) {
- getSingleInstance()
- .log(LogLevel.ERROR, group, messageHash, paramsMask, messageString, args);
+ public static void e(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+ getSingleInstance().log(LogLevel.ERROR, group, messageHash, paramsMask, args);
}
/** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
- public static void wtf(IProtoLogGroup group, long messageHash, int paramsMask,
- @Nullable String messageString,
- Object... args) {
- getSingleInstance().log(LogLevel.WTF, group, messageHash, paramsMask, messageString, args);
+ public static void wtf(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+ getSingleInstance().log(LogLevel.WTF, group, messageHash, paramsMask, args);
}
/**
@@ -107,18 +92,27 @@ public class ProtoLogImpl {
}
/**
+ * Registers available protolog groups. A group must be registered before it can be used.
+ * @param protoLogGroups The groups to register for use in protolog.
+ */
+ public static void registerGroups(IProtoLogGroup... protoLogGroups) {
+ getSingleInstance().registerGroups(protoLogGroups);
+ }
+
+ /**
* Returns the single instance of the ProtoLogImpl singleton class.
*/
public static synchronized IProtoLog getSingleInstance() {
if (sServiceInstance == null) {
if (android.tracing.Flags.perfettoProtologTracing()) {
- sServiceInstance = new PerfettoProtoLogImpl(
- sViewerConfigPath, sLogGroups, sCacheUpdater);
+ sServiceInstance = new PerfettoProtoLogImpl(sViewerConfigPath, sCacheUpdater);
} else {
sServiceInstance = new LegacyProtoLogImpl(
- sLegacyOutputFilePath, sLegacyViewerConfigPath, sLogGroups, sCacheUpdater);
+ sLegacyOutputFilePath, sLegacyViewerConfigPath, sCacheUpdater);
}
+ IProtoLogGroup[] groups = sLogGroups.values().toArray(new IProtoLogGroup[0]);
+ sServiceInstance.registerGroups(groups);
sCacheUpdater.run();
}
return sServiceInstance;
diff --git a/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java b/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java
index b7b24241c26a..bb6c8b7a9698 100644
--- a/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java
+++ b/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java
@@ -1,20 +1,32 @@
package com.android.internal.protolog;
+import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.GROUPS;
+import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.Group.ID;
+import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.Group.NAME;
+
import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MESSAGES;
import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.MESSAGE;
import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.MESSAGE_ID;
+import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.GROUP_ID;
-import android.util.ArrayMap;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Log;
+import android.util.LongSparseArray;
import android.util.proto.ProtoInputStream;
import com.android.internal.protolog.common.ILogger;
import java.io.IOException;
import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
public class ProtoLogViewerConfigReader {
private final ViewerConfigInputStreamProvider mViewerConfigInputStreamProvider;
- private Map<Long, String> mLogMessageMap = null;
+ private final Map<String, Set<Long>> mGroupHashes = new TreeMap<>();
+ private final LongSparseArray<String> mLogMessageMap = new LongSparseArray<>();
public ProtoLogViewerConfigReader(
ViewerConfigInputStreamProvider viewerConfigInputStreamProvider) {
@@ -26,39 +38,62 @@ public class ProtoLogViewerConfigReader {
* or the viewer config is not loaded into memory.
*/
public synchronized String getViewerString(long messageHash) {
- if (mLogMessageMap != null) {
- return mLogMessageMap.get(messageHash);
- } else {
- return null;
- }
+ return mLogMessageMap.get(messageHash);
+ }
+
+ public synchronized void loadViewerConfig(String[] groups) {
+ loadViewerConfig(groups, (message) -> {});
}
/**
* Loads the viewer config into memory. No-op if already loaded in memory.
*/
- public synchronized void loadViewerConfig(ILogger logger) {
- if (mLogMessageMap != null) {
- return;
- }
+ public synchronized void loadViewerConfig(String[] groups, @NonNull ILogger logger) {
+ for (String group : groups) {
+ if (mGroupHashes.containsKey(group)) {
+ continue;
+ }
+
+ try {
+ Map<Long, String> mappings = loadViewerConfigMappingForGroup(group);
+ mGroupHashes.put(group, mappings.keySet());
+ for (Long key : mappings.keySet()) {
+ mLogMessageMap.put(key, mappings.get(key));
+ }
- try {
- doLoadViewerConfig();
- logger.log("Loaded " + mLogMessageMap.size() + " log definitions");
- } catch (IOException e) {
- logger.log("Unable to load log definitions: "
- + "IOException while processing viewer config" + e);
+ logger.log("Loaded " + mLogMessageMap.size() + " log definitions");
+ } catch (IOException e) {
+ logger.log("Unable to load log definitions: "
+ + "IOException while processing viewer config" + e);
+ }
}
}
+ public synchronized void unloadViewerConfig(String[] groups) {
+ unloadViewerConfig(groups, (message) -> {});
+ }
+
/**
* Unload the viewer config from memory.
*/
- public synchronized void unloadViewerConfig() {
- mLogMessageMap = null;
+ public synchronized void unloadViewerConfig(String[] groups, @NonNull ILogger logger) {
+ for (String group : groups) {
+ if (!mGroupHashes.containsKey(group)) {
+ continue;
+ }
+
+ final Set<Long> hashes = mGroupHashes.get(group);
+ for (Long hash : hashes) {
+ logger.log("Unloading viewer config hash " + hash);
+ mLogMessageMap.remove(hash);
+ }
+ }
}
- private void doLoadViewerConfig() throws IOException {
- mLogMessageMap = new ArrayMap<>();
+ private Map<Long, String> loadViewerConfigMappingForGroup(String group) throws IOException {
+ Long targetGroupId = loadGroupId(group);
+
+ final Map<Long, String> hashesForGroup = new TreeMap<>();
final ProtoInputStream pis = mViewerConfigInputStreamProvider.getInputStream();
while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
@@ -67,6 +102,7 @@ public class ProtoLogViewerConfigReader {
long messageId = 0;
String message = null;
+ int groupId = 0;
while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
switch (pis.getFieldNumber()) {
case (int) MESSAGE_ID:
@@ -75,9 +111,16 @@ public class ProtoLogViewerConfigReader {
case (int) MESSAGE:
message = pis.readString(MESSAGE);
break;
+ case (int) GROUP_ID:
+ groupId = pis.readInt(GROUP_ID);
+ break;
}
}
+ if (groupId == 0) {
+ throw new IOException("Failed to get group id");
+ }
+
if (messageId == 0) {
throw new IOException("Failed to get message id");
}
@@ -86,10 +129,45 @@ public class ProtoLogViewerConfigReader {
throw new IOException("Failed to get message string");
}
- mLogMessageMap.put(messageId, message);
+ if (groupId == targetGroupId) {
+ hashesForGroup.put(messageId, message);
+ }
+
+ pis.end(inMessageToken);
+ }
+ }
+
+ return hashesForGroup;
+ }
+
+ private Long loadGroupId(String group) throws IOException {
+ final ProtoInputStream pis = mViewerConfigInputStreamProvider.getInputStream();
+
+ while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+ if (pis.getFieldNumber() == (int) GROUPS) {
+ final long inMessageToken = pis.start(GROUPS);
+
+ long groupId = 0;
+ String groupName = null;
+ while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+ switch (pis.getFieldNumber()) {
+ case (int) ID:
+ groupId = pis.readInt(ID);
+ break;
+ case (int) NAME:
+ groupName = pis.readString(NAME);
+ break;
+ }
+ }
+
+ if (Objects.equals(groupName, group)) {
+ return groupId;
+ }
pis.end(inMessageToken);
}
}
+
+ throw new RuntimeException("Group " + group + "not found in viewer config");
}
}
diff --git a/core/java/com/android/internal/protolog/common/IProtoLog.java b/core/java/com/android/internal/protolog/common/IProtoLog.java
index f72d9f79958d..f5695acd0614 100644
--- a/core/java/com/android/internal/protolog/common/IProtoLog.java
+++ b/core/java/com/android/internal/protolog/common/IProtoLog.java
@@ -27,11 +27,19 @@ public interface IProtoLog {
* @param group The group this message belongs to.
* @param messageHash The hash of the message.
* @param paramsMask The parameters mask of the message.
- * @param messageString The message string.
* @param args The arguments of the message.
*/
void log(LogLevel logLevel, IProtoLogGroup group, long messageHash, int paramsMask,
- String messageString, Object[] args);
+ Object[] args);
+
+ /**
+ * Log a ProtoLog message
+ * @param logLevel Log level of the proto message.
+ * @param group The group this message belongs to.
+ * @param messageString The message string.
+ * @param args The arguments of the message.
+ */
+ void log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object... args);
/**
* Check if ProtoLog is tracing.
@@ -60,4 +68,10 @@ public interface IProtoLog {
* @return If we need to log this group and level to either ProtoLog or Logcat.
*/
boolean isEnabled(IProtoLogGroup group, LogLevel level);
+
+ /**
+ * Registers available protolog groups. A group must be registered before it can be used.
+ * @param protoLogGroups The groups to register for use in protolog.
+ */
+ void registerGroups(IProtoLogGroup... protoLogGroups);
}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 2b3ffeb2e619..cba27ce3fe65 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -135,6 +135,19 @@ interface IInputMethodManager {
+ "android.Manifest.permission.TEST_INPUT_METHOD)")
boolean isInputMethodPickerShownForTest();
+ /**
+ * Called when the IME switch button was clicked from the system. Depending on the number of
+ * enabled IME subtypes, this will either switch to the next IME/subtype, or show the input
+ * method picker dialog.
+ *
+ * @param displayId The ID of the display where the input method picker dialog should be shown.
+ * @param userId The ID of the user that triggered the click.
+ */
+ @EnforcePermission("WRITE_SECURE_SETTINGS")
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ + "android.Manifest.permission.WRITE_SECURE_SETTINGS)")
+ oneway void onImeSwitchButtonClickFromSystem(int displayId);
+
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
@nullable InputMethodSubtype getCurrentInputMethodSubtype(int userId);
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 82367834f93d..511c6802677e 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -109,4 +109,5 @@ interface ILockSettings {
boolean isWeakEscrowTokenActive(long handle, int userId);
boolean isWeakEscrowTokenValid(long handle, in byte[] token, int userId);
void unlockUserKeyIfUnsecured(int userId);
+ boolean writeRepairModeCredential(int userId);
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index e46b8d7c5fae..19c6f51ff9a7 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -22,6 +22,8 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+import static android.security.Flags.reportPrimaryAuthAttempts;
+import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -414,7 +416,9 @@ public class LockPatternUtils {
return;
}
getDevicePolicyManager().reportFailedPasswordAttempt(userId);
- getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
+ if (!reportPrimaryAuthAttempts() || !shouldTrustManagerListenForPrimaryAuth()) {
+ getTrustManager().reportUnlockAttempt(/* authenticated= */ false, userId);
+ }
}
@UnsupportedAppUsage
@@ -423,7 +427,9 @@ public class LockPatternUtils {
return;
}
getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
- getTrustManager().reportUnlockAttempt(true /* authenticated */, userId);
+ if (!reportPrimaryAuthAttempts() || !shouldTrustManagerListenForPrimaryAuth()) {
+ getTrustManager().reportUnlockAttempt(/* authenticated= */ true, userId);
+ }
}
public void reportPasswordLockout(int timeoutMs, int userId) {
@@ -449,6 +455,21 @@ public class LockPatternUtils {
}
/**
+ * Save the current password data to the repair mode file.
+ *
+ * @return true if success or false otherwise.
+ */
+ public boolean writeRepairModeCredential(int userId) {
+ throwIfCalledOnMainThread();
+ try {
+ return getLockSettings().writeRepairModeCredential(userId);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Failed to write repair mode credential", re);
+ return false;
+ }
+ }
+
+ /**
* Check to see if a credential matches the saved one.
* If credential matches, return an opaque attestation that the challenge was verified.
*
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 0734e6827d4d..11c220b14bcc 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -261,6 +261,8 @@ public class LockPatternView extends View {
public float lineEndY = Float.MIN_VALUE;
@Nullable
Animator activationAnimator;
+ @Nullable
+ Animator deactivationAnimator;
}
/**
@@ -667,7 +669,7 @@ public class LockPatternView extends View {
*/
private void resetPattern() {
if (mKeepDotActivated && !mPattern.isEmpty()) {
- resetLastActivatedCellProgress();
+ resetPatternCellSize();
}
mPattern.clear();
mPatternPath.reset();
@@ -676,14 +678,20 @@ public class LockPatternView extends View {
invalidate();
}
- private void resetLastActivatedCellProgress() {
- final ArrayList<Cell> pattern = mPattern;
- final Cell lastCell = pattern.get(pattern.size() - 1);
- final CellState cellState = mCellStates[lastCell.row][lastCell.column];
- if (cellState.activationAnimator != null) {
- cellState.activationAnimator.cancel();
+ private void resetPatternCellSize() {
+ for (int i = 0; i < mCellStates.length; i++) {
+ for (int j = 0; j < mCellStates[i].length; j++) {
+ CellState cellState = mCellStates[i][j];
+ if (cellState.activationAnimator != null) {
+ cellState.activationAnimator.cancel();
+ }
+ if (cellState.deactivationAnimator != null) {
+ cellState.deactivationAnimator.cancel();
+ }
+ cellState.activationAnimationProgress = 0f;
+ cellState.radius = mDotSize / 2f;
+ }
}
- cellState.activationAnimationProgress = 0f;
}
/**
@@ -819,12 +827,16 @@ public class LockPatternView extends View {
!mPatternDrawLookup[fillInGapCell.row][fillInGapCell.column]) {
addCellToPattern(fillInGapCell);
if (mKeepDotActivated) {
- startCellDeactivatedAnimation(fillInGapCell);
+ if (mFadePattern) {
+ startCellDeactivatedAnimation(fillInGapCell, /* fillInGap= */ true);
+ } else {
+ startCellActivatedAnimation(fillInGapCell);
+ }
}
}
if (mKeepDotActivated && lastCell != null) {
- startCellDeactivatedAnimation(lastCell);
+ startCellDeactivatedAnimation(lastCell, /* fillInGap= */ false);
}
addCellToPattern(cell);
@@ -872,17 +884,25 @@ public class LockPatternView extends View {
}
private void startCellActivatedAnimation(Cell cell) {
- startCellActivationAnimation(cell, CELL_ACTIVATE);
+ startCellActivationAnimation(cell, CELL_ACTIVATE, /* fillInGap= */ false);
}
- private void startCellDeactivatedAnimation(Cell cell) {
- startCellActivationAnimation(cell, CELL_DEACTIVATE);
+ private void startCellDeactivatedAnimation(Cell cell, boolean fillInGap) {
+ startCellActivationAnimation(cell, CELL_DEACTIVATE, /* fillInGap= */ fillInGap);
}
- private void startCellActivationAnimation(Cell cell, int activate) {
+ /**
+ * Start cell animation.
+ * @param cell The cell to be animated.
+ * @param activate Whether the cell is being activated or deactivated.
+ * @param fillInGap Whether the cell is a gap cell, i.e. filled in based on current pattern.
+ */
+ private void startCellActivationAnimation(Cell cell, int activate, boolean fillInGap) {
final CellState cellState = mCellStates[cell.row][cell.column];
- if (cellState.activationAnimator != null) {
+ // When mKeepDotActivated is true, don't cancel the previous animator since it would leave
+ // a dot in an in-between size if the next dot is reached before the animation is finished.
+ if (cellState.activationAnimator != null && !mKeepDotActivated) {
cellState.activationAnimator.cancel();
}
AnimatorSet animatorSet = new AnimatorSet();
@@ -898,24 +918,37 @@ public class LockPatternView extends View {
.with(createLineEndAnimation(cellState, startX, startY,
getCenterXForColumn(cell.column), getCenterYForRow(cell.row)));
if (mDotSize != mDotSizeActivated) {
- animatorSetBuilder.with(createDotRadiusAnimation(cellState));
+ animatorSetBuilder.with(createDotRadiusAnimation(cellState, activate, fillInGap));
}
if (mDotColor != mDotActivatedColor) {
- animatorSetBuilder.with(createDotActivationColorAnimation(cellState, activate));
+ animatorSetBuilder.with(
+ createDotActivationColorAnimation(cellState, activate, fillInGap));
}
- animatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- cellState.activationAnimator = null;
- invalidate();
- }
- });
- cellState.activationAnimator = animatorSet;
+ if (activate == CELL_ACTIVATE) {
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ cellState.activationAnimator = null;
+ invalidate();
+ }
+ });
+ cellState.activationAnimator = animatorSet;
+ } else {
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ cellState.deactivationAnimator = null;
+ invalidate();
+ }
+ });
+ cellState.deactivationAnimator = animatorSet;
+ }
animatorSet.start();
}
- private Animator createDotActivationColorAnimation(CellState cellState, int activate) {
+ private Animator createDotActivationColorAnimation(
+ CellState cellState, int activate, boolean fillInGap) {
ValueAnimator.AnimatorUpdateListener updateListener =
valueAnimator -> {
cellState.activationAnimationProgress =
@@ -934,7 +967,7 @@ public class LockPatternView extends View {
deactivateAnimator.setDuration(DOT_ACTIVATION_DURATION_MILLIS);
AnimatorSet set = new AnimatorSet();
- if (mKeepDotActivated) {
+ if (mKeepDotActivated && !fillInGap) {
set.play(activate == CELL_ACTIVATE ? activateAnimator : deactivateAnimator);
} else {
// 'activate' ignored in this case, do full deactivate -> activate cycle
@@ -977,7 +1010,7 @@ public class LockPatternView extends View {
return valueAnimator;
}
- private Animator createDotRadiusAnimation(CellState state) {
+ private Animator createDotRadiusAnimation(CellState state, int activate, boolean fillInGap) {
float defaultRadius = mDotSize / 2f;
float activatedRadius = mDotSizeActivated / 2f;
@@ -998,7 +1031,19 @@ public class LockPatternView extends View {
deactivationAnimator.setDuration(DOT_RADIUS_DECREASE_DURATION_MILLIS);
AnimatorSet set = new AnimatorSet();
- set.playSequentially(activationAnimator, deactivationAnimator);
+ if (mKeepDotActivated) {
+ if (mFadePattern) {
+ if (fillInGap) {
+ set.playSequentially(activationAnimator, deactivationAnimator);
+ } else {
+ set.play(activate == CELL_ACTIVATE ? activationAnimator : deactivationAnimator);
+ }
+ } else if (activate == CELL_ACTIVATE) {
+ set.play(activationAnimator);
+ }
+ } else {
+ set.playSequentially(activationAnimator, deactivationAnimator);
+ }
return set;
}
@@ -1176,9 +1221,15 @@ public class LockPatternView extends View {
// report pattern detected
if (!mPattern.isEmpty()) {
setPatternInProgress(false);
- cancelLineAnimations();
if (mKeepDotActivated) {
+ // When mKeepDotActivated is true, cancelling dot animations and resetting dot radii
+ // are handled in #resetPattern(), since we want to keep the dots activated until
+ // the pattern are reset.
deactivateLastCell();
+ } else {
+ // When mKeepDotActivated is false, cancelling animations and resetting dot radii
+ // are handled here.
+ cancelLineAnimations();
}
notifyPatternDetected();
// Also clear pattern if fading is enabled
@@ -1198,7 +1249,7 @@ public class LockPatternView extends View {
private void deactivateLastCell() {
Cell lastCell = mPattern.get(mPattern.size() - 1);
- startCellDeactivatedAnimation(lastCell);
+ startCellDeactivatedAnimation(lastCell, /* fillInGap= */ false);
}
private void cancelLineAnimations() {
diff --git a/core/java/com/android/internal/widget/NotificationRowIconView.java b/core/java/com/android/internal/widget/NotificationRowIconView.java
index f5f04a7d50d1..98e6e8505534 100644
--- a/core/java/com/android/internal/widget/NotificationRowIconView.java
+++ b/core/java/com/android/internal/widget/NotificationRowIconView.java
@@ -35,8 +35,10 @@ import android.util.AttributeSet;
import android.view.RemotableViewMethod;
import android.widget.RemoteViews;
+import com.android.internal.R;
+
/**
- * An image view that holds the icon displayed on the left side of a notification row.
+ * An image view that holds the icon displayed at the start of a notification row.
*/
@RemoteViews.RemoteView
public class NotificationRowIconView extends CachingIconView {
@@ -98,9 +100,12 @@ public class NotificationRowIconView extends CachingIconView {
setPadding(0, 0, 0, 0);
// Make the background white in case the icon itself doesn't have one.
- int white = Color.rgb(255, 255, 255);
- ColorFilter colorFilter = new PorterDuffColorFilter(white,
+ ColorFilter colorFilter = new PorterDuffColorFilter(Color.WHITE,
PorterDuff.Mode.SRC_ATOP);
+
+ if (mOriginalBackground == null) {
+ setBackground(getContext().getDrawable(R.drawable.notification_icon_circle));
+ }
getBackground().mutate().setColorFilter(colorFilter);
} else {
// Restore original padding and background if needed
diff --git a/core/java/com/android/internal/widget/OWNERS b/core/java/com/android/internal/widget/OWNERS
index e2672f5b03ba..cf2f202a03ac 100644
--- a/core/java/com/android/internal/widget/OWNERS
+++ b/core/java/com/android/internal/widget/OWNERS
@@ -9,18 +9,18 @@ per-file *Lockscreen* = file:/services/core/java/com/android/server/locksettings
per-file *LockSettings* = file:/services/core/java/com/android/server/locksettings/OWNERS
# Notification related
-per-file *Notification* = file:/services/core/java/com/android/server/notification/OWNERS
-per-file *Messaging* = file:/services/core/java/com/android/server/notification/OWNERS
-per-file *Message* = file:/services/core/java/com/android/server/notification/OWNERS
-per-file *Conversation* = file:/services/core/java/com/android/server/notification/OWNERS
-per-file *People* = file:/services/core/java/com/android/server/notification/OWNERS
-per-file *ImageResolver* = file:/services/core/java/com/android/server/notification/OWNERS
-per-file CallLayout.java = file:/services/core/java/com/android/server/notification/OWNERS
-per-file CachingIconView.java = file:/services/core/java/com/android/server/notification/OWNERS
-per-file ImageFloatingTextView.java = file:/services/core/java/com/android/server/notification/OWNERS
-per-file ObservableTextView.java = file:/services/core/java/com/android/server/notification/OWNERS
-per-file RemeasuringLinearLayout.java = file:/services/core/java/com/android/server/notification/OWNERS
-per-file ViewClippingUtil.java = file:/services/core/java/com/android/server/notification/OWNERS
+per-file *Notification* = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+per-file *Messaging* = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+per-file *Message* = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+per-file *Conversation* = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+per-file *People* = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+per-file *ImageResolver* = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+per-file CallLayout.java = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+per-file CachingIconView.java = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+per-file ImageFloatingTextView.java = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+per-file ObservableTextView.java = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+per-file RemeasuringLinearLayout.java = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+per-file ViewClippingUtil.java = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
# Appwidget related
per-file *RemoteViews* = file:/services/appwidget/java/com/android/server/appwidget/OWNERS
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index b8fd3d065d8d..3f74fac35bb7 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -582,8 +582,8 @@ static void android_hardware_Camera_getCameraInfo(JNIEnv *env, jobject thiz, jin
// connect to camera service
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
- jint cameraId, jstring clientPackageName,
- jint rotationOverride, jboolean forceSlowJpegMode,
+ jint cameraId, jint rotationOverride,
+ jboolean forceSlowJpegMode,
jobject jClientAttributionParcel,
jint devicePolicy) {
AttributionSourceState clientAttribution;
@@ -591,16 +591,8 @@ static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobj
return -EACCES;
}
- // Convert jstring to String16
- const char16_t *rawClientName = reinterpret_cast<const char16_t*>(
- env->GetStringChars(clientPackageName, NULL));
- jsize rawClientNameLen = env->GetStringLength(clientPackageName);
- std::string clientName = toStdString(rawClientName, rawClientNameLen);
- env->ReleaseStringChars(clientPackageName,
- reinterpret_cast<const jchar*>(rawClientName));
-
int targetSdkVersion = android_get_application_target_sdk_version();
- sp<Camera> camera = Camera::connect(cameraId, clientName, targetSdkVersion, rotationOverride,
+ sp<Camera> camera = Camera::connect(cameraId, targetSdkVersion, rotationOverride,
forceSlowJpegMode, clientAttribution, devicePolicy);
if (camera == NULL) {
return -EACCES;
@@ -1089,7 +1081,7 @@ static const JNINativeMethod camMethods[] = {
(void *)android_hardware_Camera_getNumberOfCameras},
{"_getCameraInfo", "(IILandroid/os/Parcel;ILandroid/hardware/Camera$CameraInfo;)V",
(void *)android_hardware_Camera_getCameraInfo},
- {"native_setup", "(Ljava/lang/Object;ILjava/lang/String;IZLandroid/os/Parcel;I)I",
+ {"native_setup", "(Ljava/lang/Object;IIZLandroid/os/Parcel;I)I",
(void *)android_hardware_Camera_native_setup},
{"native_release", "()V", (void *)android_hardware_Camera_release},
{"setPreviewSurface", "(Landroid/view/Surface;)V",
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index eaff7608ce3b..c07fd3838837 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2718,12 +2718,11 @@ static jint android_media_AudioSystem_getMaxChannelCount(JNIEnv *env, jobject th
}
static jint android_media_AudioSystem_getMaxSampleRate(JNIEnv *env, jobject thiz) {
- // see frameworks/av/services/audiopolicy/common/include/policy.h
- return 192000; // SAMPLE_RATE_HZ_MAX (for API)
+ return SAMPLE_RATE_HZ_MAX;
}
static jint android_media_AudioSystem_getMinSampleRate(JNIEnv *env, jobject thiz) {
- return 4000; // SAMPLE_RATE_HZ_MIN (for API)
+ return SAMPLE_RATE_HZ_MIN;
}
static std::vector<uid_t> convertJIntArrayToUidVector(JNIEnv *env, jintArray jArray) {
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 982189e30beb..809ec6321fad 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -656,9 +656,8 @@ static int pid_compare(const void* v1, const void* v2)
static jlong android_os_Process_getFreeMemory(JNIEnv* env, jobject clazz)
{
- std::array<std::string_view, 2> memFreeTags = {
- ::android::meminfo::SysMemInfo::kMemFree,
- ::android::meminfo::SysMemInfo::kMemCached,
+ std::array<std::string_view, 1> memFreeTags = {
+ ::android::meminfo::SysMemInfo::kMemAvailable,
};
std::vector<uint64_t> mem(memFreeTags.size());
::android::meminfo::SysMemInfo smi;
@@ -1063,8 +1062,8 @@ jboolean android_os_Process_readProcFile(JNIEnv* env, jobject clazz,
}
env->ReleaseStringUTFChars(file, file8);
- // Most proc files we read are small, so we only go through the
- // loop once and use the stack buffer. We allocate a buffer big
+ // Most proc files we read are small, so we go through the loop
+ // with the stack buffer firstly. We allocate a buffer big
// enough for the whole file.
char readBufferStack[kProcReadStackBufferSize];
@@ -1072,37 +1071,47 @@ jboolean android_os_Process_readProcFile(JNIEnv* env, jobject clazz,
char* readBuffer = &readBufferStack[0];
ssize_t readBufferSize = kProcReadStackBufferSize;
ssize_t numberBytesRead;
+ off_t offset = 0;
for (;;) {
+ ssize_t requestedBufferSize = readBufferSize - offset;
// By using pread, we can avoid an lseek to rewind the FD
// before retry, saving a system call.
- numberBytesRead = pread(fd, readBuffer, readBufferSize, 0);
- if (numberBytesRead < 0 && errno == EINTR) {
- continue;
- }
+ numberBytesRead =
+ TEMP_FAILURE_RETRY(pread(fd, readBuffer + offset, requestedBufferSize, offset));
if (numberBytesRead < 0) {
if (kDebugProc) {
- ALOGW("Unable to open process file: %s fd=%d\n", file8, fd.get());
+ ALOGW("Unable to read process file err: %s file: %s fd=%d\n",
+ strerror_r(errno, &readBufferStack[0], sizeof(readBufferStack)), file8,
+ fd.get());
}
return JNI_FALSE;
}
- if (numberBytesRead < readBufferSize) {
+ if (numberBytesRead == 0) {
+ // End of file.
+ numberBytesRead = offset;
break;
}
- if (readBufferSize > std::numeric_limits<ssize_t>::max() / 2) {
- if (kDebugProc) {
- ALOGW("Proc file too big: %s fd=%d\n", file8, fd.get());
+ if (numberBytesRead < requestedBufferSize) {
+ // Read less bytes than requested, it's not an error per pread(2).
+ offset += numberBytesRead;
+ } else {
+ // Buffer is fully used, try to grow it.
+ if (readBufferSize > std::numeric_limits<ssize_t>::max() / 2) {
+ if (kDebugProc) {
+ ALOGW("Proc file too big: %s fd=%d\n", file8, fd.get());
+ }
+ return JNI_FALSE;
}
- return JNI_FALSE;
- }
- readBufferSize = std::max(readBufferSize * 2,
- kProcReadMinHeapBufferSize);
- readBufferHeap.reset(); // Free address space before getting more.
- readBufferHeap = std::make_unique<char[]>(readBufferSize);
- if (!readBufferHeap) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
- return JNI_FALSE;
+ readBufferSize = std::max(readBufferSize * 2, kProcReadMinHeapBufferSize);
+ readBufferHeap.reset(); // Free address space before getting more.
+ readBufferHeap = std::make_unique<char[]>(readBufferSize);
+ if (!readBufferHeap) {
+ jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ return JNI_FALSE;
+ }
+ readBuffer = readBufferHeap.get();
+ offset = 0;
}
- readBuffer = readBufferHeap.get();
}
// parseProcLineArray below modifies the buffer while parsing!
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
index d11166fd6187..e874163943b6 100644
--- a/core/jni/android_view_InputChannel.cpp
+++ b/core/jni/android_view_InputChannel.cpp
@@ -16,18 +16,22 @@
#define LOG_TAG "InputChannel-JNI"
-#include "android-base/stringprintf.h"
-#include <nativehelper/JNIHelp.h>
-#include "nativehelper/scoped_utf_chars.h"
+#include "android_view_InputChannel.h"
+
#include <android_runtime/AndroidRuntime.h>
#include <binder/Parcel.h>
-#include <utils/Log.h>
+#include <com_android_input_flags.h>
#include <input/InputTransport.h>
-#include "android_view_InputChannel.h"
+#include <nativehelper/JNIHelp.h>
+#include <utils/Log.h>
+
+#include "android-base/stringprintf.h"
#include "android_os_Parcel.h"
#include "android_util_Binder.h"
-
#include "core_jni_helpers.h"
+#include "nativehelper/scoped_utf_chars.h"
+
+namespace input_flags = com::android::input::flags;
namespace android {
@@ -69,6 +73,9 @@ NativeInputChannel::~NativeInputChannel() {
}
void NativeInputChannel::setDisposeCallback(InputChannelObjDisposeCallback callback, void* data) {
+ if (input_flags::remove_input_channel_from_windowstate()) {
+ return;
+ }
mDisposeCallback = callback;
mDisposeData = data;
}
diff --git a/core/jni/platform/host/HostRuntime.cpp b/core/jni/platform/host/HostRuntime.cpp
index 59d18b8535f5..30c926c57693 100644
--- a/core/jni/platform/host/HostRuntime.cpp
+++ b/core/jni/platform/host/HostRuntime.cpp
@@ -104,6 +104,7 @@ extern int register_android_view_KeyCharacterMap(JNIEnv* env);
extern int register_android_view_KeyEvent(JNIEnv* env);
extern int register_android_view_InputDevice(JNIEnv* env);
extern int register_android_view_MotionEvent(JNIEnv* env);
+extern int register_android_view_Surface(JNIEnv* env);
extern int register_android_view_ThreadedRenderer(JNIEnv* env);
extern int register_android_graphics_HardwareBufferRenderer(JNIEnv* env);
extern int register_android_view_VelocityTracker(JNIEnv* env);
@@ -151,6 +152,7 @@ static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = {
{"android.view.KeyEvent", REG_JNI(register_android_view_KeyEvent)},
{"android.view.InputDevice", REG_JNI(register_android_view_InputDevice)},
{"android.view.MotionEvent", REG_JNI(register_android_view_MotionEvent)},
+ {"android.view.Surface", REG_JNI(register_android_view_Surface)},
{"android.view.VelocityTracker", REG_JNI(register_android_view_VelocityTracker)},
{"com.android.internal.util.VirtualRefBasePtr",
REG_JNI(register_com_android_internal_util_VirtualRefBasePtr)},
diff --git a/core/proto/android/providers/settings/system.proto b/core/proto/android/providers/settings/system.proto
index 6a0ec1dcb3f2..e5ced2521134 100644
--- a/core/proto/android/providers/settings/system.proto
+++ b/core/proto/android/providers/settings/system.proto
@@ -126,6 +126,7 @@ message SystemSettingsProto {
option (android.msg_privacy).dest = DEST_EXPLICIT;
optional SettingProto pointer_fill_style = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto pointer_stroke_style = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto pointer_scale = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Pointer pointer = 37;
diff --git a/core/proto/android/server/inputmethod/inputmethodmanagerservice.proto b/core/proto/android/server/inputmethod/inputmethodmanagerservice.proto
index b75d545b1305..eddf1d276e4b 100644
--- a/core/proto/android/server/inputmethod/inputmethodmanagerservice.proto
+++ b/core/proto/android/server/inputmethod/inputmethodmanagerservice.proto
@@ -47,4 +47,5 @@ message InputMethodManagerServiceProto {
optional int32 ime_window_visibility = 22;
optional bool show_ime_with_hard_keyboard = 23;
optional bool accessibility_requesting_no_soft_keyboard = 24;
-} \ No newline at end of file
+ optional bool concurrent_multi_user_mode_enabled = 25;
+}
diff --git a/core/proto/android/view/displayinfo.proto b/core/proto/android/view/displayinfo.proto
index f936ed1b1bd1..32f4cb3a32c0 100644
--- a/core/proto/android/view/displayinfo.proto
+++ b/core/proto/android/view/displayinfo.proto
@@ -36,4 +36,5 @@ message DisplayInfoProto {
optional string name = 5;
optional int32 flags = 6;
optional DisplayCutoutProto cutout = 7;
+ optional int32 type = 8;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f61b6bf3f861..9f00d5e08bbf 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -843,6 +843,7 @@
<protected-broadcast android:name="android.intent.action.PROFILE_UNAVAILABLE" />
<protected-broadcast android:name="android.app.action.CONSOLIDATED_NOTIFICATION_POLICY_CHANGED" />
<protected-broadcast android:name="android.intent.action.MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED" />
+ <protected-broadcast android:name="com.android.uwb.uwbcountrycode.GEOCODE_RETRY" />
<!-- ====================================================================== -->
<!-- RUNTIME PERMISSIONS -->
diff --git a/core/res/res/drawable/pointer_alias_vector.xml b/core/res/res/drawable/pointer_alias_vector.xml
index 035a099cf632..60149f1f26ae 100644
--- a/core/res/res/drawable/pointer_alias_vector.xml
+++ b/core/res/res/drawable/pointer_alias_vector.xml
@@ -22,10 +22,10 @@
android:fillColor="#00FFFFFF"
android:pathData="M14.494 12.779a5.2 5.2 0 0 1-1.771 1.414 5.2 5.2 0 0 1-1.68.489l.81 1.658a1.968 1.968 0 0 0 3.536-1.728zM12.03 8.291l-.81-1.658a1.968 1.968 0 0 0-3.536 1.728l.896 1.833a5.2 5.2 0 0 1 1.77-1.414 5.2 5.2 0 0 1 1.68-.489" />
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="m18.323 13.178-.975-1.995a5.2 5.2 0 0 0-1.704-1.978 5.2 5.2 0 0 0-.517-2.01L14.152 5.2a5.232 5.232 0 0 0-9.401 4.594l.975 1.995a5.2 5.2 0 0 0 1.704 1.978 5.2 5.2 0 0 0 .517 2.01l.975 1.995a5.233 5.233 0 0 0 9.401-4.594m-2.843 6.1a4.23 4.23 0 0 1-5.66-1.944l-.975-1.995a4.2 4.2 0 0 1-.431-1.838l-.001-.276-.234-.146a4.2 4.2 0 0 1-1.555-1.729L5.65 9.355a4.232 4.232 0 1 1 7.604-3.716l.975 1.995c.29.594.428 1.22.431 1.838l.001.276.234.146c.648.405 1.194.99 1.555 1.728l.975 1.995a4.234 4.234 0 0 1-1.945 5.661" />
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="M15.313 12.177a3 3 0 0 0-.416-.633l-.459-.534-.353.609a4.2 4.2 0 0 1-1.801 1.675 4.2 4.2 0 0 1-1.977.429l-.704-.02.213.671q.066.208.164.409l.975 1.995a2.967 2.967 0 1 0 5.332-2.606zm-.827 5.066a1.97 1.97 0 0 1-2.632-.904l-.81-1.658a5.2 5.2 0 0 0 1.68-.489 5.2 5.2 0 0 0 1.771-1.414l.896 1.833a1.97 1.97 0 0 1-.905 2.632m-3.697-7.565a4.2 4.2 0 0 1 1.977-.429l.704.02-.213-.671a3 3 0 0 0-.164-.409l-.975-1.995A2.967 2.967 0 1 0 6.785 8.8l.975 1.995q.172.35.416.633l.459.534.353-.609a4.2 4.2 0 0 1 1.801-1.675m-2.21.516-.895-1.833a1.968 1.968 0 1 1 3.536-1.728l.81 1.658a5.2 5.2 0 0 0-1.68.489 5.2 5.2 0 0 0-1.771 1.414m3.151 1.965a3 3 0 0 0 1.02-.818l.755-.95-1.205.142a2.97 2.97 0 0 0-1.975 1.1l-.755.95 1.205-.142c.324-.039.646-.132.955-.282" />
<path
android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_all_scroll_vector.xml b/core/res/res/drawable/pointer_all_scroll_vector.xml
index 45ad98c1b57c..41314ed7e3a4 100644
--- a/core/res/res/drawable/pointer_all_scroll_vector.xml
+++ b/core/res/res/drawable/pointer_all_scroll_vector.xml
@@ -24,5 +24,5 @@
android:fillColor="?attr/pointerIconVectorFill"/>
<path
android:pathData="M12 4c.36 0 .72.18.93.54l1.75 3.06c.41.71-.1 1.6-.92 1.6h-.82v1.86h1.86v-.84a1.07 1.07 0 0 1 1.6-.92l3.06 1.75c.72.41.72 1.44 0 1.85l-3.06 1.76a1.07 1.07 0 0 1-1.6-.92v-.8h-1.86v1.87h.82c.82 0 1.33.88.92 1.6l-1.75 3.06a1.07 1.07 0 0 1-1.85 0L9.32 16.4c-.4-.7.1-1.6.93-1.6h.81v-1.86H9.2v.8a1.07 1.07 0 0 1-1.6.92L4.54 12.9a1.06 1.06 0 0 1 0-1.85L7.6 9.3a1.07 1.07 0 0 1 1.6.92v.85h1.86V9.2h-.82c-.81 0-1.33-.89-.92-1.6l1.76-3.06c.2-.36.56-.54.92-.54m0-1c-.74 0-1.41.39-1.79 1.04L8.45 7.1c-.18.33-.28.7-.27 1.05h-.05c-.36 0-.71.1-1.03.28l-3.06 1.76a2.05 2.05 0 0 0 0 3.58l3.06 1.75c.32.18.67.28 1.03.28h.05c-.01.38.08.76.28 1.1l1.75 3.07c.38.65 1.05 1.03 1.8 1.03s1.41-.38 1.78-1.03l1.76-3.07c.2-.34.3-.72.28-1.1h.04c.36 0 .71-.1 1.03-.28l3.06-1.75a2.07 2.07 0 0 0 0-3.58L16.9 8.43a2.07 2.07 0 0 0-1.03-.28h-.04c0-.36-.09-.72-.28-1.05L13.8 4.04A2.04 2.04 0 0 0 12 3z"
- android:fillColor="#FFFFFF"/>
+ android:fillColor="?attr/pointerIconVectorStroke"/>
</vector>
diff --git a/core/res/res/drawable/pointer_arrow_vector.xml b/core/res/res/drawable/pointer_arrow_vector.xml
index 2614170f6994..a0bd5b614280 100644
--- a/core/res/res/drawable/pointer_arrow_vector.xml
+++ b/core/res/res/drawable/pointer_arrow_vector.xml
@@ -24,5 +24,5 @@
android:fillColor="?attr/pointerIconVectorFill"/>
<path
android:pathData="M16.94 10.38 7.37 3.22a2.77 2.77 0 0 0-2.93-.27 2.75 2.75 0 0 0-1.55 2.51l.01 11.95a2.78 2.78 0 0 0 2.82 2.8c.77 0 1.5-.32 2.03-.9l2.97-3.19a.8.8 0 0 1 .5-.25l4.34-.46a2.76 2.76 0 0 0 2.4-2.05 2.8 2.8 0 0 0-1.02-2.98zM17 13.1a1.77 1.77 0 0 1-1.55 1.31l-4.33.47a1.8 1.8 0 0 0-1.13.56l-2.97 3.2c-.4.42-.86.57-1.3.57-.24 0-.48-.05-.68-.13a1.77 1.77 0 0 1-1.14-1.67V5.46a1.81 1.81 0 0 1 1.8-1.8c.38 0 .75.11 1.07.36l9.57 7.16c.72.54.81 1.35.66 1.92z"
- android:fillColor="#FFFFFF"/>
+ android:fillColor="?attr/pointerIconVectorStroke"/>
</vector>
diff --git a/core/res/res/drawable/pointer_cell_vector.xml b/core/res/res/drawable/pointer_cell_vector.xml
index cead1c4185b4..9ad64e27da63 100644
--- a/core/res/res/drawable/pointer_cell_vector.xml
+++ b/core/res/res/drawable/pointer_cell_vector.xml
@@ -19,7 +19,7 @@
android:viewportHeight="24"
android:viewportWidth="24">
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="M19 9.667h-4.668V5a2 2 0 0 0-2-2h-.667a2 2 0 0 0-2 2v4.667H5a2 2 0 0 0-2 2v.667a2 2 0 0 0 2 2h4.665V19a2 2 0 0 0 2 2h.667a2 2 0 0 0 2-2v-4.666H19a2 2 0 0 0 2-2v-.667a2 2 0 0 0-2-2m1 2.667a1 1 0 0 1-1 1h-5.668V19a1 1 0 0 1-1 1h-.667a1 1 0 0 1-1-1v-5.666H5a1 1 0 0 1-1-1v-.667a1 1 0 0 1 1-1h5.665V5a1 1 0 0 1 1-1h.667a1 1 0 0 1 1 1v5.667H19a1 1 0 0 1 1 1z" />
<path
android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_context_menu_vector.xml b/core/res/res/drawable/pointer_context_menu_vector.xml
index fb2af431ffb6..33b1acefc827 100644
--- a/core/res/res/drawable/pointer_context_menu_vector.xml
+++ b/core/res/res/drawable/pointer_context_menu_vector.xml
@@ -19,11 +19,11 @@
android:viewportHeight="24"
android:viewportWidth="24">
<group>
- <path android:fillColor="#FFFFFF" android:pathData="M19.475 2.604h-2.66c-.842 0-1.527.685-1.527 1.527v2.66c0 .842.685 1.527 1.527 1.527h2.66c.842 0 1.527-.685 1.527-1.527v-2.66c0-.842-.685-1.527-1.527-1.527m.67 4.187c0 .37-.3.67-.67.67h-2.66a.67.67 0 0 1-.67-.67v-2.66c0-.37.3-.67.67-.67h2.66c.37 0 .67.3.67.67z" />
- <path android:fillColor="#FFFFFF" android:pathData="M19.175 4.17h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6m0 .886h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6m0 .868h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6" />
+ <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="M19.475 2.604h-2.66c-.842 0-1.527.685-1.527 1.527v2.66c0 .842.685 1.527 1.527 1.527h2.66c.842 0 1.527-.685 1.527-1.527v-2.66c0-.842-.685-1.527-1.527-1.527m.67 4.187c0 .37-.3.67-.67.67h-2.66a.67.67 0 0 1-.67-.67v-2.66c0-.37.3-.67.67-.67h2.66c.37 0 .67.3.67.67z" />
+ <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="M19.175 4.17h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6m0 .886h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6m0 .868h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6" />
</group>
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="M16.938 10.38 7.372 3.216a2.77 2.77 0 0 0-2.931-.262A2.75 2.75 0 0 0 2.894 5.46l.009 11.951a2.785 2.785 0 0 0 1.776 2.604c.33.129.691.197 1.044.197a2.75 2.75 0 0 0 2.031-.897l2.969-3.193a.8.8 0 0 1 .5-.25l4.336-.467c1.397-.15 2.157-1.153 2.401-2.041a2.785 2.785 0 0 0-1.022-2.984m.058 2.718c-.157.571-.645 1.216-1.544 1.312l-4.335.467a1.8 1.8 0 0 0-1.126.563l-2.97 3.193a1.74 1.74 0 0 1-1.298.578 1.9 1.9 0 0 1-.678-.128c-.551-.217-1.141-.771-1.142-1.674l-.009-11.95c0-.697.371-1.299.994-1.611.262-.131.538-.196.813-.196.377 0 .75.123 1.072.365l9.566 7.163c.723.542.814 1.346.657 1.918" />
<path
android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_copy_vector.xml b/core/res/res/drawable/pointer_copy_vector.xml
index 3f138685e6eb..8ac8c2181ed5 100644
--- a/core/res/res/drawable/pointer_copy_vector.xml
+++ b/core/res/res/drawable/pointer_copy_vector.xml
@@ -23,7 +23,7 @@
<path android:fillColor="?attr/pointerIconVectorFillInverse" android:pathData="M19.299 6H18V4.7a.5.5 0 0 0-1 0V6h-1.301a.5.5 0 0 0 0 1H17v1.3a.5.5 0 0 0 1 0V7h1.299a.5.5 0 0 0 0-1" />
</group>
<path
- android:fillColor="#000000"
+ android:fillColor="?attr/pointerIconVectorStrokeInverse"
android:pathData="M18.485 10.884v1.739q.013.189.013.38c0 3.045-2.518 5.514-5.563 5.514a5.58 5.58 0 0 1-3.922-1.613 1 1 0 0 1-.117-.106l-3.847-3.936c-.482-.494-.482-1.294 0-1.787s1.265-.494 1.747 0l.697.713V7.583a1 1 0 0 1 2 0v1.096q.463-.364.997-.625v-1.57a1 1 0 0 1 2 0v1.022q.22-.018.446-.018c.062 0 .123.007.185.009A4.4 4.4 0 0 1 13 6.5c0-.378.061-.739.149-1.09a1.97 1.97 0 0 0-1.659-.926c-.903 0-1.658.603-1.906 1.425a1.997 1.997 0 0 0-3.091 1.674v2.206a2.2 2.2 0 0 0-2.159.586 2.285 2.285 0 0 0 0 3.185l3.847 3.936q.063.061.13.118l-.001.001a6.58 6.58 0 0 0 4.624 1.902c3.586 0 6.563-2.905 6.563-6.514q-.001-.192-.013-.381v-2.108c-.316.156-.645.29-.999.37" />
<path
android:fillColor="#1FA54A"
diff --git a/core/res/res/drawable/pointer_crosshair_vector.xml b/core/res/res/drawable/pointer_crosshair_vector.xml
index 8a50d1bdd497..4fba08076e7a 100644
--- a/core/res/res/drawable/pointer_crosshair_vector.xml
+++ b/core/res/res/drawable/pointer_crosshair_vector.xml
@@ -19,7 +19,7 @@
android:viewportHeight="24"
android:viewportWidth="24">
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="M19.25 10.25h-5.5v-5.5a1.75 1.75 0 0 0-3.5 0v5.5h-5.5a1.75 1.75 0 0 0 0 3.5h5.5v5.5a1.75 1.75 0 0 0 3.5 0v-5.5h5.5a1.75 1.75 0 0 0 0-3.5m0 2.5h-6.5v6.5a.75.75 0 0 1-1.5 0v-6.5h-6.5a.75.75 0 0 1 0-1.5h6.5v-6.5a.75.75 0 0 1 1.5 0v6.5h6.5a.75.75 0 0 1 0 1.5" />
<path
android:fillType="evenOdd"
diff --git a/core/res/res/drawable/pointer_grab_vector.xml b/core/res/res/drawable/pointer_grab_vector.xml
index 48c01ceb6588..d9e1f18919fa 100644
--- a/core/res/res/drawable/pointer_grab_vector.xml
+++ b/core/res/res/drawable/pointer_grab_vector.xml
@@ -19,7 +19,7 @@
android:viewportHeight="24"
android:viewportWidth="24">
<path
- android:fillColor="#000000"
+ android:fillColor="?attr/pointerIconVectorStrokeInverse"
android:pathData="M20.442 7.562a2 2 0 0 0-2-2c-.366 0-.705.106-1 .277V4.686a2 2 0 0 0-2-2 2 2 0 0 0-1.004.279 1.995 1.995 0 0 0-3.986-.06 2 2 0 0 0-1.006-.28 2 2 0 0 0-2 2v6.501l-.247-.253a2.216 2.216 0 0 0-3.178 0 2.286 2.286 0 0 0 0 3.186l5.106 5.224q.063.061.131.118l-.001.001a6.58 6.58 0 0 0 4.624 1.901c3.587 0 6.565-2.906 6.565-6.516q0-.105-.004-.21m-6.561 5.727a5.58 5.58 0 0 1-3.922-1.613 1 1 0 0 1-.117-.106l-5.106-5.224a1.286 1.286 0 0 1 0-1.788 1.215 1.215 0 0 1 1.747 0l1.962 2.008V4.625a1 1 0 0 1 2 0v5.833q.463-.362.996-.623V3a1 1 0 0 1 2 0v6.29a6 6 0 0 1 1 .011V4.686a1 1 0 0 1 2 0v5.21c.357.185.693.408 1 .663V7.562a1 1 0 0 1 2 0v7.019h.001-.001q.004.104.004.207c.001 3.046-2.518 5.516-5.564 5.516" />
<path
android:fillColor="?attr/pointerIconVectorFillInverse"
diff --git a/core/res/res/drawable/pointer_grabbing_vector.xml b/core/res/res/drawable/pointer_grabbing_vector.xml
index ad9f86c1848c..7f52fc5f42ba 100644
--- a/core/res/res/drawable/pointer_grabbing_vector.xml
+++ b/core/res/res/drawable/pointer_grabbing_vector.xml
@@ -19,7 +19,7 @@
android:viewportHeight="24"
android:viewportWidth="24">
<path
- android:fillColor="#000000"
+ android:fillColor="?attr/pointerIconVectorStrokeInverse"
android:pathData="M19.485 12.622V8.508a2 2 0 0 0-3.12-1.657 1.993 1.993 0 0 0-2.99-1.006 1.99 1.99 0 0 0-1.886-1.361c-.903 0-1.658.603-1.906 1.425a2 2 0 0 0-3.09 1.674v2.206a2.2 2.2 0 0 0-2.159.586 2.285 2.285 0 0 0 0 3.185l3.847 3.936q.063.061.13.118l-.001.001a6.58 6.58 0 0 0 4.624 1.902c3.586 0 6.563-2.905 6.563-6.514a5 5 0 0 0-.012-.381m-6.55 5.895a5.58 5.58 0 0 1-3.922-1.613 1 1 0 0 1-.117-.106l-3.847-3.936c-.482-.494-.482-1.294 0-1.787s1.265-.494 1.747 0l.697.713V7.583a1 1 0 0 1 2 0v1.096q.463-.364.997-.625v-1.57a1 1 0 0 1 2 0v1.022a5.5 5.5 0 0 1 .996.009v-.007a1 1 0 0 1 2 0v.599q.537.277 1 .66v-.259a1 1 0 0 1 2 0v4.115q.013.189.013.38c-.001 3.045-2.518 5.514-5.564 5.514" />
<path
android:fillColor="?attr/pointerIconVectorFillInverse"
diff --git a/core/res/res/drawable/pointer_hand_vector.xml b/core/res/res/drawable/pointer_hand_vector.xml
index a06dc08b8b3f..115b53b5d495 100644
--- a/core/res/res/drawable/pointer_hand_vector.xml
+++ b/core/res/res/drawable/pointer_hand_vector.xml
@@ -19,7 +19,7 @@
android:viewportHeight="24"
android:viewportWidth="24">
<path
- android:fillColor="#000000"
+ android:fillColor="?attr/pointerIconVectorStrokeInverse"
android:pathData="M20.492 15.197v-4.198A1.995 1.995 0 0 0 18.5 9.001c-.413 0-.797.126-1.115.342a1.99 1.99 0 0 0-1.873-1.341c-.411 0-.792.125-1.109.339a1.99 1.99 0 0 0-1.879-1.361c-.363 0-.699.105-.992.275V3.998A1.99 1.99 0 0 0 9.542 2c-1.1 0-1.992.895-1.992 1.998v7.831l-.242-.249a2.2 2.2 0 0 0-3.164 0 2.29 2.29 0 0 0 0 3.183l5.084 5.219q.063.061.13.118l-.001.001A6.54 6.54 0 0 0 13.963 22c3.572 0 6.537-2.903 6.537-6.509q0-.148-.008-.294m-6.529 5.804a5.55 5.55 0 0 1-3.906-1.611 1 1 0 0 1-.117-.106l-5.084-5.219a1.286 1.286 0 0 1 0-1.786 1.21 1.21 0 0 1 1.74 0l1.95 2.002V3.998c0-.552.446-.999.996-.999s.996.447.996.999v7.17l.011-.007a.495.495 0 0 0 .989-.037V8.939a.992.992 0 0 1 1.984.039v.796l-.007 1.386a.5.5 0 0 0 .495.502h.003a.5.5 0 0 0 .498-.497l.006-1.157h.001V10a.997.997 0 1 1 1.991 0v.601l.004.003v1.02q.001.107.042.199a.5.5 0 0 0 .153.187l.031.021a.5.5 0 0 0 .231.083c.014.001.026.008.04.008a.5.5 0 0 0 .498-.5v-.642a.996.996 0 0 1 .993-.98c.55 0 .996.447.996.999v4.199a6 6 0 0 1 .008.293c-.001 3.043-2.509 5.51-5.542 5.51" />
<path
android:fillColor="?attr/pointerIconVectorFillInverse"
diff --git a/core/res/res/drawable/pointer_handwriting_vector.xml b/core/res/res/drawable/pointer_handwriting_vector.xml
index 849759291101..6f62abaca7aa 100644
--- a/core/res/res/drawable/pointer_handwriting_vector.xml
+++ b/core/res/res/drawable/pointer_handwriting_vector.xml
@@ -19,8 +19,8 @@
android:viewportHeight="24"
android:viewportWidth="24">
<group>
- <path android:fillColor="#FFFFFF" android:pathData="M20.12 6.8 18.7 5.38c-.57-.57-1.32-.88-2.12-.88s-1.56.31-2.13.88l-7.16 7.16-.29.29V5c0-1.1-.9-2-2-2s-2 .9-2 2v14c0 1.1.9 2 2 2s2-.9 2-2v-.5h5.67l.29-.29 7.16-7.16c.57-.57.88-1.32.88-2.12s-.31-1.57-.88-2.13M6 19c0 .55-.45 1-1 1s-1-.45-1-1V5c0-.55.45-1 1-1s1 .45 1 1zm13.41-8.66-7.16 7.16H8v-4.25l7.16-7.16c.39-.39.9-.59 1.41-.59h.01c.51 0 1.02.2 1.41.59l1.42 1.42c.78.78.78 2.05 0 2.83" />
- <path android:fillColor="#FFFFFF" android:pathData="m16.431 7.64-6.29 6.29 1.43 1.43 6.29-6.29-1.42-1.43z" />
+ <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="M20.12 6.8 18.7 5.38c-.57-.57-1.32-.88-2.12-.88s-1.56.31-2.13.88l-7.16 7.16-.29.29V5c0-1.1-.9-2-2-2s-2 .9-2 2v14c0 1.1.9 2 2 2s2-.9 2-2v-.5h5.67l.29-.29 7.16-7.16c.57-.57.88-1.32.88-2.12s-.31-1.57-.88-2.13M6 19c0 .55-.45 1-1 1s-1-.45-1-1V5c0-.55.45-1 1-1s1 .45 1 1zm13.41-8.66-7.16 7.16H8v-4.25l7.16-7.16c.39-.39.9-.59 1.41-.59h.01c.51 0 1.02.2 1.41.59l1.42 1.42c.78.78.78 2.05 0 2.83" />
+ <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="m16.431 7.64-6.29 6.29 1.43 1.43 6.29-6.29-1.42-1.43z" />
</group>
<path
android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_help_vector.xml b/core/res/res/drawable/pointer_help_vector.xml
index 07970fbdd67a..63cf287080aa 100644
--- a/core/res/res/drawable/pointer_help_vector.xml
+++ b/core/res/res/drawable/pointer_help_vector.xml
@@ -22,7 +22,7 @@
android:fillColor="?attr/pointerIconVectorFill"
android:pathData="M16.339 11.18 6.773 4.017a1.78 1.78 0 0 0-1.072-.365c-.274 0-.551.065-.813.196a1.77 1.77 0 0 0-.994 1.611l.009 11.951c0 .903.59 1.457 1.142 1.674.2.078.433.128.678.128.434 0 .906-.155 1.298-.578l2.97-3.193a1.8 1.8 0 0 1 1.126-.563l4.335-.467c.899-.097 1.387-.741 1.544-1.312.157-.573.066-1.377-.657-1.919" />
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="M16.94 10.38 7.37 3.22a2.77 2.77 0 0 0-2.93-.27A2.75 2.75 0 0 0 2.9 5.46l.01 11.95a2.79 2.79 0 0 0 2.82 2.8c.78 0 1.5-.32 2.03-.9l2.97-3.19a.8.8 0 0 1 .5-.25l4.34-.46a2.76 2.76 0 0 0 2.4-2.05 2.8 2.8 0 0 0-1.02-2.98zM17 13.1a1.77 1.77 0 0 1-1.55 1.31l-4.33.47a1.8 1.8 0 0 0-1.13.56l-2.97 3.2c-.4.42-.86.57-1.3.57-.24 0-.48-.05-.68-.13a1.77 1.77 0 0 1-1.14-1.67V5.46a1.81 1.81 0 0 1 1.8-1.8c.38 0 .75.11 1.07.36l9.57 7.16c.72.54.81 1.35.66 1.92zm2.64-10.83a2.5 2.5 0 0 0-1.84-.72 3 3 0 0 0-2.83 1.93l-.39.94.96.37.86.32.12.05-.02.03c-.22.4-.3.82-.3 1.33v.94a1.56 1.56 0 0 0 .4 1.47 1.54 1.54 0 0 0 2.24.01 1.55 1.55 0 0 0 .28-1.84v-.52c0-.1.02-.17.03-.25l.16-.15c.32-.25.6-.56.78-.93.18-.37.26-.76.26-1.16 0-.68-.21-1.32-.7-1.82zm-1.5 5.96a.55.55 0 0 1-.82 0 .56.56 0 0 1-.17-.4c0-.16.06-.3.17-.4a.55.55 0 0 1 .41-.18c.15 0 .28.06.4.17a.55.55 0 0 1 0 .81zm1.05-3.42c-.1.22-.28.42-.52.6-.26.22-.42.42-.47.6-.05.18-.08.37-.08.57l-.93-.06c0-.38.07-.62.19-.86.13-.24.3-.46.54-.66.17-.13.3-.28.4-.43s.14-.3.14-.46c0-.2-.08-.37-.22-.5s-.31-.17-.52-.17c-.2 0-.39.06-.56.18-.17.13-.3.31-.4.56l-.87-.33a2.03 2.03 0 0 1 1.91-1.3c.48 0 .86.14 1.13.42.28.28.41.65.41 1.12 0 .26-.05.5-.15.72z" />
<path
android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_horizontal_double_arrow_vector.xml b/core/res/res/drawable/pointer_horizontal_double_arrow_vector.xml
index 32c56b6aa098..7aa65713dbf0 100644
--- a/core/res/res/drawable/pointer_horizontal_double_arrow_vector.xml
+++ b/core/res/res/drawable/pointer_horizontal_double_arrow_vector.xml
@@ -19,7 +19,7 @@
android:viewportHeight="24"
android:viewportWidth="24">
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="m19.963 10.185-3.065-1.758c-1.327-.761-2.96.14-3.072 1.633h-3.651c-.113-1.492-1.746-2.394-3.072-1.633l-3.065 1.758c-1.383.793-1.383 2.786 0 3.579l3.065 1.758c1.311.752 2.918-.12 3.065-1.581h3.666c.147 1.46 1.754 2.333 3.065 1.581l3.065-1.758c1.382-.793 1.382-2.786-.001-3.579m-.498 2.712L16.4 14.655a1.065 1.065 0 0 1-1.596-.922v-.791H9.195v.791c0 .818-.886 1.33-1.596.922l-3.065-1.758a1.063 1.063 0 0 1 0-1.845l3.065-1.758a1.065 1.065 0 0 1 1.596.922v.843h5.609v-.843c0-.818.886-1.33 1.596-.922l3.065 1.758a1.063 1.063 0 0 1 0 1.845" />
<path
android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_nodrop_vector.xml b/core/res/res/drawable/pointer_nodrop_vector.xml
index 6108e9681fa5..7cef01af77af 100644
--- a/core/res/res/drawable/pointer_nodrop_vector.xml
+++ b/core/res/res/drawable/pointer_nodrop_vector.xml
@@ -23,7 +23,7 @@
<path android:fillColor="?attr/pointerIconVectorFillInverse" android:pathData="M17.5 4c-.493 0-.95.148-1.337.395l3.442 3.442C19.852 7.45 20 6.993 20 6.5 20 5.121 18.879 4 17.5 4M15 6.5C15 7.879 16.121 9 17.5 9c.525 0 1.011-.164 1.413-.441l-3.472-3.472A2.5 2.5 0 0 0 15 6.5" />
</group>
<path
- android:fillColor="#000000"
+ android:fillColor="?attr/pointerIconVectorStrokeInverse"
android:pathData="M18.485 10.932v1.69q.013.188.013.38c0 3.045-2.518 5.514-5.563 5.514a5.58 5.58 0 0 1-3.922-1.613 1 1 0 0 1-.117-.106l-3.847-3.936c-.482-.494-.482-1.294 0-1.787s1.265-.494 1.747 0l.697.713V7.583a1 1 0 0 1 2 0v1.096q.463-.364.997-.625v-1.57a1 1 0 0 1 2 0v1.022q.22-.018.446-.018c.046 0 .09.006.135.007a4.5 4.5 0 0 1-.117-.995c0-.399.068-.779.165-1.148a1.97 1.97 0 0 0-1.629-.867c-.903 0-1.658.603-1.906 1.425a2 2 0 0 0-1.091-.327 2 2 0 0 0-2 2v2.206a2.2 2.2 0 0 0-2.159.586 2.285 2.285 0 0 0 0 3.185l3.847 3.936q.063.061.13.118l-.001.001a6.58 6.58 0 0 0 4.624 1.902c3.586 0 6.563-2.905 6.563-6.514q-.001-.192-.013-.381v-2.056a4.5 4.5 0 0 1-.999.366" />
<path
android:fillColor="#B22A25"
diff --git a/core/res/res/drawable/pointer_text_vector.xml b/core/res/res/drawable/pointer_text_vector.xml
index a14727309674..2fa133258ac1 100644
--- a/core/res/res/drawable/pointer_text_vector.xml
+++ b/core/res/res/drawable/pointer_text_vector.xml
@@ -22,6 +22,6 @@
android:fillColor="?attr/pointerIconVectorFill"
android:pathData="M12 3c-.551 0-1 .448-1 1v14a1.001 1.001 0 0 0 2 0V4c0-.552-.449-1-1-1" />
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="M12 2c-1.103 0-2 .897-2 2v14c0 1.103.897 2 2 2s2-.897 2-2V4c0-1.103-.897-2-2-2m1 16a1.001 1.001 0 0 1-2 0V4a1.001 1.001 0 0 1 2 0z" />
</vector> \ No newline at end of file
diff --git a/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_vector.xml b/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_vector.xml
index 7f95207d9e82..cd4e5e703fa9 100644
--- a/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_vector.xml
+++ b/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_vector.xml
@@ -19,7 +19,7 @@
android:viewportHeight="24"
android:viewportWidth="24">
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="m18.896 16.365-.924-3.41c-.398-1.467-2.169-1.985-3.305-1.035L12.08 9.333c.952-1.136.434-2.908-1.034-3.306l-3.41-.924c-1.539-.416-2.948.993-2.532 2.532l.924 3.41c.398 1.468 2.17 1.986 3.306 1.034l2.586 2.586c-.953 1.136-.435 2.91 1.033 3.307l3.41.924c1.54.417 2.949-.992 2.533-2.531m-2.27 1.566-3.41-.924a1.065 1.065 0 0 1-.476-1.781l.579-.579-3.966-3.966-.579.579a1.066 1.066 0 0 1-1.781-.476L6.07 7.373a1.063 1.063 0 0 1 1.304-1.304l3.41.924a1.065 1.065 0 0 1 .476 1.781l-.578.578 3.966 3.966.577-.577a1.066 1.066 0 0 1 1.781.477l.924 3.41a1.062 1.062 0 0 1-1.304 1.303" />
<path
android:fillType="evenOdd"
diff --git a/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_vector.xml b/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_vector.xml
index 8a3371524429..3736290c94ad 100644
--- a/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_vector.xml
+++ b/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_vector.xml
@@ -19,7 +19,7 @@
android:viewportHeight="24"
android:viewportWidth="24">
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="m16.365 5.104-3.41.924c-1.468.398-1.986 2.171-1.033 3.307l-2.586 2.586c-1.136-.952-2.909-.434-3.306 1.034l-.924 3.41c-.417 1.539.992 2.948 2.531 2.531l3.41-.924c1.468-.398 1.986-2.17 1.034-3.306l2.587-2.587c1.136.951 2.908.432 3.305-1.035l.924-3.41c.415-1.538-.994-2.947-2.532-2.53m1.565 2.269-.924 3.41a1.065 1.065 0 0 1-1.781.476l-.577-.577-3.966 3.966.578.578a1.066 1.066 0 0 1-.476 1.781l-3.41.924a1.063 1.063 0 0 1-1.304-1.304l.924-3.41a1.066 1.066 0 0 1 1.781-.477l.578.578 3.966-3.966-.579-.579a1.066 1.066 0 0 1 .476-1.781l3.41-.924a1.063 1.063 0 0 1 1.304 1.305" />
<path
android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_vertical_double_arrow_vector.xml b/core/res/res/drawable/pointer_vertical_double_arrow_vector.xml
index 889372c39433..ff99f4101aab 100644
--- a/core/res/res/drawable/pointer_vertical_double_arrow_vector.xml
+++ b/core/res/res/drawable/pointer_vertical_double_arrow_vector.xml
@@ -19,7 +19,7 @@
android:viewportHeight="24"
android:viewportWidth="24">
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="M13.945 13.829V10.17c1.476-.131 2.363-1.75 1.606-3.069l-1.758-3.065c-.793-1.383-2.786-1.383-3.579 0L8.455 7.102c-.757 1.319.131 2.939 1.607 3.069v3.658c-1.477.13-2.364 1.75-1.607 3.069l1.758 3.065c.793 1.383 2.786 1.383 3.579 0l1.758-3.065c.758-1.319-.129-2.938-1.605-3.069m.739 2.572-1.758 3.065a1.063 1.063 0 0 1-1.845 0l-1.758-3.065a1.065 1.065 0 0 1 .922-1.596h.818v-5.61h-.818c-.818 0-1.33-.886-.922-1.596l1.758-3.065a1.063 1.063 0 0 1 1.845 0l1.758 3.065a1.065 1.065 0 0 1-.922 1.596h-.817v5.609h.817c.817.001 1.329.886.922 1.597" />
<path
android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_vertical_text_vector.xml b/core/res/res/drawable/pointer_vertical_text_vector.xml
index 9238f94fa808..d610d0488338 100644
--- a/core/res/res/drawable/pointer_vertical_text_vector.xml
+++ b/core/res/res/drawable/pointer_vertical_text_vector.xml
@@ -22,6 +22,6 @@
android:fillColor="?attr/pointerIconVectorFill"
android:pathData="M19 11H5a1 1 0 0 0 0 2h14a1 1 0 0 0 0-2" />
<path
- android:fillColor="#FFFFFF"
+ android:fillColor="?attr/pointerIconVectorStroke"
android:pathData="M19 10H5c-1.103 0-2 .897-2 2s.897 2 2 2h14c1.103 0 2-.897 2-2s-.897-2-2-2m0 3H5a1 1 0 0 1 0-2h14a1 1 0 0 1 0 2" />
</vector> \ No newline at end of file
diff --git a/core/res/res/drawable/pointer_zoom_in_vector.xml b/core/res/res/drawable/pointer_zoom_in_vector.xml
index a7f56c23d5fb..c4aa95bbc384 100644
--- a/core/res/res/drawable/pointer_zoom_in_vector.xml
+++ b/core/res/res/drawable/pointer_zoom_in_vector.xml
@@ -19,8 +19,8 @@
android:viewportHeight="24"
android:viewportWidth="24">
<group>
- <path android:fillColor="#FFFFFF" android:pathData="m20.445 17.298-3.591-3.613a7.5 7.5 0 0 0 1.243-4.138 7.547 7.547 0 1 0-7.546 7.546c1.239 0 2.402-.31 3.435-.84l3.733 3.756a1.922 1.922 0 1 0 2.726-2.711m-.713 2.009a.923.923 0 0 1-1.305-.004l-4.268-4.294a6.547 6.547 0 1 1 2.938-5.462 6.52 6.52 0 0 1-1.555 4.236l4.194 4.22a.92.92 0 0 1-.004 1.304" />
- <path android:fillColor="#FFFFFF" android:pathData="M10.55 5a4.546 4.546 0 1 0 0 9.093 4.546 4.546 0 0 0 0-9.093m2.462 5h-2v2a.5.5 0 0 1-1 0v-2h-2a.5.5 0 0 1 0-1h2V7a.5.5 0 0 1 1 0v2h2a.5.5 0 0 1 0 1" />
+ <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="m20.445 17.298-3.591-3.613a7.5 7.5 0 0 0 1.243-4.138 7.547 7.547 0 1 0-7.546 7.546c1.239 0 2.402-.31 3.435-.84l3.733 3.756a1.922 1.922 0 1 0 2.726-2.711m-.713 2.009a.923.923 0 0 1-1.305-.004l-4.268-4.294a6.547 6.547 0 1 1 2.938-5.462 6.52 6.52 0 0 1-1.555 4.236l4.194 4.22a.92.92 0 0 1-.004 1.304" />
+ <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="M10.55 5a4.546 4.546 0 1 0 0 9.093 4.546 4.546 0 0 0 0-9.093m2.462 5h-2v2a.5.5 0 0 1-1 0v-2h-2a.5.5 0 0 1 0-1h2V7a.5.5 0 0 1 1 0v2h2a.5.5 0 0 1 0 1" />
</group>
<group>
<path android:fillColor="?attr/pointerIconVectorFill" android:pathData="m19.736 18.003-4.194-4.22a6.547 6.547 0 1 0-1.382 1.226l4.268 4.294a.923.923 0 0 0 1.308-1.3m-9.186-3.91A4.546 4.546 0 1 1 10.549 5a4.546 4.546 0 0 1 .001 9.093" />
diff --git a/core/res/res/drawable/pointer_zoom_out_vector.xml b/core/res/res/drawable/pointer_zoom_out_vector.xml
index e46b978df5b6..16c4520a8637 100644
--- a/core/res/res/drawable/pointer_zoom_out_vector.xml
+++ b/core/res/res/drawable/pointer_zoom_out_vector.xml
@@ -19,8 +19,8 @@
android:viewportHeight="24"
android:viewportWidth="24">
<group>
- <path android:fillColor="#FFFFFF" android:pathData="m20.445 17.298-3.591-3.613a7.5 7.5 0 0 0 1.243-4.138 7.547 7.547 0 1 0-7.546 7.546c1.239 0 2.402-.31 3.435-.84l3.733 3.756a1.922 1.922 0 1 0 2.726-2.711m-.713 2.009a.923.923 0 0 1-1.305-.004l-4.268-4.294a6.547 6.547 0 1 1 2.938-5.462 6.52 6.52 0 0 1-1.555 4.236l4.194 4.22a.92.92 0 0 1-.004 1.304" />
- <path android:fillColor="#FFFFFF" android:pathData="M10.55 5a4.546 4.546 0 1 0 0 9.093 4.546 4.546 0 0 0 0-9.093m2.462 5h-5a.5.5 0 0 1 0-1h5a.5.5 0 0 1 0 1" />
+ <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="m20.445 17.298-3.591-3.613a7.5 7.5 0 0 0 1.243-4.138 7.547 7.547 0 1 0-7.546 7.546c1.239 0 2.402-.31 3.435-.84l3.733 3.756a1.922 1.922 0 1 0 2.726-2.711m-.713 2.009a.923.923 0 0 1-1.305-.004l-4.268-4.294a6.547 6.547 0 1 1 2.938-5.462 6.52 6.52 0 0 1-1.555 4.236l4.194 4.22a.92.92 0 0 1-.004 1.304" />
+ <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="M10.55 5a4.546 4.546 0 1 0 0 9.093 4.546 4.546 0 0 0 0-9.093m2.462 5h-5a.5.5 0 0 1 0-1h5a.5.5 0 0 1 0 1" />
</group>
<group>
<path android:fillColor="?attr/pointerIconVectorFill" android:pathData="m19.736 18.003-4.194-4.22a6.547 6.547 0 1 0-1.382 1.226l4.268 4.294a.923.923 0 0 0 1.308-1.3m-9.186-3.91A4.546 4.546 0 1 1 10.549 5a4.546 4.546 0 0 1 .001 9.093" />
diff --git a/core/res/res/layout/notification_template_conversation_icon_container.xml b/core/res/res/layout/notification_template_conversation_icon_container.xml
index 0438dc5b5c81..b45483b09ec2 100644
--- a/core/res/res/layout/notification_template_conversation_icon_container.xml
+++ b/core/res/res/layout/notification_template_conversation_icon_container.xml
@@ -77,7 +77,7 @@
android:scaleType="center"
/>
- <com.android.internal.widget.CachingIconView
+ <com.android.internal.widget.NotificationRowIconView
android:id="@+id/icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 8a98296187b2..5b6de34c831d 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1765,12 +1765,9 @@
<skip />
<!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
<skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Die kenmerk sal oopmaak wanneer jy weer op die toeganklikheidknoppie tik"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Die kenmerk sal oopmaak wanneer jy weer hierdie kortpad gebruik. Swiep vanaf die onderkant van jou skerm met 2 vingers op en los vinnig."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Die kenmerk sal oopmaak wanneer jy weer hierdie kortpad gebruik. Swiep vanaf die onderkant van jou skerm met 3 vingers op en los vinnig."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergroting"</string>
<string name="user_switched" msgid="7249833311585228097">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Skakel tans oor na <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1986,14 +1983,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Oproep aan die gang"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Keur tans \'n inkomende oproep"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Ongekategoriseer"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promosies"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sosiaal"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Nuus"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Aanbevelings"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Jy stel die belangrikheid van hierdie kennisgewings."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Dit is belangrik as gevolg van die mense wat betrokke is."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Gepasmaakte appkennisgewing"</string>
@@ -2210,10 +2203,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Toeganklikheidkortpadkieser op skerm"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Toeganklikheidkortpad"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Maak kennisgewingskerm toe"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Kieslys"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media speel/onderbreek"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-paneel op"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-paneel af"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-paneel links"</string>
@@ -2440,12 +2431,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe dit werk"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Hangend …"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Stel Vingerafdrukslot weer op"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> het nie goed gewerk nie en is uitgevee"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> het nie goed gewerk nie en is uitgevee"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> het nie goed gewerk nie en is uitgevee. Stel dit weer op om jou foon met vingerafdruk te ontsluit."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> het nie goed gewerk nie en is uitgevee. Stel dit weer op om jou foon met jou vingerafdruk te ontsluit."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan nie meer herken word nie."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan nie meer herken word nie."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan nie meer herken word nie. Stel Vingerafdrukslot weer op."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan nie meer herken word nie. Stel Vingerafdrukslot weer op."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Stel Gesigslot weer op"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Jou gesigmodel het nie goed gewerk nie en is uitgevee. Stel dit weer op om jou foon met gesig te ontsluit."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Jou gesigmodel kan nie meer herken word nie. Stel Gesigslot weer op."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Stel op"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nie nou nie"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm vir <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Wissel gebruiker"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Demp"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tik om klank te demp"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 864a5d77d3ce..7b40f305668e 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ገመድ-አልባ debuggingን ለማሰናከል ይምረጡ።"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"የሙከራ ጥቅል ሁነታ ነቅቷል"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"የመሞከሪያ ጥቅል ሁነታን ለማሰናከል የፋብሪካ ዳግም ቅንብርን ይሞክሩ።"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"የተሳሳተ HSUM ግንብ ውቅረት"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"የዚህ መሣሪያ የበይነገፅ-አልባ ሥርዓት ተጠቃሚ ሁነታ ሁኔታ ከግንብ ውቅረቱ ይለያል። እባክዎ መሣሪያውን የፋብሪካ ዳግም ያስጀምሩት።"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"ተከታታይ ኮንሶል ነቅቷል"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"አፈጻጸም ተጽዕኖ አርፎበታል። ለማሰናከል፣ bootloader ን ይፈትሹ።"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"የሙከራ MTE ነቅቷል።"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> በርቷል።"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ጠፍተዋል።"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"የድምጽ መጠን ቁልፎቹን ይልቀቁ። <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን ለማብራት ሁለቱንም የድምጽ መጠን ቁልፎች በድጋሚ ለ3 ሰከንዶች ተጭነው ይያዙ።"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"ባህሪ ይምረጡ"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"ባህሪ ይምረጡ"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"ባህሪ ይምረጡ"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"በቀጣይ ጊዜ የተደራሽነት አዝራሩን መታ ሲያደርጉ ባህሪው ይከፈታል"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"በቀጣይ ጊዜ ይህን አቋራጭ ሲመለከቱ ባህሪው ይከፈታል። ከማያ ገፅዎ ታች በ2 ጣቶች ወደላይ ያንሸራትቱ እና በፍጥነት ይልቀቁ።"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"በቀጣይ ጊዜ ይህን አቋራጭ ሲመለከቱ ባህሪው ይከፈታል። ከማያ ገፅዎ ታች ወደላይ በ3 ጣቶች ያንሸራትቱ እና ወዲያው ይልቀቁ።"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ማጉላት"</string>
<string name="user_switched" msgid="7249833311585228097">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
<string name="user_switching_message" msgid="1912993630661332336">"ወደ <xliff:g id="NAME">%1$s</xliff:g> በመቀየር ላይ…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"ፒን በጣም አጭር ነው። ቢያንስ 4 አሃዝ መሆን አለበት።"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"ቆይተው እንደገና ይሞክሩ"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"ሙሉ ገፅ በማሳየት ላይ"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"ለመውጣት ከማያ ገፅዎ አናት ወደታች ያንሸራትቱ"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"ገባኝ"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ለተሻለ ዕይታ ያሽከርክሩ"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"ለተሻለ ዕይታ <xliff:g id="NAME">%s</xliff:g>ን በሙሉ ገጽ ዕይታ ይክፈቱ"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"እየተካሄደ ያለ ጥሪ"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"ገቢ ጥሪ ማጣራት"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"ያልተመደቡ"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ማስተዋወቂያዎች"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"ማህበራዊ"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ዜና"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"ምክሮች"</string>
<string name="importance_from_user" msgid="2782756722448800447">"የእነዚህን ማሳወቂያዎች አስፈላጊነት አዘጋጅተዋል።"</string>
<string name="importance_from_person" msgid="4235804979664465383">"ይሄ በሚሳተፉ ሰዎች ምክንያት አስፈላጊ ነው።"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"ብጁ የመተግበሪያ ማሳወቂያ"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"የማያ ገፅ ላይ ተደራሽነት አቋራጭ መራጭ"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"የተደራሽነት አቋራጭ"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"የማሳወቂያ ጥላን አሰናብት"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ምናሌ"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ሚዲያ አጫውት/ለአፍታ አቁም"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"ከDpad በላይ"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"ከDpad በታች"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"ከDpad በስተግራ"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"እንዴት እንደሚሠራ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"በመጠባበቅ ላይ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"በጣት አሻራ መክፈቻን እንደገና ያዋቅሩ"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> በደንብ እየሠራ አልነበረም እና ተሰርዟል"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> በደንብ እየሠሩ አልነበረም እና ተሰርዘዋል"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> በደንብ እየሠራ አልነበረም እና ተሰርዟል። ስልክዎን በጣት አሻራ ለመክፈት እንደገና ያዋቅሩት።"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> በደንብ እየሠሩ አልነበረም እና ተሰርዘዋል። ስልክዎን በጣት አሻራ ለመክፈት እንደገና ያዋቅሯቸው።"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ከእንግዲህ መለየት አይችልም።"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ከእንግዲህ መለየት አይችሉም።"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ከእንግዲህ መለየት አይችልም። በጣት አሻራ መክፈቻን እንደገና ያዋቅሩ።"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ከእንግዲህ መለየት አይችሉም። በጣት አሻራ መክፈቻን እንደገና ያዋቅሩ።"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"በመልክ መክፈትን እንደገና ያዋቅሩ"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"የእርስዎ የመልክ ሞዴል በደንብ እየሠራ አልነበረም እና ተሰርዟል። ስልክዎን በመልክ ለመክፈት እንደገና ያዋቅሩት።"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"የመልክ ሞዴልዎ ከእንግዲህ መለየት አይችልም። በመልክ መክፈትን እንደገና ያዋቅሩ።"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ያዋቅሩ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"አሁን አይደለም"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"ለ<xliff:g id="USER_NAME">%s</xliff:g> ማንቂያ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ተጠቃሚ ቀይር"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ድምፀ-ከል አድርግ"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ድምፀ-ከል አድርግ ለማድረግ መታ ያድርጉ"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index eb2eea59bbb3..e17e0b6942d4 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1415,10 +1415,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"انقر لإيقاف ميزة \"تصحيح الأخطاء اللاسلكي\""</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"تم تفعيل وضع \"مفعّل الاختبار\""</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"يمكنك إجراء إعادة ضبط على الإعدادات الأصلية لإيقاف وضع \"مفعِّل اختبار\"."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"‏إعدادات التصميم الخاصة بوضع HSUM غير صحيحة"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"‏إنّ حالة \"وضع النظام بلا واجهة مستخدم رسومية\" (Headless System User Mode) على هذا الجهاز تختلف عن إعدادات تصميمه. يُرجى إعادة ضبط الجهاز على الإعدادات الأصلية."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"وحدة التحكّم التسلسلية مفعّلة"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"الأداء متأثر. لإيقاف وحدة التحكّم، تحقّق من برنامج الإقلاع."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"‏الميزة التجريبية إضافة وضع علامات الذاكرة (MTE) مفعّلة"</string>
@@ -1763,24 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم تفعيل <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم إيقاف <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ارفع إصبعَيك عن مفتاحَي مستوى الصوت. لتفعيل خدمة \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"، اضغط مع الاستمرار على كلا مفتاحَي مستوى الصوت مجددًا لمدة 3 ثوانٍ."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"اختيار ميزة"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"اختيار ميزة"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"اختيار ميزة"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"سيتم فتح الميزة عند النقر على زر أدوات تسهيل الاستخدام في المرة القادمة"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"سيتم فتح الميزة عند استخدام هذا الاختصار في المرة القادمة. مرِّر سريعًا من أسفل الشاشة إلى أعلاها باستخدام إصبعَين وارفعما بعدها بسرعة."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"سيتم فتح الميزة عند استخدام هذا الاختصار في المرة القادمة. مرِّر سريعًا من أسفل الشاشة إلى أعلاها باستخدام 3 أصابع وارفع أصابعك بعدها بسرعة."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"التكبير"</string>
<string name="user_switched" msgid="7249833311585228097">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"جارٍ التبديل إلى <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"جارٍ الخروج <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"المالك"</string>
- <string name="guest_name" msgid="8502103277839834324">"ضيف"</string>
+ <string name="guest_name" msgid="8502103277839834324">"وضع الضيف"</string>
<string name="error_message_title" msgid="4082495589294631966">"خطأ"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"لا يسمح المشرف بإجراء هذا التغيير"</string>
<string name="app_not_found" msgid="3429506115332341800">"لم يتم العثور على تطبيق يمكنه التعامل مع هذا الإجراء."</string>
@@ -1897,8 +1889,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"رقم التعريف الشخصي أقصر مما يلزم، يجب ألا يقل عن ٤ أرقام. "</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"أعد المحاولة لاحقًا"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"جارٍ العرض بملء الشاشة"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"للخروج، مرِّر سريعًا من أسفل الشاشة لأعلاها"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"حسنًا"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"يمكنك تدوير الجهاز لرؤية شاشة معاينة الكاميرا بشكل أوضح."</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"عليك فتح \"<xliff:g id="NAME">%s</xliff:g>\" في وضع ملء الشاشة لرؤية شاشة معاينة الكاميرا بشكل أوضح."</string>
@@ -2438,12 +2429,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"طريقة العمل"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"بانتظار الإزالة من الأرشيف…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"إعادة إعداد ميزة \"فتح الجهاز ببصمة الإصبع\""</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"هناك مشكلة في <xliff:g id="FINGERPRINT">%s</xliff:g> وتم حذفها"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"هناك مشكلة في <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> وتم حذفهما"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"هناك مشكلة في <xliff:g id="FINGERPRINT">%s</xliff:g> وتم حذفها. يُرجى إعدادها مرة أخرى لفتح قفل هاتفك باستخدام بصمة الإصبع."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"هناك مشكلة في <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> وتم حذفهما. يُرجى إعادة إعدادهما لفتح قفل هاتفك باستخدام بصمة الإصبع."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"لا يمكن بعد الآن التعرّف على \"<xliff:g id="FINGERPRINT">%s</xliff:g>\"."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"لا يمكن بعد الآن التعرّف على \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" و\"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\"."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"لا يمكن بعد الآن التعرّف على \"<xliff:g id="FINGERPRINT">%s</xliff:g>\". يجب ضبط ميزة \"فتح الجهاز ببصمة الإصبع\" مجددًا."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"لا يمكن بعد الآن التعرّف على \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" و\"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\". يجب ضبط ميزة \"فتح الجهاز ببصمة الإصبع\" مجددًا."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"إعادة إعداد ميزة \"فتح الجهاز بالتعرّف على الوجه\""</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"هناك مشكلة في نموذج الوجه الخاص بك وتم حذفه. يُرجى إعداده مرة أخرى لفتح قفل هاتفك باستخدام وجهك."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"لا يمكن بعد الآن التعرّف على نموذج الوجه الخاص بك. يجب ضبط ميزة \"فتح الجهاز بالتعرّف على الوجه\" مجددًا."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"إعداد"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"لاحقًا"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"تنبيه لـ \"<xliff:g id="USER_NAME">%s</xliff:g>\""</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"تبديل المستخدم"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"كتم الصوت"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"انقر لكتم الصوت"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 28d5f703bbbd..2642a3228546 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ৱায়াৰলেচ ডি\'বাগিং অক্ষম কৰিবলৈ বাছনি কৰক।"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"টেষ্ট হাৰনেছ ম’ড সক্ষম কৰা আছে"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"টেষ্ট হাৰনেছ ম’ড অক্ষম কৰিবলৈ ফেক্টৰী ৰিছেট কৰক।"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"ভুল HSUM বিল্ডৰ কনফিগাৰেশ্বন"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"এই ডিভাইচৰ পৰিধীয় ডিভাইচহীন ছিষ্টেম ব্যৱহাৰকাৰী ম’ড স্থিতি ইয়াৰ বিল্ডৰ কনফিগাৰেশ্বনৰ পৰা পৃথক। অনুগ্ৰহ কৰি ডিভাইচটো ফেক্টৰী ৰিছেট কৰক।"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"ক্ৰমিক কনছ’ল সক্ষম কৰা আছে"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"কাৰ্যক্ষমতা প্ৰভাৱিত হৈছে। অক্ষম কৰিবলৈ বুটল’ডাৰ পৰীক্ষা কৰক।"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"পৰীক্ষামূলক MTE সক্ষম কৰা হ\'ল"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কীসমূহ ধৰি ৰাখক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰা হ\'ল।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধৰি ৰাখিছিল। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অফ কৰা হ\'ল।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ভলিউম কী এৰি দিয়ক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰিবলৈ, দুয়োটা ভলিউম কী পুনৰ ৩ ছেকেণ্ডৰ বাবে টিপি হেঁচি ৰাখক।"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"এটা সুবিধা বাছনি কৰক"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"এটা সুবিধা বাছনি কৰক"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"এটা সুবিধা বাছনি কৰক"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"আপুনি ইয়াৰ পাছত সাধ্য-সুবিধা বুটামটোত টিপিলে সুবিধাটো খোল খাব"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ইয়াৰ পাছত আপুনি এই শ্বৰ্টকাটটো ব্যৱহাৰ কৰিলে সুবিধাটো খোল খাব। আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ২ টা আঙুলিৰে ছোৱাইপ কৰি আঙুলিকেইটা দ্ৰুতভাৱে উঠাই দিয়ক।"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ইয়াৰ পাছত আপুনি এই শ্বৰ্টকাটটো ব্যৱহাৰ কৰিলে সুবিধাটো খোল খাব। আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ৩ টা আঙুলিৰে ছোৱাইপ কৰি আঙুলিকেইটা দ্ৰুতভাৱে উঠাই দিয়ক।"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"বিবৰ্ধন"</string>
<string name="user_switched" msgid="7249833311585228097">"বৰ্তমানৰ ব্যৱহাৰকাৰী <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>লৈ সলনি কৰি থকা হৈছে…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"পিনটো অতি চুটি। কমেও ৪টা সংখ্যাৰ হ\'ব লাগিব।"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"পাছত আকৌ চেষ্টা কৰক"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"স্ক্ৰীন পূৰ্ণৰূপত চাই আছে"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"বাহিৰ হ’বলৈ, আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে ওপৰৰ পৰা তললৈ ছোৱাইপ কৰক"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"বুজি পালোঁ"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ভালকৈ চাবলৈ ঘূৰাওক"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"ভালকৈ চাবলৈ <xliff:g id="NAME">%s</xliff:g> পূৰ্ণ স্ক্ৰীনত খোলক"</string>
@@ -2434,12 +2425,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ই কেনেকৈ কাম কৰে"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"বিবেচনাধীন হৈ আছে..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ফিংগাৰপ্ৰিণ্ট আনলক পুনৰ ছেট আপ কৰক"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেইটো মচি পেলোৱা হৈছে"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> আৰু <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেয়া মচি পেলোৱা হৈছে"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেইটো মচি পেলোৱা হৈছে। ফিংগাৰপ্ৰিণ্টৰ জৰিয়তে আপোনাৰ ফ’নটো আনলক কৰিবলৈ এইটো পুনৰ ছেট আপ কৰক।"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> আৰু <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেয়া মচি পেলোৱা হৈছে। ফিংগাৰপ্ৰিণ্টৰ জৰিয়তে আপোনাৰ ফ’নটো আনলক কৰিবলৈ সেয়া পুনৰ ছেট আপ কৰক।"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> আৰু চিনাক্ত কৰিব নোৱাৰি।"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> আৰু <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> আৰু চিনাক্ত কৰিব নোৱাৰি।"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> আৰু চিনাক্ত কৰিব নোৱাৰি। ফিংগাৰপ্ৰিণ্ট আনলক পুনৰ ছেট আপ কৰক।"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> আৰু <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> আৰু চিনাক্ত কৰিব নোৱাৰি। ফিংগাৰপ্ৰিণ্ট আনলক পুনৰ ছেট আপ কৰক।"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ফে’চ আনলক পুনৰ ছেট আপ কৰক"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"আপোনাৰ মুখাৱয়বৰ মডেলটোৱে ভালদৰে কাম কৰা নাছিল আৰু সেইটো মচি পেলোৱা হৈছে। মুখাৱয়বৰ জৰিয়তে আপোনাৰ ফ’নটো আনলক কৰিবলৈ এইটো পুনৰ ছেট আপ কৰক।"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"আপোনাৰ মুখাৱয়বৰ মডেলটো আৰু চিনাক্ত কৰিব নোৱাৰি। ফে’চ আনলক পুনৰ ছেট আপ কৰক।"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ছেট আপ কৰক"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"এতিয়া নহয়"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>ৰ বাবে এলাৰ্ম"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"মিউট কৰক"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ধ্বনি মিউট কৰিবলৈ টিপক"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"ব্ৰাউজাৰ"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"সম্পৰ্ক"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"ইমেইল"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"এছএমএছ"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"সংগীত"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"কেলেণ্ডাৰ"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"কেলকুলেটৰ"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"মেপ"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"এপ্লিকেশ্বন"</string>
</resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 8d687779b643..90db2d46c0ae 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"WiFi sazlamasını deaktiv etmək üçün seçin."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Rejimi aktivdir"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Test Rejimini deaktiv etmək üçün fabrika ayarlarına sıfırlayın."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Yanlış HSUM qurma konfiqurasiyası"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Bu cihazın Monitorsuz sistem üzrə istifadəçi rejimindəki vəziyyəti onun konfiqurasiyasından fərqlənir. Cihazda zavod sıfırlaması edin."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Ardıcıl konsol aktiv edildi"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performans təsirlənir. Söndürməkçün yükləyicini yoxlayın."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimental MTE aktiv edilib"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Səs səviyyəsi düymələrinə basıb saxlayın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiv edildi."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Səs səviyyəsi düymələrinə basılaraq saxlanıb. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> deaktiv edilib."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Səs düymələrini buraxın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xidmətini aktiv etmək üçün hər iki səs düyməsinə yenidən 3 saniyə basıb saxlayın."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Funksiya seçin"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Funksiya seçin"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Funksiya seçin"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Növbəti dəfə xüsusi imkanlar düyməsinə toxunduğunuz zaman funksiya açılacaq"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Növbəti dəfə bu qısayoldan istifadə etdiyiniz zaman funksiya açılacaq. Ekranın aşağısından 2 barmaq ilə yuxarı çəkin və tez buraxın."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Növbəti dəfə bu qısayoldan istifadə etdiyiniz zaman funksiya açılacaq. Ekranın aşağısından 3 barmaq ilə yuxarı çəkin və tez buraxın."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Böyütmə"</string>
<string name="user_switched" msgid="7249833311585228097">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adına keçirilir…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PİN çox qısadır. Ən azı 4 rəqəm olmalıdır."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Daha sonra yenidən yoxlayın."</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Tam ekrana baxış"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Çıxmaq üçün ekranın yuxarısından aşağı çəkin"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Anladım"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Daha yaxşı görünüş üçün fırladın"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Yaxşı görmək üçün <xliff:g id="NAME">%s</xliff:g> tətbiqini tam ekranda açın"</string>
@@ -2427,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Şəxsi sahə"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Həssas bildiriş kontenti gizlədildi"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Güvənlik üçün tətbiq kontenti ekran paylaşımından gizlədildi"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Tətbiq kontenti güvənlik məsələlərinə görə ekran paylaşımından gizlədildi"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Peykə avtomatik qoşulub"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil və ya Wi-Fi şəbəkəsi olmadan mesaj göndərə və qəbul edə bilərsiniz"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajı açın"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Haqqında"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Gözləmədə..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmaqla Kilidaçmanı yenidən ayarlayın"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxşı işləmirdi və silindi"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxşı işləmirdi və silindi"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxşı işləmirdi və silindi. Telefonu barmaq izi ilə kiliddən çıxarmaq üçün onu yenidən ayarlayın."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxşı işləmirdi və silindi. Telefonu barmaq izi ilə kiliddən çıxarmaq üçün onları yenidən ayarlayın."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> artıq tanınmır."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artıq tanınmır."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> artıq tanınmır. Barmaqla Kilidaçmanı yenidən ayarlayın."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artıq tanınmır. Barmaqla Kilidaçmanı yenidən ayarlayın."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Üzlə Kilidaçmanı yenidən ayarlayın"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Üz modeliniz yaxşı işləmirdi və silindi. Telefonu üzlə kiliddən çıxarmaq üçün onu yenidən ayarlayın."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Üz modeliniz artıq tanınmır. Üzlə Kilidaçmanı yenidən ayarlayın."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ayarlayın"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"İndi yox"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> üçün alarm"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"İstifadəçini dəyişin"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Susdurun"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Susdurmaq üçün toxunun"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index c537ffff8611..a2a885bad85a 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -517,11 +517,11 @@
<string name="permlab_activityRecognition" msgid="1782303296053990884">"prepoznavanje fizičkih aktivnosti"</string>
<string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ova aplikacija može da prepozna fizičke aktivnosti."</string>
<string name="permlab_camera" msgid="6320282492904119413">"snimanje fotografija i videa"</string>
- <string name="permdesc_camera" msgid="5240801376168647151">"Ova aplikacija može da snima slike i video snimke pomoću kamere dok se aplikacija koristi."</string>
- <string name="permlab_backgroundCamera" msgid="7549917926079731681">"da snima slike i video snimke u pozadini"</string>
+ <string name="permdesc_camera" msgid="5240801376168647151">"Ova aplikacija može da snima slike i video pomoću kamere dok se aplikacija koristi."</string>
+ <string name="permlab_backgroundCamera" msgid="7549917926079731681">"da snima slike i video u pozadini"</string>
<string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ova aplikacija može da snima fotografije i video snimke pomoću kamere u bilo kom trenutku."</string>
<string name="permlab_systemCamera" msgid="3642917457796210580">"Dozvolite nekoj aplikaciji ili usluzi da pristupa kamerama sistema da bi snimala slike i video snimke"</string>
- <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ova privilegovana sistemska aplikacija može da snima slike i video snimke pomoću kamere sistema u bilo kom trenutku. Aplikacija treba da ima i dozvolu android.permission.CAMERA"</string>
+ <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ova privilegovana sistemska aplikacija može da snima slike i video pomoću kamere sistema u bilo kom trenutku. Aplikacija treba da ima i dozvolu android.permission.CAMERA"</string>
<string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Dozvolite aplikaciji ili usluzi da dobija povratne pozive o otvaranju ili zatvaranju uređaja sa kamerom."</string>
<string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Ova aplikacija može da dobija povratne pozive kada se bilo koji uređaj sa kamerom otvara ili zatvara (pomoću neke aplikacije)."</string>
<string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"Dozvolite aplikaciji ili usluzi da pristupa kameri kao korisnik sistema bez grafičkog korisničkog interfejsa."</string>
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Izaberite da biste onemogućili bežično otklanjanje grešaka."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Omogućen je režim probnog korišćenja"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Obavite resetovanje na fabrička podešavanja da biste onemogućili režim probnog korišćenja."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Pogrešna HSUM konfiguracija"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Status korisničkog režima sistema bez grafičkog korisničkog interfejsa za ovaj uređaj razlikuje se od njegove konfiguracije. Resetujte uređaj na fabrička podešavanja."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola je omogućena"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performanse su smanjene. Da biste onemogući konzolu, proverite pokretački program."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentalni MTE je omogućen"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tastere za jačinu zvuka. Da biste uključili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite oba tastera za jačinu zvuka 3 sekunde."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Izaberite funkciju"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Izaberite funkciju"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Izaberite funkciju"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcija će se otvoriti kada sledeći put dodirnete dugme Pristupačnost"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija će se otvoriti kada sledeći put budete koristili ovu prečicu. Prevucite nagore od dna ekrana sa 2 prsta i brzo pustite."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija će se otvoriti kada sledeći put budete koristili ovu prečicu. Prevucite nagore od dna ekrana sa 3 prsta i brzo pustite."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Uvećanje"</string>
<string name="user_switched" msgid="7249833311585228097">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN je prekratak. Mora da ima bar 4 cifre."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Probajte ponovo kasnije"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Prikazuje se ceo ekran"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Da biste zatvorili, prevucite nadole od vrha ekrana"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Važi"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotirajte radi boljeg prikaza"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Otvorite aplikaciju <xliff:g id="NAME">%s</xliff:g> preko celog ekrana da biste bolje videli"</string>
@@ -2435,12 +2426,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Princip rada"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovo podesite otključavanje otiskom prsta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nije funkcionisao i izbrisali smo ga"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu funkcionisali i izbrisali smo ih"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nije funkcionisao i izbrisali smo ga. Ponovo ga podesite da biste telefon otključavali otiskom prsta."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu funkcionisali i izbrisali smo ih. Ponovo ih podesite da biste telefon otključavali otiskom prsta."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> više ne može da se prepozna."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> više ne mogu da se prepoznaju."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> više ne može da se prepozna. Ponovo podesite otključavanje otiskom prsta."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> više ne mogu da se prepoznaju. Ponovo podesite otključavanje otiskom prsta."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovo podesite otključavanje licem"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Vaš model lica nije funkcionisao i izbrisali smo ga. Ponovo ga podesite da biste telefon otključavali licem."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Vaš model lica više ne može da se prepozna. Ponovo podesite otključavanje licem."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Podesi"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sada"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Promeni korisnika"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Isključi zvuk"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dodirnite da biste isključili zvuk"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index e6391df97ed1..18d5698ae460 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1413,10 +1413,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Выберыце, каб выключыць адладку па Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Тэставы рэжым уключаны"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Каб выключыць тэставы рэжым, скіньце налады да заводскіх значэнняў."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Канфігурацыя рэжыму кансольнага сістэмнага карыстальніка не адпавядае зборцы"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Стан рэжыму кансольнага сістэмнага карыстальніка на гэтай прыладзе не адпавядае канфігурацыі яе зборкі. Скіньце прыладу да заводскіх налад."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Паслядоўная кансоль уключана"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Паказчык прадукцыйнасці змяніўся. Каб выключыць кансоль, праверце загрузчык."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Эксперыментальнае пашырэнне тэгаў памяці (MTE) уключана"</string>
@@ -1761,18 +1759,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Клавішы гучнасці ўтрымліваліся націснутымі. Уключана служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Клавішы гучнасці ўтрымліваліся націснутымі. Служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" выключана."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Адпусціце клавішы гучнасці. Каб уключыць сэрвіс \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", націсніце абедзве клавішы гучнасці яшчэ раз і ўтрымлівайце іх на працягу 3 секунд."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Выберыце функцыю"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Выберыце функцыю"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Выберыце функцыю"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функцыя адкрыецца, калі вы наступным разам націснеце на кнопку спецыяльных магчымасцей"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функцыя адкрыецца, калі вы наступным разам выкарыстаеце гэты хуткі доступ. Правядзіце двума пальцамі ад нізу экрана ўверх і хутка адпусціце."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функцыя адкрыецца, калі вы наступным разам выкарыстаеце гэты хуткі доступ. Правядзіце трыма пальцамі ад нізу экрана ўверх і хутка адпусціце."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Павелічэнне"</string>
<string name="user_switched" msgid="7249833311585228097">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Пераход у рэжым \"<xliff:g id="NAME">%1$s</xliff:g>\"..."</string>
@@ -1895,8 +1887,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN-код занадта кароткі. Павінен змяшчаць не менш за 4 лічбы."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Паўтарыце спробу пазней"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Прагляд у поўнаэкранным рэжыме"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Каб выйсці, правядзіце пальцам уніз ад верхняга краю экрана"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Зразумела"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Павярнуць для лепшага прагляду"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Для больш зручнага прагляду адкрыйце праграму \"<xliff:g id="NAME">%s</xliff:g>\", выкарыстоўваючы поўнаэкранны рэжым"</string>
@@ -1988,14 +1979,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Бягучы выклік"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Фільтраванне ўваходнага выкліку"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Некатэгарызаванае"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Прома-акцыі"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Сацыяльныя сеткі"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Навіны"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Рэкамендацыі"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Вы задалі важнасць гэтых апавяшчэнняў."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Гэта важна, бо з гэтым звязаны пэўныя людзі."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Апавяшчэнне пра карыстальніцкую праграму"</string>
@@ -2212,10 +2199,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Налада хуткага доступу да спецыяльных магчымасцей на экране"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Хуткі доступ"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Закрыць шчыток апавяшчэнняў"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Прайграць або прыпыніць медыяфайл"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Уверх на панэлі кіравання"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Уніз на панэлі кіравання"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Улева на панэлі кіравання"</string>
@@ -2442,12 +2427,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як гэта працуе"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"У чаканні..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Наладзіць разблакіроўку адбіткам пальца паўторна"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Адбітак пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" не працаваў належным чынам і быў выдалены"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Адбіткі пальцаў \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" не працавалі належным чынам і былі выдалены"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Адбітак пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" не працаваў належным чынам і быў выдалены. Каб мець магчымасць разблакіраваць тэлефон з дапамогай адбітка пальца, наладзьце яго яшчэ раз."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Адбіткі пальцаў \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" не працавалі належным чынам і былі выдалены. Каб мець магчымасць разблакіраваць тэлефон з дапамогай адбітка пальца, наладзьце іх яшчэ раз."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Адбітак пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больш не можа быць распазнаны."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Адбіткі пальцаў \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больш не могуць быць распазнаны."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Адбітак пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больш не можа быць распазнаны. Паўторна наладзьце разблакіроўку адбіткам пальца."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Адбіткі пальцаў \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больш не могуць быць распазнаны. Паўторна наладзьце разблакіроўку адбіткам пальца."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Паўторна наладзьце распазнаванне твару"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Мадэль твару не працавала належным чынам і была выдалена. Каб мець магчымасць разблакіраваць тэлефон з дапамогай распазнавання твару, наладзьце яго яшчэ раз."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Мадэль твару больш не можа быць распазнана. Паўторна наладзьце распазнаванне твару."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Наладзіць"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не зараз"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будзільнік карыстальніка <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Змяніць карыстальніка"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Выключыць гук"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Націсніце, каб выключыць гук"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 4a12c2bc23b7..ea49f521560b 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Изберете, за да деактивирате безжичното отстраняване на грешки."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Режимът за тестова среда е активиран"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Възстановете фабричните настройки, за да деактивирате режима за тестова среда."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Грешна конфигурация на компилацията за режима на потребител на система без графичен потребителски интерфейс"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Състоянието на устройството в режима на потребител на система без графичен потребителски интерфейс се различава от това в конфигурацията на компилация. Моля, възстановете фабричните настройки на устройството."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Серийната конзола е активирана"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ефективността е засегната. За да деактивирате, проверете програмата за първоначално зареждане."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Експерименталното разширение MTE е активирано"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е включена."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е изключена."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Освободете бутоните за силата на звука. За да включите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, отново натиснете двата бутона за силата на звука и задръжте за 3 секунди."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Изберете функция"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Изберете функция"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Изберете функция"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функцията ще се отвори при следващото докосване бутона за достъпност"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функцията ще се отвори при следващото използване на този пряк път. Прекарайте 2 пръста нагоре от долната част на екрана и бързо освободете."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функцията ще се отвори при следващото използване на този пряк път. Прекарайте 3 пръста нагоре от долната част на екрана и бързо освободете."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увеличение"</string>
<string name="user_switched" msgid="7249833311585228097">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Превключва се към: <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"ПИН кодът е твърде кратък. Трябва да е поне 4 цифри."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Опитайте отново по-късно"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Изглед на цял екран"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"За изход плъзнете надолу от горната част на екрана"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Разбрах"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Завъртете за по-добър изглед"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Отворете <xliff:g id="NAME">%s</xliff:g> на цял екран за по-добър изглед"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Начин на работа"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Изчаква..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Повторно настройване на „Отключване с отпечатък“"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Отпечатъкът „<xliff:g id="FINGERPRINT">%s</xliff:g>“ бе изтрит, защото не работеше добре"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Отпечатъците „<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>“ и „<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>“ бяха изтрити, защото не работеха добре"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Отпечатъкът „<xliff:g id="FINGERPRINT">%s</xliff:g>“ бе изтрит, защото не работеше добре. Настройте го отново, за да отключвате телефона си с отпечатък."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Отпечатъците „<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>“ и „<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>“ бяха изтрити, защото не работеха добре. Настройте ги отново, за да отключвате телефона си с отпечатък."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> вече не може да се разпознае."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> вече не могат да бъдат разпознати."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> вече не може да се разпознае. Настройте отново „Отключване с отпечатък“."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> вече не могат да бъдат разпознати. Настройте отново „Отключване с отпечатък“."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Повторно настройване на „Отключване с лице“"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Моделът на лицето ви бе изтрит, защото не работеше добре. Настройте го отново, за да отключвате телефона си с лице."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Моделът на лицето ви вече не може да бъде разпознат. Настройте отново „Отключване с лице“."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Настройване"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сега"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будилник за <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Смяна на потребителя"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Спиране на звука"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Докоснете, за да спрете звука"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index b895d7f317b3..354899358dbc 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ওয়্যারলেস ডিবাগিং বন্ধ করতে বেছে নিন।"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"টেস্ট হারনেস মোড চালু আছে"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"টেস্ট হারনেস মোড বন্ধ করতে ফ্যাক্টরি রিসেট করুন।"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM বিল্ড কনফিগারেশন ভুল আছে"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"এই ডিভাইসের হেডলেস সিস্টেম ইউজার মোড স্ট্যাটাস, তার বিল্ড কনফিগারেশনের থেকে আলাদা। আপনার ডিভাইস ফ্যাক্টরি রিসেট করুন।"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"সিরিয়াল কনসোল চালু করা হয়েছে"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"পারফর্ম্যান্সে এর প্রভাব পড়বে। চালানো বন্ধ করতে \'বুটলোডার\' প্রোগ্রামে এটিকে চেক করে দেখুন।"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"পরীক্ষামূলক MTE চালু আছে"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করা হয়েছে।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> বন্ধ করা হয়েছে।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ভলিউম \'কী\' রিলিজ করুন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করুন, দু\'টি ভলিউম \'কী\' আবার প্রেস করে ৩ সেকেন্ড ধরে রাখুন।"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"ফিচার বেছে নিন"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"ফিচার বেছে নিন"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"ফিচার বেছে নিন"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"পরের বার অ্যাক্সেসিবিলিটি বোতামে ট্যাপ করলে, ফিচারটি চালু হয়ে যাবে"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"পরের বার এই শর্টকাট ব্যবহার করলে, ফিচারটি চালু হয়ে যাবে। ২টি আঙ্গুল দিয়ে স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করে দ্রুত ছেড়ে দিন।"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"পরের বার এই শর্টকাট ব্যবহার করলে, ফিচারটি চালু হয়ে যাবে। ৩টি আঙ্গুল দিয়ে স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করে দ্রুত ছেড়ে দিন।"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"বড় করে দেখা"</string>
<string name="user_switched" msgid="7249833311585228097">"বর্তমান ব্যবহারকারী <xliff:g id="NAME">%1$s</xliff:g>৷"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> প্রোফাইলে পাল্টানো হচ্ছে…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"পিন খুবই ছোট৷ এটিকে কমপক্ষে ৪ সংখ্যার হতে হবে৷"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"পরে আবার চেষ্টা করুন"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"পূর্ণ স্ক্রিনে দেখা হচ্ছে"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"বেরিয়ে আসতে, আপনার স্ক্রিনের একেবারে উপর থেকে নিচের দিকে সোয়াইপ করুন"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"বুঝেছি"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"আরও ভাল ক্যামেরা ভিউ পাওয়ার জন্য ঘোরান"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"আরও ভাল ভিউয়ের জন্য ফুল স্ক্রিনে <xliff:g id="NAME">%s</xliff:g> খুলুন"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"এটি কীভাবে কাজ করে"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"বাকি আছে…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"\'ফিঙ্গারপ্রিন্ট আনলক\' আবার সেট-আপ করুন"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ভালোভাবে কাজ করছিল না এবং সেটি মুছে ফেলা হয়েছে"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ও <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ভালোভাবে কাজ করছিল না এবং মুছে ফেলা হয়েছে"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ভালোভাবে কাজ করছিল না বলে সেটি মুছে ফেলা হয়েছে। ফিঙ্গারপ্রিন্ট ব্যবহার করে আপনার ফোন আনলক করতে হলে এটি আবার সেট-আপ করুন।"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ও <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ভালোভাবে কাজ করছিল না বলে মুছে ফেলা হয়েছে। ফিঙ্গারপ্রিন্ট ব্যবহার করে আপনার ফোন আনলক করতে হলে সেগুলি আবার সেট-আপ করুন।"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> আর শনাক্ত করা যাবে না।"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ও <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> আর শনাক্ত করা যাবে না।"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> আর শনাক্ত করা যাবে না। ফিঙ্গারপ্রিন্ট আনলক আবার সেট-আপ করুন।"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ও <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> আর শনাক্ত করা যাবে না। ফিঙ্গারপ্রিন্ট আনলক আবার সেট-আপ করুন।"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"\'ফেস আনলক\' আবার সেট-আপ করুন"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"আপনার ফেস মডেল ভালোভাবে কাজ করছিল না বলে সেটি মুছে ফেলা হয়েছে। ফেস ব্যবহার করে আপনার ফোন আনলক করতে হলে এটি আবার সেট-আপ করুন।"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"আপনার ফেস মডেল আর শনাক্ত করা যাবে না। ফেস আনলক আবার সেট-আপ করুন।"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"সেট-আপ করুন"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"এখন নয়"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>-এর জন্য অ্যালার্ম"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ব্যবহারকারী পাল্টান"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"মিউট করুন"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"সাউন্ড মিউট করতে ট্যাপ করুন"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 0e4ce17bdea8..eb66410b3f69 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Odaberite da onemogućite bežično otklanjanje grešaka."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Omogućen način rada okvira za testiranje"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Izvršite vraćanje na fabričke postavke da onemogućite način rada okvira za testiranje."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Pogrešna konfiguracija HSUM-a"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Stanje korisnika sistema bez grafičkog korisničkog interfejsa se razlikuje od njegove konfiguracije. Vratite uređaj na fabričke postavke."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola omogućena"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performanse su smanjene. Da onemogućite, provjerite program za učitavanje operativnog sistema."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentalni MTE je omogućen"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tipke za jačinu zvuka. Da uključite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite obje tipke za jačinu zvuka 3 sekunde."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Odaberite funkciju"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Odaberite funkciju"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Odaberite funkciju"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcija će se otvoriti sljedeći put kada dodirnete dugme za pristupačnost"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija će se otvoriti sljedeći put kada upotrijebite ovu prečicu. Prevucite s 2 prsta s dna ekrana i brzo pustite."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija će se otvoriti sljedeći put kada upotrijebite ovu prečicu. Prevucite s 3 prsta s dna ekrana i brzo pustite."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Uvećavanje"</string>
<string name="user_switched" msgid="7249833311585228097">"Trenutni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN je prekratak. Mora imati najmanje 4 cifre."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Pokušajte ponovo kasnije."</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Prikazuje se cijeli ekran"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Da izađete, prevucite s vrha ekrana nadolje"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Razumijem"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotirajte za bolji prikaz"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Otvorite aplikaciju <xliff:g id="NAME">%s</xliff:g> preko cijelog ekrana radi boljeg pregleda"</string>
@@ -1988,7 +1979,7 @@
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtriranje dolaznog poziva"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Nije kategorizirano"</string>
<string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocije"</string>
- <string name="social_notification_channel_label" msgid="106520267132019945">"Društvene mreže"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Društveni mediji"</string>
<string name="news_notification_channel_label" msgid="4299937455247883311">"Vijesti"</string>
<string name="recs_notification_channel_label" msgid="4945985121418684297">"Preporuke"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Vi određujete značaj ovih obavještenja."</string>
@@ -2207,8 +2198,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Okvir za odabir prečice za pristupačnost na ekranu"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečica za pristupačnost"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbacite lokaciju za obavještenja"</string>
- <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Izbornik"</string>
- <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reproduciraj/pauziraj medijske sadržaje"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meni"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reprodukcija/pauziranje medijskog sadržaja"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Upravljač gore"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Upravljač dolje"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Upravljač lijevo"</string>
@@ -2435,12 +2426,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako ovo funkcionira"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovo postavite otključavanje otiskom prsta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao, pa je izbrisan"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali, pa su izbrisani"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao, pa je izbrisan. Postavite ga ponovo da otključavate telefon otiskom prsta."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali, pa su izbrisani. Postavite ih ponovo da otključavate telefon otiskom prsta."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> se više ne može prepoznati."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se više ne mogu prepoznati."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> se više ne može prepoznati. Ponovo postavite otključavanje otiskom prsta."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se više ne mogu prepoznati. Ponovo postavite otključavanje otiskom prsta."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovo postavite otključavanje licem"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model lica nije dobro funkcionirao, pa je izbrisan. Postavite ga ponovo da otključavate telefon licem."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Vaš model lica se više ne može prepoznati. Ponovo postavite otključavanje licem."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Postavite"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sada"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Prebaci na drugog korisnika"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Isključi zvuk"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dodirnite da isključite zvuk"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index c1b740a4c1a5..9e5c336b9b6a 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecciona per desactivar la depuració sense fil."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"S\'ha activat el mode Agent de prova"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Si vols desactivar el mode Agent de prova, restableix les dades de fàbrica."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Configuració de la compilació HSUM incorrecta"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"L\'estat del mode d\'usuari del sistema sense interfície gràfica d\'aquest dispositiu és diferent de la configuració de la seva compilació. Restableix les dades de fàbrica del dispositiu."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"S\'ha activat la consola de sèrie"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Afecta el rendiment. Per desactivar-la, comprova el bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"L\'MTE experimental s\'ha activat"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S\'han mantingut premudes les tecles de volum. S\'ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S\'han mantingut premudes les tecles de volum. S\'ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Deixa anar les tecles de volum. Per activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, torna a mantenir premudes totes dues tecles de volum durant 3 segons."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Tria una funció"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Tria una funció"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Tria una funció"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La funció s\'obrirà la pròxima vegada que toquis el botó d\'accessibilitat"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La funció s\'obrirà la pròxima vegada que utilitzis aquesta drecera. Llisca cap amunt amb 2 dits des de la part inferior de la pantalla i aixeca\'ls ràpidament."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La funció s\'obrirà la pròxima vegada que utilitzis aquesta drecera. Llisca cap amunt amb 3 dits des de la part inferior de la pantalla i aixeca\'ls ràpidament."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliació"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"S\'està canviant a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"El PIN és massa curt. Ha de tenir quatre dígits com a mínim."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Torna-ho a provar més tard"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Mode de pantalla completa"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Per sortir, llisca cap avall des de la part superior de la pantalla"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Entesos"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gira per a una millor visualització"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Obre <xliff:g id="NAME">%s</xliff:g> en pantalla completa per a una millor visualització"</string>
@@ -1987,14 +1978,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Trucada en curs"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"S\'està filtrant una trucada entrant"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sense classificar"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocions"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Notícies"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomanacions"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Has definit la importància d\'aquestes notificacions."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Aquest missatge és important per les persones implicades."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificació d\'aplicació personalitzada"</string>
@@ -2211,10 +2198,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector de dreceres d\'accessibilitat en pantalla"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Drecera d\'accessibilitat"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignora l\'àrea de notificacions"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menú"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reprodueix o posa en pausa el contingut multimèdia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Creu direccional: amunt"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Creu direccional: avall"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Creu direccional: esquerra"</string>
@@ -2434,19 +2419,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espai privat"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"S\'ha amagat contingut sensible de les notificacions"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contingut de l\'aplicació amagat de la compartició de pantalla per motius de seguretat"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contingut de l\'aplicació amagat de la compartició de pantalla per seguretat"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"S\'ha connectat automàticament a un satèl·lit"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Pots enviar i rebre missatges sense una xarxa mòbil o Wi‑Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Obre Missatges"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Com funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendent..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Torna a configurar Desbloqueig amb empremta digital"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionava correctament i s\'ha suprimit"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaven correctament i s\'han suprimit"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionava correctament i s\'ha suprimit. Torna a configurar-la per desbloquejar el telèfon amb l\'empremta digital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaven correctament i s\'han suprimit. Torna a configurar-les per desbloquejar el telèfon amb l\'empremta digital."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ja no es pot reconèixer."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ja no es poden reconèixer."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ja no es pot reconèixer. Torna a configurar Desbloqueig amb empremta digital."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ja no es poden reconèixer. Torna a configurar Desbloqueig amb empremta digital."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Torna a configurar Desbloqueig facial"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"El teu model facial no funcionava correctament i s\'ha suprimit. Torna a configurar-lo per desbloquejar el telèfon amb la cara."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"El teu model facial ja no es pot reconèixer. Torna a configurar Desbloqueig facial."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configura"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ara no"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma per a <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Canvia d\'usuari"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silencia"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toca per silenciar el so"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 3caf4a2cadef..78b79cb227e6 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1413,10 +1413,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Vyberte, chcete-li zakázat bezdrátové ladění."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Režim správce testů je aktivní"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Chcete-li deaktivovat režim správce testů, restartujte zařízení do továrního nastavení."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Nesprávná konfigurace sestavení HSUM"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Stav systémového uživatele bez grafické vrstvy (HSUM) tohoto zařízení se liší od konfigurace sestavení. Resetujte zařízení do továrního nastavení."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Je zapnutá sériová konzole"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Toto má dopad na výkon. Chcete-li ji vypnout, zkontrolujte bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Je zapnuto experimentální MTE"</string>
@@ -1441,7 +1439,7 @@
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Zobrazení přes ostatní aplikace"</string>
<string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"Aplikace <xliff:g id="NAME">%s</xliff:g> se zobrazuje přes ostatní aplikace"</string>
- <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> se zobrazuje přes ostatní aplikace"</string>
+ <string name="alert_windows_notification_title" msgid="6331662751095228536">"Aplikace <xliff:g id="NAME">%s</xliff:g> se zobrazuje přes ostatní aplikace"</string>
<string name="alert_windows_notification_message" msgid="6538171456970725333">"Pokud nechcete, aby aplikace <xliff:g id="NAME">%s</xliff:g> tuto funkci používala, klepnutím otevřete nastavení a funkci vypněte."</string>
<string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Vypnout"</string>
<string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Kontroluje se <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1761,18 +1759,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> byla vypnuta."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Uvolněte tlačítka hlasitosti. Pokud chcete zapnout službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znovu tři sekundy podržte obě tlačítka hlasitosti."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Vyberte funkci"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Vyberte funkci"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Vyberte funkci"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkce se otevře, až příště klepnete na tlačítko přístupnosti"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkce se otevře při příštím použití této zkratky. Přejeďte dvěma prsty nahoru ze spodní části obrazovky a rychle je zvedněte."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkce se otevře při příštím použití této zkratky. Přejeďte třemi prsty nahoru ze spodní části obrazovky a rychle je zvedněte."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zvětšení"</string>
<string name="user_switched" msgid="7249833311585228097">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Přepínání na uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1895,8 +1887,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Kód PIN je příliš krátký. Musí mít alespoň čtyři číslice."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Zkuste to znovu později"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Zobrazení celé obrazovky"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Tento režim ukončíte přejetím prstem dolů z horního okraje obrazovky"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Rozumím"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Otočte obrazovku, abyste lépe viděli"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Otevřete aplikaci <xliff:g id="NAME">%s</xliff:g> na celou obrazovku, aby byla lépe vidět"</string>
@@ -1988,14 +1979,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Probíhající hovor"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Prověřování příchozího hovoru"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Neklasifikováno"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoakce"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sociální sítě"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Zprávy"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Doporučení"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Důležitost oznámení určujete vy."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Tato zpráva je důležitá kvůli lidem zapojeným do konverzace."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Vlastní oznámení aplikace"</string>
@@ -2212,10 +2199,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Výběr zkratky přístupnosti na obrazovce"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Zkratka přístupnosti"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Zavřít panel oznámení"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Nabídka"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Přehrát/pozastavit média"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad nahoru"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad dolů"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad doleva"</string>
@@ -2442,12 +2427,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to funguje"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Čeká na vyřízení…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Opětovné nastavení odemknutí otiskem prstu"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správně a byl vymazán"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovaly správně a byly vymazány"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správně a byl vymazán. Pokud chcete telefon odemykat otiskem prstu, nastavte jej znovu."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovaly správně a byly vymazány. Pokud chcete telefon odemykat otiskem prstu, nastavte je znovu."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> se nedaří rozpoznat."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se nedaří rozpoznat."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> se nedaří rozpoznat. Nastavte odemknutí otiskem prstu znovu."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se nedaří rozpoznat. Nastavte odemknutí otiskem prstu znovu."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Nastavte odemknutí obličejem znovu"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Váš model obličeje nefungoval správně a byl vymazán. Pokud chcete telefon odemykat obličejem, nastavte jej znovu."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Váš model obličeje se nedaří rozpoznat. Nastavte odemknutí obličejem znovu."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastavit"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Teď ne"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Budík pro uživatele <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Přepnout uživatele"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ztlumit"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Klepnutím ztlumíte zvuk"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 66daf446b4d9..b7e70ef6f7eb 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Vælg for at deaktivere trådløs fejlretning."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Tilstanden Testsele er aktiveret"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Gendan fabriksindstillingerne for at deaktivere tilstanden Testsele."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Forkert HSUM-buildkonfiguration"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Tilstanden systembruger uden grafisk brugerflade på denne enhed er forskellig fra dens buildkonfiguration. Gendan enhedens fabriksindstillinger."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Seriekonsollen er aktiveret"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Effektiviteten er påvirket. Deaktiver via bootloaderen."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentel MTE er aktiveret"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er aktiveret."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er deaktiveret."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slip lydstyrkeknapperne. Du kan aktivere <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ved at holde begge lydstyrkeknapper nede igen i 3 sekunder."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Vælg en funktion"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Vælg en funktion"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Vælg en funktion"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funktionen åbnes næste gang, du trykker på knappen til hjælpefunktioner"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funktionen åbnes næste gang, du bruger denne genvej. Stryg opad fra bunden af skærmen med 2 fingre, og slip derefter hurtigt."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funktionen åbnes næste gang, du bruger denne genvej. Stryg opad fra bunden af skærmen med 3 fingre, og slip derefter hurtigt."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Forstørrelse"</string>
<string name="user_switched" msgid="7249833311585228097">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Skifter til <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Pinkoden er for kort. Den skal være på mindst 4 tal."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Prøv igen senere"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Visning i fuld skærm"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Stryg nedad fra toppen af skærmen for at afslutte"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"OK, det er forstået"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Roter, og få en bedre visning"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Åbn <xliff:g id="NAME">%s</xliff:g> i fuld skærm for at få en bedre visning"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Igangværende opkald"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Et indgående opkald screenes"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Uden kategori"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoveringer"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Socialt"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Nyheder"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Anbefalinger"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Du angiver, hvor vigtige disse notifikationer er."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Dette er vigtigt på grund af de personer, det handler om."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Tilpasset appnotifikation"</string>
@@ -2158,7 +2145,7 @@
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Denne notifikation blev placeret højere. Tryk for at give feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Denne notifikation blev placeret lavere. Tryk for at give feedback."</string>
<string name="nas_upgrade_notification_title" msgid="8436359459300146555">"Forbedrede notifikationer"</string>
- <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"Foreslåede handlinger og svar leveres nu via forbedrede notifikationer. Tilpassede Android-notifikationer understøttes ikke længere."</string>
+ <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"Foreslåede handlinger og svar leveres nu via forbedrede notifikationer. Adaptive Android-notifikationer understøttes ikke længere."</string>
<string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
<string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Deaktiver"</string>
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Få flere oplysninger"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Valg af genvej til hjælpefunktioner på skærmen"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Genvej til hjælpefunktioner"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Luk notifikationspanel"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Afspil medie/sæt medie på pause"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad, op"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad, ned"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad, venstre"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Sådan fungerer det"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Afventer…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer fingeroplåsning igen"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkede ikke optimalt og er derfor slettet"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkede ikke optimalt og er derfor slettet"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkede ikke optimalt og er derfor slettet. Konfigurer den igen for at bruge fingeroplåsning på din telefon."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkede ikke optimalt og er derfor slettet. Konfigurer dem igen for at bruge dit fingeraftryk til at låse din telefon op."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan ikke længere genkendes."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan ikke længere genkendes."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan ikke længere genkendes. Konfigurer fingeroplåsning igen."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan ikke længere genkendes. Konfigurer fingeroplåsning igen."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurer ansigtsoplåsning igen"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Din ansigtsmodel virkede ikke optimalt og er derfor slettet. Konfigurer den igen for at bruge ansigtsoplåsning på din telefon."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Din ansigtsmodel kan ikke længere genkendes. Konfigurer ansigtsoplåsning igen."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfigurer"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ikke nu"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm til <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Skift bruger"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Slå lyden fra"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tryk for at slå lyden fra"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 492bbebdfd34..e30f92d4725f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -345,7 +345,7 @@
<string name="permgroupdesc_phone" msgid="270048070781478204">"Telefonanrufe tätigen und verwalten"</string>
<string name="permgrouplab_sensors" msgid="9134046949784064495">"Körpersensoren"</string>
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"auf Sensordaten zu deinen Vitaldaten zugreifen"</string>
- <string name="permgrouplab_notifications" msgid="5472972361980668884">"Benachrichtigungen"</string>
+ <string name="permgrouplab_notifications" msgid="5472972361980668884">"Benachrichtigun­gen"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"Benachrichtigungen anzeigen"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Fensterinhalte abrufen"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Die Inhalte eines Fensters, mit dem du interagierst, werden abgerufen."</string>
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Auswählen, um \"Debugging über WLAN\" zu deaktivieren."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test-Harnischmodus aktiviert"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Setz das Gerät auf die Werkseinstellungen zurück, um den Test-Harnischmodus zu deaktivieren."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Falsche HSUM‑Build-Konfiguration"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Der Headless System User Mode-Zustand unterscheidet sich von seiner Build-Konfiguration. Bitte setze das Gerät auf die Werkseinstellungen zurück."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serielle Konsole aktiviert"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Leistung wird beeinflusst. Überprüfe Bootloader zum Deaktivieren."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimentelle MTE aktiviert"</string>
@@ -1577,7 +1575,7 @@
<string name="add_account_button_label" msgid="322390749416414097">"Konto hinzufügen"</string>
<string name="number_picker_increment_button" msgid="7621013714795186298">"Verlängern"</string>
<string name="number_picker_decrement_button" msgid="5116948444762708204">"Verringern"</string>
- <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> berühren und halten."</string>
+ <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> gedrückt halten."</string>
<string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"Zum Verlängern nach oben und zum Verringern nach unten schieben"</string>
<string name="time_picker_increment_minute_button" msgid="7195870222945784300">"Minuten verlängern"</string>
<string name="time_picker_decrement_minute_button" msgid="230925389943411490">"Minuten verringern"</string>
@@ -1604,7 +1602,7 @@
<string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> konnte nicht gestartet werden."</string>
<string name="shareactionprovider_share_with" msgid="2753089758467748982">"Teilen mit"</string>
<string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Mit <xliff:g id="APPLICATION_NAME">%s</xliff:g> teilen"</string>
- <string name="content_description_sliding_handle" msgid="982510275422590757">"Schieberegler: Berühren und halten"</string>
+ <string name="content_description_sliding_handle" msgid="982510275422590757">"Schieberegler: Gedrückt halten"</string>
<string name="description_target_unlock_tablet" msgid="7431571180065859551">"Zum Entsperren den Finger über den Bildschirm ziehen"</string>
<string name="action_bar_home_description" msgid="1501655419158631974">"Zur Startseite navigieren"</string>
<string name="action_bar_up_description" msgid="6611579697195026932">"Nach oben navigieren"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist aktiviert."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist deaktiviert."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lass die Lautstärketasten los. Halte zum Aktivieren von <xliff:g id="SERVICE_NAME">%1$s</xliff:g> beide Lautstärketasten noch einmal 3 Sekunden lang gedrückt."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Funktion auswählen"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Funktion auswählen"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Funktion auswählen"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Die Funktion wird geöffnet, wenn du das nächste Mal auf die Schaltfläche „Bedienungshilfen“ tippst"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Die Funktion wird geöffnet, wenn du diese Touch-Geste für Bedienungshilfen das nächste Mal verwendest. Wische mit 2 Fingern vom unteren Displayrand nach oben und lass dann schnell los."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Die Funktion wird geöffnet, wenn du diese Touch-Geste für Bedienungshilfen das nächste Mal verwendest. Wische mit 3 Fingern vom unteren Displayrand nach oben und lass dann schnell los."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergrößerung"</string>
<string name="user_switched" msgid="7249833311585228097">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Wechseln zu <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Die PIN ist zu kurz. Sie muss mindestens 4 Ziffern umfassen."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Später erneut versuchen"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Vollbildmodus wird aktiviert"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Wenn du den Modus verlassen möchtest, wische vom oberen Displayrand nach unten"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Ok"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Drehen, um die Ansicht zu verbessern"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Du kannst <xliff:g id="NAME">%s</xliff:g> im Vollbildmodus öffnen, um die Ansicht zu verbessern"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Aktueller Anruf"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filter für eingehenden Anruf"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Unkategorisiert"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Werbeaktionen"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Soziale Netzwerke"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Neuigkeiten"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Empfehlungen"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Du hast die Wichtigkeit dieser Benachrichtigungen festgelegt."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Diese Benachrichtigung ist aufgrund der beteiligten Personen wichtig."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Benutzerdefinierte App-Benachrichtigung"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Auswahl für Kurzbefehle für Bildschirmbedienungshilfen"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Kurzbefehl für Bedienungshilfen"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Benachrichtigungsleiste schließen"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menü"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Medien wiedergeben/pausieren"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Steuerkreuz nach oben"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Steuerkreuz nach unten"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Steuerkreuz nach links"</string>
@@ -2433,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Vertrauliches Profil"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Vertrauliche Benachrichtigungsinhalte ausgeblendet"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App-Inhalte werden aus Sicherheitsgründen bei der Bildschirmfreigabe ausgeblendet"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Aus Sicherheitsgründen werden bei der Bildschirmfreigabe App-Inhalte ausgeblendet"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch mit Satellit verbunden"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Du kannst Nachrichten ohne Mobilfunknetz oder WLAN senden und empfangen"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages öffnen"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"So funktionierts"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ausstehend…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Entsperrung per Fingerabdruck neu einrichten"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> hat nicht einwandfrei funktioniert und wurde gelöscht"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> haben nicht einwandfrei funktioniert und wurden gelöscht"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> hat nicht einwandfrei funktioniert und wurde gelöscht. Richte ihn noch einmal ein, um dein Smartphone per Fingerabdruck zu entsperren."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> haben nicht einwandfrei funktioniert und wurden gelöscht. Richte sie noch einmal ein, um dein Smartphone per Fingerabdruck zu entsperren."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> wird nicht mehr erkannt."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werden nicht mehr erkannt."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> wird nicht mehr erkannt. Richte die Entsperrung per Fingerabdruck neu ein."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werden nicht mehr erkannt. Richte die Entsperrung per Fingerabdruck neu ein."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Entsperrung per Gesichtserkennung neu einrichten"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Dein Gesichtsmodell hat nicht einwandfrei funktioniert und wurde gelöscht. Richte es noch einmal ein, um dein Smartphone per Gesichtserkennung zu entsperren."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Dein Gesichtsmodell wird nicht mehr erkannt. Richte die Entsperrung per Gesichtserkennung neu ein."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Einrichten"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nicht jetzt"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Wecker für <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Nutzer wechseln"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Stummschalten"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Zum Stummschalten tippen"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 7b1c7c81e77c..c7a55634fb4b 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Επιλέξτε, για να απενεργοποιήσετε τον ασύρματο εντοπισμό σφαλμάτων."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Η λειτουργία περιβάλλοντος δοκιμών ενεργοποιήθηκε"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Εκτελέστε επαναφορά εργοστασιακών ρυθμίσεων για να απενεργοποιήσετε τη λειτουργία περιβάλλοντος δοκιμών."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Λάθος διαμόρφωση κατασκευής HSUM"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Η κατάσταση της Λειτουργίας χρήστη συστήματος Headless (Headless System User Mode, HSUM) αυτής της συσκευής διαφέρει από τη διαμόρφωση κατασκευής της. Κάντε επαναφορά εργοστασιακών ρυθμίσεων της συσκευής."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Η σειριακή κονσόλα ενεργοποιήθηκε"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Η απόδοση επηρεάζεται. Για απενεργοποίηση, επιλέξτε το πρόγραμμα φόρτωσης εκκίνησης."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Ενεργοποιήθηκε το πειραματικό MTE"</string>
@@ -1439,7 +1437,7 @@
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Εμφάνιση πάνω σε άλλες εφαρμογές"</string>
<string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"Η εφαρμογή <xliff:g id="NAME">%s</xliff:g> προβάλλεται πάνω από άλλες εφαρμογές"</string>
- <string name="alert_windows_notification_title" msgid="6331662751095228536">"Η εφαρμογή <xliff:g id="NAME">%s</xliff:g> επικαλύπτει άλλες"</string>
+ <string name="alert_windows_notification_title" msgid="6331662751095228536">"Η εφαρ. <xliff:g id="NAME">%s</xliff:g> επικαλύπτει άλλες"</string>
<string name="alert_windows_notification_message" msgid="6538171456970725333">"Εάν δεν θέλετε να χρησιμοποιείται αυτή η λειτουργία από την εφαρμογή <xliff:g id="NAME">%s</xliff:g>, πατήστε για να ανοίξετε τις ρυθμίσεις και απενεργοποιήστε την."</string>
<string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Απενεργοποίηση"</string>
<string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Έλεγχος <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ενεργοποιήθηκε."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>: απενεργοποιημένο"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Αφήστε τα κουμπιά έντασης ήχου. Για να ενεργοποιήσετε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, πατήστε ξανά παρατεταμένα και τα δύο κουμπιά έντασης ήχου για τρία δευτερόλεπτα."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Επιλέξτε μια λειτουργία"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Επιλέξτε μια λειτουργία"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Επιλέξτε μια λειτουργία"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Η λειτουργία θα ανοίξει την επόμενη φορά που θα πατήσετε το κουμπί προσβασιμότητας"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Η λειτουργία θα ανοίξει την επόμενη φορά που θα χρησιμοποιήσετε αυτή τη συντόμευση. Σαρώστε προς τα πάνω με 2 δάχτυλα από το κάτω μέρος της οθόνης και απομακρύνετε γρήγορα τα δάχτυλά σας."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Η λειτουργία θα ανοίξει την επόμενη φορά που θα χρησιμοποιήσετε αυτή τη συντόμευση. Σαρώστε προς τα πάνω με 3 δάχτυλα από το κάτω μέρος της οθόνης και απομακρύνετε γρήγορα τα δάχτυλά σας."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Μεγιστοποίηση"</string>
<string name="user_switched" msgid="7249833311585228097">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Εναλλαγή σε <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Το PIN είναι υπερβολικά μικρό. Πρέπει να έχει μέγεθος τουλάχιστον 4 χαρακτήρων."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Δοκιμάστε ξανά αργότερα"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Προβολή σε πλήρη οθόνη"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Για έξοδο, σύρετε προς τα κάτω από το επάνω μέρος της οθόνης"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Το κατάλαβα"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Περιστρέψτε την οθόνη για καλύτερη προβολή"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Ανοίξτε την εφαρμογή <xliff:g id="NAME">%s</xliff:g> σε πλήρη οθόνη για καλύτερη προβολή"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Κλήση σε εξέλιξη"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Διαλογή εισερχόμενης κλήσης"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Μη κατηγοριοποιημένο"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Προωθήσεις"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Κοινωνικά δίκτυα"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Ειδήσεις"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Προτάσεις"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Μπορείτε να ρυθμίσετε τη βαρύτητα αυτών των ειδοποιήσεων."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Αυτό είναι σημαντικό λόγω των ατόμων που συμμετέχουν."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Προσαρμοσμένη ειδοποίηση εφαρμογής"</string>
@@ -2126,7 +2113,7 @@
<string name="popup_window_default_title" msgid="6907717596694826919">"Αναδυόμενο παράθυρο"</string>
<string name="slice_more_content" msgid="3377367737876888459">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
<string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"Η έκδοση εφαρμογής υποβαθμίστηκε ή δεν είναι συμβατή με αυτήν τη συντόμευση"</string>
- <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Δεν ήταν δυνατή η επαναφορά της συντόμευσης, επειδή η εφαρμογή δεν υποστηρίζει τη δημιουργία αντιγράφων ασφαλείας και την επαναφορά"</string>
+ <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Δεν ήταν δυνατή η επαναφορά της συντόμευσης, επειδή η εφαρμογή δεν υποστηρίζει τη δημιουργία αντιγράφου ασφαλείας και την επαναφορά"</string>
<string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Δεν ήταν δυνατή η επαναφορά της συντόμευσης, λόγω αναντιστοιχίας της υπογραφής εφαρμογής"</string>
<string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Δεν ήταν δυνατή η επαναφορά της συντόμευσης"</string>
<string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Η συντόμευση είναι απενεργοποιημένη"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Επιλογέας συντόμευσης οθόνης για την προσβασιμότητα"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Συντόμευση προσβασιμότητας"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Παράβλεψη πλαισίου σκίασης ειδοποιήσεων"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Μενού"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Αναπαραγωγή/παύση μέσων"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad επάνω"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad κάτω"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad αριστερά"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Πώς λειτουργεί"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Σε εκκρεμότητα…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με δακτυλικό αποτύπωμα"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Το δακτυλικό αποτύπωμα <xliff:g id="FINGERPRINT">%s</xliff:g> δεν λειτουργούσε καλά και διαγράφηκε"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Τα δακτυλικά αποτυπώματα <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> δεν λειτουργούσαν καλά και διαγράφηκαν"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Το δακτυλικό αποτύπωμα <xliff:g id="FINGERPRINT">%s</xliff:g> δεν λειτουργούσε καλά και διαγράφηκε. Ρυθμίστε το ξανά για να ξεκλειδώνετε το τηλέφωνο με το δακτυλικό αποτύπωμά σας."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Τα δακτυλικά αποτυπώματα <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> δεν λειτουργούσαν καλά και διαγράφηκαν. Ρυθμίστε τα ξανά για να ξεκλειδώνετε το τηλέφωνο με το δακτυλικό αποτύπωμά σας."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και του <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT">%s</xliff:g>. Ρυθμίστε ξανά τη λειτουργία Ξεκλείδωμα με δακτυλικό αποτύπωμα."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και του <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. Ρυθμίστε ξανά τη λειτουργία Ξεκλείδωμα με δακτυλικό αποτύπωμα."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με το πρόσωπο"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Το μοντέλο προσώπου δεν λειτουργούσε καλά και διαγράφηκε. Ρυθμίστε το ξανά για να ξεκλειδώνετε το τηλέφωνο με το πρόσωπό σας."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Δεν είναι πλέον δυνατή η αναγνώριση του μοντέλου προσώπου σας. Ρυθμίστε ξανά τη λειτουργία Ξεκλείδωμα με το πρόσωπο."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ρύθμιση"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Όχι τώρα"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Ξυπνητήρι για τον χρήστη <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Εναλλαγή χρήστη"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Σίγαση"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Πατήστε για σίγαση του ήχου"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 159ef5159012..5dfd2ac76aad 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Wrong HSUM build configuration"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"The headless system user mode state of this device differs from its build configuration. Please factory reset the device."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Choose a feature"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Choose a feature"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Choose a feature"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"The feature will open the next time that you tap the accessibility button"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open the next time that you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open the next time that you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
<string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least four digits."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Try again later"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Viewing full screen"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"To exit, swipe down from the top of your screen"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Got it"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotate for a better view"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Open <xliff:g id="NAME">%s</xliff:g> in full screen for a better view"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with your fingerprint."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with your face."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Your face model can no longer be recognised. Set up Face Unlock again."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index ed7871f9dc0c..55c637610f8e 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1760,9 +1760,9 @@
<string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Choose a feature"</string>
<string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Choose a feature"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Choose a feature"</string>
- <string name="accessibility_button_instructional_text" msgid="8029780800681458835">"The feature will open next time you tap the accessibility button."</string>
- <string name="accessibility_gesture_instructional_text" msgid="1485998586929977949">"The feature will open next time you use this shortcut. Swipe up with two fingers from the bottom of your screen and release quickly."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3430237316928654219">"The feature will open next time you use this shortcut. Swipe up with three fingers from the bottom of your screen and release quickly."</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"The feature will open next time you tap the accessibility button"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open next time you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open next time you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
<string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -2425,12 +2425,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with fingerprint."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognized."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognized."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognized. Set up Fingerprint Unlock again."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognized. Set up Fingerprint Unlock again."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with face."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Your face model can no longer be recognized. Set up Face Unlock again."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"Browser"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"Contacts"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"Email"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"SMS"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"Music"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"Calendar"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"Calculator"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Maps"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"Applications"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 71a374f78329..bb55bade208b 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Wrong HSUM build configuration"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"The headless system user mode state of this device differs from its build configuration. Please factory reset the device."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Choose a feature"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Choose a feature"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Choose a feature"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"The feature will open the next time that you tap the accessibility button"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open the next time that you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open the next time that you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
<string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least four digits."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Try again later"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Viewing full screen"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"To exit, swipe down from the top of your screen"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Got it"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotate for a better view"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Open <xliff:g id="NAME">%s</xliff:g> in full screen for a better view"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with your fingerprint."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with your face."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Your face model can no longer be recognised. Set up Face Unlock again."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 3e630f3c6f82..1ab0a1664444 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Wrong HSUM build configuration"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"The headless system user mode state of this device differs from its build configuration. Please factory reset the device."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Choose a feature"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Choose a feature"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Choose a feature"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"The feature will open the next time that you tap the accessibility button"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open the next time that you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open the next time that you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
<string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least four digits."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Try again later"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Viewing full screen"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"To exit, swipe down from the top of your screen"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Got it"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotate for a better view"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Open <xliff:g id="NAME">%s</xliff:g> in full screen for a better view"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with your fingerprint."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with your face."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Your face model can no longer be recognised. Set up Face Unlock again."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 78fadb38a6e1..cac4a51ba497 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1760,9 +1760,9 @@
<string name="accessibility_button_prompt_text" msgid="6105393217162198616">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎Choose a feature‎‏‎‎‏‎"</string>
<string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‎Choose a feature‎‏‎‎‏‎"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‎‎‎‎Choose a feature‎‏‎‎‏‎"</string>
- <string name="accessibility_button_instructional_text" msgid="8029780800681458835">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎The feature will open next time you tap the accessibility button.‎‏‎‎‏‎"</string>
- <string name="accessibility_gesture_instructional_text" msgid="1485998586929977949">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎The feature will open next time you use this shortcut. Swipe up with two fingers from the bottom of your screen and release quickly.‎‏‎‎‏‎"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3430237316928654219">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‏‎‏‏‎The feature will open next time you use this shortcut. Swipe up with three fingers from the bottom of your screen and release quickly.‎‏‎‎‏‎"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‏‎‎‎The feature will open next time you tap the accessibility button‎‏‎‎‏‎"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎The feature will open next time you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly.‎‏‎‎‏‎"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎The feature will open next time you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly.‎‏‎‎‏‎"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎Magnification‎‏‎‎‏‎"</string>
<string name="user_switched" msgid="7249833311585228097">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎Current user ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
<string name="user_switching_message" msgid="1912993630661332336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎Switching to ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎…‎‏‎‎‏‎"</string>
@@ -2425,12 +2425,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‎‎‎‏‏‏‎How it works‎‏‎‎‏‎"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎Pending...‎‏‎‎‏‎"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎Set up Fingerprint Unlock again‎‏‎‎‏‎"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT">%s</xliff:g>‎‏‎‎‏‏‏‎ wasn\'t working well and was deleted‎‏‎‎‏‎"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ weren\'t working well and were deleted‎‏‎‎‏‎"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT">%s</xliff:g>‎‏‎‎‏‏‏‎ wasn\'t working well and was deleted. Set it up again to unlock your phone with fingerprint.‎‏‎‎‏‎"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint.‎‏‎‎‏‎"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT">%s</xliff:g>‎‏‎‎‏‏‏‎ can no longer be recognized.‎‏‎‎‏‎"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ can no longer be recognized.‎‏‎‎‏‎"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT">%s</xliff:g>‎‏‎‎‏‏‏‎ can no longer be recognized. Set up Fingerprint Unlock again.‎‏‎‎‏‎"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ can no longer be recognized. Set up Fingerprint Unlock again.‎‏‎‎‏‎"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎Set up Face Unlock again‎‏‎‎‏‎"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with face.‎‏‎‎‏‎"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‎Your face model can no longer be recognized. Set up Face Unlock again.‎‏‎‎‏‎"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎Set up‎‏‎‎‏‎"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‏‎‎‎‏‏‎Not now‎‏‎‎‏‎"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎Alarm for ‎‏‎‎‏‏‎<xliff:g id="USER_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‏‎‎Switch user‎‏‎‎‏‎"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎Mute‎‏‎‎‏‎"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‎Tap to mute sound‎‏‎‎‏‎"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎Browser‎‏‎‎‏‎"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎Contacts‎‏‎‎‏‎"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‎‏‏‎Email‎‏‎‎‏‎"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‎SMS‎‏‎‎‏‎"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‎Music‎‏‎‎‏‎"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎Calendar‎‏‎‎‏‎"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‎‏‏‎Calculator‎‏‎‎‏‎"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎Maps‎‏‎‎‏‎"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎Applications‎‏‎‎‏‎"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 86e2b44b377b..b1f56b79b201 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecciona para inhabilitar la depuración inalámbrica."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Se habilitó el modo de agente de prueba"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Restablece la configuración de fábrica para inhabilitar el modo de agente de prueba."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"La configuración de compilación HSUM no es correcta"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"El estado de Headless System User Mode de este dispositivo difiere de la configuración de compilación. Restablece el dispositivo a su configuración de fábrica."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Se habilitó la consola en serie"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Afecta el rendimiento. Para inhabilitarla, verifica el bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental habilitada"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Como mantuviste presionadas las teclas de volumen, se activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se presionaron las teclas de volumen. Se desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Suelta las teclas de volumen. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, vuelve a mantener presionadas las teclas de volumen durante 3 segundos."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Elige una función"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Elige una función"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Elige una función"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La función se abrirá la próxima vez que presiones el botón de accesibilidad"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La función se abrirá la próxima vez que uses este atajo. Desliza hacia arriba con 2 dedos desde la parte inferior de la pantalla y levanta los dedos rápidamente."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La función se abrirá la próxima vez que uses este atajo. Desliza hacia arriba con 3 dedos desde la parte inferior de la pantalla y levanta los dedos rápidamente."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"El PIN es demasiado corto. Debe tener al menos 4 dígitos."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Vuelve a intentar más tarde."</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Visualización en pantalla completa"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Para salir, desliza el dedo hacia abajo desde la parte superior de la pantalla"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gira la pantalla para obtener una mejor vista"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Abre <xliff:g id="NAME">%s</xliff:g> en pantalla completa para una mejor visualización"</string>
@@ -1987,14 +1978,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Llamada en curso"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando una llamada entrante"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sin categoría"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promociones"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Redes sociales"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Noticias"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendaciones"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Estableciste la importancia de estas notificaciones."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Es importante debido a las personas involucradas."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificación de app personalizada"</string>
@@ -2211,10 +2198,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector del acceso directo de accesibilidad en pantalla"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Acceso directo de accesibilidad"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Descartar panel de notificaciones"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menú"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reproducir o pausar contenido multimedia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Pad direccional: arriba"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Pad direccional: abajo"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Pad direccional: izquierda"</string>
@@ -2441,12 +2426,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vuelve a configurar el Desbloqueo con huellas dactilares"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Se borró <xliff:g id="FINGERPRINT">%s</xliff:g> porque no funcionaba correctamente"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Se borraron <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> porque no funcionaban correctamente"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Se borró <xliff:g id="FINGERPRINT">%s</xliff:g> porque no funcionaba correctamente. Vuelve a configurarla para desbloquear el teléfono con la huella dactilar."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Se borraron <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> porque no funcionaban correctamente. Vuelve a configurarlas para desbloquear el teléfono con la huella dactilar."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Ya no se puede reconocer <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Ya no se pueden reconocer <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Ya no se puede reconocer <xliff:g id="FINGERPRINT">%s</xliff:g>. Vuelve a configurar el Desbloqueo con huellas dactilares."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Ya no se pueden reconocer <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. Vuelve a configurar el Desbloqueo con huellas dactilares."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Vuelve a configurar el Desbloqueo facial"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Se borró tu modelo de rostro porque no funcionaba correctamente. Vuelve a configurarlo para desbloquear el teléfono con el rostro."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Ya no se puede reconocer tu modelo de rostro. Vuelve a configurar el Desbloqueo facial."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ahora no"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambiar de usuario"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silenciar"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Presiona para silenciar el sonido"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index a12b16854c8c..f187cfde4c91 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Toca para desactivar la depuración inalámbrica."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo de agente de prueba habilitado"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Restablece los ajustes de fábrica para inhabilitar el modo de agente de prueba."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Configuración de compilación del modo de usuario del sistema sin interfaz gráfica incorrecta"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"El estado del modo de usuario del sistema sin interfaz gráfica de este dispositivo es distinto al de su configuración de compilación. Restablece el estado de fábrica del dispositivo."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Se ha habilitado la consola en serie"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Afecta al rendimiento. Para inhabilitarlo, comprueba el bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental habilitado"</string>
@@ -1440,7 +1438,7 @@
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Mostrar sobre otras aplicaciones"</string>
<string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras aplicaciones"</string>
- <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras apps"</string>
+ <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras aplicaciones"</string>
<string name="alert_windows_notification_message" msgid="6538171456970725333">"Si no quieres que <xliff:g id="NAME">%s</xliff:g> utilice esta función, toca la notificación para abrir los ajustes y desactivarla."</string>
<string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desactivar"</string>
<string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Comprobando <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1752,7 +1750,7 @@
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Hecho"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar acceso directo"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar acceso directo"</string>
- <string name="color_inversion_feature_name" msgid="2672824491933264951">"Invertir colores"</string>
+ <string name="color_inversion_feature_name" msgid="2672824491933264951">"Inversión de colores"</string>
<string name="color_correction_feature_name" msgid="7975133554160979214">"Corrección de color"</string>
<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>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener pulsadas las teclas de volumen, se ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se han mantenido pulsadas las teclas de volumen. Se ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Suelta las teclas de volumen. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas las dos teclas de volumen de nuevo durante 3 segundos."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Elige una función"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Elige una función"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Elige una función"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La función se abrirá la próxima vez que toques el botón de accesibilidad"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La función se abrirá la próxima vez que uses este acceso directo. Desliza hacia arriba con 2 dedos desde la parte inferior de la pantalla y suelta rápidamente."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La función se abrirá la próxima vez que uses este acceso directo. Desliza hacia arriba con 3 dedos desde la parte inferior de la pantalla y suelta rápidamente."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"El PIN es demasiado corto. Debe tener al menos 4 dígitos."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Reintentar más tarde"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Modo de pantalla completa"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Para salir, desliza hacia abajo desde la parte superior de la pantalla"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gira la pantalla para verlo mejor"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Abre <xliff:g id="NAME">%s</xliff:g> en pantalla completa para verlo mejor"</string>
@@ -1987,14 +1978,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Llamada en curso"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando una llamada entrante"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sin clasificar"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promociones"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Noticias"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendaciones"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Tú determinas la importancia de estas notificaciones."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Esto es importante por los usuarios implicados."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificación de aplicación personalizada"</string>
@@ -2211,10 +2198,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Menú de acceso directo de accesibilidad en pantalla"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Acceso directo de accesibilidad"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Cerrar pantalla de notificaciones"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menú"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Pausar/Reproducir contenido multimedia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Cruceta: arriba"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Cruceta: abajo"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Cruceta: izquierda"</string>
@@ -2434,19 +2419,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espacio privado"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Contenido sensible de la notificación oculto"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contenido de la aplicación oculto en pantalla compartida por motivos de seguridad"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contenido de la aplicación oculto en pantalla compartida por seguridad"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automáticamente al satélite"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Puedes enviar y recibir mensajes sin una red móvil o Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre Mensajes"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura Desbloqueo con huella digital de nuevo"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionaba correctamente y se ha eliminado"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaban correctamente y se han eliminado"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionaba correctamente y se ha eliminado. Configúrala de nuevo para desbloquear el teléfono con la huella digital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaban correctamente y se han eliminado. Configúralas de nuevo para desbloquear el teléfono con la huella digital."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ya no puede reconocerse."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ya no pueden reconocerse."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ya no puede reconocerse. Vuelve a configurar Desbloqueo con huella digital."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ya no pueden reconocerse. Vuelve a configurar Desbloqueo con huella digital."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configura Desbloqueo facial de nuevo"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Tu modelo facial no funcionaba correctamente y se ha eliminado. Configúralo de nuevo para desbloquear el teléfono con la cara."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Tu modelo facial ya no puede reconocerse. Vuelve a configurar Desbloqueo facial."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ahora no"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambiar de usuario"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silenciar"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toca para silenciar el sonido"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index e8696c4d2e65..5a618d6c5d53 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Valige juhtmevaba silumise keelamiseks."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testrakendirežiim on lubatud"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Testrakendirežiimi keelamiseks taastage tehaseseaded."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Vale HSUM-i järgu seadistus"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Selle seadme kasutajaliideseta süsteemikasutaja režiimi olek erineb selle järgu seadistusest. Lähtestage seade tehaseseadetele."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Seeriakonsool on lubatud"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"See mõjutab toimivust. Keelamiseks kontrollige käivituslaadurit."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Katseline MTE on lubatud"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Vabastage helitugevuse klahvid. Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> sisselülitamiseks vajutage uuesti mõlemat helitugevuse klahvi ja hoidke neid 3 sekundit all."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Valige funktsioon"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Valige funktsioon"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Valige funktsioon"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funktsioon avaneb järgmine kord, kui puudutate juurdepääsetavuse nuppu"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funktsioon avaneb järgmine kord, kui kasutate seda otseteed. Tõmmake kahe sõrmega ekraani allservast üles ja vabastage kiiresti."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funktsioon avaneb järgmine kord, kui kasutate seda otseteed. Tõmmake kolme sõrmega ekraani allservast üles ja vabastage kiiresti."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Suurendus"</string>
<string name="user_switched" msgid="7249833311585228097">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Üleminek kasutajale <xliff:g id="NAME">%1$s</xliff:g> ..."</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN-kood on liiga lühike. Peab olema vähemalt 4-kohaline."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Proovige hiljem uuesti"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Kuvamine täisekraanil"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Väljumiseks pühkige ekraanikuva ülaosast alla"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Selge"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Pöörake parema vaate jaoks"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Parema vaate jaoks avage rakendus <xliff:g id="NAME">%s</xliff:g> täisekraanil"</string>
@@ -2427,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Privaatne ruum"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Märguande delikaatne sisu peideti"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Rakenduse sisu on ekraani jagamises turvalisuse huvides peidetud"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Rakenduse sisu on ekraani jagamisel turvalisuse huvides peidetud"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Satelliidiga loodi automaatselt ühendus"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Teil on võimalik sõnumeid saata ja vastu võtta ilma mobiilside- ja WiFi-võrguta"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Ava rakendus Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Tööpõhimõtted"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ootel …"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Seadistage sõrmejäljega avamine uuesti"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei töötanud hästi ja kustutati"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei töötanud hästi ning kustutati"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei töötanud hästi ja kustutati. Telefoni sõrmejäljega avamiseks seadistage see uuesti."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei töötanud hästi ning kustutati. Telefoni sõrmejäljega avamiseks seadistage need uuesti."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Sõrmejälge <xliff:g id="FINGERPRINT">%s</xliff:g> ei saa enam tuvastada."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Sõrmejälgi <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei saa enam tuvastada."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Sõrmejälge <xliff:g id="FINGERPRINT">%s</xliff:g> ei saa enam tuvastada. Seadistage sõrmejäljega avamine uuesti."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Sõrmejälgi <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei saa enam tuvastada. Seadistage sõrmejäljega avamine uuesti."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Seadistage näoga avamine uuesti"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Teie näomudel ei töötanud hästi ja kustutati. Telefoni näoga avamiseks seadistage see uuesti."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Teie näomudelit ei saa enam tuvastada. Seadistage näoga avamine uuesti."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Seadista"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Mitte praegu"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Äratus kasutajale <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Vaheta kasutajat"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Vaigista"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Puudutage heli vaigistamiseks"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index e6a4ec7c22af..58192893b337 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -270,7 +270,7 @@
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Txosten dinamikoa"</string>
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Aukera hau erabili beharko zenuke ia beti. Txostenaren jarraipena egin ahal izango duzu eta arazoari buruzko xehetasunak eman ahal izango dituzu. Baliteke gutxitan erabili behar izaten diren atalak ez agertzea, denbora aurrezteko."</string>
<string name="bugreport_option_full_title" msgid="7681035745950045690">"Txosten osoa"</string>
- <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Erabili aukera hau sisteman ahalik eta traba gutxien eragiteko gailuak erantzuten ez duenean, mantsoegi dabilenean edo txosteneko atal guztiak behar dituzunean. Ez dizu uzten xehetasun gehiago idazten, ezta beste pantaila-argazkirik ateratzen ere."</string>
+ <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Erabili aukera hau sistemaren interferentzia ahalik eta txikiena izateko gailuak erantzuten ez duenean, mantsoegi dabilenean edo txosteneko atal guztiak behar dituzunean. Ez dizu uzten xehetasun gehiago idazten, ezta beste pantaila-argazkirik ateratzen ere."</string>
<string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Akatsen txostenerako argazkia aterako da # segundo barru.}other{Akatsen txostenerako argazkia aterako da # segundo barru.}}"</string>
<string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Pantaila-argazkia egin da akatsen txostenarekin"</string>
<string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Ezin izan da egin pantaila-argazkia akatsen txostenarekin"</string>
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Hautatu hau hari gabeko arazketa desgaitzeko."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Proba-materialeko modua gaitu da"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Proba-materialaren modua desgaitzeko, berrezarri jatorrizko datuak."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Interfaze grafikorik gabeko sistema-erabiltzaile moduaren konpilazioaren konfigurazioa ez da zuzena"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Gailu honen interfaze grafikorik gabeko sistema-erabiltzaile moduaren egoera ez dator bat haren konpilazioaren konfigurazioarekin. Berrezarri gailuko jatorrizko datuak."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serie-kontsola gaituta"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Errendimenduari eragiten dio. Desgaitzeko, joan abiarazlera."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE esperimentala gaituta dago"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu egin da."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu egin da."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Askatu bolumen-botoiak. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatzeko, eduki sakatuta berriro bi bolumen-botoiak hiru segundoz."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Aukeratu eginbide bat"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Aukeratu eginbide bat"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Aukeratu eginbide bat"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Erabilerraztasuna botoia sakatzen duzun hurrengoan irekiko da eginbidea"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Lasterbidea erabiltzen duzun hurrengoan irekiko da eginbidea. Pasatu 2 hatz pantailaren behealdetik gorantz eta askatu bizkor."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Lasterbidea erabiltzen duzun hurrengoan irekiko da eginbidea. Pasatu 3 hatz pantailaren behealdetik gorantz eta askatu bizkor."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Lupa"</string>
<string name="user_switched" msgid="7249833311585228097">"Erabiltzailea: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"\"<xliff:g id="NAME">%1$s</xliff:g>\" erabiltzailera aldatzen…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PINa laburregia da. Lau digitu izan behar ditu gutxienez."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Saiatu berriro geroago"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Pantaila osoko ikuspegia"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Irteteko, pasatu hatza pantailaren goialdetik beherantz"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Ados"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Biratu pantaila ikuspegi hobea lortzeko"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Ireki <xliff:g id="NAME">%s</xliff:g> pantaila osoan eta ikuspegi hobea lortuko duzu"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Deia abian da"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Sarrerako dei bat bistaratzen"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Kategoriarik gabea"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promozioak"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sare sozialak"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Albisteak"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Gomendioak"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Zuk ezarri duzu jakinarazpen hauen garrantzia."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Garrantzitsua da eragiten dien pertsonengatik."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Aplikazio-jakinarazpen pertsonalizatua"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Pantailako erabilerraztasun-lasterbideen hautatzailea"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Erabilerraztasun-lasterbidea"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Baztertu jakinarazpenen panela"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menua"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Erreproduzitu/Pausatu multimedia-elementua"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Norabide-kontrolagailuko goiko botoia"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Norabide-kontrolagailuko beheko botoia"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Norabide-kontrolagailuko ezkerreko botoia"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Nola funtzionatzen du?"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Zain…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguratu berriro hatz-marka bidez desblokeatzeko eginbidea"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ezabatu egin da, ez zuelako ondo funtzionatzen"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ezabatu egin dira, ez zutelako ondo funtzionatzen"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ezabatu egin da, ez zuelako ondo funtzionatzen. Telefonoa hatz-markarekin desblokeatzeko, konfigura ezazu berriro."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ezabatu egin dira, ez zutelako ondo funtzionatzen. Telefonoa hatz-markarekin desblokeatzeko, konfigura itzazu berriro."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ez da ezagutzen jada."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ez dira ezagutzen jada."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ez da ezagutzen jada. Konfiguratu berriro hatz-marka bidez desblokeatzeko eginbidea."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ez dira ezagutzen jada. Konfiguratu berriro hatz-marka bidez desblokeatzeko eginbidea."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfiguratu berriro aurpegi bidez desblokeatzeko eginbidea"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Aurpegi-eredua ezabatu egin da, ez zuelako ondo funtzionatzen. Telefonoa aurpegiarekin desblokeatzeko, konfigura ezazu berriro."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Zure aurpegi-eredua ez da ezagutzen jada. Konfiguratu berriro aurpegi bidez desblokeatzeko eginbidea."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfiguratu"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Orain ez"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> erabiltzailearentzako alarma"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Aldatu erabiltzailea"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desaktibatu audioa"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Sakatu audioa desaktibatzeko"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index c89bba74c09e..7a08af6b5184 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"برای غیرفعال کردن اشکال‌زدایی بی‌سیم انتخاب کنید."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"«حالت مجموعه داده‌های تست» فعال شد"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"برای غیرفعال کردن «حالت مجموعه داده‌های تست»، بازنشانی کارخانه‌ای کنید."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"‏پیکربندی ساخت HSUM اشتباه است"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"وضعیت «حالت کاربر سیستم بی‌سر» در این دستگاه با پیکربندی ساخت متفاوت است. لطفاً دستگاه را بازنشانی کارخانه‌ای کنید."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"کنسول سریال فعال است"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"‏عملکرد تحت‌تأثیر قرار گرفته است. برای غیرفعال کردن، bootloader را بررسی کنید."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"‏MTE آزمایشی فعال شد"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> روشن شد."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> خاموش شد."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"کلیدهای میزان صدا را رها کنید. برای روشن کردن <xliff:g id="SERVICE_NAME">%1$s</xliff:g>، هر دو کلید میزان صدا را مجدداً به‌مدت ۳ ثانیه فشار دهید و نگه دارید."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"انتخاب ویژگی"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"انتخاب ویژگی"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"انتخاب ویژگی"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"دفعه بعد که روی دکمه دسترس‌پذیری تک‌ضرب بزنید، این ویژگی باز می‌شود"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"دفعه بعد که از این میان‌بر استفاده کنید، این ویژگی باز می‌شود. با ۲ انگشت از پایین صفحه تند به بالا بکشید و سریع رها کنید."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"دفعه بعد که از این میان‌بر استفاده کنید، این ویژگی باز می‌شود. با ۳ انگشت از پایین صفحه تند به بالا بکشید و سریع رها کنید."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"درشت‌نمایی"</string>
<string name="user_switched" msgid="7249833311585228097">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"در حالت تغییر به <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"پین بیش از حد کوتاه است. باید حداقل ۴ رقم باشد."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"بعداً دوباره امتحان کنید"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"مشاهده در حالت تمام صفحه"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"برای خروج، از بالای صفحه تند به پایین بکشید"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"متوجه شدم"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"برای دید بهتر، دستگاه را بچرخانید"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"برای دید بهتر، <xliff:g id="NAME">%s</xliff:g> را به‌صورت تمام‌صفحه باز کنید"</string>
@@ -2427,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"فضای خصوصی"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"محتوای اعلان حساس پنهان شده است"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"به‌دلایل امنیتی، محتوای برنامه از دید هم‌رسانی صفحه‌نمایش پنهان شد"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"به‌دلایل امنیتی، محتوای برنامه پس‌از هم‌رسانی صفحه‌نمایش پنهان می‌شود"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"به‌طور خودکار به ماهواره متصل شد"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"‏می‌توانید بدون شبکه تلفن همراه یا Wi-Fi پیام ارسال و دریافت کنید"</string>
- <string name="satellite_notification_open_message" msgid="4149234979688273729">"باز کردن «پیام‌ها»"</string>
+ <string name="satellite_notification_open_message" msgid="4149234979688273729">"باز کردن «پیام‌نگار»"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"روش کار"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"درحال تعلیق…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"راه‌اندازی مجدد «قفل‌گشایی با اثر انگشت»"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> خوب کار نمی‌کرد و حذف شد"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> خوب کار نمی‌کردند و حذف شدند"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> خوب کار نمی‌کرد و حذف شد. برای باز کردن قفل تلفن با اثر انگشت، آن را دوباره راه‌اندازی کنید."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> خوب کار نمی‌کرد و حذف شد. برای باز کردن قفل تلفن با اثر انگشت، آن‌ها را دوباره راه‌اندازی کنید."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> دیگر قابل‌شناسایی نیست."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> دیگر قابل‌شناسایی نیستند."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> دیگر قابل‌شناسایی نیست. «قفل‌گشایی با اثر انگشت» را دوباره راه‌اندازی کنید."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> دیگر قابل‌شناسایی نیستند. «قفل‌گشایی با اثر انگشت» را دوباره راه‌اندازی کنید."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"راه‌اندازی مجدد «قفل‌گشایی با چهره»"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"مدل چهره شما خوب کار نمی‌کرد و حذف شد. برای باز کردن قفل تلفن با چهره، دوباره آن را راه‌اندازی کنید."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"مدل چهره‌تان دیگر قابل‌شناسایی نیست. «قفل‌گشایی با چهره» را دوباره راه‌اندازی کنید."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"راه‌اندازی"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"حالا نه"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"زنگ ساعت <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"تغییر کاربر"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"بی‌صدا کردن"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"برای بی‌صدا کردن تک‌ضرب بزنید"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 6a12f3c012fd..8393e9a2697e 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Poista langaton virheenkorjaus käytöstä valitsemalla tämä."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testikehystila käytössä"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Palauta tehdasasetukset, niin voit poistaa testikehystilan käytöstä."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Väärä HSUM-koontiversiomääritys"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Tämän laitteen järjestelmäkäyttäjän tila eroaa koontiversiomäärityksestä. Palauta laitteen tehdasasetukset."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Sarjakonsoli käytössä"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Tämä vaikuttaa suorituskykyyn. Jos haluat poistaa toiminnon käytöstä, tarkista käynnistysohjelma."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Kokeellinen MTE käytössä"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin päälle."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin pois päältä."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Vapauta äänenvoimakkuuspainikkeet. Laita <xliff:g id="SERVICE_NAME">%1$s</xliff:g> päälle painamalla äänenvoimakkuuspainikkeita uudelleen kolmen sekunnin ajan."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Valitse ominaisuus"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Valitse ominaisuus"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Valitse ominaisuus"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Ominaisuus avautuu, kun seuraavan kerran napautat saavutettavuuspainiketta"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Ominaisuus avautuu, kun seuraavan kerran käytät tätä pikakomentoa. Pyyhkäise näytön alareunasta ylös kahdella sormella ja nosta sormet näytöltä nopeasti."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Ominaisuus avautuu, kun seuraavan kerran käytät tätä pikakomentoa. Pyyhkäise näytön alareunasta ylös kolmella sormella ja nosta sormet näytöltä nopeasti."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Suurennus"</string>
<string name="user_switched" msgid="7249833311585228097">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Vaihdetaan käyttäjään <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN-koodi on liian lyhyt. Vähimmäispituus on neljä merkkiä."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Yritä myöhemmin uudelleen"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Koko ruudun tilassa"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Poistu pyyhkäisemällä alas näytön yläreunasta"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Selvä"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Kierrä, niin saat paremman näkymän"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Avaa <xliff:g id="NAME">%s</xliff:g>, niin saat paremman näkymän"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Käynnissä oleva puhelu"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Seulotaan saapuvaa puhelua"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Luokittelematon"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Tarjoukset"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Some"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Uutiset"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Suositukset"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Voit valita näiden ilmoitusten tärkeyden."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Tämä on tärkeää siihen liittyvien ihmisten perusteella."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Oma sovellusilmoitus"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Näytöllä näkyvän esteettömyyspainikkeen valitsin"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Saavutettavuuspainike"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Sulje ilmoitusalue"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Valikko"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media: toista/keskeytä"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Suuntanäppäimistö: ylös-painike"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Suuntanäppäimisto: alas-painike"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Suuntanäppäimistö: vasen painike"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Näin se toimii"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Odottaa…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ota sormenjälkiavaus uudelleen käyttöön"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei toiminut kunnolla, ja se poistettiin"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät toimineet kunnolla, ja ne poistettiin"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei toiminut kunnolla, ja se poistettiin. Ota se uudelleen käyttöön, jotta voit avata puhelimen lukituksen sormenjäljellä."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät toimineet kunnolla, ja ne poistettiin. Ota ne uudelleen käyttöön, jotta voit avata puhelimen lukituksen sormenjäljellä."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei enää ole tunnistettavissa."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät enää ole tunnistettavissa."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei enää ole tunnistettavissa. Ota sormenjälkiavaus uudelleen käyttöön."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät enää ole tunnistettavissa. Ota sormenjälkiavaus uudelleen käyttöön."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ota kasvojentunnistusavaus uudelleen käyttöön"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Kasvomallisi ei toiminut kunnolla, ja se poistettiin. Ota se uudelleen käyttöön, jotta voit avata puhelimen lukituksen kasvoilla."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Kasvomallia ei enää tunnisteta. Ota kasvojentunnistusavaus uudelleen käyttöön."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ota käyttöön"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ei nyt"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Hälytys: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Vaihda käyttäjää"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mykistä"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Mykistä äänet napauttamalla"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index afd5c9af0916..a0f8ec017e64 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -198,7 +198,7 @@
<string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Par l\'administrateur de votre profil professionnel"</string>
<string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Par <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
<string name="work_profile_deleted" msgid="5891181538182009328">"Profil professionnel supprimé"</string>
- <string name="work_profile_deleted_details" msgid="3773706828364418016">"Le profil professionnel de l\'application d\'administration est manquant ou corrompu. Votre profil professionnel et ses données connexes ont donc été supprimés. Communiquez avec votre administrateur pour obtenir de l\'assistance."</string>
+ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Le profil professionnel de l\'appli d\'administration est manquant ou corrompu. Votre profil professionnel et ses données connexes ont donc été supprimés. Communiquez avec votre administrateur pour obtenir de l\'assistance."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Votre profil professionnel n\'est plus accessible sur cet appareil"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Trop de tentatives d\'entrée du mot de passe"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrateur a libéré l\'appareil pour un usage personnel"</string>
@@ -206,7 +206,7 @@
<string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Votre organisation n\'autorise pas les espaces privés sur cet appareil géré."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"L\'appareil est géré"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Touchez ici pour obtenir plus d\'information."</string>
- <string name="location_changed_notification_title" msgid="3620158742816699316">"Les applications peuvent accéder à votre position"</string>
+ <string name="location_changed_notification_title" msgid="3620158742816699316">"Les applis peuvent accéder à votre position"</string>
<string name="location_changed_notification_text" msgid="7158423339982706912">"Communiquez avec votre administrateur informatique pour en savoir plus"</string>
<string name="geofencing_service" msgid="3826902410740315456">"Service de définition de limites géographiques"</string>
<string name="country_detector" msgid="7023275114706088854">"Détecteur de pays"</string>
@@ -218,14 +218,14 @@
<string name="device_policy_manager_service" msgid="5085762851388850332">"Service de gestionnaire Device Policy"</string>
<string name="music_recognition_manager_service" msgid="7481956037950276359">"Service de gestion de la reconnaissance musicale"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Le contenu de votre appareil sera effacé"</string>
- <string name="factory_reset_message" msgid="2657049595153992213">"Impossible d\'utiliser l\'application d\'administration. Les données de votre appareil vont maintenant être effacées.\n\nSi vous avez des questions, communiquez avec l\'administrateur de votre organisation."</string>
+ <string name="factory_reset_message" msgid="2657049595153992213">"Impossible d\'utiliser l\'appli d\'administration. Les données de votre appareil vont maintenant être effacées.\n\nSi vous avez des questions, communiquez avec l\'administrateur de votre organisation."</string>
<string name="printing_disabled_by" msgid="3517499806528864633">"Impression désactivée par <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
<string name="personal_apps_suspension_title" msgid="7561416677884286600">"Activer profil professionnel"</string>
- <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Vos applications personnelles sont bloquées jusqu\'à ce que vous activiez votre profil professionnel"</string>
- <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"Les applications personnelles seront bloquées le <xliff:g id="DATE">%1$s</xliff:g> à <xliff:g id="TIME">%2$s</xliff:g>. Votre administrateur informatique ne vous autorise pas à laisser votre profil professionnel désactivé pendant plus de <xliff:g id="NUMBER">%3$d</xliff:g> jours."</string>
+ <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Vos applis personnelles sont bloquées jusqu\'à ce que vous activiez votre profil professionnel"</string>
+ <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"Les applis personnelles seront bloquées le <xliff:g id="DATE">%1$s</xliff:g> à <xliff:g id="TIME">%2$s</xliff:g>. Votre administrateur informatique ne vous autorise pas à laisser votre profil professionnel désactivé pendant plus de <xliff:g id="NUMBER">%3$d</xliff:g> jours."</string>
<string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"Activer"</string>
<string name="work_profile_telephony_paused_title" msgid="7690804479291839519">"Les appels et messages sont désactivés"</string>
- <string name="work_profile_telephony_paused_text" msgid="8065762301100978221">"Vous avez mis en pause les applications professionnelles. Vous ne recevrez aucun appel téléphonique ni message texte."</string>
+ <string name="work_profile_telephony_paused_text" msgid="8065762301100978221">"Vous avez mis en pause les applis professionnelles. Vous ne recevrez aucun appel téléphonique ni message texte."</string>
<string name="work_profile_telephony_paused_turn_on_button" msgid="7542632318337068821">"Réact. applis pros"</string>
<string name="me" msgid="6207584824693813140">"Moi"</string>
<string name="power_dialog" product="tablet" msgid="8333207765671417261">"Options de la tablette"</string>
@@ -252,7 +252,7 @@
<string name="shutdown_confirm" product="default" msgid="136816458966692315">"Votre téléphone va s\'éteindre."</string>
<string name="shutdown_confirm_question" msgid="796151167261608447">"Voulez-vous éteindre l\'appareil?"</string>
<string name="reboot_safemode_title" msgid="5853949122655346734">"Redémarrer en mode sans échec"</string>
- <string name="reboot_safemode_confirm" msgid="1658357874737219624">"Voulez-vous redémarrer en mode sans échec? Cette opération aura pour effet de désactiver toutes les applications tierces que vous avez installées. Elles seront réactivées au prochain redémarrage."</string>
+ <string name="reboot_safemode_confirm" msgid="1658357874737219624">"Voulez-vous redémarrer en mode sans échec? Cette opération aura pour effet de désactiver toutes les applis tierces que vous avez installées. Elles seront réactivées au prochain redémarrage."</string>
<string name="recent_tasks_title" msgid="8183172372995396653">"Récents"</string>
<string name="no_recent_tasks" msgid="9063946524312275906">"Aucune appli récente"</string>
<string name="global_actions" product="tablet" msgid="4412132498517933867">"Options de la tablette"</string>
@@ -303,13 +303,13 @@
<string name="notification_channel_alerts" msgid="5070241039583668427">"Alertes"</string>
<string name="notification_channel_retail_mode" msgid="3732239154256431213">"Démo en magasin"</string>
<string name="notification_channel_usb" msgid="1528280969406244896">"Connexion USB"</string>
- <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Application en cours d\'exécution"</string>
- <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Applications qui sollicitent la pile"</string>
+ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Appli en cours d\'exécution"</string>
+ <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Applis qui sollicitent la pile"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Agrandissement"</string>
<string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Usage des fonctionnalités d\'accessibilité"</string>
<string name="notification_channel_display" msgid="6905032605735615090">"Écran"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> sollicite la pile"</string>
- <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> applications sollicitent la pile"</string>
+ <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> applis sollicitent la pile"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</string>
<string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="8974401416068943888">"Mode sans échec"</string>
@@ -365,282 +365,282 @@
<string name="dream_preview_title" msgid="5570751491996100804">"Aperçu, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
<string name="dream_accessibility_action_click" msgid="7392398629967797805">"Ignorer"</string>
<string name="permlab_statusBar" msgid="8798267849526214017">"désactiver ou modifier la barre d\'état"</string>
- <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
+ <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet à l\'appli de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
<string name="permlab_statusBarService" msgid="2523421018081437981">"servir de barre d\'état"</string>
- <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permet à l\'application de faire office de barre d\'état."</string>
+ <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permet à l\'appli de faire office de barre d\'état."</string>
<string name="permlab_expandStatusBar" msgid="1184232794782141698">"agrandir ou réduire la barre d\'état"</string>
- <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permet à l\'application de réduire ou de développer la barre d\'état."</string>
+ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permet à l\'appli de réduire ou de développer la barre d\'état."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"afficher les notifications en mode plein écran sur un appareil verrouillé"</string>
- <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permet à l\'application d\'afficher les notifications en mode plein écran sur un appareil verrouillé."</string>
+ <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permet à l\'appli d\'afficher les notifications en mode plein écran sur un appareil verrouillé."</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"Installer des raccourcis"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permet à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permet à une appli d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"désinstaller des raccourcis"</string>
- <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permet à l\'application de supprimer des raccourcis de la page d\'accueil sans intervention de l\'utilisateur."</string>
+ <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permet à l\'appli de supprimer des raccourcis de la page d\'accueil sans intervention de l\'utilisateur."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"transférer les appels sortants"</string>
- <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Permet à l\'application de lire le numéro composé lors d\'un appel sortant et lui donne la possibilité de rediriger l\'appel vers un autre numéro ou d\'abandonner l\'appel."</string>
+ <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Permet à l\'appli de lire le numéro composé lors d\'un appel sortant et lui donne la possibilité de rediriger l\'appel vers un autre numéro ou d\'abandonner l\'appel."</string>
<string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"répondre aux appels téléphoniques"</string>
- <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Permet à l\'application de répondre aux appels entrants."</string>
+ <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Permet à l\'appli de répondre aux appels entrants."</string>
<string name="permlab_receiveSms" msgid="505961632050451881">"recevoir des messages texte"</string>
- <string name="permdesc_receiveSms" msgid="1797345626687832285">"Permet à l\'application de recevoir et de traiter les messages texte. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
+ <string name="permdesc_receiveSms" msgid="1797345626687832285">"Permet à l\'appli de recevoir et de traiter les messages texte. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
<string name="permlab_receiveMms" msgid="4000650116674380275">"recevoir des messages multimédias"</string>
- <string name="permdesc_receiveMms" msgid="958102423732219710">"Permet à l\'application de recevoir et de traiter les messages multimédias. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
+ <string name="permdesc_receiveMms" msgid="958102423732219710">"Permet à l\'appli de recevoir et de traiter les messages multimédias. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
<string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"Transférer les messages de diffusion cellulaire"</string>
- <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Permet à l\'application d\'établir un lien avec le module de diffusion cellulaire afin de transférer les messages de diffusion cellulaire à mesure de leur réception. Dans certaines régions, des alertes de diffusion cellulaire sont envoyées afin de vous avertir de situations d\'urgence. Des applications malveillantes peuvent interférer avec les performances ou le fonctionnement de votre appareil lors de la réception d\'une alerte d\'urgence par diffusion cellulaire."</string>
+ <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Permet à l\'appli d\'établir un lien avec le module de diffusion cellulaire afin de transférer les messages de diffusion cellulaire à mesure de leur réception. Dans certaines régions, des alertes de diffusion cellulaire sont envoyées afin de vous avertir de situations d\'urgence. Des applis malveillantes peuvent interférer avec les performances ou le fonctionnement de votre appareil lors de la réception d\'une alerte d\'urgence par diffusion cellulaire."</string>
<string name="permlab_manageOngoingCalls" msgid="281244770664231782">"Gérer les appels en cours"</string>
- <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Autorise une application à afficher les renseignements concernant les appels en cours sur votre appareil et à les gérer."</string>
+ <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Autorise une appli à afficher les renseignements concernant les appels en cours sur votre appareil et à les gérer."</string>
<string name="permlab_accessLastKnownCellId" msgid="7638226620825665130">"Accéder à la dernière identité cellulaire connue."</string>
- <string name="permdesc_accessLastKnownCellId" msgid="6664621339249308857">"Autorise une application à accéder à la dernière identité cellulaire connue fournie par la téléphonie."</string>
+ <string name="permdesc_accessLastKnownCellId" msgid="6664621339249308857">"Autorise une appli à accéder à la dernière identité cellulaire connue fournie par la téléphonie."</string>
<string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"lire les messages de diffusion cellulaire"</string>
- <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Permet à l\'application de lire les messages de diffusion cellulaire que votre appareil reçoit. Dans certaines zones géographiques, des alertes vous sont envoyées afin de vous prévenir en cas de situation d\'urgence. Des applications malveillantes peuvent venir perturber les performances ou le fonctionnement de votre appareil lors de la réception d\'un message de diffusion cellulaire."</string>
+ <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Permet à l\'appli de lire les messages de diffusion cellulaire que votre appareil reçoit. Dans certaines zones géographiques, des alertes vous sont envoyées afin de vous prévenir en cas de situation d\'urgence. Des applis malveillantes peuvent venir perturber les performances ou le fonctionnement de votre appareil lors de la réception d\'un message de diffusion cellulaire."</string>
<string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"lire les flux auxquels vous êtes abonné"</string>
- <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Permet à l\'application d\'obtenir des données sur les flux en cours de synchronisation."</string>
+ <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Permet à l\'appli d\'obtenir des données sur les flux en cours de synchronisation."</string>
<string name="permlab_sendSms" msgid="7757368721742014252">"envoyer et afficher des messages texte"</string>
- <string name="permdesc_sendSms" msgid="6757089798435130769">"Permet à l\'application d\'envoyer des messages texte. Cette autorisation peut entraîner des frais inattendus. Des applications malveillantes peuvent générer des frais en envoyant des messages sans votre consentement."</string>
+ <string name="permdesc_sendSms" msgid="6757089798435130769">"Permet à l\'appli d\'envoyer des messages texte. Cette autorisation peut entraîner des frais inattendus. Des applis malveillantes peuvent générer des frais en envoyant des messages sans votre consentement."</string>
<string name="permlab_readSms" msgid="5164176626258800297">"voir les messages texte ou multimédias"</string>
- <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Cette application peut lire tous les messages texte stockés sur votre tablette."</string>
- <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Cette application peut lire tous les messages texte stockés sur votre appareil Android TV."</string>
- <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Cette application peut lire tous les messages texte stockés sur votre téléphone."</string>
+ <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Cette appli peut lire tous les messages texte stockés sur votre tablette."</string>
+ <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Cette appli peut lire tous les messages texte stockés sur votre appareil Android TV."</string>
+ <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Cette appli peut lire tous les messages texte stockés sur votre téléphone."</string>
<string name="permlab_receiveWapPush" msgid="4223747702856929056">"recevoir des messages WAP"</string>
- <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Permet à l\'application de recevoir et de traiter les messages WAP. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
- <string name="permlab_getTasks" msgid="7460048811831750262">"récupérer les données des applications en cours d\'exécution"</string>
- <string name="permdesc_getTasks" msgid="7388138607018233726">"Permet à l\'application de récupérer des données sur des tâches en cours d\'exécution et récemment exécutées. L\'application est ainsi susceptible d\'obtenir des données concernant les applications utilisées sur l\'appareil."</string>
+ <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Permet à l\'appli de recevoir et de traiter les messages WAP. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
+ <string name="permlab_getTasks" msgid="7460048811831750262">"récupérer les données des applis en cours d\'exécution"</string>
+ <string name="permdesc_getTasks" msgid="7388138607018233726">"Permet à l\'appli de récupérer des données sur des tâches en cours d\'exécution et récemment exécutées. L\'appli est ainsi susceptible d\'obtenir des données concernant les applis utilisées sur l\'appareil."</string>
<string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"gérer les propriétaires des profils et de l\'appareil"</string>
- <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"Autoriser les applications à définir les propriétaires des profils et celui de l\'appareil"</string>
- <string name="permlab_reorderTasks" msgid="7598562301992923804">"réorganiser les applications en cours d\'exécution"</string>
- <string name="permdesc_reorderTasks" msgid="8796089937352344183">"Permet à l\'application de déplacer les tâches au premier plan et en arrière-plan. L\'application peut procéder à ces opérations sans votre intervention."</string>
+ <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"Autoriser les applis à définir les propriétaires des profils et celui de l\'appareil"</string>
+ <string name="permlab_reorderTasks" msgid="7598562301992923804">"réorganiser les applis en cours d\'exécution"</string>
+ <string name="permdesc_reorderTasks" msgid="8796089937352344183">"Permet à l\'appli de déplacer les tâches au premier plan et en arrière-plan. L\'appli peut procéder à ces opérations sans votre intervention."</string>
<string name="permlab_enableCarMode" msgid="893019409519325311">"activer le mode voiture"</string>
- <string name="permdesc_enableCarMode" msgid="56419168820473508">"Permet à l\'application d\'activer le mode Voiture."</string>
- <string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"fermer les autres applications"</string>
- <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"Permet à l\'application de mettre fin aux processus d\'autres applications exécutés en arrière-plan. Cette autorisation peut interrompre l\'exécution d\'autres applications."</string>
- <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Cette application peut s\'afficher par-dessus d\'autres applications"</string>
- <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Cette application peut s\'afficher par-dessus d\'autres applications ou parties de l\'écran. Cela pourrait interférer avec l\'utilisation normale des applications et modifier la manière dont les autres applications s\'affichent à l\'écran."</string>
- <string name="permlab_hideOverlayWindows" msgid="6382697828482271802">"Masquer les superpositions d\'autres applications"</string>
- <string name="permdesc_hideOverlayWindows" msgid="5660242821651958225">"Cette application peut demander au système de masquer les superpositions provenant d\'applications, afin qu\'elles ne s\'affichent pas au-dessus de celle-ci."</string>
+ <string name="permdesc_enableCarMode" msgid="56419168820473508">"Permet à l\'appli d\'activer le mode Voiture."</string>
+ <string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"fermer les autres applis"</string>
+ <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"Permet à l\'appli de mettre fin aux processus d\'autres applis exécutés en arrière-plan. Cette autorisation peut interrompre l\'exécution d\'autres applis."</string>
+ <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Cette appli peut s\'afficher par-dessus d\'autres applis"</string>
+ <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Cette appli peut s\'afficher par-dessus d\'autres applis ou parties de l\'écran. Cela pourrait interférer avec l\'utilisation normale des applis et modifier la manière dont les autres applis s\'affichent à l\'écran."</string>
+ <string name="permlab_hideOverlayWindows" msgid="6382697828482271802">"Masquer les superpositions d\'autres applis"</string>
+ <string name="permdesc_hideOverlayWindows" msgid="5660242821651958225">"Cette appli peut demander au système de masquer les superpositions provenant d\'applis, afin qu\'elles ne s\'affichent pas au-dessus de celle-ci."</string>
<string name="permlab_runInBackground" msgid="541863968571682785">"fonctionner en arrière-plan"</string>
- <string name="permdesc_runInBackground" msgid="4344539472115495141">"Cette application peut fonctionner en arrière-plan. Cela risque d\'épuiser la pile plus rapidement."</string>
+ <string name="permdesc_runInBackground" msgid="4344539472115495141">"Cette appli peut fonctionner en arrière-plan. Cela risque d\'épuiser la pile plus rapidement."</string>
<string name="permlab_useDataInBackground" msgid="783415807623038947">"utiliser des données en arrière-plan"</string>
- <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Cette application peut utiliser des données en arrière-plan. Cela risque d\'augmenter l\'utilisation des données."</string>
+ <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Cette appli peut utiliser des données en arrière-plan. Cela risque d\'augmenter l\'utilisation des données."</string>
<string name="permlab_schedule_exact_alarm" msgid="6683283918033029730">"Programmer des actions à échéance précise"</string>
- <string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"Cette application peut programmer des tâches à effectuer ultérieurement à un moment voulu. Cela implique que l\'application peut également s\'exécuter quand vous n\'utilisez pas activement l\'appareil."</string>
+ <string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"Cette appli peut programmer des tâches à effectuer ultérieurement à un moment voulu. Cela implique que l\'appli peut également s\'exécuter quand vous n\'utilisez pas activement l\'appareil."</string>
<string name="permlab_use_exact_alarm" msgid="348045139777131552">"Programmer des alarmes ou des rappels d\'événements"</string>
- <string name="permdesc_use_exact_alarm" msgid="7033761461886938912">"Cette application peut programmer des actions, comme des alarmes et des rappels, pour vous avertir ultérieurement à un moment voulu."</string>
- <string name="permlab_persistentActivity" msgid="464970041740567970">"exécuter l\'application en continu"</string>
- <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Permet à l\'application de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applications et ralentir la tablette."</string>
- <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Permet à l\'application de rendre certains de ses composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applications et ralentir l\'appareil Android TV."</string>
- <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permet à l\'application de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applications et ralentir le téléphone."</string>
+ <string name="permdesc_use_exact_alarm" msgid="7033761461886938912">"Cette appli peut programmer des actions, comme des alarmes et des rappels, pour vous avertir ultérieurement à un moment voulu."</string>
+ <string name="permlab_persistentActivity" msgid="464970041740567970">"exécuter l\'appli en continu"</string>
+ <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Permet à l\'appli de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applis et ralentir la tablette."</string>
+ <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Permet à l\'appli de rendre certains de ses composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applis et ralentir l\'appareil Android TV."</string>
+ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permet à l\'appli de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applis et ralentir le téléphone."</string>
<string name="permlab_foregroundService" msgid="1768855976818467491">"exécuter le service en premier plan"</string>
- <string name="permdesc_foregroundService" msgid="8720071450020922795">"Permet à l\'application d\'utiliser les services en premier plan."</string>
+ <string name="permdesc_foregroundService" msgid="8720071450020922795">"Permet à l\'appli d\'utiliser les services en premier plan."</string>
<string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"exécuter le service d\'avant-plan avec le type « appareil photo »"</string>
- <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « appareil photo »"</string>
+ <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « appareil photo »"</string>
<string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"exécuter le service d\'avant-plan avec le type « appareil connecté »"</string>
- <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « appareil connecté »"</string>
+ <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « appareil connecté »"</string>
<string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"exécuter le service d\'avant-plan avec le type « synchronisation des données »"</string>
- <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « synchronisation des données »"</string>
+ <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « synchronisation des données »"</string>
<string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"exécuter le service d\'avant-plan avec le type « emplacement »"</string>
- <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « emplacement »"</string>
+ <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « emplacement »"</string>
<string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"exécuter le service d\'avant-plan avec le type « lecture multimédia »"</string>
- <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « lecture multimédia »"</string>
+ <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « lecture multimédia »"</string>
<string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"exécuter le service d\'avant-plan avec le type « projection de contenus multimédias »"</string>
- <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « projection de contenus multimédias »"</string>
+ <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « projection de contenus multimédias »"</string>
<string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"exécuter le service d\'avant-plan avec le type « microphone »"</string>
- <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « microphone »"</string>
+ <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « microphone »"</string>
<string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"exécuter le service d\'avant-plan avec le type « appel téléphonique »"</string>
- <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « appel téléphonique »"</string>
+ <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « appel téléphonique »"</string>
<string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"exécuter le service d\'avant-plan avec le type « santé »"</string>
- <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « santé »"</string>
+ <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « santé »"</string>
<string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"exécuter le service d\'avant-plan avec le type « messagerie à distance »"</string>
- <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « messagerie à distance »"</string>
+ <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « messagerie à distance »"</string>
<string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"exécuter le service d\'avant-plan avec le type « système exempté »"</string>
- <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « système exempté »"</string>
+ <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « système exempté »"</string>
<string name="permlab_foregroundServiceFileManagement" msgid="2585000987966045030">"exécuter le service d\'avant-plan avec le type « fileManagement »"</string>
- <string name="permdesc_foregroundServiceFileManagement" msgid="417103601269698508">"Autorise l\'application à utiliser les services d\'avant-plan avec le type « fileManagement »"</string>
+ <string name="permdesc_foregroundServiceFileManagement" msgid="417103601269698508">"Autorise l\'appli à utiliser les services d\'avant-plan avec le type « fileManagement »"</string>
<string name="permlab_foregroundServiceMediaProcessing" msgid="3045295152245381864">"exécuter le service de premier plan avec le type « mediaProcessing »"</string>
- <string name="permdesc_foregroundServiceMediaProcessing" msgid="8303086172106677312">"Autorise l\'application à utiliser les services de premier plan avec le type « mediaProcessing »"</string>
+ <string name="permdesc_foregroundServiceMediaProcessing" msgid="8303086172106677312">"Autorise l\'appli à utiliser les services de premier plan avec le type « mediaProcessing »"</string>
<string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"exécuter le service d\'avant-plan avec le type « usage spécial »"</string>
- <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « usage spécial »"</string>
- <string name="permlab_getPackageSize" msgid="375391550792886641">"évaluer l\'espace de stockage de l\'application"</string>
- <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permet à l\'application de récupérer la taille de son code, de ses données et de sa mémoire cache."</string>
+ <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « usage spécial »"</string>
+ <string name="permlab_getPackageSize" msgid="375391550792886641">"évaluer l\'espace de stockage de l\'appli"</string>
+ <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permet à l\'appli de récupérer la taille de son code, de ses données et de sa mémoire cache."</string>
<string name="permlab_writeSettings" msgid="8057285063719277394">"modifier les paramètres du système"</string>
- <string name="permdesc_writeSettings" msgid="8293047411196067188">"Permet à l\'application de modifier les paramètres du système. Des applications malveillantes peuvent utiliser cette fonctionnalité pour corrompre la configuration de votre système."</string>
+ <string name="permdesc_writeSettings" msgid="8293047411196067188">"Permet à l\'appli de modifier les paramètres du système. Des applis malveillantes peuvent utiliser cette fonctionnalité pour corrompre la configuration de votre système."</string>
<string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"s\'exécuter au démarrage"</string>
- <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Permet à l\'application de se lancer une fois le démarrage du système terminé. Elle peut rallonger le temps de démarrage de la tablette et ralentir son fonctionnement global en raison de son exécution continue."</string>
- <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Permet à l\'application de se lancer une fois le démarrage du système terminé. Cela peut rallonger le temps de démarrage de votre appareil Android TV et permettre à l\'application d\'en ralentir le fonctionnement global en raison de son exécution continue."</string>
- <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Permet à l\'application de se lancer une fois le démarrage du système terminé. Elle peut rallonger le temps de démarrage du téléphone et ralentir son fonctionnement global en raison de son exécution continue."</string>
+ <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Permet à l\'appli de se lancer une fois le démarrage du système terminé. Elle peut rallonger le temps de démarrage de la tablette et ralentir son fonctionnement global en raison de son exécution continue."</string>
+ <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Permet à l\'appli de se lancer une fois le démarrage du système terminé. Cela peut rallonger le temps de démarrage de votre appareil Android TV et permettre à l\'appli d\'en ralentir le fonctionnement global en raison de son exécution continue."</string>
+ <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Permet à l\'appli de se lancer une fois le démarrage du système terminé. Elle peut rallonger le temps de démarrage du téléphone et ralentir son fonctionnement global en raison de son exécution continue."</string>
<string name="permlab_broadcastSticky" msgid="4552241916400572230">"envoyer une diffusion persistante"</string>
- <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir la tablette ou la rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
- <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permet à l\'application d\'envoyer des intentions de diffusion persistantes, qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir votre appareil Android TV ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
- <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir le téléphone ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
+ <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Permet à l\'appli d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir la tablette ou la rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
+ <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permet à l\'appli d\'envoyer des intentions de diffusion persistantes, qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir votre appareil Android TV ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
+ <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permet à l\'appli d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir le téléphone ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"lire vos contacts"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre tablette. Les applications auront aussi accès aux comptes sur votre tablette qui ont créé des contacts. Cela peut comprendre des comptes créés par des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
- <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre appareil Android TV. Les applications auront aussi accès aux comptes sur votre appareil Android TV qui ont créé des contacts. Cela peut comprendre des comptes créés par des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
- <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre téléphone. Les applications auront aussi accès aux comptes sur votre téléphone qui ont créé des contacts. Cela peut comprendre des comptes créés par des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permet à l\'appli de lire les données relatives aux contacts stockés sur votre tablette. Les applis auront aussi accès aux comptes sur votre tablette qui ont créé des contacts. Cela peut comprendre des comptes créés par des applis que vous avez installées. Cette autorisation permet aux applis d\'enregistrer ces données. Les applis malveillantes peuvent les partager à votre insu."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permet à l\'appli de lire les données relatives aux contacts stockés sur votre appareil Android TV. Les applis auront aussi accès aux comptes sur votre appareil Android TV qui ont créé des contacts. Cela peut comprendre des comptes créés par des applis que vous avez installées. Cette autorisation permet aux applis d\'enregistrer ces données. Les applis malveillantes peuvent les partager à votre insu."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permet à l\'appli de lire les données relatives aux contacts stockés sur votre téléphone. Les applis auront aussi accès aux comptes sur votre téléphone qui ont créé des contacts. Cela peut comprendre des comptes créés par des applis que vous avez installées. Cette autorisation permet aux applis d\'enregistrer ces données. Les applis malveillantes peuvent les partager à votre insu."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modifier vos contacts"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre tablette. Cette autorisation permet aux applications de supprimer des données relatives aux contacts."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre appareil Android TV. Cette autorisation permet aux applications de supprimer des données relatives aux contacts."</string>
- <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre téléphone. Cette autorisation permet aux applications de supprimer des données relatives aux contacts."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permet à l\'appli de modifier les données relatives aux contacts stockés sur votre tablette. Cette autorisation permet aux applis de supprimer des données relatives aux contacts."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permet à l\'appli de modifier les données relatives aux contacts stockés sur votre appareil Android TV. Cette autorisation permet aux applis de supprimer des données relatives aux contacts."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permet à l\'appli de modifier les données relatives aux contacts stockés sur votre téléphone. Cette autorisation permet aux applis de supprimer des données relatives aux contacts."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"lire le journal d\'appels"</string>
- <string name="permdesc_readCallLog" msgid="8964770895425873433">"Cette application peut lire votre historique d\'appel."</string>
+ <string name="permdesc_readCallLog" msgid="8964770895425873433">"Cette appli peut lire votre historique d\'appel."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"modifier le journal d\'appels"</string>
- <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permet à l\'application de lire le journal d\'appels de votre tablette, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
- <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permet à l\'application de modifier le journal d\'appels de votre appareil Android TV, y compris les données sur les appels entrants et sortants. Des applications malveillantes pourraient utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permet à l\'application de lire le journal d\'appels de votre téléphone, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permet à l\'appli de lire le journal d\'appels de votre tablette, y compris les données relatives aux appels entrants et sortants. Des applis malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permet à l\'appli de modifier le journal d\'appels de votre appareil Android TV, y compris les données sur les appels entrants et sortants. Des applis malveillantes pourraient utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permet à l\'appli de lire le journal d\'appels de votre téléphone, y compris les données relatives aux appels entrants et sortants. Des applis malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
<string name="permlab_bodySensors" msgid="662918578601619569">"Accéder aux données des capteurs corporels si en utilisation (fréq. card., etc.)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant l\'utilisation de l\'application."</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'appli d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant l\'utilisation de l\'appli."</string>
<string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données des capteurs corporels (comme la fréq. card.) en arrière-plan"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant que l\'application s\'exécute en arrière-plan."</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'appli d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant que l\'appli s\'exécute en arrière-plan."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Lire les événements d\'agenda et leurs détails"</string>
- <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette application peut lire tous les événements d\'agenda stockés sur votre tablette et partager ou enregistrer les données de votre agenda."</string>
- <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Cette application peut lire tous les événements d\'agenda stockés sur votre appareil Android TV et partager ou enregistrer les données de votre agenda."</string>
- <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Cette application peut lire tous les événements d\'agenda stockés sur votre téléphone et partager ou enregistrer les données de votre agenda."</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette appli peut lire tous les événements d\'agenda stockés sur votre tablette et partager ou enregistrer les données de votre agenda."</string>
+ <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Cette appli peut lire tous les événements d\'agenda stockés sur votre appareil Android TV et partager ou enregistrer les données de votre agenda."</string>
+ <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Cette appli peut lire tous les événements d\'agenda stockés sur votre téléphone et partager ou enregistrer les données de votre agenda."</string>
<string name="permlab_writeCalendar" msgid="6422137308329578076">"ajouter ou modifier des événements d\'agenda et envoyer des courriels aux invités à l\'insu du propriétaire"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Cette application peut ajouter, supprimer et modifier des événements d\'agenda sur votre tablette. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
- <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Cette application peut ajouter, supprimer et modifier des événements d\'agenda sur votre appareil Android TV. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Cette application peut ajouter, supprimer et modifier des événements d\'agenda sur votre téléphone. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Cette appli peut ajouter, supprimer et modifier des événements d\'agenda sur votre tablette. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
+ <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Cette appli peut ajouter, supprimer et modifier des événements d\'agenda sur votre appareil Android TV. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Cette appli peut ajouter, supprimer et modifier des événements d\'agenda sur votre téléphone. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"accéder aux commandes de fournisseur de position géographique supplémentaires"</string>
- <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permet à l\'application d\'accéder à des commandes de localisation supplémentaires offertes par le fournisseur. Elle est ainsi susceptible d\'interférer avec le bon fonctionnement du GPS ou de toute autre source de localisation."</string>
+ <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permet à l\'appli d\'accéder à des commandes de localisation supplémentaires offertes par le fournisseur. Elle est ainsi susceptible d\'interférer avec le bon fonctionnement du GPS ou de toute autre source de localisation."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"accéder à votre position précise seulement en avant-plan"</string>
- <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Cette application peut obtenir votre position précise des services de localisation lorsque vous utilisez l\'application. Les services de localisation doivent être activés sur votre appareil pour que l\'application puisse obtenir votre position. Cela pourrait accroître l\'utilisation de la pile."</string>
+ <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Cette appli peut obtenir votre position précise des services de localisation lorsque vous utilisez l\'appli. Les services de localisation doivent être activés sur votre appareil pour que l\'appli puisse obtenir votre position. Cela pourrait accroître l\'utilisation de la pile."</string>
<string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"accéder à votre position approximative seulement en avant-plan"</string>
- <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Cette application peut obtenir votre position approximative des services de localisation lorsque vous utilisez l\'application. Les services de localisation doivent être activés sur votre appareil pour que l\'application puisse obtenir votre position."</string>
+ <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Cette appli peut obtenir votre position approximative des services de localisation lorsque vous utilisez l\'appli. Les services de localisation doivent être activés sur votre appareil pour que l\'appli puisse obtenir votre position."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"accès à la localisation en arrière-plan"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Cette application peut accéder à votre position en tout temps, même lorsque vous n\'utilisez pas l\'application."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Cette appli peut accéder à votre position en tout temps, même lorsque vous n\'utilisez pas l\'appli."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"modifier vos paramètres audio"</string>
- <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permet à l\'application de modifier les paramètres audio généraux, tels que le volume et la sortie audio utilisée."</string>
+ <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permet à l\'appli de modifier les paramètres audio généraux, tels que le volume et la sortie audio utilisée."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"enregistrer des fichiers audio"</string>
- <string name="permdesc_recordAudio" msgid="5857246765327514062">"Cette application peut enregistrer de l\'audio à l\'aide du microphone lorsque vous utilisez l\'application."</string>
+ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Cette appli peut enregistrer de l\'audio à l\'aide du microphone lorsque vous utilisez l\'appli."</string>
<string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"enregistrer de l\'audio en arrière-plan"</string>
- <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Cette application peut enregistrer de l\'audio à l\'aide du microphone en tout temps."</string>
- <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"détecter les captures d\'écran des fenêtres d\'application"</string>
- <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Cette application recevra une notification lorsqu\'une capture d\'écran sera prise pendant que l\'application est en cours d\'utilisation."</string>
+ <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Cette appli peut enregistrer de l\'audio à l\'aide du microphone en tout temps."</string>
+ <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"détecter les captures d\'écran des fenêtres d\'appli"</string>
+ <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Cette appli recevra une notification lorsqu\'une capture d\'écran sera prise pendant que l\'appli est en cours d\'utilisation."</string>
<string name="permlab_sim_communication" msgid="176788115994050692">"envoyer des commandes à la carte SIM"</string>
- <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permet à l\'application d\'envoyer des commandes à la carte SIM. Cette fonctionnalité est très dangereuse."</string>
+ <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permet à l\'appli d\'envoyer des commandes à la carte SIM. Cette fonctionnalité est très dangereuse."</string>
<string name="permlab_activityRecognition" msgid="1782303296053990884">"reconnaître les activités physiques"</string>
- <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Cette application peut reconnaître vos activités physiques."</string>
+ <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Cette appli peut reconnaître vos activités physiques."</string>
<string name="permlab_camera" msgid="6320282492904119413">"prendre des photos et filmer des vidéos"</string>
- <string name="permdesc_camera" msgid="5240801376168647151">"Cette application peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo lorsque vous utilisez l\'application."</string>
+ <string name="permdesc_camera" msgid="5240801376168647151">"Cette appli peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo lorsque vous utilisez l\'appli."</string>
<string name="permlab_backgroundCamera" msgid="7549917926079731681">"prendre des photos et enregistrer des vidéos en arrière-plan"</string>
- <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Cette application peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo en tout temps."</string>
- <string name="permlab_systemCamera" msgid="3642917457796210580">"Autoriser une application ou un service à accéder aux appareils photo système pour prendre des photos et filmer des vidéos"</string>
- <string name="permdesc_systemCamera" msgid="5938360914419175986">"Cette application privilégiée ou système peut prendre des photos ou filmer des vidéos à l\'aide d\'un appareil photo système en tout temps. L\'application doit également posséder l\'autorisation android.permission.CAMERA"</string>
- <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Autoriser une application ou un service de recevoir des rappels relatifs à l\'ouverture ou à la fermeture des appareils photos."</string>
- <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Cette application peut recevoir des rappels lorsque l\'appareil photo est ouvert ou fermé (par l\'application en question)."</string>
- <string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"Autoriser une application ou un service à accéder à la caméra en tant qu\'utilisateur de système sans interface."</string>
- <string name="permdesc_cameraHeadlessSystemUser" msgid="6963163319710996412">"Cette application peut accéder à la caméra en tant qu\'utilisateur de système sans interface."</string>
+ <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Cette appli peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo en tout temps."</string>
+ <string name="permlab_systemCamera" msgid="3642917457796210580">"Autoriser une appli ou un service à accéder aux appareils photo système pour prendre des photos et filmer des vidéos"</string>
+ <string name="permdesc_systemCamera" msgid="5938360914419175986">"Cette appli privilégiée ou système peut prendre des photos ou filmer des vidéos à l\'aide d\'un appareil photo système en tout temps. L\'appli doit également posséder l\'autorisation android.permission.CAMERA"</string>
+ <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Autoriser une appli ou un service de recevoir des rappels relatifs à l\'ouverture ou à la fermeture des appareils photos."</string>
+ <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Cette appli peut recevoir des rappels lorsque l\'appareil photo est ouvert ou fermé (par l\'appli en question)."</string>
+ <string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"Autoriser une appli ou un service à accéder à la caméra en tant qu\'utilisateur de système sans interface."</string>
+ <string name="permdesc_cameraHeadlessSystemUser" msgid="6963163319710996412">"Cette appli peut accéder à la caméra en tant qu\'utilisateur de système sans interface."</string>
<string name="permlab_vibrate" msgid="8596800035791962017">"gérer le vibreur"</string>
- <string name="permdesc_vibrate" msgid="8733343234582083721">"Permet à l\'application de gérer le vibreur de l\'appareil."</string>
- <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permet à l\'application d\'accéder au mode vibration."</string>
+ <string name="permdesc_vibrate" msgid="8733343234582083721">"Permet à l\'appli de gérer le vibreur de l\'appareil."</string>
+ <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permet à l\'appli d\'accéder au mode vibration."</string>
<string name="permlab_callPhone" msgid="1798582257194643320">"appeler directement des numéros de téléphone"</string>
- <string name="permdesc_callPhone" msgid="7892422187827695656">"Autorisez l\'application à appeler des numéros de téléphone sans votre intervention. Cela peut entraîner des frais ou des appels imprévus. Notez aussi que cela ne permet pas à l\'application d\'appeler des numéros d\'urgence. Des applications malveillantes peuvent engendrer des frais en passant des appels sans votre confirmation ou en composant des codes de fournisseurs de service qui transfèrent automatiquement des appels entrants vers un autre numéro."</string>
+ <string name="permdesc_callPhone" msgid="7892422187827695656">"Autorisez l\'appli à appeler des numéros de téléphone sans votre intervention. Cela peut entraîner des frais ou des appels imprévus. Notez aussi que cela ne permet pas à l\'appli d\'appeler des numéros d\'urgence. Des applis malveillantes peuvent engendrer des frais en passant des appels sans votre confirmation ou en composant des codes de fournisseurs de service qui transfèrent automatiquement des appels entrants vers un autre numéro."</string>
<string name="permlab_accessImsCallService" msgid="442192920714863782">"accéder au service d\'appel IMS"</string>
- <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permet à l\'application d\'utiliser le service IMS pour faire des appels sans votre intervention."</string>
+ <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permet à l\'appli d\'utiliser le service IMS pour faire des appels sans votre intervention."</string>
<string name="permlab_readPhoneState" msgid="8138526903259297969">"voir l\'état et l\'identité du téléphone"</string>
- <string name="permdesc_readPhoneState" msgid="7229063553502788058">"Permet à l\'application d\'accéder aux fonctionnalités téléphoniques de l\'appareil. Cette autorisation permet à l\'application de déterminer le numéro de téléphone et les identifiants de l\'appareil, si un appel est actif et le numéro distant connecté par un appel."</string>
+ <string name="permdesc_readPhoneState" msgid="7229063553502788058">"Permet à l\'appli d\'accéder aux fonctionnalités téléphoniques de l\'appareil. Cette autorisation permet à l\'appli de déterminer le numéro de téléphone et les identifiants de l\'appareil, si un appel est actif et le numéro distant connecté par un appel."</string>
<string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"Lire l\'état et l\'identité de la téléphonie de base"</string>
- <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Permet à l\'application d\'accéder aux fonctionnalités de téléphonie de base de l\'appareil."</string>
+ <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Permet à l\'appli d\'accéder aux fonctionnalités de téléphonie de base de l\'appareil."</string>
<string name="permlab_manageOwnCalls" msgid="9033349060307561370">"acheminer les appels dans le système"</string>
- <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Permet à l\'application d\'acheminer ses appels dans le système afin d\'améliorer l\'expérience d\'appel."</string>
+ <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Permet à l\'appli d\'acheminer ses appels dans le système afin d\'améliorer l\'expérience d\'appel."</string>
<string name="permlab_callCompanionApp" msgid="3654373653014126884">"afficher et gérer les appels à l\'aide du système."</string>
- <string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Autorise l\'application à afficher et à gérer les appels sortants sur l\'appareil. Cela comprend de l\'information comme les numéros pour les appels et l\'état des appels."</string>
+ <string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Autorise l\'appli à afficher et à gérer les appels sortants sur l\'appareil. Cela comprend de l\'information comme les numéros pour les appels et l\'état des appels."</string>
<string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"est exemptée des restrictions relatives à l\'enregistrement de fichiers audio"</string>
- <string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Exempter l\'application des restrictions relatives à l\'enregistrement de fichiers audio."</string>
- <string name="permlab_acceptHandover" msgid="2925523073573116523">"continuer un appel d\'une autre application"</string>
- <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Permet à l\'application de continuer un appel commencé dans une autre application."</string>
+ <string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Exempter l\'appli des restrictions relatives à l\'enregistrement de fichiers audio."</string>
+ <string name="permlab_acceptHandover" msgid="2925523073573116523">"continuer un appel d\'une autre appli"</string>
+ <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Permet à l\'appli de continuer un appel commencé dans une autre appli."</string>
<string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"lire les numéros de téléphone"</string>
- <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Permet à l\'application d\'accéder aux numéros de téléphone de l\'appareil."</string>
+ <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Permet à l\'appli d\'accéder aux numéros de téléphone de l\'appareil."</string>
<string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"garder l\'écran de la voiture allumé"</string>
<string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"empêcher la tablette de passer en mode veille"</string>
<string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"Empêcher votre appareil Android TV de passer en mode Veille"</string>
<string name="permlab_wakeLock" product="default" msgid="569409726861695115">"empêcher le téléphone de passer en mode veille"</string>
- <string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"Permet à l\'application de garder l\'écran de la voiture allumé."</string>
- <string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"Permet à l\'application d\'empêcher la tablette de passer en mode veille."</string>
- <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Permet à l\'application d\'empêcher votre appareil Android TV de passer en mode Veille."</string>
- <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Permet à l\'application d\'empêcher le téléphone de passer en mode veille."</string>
+ <string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"Permet à l\'appli de garder l\'écran de la voiture allumé."</string>
+ <string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"Permet à l\'appli d\'empêcher la tablette de passer en mode veille."</string>
+ <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Permet à l\'appli d\'empêcher votre appareil Android TV de passer en mode Veille."</string>
+ <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Permet à l\'appli d\'empêcher le téléphone de passer en mode veille."</string>
<string name="permlab_transmitIr" msgid="8077196086358004010">"transmettre des signaux infrarouges"</string>
- <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Permet à l\'application d\'utiliser l\'émetteur infrarouge de la tablette."</string>
- <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Permet à l\'application d\'utiliser le transmetteur infrarouge de votre appareil Android TV."</string>
- <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Permet à l\'application d\'utiliser l\'émetteur infrarouge du téléphone."</string>
+ <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Permet à l\'appli d\'utiliser l\'émetteur infrarouge de la tablette."</string>
+ <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Permet à l\'appli d\'utiliser le transmetteur infrarouge de votre appareil Android TV."</string>
+ <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Permet à l\'appli d\'utiliser l\'émetteur infrarouge du téléphone."</string>
<string name="permlab_setWallpaper" msgid="6959514622698794511">"définir le fond d\'écran"</string>
- <string name="permdesc_setWallpaper" msgid="2973996714129021397">"Permet à l\'application de définir le fond d\'écran du système."</string>
+ <string name="permdesc_setWallpaper" msgid="2973996714129021397">"Permet à l\'appli de définir le fond d\'écran du système."</string>
<string name="permlab_accessHiddenProfile" msgid="8607094418491556823">"Accéder aux profils masqués"</string>
- <string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"Autorise l\'application à accéder aux profils masqués"</string>
+ <string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"Autorise l\'appli à accéder aux profils masqués"</string>
<string name="permlab_setWallpaperHints" msgid="1153485176642032714">"modifier la taille du fond d\'écran"</string>
- <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Permet à l\'application de définir les bulles d\'aide concernant la taille du fond d\'écran du système."</string>
+ <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Permet à l\'appli de définir les bulles d\'aide concernant la taille du fond d\'écran du système."</string>
<string name="permlab_setTimeZone" msgid="7922618798611542432">"définir le fuseau horaire"</string>
- <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Permet à l\'application de modifier le fuseau horaire de la tablette."</string>
- <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Permet à l\'application de modifier le fuseau horaire de votre appareil Android TV."</string>
- <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Permet à l\'application de modifier le fuseau horaire du téléphone."</string>
+ <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Permet à l\'appli de modifier le fuseau horaire de la tablette."</string>
+ <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Permet à l\'appli de modifier le fuseau horaire de votre appareil Android TV."</string>
+ <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Permet à l\'appli de modifier le fuseau horaire du téléphone."</string>
<string name="permlab_getAccounts" msgid="5304317160463582791">"rechercher des comptes sur l\'appareil"</string>
- <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Permet à l\'application d\'obtenir la liste des comptes connus par la tablette. Il peut s\'agir de n\'importe quel compte créé par les applications que vous avez installées."</string>
- <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Permet à l\'application d\'obtenir la liste des comptes connus de votre appareil Android TV. Cela peut comprendre n\'importe quel compte créé par les applications que vous avez installées."</string>
- <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Permet à l\'application d\'obtenir la liste des comptes connus par le téléphone. Il peut s\'agir de n\'importe quel compte créé par les applications que vous avez installées."</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Permet à l\'appli d\'obtenir la liste des comptes connus par la tablette. Il peut s\'agir de n\'importe quel compte créé par les applis que vous avez installées."</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Permet à l\'appli d\'obtenir la liste des comptes connus de votre appareil Android TV. Cela peut comprendre n\'importe quel compte créé par les applis que vous avez installées."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Permet à l\'appli d\'obtenir la liste des comptes connus par le téléphone. Il peut s\'agir de n\'importe quel compte créé par les applis que vous avez installées."</string>
<string name="permlab_accessNetworkState" msgid="2349126720783633918">"afficher les connexions réseau"</string>
- <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Permet à l\'application d\'accéder à des détails concernant les connexions réseau, comme les réseaux existants et connectés."</string>
+ <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Permet à l\'appli d\'accéder à des détails concernant les connexions réseau, comme les réseaux existants et connectés."</string>
<string name="permlab_createNetworkSockets" msgid="3224420491603590541">"bénéficier d\'un accès complet au réseau"</string>
- <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"Permet à l\'application de créer des interfaces de connexion réseau et d\'utiliser des protocoles réseau personnalisés. Le navigateur et d\'autres applications permettent d\'envoyer des données sur Internet. Cette autorisation n\'est donc pas nécessaire pour envoyer des données sur Internet."</string>
+ <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"Permet à l\'appli de créer des interfaces de connexion réseau et d\'utiliser des protocoles réseau personnalisés. Le navigateur et d\'autres applis permettent d\'envoyer des données sur Internet. Cette autorisation n\'est donc pas nécessaire pour envoyer des données sur Internet."</string>
<string name="permlab_changeNetworkState" msgid="8945711637530425586">"modifier la connectivité réseau"</string>
- <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Permet à l\'application de modifier l\'état de la connectivité réseau."</string>
+ <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Permet à l\'appli de modifier l\'état de la connectivité réseau."</string>
<string name="permlab_changeTetherState" msgid="9079611809931863861">"changer la connectivité du partage de connexion"</string>
- <string name="permdesc_changeTetherState" msgid="3025129606422533085">"Permet à l\'application de modifier l\'état de la connectivité du partage de connexion."</string>
+ <string name="permdesc_changeTetherState" msgid="3025129606422533085">"Permet à l\'appli de modifier l\'état de la connectivité du partage de connexion."</string>
<string name="permlab_accessWifiState" msgid="5552488500317911052">"afficher les connexions Wi-Fi"</string>
- <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Permet à l\'application d\'accéder à des détails sur les réseaux Wi-Fi afin de savoir si une connexion Wi-Fi est activée et pour connaître le nom des appareils connectés au Wi-Fi, par exemple."</string>
+ <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Permet à l\'appli d\'accéder à des détails sur les réseaux Wi-Fi afin de savoir si une connexion Wi-Fi est activée et pour connaître le nom des appareils connectés au Wi-Fi, par exemple."</string>
<string name="permlab_changeWifiState" msgid="7947824109713181554">"activer/désactiver la connexion Wi-Fi"</string>
- <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Permet à l\'application de se connecter à des points d\'accès Wi-Fi, de s\'en déconnecter et de modifier la configuration de l\'appareil pour les réseaux Wi-Fi."</string>
+ <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Permet à l\'appli de se connecter à des points d\'accès Wi-Fi, de s\'en déconnecter et de modifier la configuration de l\'appareil pour les réseaux Wi-Fi."</string>
<string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"autoriser la réception de données en mode Wi-Fi multidiffusion"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Permet à l\'application de recevoir des paquets envoyés à tous les appareils (et pas seulement à votre tablette) d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
- <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Permet à l\'application de recevoir des paquets envoyés à tous les appareils d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion, et pas seulement à votre appareil Android TV. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Permet à l\'application de recevoir des paquets envoyés à tous les appareils (et pas seulement à votre téléphone) d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Permet à l\'appli de recevoir des paquets envoyés à tous les appareils (et pas seulement à votre tablette) d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Permet à l\'appli de recevoir des paquets envoyés à tous les appareils d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion, et pas seulement à votre appareil Android TV. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Permet à l\'appli de recevoir des paquets envoyés à tous les appareils (et pas seulement à votre téléphone) d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"accéder aux paramètres Bluetooth"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Permet à l\'application de configurer la tablette Bluetooth locale, d\'identifier des appareils distants et de les associer à la tablette."</string>
- <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Permet à l\'application de configurer le Bluetooth sur votre appareil Android TV, de repérer des appareils distants et de les associer à l\'appareil."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Permet à l\'application de configurer le téléphone Bluetooth local, d\'identifier des appareils distants et de les associer au téléphone."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Permet à l\'appli de configurer la tablette Bluetooth locale, d\'identifier des appareils distants et de les associer à la tablette."</string>
+ <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Permet à l\'appli de configurer le Bluetooth sur votre appareil Android TV, de repérer des appareils distants et de les associer à l\'appareil."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Permet à l\'appli de configurer le téléphone Bluetooth local, d\'identifier des appareils distants et de les associer au téléphone."</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"se connecter au réseau WiMAX et s\'en déconnecter"</string>
- <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Permet à l\'application de déterminer si le WiMAX est activé et d\'obtenir des détails sur tous les réseaux WiMAX connectés."</string>
+ <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Permet à l\'appli de déterminer si le WiMAX est activé et d\'obtenir des détails sur tous les réseaux WiMAX connectés."</string>
<string name="permlab_changeWimaxState" msgid="6223305780806267462">"modifier l\'état du WiMAX"</string>
- <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Permet à l\'application de connecter la tablette aux réseaux WiMAX et de l\'en déconnecter."</string>
- <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Permet à l\'application de connecter votre appareil Android TV aux réseaux WiMAX et de les en déconnecter."</string>
- <string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Permet à l\'application de connecter le téléphone aux réseaux WiMAX et de l\'en déconnecter."</string>
+ <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Permet à l\'appli de connecter la tablette aux réseaux WiMAX et de l\'en déconnecter."</string>
+ <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Permet à l\'appli de connecter votre appareil Android TV aux réseaux WiMAX et de les en déconnecter."</string>
+ <string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Permet à l\'appli de connecter le téléphone aux réseaux WiMAX et de l\'en déconnecter."</string>
<string name="permlab_bluetooth" msgid="586333280736937209">"s\'associer à des appareils Bluetooth"</string>
- <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur la tablette, et d\'établir et accepter des connexions avec les appareils associés."</string>
- <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permet à l\'application d\'afficher la configuration du Bluetooth sur votre appareil Android TV, de se connecter à des appareils associés et d\'accepter leur connexion."</string>
- <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur le téléphone, et d\'établir et accepter des connexions avec les appareils associés."</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permet à l\'appli d\'accéder à la configuration du Bluetooth sur la tablette, et d\'établir et accepter des connexions avec les appareils associés."</string>
+ <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permet à l\'appli d\'afficher la configuration du Bluetooth sur votre appareil Android TV, de se connecter à des appareils associés et d\'accepter leur connexion."</string>
+ <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permet à l\'appli d\'accéder à la configuration du Bluetooth sur le téléphone, et d\'établir et accepter des connexions avec les appareils associés."</string>
<string name="permlab_bluetooth_scan" msgid="5402587142833124594">"découvrir des appareils Bluetooth et s\'y connecter"</string>
- <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permet à l\'application de découvrir les appareils Bluetooth à proximité et de s\'y connecter"</string>
+ <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permet à l\'appli de découvrir les appareils Bluetooth à proximité et de s\'y connecter"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"se connecter aux appareils Bluetooth associés"</string>
- <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permet à l\'application de se connecter aux appareils Bluetooth associés"</string>
+ <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permet à l\'appli de se connecter aux appareils Bluetooth associés"</string>
<string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"envoyer annonces aux appareils Bluetooth à proxim."</string>
- <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permet à l\'application d\'envoyer des annonces aux appareils Bluetooth à proximité"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permet à l\'appli d\'envoyer des annonces aux appareils Bluetooth à proximité"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
- <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autorisez l\'application à déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autorisez l\'appli à déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir avec les appareils Wi-Fi à proximité"</string>
- <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'application de diffuser des annonces, de se connecter et de déterminer la position relative des appareils Wi-Fi à proximité"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'appli de diffuser des annonces, de se connecter et de déterminer la position relative des appareils Wi-Fi à proximité"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information sur le service préféré de paiement CCP"</string>
- <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir de l\'information sur le service préféré de paiement CCP comme les aides enregistrées et la route de destination."</string>
+ <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'appli d\'obtenir de l\'information sur le service préféré de paiement CCP comme les aides enregistrées et la route de destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"gérer la communication en champ proche"</string>
- <string name="permdesc_nfc" msgid="8352737680695296741">"Permet à l\'application de communiquer avec des bornes, des cartes et des lecteurs compatibles avec la technologie CCP (communication en champ proche)."</string>
+ <string name="permdesc_nfc" msgid="8352737680695296741">"Permet à l\'appli de communiquer avec des bornes, des cartes et des lecteurs compatibles avec la technologie CCP (communication en champ proche)."</string>
<string name="permlab_nfcTransactionEvent" msgid="5868209446710407679">"Événement de transaction relatif à un élément sécurisé"</string>
- <string name="permdesc_nfcTransactionEvent" msgid="1904286701876487397">"Autorise l\'application à recevoir des informations relatives aux transactions effectuées sur un élément sécurisé."</string>
+ <string name="permdesc_nfcTransactionEvent" msgid="1904286701876487397">"Autorise l\'appli à recevoir des informations relatives aux transactions effectuées sur un élément sécurisé."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"désactiver le verrouillage de l\'écran"</string>
- <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Permet à l\'application de désactiver le verrouillage des touches et toute mesure de sécurité par mot de passe associée. Par exemple, votre téléphone désactive le verrouillage des touches lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez."</string>
+ <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Permet à l\'appli de désactiver le verrouillage des touches et toute mesure de sécurité par mot de passe associée. Par exemple, votre téléphone désactive le verrouillage des touches lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez."</string>
<string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"demander la complexité du verrouillage d\'écran"</string>
- <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Autorise l\'application à apprendre le niveau de complexité de l\'écran de verrouillage (élevé, moyen, faible ou aucun), qui indique la gamme possible de longueur et de type de verrouillage d\'écran. L\'application peut aussi suggérer aux utilisateurs de mettre à jour l\'écran de verrouillage afin d\'utiliser un certain niveau de complexité, mais ils peuvent ignorer la suggestion. Notez que le verrouillage d\'écran n\'est pas stocké en texte brut pour de manière à ce que l\'application n\'ait pas accès au mot de passe exact."</string>
+ <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Autorise l\'appli à apprendre le niveau de complexité de l\'écran de verrouillage (élevé, moyen, faible ou aucun), qui indique la gamme possible de longueur et de type de verrouillage d\'écran. L\'appli peut aussi suggérer aux utilisateurs de mettre à jour l\'écran de verrouillage afin d\'utiliser un certain niveau de complexité, mais ils peuvent ignorer la suggestion. Notez que le verrouillage d\'écran n\'est pas stocké en texte brut pour de manière à ce que l\'appli n\'ait pas accès au mot de passe exact."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"afficher les notifications"</string>
- <string name="permdesc_postNotification" msgid="5974977162462877075">"Permet à l\'application d\'afficher les notifications"</string>
+ <string name="permdesc_postNotification" msgid="5974977162462877075">"Permet à l\'appli d\'afficher les notifications"</string>
<string name="permlab_turnScreenOn" msgid="219344053664171492">"allumer l\'écran"</string>
- <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permet à l\'application d\'allumer l\'écran."</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permet à l\'appli d\'allumer l\'écran."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"utiliser le matériel biométrique"</string>
- <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permet à l\'application d\'utiliser du matériel biométrique pour l\'authentification"</string>
+ <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permet à l\'appli d\'utiliser du matériel biométrique pour l\'authentification"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"gérer le lecteur d\'empreintes digitales"</string>
- <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Permet à l\'application de faire appel à des méthodes d\'ajout et de suppression de modèles d\'empreinte digitale que vous pouvez utiliser."</string>
+ <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Permet à l\'appli de faire appel à des méthodes d\'ajout et de suppression de modèles d\'empreinte digitale que vous pouvez utiliser."</string>
<string name="permlab_useFingerprint" msgid="1001421069766751922">"utiliser le lecteur d\'empreintes digitales"</string>
- <string name="permdesc_useFingerprint" msgid="412463055059323742">"Permet à l\'application d\'utiliser le lecteur d\'empreintes digitales pour l\'authentification"</string>
+ <string name="permdesc_useFingerprint" msgid="412463055059323742">"Permet à l\'appli d\'utiliser le lecteur d\'empreintes digitales pour l\'authentification"</string>
<string name="permlab_audioWrite" msgid="8501705294265669405">"modifier votre collection de musique"</string>
- <string name="permdesc_audioWrite" msgid="8057399517013412431">"Autorise l\'application à modifier votre collection de musique."</string>
+ <string name="permdesc_audioWrite" msgid="8057399517013412431">"Autorise l\'appli à modifier votre collection de musique."</string>
<string name="permlab_videoWrite" msgid="5940738769586451318">"modifier votre collection de vidéos"</string>
- <string name="permdesc_videoWrite" msgid="6124731210613317051">"Autorise l\'application à modifier votre collection de vidéos."</string>
+ <string name="permdesc_videoWrite" msgid="6124731210613317051">"Autorise l\'appli à modifier votre collection de vidéos."</string>
<string name="permlab_imagesWrite" msgid="1774555086984985578">"modifier votre collection de photos"</string>
- <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Autorise l\'application à modifier votre collection de photos."</string>
+ <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Autorise l\'appli à modifier votre collection de photos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lire les positions issues de votre collection multimédia"</string>
- <string name="permdesc_mediaLocation" msgid="597912899423578138">"Autorise l\'application à lire les positions indiquées dans votre collection multimédia."</string>
+ <string name="permdesc_mediaLocation" msgid="597912899423578138">"Autorise l\'appli à lire les positions indiquées dans votre collection multimédia."</string>
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Utiliser les données biométriques"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utiliser les données biométriques ou le verrouillage de l\'écran"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmez que c\'est vous"</string>
@@ -758,81 +758,81 @@
<string name="face_error_vendor_unknown" msgid="7387005932083302070">"Un problème est survenu. Réessayez."</string>
<string name="face_icon_content_description" msgid="465030547475916280">"Icône visage"</string>
<string name="permlab_readSyncSettings" msgid="6250532864893156277">"lire les paramètres de synchronisation"</string>
- <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Permet à l\'application d\'accéder aux paramètres de synchronisation d\'un compte. Par exemple, cette autorisation peut permettre de déterminer si l\'application Contacts est synchronisée avec un compte ou non."</string>
+ <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Permet à l\'appli d\'accéder aux paramètres de synchronisation d\'un compte. Par exemple, cette autorisation peut permettre de déterminer si l\'appli Contacts est synchronisée avec un compte ou non."</string>
<string name="permlab_writeSyncSettings" msgid="6583154300780427399">"activer ou désactiver la synchronisation"</string>
- <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Permet à une application de modifier les paramètres de synchronisation d\'un compte. Cette autorisation peut, par exemple, être utilisée pour activer la synchronisation de l\'application Contacts avec un compte."</string>
+ <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Permet à une appli de modifier les paramètres de synchronisation d\'un compte. Cette autorisation peut, par exemple, être utilisée pour activer la synchronisation de l\'appli Contacts avec un compte."</string>
<string name="permlab_readSyncStats" msgid="3747407238320105332">"lire les statistiques de synchronisation"</string>
- <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Permet à une application d\'accéder aux statistiques de synchronisation d\'un compte, y compris l\'historique des événements de synchronisation et le volume de données synchronisées."</string>
+ <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Permet à une appli d\'accéder aux statistiques de synchronisation d\'un compte, y compris l\'historique des événements de synchronisation et le volume de données synchronisées."</string>
<string name="permlab_sdcardRead" msgid="5791467020950064920">"lire le contenu de votre espace de stockage partagé"</string>
- <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Permet à l\'application de lire le contenu de votre espace de stockage partagé."</string>
+ <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Permet à l\'appli de lire le contenu de votre espace de stockage partagé."</string>
<string name="permlab_readMediaAudio" msgid="8723513075731763810">"lire des fichiers audio à partir de l\'espace de stockage partagé"</string>
- <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permet à l\'application de lire les fichiers audio de votre espace de stockage partagé."</string>
+ <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permet à l\'appli de lire les fichiers audio de votre espace de stockage partagé."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"lire des fichiers vidéo à partir de l\'espace de stockage partagé"</string>
- <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permet à l\'application de lire les fichiers vidéo de votre espace de stockage partagé."</string>
+ <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permet à l\'appli de lire les fichiers vidéo de votre espace de stockage partagé."</string>
<string name="permlab_readMediaImages" msgid="4057590631020986789">"lire des fichiers d\'image à partir de l\'espace de stockage partagé"</string>
- <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permet à l\'application de lire les fichiers d\'image de votre espace de stockage partagé."</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permet à l\'appli de lire les fichiers d\'image de votre espace de stockage partagé."</string>
<string name="permlab_readVisualUserSelect" msgid="5516204215354667586">"lire les fichiers d\'images et de vidéos sélectionnés par l\'utilisateur dans l\'espace de stockage partagé"</string>
- <string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"Permet à l\'application de lire les fichiers d\'images et de vidéos que vous sélectionnez dans votre espace de stockage partagé."</string>
+ <string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"Permet à l\'appli de lire les fichiers d\'images et de vidéos que vous sélectionnez dans votre espace de stockage partagé."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modifier ou supprimer le contenu de votre espace de stockage partagé"</string>
- <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Autorise l\'application à écrire le contenu de votre espace de stockage partagé."</string>
+ <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Autorise l\'appli à écrire le contenu de votre espace de stockage partagé."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"faire et recevoir des appels SIP"</string>
- <string name="permdesc_use_sip" msgid="3590270893253204451">"Autorise l\'application à effectuer et à recevoir des appels SIP."</string>
+ <string name="permdesc_use_sip" msgid="3590270893253204451">"Autorise l\'appli à effectuer et à recevoir des appels SIP."</string>
<string name="permlab_register_sim_subscription" msgid="1653054249287576161">"enregistrer de nouvelles connexions de télécommunication à l\'aide de la carte SIM"</string>
- <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Permettre à l\'application d\'enregistrer de nouvelles connexions de télécommunication à l\'aide de la carte SIM"</string>
+ <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Permettre à l\'appli d\'enregistrer de nouvelles connexions de télécommunication à l\'aide de la carte SIM"</string>
<string name="permlab_register_call_provider" msgid="6135073566140050702">"enregistrer de nouvelles connexions de télécommunication"</string>
- <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Permettre à l\'application d\'enregistrer de nouvelles connexions de télécommunication"</string>
+ <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Permettre à l\'appli d\'enregistrer de nouvelles connexions de télécommunication"</string>
<string name="permlab_connection_manager" msgid="3179365584691166915">"gérer les connexions de télécommunication"</string>
- <string name="permdesc_connection_manager" msgid="1426093604238937733">"Permettre à l\'application de gérer les connexions de télécommunication"</string>
+ <string name="permdesc_connection_manager" msgid="1426093604238937733">"Permettre à l\'appli de gérer les connexions de télécommunication"</string>
<string name="permlab_bind_incall_service" msgid="5990625112603493016">"interagir avec l\'écran d\'appel"</string>
- <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Permet à l\'application de contrôler quand et comment l\'écran d\'appel s\'affiche."</string>
+ <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Permet à l\'appli de contrôler quand et comment l\'écran d\'appel s\'affiche."</string>
<string name="permlab_bind_connection_service" msgid="5409268245525024736">"interagir avec les services de téléphonie"</string>
- <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Permet à l\'application d\'interagir avec les services de téléphonie afin de faire et de recevoir des appels."</string>
+ <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Permet à l\'appli d\'interagir avec les services de téléphonie afin de faire et de recevoir des appels."</string>
<string name="permlab_control_incall_experience" msgid="6436863486094352987">"fournir une expérience utilisateur pendant l\'appel"</string>
- <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Permet à l\'application de fournir une expérience utilisateur pendant l\'appel."</string>
+ <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Permet à l\'appli de fournir une expérience utilisateur pendant l\'appel."</string>
<string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"lire l\'historique d\'utilisation de réseaux"</string>
- <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"Permet à l\'application de lire l\'historique d\'utilisation de réseaux et d\'applications particuliers."</string>
+ <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"Permet à l\'appli de lire l\'historique d\'utilisation de réseaux et d\'applis particuliers."</string>
<string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"gérer les politiques du réseau"</string>
- <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Permet à l\'application de gérer les politiques du réseau et de définir celles propres à l\'application"</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Permet à l\'appli de gérer les politiques du réseau et de définir celles propres à l\'appli"</string>
<string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"modifier le système d\'analyse de l\'utilisation du réseau"</string>
- <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Permet à l\'application de modifier le système d\'analyse de l\'utilisation du réseau par les autres applications. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+ <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Permet à l\'appli de modifier le système d\'analyse de l\'utilisation du réseau par les autres applis. Les applis standards ne doivent pas utiliser cette fonctionnalité."</string>
<string name="permlab_accessNotifications" msgid="7130360248191984741">"accéder aux notifications"</string>
- <string name="permdesc_accessNotifications" msgid="761730149268789668">"Permet aux applications de récupérer, d\'examiner et d\'autoriser les notifications, y compris celles envoyées par d\'autres applications."</string>
+ <string name="permdesc_accessNotifications" msgid="761730149268789668">"Permet aux applis de récupérer, d\'examiner et d\'autoriser les notifications, y compris celles envoyées par d\'autres applis."</string>
<string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications"</string>
- <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications. Ne devrait jamais être nécessaire pour les applications normales."</string>
+ <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"Permet à l\'appli de s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications. Ne devrait jamais être nécessaire pour les applis normales."</string>
<string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"s\'associer à un service de fournisseur de conditions"</string>
- <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service de fournisseur de conditions. Ne devrait pas être nécessaire pour les applications standards."</string>
+ <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Permet à l\'appli de s\'associer à l\'interface de niveau supérieur d\'un service de fournisseur de conditions. Ne devrait pas être nécessaire pour les applis standards."</string>
<string name="permlab_bindDreamService" msgid="4776175992848982706">"associer à un service de rêve"</string>
- <string name="permdesc_bindDreamService" msgid="9129615743300572973">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de rêve. Les applications standard ne devraient pas avoir recours à cette fonctionnalité."</string>
- <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"faire appel à l\'application de configuration du fournisseur de services"</string>
- <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Permet à l\'application autorisée de faire appel à l\'application de configuration fournie par le fournisseur de services. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+ <string name="permdesc_bindDreamService" msgid="9129615743300572973">"Permet à l\'appli autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de rêve. Les applis standard ne devraient pas avoir recours à cette fonctionnalité."</string>
+ <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"faire appel à l\'appli de configuration du fournisseur de services"</string>
+ <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Permet à l\'appli autorisée de faire appel à l\'appli de configuration fournie par le fournisseur de services. Cette fonctionnalité ne devrait pas être nécessaire pour les applis standards."</string>
<string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"détecter des observations sur les conditions du réseau"</string>
- <string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Permet à une application de détecter les observations sur les conditions du réseau. Ne devrait jamais être nécessaire pour les applications standards."</string>
+ <string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Permet à une appli de détecter les observations sur les conditions du réseau. Ne devrait jamais être nécessaire pour les applis standards."</string>
<string name="permlab_setInputCalibration" msgid="932069700285223434">"modifier le calibrage du périphérique d\'entrée"</string>
- <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Permet à l\'application de modifier les paramètres de calibrage de l\'écran tactile. Ne devrait jamais être nécessaire pour les applications standards."</string>
+ <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Permet à l\'appli de modifier les paramètres de calibrage de l\'écran tactile. Ne devrait jamais être nécessaire pour les applis standards."</string>
<string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"accéder aux certificats GDN"</string>
- <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Permet à une application de fournir et d\'utiliser les certificats de GDN. Cela ne devrait jamais être nécessaire pour les applications normales."</string>
+ <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Permet à une appli de fournir et d\'utiliser les certificats de GDN. Cela ne devrait jamais être nécessaire pour les applis normales."</string>
<string name="permlab_handoverStatus" msgid="7620438488137057281">"recevoir des données sur l\'état du transfert Android Beam"</string>
- <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Autoriser cette application à recevoir des données sur les transferts Android Beam en cours"</string>
+ <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Autoriser cette appli à recevoir des données sur les transferts Android Beam en cours"</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"supprimer des certificats GDN"</string>
- <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Permet à une application de supprimer les certificats GDN. Cela ne devrait jamais être nécessaire pour des applications normales."</string>
+ <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Permet à une appli de supprimer les certificats GDN. Cela ne devrait jamais être nécessaire pour des applis normales."</string>
<string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"s\'associer à un service de messagerie d\'un fournisseur"</string>
- <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de messagerie d\'un fournisseur. Les applications standards ne devraient jamais avoir recours à cette fonctionnalité."</string>
+ <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permet à l\'appli autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de messagerie d\'un fournisseur. Les applis standards ne devraient jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"s\'associer aux services d\'un fournisseur"</string>
- <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permet à l\'application autorisée de s\'associer aux services d\'un fournisseur. Ne devrait pas être nécessaire pour les applications standards."</string>
+ <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permet à l\'appli autorisée de s\'associer aux services d\'un fournisseur. Ne devrait pas être nécessaire pour les applis standards."</string>
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"accéder au mode Ne pas déranger"</string>
- <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permet à l\'application de consulter et de modifier la configuration du mode Ne pas déranger."</string>
+ <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permet à l\'appli de consulter et de modifier la configuration du mode Ne pas déranger."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"démarrer l\'affichage de l\'usage des autorisations"</string>
- <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permet au détenteur de démarrer l\'usage des autorisations pour une application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+ <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permet au détenteur de démarrer l\'usage des autorisations pour une appli. Cette fonctionnalité ne devrait pas être nécessaire pour les applis standards."</string>
<string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"démarrer les décisions d\'autorisation de lecture"</string>
- <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"Permet au détenteur de démarrer l\'écran pour revoir les décisions d\'autorisation. Ne devrait pas être requis pour les applications standards."</string>
- <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"démarrer l\'affichage des fonctionnalités de l\'application"</string>
- <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permet au détenteur de commencer à afficher les renseignements sur les fonctionnalités d\'une application."</string>
+ <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"Permet au détenteur de démarrer l\'écran pour revoir les décisions d\'autorisation. Ne devrait pas être requis pour les applis standards."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"démarrer l\'affichage des fonctionnalités de l\'appli"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permet au détenteur de commencer à afficher les renseignements sur les fonctionnalités d\'une appli."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"accéder aux données des capteurs à un taux d’échantillonnage élevé"</string>
- <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permet à l’application d’échantillonner les données des capteurs à une fréquence supérieure à 200 Hz"</string>
- <string name="permlab_updatePackagesWithoutUserAction" msgid="3363272609642618551">"Mettre à jour l\'application sans intervention de l\'utilisateur"</string>
- <string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Permet à une application précédemment installée de se mettre à jour sans intervention de l\'utilisateur"</string>
- <string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"mettre à jour les états des vérifications des clés de contact chiffrées de bout en bout qui appartiennent à d\'autres applications"</string>
- <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Autorise l\'application à mettre à jour les états des vérifications des clés de contact chiffrées de bout en bout qui appartiennent à d\'autres applications"</string>
+ <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permet à l’appli d’échantillonner les données des capteurs à une fréquence supérieure à 200 Hz"</string>
+ <string name="permlab_updatePackagesWithoutUserAction" msgid="3363272609642618551">"Mettre à jour l\'appli sans intervention de l\'utilisateur"</string>
+ <string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Permet à une appli précédemment installée de se mettre à jour sans intervention de l\'utilisateur"</string>
+ <string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"mettre à jour les états des vérifications des clés de contact chiffrées de bout en bout qui appartiennent à d\'autres applis"</string>
+ <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Autorise l\'appli à mettre à jour les états des vérifications des clés de contact chiffrées de bout en bout qui appartiennent à d\'autres applis"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Définir les règles du mot de passe"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Gérer le nombre et le type de caractères autorisés dans les mots de passe et les NIP de verrouillage de l\'écran."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -864,7 +864,7 @@
<string name="policylab_expirePassword" msgid="6015404400532459169">"Déf. expir. m. passe verr. écr."</string>
<string name="policydesc_expirePassword" msgid="9136524319325960675">"Modifier la fréquence de modification du mot de passe, du NIP ou du schéma de verrouillage de l\'écran."</string>
<string name="policylab_encryptedStorage" msgid="9012936958126670110">"Définir cryptage du stockage"</string>
- <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"Exiger le chiffrement des données d\'application stockées"</string>
+ <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"Exiger le chiffrement des données d\'appli stockées"</string>
<string name="policylab_disableCamera" msgid="5749486347810162018">"Désactiver les appareils photo"</string>
<string name="policydesc_disableCamera" msgid="3204405908799676104">"Empêcher l\'utilisation de tous les appareils photos"</string>
<string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"Désact. fonctions verr. écran"</string>
@@ -982,7 +982,7 @@
<string name="sipAddressTypeHome" msgid="5918441930656878367">"Domicile"</string>
<string name="sipAddressTypeWork" msgid="7873967986701216770">"Travail"</string>
<string name="sipAddressTypeOther" msgid="6317012577345187275">"Autre"</string>
- <string name="quick_contacts_not_available" msgid="1262709196045052223">"Aucune application permettant d\'afficher ce contact n\'a été trouvée."</string>
+ <string name="quick_contacts_not_available" msgid="1262709196045052223">"Aucune appli permettant d\'afficher ce contact n\'a été trouvée."</string>
<string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"Saisissez le NIP."</string>
<string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"Saisissez la clé PUK et le nouveau NIP."</string>
<string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"Clé PUK"</string>
@@ -1100,9 +1100,9 @@
<string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nVoulez-vous vraiment quitter cette page?"</string>
<string name="autofill_window_title" msgid="4379134104008111961">"Remplissage automatique avec <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
<string name="permlab_setAlarm" msgid="1158001610254173567">"définir une alarme"</string>
- <string name="permdesc_setAlarm" msgid="2185033720060109640">"Permet à l\'application de régler la sonnerie d\'une fonction de réveil installée sur votre appareil. Cette fonctionnalité n\'est pas compatible avec toutes les applications de réveils."</string>
+ <string name="permdesc_setAlarm" msgid="2185033720060109640">"Permet à l\'appli de régler la sonnerie d\'une fonction de réveil installée sur votre appareil. Cette fonctionnalité n\'est pas compatible avec toutes les applis de réveils."</string>
<string name="permlab_addVoicemail" msgid="4770245808840814471">"ajouter des messages vocaux"</string>
- <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Permet à l\'application d\'ajouter des messages à votre messagerie vocale."</string>
+ <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Permet à l\'appli d\'ajouter des messages à votre messagerie vocale."</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé du contenu de votre presse-papiers"</string>
<string name="more_item_label" msgid="7419249600215749115">"Plus"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
@@ -1199,7 +1199,7 @@
<string name="low_internal_storage_view_text" msgid="8172166728369697835">"Il est possible que certaines fonctionnalités du système ne soient pas opérationnelles."</string>
<string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Espace de stockage insuffisant pour le système. Assurez-vous de disposer de 250 Mo d\'espace libre, puis redémarrez."</string>
<string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> en cours d\'exécution"</string>
- <string name="app_running_notification_text" msgid="5120815883400228566">"Touchez pour en savoir plus ou pour arrêter l\'application."</string>
+ <string name="app_running_notification_text" msgid="5120815883400228566">"Touchez pour en savoir plus ou pour arrêter l\'appli."</string>
<string name="ok" msgid="2646370155170753815">"OK"</string>
<string name="cancel" msgid="6908697720451760115">"Annuler"</string>
<string name="yes" msgid="9069828999585032361">"OK"</string>
@@ -1234,28 +1234,28 @@
<string name="whichSendToApplication" msgid="77101541959464018">"Envoyer avec"</string>
<string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Envoyer avec %1$s"</string>
<string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Envoyer"</string>
- <string name="whichHomeApplication" msgid="8276350727038396616">"Sélectionner une application pour l\'écran d\'accueil"</string>
+ <string name="whichHomeApplication" msgid="8276350727038396616">"Sélectionner une appli pour l\'écran d\'accueil"</string>
<string name="whichHomeApplicationNamed" msgid="5855990024847433794">"Utiliser %1$s comme écran d\'accueil"</string>
<string name="whichHomeApplicationLabel" msgid="8907334282202933959">"Enregistrer l\'image"</string>
<string name="whichImageCaptureApplication" msgid="2737413019463215284">"Enregistrer l\'image avec"</string>
<string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"Enregistrer l\'image avec %1$s"</string>
<string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Enregistrer l\'image"</string>
- <string name="alwaysUse" msgid="3153558199076112903">"Utiliser cette application par défaut pour cette action"</string>
+ <string name="alwaysUse" msgid="3153558199076112903">"Utiliser cette appli par défaut pour cette action"</string>
<string name="use_a_different_app" msgid="4987790276170972776">"Utiliser une appli différente"</string>
- <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Pour supprimer les valeurs par défaut, accédez à Paramètres système &gt; Applications &gt; Téléchargements."</string>
+ <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Pour supprimer les valeurs par défaut, accédez à Paramètres système &gt; Applis &gt; Téléchargements."</string>
<string name="chooseActivity" msgid="8563390197659779956">"Sélectionnez une action"</string>
- <string name="chooseUsbActivity" msgid="2096269989990986612">"Sélectionnez une application pour le périphérique de stockage USB"</string>
- <string name="noApplications" msgid="1186909265235544019">"Aucune application ne peut effectuer cette action."</string>
+ <string name="chooseUsbActivity" msgid="2096269989990986612">"Sélectionnez une appli pour le périphérique de stockage USB"</string>
+ <string name="noApplications" msgid="1186909265235544019">"Aucune appli ne peut effectuer cette action."</string>
<string name="aerr_application" msgid="4090916809370389109">"<xliff:g id="APPLICATION">%1$s</xliff:g> a cessé de fonctionner"</string>
<string name="aerr_process" msgid="4268018696970966407">"<xliff:g id="PROCESS">%1$s</xliff:g> a cessé de fonctionner"</string>
<string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> plante continuellement"</string>
<string name="aerr_process_repeated" msgid="1153152413537954974">"<xliff:g id="PROCESS">%1$s</xliff:g> plante continuellement"</string>
- <string name="aerr_restart" msgid="2789618625210505419">"Rouvrir l\'application"</string>
+ <string name="aerr_restart" msgid="2789618625210505419">"Rouvrir l\'appli"</string>
<string name="aerr_report" msgid="3095644466849299308">"Envoyer des commentaires"</string>
<string name="aerr_close" msgid="3398336821267021852">"Fermer"</string>
<string name="aerr_mute" msgid="2304972923480211376">"Désactiver jusqu\'au redémarrage de l\'appareil"</string>
<string name="aerr_wait" msgid="3198677780474548217">"Attendre"</string>
- <string name="aerr_close_app" msgid="8318883106083050970">"Fermer l\'application"</string>
+ <string name="aerr_close_app" msgid="8318883106083050970">"Fermer l\'appli"</string>
<string name="anr_title" msgid="7290329487067300120"></string>
<string name="anr_activity_application" msgid="8121716632960340680">"<xliff:g id="APPLICATION">%2$s</xliff:g> ne répond pas"</string>
<string name="anr_activity_process" msgid="3477362583767128667">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ne répond pas"</string>
@@ -1265,18 +1265,18 @@
<string name="report" msgid="2149194372340349521">"Signaler"</string>
<string name="wait" msgid="7765985809494033348">"Attendre"</string>
<string name="webpage_unresponsive" msgid="7850879412195273433">"La page ne répond pas.\n \nVoulez-vous la fermer?"</string>
- <string name="launch_warning_title" msgid="6725456009564953595">"Application redirigée"</string>
+ <string name="launch_warning_title" msgid="6725456009564953595">"Appli redirigée"</string>
<string name="launch_warning_replace" msgid="3073392976283203402">"<xliff:g id="APP_NAME">%1$s</xliff:g> est maintenant lancée."</string>
- <string name="launch_warning_original" msgid="3332206576800169626">"L\'application <xliff:g id="APP_NAME">%1$s</xliff:g> a été lancée initialement."</string>
+ <string name="launch_warning_original" msgid="3332206576800169626">"L\'appli <xliff:g id="APP_NAME">%1$s</xliff:g> a été lancée initialement."</string>
<string name="screen_compat_mode_scale" msgid="8627359598437527726">"Redimensionner"</string>
<string name="screen_compat_mode_show" msgid="5080361367584709857">"Toujours afficher"</string>
- <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Réactivez ce mode en accédant à Paramètres système &gt; Applications &gt; Téléchargements"</string>
+ <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Réactivez ce mode en accédant à Paramètres système &gt; Applis &gt; Téléchargements"</string>
<string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas compatible avec le paramètre de taille d\'affichage actuel et peut se comporter de manière inattendue."</string>
<string name="unsupported_display_size_show" msgid="980129850974919375">"Toujours afficher"</string>
- <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> a été conçue pour une version incompatible du système d\'exploitation Android et peut se comporter de manière inattendue. Il se peut qu\'une version mise à jour de l\'application soit proposée."</string>
+ <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> a été conçue pour une version incompatible du système d\'exploitation Android et peut se comporter de manière inattendue. Il se peut qu\'une version mise à jour de l\'appli soit proposée."</string>
<string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Toujours afficher"</string>
<string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Vérifier la présence de mises à jour"</string>
- <string name="smv_application" msgid="3775183542777792638">"L\'application <xliff:g id="APPLICATION">%1$s</xliff:g> (du processus <xliff:g id="PROCESS">%2$s</xliff:g>) a enfreint ses propres règles du mode strict."</string>
+ <string name="smv_application" msgid="3775183542777792638">"L\'appli <xliff:g id="APPLICATION">%1$s</xliff:g> (du processus <xliff:g id="PROCESS">%2$s</xliff:g>) a enfreint ses propres règles du mode strict."</string>
<string name="smv_process" msgid="1398801497130695446">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> a enfreint ses propres règles du mode strict."</string>
<string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Mise à jour du téléphone en cours…"</string>
<string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Mise à jour de la tablette en cours…"</string>
@@ -1288,7 +1288,7 @@
<string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Finalisation de la m. à j. syst. en cours…"</string>
<string name="app_upgrading_toast" msgid="1016267296049455585">"Mise à niveau de <xliff:g id="APPLICATION">%1$s</xliff:g> en cours…"</string>
<string name="android_preparing_apk" msgid="589736917792300956">"Préparation de <xliff:g id="APPNAME">%1$s</xliff:g> en cours…"</string>
- <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Lancement des applications…"</string>
+ <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Lancement des applis…"</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"Finalisation de la mise à jour."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Vous avez appuyé sur le l\'interrupteur – cette action éteint habituellement l\'écran.\n\nEssayez de toucher légèrement pendant la configuration de votre empreinte digitale."</string>
<string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Pour terminer, éteignez l\'écran"</string>
@@ -1308,9 +1308,9 @@
<string name="dump_heap_ready_notification" msgid="2302452262927390268">"L\'empreinte de mémoire <xliff:g id="PROC">%1$s</xliff:g> est prête"</string>
<string name="dump_heap_notification_detail" msgid="8431586843001054050">"L\'empreinte de mémoire a été recueillie. Touchez ici pour la partager."</string>
<string name="dump_heap_title" msgid="4367128917229233901">"Partager l\'empreinte de mémoire?"</string>
- <string name="dump_heap_text" msgid="1692649033835719336">"Le processus <xliff:g id="PROC">%1$s</xliff:g> a dépassé sa limite de mémoire de <xliff:g id="SIZE">%2$s</xliff:g>. Vous pouvez partager son empreinte de mémoire avec son développeur. Attention : Cette empreinte peut contenir certains de vos renseignements personnels auxquels l\'application a accès."</string>
+ <string name="dump_heap_text" msgid="1692649033835719336">"Le processus <xliff:g id="PROC">%1$s</xliff:g> a dépassé sa limite de mémoire de <xliff:g id="SIZE">%2$s</xliff:g>. Vous pouvez partager son empreinte de mémoire avec son développeur. Attention : Cette empreinte peut contenir certains de vos renseignements personnels auxquels l\'appli a accès."</string>
<string name="dump_heap_system_text" msgid="6805155514925350849">"Le processus <xliff:g id="PROC">%1$s</xliff:g> a dépassé sa limite de mémoire de <xliff:g id="SIZE">%2$s</xliff:g>. Vous pouvez partager son empreinte de mémoire. Attention : Cette empreinte peut contenir des renseignements personnels auxquels le processus a accès, y compris du texte que vous avez entré."</string>
- <string name="dump_heap_ready_text" msgid="5849618132123045516">"Une empreinte de mémoire du processus lié à l\'application <xliff:g id="PROC">%1$s</xliff:g> peut être partagée. Attention : Cette empreinte peut contenir des renseignements personnels auxquels le processus a accès, y compris du texte que vous avez entré."</string>
+ <string name="dump_heap_ready_text" msgid="5849618132123045516">"Une empreinte de mémoire du processus lié à l\'appli <xliff:g id="PROC">%1$s</xliff:g> peut être partagée. Attention : Cette empreinte peut contenir des renseignements personnels auxquels le processus a accès, y compris du texte que vous avez entré."</string>
<string name="sendText" msgid="493003724401350724">"Sélectionner une action pour le texte"</string>
<string name="volume_ringtone" msgid="134784084629229029">"Volume de la sonnerie"</string>
<string name="volume_music" msgid="7727274216734955095">"Volume du contenu multimédia"</string>
@@ -1359,7 +1359,7 @@
<string name="decline" msgid="6490507610282145874">"Refuser"</string>
<string name="select_character" msgid="3352797107930786979">"Insérer un caractère"</string>
<string name="sms_control_title" msgid="4748684259903148341">"Envoi de messages SMS"</string>
- <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; envoie un grand nombre de SMS. Autorisez-vous cette application à poursuivre l\'envoi des messages?"</string>
+ <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; envoie un grand nombre de SMS. Autorisez-vous cette appli à poursuivre l\'envoi des messages?"</string>
<string name="sms_control_yes" msgid="4858845109269524622">"Autoriser"</string>
<string name="sms_control_no" msgid="4845717880040355570">"Refuser"</string>
<string name="sms_short_code_confirm_message" msgid="1385416688897538724">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; souhaite envoyer un message à &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
@@ -1368,7 +1368,7 @@
<string name="sms_short_code_confirm_allow" msgid="920477594325526691">"Envoyer"</string>
<string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Annuler"</string>
<string name="sms_short_code_remember_choice" msgid="1374526438647744862">"Mémoriser mon choix"</string>
- <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Pour modifier : Paramètres &gt; Applications"</string>
+ <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Pour modifier : Paramètres &gt; Applis"</string>
<string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Toujours autoriser"</string>
<string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Ne jamais autoriser"</string>
<string name="sim_removed_title" msgid="1349026474932481037">"Carte SIM retirée"</string>
@@ -1378,9 +1378,9 @@
<string name="sim_added_message" msgid="6602906609509958680">"Redémarrez votre appareil pour accéder au réseau mobile."</string>
<string name="sim_restart_button" msgid="8481803851341190038">"Redémarrer"</string>
<string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Activer le service cellulaire"</string>
- <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Téléchargez l\'application du fournisseur de services pour activer votre nouvelle carte SIM"</string>
- <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Téléchargez l\'application de <xliff:g id="APP_NAME">%1$s</xliff:g> pour activer votre nouvelle carte SIM"</string>
- <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Télécharger l\'application"</string>
+ <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Téléchargez l\'appli du fournisseur de services pour activer votre nouvelle carte SIM"</string>
+ <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Téléchargez l\'appli de <xliff:g id="APP_NAME">%1$s</xliff:g> pour activer votre nouvelle carte SIM"</string>
+ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Télécharger l\'appli"</string>
<string name="carrier_app_notification_title" msgid="5815477368072060250">"Nouvelle carte SIM insérée"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Touchez ici pour effectuer la configuration"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Définir l\'heure"</string>
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Sélectionnez cette option pour désactiver le débogage sans fil."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mode Logiciel de test activé"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Effectuez une réinitialisation pour désactiver le mode Logiciel de test."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Configuration incorrecte de la version du mode Utilisateur de système sans interface"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"L\'état du mode Utilisateur de système sans interface de cet appareil est différent de la configuration de votre version. Veuillez rétablir les paramètres par défaut de l\'appareil."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"La console série est activée"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"La performance est réduite. Pour désactiver cette fonction, vérifier le programme d\'amorçage."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Extension MTE expérimentale activée"</string>
@@ -1427,7 +1425,7 @@
<string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Création d\'un rapport de bogue en cours..."</string>
<string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Partager le rapport de bogue?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"Partage du rapport de bogue en cours..."</string>
- <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Votre administrateur a demandé un rapport de bogue pour l\'aider à dépanner cet appareil. Les applications et les données peuvent être partagées."</string>
+ <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Votre administrateur a demandé un rapport de bogue pour l\'aider à dépanner cet appareil. Les applis et les données peuvent être partagées."</string>
<string name="share_remote_bugreport_action" msgid="7630880678785123682">"PARTAGER"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"REFUSER"</string>
<string name="select_input_method" msgid="3971267998568587025">"Sélectionnez le mode de saisie"</string>
@@ -1439,7 +1437,7 @@
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Afficher par-dessus les autres applis"</string>
- <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> affiche du contenu par-dessus d\'autres applications"</string>
+ <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> affiche du contenu par-dessus d\'autres applis"</string>
<string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> aff. contenu par-dessus applis"</string>
<string name="alert_windows_notification_message" msgid="6538171456970725333">"Si vous ne voulez pas que <xliff:g id="NAME">%s</xliff:g> utilise cette fonctionnalités, touchez l\'écran pour ouvrir les paramètres, puis désactivez-la."</string>
<string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Désactiver"</string>
@@ -1494,17 +1492,17 @@
<string name="ext_media_status_missing" msgid="6520746443048867314">"Non insérée"</string>
<string name="activity_list_empty" msgid="4219430010716034252">"Aucune activité correspondante trouvée."</string>
<string name="permlab_route_media_output" msgid="8048124531439513118">"diriger la sortie multimédia"</string>
- <string name="permdesc_route_media_output" msgid="1759683269387729675">"Permet à une application de diriger la sortie multimédia vers d\'autres appareils externes."</string>
+ <string name="permdesc_route_media_output" msgid="1759683269387729675">"Permet à une appli de diriger la sortie multimédia vers d\'autres appareils externes."</string>
<string name="permlab_readInstallSessions" msgid="7279049337895583621">"accéder aux sessions d\'installation"</string>
- <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Permet à une application d\'accéder aux sessions d\'installation. Cela lui permet de consulter les détails relatifs à l\'installation des paquets actifs."</string>
+ <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Permet à une appli d\'accéder aux sessions d\'installation. Cela lui permet de consulter les détails relatifs à l\'installation des paquets actifs."</string>
<string name="permlab_requestInstallPackages" msgid="7600020863445351154">"demander l\'installation de paquets"</string>
- <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Permet à une application de demander l\'installation de paquets."</string>
+ <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Permet à une appli de demander l\'installation de paquets."</string>
<string name="permlab_requestDeletePackages" msgid="2541172829260106795">"demander la suppression de paquets"</string>
- <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permet à une application de demander la suppression de paquets."</string>
+ <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permet à une appli de demander la suppression de paquets."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"demander d\'ignorer les optimisations de la pile"</string>
- <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permet à une application de demander la permission d\'ignorer les optimisations de la pile."</string>
+ <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permet à une appli de demander la permission d\'ignorer les optimisations de la pile."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"envoyer une requête à propos de tous les paquets"</string>
- <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permet à une application de voir tous les paquets installés."</string>
+ <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permet à une appli de voir tous les paquets installés."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Appuyer deux fois pour régler le zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Impossible d\'ajouter le widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Aller"</string>
@@ -1516,7 +1514,7 @@
<string name="ime_action_default" msgid="8265027027659800121">"Exécuter"</string>
<string name="dial_number_using" msgid="6060769078933953531">"Composer le numéro\nen utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="create_contact_using" msgid="6200708808003692594">"Ajouter un contact\nen utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string>
- <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Les applications suivantes demandent l\'autorisation d\'accéder à votre compte à partir de maintenant."</string>
+ <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Les applis suivantes demandent l\'autorisation d\'accéder à votre compte à partir de maintenant."</string>
<string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Voulez-vous autoriser cette demande?"</string>
<string name="grant_permissions_header_text" msgid="3420736827804657201">"Demande d\'accès"</string>
<string name="allow" msgid="6195617008611933762">"Autoriser"</string>
@@ -1524,8 +1522,8 @@
<string name="permission_request_notification_title" msgid="1810025922441048273">"Autorisation demandée"</string>
<string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Autorisation demandée\npour le compte \"<xliff:g id="ACCOUNT">%s</xliff:g>\""</string>
<string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"Autorisation demandée par <xliff:g id="APP">%1$s</xliff:g>\npour le compte <xliff:g id="ACCOUNT">%2$s</xliff:g>."</string>
- <string name="forward_intent_to_owner" msgid="4620359037192871015">"Vous utilisez cette application en dehors de votre profil professionnel"</string>
- <string name="forward_intent_to_work" msgid="3620262405636021151">"Vous utilisez cette application dans votre profil professionnel"</string>
+ <string name="forward_intent_to_owner" msgid="4620359037192871015">"Vous utilisez cette appli en dehors de votre profil professionnel"</string>
+ <string name="forward_intent_to_work" msgid="3620262405636021151">"Vous utilisez cette appli dans votre profil professionnel"</string>
<string name="input_method_binding_label" msgid="1166731601721983656">"Mode de saisie"</string>
<string name="sync_binding_label" msgid="469249309424662147">"Synchroniser"</string>
<string name="accessibility_binding_label" msgid="1974602776545801715">"Accessibilité"</string>
@@ -1548,8 +1546,8 @@
<string name="no_file_chosen" msgid="4146295695162318057">"Aucun fichier sélectionné"</string>
<string name="reset" msgid="3865826612628171429">"Réinitialiser"</string>
<string name="submit" msgid="862795280643405865">"Envoyer"</string>
- <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"L\'application de conduite est en cours d\'exécution"</string>
- <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Touchez pour quitter l\'application de conduite."</string>
+ <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"L\'appli de conduite est en cours d\'exécution"</string>
+ <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Touchez pour quitter l\'appli de conduite."</string>
<string name="back_button_label" msgid="4078224038025043387">"Précédent"</string>
<string name="next_button_label" msgid="6040209156399907780">"Suivante"</string>
<string name="skip_button_label" msgid="3566599811326688389">"Ignorer"</string>
@@ -1601,8 +1599,8 @@
<string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"Changement de mode"</string>
<string name="keyboardview_keycode_shift" msgid="3026509237043975573">"Maj"</string>
<string name="keyboardview_keycode_enter" msgid="168054869339091055">"Entrée"</string>
- <string name="activitychooserview_choose_application" msgid="3500574466367891463">"Sélectionnez une application"</string>
- <string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Impossible de lancer l\'application <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="activitychooserview_choose_application" msgid="3500574466367891463">"Sélectionnez une appli"</string>
+ <string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Impossible de lancer l\'appli <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="shareactionprovider_share_with" msgid="2753089758467748982">"Partagez avec"</string>
<string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Partager avec <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="982510275422590757">"Poignée coulissante. Appuyez de manière prolongée."</string>
@@ -1630,7 +1628,7 @@
<string name="data_usage_restricted_title" msgid="126711424380051268">"Données en arrière-plan limitées"</string>
<string name="data_usage_restricted_body" msgid="5338694433686077733">"Touchez pour suppr. restriction."</string>
<string name="data_usage_rapid_title" msgid="2950192123248740375">"Utilis. élevée des données cell."</string>
- <string name="data_usage_rapid_body" msgid="3886676853263693432">"Vos applications ont utilisé plus de données que d\'habitude"</string>
+ <string name="data_usage_rapid_body" msgid="3886676853263693432">"Vos applis ont utilisé plus de données que d\'habitude"</string>
<string name="data_usage_rapid_app_body" msgid="5425779218506513861">"<xliff:g id="APP">%s</xliff:g> a utilisé plus de données que d\'habitude"</string>
<string name="ssl_certificate" msgid="5690020361307261997">"Certificat de sécurité"</string>
<string name="ssl_certificate_is_valid" msgid="7293675884598527081">"Ce certificat est valide."</string>
@@ -1735,15 +1733,15 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVÉ"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DÉSACTIVÉ"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permettre à <xliff:g id="SERVICE">%1$s</xliff:g> de contrôler complètement votre appareil?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"Le contrôle total convient aux applications qui répondent à vos besoins d\'accessibilité. Il ne convient pas à la plupart des applications."</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"Le contrôle total convient aux applis qui répondent à vos besoins d\'accessibilité. Il ne convient pas à la plupart des applis."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Afficher et contrôler l\'écran"</string>
- <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Cette fonctionnalité peut lire tout le contenu à l\'écran et afficher du contenu par-dessus d\'autres applications."</string>
+ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Cette fonctionnalité peut lire tout le contenu à l\'écran et afficher du contenu par-dessus d\'autres applis."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Afficher et effectuer des actions"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Cette fonctionnalité peut faire le suivi de vos interactions avec une application ou un capteur matériel et interagir avec des applications en votre nom."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Cette fonctionnalité peut faire le suivi de vos interactions avec une appli ou un capteur matériel et interagir avec des applis en votre nom."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Autoriser"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuser"</string>
<string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Désinstaller"</string>
- <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Une application masque la demande d\'autorisation de sorte que votre réponse ne peut pas être vérifiée."</string>
+ <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Une appli masque la demande d\'autorisation de sorte que votre réponse ne peut pas être vérifiée."</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Toucher une fonctionnalité pour commencer à l\'utiliser :"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Choisir les fonctionnalités à utiliser à l\'aide du bouton d\'accessibilité"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Choisir les fonctionnalités à utiliser avec le raccourci des touches de volume"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume maintenues enfoncées. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume maintenues enfoncées. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Relâchez les touches de volume. Pour activer <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, maintenez les deux touches de volume enfoncées pendant 3 secondes."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Choisir une fonctionnalité"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Choisir une fonctionnalité"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Choisir une fonctionnalité"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La fonctionnalité s\'ouvrira la prochaine fois que vous toucherez le bouton d\'accessibilité"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez l\'écran du bas vers le haut avec deux doigts et relâchez rapidement."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez l\'écran du bas vers le haut avec trois doigts et relâchez rapidement."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string>
<string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g> en cours…"</string>
@@ -1780,7 +1772,7 @@
<string name="guest_name" msgid="8502103277839834324">"Invité"</string>
<string name="error_message_title" msgid="4082495589294631966">"Erreur"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Cette modification n\'est pas autorisée par votre administrateur"</string>
- <string name="app_not_found" msgid="3429506115332341800">"Aucune application trouvée pour gérer cette action."</string>
+ <string name="app_not_found" msgid="3429506115332341800">"Aucune appli trouvée pour gérer cette action."</string>
<string name="revoke" msgid="5526857743819590458">"Révoquer"</string>
<string name="mediasize_iso_a0" msgid="7039061159929977973">"ISO A0"</string>
<string name="mediasize_iso_a1" msgid="4063589931031977223">"ISO A1"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Le NIP est trop court. Il doit comporter au moins 4 chiffres."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Réessayez plus tard"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Affichage plein écran"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Pour quitter ce mode, balayer l\'écran vers le bas à partir du haut"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Faire pivoter pour obtenir un meilleur affichage"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Ouvrir <xliff:g id="NAME">%s</xliff:g> en plein écran pour un meilleur affichage"</string>
@@ -1987,17 +1978,13 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Appel en cours"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrer un appel entrant"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Médias sociaux"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Actualités"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommandations"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Vous définissez l\'importance de ces notifications."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ces notifications sont importantes en raison des participants."</string>
- <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notification d\'application personnalisée"</string>
+ <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notification d\'appli personnalisée"</string>
<string name="user_creation_account_exists" msgid="2239146360099708035">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un utilisateur <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Un utilisateur est déjà associé à ce compte)"</string>
<string name="user_creation_adding" msgid="7305185499667958364">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil d\'utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="supervised_user_creation_label" msgid="6884904353827427515">"Ajouter un utilisateur supervisé"</string>
@@ -2011,17 +1998,17 @@
<string name="language_picker_section_all" msgid="1985809075777564284">"Toutes les langues"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"Toutes les régions"</string>
<string name="locale_search_menu" msgid="6258090710176422934">"Rechercher"</string>
- <string name="app_suspended_title" msgid="888873445010322650">"L\'application n\'est pas accessible"</string>
- <string name="app_suspended_default_message" msgid="6451215678552004172">"L\'application <xliff:g id="APP_NAME_0">%1$s</xliff:g> n\'est pas accessible pour le moment. Ceci est géré par <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
+ <string name="app_suspended_title" msgid="888873445010322650">"L\'appli n\'est pas accessible"</string>
+ <string name="app_suspended_default_message" msgid="6451215678552004172">"L\'appli <xliff:g id="APP_NAME_0">%1$s</xliff:g> n\'est pas accessible pour le moment. Ceci est géré par <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"En savoir plus"</string>
- <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Réactiver l\'application"</string>
+ <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Réactiver l\'appli"</string>
<string name="work_mode_off_title" msgid="6367463960165135829">"Réactiver les applis pros?"</string>
<string name="work_mode_turn_on" msgid="5316648862401307800">"Réactiver"</string>
<string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Urgence"</string>
<string name="set_up_screen_lock_title" msgid="8346083801616474030">"Config. Verrouillage d\'écran"</string>
<string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Config. Verrouillage d\'écran"</string>
<string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Configurez verrouillage de l\'écran pour utiliser Espace privé"</string>
- <string name="app_blocked_title" msgid="7353262160455028160">"L\'application n\'est pas accessible"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"L\'appli n\'est pas accessible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas accessible pour le moment."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non accessible"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"La demande d\'autorisation a été supprimée."</string>
@@ -2035,20 +2022,20 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre appareil Android TV à la place."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre tablette à la place."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre téléphone à la place."</string>
- <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Cette application demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre appareil Android TV d\'abord."</string>
- <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Cette application demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre tablette d\'abord."</string>
- <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Cette application demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre téléphone d\'abord."</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Cette application demande une sécurité supplémentaire. Essayez sur votre appareil Android TV à la place."</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Cette application demande une sécurité supplémentaire. Essayez sur votre tablette à la place."</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Cette application demande une sécurité supplémentaire. Essayez sur votre téléphone à la place."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Cette appli demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre appareil Android TV d\'abord."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Cette appli demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre tablette d\'abord."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Cette appli demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre téléphone d\'abord."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Cette appli demande une sécurité supplémentaire. Essayez sur votre appareil Android TV à la place."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Cette appli demande une sécurité supplémentaire. Essayez sur votre tablette à la place."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Cette appli demande une sécurité supplémentaire. Essayez sur votre téléphone à la place."</string>
<string name="app_streaming_blocked_message_for_settings_dialog" product="tv" msgid="820334666354451145">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez sur votre appareil Android TV à la place."</string>
<string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez sur votre tablette à la place."</string>
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez sur votre téléphone à la place."</string>
- <string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Cette application a été conçue pour une ancienne version d\'Android. Elle pourrait ne pas fonctionner correctement, et ne comprend pas les dernières protections des données confidentielles et de sécurité. Vérifiez s\'il existe une mise à jour ou contactez le développeur de l\'application."</string>
+ <string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Cette appli a été conçue pour une ancienne version d\'Android. Elle pourrait ne pas fonctionner correctement, et ne comprend pas les dernières protections des données confidentielles et de sécurité. Vérifiez s\'il existe une mise à jour ou contactez le développeur de l\'appli."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Vérifier la présence de mises à jour"</string>
- <string name="deprecated_abi_message" msgid="6820548011196218091">"Cette application n\'est pas compatible avec la dernière version d\'Android. Vérifiez s\'il existe une mise à jour ou communiquez avec le développeur de l\'application."</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Cette appli n\'est pas compatible avec la dernière version d\'Android. Vérifiez s\'il existe une mise à jour ou communiquez avec le développeur de l\'appli."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Vous avez de nouveaux messages"</string>
- <string name="new_sms_notification_content" msgid="3197949934153460639">"Ouvrez l\'application de messagerie texte pour l\'afficher"</string>
+ <string name="new_sms_notification_content" msgid="3197949934153460639">"Ouvrez l\'appli de messagerie texte pour l\'afficher"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Des fonctionnalités sont limitées"</string>
<string name="profile_encrypted_detail" msgid="5279730442756849055">"Profil professionnel verrouillé"</string>
<string name="profile_encrypted_message" msgid="1128512616293157802">"Touch. pr déver. profil profess."</string>
@@ -2058,7 +2045,7 @@
<string name="pin_specific_target" msgid="7824671240625957415">"Épingler <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="unpin_target" msgid="3963318576590204447">"Annuler l\'épinglage"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"Annuler l\'épinglage de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <string name="app_info" msgid="6113278084877079851">"Détails de l\'application"</string>
+ <string name="app_info" msgid="6113278084877079851">"Détails de l\'appli"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Démarrage de la démonstration en cours…"</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"Réinitialisation de l\'appareil en cours…"</string>
@@ -2126,14 +2113,14 @@
<string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"La carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g> n\'est pas autorisée"</string>
<string name="popup_window_default_title" msgid="6907717596694826919">"Fenêtre contextuelle"</string>
<string name="slice_more_content" msgid="3377367737876888459">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"La version de l\'application a été rétrogradée ou n\'est pas compatible avec ce raccourci"</string>
- <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Impossible de restaurer le raccourci, car l\'application ne prend pas en charge la sauvegarde et la restauration"</string>
- <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Impossible de restaurer le raccourci en raison d\'une erreur de correspondance des signature d\'applications"</string>
+ <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"La version de l\'appli a été rétrogradée ou n\'est pas compatible avec ce raccourci"</string>
+ <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Impossible de restaurer le raccourci, car l\'appli ne prend pas en charge la sauvegarde et la restauration"</string>
+ <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Impossible de restaurer le raccourci en raison d\'une erreur de correspondance des signature d\'applis"</string>
<string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Impossible de restaurer le raccourci"</string>
<string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Le raccourci est désactivé"</string>
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DÉSINSTALLER"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OUVRIR QUAND MÊME"</string>
- <string name="harmful_app_warning_title" msgid="8794823880881113856">"Une application nuisible a été détectée"</string>
+ <string name="harmful_app_warning_title" msgid="8794823880881113856">"Une appli nuisible a été détectée"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> souhaite afficher <xliff:g id="APP_2">%2$s</xliff:g> tranches"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Modifier"</string>
<string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Les appels et les notifications vibreront"</string>
@@ -2145,14 +2132,14 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Les paramètres du mode Ne pas déranger ont changé"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Touchez l\'écran pour vérifier ce qui est bloqué."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Examiner les paramètres de notification"</string>
- <string name="review_notification_settings_text" msgid="5916244866751849279">"À partir d\'Android 13, les applications que vous installez ont besoin de votre autorisation pour envoyer des notifications. Touchez pour modifier cette autorisation pour les applications existantes."</string>
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"À partir d\'Android 13, les applis que vous installez ont besoin de votre autorisation pour envoyer des notifications. Touchez pour modifier cette autorisation pour les applis existantes."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Me rappeler plus tard"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Fermer"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Système"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Paramètres"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Appareil photo"</string>
<string name="notification_appops_microphone_active" msgid="581333393214739332">"Microphone"</string>
- <string name="notification_appops_overlay_active" msgid="5571732753262836481">"superpose du contenu par-dessus d\'autres applications à l\'écran"</string>
+ <string name="notification_appops_overlay_active" msgid="5571732753262836481">"superpose du contenu par-dessus d\'autres applis à l\'écran"</string>
<string name="notification_feedback_indicator" msgid="663476517711323016">"Envoyer des commentaires"</string>
<string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"La notification a été automatiquement élevée à la catégorie Par défaut. Touchez pour envoyer des commentaires."</string>
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Cette notification a été rétrogradée à Silencieuse. Touchez pour envoyer des commentaires."</string>
@@ -2175,7 +2162,7 @@
<string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"La tablette est suffisamment chargée. Ces fonctionnalités ne sont plus restreintes."</string>
<string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"L\'appareil est suffisamment chargé. Ces fonctionnalités ne sont plus restreintes."</string>
<string name="mime_type_folder" msgid="2203536499348787650">"Dossier"</string>
- <string name="mime_type_apk" msgid="3168784749499623902">"Application Android"</string>
+ <string name="mime_type_apk" msgid="3168784749499623902">"Appli Android"</string>
<string name="mime_type_generic" msgid="4606589110116560228">"Fichier"</string>
<string name="mime_type_generic_ext" msgid="9220220924380909486">"Fichier <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
<string name="mime_type_audio" msgid="4933450584432509875">"Son"</string>
@@ -2196,11 +2183,11 @@
<string name="car_loading_profile" msgid="8219978381196748070">"Chargement en cours…"</string>
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # fichier}one{{file_name} + # fichier}many{{file_name} + # fichiers}other{{file_name} + # fichiers}}"</string>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personnes avec lesquelles effectuer un partage"</string>
- <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Liste des applications"</string>
- <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Cette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait capturer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
+ <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Liste des applis"</string>
+ <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Cette appli n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait capturer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Accueil"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Retour"</string>
- <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Applications récentes"</string>
+ <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Applis récentes"</string>
<string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifications"</string>
<string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Paramètres rapides"</string>
<string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Boîte de dialogue sur l\'alimentation"</string>
@@ -2211,10 +2198,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Sélecteur de raccourci d\'accessibilité à l\'écran"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Raccourci d\'accessibilité"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignorer le volet de notification"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Lecture/pause du contenu multimédia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Pavé directionnel – haut"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Pavé directionnel – bas"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Pavé directionnel – gauche"</string>
@@ -2231,22 +2216,22 @@
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Affichage personnel"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Affichage professionnel"</string>
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Bloqué par votre administrateur informatique"</string>
- <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Impossible de partager ce contenu avec des applications professionnelles"</string>
- <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Impossible d\'ouvrir ce contenu avec des applications professionnelles"</string>
- <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Impossible de partager ce contenu avec des applications personnelles"</string>
- <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Impossible d\'ouvrir ce contenu avec des applications personnelles"</string>
- <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Les applications professionnelles sont interrompues"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Impossible de partager ce contenu avec des applis professionnelles"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Impossible d\'ouvrir ce contenu avec des applis professionnelles"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Impossible de partager ce contenu avec des applis personnelles"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Impossible d\'ouvrir ce contenu avec des applis personnelles"</string>
+ <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Les applis professionnelles sont interrompues"</string>
<string name="resolver_switch_on_work" msgid="4527096360772311894">"Réactiver"</string>
- <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Aucune application professionnelle"</string>
- <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Aucune application personnelle"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Aucune appli professionnelle"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Aucune appli personnelle"</string>
<string name="miniresolver_open_work" msgid="6286176185835401931">"Ouvrir le profil professionnel de <xliff:g id="APP">%s</xliff:g>?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"Ouvrir <xliff:g id="APP">%s</xliff:g> dans le profil personnel?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Ouvrir <xliff:g id="APP">%s</xliff:g> dans le profil professionnel?"</string>
- <string name="miniresolver_call_in_work" msgid="528779988307529039">"Appeler à partir de l\'application professionnelle?"</string>
- <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Passer à l\'application professionnelle?"</string>
- <string name="miniresolver_call_information" msgid="6739417525304184083">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applications professionnelles"</string>
- <string name="miniresolver_sms_information" msgid="4311292661329483088">"Votre organisation vous autorise à envoyer des messages uniquement à partir d\'applications professionnelles"</string>
- <string name="miniresolver_private_space_phone_information" msgid="4469511223312488570">"Vous ne pouvez passer des appels téléphoniques qu\'à partir de votre application Téléphone personnelle. Les appels passés à l\'aide de cette dernière seront ajoutés à votre historique personnel des appels."</string>
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Appeler à partir de l\'appli professionnelle?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Passer à l\'appli professionnelle?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applis professionnelles"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"Votre organisation vous autorise à envoyer des messages uniquement à partir d\'applis professionnelles"</string>
+ <string name="miniresolver_private_space_phone_information" msgid="4469511223312488570">"Vous ne pouvez passer des appels téléphoniques qu\'à partir de votre appli Téléphone personnelle. Les appels passés à l\'aide de cette dernière seront ajoutés à votre historique personnel des appels."</string>
<string name="miniresolver_private_space_messages_information" msgid="111285656327622118">"Vous ne pouvez envoyer des messages texte qu\'à partir de votre appli Messages personnelle."</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utiliser le navigateur du profil personnel"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utiliser le navigateur du profil professionnel"</string>
@@ -2370,35 +2355,35 @@
<string name="dismiss_action" msgid="1728820550388704784">"Fermer"</string>
<string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Débloquer le microphone de l\'appareil"</string>
<string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Débloquer l\'appareil photo de l\'appareil"</string>
- <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Pour &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ainsi que toutes les applications et tous les services"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Pour &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ainsi que toutes les applis et tous les services"</string>
<string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Débloquer"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidentialité des capteurs"</string>
- <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icône de l\'application"</string>
- <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image de marque de l\'application"</string>
+ <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icône de l\'appli"</string>
+ <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image de marque de l\'appli"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"Vérifiez les paramètres d\'accès"</string>
<string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> peut voir et contrôler votre écran. Touchez pour examiner."</string>
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Message <xliff:g id="MESSAGE">%1$s</xliff:g> traduit."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Message traduit : <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> vers <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Activité en arrière-plan"</string>
- <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Une application décharge votre pile"</string>
- <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Une application est toujours active"</string>
+ <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Une appli décharge votre pile"</string>
+ <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Une appli est toujours active"</string>
<string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan. Touchez pour gérer l\'utilisation de la pile."</string>
- <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> peut avoir une incidence sur l\'autonomie de la pile. Touchez pour examiner les applications actives."</string>
- <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applications actives"</string>
+ <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> peut avoir une incidence sur l\'autonomie de la pile. Touchez pour examiner les applis actives."</string>
+ <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applis actives"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossible d\'accéder à l\'appareil photo de la tablette à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_secure_window" msgid="161700398158812314">"Vous ne pouvez pas y accéder lorsque vous utilisez la diffusion en continu. Essayez sur votre téléphone à la place."</string>
<string name="vdm_pip_blocked" msgid="4036107522497281397">"Impossible d\'afficher des incrustations d\'image pendant une diffusion en continu"</string>
<string name="system_locale_title" msgid="711882686834677268">"Paramètre système par défaut"</string>
<string name="default_card_name" msgid="9198284935962911468">"CARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
- <string name="permlab_companionProfileWatch" msgid="2457738382085872542">"Autorisation du profil de la montre de l\'application compagnon pour gérer les montres"</string>
- <string name="permdesc_companionProfileWatch" msgid="5655698581110449397">"Autorise une application compagnon à gérer les montres."</string>
+ <string name="permlab_companionProfileWatch" msgid="2457738382085872542">"Autorisation du profil de la montre de l\'appli compagnon pour gérer les montres"</string>
+ <string name="permdesc_companionProfileWatch" msgid="5655698581110449397">"Autorise une appli compagnon à gérer les montres."</string>
<string name="permlab_observeCompanionDevicePresence" msgid="9008994909653990465">"Surveiller la présence d\'un appareil compagnon"</string>
- <string name="permdesc_observeCompanionDevicePresence" msgid="3011699826788697852">"Autorise une application compagnon à surveiller la présence d\'un appareil compagnon lorsque les appareils sont à proximité ou éloignés."</string>
- <string name="permlab_deliverCompanionMessages" msgid="3931552294842980887">"Transmettre les messages des applications compagnons"</string>
- <string name="permdesc_deliverCompanionMessages" msgid="2170847384281412850">"Autorise une application compagnon à transmettre des messages à d\'autres appareils."</string>
+ <string name="permdesc_observeCompanionDevicePresence" msgid="3011699826788697852">"Autorise une appli compagnon à surveiller la présence d\'un appareil compagnon lorsque les appareils sont à proximité ou éloignés."</string>
+ <string name="permlab_deliverCompanionMessages" msgid="3931552294842980887">"Transmettre les messages des applis compagnons"</string>
+ <string name="permdesc_deliverCompanionMessages" msgid="2170847384281412850">"Autorise une appli compagnon à transmettre des messages à d\'autres appareils."</string>
<string name="permlab_startForegroundServicesFromBackground" msgid="6363004936218638382">"Lancer les services d\'avant-plan à partir de l\'arrière-plan"</string>
- <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permet à une application compagnon en arrière-plan de lancer des services d\'avant-plan."</string>
+ <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permet à une appli compagnon en arrière-plan de lancer des services d\'avant-plan."</string>
<string name="mic_access_on_toast" msgid="2666925317663845156">"Le microphone est accessible"</string>
<string name="mic_access_off_toast" msgid="8111040892954242437">"Le microphone est bloqué"</string>
<string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Impossible de dupliquer l\'écran"</string>
@@ -2434,19 +2419,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espace privé"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Le contenu confidentiel de la notification est masqué"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'application est masqué du Partage d\'écran par mesure de sécurité"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué du Partage d\'écran par mesure de sécurité"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Connecté au satellite automatiquement"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans avoir recours à un appareil mobile ou à un réseau Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurer le Déverrouillage par empreinte digitale à nouveau"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas bien et a été supprimée"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas bien et ont été supprimées"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas bien et a été supprimée. Configurez-le à nouveau pour déverrouiller votre téléphone avec l\'empreinte digitale."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas bien et ont été supprimées. Configurez-les à nouveau pour déverrouiller votre téléphone avec votre empreinte digitale."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"L\'empreinte digitale <xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Les empreintes digitales <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"L\'empreinte digitale <xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue. Reconfigurez le Déverrouillage par empreinte digitale."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Les empreintes digitales <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues. Reconfigurez le Déverrouillage par empreinte digitale."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configurer le Déverrouillage par reconnaissance faciale à nouveau"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Votre modèle facial ne fonctionnait pas bien et a été supprimé. Configurez-le à nouveau pour déverrouiller votre téléphone avec votre visage."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Votre modèle facial ne peut plus être reconnu. Reconfigurez le Déverrouillage par reconnaissance faciale."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurer"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Plus tard"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme pour <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Changer d\'utilisateur"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Désactiver le son"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toucher pour désactiver le son"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 35a866c89c67..0f58c47a3dc5 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Sélectionnez cette option pour désactiver le débogage sans fil."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mode Atelier de test activé"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Rétablissez la configuration d\'usine pour désactiver le mode Atelier de test."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Mauvaise configuration de compilation HSUM"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"L\'état du mode utilisateur du système headless de cet appareil diffère de sa configuration de compilation. Veuillez rétablir la configuration d\'usine de l\'appareil."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Console série activée"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Les performances sont affectées. Pour désactiver la console série, vérifiez le bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE expérimentale activée"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Relâchez les boutons de volume. Pour activer <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, appuyez de nouveau sur les deux boutons de volume pendant trois secondes."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Sélectionnez une fonctionnalité"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Sélectionnez une fonctionnalité"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Sélectionnez une fonctionnalité"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La fonctionnalité s\'ouvrira la prochaine fois que vous appuierez sur le bouton Accessibilité"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez du bas de l\'écran vers le haut avec deux doigts et relâchez rapidement."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez du bas de l\'écran vers le haut avec trois doigts et relâchez rapidement."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string>
<string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Passage à <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Le code PIN est trop court. Il doit comporter au moins 4 chiffres."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Veuillez réessayer ultérieurement."</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Affichage en plein écran"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Pour quitter, balayez l\'écran de haut en bas"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Faites pivoter pour mieux voir"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Ouvrez <xliff:g id="NAME">%s</xliff:g> en plein écran pour mieux voir"</string>
@@ -1987,14 +1978,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Appel en cours"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrage d\'un appel entrant"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Réseaux sociaux"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Actualités"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommandations"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Vous définissez l\'importance de ces notifications."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ces notifications sont importantes en raison des participants."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notification d\'application personnalisée"</string>
@@ -2211,10 +2198,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Outil de sélection des raccourcis d\'accessibilité à l\'écran"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Raccourci d\'accessibilité"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Fermer le volet des notifications"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Contenu multimédia : lecture/pause"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Pavé directionnel - Haut"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Pavé directionnel - Bas"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Pavé directionnel - Gauche"</string>
@@ -2434,19 +2419,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espace privé"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Le contenu sensible de la notification a été masqué"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué lors du partage d\'écran pour des raisons de sécurité"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué lors du partage d\'écran par mesure de sécurité"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Connecté automatiquement au réseau satellite"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans connexion au réseau mobile ou Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Reconfigurer le déverrouillage par empreinte digitale"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas correctement et a été supprimée"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas correctement et ont été supprimées"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas correctement et a été supprimée. Configurez-la à nouveau pour déverrouiller votre téléphone à l\'aide de votre empreinte digitale."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas correctement et ont été supprimées. Configurez-les à nouveau pour déverrouiller votre téléphone à l\'aide de votre empreinte digitale."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue. Reconfigurez le déverrouillage par empreinte digitale."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues. Reconfigurez le déverrouillage par empreinte digitale."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Reconfigurer le déverrouillage par reconnaissance faciale"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Votre empreinte faciale ne fonctionnait pas correctement et a été supprimée. Configurez-la à nouveau pour déverrouiller votre téléphone à l\'aide de votre visage."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Votre empreinte faciale ne peut plus être reconnue. Reconfigurez le déverrouillage par reconnaissance faciale."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configuration"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Pas maintenant"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme pour <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Changer d\'utilisateur"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Couper le son"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Appuyer pour couper le son"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 3f3634a286f6..d016747ea3c6 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1765,12 +1765,9 @@
<skip />
<!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
<skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"A función abrirase cando volvas tocar o botón Accesibilidade"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"A función abrirase cando volvas usar este atallo. Pasa dous dedos desde a parte inferior da pantalla e solta rapidamente."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"A función abrirase cando volvas usar este atallo. Pasa tres dedos desde a parte inferior da pantalla e solta rapidamente."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuario actual <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -2427,19 +2424,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espazo privado"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Contido confidencial da notificación oculto"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Por motivos de seguranza, ocultouse o contido da aplicación para que no se mostre na pantalla compartida"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Por seguranza, ocultouse o contido da aplicación na pantalla compartida"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Conexión automática ao satélite"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Podes enviar e recibir mensaxes sen unha rede de telefonía móbil ou wifi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensaxes"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona?"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura de novo o desbloqueo dactilar"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A <xliff:g id="FINGERPRINT">%s</xliff:g> non funcionaba correctamente, polo que se eliminou"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"As impresións dixitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funcionaban correctamente, polo que se eliminaron"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A <xliff:g id="FINGERPRINT">%s</xliff:g> non funcionaba correctamente, polo que se eliminou. Configúraa de novo para desbloquear o teléfono usando a impresión dixital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"As impresións dixitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funcionaban correctamente, polo que se eliminaron. Configúraas de novo para desbloquear o teléfono usando a impresión dixital."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> xa non se recoñece."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> xa non se recoñecen."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> xa non se recoñece. Configura de novo o desbloqueo dactilar."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> xa non se recoñecen. Configura de novo o desbloqueo dactilar."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configura de novo o desbloqueo facial"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"O teu modelo facial non funcionaba correctamente, polo que se eliminou. Configúrao de novo para desbloquear o teléfono usando a cara."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Xa non se recoñece o teu modelo facial. Configura de novo o desbloqueo facial."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora non"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambiar de usuario"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silenciar"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tocar para silenciar o son"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index b3918668fe6f..7204703fb9f1 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"વાયરલેસ ડિબગીંગ બંધ કરવા માટે પસંદ કરો."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ટેસ્ટ હાર્નેસ મોડ ચાલુ કર્યો"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ટેસ્ટ હાર્નેસ મોડ બંધ કરવા માટે ફૅક્ટરી રીસેટ કરો."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUMનું ખોટું બિલ્ડ કન્ફિગ્યુરેશન"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"આ ડિવાઇસના હેડલેસ સિસ્ટમ યુઝર મોડનું સ્ટેટસ તેના બિલ્ડ કન્ફિગ્યુરેશન કરતાં અલગ હોય છે. કૃપા કરીને ડિવાઇસને ફેક્ટરી રીસેટ કરો."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"સિરીયલ કન્સોલ ચાલુ થયો"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"કાર્યપ્રદર્શનને અસર થાય છે. બંધ કરવા માટે, બૂટલોડર ચેક કરો."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"પ્રયોગાત્મક MTE ચાલુ કર્યું"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ચાલુ કરી."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> બંધ કરી."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"વૉલ્યૂમ કી છોડી દો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ને ચાલુ કરવા માટે, 3 સેકન્ડ માટે બન્ને વૉલ્યૂમ કીને ફરીથી દબાવી રાખો."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"સુવિધા પસંદ કરો"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"સુવિધા પસંદ કરો"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"સુવિધા પસંદ કરો"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"તમે આગલી વાર જ્યારે ઍક્સેસિબિલિટી બટન પર ટૅપ કરશો, ત્યારે આ સુવિધા ચાલુ થશે"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"તમે આગલી વાર જ્યારે આ શૉર્ટકટનો ઉપયોગ કરશો, ત્યારે આ સુવિધા ચાલુ થશે. તમારી સ્ક્રીનની સૌથી નીચેથી 2 આંગળી વડે ઉપરની દિશાએ સ્વાઇપ કરો અને ઝડપથી છોડી દો."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"તમે આગલી વાર જ્યારે આ શૉર્ટકટનો ઉપયોગ કરશો, ત્યારે આ સુવિધા ચાલુ થશે. તમારી સ્ક્રીનની સૌથી નીચેથી 3 આંગળી વડે ઉપરની દિશાએ સ્વાઇપ કરો અને ઝડપથી છોડી દો."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"મોટું કરવું"</string>
<string name="user_switched" msgid="7249833311585228097">"વર્તમાન વપરાશકર્તા <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> પર સ્વિચ કરી રહ્યાં છે…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"પિન ખૂબ નાનો છે. ઓછામાં ઓછો 4 અંકનો હોવો આવશ્યક છે."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"પછી ફરી પ્રયાસ કરો"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"પૂર્ણ સ્ક્રીન પર જુઓ"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"બહાર નીકળવા માટે, તમારી સ્ક્રીનની સૌથી ઉપરથી નીચેની તરફ સ્વાઇપ કરો"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"સમજાઈ ગયું"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"બહેતર વ્યૂ માટે ફેરવો"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"બહેતર વ્યૂ માટે, પૂર્ણ સ્ક્રીનમાં <xliff:g id="NAME">%s</xliff:g> ખોલો"</string>
@@ -2434,12 +2425,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"તેની કામ કરવાની રીત"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"બાકી..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ફિંગરપ્રિન્ટ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> યોગ્ય રીતે કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> યોગ્ય રીતે કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> બરાબર કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી. તમારા ફોનને ફિંગરપ્રિન્ટ વડે અનલૉક કરવા માટે, તેનું ફરીથી સેટઅપ કરો."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> બરાબર કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી. તમારા ફોનને તમારી ફિંગરપ્રિન્ટ વડે અનલૉક કરવા માટે, તેનું ફરીથી સેટઅપ કરો."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"હવે <xliff:g id="FINGERPRINT">%s</xliff:g> ઓળખી શકાતી નથી."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"હવે <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ઓળખી શકાતી નથી."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"હવે <xliff:g id="FINGERPRINT">%s</xliff:g> ઓળખી શકાતી નથી. ફિંગરપ્રિન્ટ અનલૉક સુવિધાનું ફરી સેટઅપ કરો."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"હવે <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ઓળખી શકાતી નથી. ફિંગરપ્રિન્ટ અનલૉક સુવિધાનું ફરી સેટઅપ કરો."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ફેસ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"તમારા ચહેરાનું મૉડલ બરાબર કામ કરતું ન હતું અને તેને ડિલીટ કરવામાં આવ્યું હતું. તમારા ફોનને ચહેરા વડે અનલૉક કરવા માટે, તેનું ફરીથી સેટઅપ કરો."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"હવે તમારા ચહેરાનું મૉડલ ઓળખી શકાતું નથી. ફેસ અનલૉક સુવિધાનું ફરી સેટઅપ કરો."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"સેટઅપ કરો"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"હમણાં નહીં"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> માટે અલાર્મ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"વપરાશકર્તા સ્વિચ કરો"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"મ્યૂટ કરો"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"સાઉન્ડ મ્યૂટ કરવા માટે ટૅપ કરો"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"બ્રાઉઝર"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"સંપર્કો"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"ઇમેઇલ"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"SMS"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"મ્યુઝિક"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"કૅલેન્ડર"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"કેલ્ક્યુલેટર"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"નકશા"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"ઍપ્લિકેશનો"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 6db2ee26243d..c4d6f4afdff8 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -629,7 +629,7 @@
<string name="permlab_useBiometric" msgid="6314741124749633786">"बायोमीट्रिक हार्डवेयर इस्तेमाल करने दें"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"पुष्टि के लिए, ऐप्लिकेशन को बायोमीट्रिक हार्डवेयर इस्तेमाल करने की मंज़ूरी दें"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"फ़िंगरप्रिंट हार्डवेयर को प्रबंधित करें"</string>
- <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"फ़िंगरप्रिंट वाले टेम्पलेट का इस्तेमाल करने के लिए जोड़ने और हटाने के लिए ऐप को तरीके शुरू करने देती है."</string>
+ <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"फ़िंगरप्रिंट वाले टेंप्लेट का इस्तेमाल करने के लिए जोड़ने और हटाने के लिए ऐप को तरीके शुरू करने देती है."</string>
<string name="permlab_useFingerprint" msgid="1001421069766751922">"फ़िंगरप्रिंट हार्डवेयर का उपयोग करें"</string>
<string name="permdesc_useFingerprint" msgid="412463055059323742">"ऐप के प्रमाणीकरण के लिए फ़िंगरप्रिंट हार्डवेयर का उपयोग करने देती है"</string>
<string name="permlab_audioWrite" msgid="8501705294265669405">"अपने संगीत संग्रह में बदलाव करने की अनुमति दें"</string>
@@ -1198,7 +1198,7 @@
<string name="low_internal_storage_view_text" msgid="8172166728369697835">"हो सकता है कुछ सिस्टम फ़ंक्शन काम नहीं करें"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"सिस्टम के लिए ज़रूरी मेमोरी नहीं है. पक्का करें कि आपके पास 250एमबी की खाली जगह है और फिर से शुरू करें."</string>
<string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> चल रहा है"</string>
- <string name="app_running_notification_text" msgid="5120815883400228566">"ज़्यादा जानकारी के लिए या ऐप्लिकेशन को रोकने के लिए छूएं."</string>
+ <string name="app_running_notification_text" msgid="5120815883400228566">"ऐप्लिकेशन को रोकने या ज़्यादा जानकारी के लिए टैप करें."</string>
<string name="ok" msgid="2646370155170753815">"ठीक है"</string>
<string name="cancel" msgid="6908697720451760115">"रद्द करें"</string>
<string name="yes" msgid="9069828999585032361">"ठीक है"</string>
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"वॉयरलेस डीबगिंग की सुविधा बंद करने के लिए चुनें."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"टेस्ट हार्नेस मोड चालू किया गया"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"टेस्ट हार्नेस मोड बंद करने के लिए फ़ैक्ट्री रीसेट करें."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"एचएसयूएम का बिल्ड कॉन्फ़िगरेशन गलत है"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"इस डिवाइस के लिए हेडलेस सिस्टम यूज़र मोड की स्थिति इसके बिल्ड कॉन्फ़िगरेशन से अलग है. कृपया अपने डिवाइस को फ़ैक्ट्री रीसेट करें."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"सीरियल कंसोल को चालू करें"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"परफ़ॉर्मेंस पर असर पड़ा है. बंद करने के लिए बूटलोडर चुनें."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"आज़माने के लिए एमटीई चालू है"</string>
@@ -1439,8 +1437,8 @@
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"दूसरे ऐप्लिकेशन के ऊपर दिखाए जाने का ऐक्सेस"</string>
<string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> अन्य ऐप्लिकेशन के ऊपर दिखाई दे रहा है"</string>
- <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> अन्य ऐप पर दिखाई दे रहा है"</string>
- <string name="alert_windows_notification_message" msgid="6538171456970725333">"अगर आप नहीं चाहते कि <xliff:g id="NAME">%s</xliff:g> इस सुविधा का उपयोग करे, तो सेटिंग खोलने और उसे बंद करने के लिए टैप करें."</string>
+ <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> दूसरे ऐप के ऊपर दिख रहा है"</string>
+ <string name="alert_windows_notification_message" msgid="6538171456970725333">"अगर <xliff:g id="NAME">%s</xliff:g> को इस सुविधा का इस्तेमाल करने की अनुमति नहीं देनी है, तो इसे बंद करने के लिए सेटिंग पर जाएं."</string>
<string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"बंद करें"</string>
<string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> ढूंढा जा रहा है…"</string>
<string name="ext_media_checking_notification_message" msgid="2231566971425375542">"मौजूदा सामग्री की जाँच की जा रही है"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू कर दिया गया."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद कर दिया गया."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"आवाज़ बटन को छोड़ें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> की सुविधा चालू करने के लिए, आवाज़ वाले दोनों बटन तीन सेकंड तक दबाकर रखें."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"कोई सुविधा चुनें"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"कोई सुविधा चुनें"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"कोई सुविधा चुनें"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"अगली बार सुलभता बटन पर टैप करने से, यह सुविधा चालू हो जाएगी"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"इस शॉर्टकट का अगली बार इस्तेमाल करने पर, यह सुविधा चालू हो जाएगी. स्क्रीन पर दो उंगलियों से, नीचे से ऊपर की ओर स्वाइप करें और फिर स्क्रीन से तुरंत उंगलियां हटा दें."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"इस शॉर्टकट का अगली बार इस्तेमाल करने पर, यह सुविधा चालू हो जाएगी. स्क्रीन पर तीन उंगलियों से, नीचे से ऊपर की ओर स्वाइप करें और फिर स्क्रीन से तुरंत उंगलियां हटा दें."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ज़ूम करने की सुविधा"</string>
<string name="user_switched" msgid="7249833311585228097">"मौजूदा उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN बहुत छोटा है. कम से कम 4 अंकों का होना चाहिए."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"बाद में फिर से प्रयास करें"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"आप पूरे स्क्रीन पर देख रहे हैं"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"बंद करने के लिए, स्क्रीन के सबसे ऊपरी हिस्से से नीचे की ओर स्वाइप करें"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"ठीक है"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"बेहतर व्यू पाने के लिए, डिवाइस की स्क्रीन को घुमाएं"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"बेहतर व्यू पाने के लिए <xliff:g id="NAME">%s</xliff:g> को फ़ुल स्क्रीन में खोलें"</string>
@@ -2434,12 +2425,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यह सेटिंग कैसे काम करती है"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"प्रोसेस जारी है..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"अच्छे से काम न करने की वजह से <xliff:g id="FINGERPRINT">%s</xliff:g> को मिटा दिया गया"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"अच्छे से काम न करने की वजह से, <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> और <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> को मिटा दिया गया"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"अच्छे से काम न करने की वजह से <xliff:g id="FINGERPRINT">%s</xliff:g> को मिटा दिया गया. फ़िंगरप्रिंट की मदद से फ़ोन अनलॉक करने के लिए, फ़िंगरप्रिंट अनलॉक की सुविधा को दोबारा सेट अप करें."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"अच्छे से काम न करने की वजह से, <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> और <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> को मिटा दिया गया. फ़िंगरप्रिंट की मदद से फ़ोन अनलॉक करने के लिए, फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"अब <xliff:g id="FINGERPRINT">%s</xliff:g> की पहचान नहीं की जा सकती."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"अब <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> और <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> की पहचान नहीं की जा सकती."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"अब <xliff:g id="FINGERPRINT">%s</xliff:g> की पहचान नहीं की जा सकती. फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"अब <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> और <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> की पहचान नहीं की जा सकती. फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"फ़ेस अनलॉक की सुविधा को दोबारा सेट अप करें"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"अच्छे से काम न करने की वजह से, चेहरे का मॉडल मिटा दिया गया. फ़ेस अनलॉक की सुविधा की मदद से फ़ोन अनलॉक करने के लिए, इस सुविधा को दोबारा सेट अप करें."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"अब आपके चेहरे के मॉडल की पहचान नहीं की जा सकती. फ़ेस अनलॉक की सुविधा को दोबारा सेट अप करें."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेट अप करें"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"अभी नहीं"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> के लिए अलार्म"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"दूसरे खाते पर स्विच करें"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"म्यूट करें"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"आवाज़ म्यूट करने के लिए टैप करें"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"ब्राउज़र"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"संपर्क"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"ईमेल"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"एसएमएस"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"संगीत"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"कैलेंडर"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"कैल्कुलेटर"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"मैप"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"ऐप्लिकेशन"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 611dc46cdbf8..c3a6ec20c0b3 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Odaberite da biste onemogućili bežično otklanjanje pogrešaka."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Omogućen je način testnog okvira"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Vratite na tvorničke postavke da biste onemogućili način testnog okvira."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Pogrešna konfiguracija sustavnog korisnika bez grafičkog korisničkog sučelja"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Stanje načina sustavnog korisnika bez grafičkog korisničkog sučelja na ovom uređaju razlikuje se od njegove konfiguracije. Vratite uređaj na tvorničke postavke."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola omogućena"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Izvedba je otežana. Provjerite pokretač operativnog sustava da biste onemogućili konzolu."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Omogućen je eksperimentalni MTE"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za glasnoću. Uključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za glasnoću. Isključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tipke za glasnoću. Da biste uključili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite obje tipke za glasnoću tri sekunde."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Odaberite značajku"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Odaberite značajku"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Odaberite značajku"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Značajka će se otvoriti sljedeći put kad dodirnete gumb za pristupačnost"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Značajka će se otvoriti sljedeći put kad upotrijebite ovaj prečac. Nakratko prijeđite dvama prstima s dna zaslona."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Značajka će se otvoriti sljedeći put kad upotrijebite ovaj prečac. Nakratko prijeđite s dna zaslona trima prstima."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povećavanje"</string>
<string name="user_switched" msgid="7249833311585228097">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN je prekratak. Mora imati barem 4 znamenke."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Pokušajte ponovo kasnije"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Gledanje preko cijelog zaslona"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Za izlaz povucite prstom od vrha zaslona prema dolje"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Shvaćam"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zakrenite kako biste bolje vidjeli"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Otvorite aplikaciju <xliff:g id="NAME">%s</xliff:g> preko cijelog zaslona za bolji prikaz"</string>
@@ -2435,12 +2426,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako to funkcionira"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovno postavite otključavanje otiskom prsta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao i izbrisan je"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali i izbrisani su"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao i izbrisan je. Ponovno ga postavite da biste otključali telefon otiskom prsta."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali i izbrisani su. Ponovno ih postavite da biste otključali telefon otiskom prsta."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> više se ne prepoznaje."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> više se ne prepoznaju."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> više se ne prepoznaje. Ponovo postavite otključavanje otiskom prsta."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> više se ne prepoznaju. Ponovo postavite otključavanje otiskom prsta."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovno postavite otključavanje licem"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model vašeg lica nije dobro funkcionirao i izbrisan je. Ponovno ga postavite da biste otključali telefon licem."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Vaš model lica više se ne prepoznaje. Ponovo postavite otključavanje licem."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Postavi"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sad"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Promijeni korisnika"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Isključi zvuk"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dodirnite za isključivanje zvuka"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index dbbba59f29ba..396a482d0e9a 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Válassza ezt a vezeték nélküli hibakeresés letiltásához."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Tesztelési alapkörnyezet mód engedélyezve"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"A Tesztelési alapkörnyezet mód kikapcsolásához állítsa vissza a gyári beállításokat."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Hibás HSUM-buildkonfiguráció"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Az eszköz Headless System User Mode állapota eltér a buildjének a konfigurációjától. Kérjük, állítsa vissza az eszköz gyári beállításait."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Soros konzol engedélyezve"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ez hatással van a teljesítményre. A letiltáshoz ellenőrizze a rendszerindítót."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Kísérleti MTE engedélyezve"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolva."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kikapcsolva."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Engedje fel a hangerőszabályzó gombokat. A(z) <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolásához tartsa újra lenyomva a hangerőszabályzó gombokat három másodpercig."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Funkció kiválasztása"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Funkció kiválasztása"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Funkció kiválasztása"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"A funkció a Kisegítő lehetőségek gombra való következő koppintáskor lesz megnyitva"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"A funkció a gyorsparancs következő használatakor lesz megnyitva. Csúsztasson felfelé két ujjal a képernyő aljáról, majd emelje fel gyorsan az ujjait."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"A funkció a gyorsparancs következő használatakor lesz megnyitva. Csúsztasson felfelé három ujjal a képernyő aljáról, majd emelje fel gyorsan az ujjait."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Nagyítás"</string>
<string name="user_switched" msgid="7249833311585228097">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Átváltás erre: <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"A PIN-kód túl rövid. Legalább 4 számjegyből kell állnia."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Próbálkozzon később"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Megtekintése teljes képernyőn"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"A kilépéshez csúsztasson gyorsan lefelé a képernyő tetejéről."</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Értem"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Forgassa el a jobb élmény érdekében"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"A jobb élmény érdekében teljes képernyős módban nyissa meg a(z) <xliff:g id="NAME">%s</xliff:g> alkalmazást"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Hívás folyamatban"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Bejövő hívás szűrése"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Nincs kategóriába sorolva"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promóciók"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Közösségi"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Hírek"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Javaslatok"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ön állította be ezen értesítések fontossági szintjét."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ez az üzenet a résztvevők miatt fontos."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Egyéni alkalmazásértesítés"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Képernyőn megjelenő kisegítő lehetőségekre vonatkozó parancsválasztó"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Kisegítő lehetőségek gyorsparancsa"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Értesítési felület bezárása"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menü"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Médialejátszás/szüneteltetés"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad – fel"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad – le"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad – balra"</string>
@@ -2433,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Privát terület"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Bizalmas értesítéstartalom elrejtve"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"A biztonság érdekében a képernyőmegosztástól elrejtett alkalmazástartalom"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Apptartalom elrejtve a megosztástól a biztonság érdekében"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Automatikusan csatlakozva a műholdhoz"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Küldhet és fogadhat üzeneteket mobil- és Wi-Fi-hálózat nélkül is"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"A Messages megnyitása"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hogyan működik?"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Függőben…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"A Feloldás ujjlenyomattal funkció újbóli beállítása"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A(z) <xliff:g id="FINGERPRINT">%s</xliff:g> nem működött megfelelően, ezért törölve lett"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"A(z) <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és a(z) <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nem működtek megfelelően, ezért törölve lettek"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A(z) <xliff:g id="FINGERPRINT">%s</xliff:g> nem működött megfelelően, ezért törölve lett. Állítsa be újra, hogy feloldhassa a telefonját az ujjlenyomata segítségével."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"A(z) <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és a(z) <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nem működtek megfelelően, ezért törölve lettek. Állítsa be őket újra, hogy feloldhassa a telefonját az ujjlenyomata segítségével."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"A következő már nem felismerhető: <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"A következők már nem felismerhetők: <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"A következő már nem felismerhető: <xliff:g id="FINGERPRINT">%s</xliff:g>. Állítsa be újra a Feloldás ujjlenyomattal funkciót."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"A következők már nem felismerhetők: <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. Állítsa be újra a Feloldás ujjlenyomattal funkciót."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Állítsa be újra az Arcalapú feloldást"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Az arcmodellje nem működött megfelelően, ezért törölve lett. Állítsa be újra, hogy feloldhassa a telefonját az arca segítségével."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Az arcmodellje már nem felismerhető. Állítsa be újra az Arcalapú feloldást."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Beállítás"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Most nem"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Riasztás <xliff:g id="USER_NAME">%s</xliff:g> részére"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Felhasználóváltás"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Némítás"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Koppintson a hang elnémításához"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index c690b293e9d1..aad776043bc4 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Սեղմեք՝ անլար վրիպազերծումն անջատելու համար:"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Թեստային ռեժիմը միացված է"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Թեստային ռեժիմն անջատելու համար զրոյացրեք կարգավորումները։"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM կառուցման սխալ կազմաձև"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Այս սարքի առանց գրաֆիկական ինտերֆեյսի համակարգի օգտատիրոջ ռեժիմի (HSUM) կարգավիճակը տարբերվում է դրա կառուցման կազմաձևից։ Խնդրում ենք վերականգնել սարքի գործարանային կարգավորումները։"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Սերիական վահանակը միացված է"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Աշխատանքի արդյունավետությունը նվազում է։ Վահանակն անջատելու համար ստուգեք օպերացիոն համակարգի բեռնիչը։"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Միացված է փորձնական MTE գործառույթը"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացավ։"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունն անջատվեց։"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Բաց թողեք ձայնի ուժգնության կոճակները։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացնելու համար սեղմեք և 3 վայրկյան պահեք ձայնի ուժգնության երկու կոճակը։"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Ընտրեք որևէ գործառույթ"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Ընտրեք որևէ գործառույթ"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Ընտրեք որևէ գործառույթ"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Գործառույթը կբացվի հաջորդ անգամ, երբ սեղմեք «Հատուկ գործառույթներ» կոճակը"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Գործառույթը կբացվի հաջորդ անգամ, երբ օգտագործեք այս դյուրանցումը։ Երկու մատը էկրանի ներքևից սահեցրեք վերև և արագ բաց թողեք։"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Գործառույթը կբացվի հաջորդ անգամ, երբ օգտագործեք այս դյուրանցումը։ Երեք մատը էկրանի ներքևից սահեցրեք վերև և արագ բաց թողեք։"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Խոշորացում"</string>
<string name="user_switched" msgid="7249833311585228097">"Ներկայիս օգտատերը <xliff:g id="NAME">%1$s</xliff:g>:"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Անցում <xliff:g id="NAME">%1$s</xliff:g> պրոֆիլին..."</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN-ը չափազանց կարճ է: Պետք է ունենա առնվազն 4 թվանիշ:"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Կրկին փորձեք մի փոքր ուշ"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Լիաէկրան դիտում"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Դուրս գալու համար էկրանի վերևից մատը սահեցրեք ներքև"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Պարզ է"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Պտտեք՝ դիտակերպը լավացնելու համար"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Բացեք <xliff:g id="NAME">%s</xliff:g> հավելվածը լիաէկրան ռեժիմում՝ դիտակերպը լավացնելու համար"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ընթացիկ զանգ"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Մուտքային զանգի զտում"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Չդասակարգված"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Պրոմոակցիաներ"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Սոցցանցեր"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Նորություններ"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Առաջարկներ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Դուք սահմանել եք այս ծանուցումների կարևորությունը:"</string>
<string name="importance_from_person" msgid="4235804979664465383">"Կարևոր է, քանի որ որոշակի մարդիկ են ներգրավված:"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Հատուկ հավելվածի ծանուցում"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Հատուկ գործառույթների դյուրանցման ընտրիչ"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Հատուկ գործառույթների դյուրանցում"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Փակել ծանուցումների վահանակը"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Ընտրացանկ"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Նվագարկում/դադար"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad-ի «Վերև» կոճակ"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad-ի «Ներքև» կոճակ"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad-ի «Ձախ» կոճակ"</string>
@@ -2433,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Մասնավոր տարածք"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Ծանուցման զգայուն բովանդակությունը թաքցված է"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Անվտանգության նկատառումներից ելնելով՝ հավելվածի բովանդակությունը թաքցվել է էկրանի ցուցադրումից"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Անվտանգության նկատառումներով՝ բովանդակությունը թաքցվել է ցուցադրումից"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Ավտոմատ միացել է արբանյակին"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Դուք կարող եք ուղարկել և ստանալ հաղորդագրություններ՝ առանց բջջային կամ Wi-Fi կապի"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Բացել Messages-ը"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ինչպես է դա աշխատում"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Առկախ է…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Նորից կարգավորեք մատնահետքով ապակողպումը"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"«<xliff:g id="FINGERPRINT">%s</xliff:g>» մատնահետքը հեռացվել է, քանի որ լավ չէր աշխատում"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"«<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>» և «<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>» մատնահետքերը հեռացվել են, քանի որ լավ չէին աշխատում"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"«<xliff:g id="FINGERPRINT">%s</xliff:g>» մատնահետքը հեռացվել է, քանի որ լավ չէր աշխատում։ Նորից կարգավորեք այն՝ ձեր հեռախոսը մատնահետքով ապակողպելու համար։"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"«<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>» և «<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>» մատնահետքերը հեռացվել են, քանի որ լավ չէին աշխատում։ Նորից կարգավորեք դրանք՝ ձեր հեռախոսը մատնահետքով ապակողպելու համար։"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> մատնահետքն այլևս չի կարող ճանաչվել։"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> և <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> մատնահետքերն այլևս չեն կարող ճանաչվել։"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> մատնահետքն այլևս չի կարող ճանաչվել։ Նորից կարգավորեք մատնահետքով ապակողպումը։"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> և <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> մատնահետքերն այլևս չեն կարող ճանաչվել։ Նորից կարգավորեք մատնահետքով ապակողպումը։"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Նորից կարգավորեք դեմքով ապակողպումը"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ձեր դեմքի նմուշը հեռացվել է, քանի որ լավ չէր աշխատում։ Նորից կարգավորեք այն՝ ձեր հեռախոսը դեմքով ապակողպելու համար։"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Ձեր դեմքի նմուշն այլևս չի կարող ճանաչվել։ Նորից կարգավորեք դեմքով ապակողպումը։"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Կարգավորել"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ոչ հիմա"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>-ի զարթուցիչ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Անցնել մյուս հաշիվ"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Անտեսել"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Հպեք՝ ձայնն անջատելու համար"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 1b3fc0e8c4e5..9668f0e52719 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Pilih untuk menonaktifkan proses debug nirkabel."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mode Tes Otomatis diaktifkan"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Lakukan reset ke setelan pabrik untuk menonaktifkan Mode Tes Otomatis."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Konfigurasi build HSUM salah"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Status Mode Pengguna Sistem Headless dari perangkat ini berbeda dari konfigurasi build-nya. Reset perangkat ke setelan pabrik."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Konsol serial diaktifkan"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performa terpengaruh. Untuk menonaktifkan, periksa bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE eksperimental diaktifkan"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan tombol volume. Untuk mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tekan dan tahan kedua tombol volume lagi selama 3 detik."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Pilih fitur"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Pilih fitur"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Pilih fitur"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Fitur akan terbuka setelah Anda mengetuk tombol aksesibilitas"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Fitur akan terbuka setelah Anda menggunakan pintasan ini. Geser ke atas dengan 2 jari dari bawah layar, lalu lepaskan dengan cepat."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Fitur akan terbuka setelah Anda menggunakan pintasan ini. Geser ke atas dengan 3 jari dari bawah layar, lalu lepaskan dengan cepat."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pembesaran"</string>
<string name="user_switched" msgid="7249833311585228097">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Beralih ke <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN terlalu pendek. Minimal 4 digit."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Coba lagi nanti"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Melihat layar penuh"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Untuk keluar, geser ke bawah dari bagian atas layar"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Mengerti"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Putar posisi layar untuk mendapatkan tampilan yang lebih baik"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Buka <xliff:g id="NAME">%s</xliff:g> dalam layar penuh untuk mendapatkan tampilan yang lebih baik"</string>
@@ -2427,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Ruang privasi"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Konten notifikasi sensitif disembunyikan"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Konten aplikasi disembunyikan dari berbagi layar untuk alasan keamanan"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Konten aplikasi disembunyikan dari berbagi layar karena alasan keamanan"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Menghubungkan otomatis ke satelit"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Anda dapat mengirim dan menerima pesan tanpa jaringan seluler atau Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Message"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara kerjanya"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Tertunda..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Siapkan Buka dengan Sidik Jari lagi"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dihapus"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dihapus"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dihapus. Siapkan lagi untuk membuka kunci ponsel Anda dengan sidik jari."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dihapus. Siapkan lagi untuk membuka kunci ponsel Anda dengan sidik jari."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dikenali lagi."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dikenali lagi."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dikenali lagi. Siapkan Buka dengan Sidik Jari lagi."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dikenali lagi. Siapkan Buka dengan Sidik Jari lagi."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Siapkan Buka dengan Wajah lagi"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model wajah Anda tidak berfungsi dengan baik dan telah dihapus. Siapkan lagi untuk membuka kunci ponsel Anda dengan wajah."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Model wajah Anda tidak dapat dikenali lagi. Siapkan Buka dengan Wajah lagi."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Penyiapan"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Lain kali"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm untuk <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Ganti pengguna"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Bisukan"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Ketuk untuk membisukan suara"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 01e2f6fc93b5..b179c15d1f83 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Veldu til að slökkva á þráðlausri villuleit."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Kveikt á stillingu prófunarvangs"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Núllstilltu til að slökkva á stillingu prófunarvangs."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Röng HSUM-grunnstilling"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Ástand bakgrunnsnotandastillingarinnar í þessu tæki er ekki það sama og grunnstillingin gefur til kynna. Núllstilltu tækið."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Raðstjórnborð virkjað"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Þetta hefur áhrif á afköst. Athugaðu ræsiforritið ef þú vilt gera þetta óvirkt."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Kveikt á MTE á tilraunarstigi"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Hljóðstyrkstökkum haldið inni. Kveikt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Hljóðstyrkstökkum haldið inni. Slökkt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slepptu hljóðstyrkstökkunum. Til að kveikja á <xliff:g id="SERVICE_NAME">%1$s</xliff:g> skaltu halda báðum hljóðstyrkstökkunum aftur inni í 3 sekúndur."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Veldu eiginleika"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Veldu eiginleika"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Veldu eiginleika"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Eiginleikinn opnast næst þegar þú ýtir á aðgengishnappinn"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Eiginleikinn opnast næst þegar þú notar þessa flýtileið Strjúktu upp með 2 fingrum frá neðsta hluta skjásins og slepptu hratt."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Eiginleikinn opnast næst þegar þú notar þessa flýtileið Strjúktu upp með 3 fingrum frá neðsta hluta skjásins og slepptu hratt."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Stækkun"</string>
<string name="user_switched" msgid="7249833311585228097">"Núverandi notandi <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Skiptir yfir á <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN-númerið er of stutt. Það verður að vera a.m.k. 4 tölustafir."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Reyndu aftur síðar"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Notar allan skjáinn"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Strjúktu niður frá efsta hluta skjásins til að hætta"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Ég skil"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Snúðu til að sjá betur"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Opnaðu <xliff:g id="NAME">%s</xliff:g> á öllum skjánum til að fá betra yfirlit"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Símtal í gangi"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Síar símtal sem berst"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Óflokkað"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Kynningar"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Samfélag"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Fréttir"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Tillögur"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Þú stilltir mikilvægi þessara tilkynninga."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Þetta er mikilvægt vegna fólksins sem tekur þátt í þessu."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Sérsniðin forritatilkynning"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Val um flýtileið í aðgengiseiginleika á skjánum"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Flýtileið aðgengisstillingar"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Loka tilkynningaglugga"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Valmynd"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Spila/gera hlé á margmiðlunarefni"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Upphnappur stýriflatar"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Niðurhnappur stýriflatar"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Vinstrihnappur stýriflatar"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Svona virkar þetta"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Í bið…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setja upp fingrafarskenni aftur"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkaði illa og var eytt."</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkuðu illa og var eytt."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkaði illa og var eytt. Settu það upp aftur til að taka símann úr lás með fingrafari."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkuðu illa og var eytt. Settu þau upp aftur til að taka símann úr lás með fingrafarinu þínu."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Ekki er hægt að bera kennsl á <xliff:g id="FINGERPRINT">%s</xliff:g> lengur."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Ekki er hægt að bera kennsl á <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> lengur."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Ekki er hægt að bera kennsl á <xliff:g id="FINGERPRINT">%s</xliff:g> lengur. Settu upp fingrafarskenni aftur."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Ekki er hægt að bera kennsl á <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> lengur. Settu upp fingrafarskenni aftur."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Setja upp andlitskenni aftur"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Andlitslíkanið þitt virkaði illa og var eytt. Settu það upp aftur til að taka símann úr lás með andlitinu."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Ekki er hægt að bera kennsl á andlitslíkanið þitt lengur. Settu upp andlitskenni aftur."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Setja upp"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ekki núna"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Viðvörun fyrir <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Skipta um notanda"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Þagga"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Ýttu til að þagga hljóð"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 240f3187284e..06aa308d6378 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -499,9 +499,9 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"accesso a comandi aggiuntivi provider di geolocalizz."</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Consente all\'app di accedere a ulteriori comandi del fornitore di posizione. Ciò potrebbe consentire all\'app di interferire con il funzionamento del GPS o di altre fonti di geolocalizzazione."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"accesso alla posizione esatta solo in primo piano"</string>
- <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Questa app può recuperare la tua posizione precisa dai Servizi di geolocalizzazione quando l\'app è in uso. L\'impostazione Servizi di geolocalizzazione deve essere attiva sul tuo dispositivo perché l\'app possa recuperare la tua posizione. Questa operazione potrebbe comportare un maggior consumo della batteria."</string>
+ <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Questa app può recuperare la tua posizione precisa dai Servizi di localizzazione quando l\'app è in uso. L\'impostazione Servizi di localizzazione deve essere attiva sul tuo dispositivo perché l\'app possa recuperare la tua posizione. Questa operazione potrebbe comportare un maggior consumo della batteria."</string>
<string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"Accesso alla posizione approssimativa solo in primo piano"</string>
- <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Questa app può recuperare la tua posizione approssimativa dai Servizi di geolocalizzazione quando l\'app è in uso. L\'impostazione Servizi di geolocalizzazione deve essere attiva sul tuo dispositivo perché l\'app possa recuperare la tua posizione."</string>
+ <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Questa app può recuperare la tua posizione approssimativa dai Servizi di localizzazione quando l\'app è in uso. L\'impostazione Servizi di localizzazione deve essere attiva sul tuo dispositivo perché l\'app possa recuperare la tua posizione."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"accesso alla posizione in background"</string>
<string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Questa app può accedere alla posizione in qualsiasi momento, anche quando l\'app non è in uso."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"modifica impostazioni audio"</string>
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Seleziona per disattivare il debug wireless."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modalità test harness attivata"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Ripristina le impostazioni di fabbrica per disattivare la modalità test harness."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Configurazione di compilazione della modalità utente di sistema headless errata"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Lo stato della modalità utente di sistema headless di questo dispositivo è diverso dalla sua configurazione di compilazione. Ripristina i dati di fabbrica del dispositivo."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Console seriale attivata"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ci sono conseguenze sulle prestazioni. Per disattivare, seleziona il bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Funzionalità MTE sperimentale attivata"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> attivato."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> disattivato."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Rilascia i tasti del volume. Per attivare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tieni di nuovo premuti entrambi i tasti del volume per 3 secondi."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Scegli una funzionalità"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Scegli una funzionalità"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Scegli una funzionalità"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La funzionalità si aprirà la prossima volta che toccherai il pulsante Accessibilità"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La funzionalità si aprirà la prossima volta che utilizzerai questa scorciatoia. Scorri verso l\'alto con 2 dita dalla parte inferiore dello schermo e rilascia rapidamente."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La funzionalità si aprirà la prossima volta che utilizzerai questa scorciatoia. Scorri verso l\'alto con 3 dita dalla parte inferiore dello schermo e rilascia rapidamente."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ingrandimento"</string>
<string name="user_switched" msgid="7249833311585228097">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Passaggio a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Il PIN è troppo corto. Deve avere almeno quattro cifre."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Riprova più tardi"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Visualizzazione a schermo intero"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Per uscire, scorri verso il basso dalla parte superiore dello schermo"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Ruota per migliorare l\'anteprima"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Apri <xliff:g id="NAME">%s</xliff:g> a schermo intero per migliorare la visualizzazione"</string>
@@ -1987,14 +1978,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chiamata in corso"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Applicazione filtro a chiamata in arrivo"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Senza categoria"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promozioni"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Novità"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Contenuti consigliati"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Stabilisci tu l\'importanza di queste notifiche."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Importante a causa delle persone coinvolte."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notifica app personalizzata"</string>
@@ -2211,10 +2198,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selettore scorciatoia Accessibilità sullo schermo"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Scorciatoia Accessibilità"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignora area notifiche"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Play/Pausa contenuti multimediali"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad - Su"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad - Giù"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad - Sinistra"</string>
@@ -2441,12 +2426,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Come funziona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"In attesa…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Riconfigura lo Sblocco con l\'Impronta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> non funzionava bene ed è stata eliminata"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funzionavano bene e sono state eliminate"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> non funzionava bene ed è stata eliminata. Riconfigurala per sbloccare lo smartphone con l\'impronta."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funzionavano bene e sono state eliminate. Riconfigurale per sbloccare lo smartphone con l\'impronta."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> non può più essere riconosciuto."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non possono più essere riconosciuti."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> non può più essere riconosciuto. Riconfigura lo Sblocco con l\'Impronta."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non possono più essere riconosciuti. Riconfigura lo Sblocco con l\'Impronta."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Riconfigura lo Sblocco con il Volto"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Il tuo modello del volto non funzionava bene ed è stato eliminato. Riconfiguralo per sbloccare lo smartphone con il volto."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Il tuo modello del volto non può più essere riconosciuto. Riconfigura lo Sblocco con il Volto."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configura"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Non ora"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Sveglia per: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambia utente"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Disattiva audio"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tocca per disattivare l\'audio"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 9e68dd56cc97..dd9f6b82c3fa 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"יש לבחור כדי להשבית ניפוי באגים אלחוטי."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"מצב מסגרת בדיקה הופעל"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"כדי להשבית את מצב \'מסגרת בדיקה\' צריך לאפס להגדרות היצרן."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"‏תצורת build שגויה של \'משתמש מערכת ללא GUI\' ‏(HSUM)"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"‏מצב ה\'משתמש מערכת ללא GUI\' של המכשיר הזה שונה מתצורת ה-build שלו. צריך לאפס את המכשיר להגדרות המקוריות."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"קונסולה סדרתית מופעלת"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"קיימת השפעה על הביצועים. כדי להשבית, יש לבדוק את תוכנת האתחול."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"‏ה-MTE הניסיוני הופעל"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. שירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הופעל."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. שירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הושבת."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"אפשר לשחרר את מקש עוצמת הקול. כדי להפעיל את השירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, צריך ללחוץ לחיצה ארוכה על שני המקשים של עוצמת הקול שוב במשך 3 שניות."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"בחירת תכונה"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"בחירת תכונה"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"בחירת תכונה"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"התכונה תיפתח בפעם הבאה שתזוהה הקשה על לחצן הנגישות"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"התכונה תיפתח בפעם הבאה שייעשה שימוש במקש הקיצור הזה. צריך להחליק למעלה עם 2 אצבעות מהחלק התחתון של המסך ולשחרר במהירות."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"התכונה תיפתח בפעם הבאה שייעשה שימוש במקש הקיצור הזה. צריך להחליק למעלה עם 3 אצבעות מהחלק התחתון של המסך ולשחרר במהירות."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"הגדלה"</string>
<string name="user_switched" msgid="7249833311585228097">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"מעבר אל <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"קוד הגישה קצר מדי. חייב להיות באורך 4 ספרות לפחות."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"יש לנסות שוב מאוחר יותר"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"צפייה במסך מלא"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"כדי לצאת, מחליקים למטה מהחלק העליון של המסך"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"הבנתי"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"מסובבים כדי לראות טוב יותר"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"צריך לפתוח את <xliff:g id="NAME">%s</xliff:g> במסך מלא כדי לראות טוב יותר"</string>
@@ -1987,14 +1978,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"שיחה פעילה"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"סינון שיחה נכנסת"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"ללא שיוך לקטגוריה"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"קידומי מכירות"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"רשתות חברתיות"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"חדשות"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"המלצות"</string>
<string name="importance_from_user" msgid="2782756722448800447">"עליך להגדיר את החשיבות של ההתראות האלה."</string>
<string name="importance_from_person" msgid="4235804979664465383">"ההודעה חשובה בשל האנשים המעורבים."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"התראות אפליקציה בהתאמה אישית"</string>
@@ -2211,10 +2198,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"בורר קיצורי דרך לנגישות במסך"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"קיצור דרך לנגישות"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"סגירת לוח ההתראות"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"תפריט"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"הפעלה/השהיה של המדיה"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"‏לחצן עליון ב-Dpad"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"‏לחצן תחתון ב-Dpad"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"‏לחצן שמאלי ב-Dpad"</string>
@@ -2441,12 +2426,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"איך זה עובד"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"בהמתנה..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"הגדרה חוזרת של \'ביטול הנעילה בטביעת אצבע\'"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> לא פעלה טוב ולכן היא נמחקה"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ו<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> לא פעלו טוב ולכן הן נמחקו"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> לא פעלה היטב ולכן היא נמחקה. עליך להגדיר אותה שוב כדי שתהיה לך אפשרות לבטל את הנעילה של הטלפון באמצעות טביעת אצבע."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ו<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> לא פעלו היטב ולכן הן נמחקו. עליך להגדיר אותן שוב כדי שתהיה לך אפשרות לבטל את הנעילה של הטלפון באמצעות טביעת אצבע."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"כבר לא ניתן לזהות את <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"כבר לא ניתן לזהות את <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ואת <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"כבר לא ניתן לזהות את <xliff:g id="FINGERPRINT">%s</xliff:g>. הגדרה חוזרת של \'פתיחה בטביעת אצבע\'."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"כבר לא ניתן לזהות את <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ואת <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. הגדרה חוזרת של \'פתיחה בטביעת אצבע\'."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"הגדרה חוזרת של \'פתיחה ע\"י זיהוי הפנים\'"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"התבנית לזיהוי הפנים לא פעלה היטב ולכן היא נמחקה. עליך להגדיר אותה שוב כדי שתהיה לך אפשרות לבטל את הנעילה של הטלפון באמצעות זיהוי הפנים."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"כבר לא ניתן לזהות את התבנית לזיהוי הפנים. הגדרה חוזרת של \'פתיחה בזיהוי פנים\'."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"הגדרה"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"לא עכשיו"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"שעון מעורר של <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"החלפת משתמש"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"השתקה"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"צריך להקיש כדי להשתיק את הצליל"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index db56a3a781a0..29644862065c 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -156,7 +156,7 @@
<string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"モバイル ネットワーク セキュリティ"</string>
<string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"暗号化、暗号化されていないネットワークに関する通知"</string>
<string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"デバイス ID へのアクセスが発生しました"</string>
- <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に付近のネットワークでお使いのデバイスの一意の ID(IMSI または IMEI)が記録されました"</string>
+ <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に、お使いのデバイスの一意の ID(IMSI または IMEI)が付近のネットワークで記録されました。"</string>
<string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に、お使いのデバイスの一意の ID(IMSI または IMEI)が付近のネットワークで記録されました。\n\nつまり、あなたの位置情報、アクティビティ、身元などが記録されたことになります。これはよくある事象ですが、プライバシーを保護したいユーザーにとっては問題となる可能性があります。"</string>
<string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"暗号化されたネットワーク(<xliff:g id="NETWORK_NAME">%1$s</xliff:g>)に接続しました"</string>
<string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> の SIM 接続のセキュリティが強化されました"</string>
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ワイヤレス デバッグを無効にするには選択します。"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"テストハーネス モード有効"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"出荷時設定にリセットしてテストハーネス モードを無効にしてください。"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"ヘッドレス システム ユーザー モードのビルド構成に誤りがあります"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"このデバイスのヘッドレス システム ユーザー モードの状態は、ビルド構成と異なります。デバイスを初期状態にリセットしてください。"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"シリアル コンソールは有効です"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"シリアル コンソールを有効にすると、パフォーマンスに影響します。無効にするには、ブートローダーをチェックしてください。"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"試験運用版 MTE を有効にしました"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が ON になりました。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が OFF になりました。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"音量ボタンを離してください。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> を有効にするには音量大と音量小の両方のボタンを 3 秒ほど長押ししてください。"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"機能の選択"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"機能の選択"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"機能の選択"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"この機能は、ユーザー補助機能ボタンを次回タップした時に利用できるようになります"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"この機能は、このショートカットを次回使用した時に利用できるようになります。2 本の指で画面の下部から上にスワイプし、素早く離してください。"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"この機能は、このショートカットを次回使用した時に利用できるようになります。3 本の指で画面の下部から上にスワイプし、素早く離してください。"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"拡大"</string>
<string name="user_switched" msgid="7249833311585228097">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>に切り替えています…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PINが短すぎます。4桁以上で設定してください。"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"しばらくしてから再試行"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"全画面表示"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"終了するには画面の上部から下にスワイプします"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"画面を回転させて見やすくしましょう"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"<xliff:g id="NAME">%s</xliff:g> を全画面表示で開いて見やすくしましょう"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"仕組み"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"保留中..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"指紋認証をもう一度設定してください"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> は正常に機能せず、削除されました"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> と <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> は正常に機能せず、削除されました"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> が正常に機能せず、削除されました。指紋認証でスマートフォンのロックを解除するには、設定し直してください。"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> と <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> が正常に機能せず、削除されました。指紋認証でスマートフォンのロックを解除するには、設定し直してください。"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>を認識できなくなりました。"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>と<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>を認識できなくなりました。"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>を認識できなくなりました。指紋認証をもう一度設定してください。"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>と<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>を認識できなくなりました。指紋認証をもう一度設定してください。"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"顔認証をもう一度設定してください"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"顔モデルが正常に機能せず、削除されました。顔認証でスマートフォンのロックを解除するには、設定し直してください。"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"顔モデルを認識できなくなりました。顔認証をもう一度設定してください。"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"後で"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> さんのアラーム"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ユーザーを切り替え"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ミュート"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"音声をミュートするにはタップします"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 6bfacd486d6f..a45176fce061 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"აირჩიეთ შეცდომების უსადენო გამართვის გასათიშად."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"რეჟიმი „გარემო ტესტირებისთვის“ ჩართულია"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"დააბრუნეთ ქარხნული პარამეტრები „გარემო ტესტირებისთვის“ რეჟიმის გასათიშად."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"არასწორი HSUM build კონფიგურაცია"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"ამ მოწყობილობის Headless სისტემის მომხმარებლის რეჟიმის მდგომარეობა განსხვავდება მისი build კონფიგურაციისგან. გთხოვთ მოწყობილობა ქარხნულ პარამეტრებზე დააბრუნოთ."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"სერიული კონსოლი ჩართულია"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"მუშაობა შეფერხებულია. გასათიშად მონიშნეთ ჩამტვირთავი."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ექსპერიმენტული MTE ჩართულია"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ჩართულია."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> გამორთულია."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ხელი აუშვით ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-ის ჩასართველად, ხელმეორედ ხანგრძლივად დააჭირეთ ორივე ხმის ღილაკს 3 წამის განმავლობაში."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"ფუნქციის არჩევა"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"ფუნქციის არჩევა"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"ფუნქციის არჩევა"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ეს ფუნქცია გაიხსნება, როცა შემდეგ ჯერზე შეეხებით მარტივი წვდომის ღილაკს"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ეს ფუნქცია გაიხსნება, როცა შემდეგ ჯერზე გამოიყენებთ ამ მალსახმობს. გადაფურცლეთ 2 თითით თქვენი ეკრანის ქვედა ნაწილიდან და სწრაფად აუშვით."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ეს ფუნქცია გაიხსნება, როცა შემდეგ ჯერზე გამოიყენებთ ამ მალსახმობს. გადაფურცლეთ 3 თითით თქვენი ეკრანის ქვედა ნაწილიდან და სწრაფად აუშვით."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"გადიდება"</string>
<string name="user_switched" msgid="7249833311585228097">"ამჟამინდელი მომხმარებელი <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>-ზე გადართვა…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN ძალიან მოკლეა. უნდა შედგებოდეს სულ ცოტა 4 ციფრისგან."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"სცადეთ მოგვიანებით"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"სრულ ეკრანზე ნახვა"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"თქვენი ეკრანის ზემოდან გადაფურცლეთ ქვემოთ, რათა გამოხვიდეთ"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"გასაგებია"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"შეატრიალეთ უკეთესი ხედისთვის"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"გახსენით <xliff:g id="NAME">%s</xliff:g> სრულ ეკრანზე უკეთესი ხედისთვის"</string>
@@ -2427,19 +2418,32 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"კერძო სივრცე"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"სენსიტიური შეტყობინების კონტენტი დამალულია"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ეკრანის გაზიარებიდან აპის კონტენტი დამალულია უსაფრთხოების მიზნით"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ეკრანის გაზიარებისას აპის კონტენტი დამალულია უსაფრთხოების მიზნით"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"სატელიტთან ავტომატურად დაკავშირებულია"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"შეგიძლიათ გაგზავნოთ და მიიღოთ შეტყობინებები მობილური ან Wi-Fi ქსელის გარეშე"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages-ის გახსნა"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"მუშაობის პრინციპი"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"მომლოდინე..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ანაბეჭდით განბლოკვის ხელახლა დაყენება"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> კარგად არ მუშაობდა და წაიშალა"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> და <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> კარგად არ მუშაობდნენ და წაიშალა"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> კარგად არ მუშაობდა და წაიშალა. თავიდან დააყენეთ, რათა თქვენი ტელეფონი თითის ანაბეჭდის საშუალებით განბლოკოთ."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> და <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> კარგად არ მუშაობდნენ და წაიშალა. თავიდან დააყენეთ, რათა თქვენი ტელეფონი თითის ანაბეჭდის საშუალებით განბლოკოთ."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>-ის ამოცნობა ვეღარ ხერხდება."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>-ისა და <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-ის ამოცნობა ვეღარ ხერხდება."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>-ის ამოცნობა ვეღარ ხერხდება. დააყენეთ ანაბეჭდით განბლოკვა ხელახლა."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>-ისა და <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-ის ამოცნობა ვეღარ ხერხდება. დააყენეთ ანაბეჭდით განბლოკვა ხელახლა."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"დააყენეთ სახით განბლოკვა ხელახლა"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"თქვენი სახის მოდელი კარგად არ მუშაობდა და წაიშალა. თავიდან დააყენეთ, რათა თქვენი ტელეფონი სახის საშუალებით განბლოკოთ."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"თქვენი სახის მოდელის ამოცნობა ვეღარ ხერხდება. დააყენეთ სახით განბლოკვა ხელახლა."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"დაყენება"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ახლა არა"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"მაღვიძარა <xliff:g id="USER_NAME">%s</xliff:g>-ისთვის"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"მომხმარებლის გადართვა"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"დადუმება"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"შეეხეთ ხმის დასადუმებლად"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"ბრაუზერი"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"კონტაქტები"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"ელფოსტა"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"SMS"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"მუსიკა"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"კალენდარი"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"კალკულატორი"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Maps"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"აპლიკაციები"</string>
</resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 16e863253544..c526870ddbab 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Сымсыз түзетуді өшіру үшін басыңыз."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Сынақ бағдарламасы режимі қосылды"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Сынақ бағдарламасы режимін өшіру үшін зауыттық күйіне қайтарыңыз."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM құрастыру конфигурациясы дұрыс емес"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Бұл құрылғының Headless System User Mode күйі құрастыру кезіндегі конфигурациясынан ерекшеленеді. Құрылғыны зауыттық параметрлеріне қайтарыңыз."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Сериялық консоль қосылды"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Өнімділікке әсер етеді. Өшіру үшін жүктегішті тексеріңіз."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Эксперименттік MTE қосылды"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Пайдаланушы дыбыс деңгейі пернелерін басып ұстап тұрды. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қосулы."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дыбыс деңгейі пернелерін басып тұрған соң, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өшірілді."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Дыбыс деңгейі пернелерін жіберіңіз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін қосу үшін дыбыс деңгейі пернесінің екеуін де қайтадан 3 секундқа басып тұрыңыз."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Функция таңдау"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Функция таңдау"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Функция таңдау"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Келесіде арнайы мүмкіндіктер түймесін түрткенде, функция ашылады."</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Келесіде осы жылдам пәрменді қолданғанда, функция ашылады. 2 саусақпен экранның төменгі жағынан жоғары қарай сырғытып, жылдам жіберіп қалыңыз."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Келесіде осы жылдам пәрменді қолданғанда, функция ашылады. 3 саусақпен экранның төменгі жағынан жоғары қарай сырғытып, жылдам жіберіп қалыңыз."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ұлғайту"</string>
<string name="user_switched" msgid="7249833311585228097">"Ағымдағы пайдаланушы <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> профиліне ауысу…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN тым қысқа. Кем дегенде 4 бірлік болуы тиіс."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Кейінірек қайта әрекеттеніңіз."</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Толық экранда көру"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Шығу үшін экранның жоғарғы жағынан төмен қарай сырғытыңыз."</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Түсінікті"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Жақсырақ көру үшін бұрыңыз."</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Жақсырақ көру үшін <xliff:g id="NAME">%s</xliff:g> қолданбасын толық экранда ашыңыз."</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Қоңырау"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Келген қоңырауды сүзу"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Санатқа жатқызылмаған"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промонауқандар"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Әлеуметтік желі"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Жаңалықтар"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Ұсыныстар"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Сіз осы хабарландырулардың маңыздылығын орнатасыз."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Қатысты адамдарға байланысты бұл маңызды."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Арнаулы қолданба хабарландыруы"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Экрандағы арнайы мүмкіндіктерді жылдам қосу әрекетін таңдау"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Арнайы мүмкіндіктерді жылдам қосу"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Хабарландыру тақтасын жабу"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Mәзір"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Медиафайл ойнату/кідірту"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Жоғарғы Dpad түймесі"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Төменгі Dpad түймесі"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Сол жақ Dpad түймесі"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Бұл қалай орындалады?"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Дайын емес…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Саусақ ізімен ашу функциясын қайта реттеу"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> саусақ ізі дұрыс істемегендіктен жойылды."</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Саусақ іздері (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) дұрыс істемегендіктен жойылды."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> саусақ ізі дұрыс істемегендіктен жойылды. Телефонды саусақ ізімен ашу үшін оны қайта реттеңіз."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Саусақ іздері (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) дұрыс істемегендіктен жойылды. Телефонды саусақ ізімен ашу үшін оларды қайта реттеңіз."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> бұдан былай танылмайды."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> бұдан былай танылмайды."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> бұдан былай танылмайды. Саусақ ізімен ашу функциясын қайта реттеңіз."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> бұдан былай танылмайды. Саусақ ізімен ашу функциясын қайта реттеңіз."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Бет тану функциясын қайта реттеу"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Бет үлгісі дұрыс істемегендіктен жойылды. Телефонды бетпен ашу үшін оны қайта реттеңіз."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Бет үлгіңіз бұдан былай танылмайды. Бет тану функциясын қайта реттеңіз."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Реттеу"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Қазір емес"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> атына қойылған дабыл"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Пайдаланушыны ауыстыру"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Дыбысын өшіру"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Дыбысын өшіру үшін түртіңіз."</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 5a5a8da29fba..2bf799c9e8cf 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ជ្រើសរើស ដើម្បី​បិទ​ការជួសជុល​ដោយឥតខ្សែ។"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"បាន​បើក​មុខងារប្រមូលធ្វើតេស្ត"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ធ្វើការកំណត់ដូចដើមឡើងវិញ ដើម្បី​បិទ​មុខងារប្រមូលធ្វើតេស្ត។"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"ការកំណត់រចនាសម្ព័ន្ធកំណែបង្កើត HSUM ខុស"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"ស្ថានភាព Headless System User Mode របស់ឧបករណ៍នេះខុសពីការកំណត់រចនាសម្ព័ន្ធកំណែបង្កើតរបស់វា។ សូមកំណត់ឧបករណ៍នេះ​ដូច​ចេញ​ពី​រោងចក្រ។"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"កុងសូល​ស៊េរី​ត្រូវបានបើក"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"ប្រតិបត្តិការ​ទទួលរង​ការប៉ះពាល់។ សូម​ពិនិត្យមើល​កម្មវិធី​ដំណើរការ​ប្រព័ន្ធ ដើម្បី​បិទ។"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"បានបើក MTE ពិសោធន៍"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"បានសង្កត់​គ្រាប់ចុច​កម្រិតសំឡេង​ជាប់។ បាន​បើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"បានសង្កត់​គ្រាប់ចុច​កម្រិតសំឡេង​ជាប់។ បាន​បិទ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"លែង​គ្រាប់ចុចកម្រិតសំឡេង។ ដើម្បីបើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g> សូមចុច​គ្រាប់ចុចកម្រិតសំឡេងទាំងពីរឱ្យជាប់ម្ដងទៀត​រយៈពេល 3 វិនាទី។"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"ជ្រើសរើសមុខងារ"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"ជ្រើសរើសមុខងារ"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"ជ្រើសរើសមុខងារ"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"មុខងារនេះនឹងបើក ពេលអ្នកចុចប៊ូតុង​ភាពងាយស្រួលនៅលើកក្រោយ"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"មុខងារនេះនឹងបើក ពេលអ្នកប្រើផ្លូវកាត់នេះនៅលើកក្រោយ។ អូសពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នកឡើងលើដោយប្រើម្រាមដៃ 2 ហើយលែងឱ្យរហ័ស។"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"មុខងារនេះនឹងបើក ពេលអ្នកប្រើផ្លូវកាត់នេះនៅលើកក្រោយ។ អូសពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នកឡើងលើដោយប្រើម្រាមដៃ 3 ហើយលែងឱ្យរហ័ស។"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ការ​ពង្រីក"</string>
<string name="user_switched" msgid="7249833311585228097">"អ្នក​ប្រើ​បច្ចុប្បន្ន <xliff:g id="NAME">%1$s</xliff:g> ។"</string>
<string name="user_switching_message" msgid="1912993630661332336">"កំពុង​ប្ដូរ​ទៅ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"កូដ​ PIN ខ្លី​ពេក។ ត្រូវ​តែ​មាន​យ៉ាង​ហោច​ណាស់ ៤ តួ។"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"សូម​ព្យាយាម​ម្ដងទៀត​នៅ​ពេល​ក្រោយ។"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"កំពុងមើលពេញអេក្រង់"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"ដើម្បីចេញ សូមអូសពីផ្នែកខាងលើនៃអេក្រង់របស់អ្នកចុះក្រោម"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"យល់ហើយ"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"បង្វិលដើម្បីមើលបានកាន់តែច្បាស់"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"បើក <xliff:g id="NAME">%s</xliff:g> នៅក្នុងអេក្រង់ពេញ ដើម្បីមើលបានកាន់តែច្បាស់"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"របៀបដែលវាដំណើរការ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"កំពុងរង់ចាំ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"រៀបចំការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃម្ដងទៀត"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> និង <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ។ រៀបចំវាម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នកដោយប្រើស្នាមម្រាមដៃ។"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> និង <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ។ រៀបចំវាម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នកដោយប្រើស្នាមម្រាមដៃ។"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"លែងអាចសម្គាល់ <xliff:g id="FINGERPRINT">%s</xliff:g> បានទៀតហើយ។"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"លែងអាចសម្គាល់ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> និង <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> បានទៀតហើយ។"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"លែងអាចសម្គាល់ <xliff:g id="FINGERPRINT">%s</xliff:g> បានទៀតហើយ។ សូមរៀបចំការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃម្ដងទៀត។"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"លែងអាចសម្គាល់ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> និង <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> បានទៀតហើយ។ សូមរៀបចំការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃម្ដងទៀត។"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"រៀបចំ​ការដោះ​សោ​ដោយស្កេន​មុខម្ដងទៀត"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"គំរូមុខរបស់អ្នកមិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ។ រៀបចំវាម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នកដោយប្រើមុខ។"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"លែងអាចសម្គាល់គំរូមុខរបស់អ្នកបានទៀតហើយ។ សូមរៀបចំ​ការដោះ​សោ​ដោយស្កេន​មុខម្ដងទៀត។"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"រៀបចំ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"កុំទាន់"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"ម៉ោងរោទ៍សម្រាប់ <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ប្ដូរអ្នកប្រើប្រាស់"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"បិទសំឡេង"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ចុចដើម្បីបិទសំឡេង"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 9131b5ae6bd1..413a35a92c48 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ಸ್ವಯಂ ಪರೀಕ್ಷೆಯಾಗುವಿಕೆ ಮೋಡ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ಸ್ವಯಂ ಪರೀಕ್ಷೆಯಾಗುವಿಕೆ ಮೋಡ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಫ್ಯಾಕ್ಟರಿ ರಿಸೆಟ್ ಮಾಡಬೇಕು."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM ಬಿಲ್ಡ್ ಕಾನ್ಫಿಗರೇಶನ್ ತಪ್ಪಾಗಿದೆ"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"ಈ ಸಾಧನದ ಹೆಡ್‌ಲೆಸ್ ಸಿಸ್ಟಂ ಬಳಕೆದಾರ ಮೋಡ್ ಸ್ಥಿತಿಯು ಅದರ ಬಿಲ್ಡ್ ಕಾನ್ಫಿಗರೇಶನ್‌ಗಿಂತ ಭಿನ್ನವಾಗಿದೆ. ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ರೀಸೆಟ್ ಮಾಡಿ."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"ಸರಣಿ ಕನ್ಸೋಲ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"ಕಾರ್ಯಕ್ಷಮತೆಯ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ. ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು, ಬೂಟ್‌ಲೋಡರ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿ."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ಪ್ರಾಯೋಗಿಕ MTE ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದುಕೊಳ್ಳಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಲಾಗಿದೆ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಬಿಡುಗಡೆ ಮಾಡಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲು, ಎರಡೂ ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಮತ್ತೊಮ್ಮೆ 3 ಸೆಕೆಂಡ್‌ಗಳ ಕಾಲ ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"ಫೀಚರ್ ಆರಿಸಿ"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"ಫೀಚರ್ ಆರಿಸಿ"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"ಫೀಚರ್ ಆರಿಸಿ"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ಮುಂದಿನ ಬಾರಿ ನೀವು ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಬಟನ್ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿದಾಗ ಈ ಫೀಚರ್ ಆನ್‌ ಆಗುತ್ತದೆ"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ಮುಂದಿನ ಬಾರಿ ನೀವು ಈ ಶಾರ್ಟ್‌ಕಟ್ ಅನ್ನು ಬಳಸುವಾಗ ಈ ಫೀಚರ್ ಆನ್ ಆಗುತ್ತದೆ. ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಗಿನಿಂದ 2 ಬೆರಳುಗಳಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಹಾಗೂ ತ್ವರಿತವಾಗಿ ಬಿಡುಗಡೆ ಮಾಡಿ."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ಮುಂದಿನ ಬಾರಿ ನೀವು ಈ ಶಾರ್ಟ್‌ಕಟ್ ಅನ್ನು ಬಳಸುವಾಗ ಈ ಫೀಚರ್ ಆನ್ ಆಗುತ್ತದೆ. ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಗಿನಿಂದ 3 ಬೆರಳುಗಳಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಹಾಗೂ ತ್ವರಿತವಾಗಿ ಬಿಡುಗಡೆ ಮಾಡಿ."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ಹಿಗ್ಗಿಸುವಿಕೆ"</string>
<string name="user_switched" msgid="7249833311585228097">"ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರು <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ಗೆ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"ಪಿನ್‌ ತುಂಬಾ ಚಿಕ್ಕದಾಗಿದೆ. ಕನಿಷ್ಠ ಪಕ್ಷ 4 ಅಂಕಿಗಳಾಗಿರಬೇಕು."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"ಪೂರ್ಣ ಪರದೆಯನ್ನು ವೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"ನಿರ್ಗಮಿಸಲು, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲಿನಿಂದ ಕೆಳಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"ತಿಳಿಯಿತು"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ಅತ್ಯುತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ ತಿರುಗಿಸಿ"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"ಅತ್ಯುತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ <xliff:g id="NAME">%s</xliff:g> ಅನ್ನು ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ತೆರೆಯಿರಿ"</string>
@@ -2434,12 +2425,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ಇದು ಹೇಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ಬಾಕಿ ಉಳಿದಿದೆ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿರಲಿಲ್ಲ, ಹಾಗಾಗಿ ಅದನ್ನು ಅಳಿಸಲಾಗಿದೆ"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿರಲಿಲ್ಲ, ಹಾಗಾಗಿ ಅವುಗಳನ್ನು ಅಳಿಸಲಾಗಿದೆ"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ ಹಾಗೂ ಅದನ್ನು ಅಳಿಸಲಾಗಿದೆ. ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಮೂಲಕ ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಅದನ್ನು ಪುನಃ ಸೆಟಪ್‌ ಮಾಡಿ."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ ಹಾಗೂ ಅವುಗಳನ್ನು ಅಳಿಸಲಾಗಿದೆ. ನಿಮ್ಮ ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಮೂಲಕ ನಿಮ್ಮ ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಅವುಗಳನ್ನು ಪುನಃ ಸೆಟಪ್‌ ಮಾಡಿ."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ. ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ. ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ನಿಮ್ಮ ಫೇಸ್ ಮಾಡೆಲ್ ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ ಹಾಗೂ ಅದನ್ನು ಅಳಿಸಲಾಗಿದೆ. ಫೇಸ್ ಮೂಲಕ ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಅದನ್ನು ಪುನಃ ಸೆಟಪ್‌ ಮಾಡಿ."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"ನಿಮ್ಮ ಫೇಸ್ ಮಾಡೆಲ್ ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ. ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ಸೆಟಪ್ ಮಾಡಿ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ಈಗ ಬೇಡ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> ಗಾಗಿ ಅಲಾರಾಂ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ಧ್ವನಿಯನ್ನು ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"ಬ್ರೌಸರ್"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"ಸಂಪರ್ಕಗಳು"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"ಇಮೇಲ್"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"SMS"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"ಸಂಗೀತ"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"Calendar"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"ಕ್ಯಾಲ್ಕ್ಯುಲೇಟರ್"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Maps"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"ಆ್ಯಪ್‌ಗಳು"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 804957c7b5e8..e0d3fb7ae1d1 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1197,7 +1197,7 @@
<string name="low_internal_storage_view_title" msgid="9024241779284783414">"저장 공간이 부족함"</string>
<string name="low_internal_storage_view_text" msgid="8172166728369697835">"일부 시스템 기능이 작동하지 않을 수 있습니다."</string>
<string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"시스템의 저장 공간이 부족합니다. 250MB의 여유 공간이 확보한 후 다시 시작하세요."</string>
- <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g>이(가) 실행 중입니다."</string>
+ <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> 실행 중"</string>
<string name="app_running_notification_text" msgid="5120815883400228566">"자세한 내용을 보거나 앱을 중지하려면 탭하세요."</string>
<string name="ok" msgid="2646370155170753815">"확인"</string>
<string name="cancel" msgid="6908697720451760115">"취소"</string>
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"무선 디버깅을 사용 중지하려면 선택하세요."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"테스트 하네스 모드 사용 설정됨"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"테스트 하네스 모드를 사용 중지하려면 초기화하세요."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"잘못된 HSUM 빌드 구성"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"이 기기의 헤드리스 시스템 사용자 모드 상태가 빌드 구성과 다릅니다. 기기를 초기화하세요."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"시리얼 콘솔 사용 설정됨"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"성능에 영향을 미쳤습니다. 사용 중지하려면 부트로더를 확인하세요."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"실험용 MTE 사용 설정됨"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 설정되었습니다."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 중지되었습니다."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"볼륨 키에서 손을 뗍니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>을 켜려면 볼륨 키 2개를 3초 동안 길게 누르세요."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"기능을 선택합니다"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"기능을 선택합니다"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"기능을 선택합니다"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"다음번에 접근성 버튼을 탭할 때 이 기능이 열립니다."</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"다음번에 이 단축키를 사용할 때 이 기능이 열립니다. 화면 하단에서 손가락 두 개를 사용해 위로 스와이프했다가 빠르게 놓습니다."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"다음번에 이 단축키를 사용할 때 이 기능이 열립니다. 화면 하단에서 손가락 세 개를 사용해 위로 스와이프했다가 빠르게 놓습니다."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"확대"</string>
<string name="user_switched" msgid="7249833311585228097">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>로 전환하는 중…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN이 너무 짧습니다. 최소 4자 이상이어야 합니다."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"나중에 다시 시도"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"전체 화면 모드"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"종료하려면 화면 상단에서 아래로 스와이프합니다."</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"확인"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"카메라 미리보기 화면이 잘 보이도록 회전하세요."</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"화면이 더 잘 보이도록 <xliff:g id="NAME">%s</xliff:g>을(를) 전체 화면에서 여세요."</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"진행 중인 통화"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"수신 전화 검사 중"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"지정된 카테고리 없음"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"프로모션"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"소셜"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"뉴스"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"권장사항"</string>
<string name="importance_from_user" msgid="2782756722448800447">"이러한 알림의 중요도를 설정했습니다."</string>
<string name="importance_from_person" msgid="4235804979664465383">"관련된 사용자가 있으므로 중요합니다."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"맞춤 앱 알림"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"화면상의 접근성 바로가기 선택 도구"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"접근성 단축키"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"알림 창 닫기"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"메뉴"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"미디어 재생/일시중지"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"방향 패드 위쪽"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"방향 패드 아래"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"방향 패드 왼쪽"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"작동 방식"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"대기 중…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"지문 잠금 해제 다시 설정"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> 지문이 제대로 작동하지 않아 삭제되었습니다."</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> 및 <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> 지문이 제대로 작동하지 않아 삭제되었습니다."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g>이(가) 제대로 작동하지 않아 삭제되었습니다. 지문으로 휴대전화를 잠금 해제하려면 다시 설정하세요."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> 및 <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>이(가) 제대로 작동하지 않아 삭제되었습니다. 지문으로 휴대전화를 잠금 해제하려면 다시 설정하세요."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> 지문을 더 이상 인식할 수 없습니다."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> 및 <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> 지문을 더 이상 인식할 수 없습니다."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> 지문을 더 이상 인식할 수 없습니다. 지문 잠금 해제를 다시 설정하세요."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> 및 <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> 지문을 더 이상 인식할 수 없습니다. 지문 잠금 해제를 다시 설정하세요."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"얼굴 인식 잠금 해제 다시 설정"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"얼굴 모델이 제대로 작동하지 않아 삭제되었습니다. 얼굴로 휴대전화를 잠금 해제하려면 다시 설정하세요."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"얼굴 모델을 더 이상 인식할 수 없습니다. 얼굴 인식 잠금 해제를 다시 설정하세요."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"설정"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"나중에"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>님의 알람"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"사용자 전환"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"음소거"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"탭하여 소리 음소거"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index da709f75d820..e4c460381134 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоону өчүрүңүз."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Сыноо программасынын режими иштетилди"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Сыноо программасынын режимин өчүрүү үчүн баштапкы параметрлерге кайтарыңыз."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM курама конфигурациясы туура эмес"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Бул түзмөктөгү Консолдук системаны колдонуучу режиминин абалы курама конфигурациядан айырмаланып турат. Түзмөктү баштапкы абалга кайтарыңыз."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Сериялык консоль иштетилди"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Майнаптуулугуна таасири тиет. Өчүрүү үчүн операциялык тутумду жүктөгүчтү текшериңиз."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Cынамык MTE иштетилди"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> күйгүзүлдү."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өчүрүлдү."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Үн баскычтарын коё бериңиз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын күйгүзүү үчүн үн баскычтарын кайра 3 секунд коё бербей басып туруңуз."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Функция тандаңыз"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Функция тандаңыз"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Функция тандаңыз"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Эми функция атайын мүмкүнчүлүктөр баскычын басканыңызда ачылат"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Эми функция ушул ыкчам баскыч менен ачылат. Экранды 2 манжаңыз менен ылдыйдан өйдө карай сүрүп, тез коё бериңиз."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Эми функция ушул ыкчам баскыч менен ачылат. Экранды 3 манжаңыз менен ылдыйдан өйдө карай сүрүп, тез коё бериңиз."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Чоңойтуу"</string>
<string name="user_switched" msgid="7249833311585228097">"Учурдагы колдонуучу <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> дегенге которулууда…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN өтө кыска. Аз дегенде 4 сандан турушу керек."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Бир аздан кийин кайталап көрүңүз"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Толук экран режими"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Чыгуу үчүн экранды өйдө жагынан ылдый сүрүп коюңуз"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Түшүндүм"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Жакшыраак көрүү үчүн буруңуз"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Жакшыраак көрүү үчүн <xliff:g id="NAME">%s</xliff:g> колдонмосун толук экранда ачыңыз"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Учурдагы чалуу"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Кирүүчү чалууну иргөө"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Категорияларга бөлүнгөн эмес"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоакциялар"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Коомдук тармактар"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Жаңылыктар"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Cунуштар"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Бул эскертмелердин маанилүүлүгүн белгиледиңиз."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Булар сиз үчүн маанилүү адамдар."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Колдонмонун ыңгайлаштырылган билдирмеси"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ыкчам иштетүү менюсу"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Ыкчам иштетүү"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Билдирмелер тактасын жабуу"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Медиа файлды ойнотуу/тындыруу"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad\'дын жогорку баскычы"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad\'дын ылдыйкы баскычы"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad\'дын сол баскычы"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ал кантип иштейт"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Кезекте турат..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Манжа изи менен ачуу функциясын кайра тууралаңыз"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ойдогудай иштебегендиктен өчүрүлдү"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ойдогудай иштебегендиктен өчүрүлдү"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ойдогудай иштебегендиктен, жок кылынды. Телефондо Манжа изи менен ачуу функциясын колдонуу үчүн аны кайра тууралаңыз."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ойдогудай иштебегендиктен, жок кылынды. Телефонду манжа изи менен ачуу үчүн аларды кайра тууралаңыз."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> мындан ары таанылбайт."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> мындан ары таанылбайт."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> мындан ары таанылбайт. Манжа изи менен ачуу функциясын кайрадан тууралаңыз."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> мындан ары таанылбайт. Манжа изи менен ачуу функциясын кайрадан тууралаңыз."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Жүзүнөн таанып ачуу функциясын кайрадан тууралаңыз"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Жүзүңүздүн үлгүсү ойдогудай иштебегендиктен, жок кылынды. Телефондо Жүзүнөн таанып ачуу функциясын колдонуу үчүн аны кайра тууралаңыз."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Жүзүңүздүн үлгүсү мындан ары таанылбайт. Жүзүнөн таанып ачуу функциясын кайрадан тууралаңыз."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Тууралоо"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Азыр эмес"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> үчүн ойготкуч"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Колдонуучуну которуштуруу"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Үнүн басуу"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Үнүн басуу үчүн таптап коюңуз"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 0ee3d5063915..ef5e51dc6dc5 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ເລືອກເພື່ອປິດການນຳໃຊ້ການດີບັກໄຮ້ສາຍ."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ເປີດໃຊ້ໂໝດ Test Harness ແລ້ວ"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ດຳເນີນການຣີເຊັດເປັນຄ່າຈາກໂຮງງານເພື່ອປິດການນຳໃຊ້ໂໝດ Test Harness."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"ການຕັ້ງຄ່າ build ຂອງ HSUM ບໍ່ຖືກຕ້ອງ"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"ສະຖານະໂໝດຜູ້ໃຊ້ລະບົບແບບບໍ່ມີສ່ວນຫົວຂອງອຸປະກອນນີ້ແຕກຕ່າງຈາກການຕັ້ງຄ່າ build. ກະລຸນາຣີເຊັດອຸປະກອນເປັນຄ່າຈາກໂຮງງານ."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"ເປີດນຳໃຊ້ຊີຣຽວຄອນໂຊແລ້ວ"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"ມີຜົນກະທົບກັບປະສິດທິພາບ. ເພື່ອປິດການນຳໃຊ້, ໃຫ້ກວດສອບ bootloader ເບິ່ງ."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ເປີດການນຳໃຊ້ MTE ແບບທົດລອງແລ້ວ"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ເປີດໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ແລ້ວ."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ປິດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ໄວ້ແລ້ວ."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ປ່ອຍປຸ່ມລະດັບສຽງ. ເພື່ອເປີດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ໃຫ້ກົດປຸ່ມລະດັບສຽງທັງສອງຄ້າງໄວ້ 3 ວິນາທີ."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"ເລືອກຄຸນສົມບັດ"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"ເລືອກຄຸນສົມບັດ"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"ເລືອກຄຸນສົມບັດ"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ຄຸນສົມບັດນີ້ຈະເປີດຂຶ້ນໃນເທື່ອຕໍ່ໄປທີ່ທ່ານແຕະປຸ່ມການຊ່ວຍເຂົ້າເຖິງ"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ຄຸນສົມບັດນີ້ຈະເປີດຂຶ້ນໃນເທື່ອຕໍ່ໄປທີ່ທ່ານໃຊ້ທາງລັດນີ້. ໃຊ້ 2 ນິ້ວປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍຂອງທ່ານແລ້ວປ່ອຍແບບໄວໆ."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ຄຸນສົມບັດນີ້ຈະເປີດຂຶ້ນໃນເທື່ອຕໍ່ໄປທີ່ທ່ານໃຊ້ທາງລັດນີ້. ໃຊ້ 3 ນິ້ວປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍຂອງທ່ານແລ້ວປ່ອຍແບບໄວໆ."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ການຂະຫຍາຍ"</string>
<string name="user_switched" msgid="7249833311585228097">"ຜູ່ໃຊ້ປັດຈຸບັນ <xliff:g id="NAME">%1$s</xliff:g> ."</string>
<string name="user_switching_message" msgid="1912993630661332336">"ກຳລັງສະຫຼັບໄປຫາ<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN ​ສັ້ນ​ເກີນ​ໄປ​. ຕ້ອງມີຢ່າງໜ້ອຍ 4 ຫຼັກ​."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"ລອງໃໝ່ອີກຄັ້ງໃນພາຍຫລັງ."</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"ການ​ເບິ່ງ​ເຕັມ​ໜ້າ​ຈໍ"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"ເພື່ອອອກ, ໃຫ້ປັດລົງຈາກເທິງສຸດຂອງໜ້າຈໍຂອງທ່ານ"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"ເຂົ້າ​ໃຈ​ແລ້ວ"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ໝຸນເພື່ອມຸມມອງທີ່ດີຂຶ້ນ"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"ເປີດ <xliff:g id="NAME">%s</xliff:g> ໃນໂໝດເຕັມຈໍເພື່ອມຸມມອງທີ່ດີຂຶ້ນ"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ມັນເຮັດວຽກແນວໃດ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ລໍຖ້າດຳເນີນການ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍລາຍນິ້ວມືຄືນໃໝ່"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ແລະ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ. ໃຫ້ຕັ້ງຄ່າມັນຄືນໃໝ່ເພື່ອປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍລາຍນິ້ວມື."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ແລະ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ. ໃຫ້ຕັ້ງຄ່າພວກມັນຄືນໃໝ່ເພື່ອປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍລາຍນິ້ວມື."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"ບໍ່ສາມາດຈຳແນກ <xliff:g id="FINGERPRINT">%s</xliff:g> ໄດ້ອີກຕໍ່ໄປ."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"ບໍ່ສາມາດຈຳແນກ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ແລະ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ໄດ້ອີກຕໍ່ໄປ."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"ບໍ່ສາມາດຈຳແນກ <xliff:g id="FINGERPRINT">%s</xliff:g> ໄດ້ອີກຕໍ່ໄປ. ກະລຸນາຕັ້ງຄ່າການປົດລັອກດ້ວຍລາຍນິ້ວມືອີກຄັ້ງ."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"ບໍ່ສາມາດຈຳແນກ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ແລະ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ໄດ້ອີກຕໍ່ໄປ. ກະລຸນາຕັ້ງຄ່າການປົດລັອກດ້ວຍລາຍນິ້ວມືອີກຄັ້ງ."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍໜ້າຄືນໃໝ່"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ຮູບແບບໃບໜ້າຂອງທ່ານເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ. ໃຫ້ຕັ້ງຄ່າມັນຄືນໃໝ່ເພື່ອປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍໃບໜ້າ."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"ບໍ່ສາມາດຈຳແນກຮູບແບບໃບໜ້າຂອງທ່ານໄດ້ອີກຕໍ່ໄປ. ກະລຸນາຕັ້ງຄ່າການປົດລັອກດ້ວຍໜ້າອີກຄັ້ງ."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ຕັ້ງຄ່າ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ບໍ່ຟ້າວເທື່ອ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"ໂມງປຸກສຳລັບ <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ສະຫຼັບຜູ້ໃຊ້"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ປິດສຽງ"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ແຕະເພື່ອປິດສຽງ"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 43a619de3672..e2d59fd81d12 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1413,10 +1413,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Pasirinkite, kad išjungtumėte belaidžio ryšio derinimą."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testavimo sistemos režimas įgalintas"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Atkurkite gamyklinius duomenis, kad išjungtumėte testavimo sistemos režimą."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Netinkama sistemos be grafinės naudotojo sąsajos naudotojo režimo kompiliavimo konfigūracija"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Šio įrenginio sistemos be grafinės naudotojo sąsajos naudotojo režimo būsena skiriasi nuo jo kompiliavimo konfigūracijos. Atkurkite gamyklinius įrenginio nustatymus."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serijos pultas įgalintas"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Našumas paveiktas. Norėdami išjungti, patikrinkite paleidyklę."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentiniai atminties žymėjimo plėtiniai (angl. „Memory Tagging Extensions“, MTE) įgalinti"</string>
@@ -1761,18 +1759,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ įjungta."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ išjungta."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Atleiskite garsumo klavišus. Kad įjungtumėte „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“, paspauskite ir 3 sekundes palaikykite garsumo klavišus."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Pasirinkite funkciją"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Pasirinkite funkciją"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Pasirinkite funkciją"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcija bus atidaryta kitą kartą, kai paliesite pritaikomumo mygtuką"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija bus atidaryta kitą kartą, kai naudosite šį spartųjį klavišą. Perbraukite dviem pirštais aukštyn nuo ekrano apačios ir greitai atleiskite."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija bus atidaryta kitą kartą, kai naudosite šį spartųjį klavišą. Perbraukite trimis pirštais aukštyn nuo ekrano apačios ir greitai atleiskite."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Didinimas"</string>
<string name="user_switched" msgid="7249833311585228097">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Perjungiama į <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1895,8 +1887,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN kodas per trumpas. Jis turi būti bent 4 skaitmenų."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Vėliau bandykite dar kartą"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Peržiūrima viso ekrano režimu"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Jei norite išeiti, perbraukite žemyn nuo ekrano viršaus"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Supratau"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Pasukite, kad geriau matytumėte vaizdą"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Atidarykite „<xliff:g id="NAME">%s</xliff:g>“ viso ekrano režimu, kad geriau matytumėte vaizdą"</string>
@@ -2436,12 +2427,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kaip tai veikia"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Laukiama..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Atrakinimo piršto atspaudu nustatymas dar kartą"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> neveikė tinkamai ir buvo ištrintas"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ir <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> neveikė tinkamai ir buvo ištrinti"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> neveikė tinkamai ir buvo ištrintas. Nustatykite jį dar kartą, kad atrakintumėte telefoną piršto atspaudu."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ir <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> neveikė tinkamai ir buvo ištrinti. Nustatykite juos dar kartą, kad atrakintumėte telefoną piršto atspaudu."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> nebegalima atpažinti."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ir <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nebegalima atpažinti."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> nebegalima atpažinti. Dar kartą nustatykite atrakinimą piršto atspaudu."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ir <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nebegalima atpažinti. Dar kartą nustatykite atrakinimą piršto atspaudu."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Atrakinimo pagal veidą nustatymas iš naujo"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Jūsų veido modelis neveikė tinkamai ir buvo ištrintas. Nustatykite jį dar kartą, kad atrakintumėte telefoną pagal veidą."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Jūsų veido modelio nebegalima atpažinti. Iš naujo nustatykite atrakinimą pagal veidą."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nustatyti"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne dabar"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Signalas: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Perjungti naudotoją"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Nutildyti"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Palieskite, kad nutildytumėte garsą"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 8481d988447b..42fb763bda65 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1766,12 +1766,9 @@
<skip />
<!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
<skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcija tiks atvērta, kad nākamreiz pieskarsieties pieejamības pogai."</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija tiks atvērta, kad nākamreiz izmantosiet šo saīsni. Velciet augšup ar diviem pirkstiem no ekrāna apakšdaļas un ātri atlaidiet."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija tiks atvērta, kad nākamreiz izmantosiet šo saīsni. Velciet augšup ar trim pirkstiem no ekrāna apakšdaļas un ātri atlaidiet."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Palielinājums"</string>
<string name="user_switched" msgid="7249833311585228097">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Notiek pāriešana uz: <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -2435,12 +2432,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Darbības principi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Gaida…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vēlreiz iestatiet autorizāciju ar pirksta nospiedumu"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nedarbojās pareizi un tika izdzēsts"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nedarbojās pareizi un tika izdzēsti"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nedarbojās pareizi un tika izdzēsts. Iestatiet to atkal, lai varētu atbloķēt tālruni ar pirksta nospiedumu."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nedarbojās pareizi un tika izdzēsti. Iestatiet tos atkal, lai varētu atbloķētu tālruni ar pirksta nospiedumu."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Pirksta nospiedumu (<xliff:g id="FINGERPRINT">%s</xliff:g>) vairs nevar atpazīt."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Pirkstu nospiedumus (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) vairs nevar atpazīt."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Pirksta nospiedumu (<xliff:g id="FINGERPRINT">%s</xliff:g>) vairs nevar atpazīt. Vēlreiz iestatiet autorizāciju ar pirksta nospiedumu."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Pirkstu nospiedumus (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) vairs nevar atpazīt. Vēlreiz iestatiet autorizāciju ar pirksta nospiedumu."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Vēlreiz iestatiet autorizāciju pēc sejas"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Jūsu sejas modelis nedarbojās pareizi un tika izdzēsts. Iestatiet to atkal, lai varētu atbloķēt tālruni ar seju."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Jūsu sejas modeli vairs nevar atpazīt. Vēlreiz iestatiet autorizāciju pēc sejas."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Iestatīt"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne tagad"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Signāls lietotājam <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Mainīt lietotāju"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Izslēgt skaņu"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Pieskarieties, lai izslēgtu skaņu"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 1311690f3701..b3b3e37cf2b5 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1242,7 +1242,7 @@
<string name="alwaysUse" msgid="3153558199076112903">"Користи ја стандардно за ова дејство."</string>
<string name="use_a_different_app" msgid="4987790276170972776">"Користи различна апликација"</string>
<string name="clearDefaultHintMsg" msgid="1325866337702524936">"Избриши ги стандардните вредности во Системски поставки &gt; Апликации &gt; Преземено."</string>
- <string name="chooseActivity" msgid="8563390197659779956">"Избери дејство"</string>
+ <string name="chooseActivity" msgid="8563390197659779956">"Изберете дејство"</string>
<string name="chooseUsbActivity" msgid="2096269989990986612">"Изберете апликација за USB-уредот"</string>
<string name="noApplications" msgid="1186909265235544019">"Нема апликации што можат да го извршат ова дејство."</string>
<string name="aerr_application" msgid="4090916809370389109">"<xliff:g id="APPLICATION">%1$s</xliff:g> запре"</string>
@@ -1310,7 +1310,7 @@
<string name="dump_heap_text" msgid="1692649033835719336">"Процесот <xliff:g id="PROC">%1$s</xliff:g> го надмина ограничувањето за меморија од <xliff:g id="SIZE">%2$s</xliff:g>. Слика од меморијата ви е достапна за споделување со програмерот. Бидете внимателни: оваа слика од меморијата може да ги содржи сите лични информации до коишто апликацијата има пристап."</string>
<string name="dump_heap_system_text" msgid="6805155514925350849">"Процесот <xliff:g id="PROC">%1$s</xliff:g> го надмина ограничувањето за меморија од <xliff:g id="SIZE">%2$s</xliff:g>. Слика од меморијата ви е достапна за споделување. Бидете внимателни: оваа слика од меморијата може да содржи чувствителни лични информации до коишто процесот има пристап, што може да вклучуваат работи што сте ги напишале."</string>
<string name="dump_heap_ready_text" msgid="5849618132123045516">"Слика од меморијата на <xliff:g id="PROC">%1$s</xliff:g> ви е достапна за споделување. Бидете внимателни: оваа слика од меморијата можеби ги содржи сите чувствителни лични информации до коишто процесот има пристап, што може да вклучуваат работи што сте ги напишале."</string>
- <string name="sendText" msgid="493003724401350724">"Избери дејство за текст"</string>
+ <string name="sendText" msgid="493003724401350724">"Изберете дејство за текст"</string>
<string name="volume_ringtone" msgid="134784084629229029">"Јачина на звук на ѕвонче"</string>
<string name="volume_music" msgid="7727274216734955095">"Јачина на звук за аудио/видео"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Се репродуцира преку Bluetooth"</string>
@@ -1765,12 +1765,9 @@
<skip />
<!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
<skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функцијата ќе се отвори следниот пат кога ќе го допрете копчето за пристапност"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функцијата ќе се отвори следниот пат кога ќе ја користите кратенкава. Повлечете нагоре со 2 прста од долниот дел на екранот и брзо отпуштете."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функцијата ќе се отвори следниот пат кога ќе ја користите кратенкава. Повлечете нагоре со 3 прста од долниот дел на екранот и брзо отпуштете."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Зголемување"</string>
<string name="user_switched" msgid="7249833311585228097">"Тековен корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Се префрла на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1986,14 +1983,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Тековен повик"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Проверка на дојдовен повик"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Некатегоризирано"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоции"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Друштвени"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Вести"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Препораки"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ја поставивте важноста на известувањава."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ова е важно заради луѓето кои се вклучени."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Приспособено известување за апликација"</string>
@@ -2210,10 +2203,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Избирач на кратенка за пристапност на екранот"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Кратенка за пристапност"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Отфрлете го панелот за известување"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Мени"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Пушти/паузирај аудиовизуелни содржини"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Навигациско копче за нагоре"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Навигациско копче за надолу"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Навигациско копче за налево"</string>
@@ -2440,12 +2431,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Дознајте како функционира"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Во фаза на чекање…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поставете „Отклучување со отпечаток“ повторно"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> не функционираше добро, па се избриша"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> не функционираа добро, па се избришаа"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> не функционираше добро, па се избриша. Поставете го повторно за да го отклучувате телефонот со отпечаток."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> не функционираа добро, па се избришаа. Поставете ги повторно за да го отклучувате телефонот со отпечаток."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> веќе не може да се препознае."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> веќе не може да се препознаат."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> веќе не може да се препознае. Поставете „Отклучување со отпечаток“ повторно."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> веќе не може да се препознаат. Поставете „Отклучување со отпечаток“ повторно."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Поставете „Отклучување со лик“ повторно"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Вашиот модел на лик не функционираше добро, па се избриша. Поставете го повторно за да го отклучите телефонот со лик."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Вашиот модел на лик веќе не може да се препознае. Поставете „Отклучување со лик“ повторно."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Поставете"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сега"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Аларм за <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Сменете го корисникот"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Исклучи звук"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Допрете за да го исклучите звукот"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index c856ec80017a..f9a74e79750c 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"വയർലെസ് ഡീബഗ്ഗിംഗ് പ്രവർത്തനരഹിതമാക്കാൻ തിരഞ്ഞെടുക്കുക."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"പരിശോധനാ സംവിധാനങ്ങൾ മോഡ് പ്രവർത്തനക്ഷമമാക്കി"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"പരിശോധനാ സംവിധാന മോഡ് പ്രവർത്തനരഹിതമാക്കാൻ ഫാക്‌ടറി പുനഃക്രമീകരണം നിർവഹിക്കുക."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM ബിൽഡ് കോൺഫിഗറേഷൻ തെറ്റാണ്"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"ഈ ഉപകരണത്തിന്റെ ഹെഡ്‌ലെസ് സിസ്റ്റം യൂസർ മോഡ് നില ഇതിന്റെ ബിൽഡ് കോൺഫിഗറേഷനിൽ നിന്ന് വ്യത്യസ്തമാണ്. ഉപകരണം ഫാക്‌ടറി റീസെറ്റ് ചെയ്യുക."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"സീരിയൽ കൺസോൾ പ്രവർത്തനക്ഷമമാക്കി"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"പ്രകടനത്തെ ബാധിച്ചു. പ്രവർത്തനരഹിതമാക്കാൻ, ബൂട്ട് ലോഡർ പരിശോധിക്കുക."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"പരീക്ഷണാത്മക MTE പ്രവർത്തനക്ഷമമാക്കി"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"വോളിയം കീകൾ പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കി."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"വോളിയം കീകൾ അമർത്തിപ്പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫാക്കി."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"വോളിയം കീകൾ വിടുക. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കാൻ, രണ്ട് വോളിയം കീകളും വീണ്ടും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"അടുത്ത തവണ നിങ്ങൾ ഉപയോഗസഹായി ബട്ടൺ ടാപ്പ് ചെയ്യുമ്പോൾ ഫീച്ചർ തുറക്കും"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"അടുത്ത തവണ നിങ്ങൾ ഈ കുറുക്കുവഴി ഉപയോഗിക്കുമ്പോൾ ഫീച്ചർ തുറക്കും. നിങ്ങളുടെ സ്ക്രീനിന്റെ താഴെ നിന്ന് 2 വിരലുകൾ ഉപയോഗിച്ച് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്‌ത് പെട്ടെന്ന് വിടുക."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"അടുത്ത തവണ നിങ്ങൾ ഈ കുറുക്കുവഴി ഉപയോഗിക്കുമ്പോൾ ഫീച്ചർ തുറക്കും. നിങ്ങളുടെ സ്ക്രീനിന്റെ താഴെ നിന്ന് 3 വിരലുകൾ ഉപയോഗിച്ച് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്‌ത് പെട്ടെന്ന് വിടുക."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"മാഗ്നിഫിക്കേഷൻ"</string>
<string name="user_switched" msgid="7249833311585228097">"നിലവിലെ ഉപയോക്താവ് <xliff:g id="NAME">%1$s</xliff:g> ആണ്."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിലേക്ക് മാറുന്നു…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"പിൻ തീരെ ചെറുതാണ്. 4 അക്കമെങ്കിലും ഉണ്ടായിരിക്കണം."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"പിന്നീട് വീണ്ടും ശ്രമിക്കുക"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"പൂർണ്ണ സ്‌ക്രീനിൽ കാണുന്നു"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"പുറത്ത് കടക്കാൻ, സ്‌ക്രീനിന്റെ മുകളിൽ നിന്ന് താഴോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"മനസ്സിലായി"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"മികച്ച കാഴ്‌ചയ്‌ക്കായി റൊട്ടേറ്റ് ചെയ്യുക"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"മികച്ച കാഴ്‌‌ചയ്ക്ക് പൂർണ്ണ സ്‌ക്രീനിൽ <xliff:g id="NAME">%s</xliff:g> തുറക്കുക"</string>
@@ -2427,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"സ്വകാര്യ സ്പേസ്"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട അറിയിപ്പ് ഉള്ളടക്കം മറച്ചിരിക്കുന്നു"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ആപ്പ് ഉള്ളടക്കം, അതിന്റെ സുരക്ഷയ്ക്കായി സ്ക്രീൻ പങ്കിടലിൽ നിന്ന് മറച്ചിരിക്കുന്നു"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"സുരക്ഷയ്ക്കായി സ്ക്രീൻ പങ്കിടലിൽ നിന്ന് ആപ്പ് ഉള്ളടക്കം മറച്ചിരിക്കുന്നു"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"സാറ്റലൈറ്റിലേക്ക് സ്വയമേവ കണക്റ്റ് ചെയ്തു"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"മൊബൈലോ വൈഫൈ നെറ്റ്‌വർക്കോ ഇല്ലാതെ തന്നെ സന്ദേശങ്ങൾ അയയ്‌ക്കാനും സ്വീകരിക്കാനും നിങ്ങൾക്ക് കഴിയും"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages തുറക്കുക"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ഇത് പ്രവർത്തിക്കുന്നത് എങ്ങനെയാണ്"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"തീർപ്പാക്കിയിട്ടില്ല..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അത് ഇല്ലാതാക്കി"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> എന്നിവ ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അവ ഇല്ലാതാക്കി"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അത് ഇല്ലാതാക്കി. നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യുന്നതിനായി വീണ്ടും സജ്ജീകരിക്കുക."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> എന്നിവ ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അവ ഇല്ലാതാക്കി. നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യുന്നതിനായി അവ വീണ്ടും സജ്ജീകരിക്കുക."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ഇനി തിരിച്ചറിയാനാകില്ല."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> എന്നിവ ഇനി തിരിച്ചറിയാനാകില്ല."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ഇനി തിരിച്ചറിയാനാകില്ല. ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> എന്നിവ ഇനി തിരിച്ചറിയാനാകില്ല. ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ഫെയ്‌സ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"നിങ്ങളുടെ മുഖ മോഡൽ ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അത് ഇല്ലാതാക്കി. നിങ്ങളുടെ മുഖം ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യുന്നതിനായി വീണ്ടും സജ്ജീകരിക്കുക."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"നിങ്ങളുടെ മുഖ മോഡൽ ഇനി തിരിച്ചറിയാനാകില്ല. ഫെയ്‌സ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"സജ്ജീകരിക്കുക"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ഇപ്പോൾ വേണ്ട"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> എന്നയാൾക്കുള്ള അലാറം"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ഉപയോക്താവിനെ മാറുക"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"മ്യൂട്ടുചെയ്യുക"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ശബ്ദം മ്യൂട്ട് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 1dbbe990ac5f..dc92f63c30d4 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Wireless debugging-г идэвхгүй болгохын тулд сонгоно уу."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Туршилтын цогц горимыг идэвхжүүлсэн"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Туршилтын цогц горимыг идэвхгүй болгохын тулд үйлдвэрийн төлөвт шинэчилнэ үү."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM-н хийцийн тохируулга буруу байна"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Энэ төхөөрөмжийн Интерфейсгүй системийн хэрэглэгчийн горимын төлөв хийцийн тохируулгаас нь өөр байна. Төхөөрөмжийг үйлдвэрийн тохиргоонд шинэчилнэ үү."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Цуваа консолыг идэвхжүүлсэн"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Гүйцэтгэлд нөлөөлнө. Идэвхгүй болгохын тулд эхэлж ачаалагчийг шалгана уу."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Туршилтын MTE-г идэвхжүүлсэн"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаалаа."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г унтраалаа."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Дууны түвшний товчнуудыг суллана уу. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаахын тулд дууны түвшний 2 товчийг зэрэг 3 секундийн турш удаан дарна уу."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Онцлог сонгоно уу"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Онцлог сонгоно уу"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Онцлог сонгоно уу"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Таныг дараагийн удаа хандалтын товчийг товших үед тус онцлог нээгдэнэ"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Таныг дараагийн удаа энэ товчлолыг ашиглах үед тус онцлог нээгдэнэ. Дэлгэцийнхээ доод талаас 2 хуруугаараа дээш шудраад, түргэн суллана уу."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Таныг дараагийн удаа энэ товчлолыг ашиглах үед тус онцлог нээгдэнэ. Дэлгэцийнхээ доод талаас 3 хуруугаараа дээш шудраад, түргэн суллана уу."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Томруулах"</string>
<string name="user_switched" msgid="7249833311585228097">"Одоогийн хэрэглэгч <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> руу сэлгэж байна…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"ПИН хэт богино байна. Хамгийн багадаа 4 цифртэй байх ёстой."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Дараа дахин оролдоно уу"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Бүтэн дэлгэцээр үзэж байна"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Гарахын тулд дэлгэцийнхээ дээд талаас доош шударна уу"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Ойлголоо"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Харагдах байдлыг сайжруулах бол эргүүлнэ үү"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Харагдах байдлыг сайжруулах бол <xliff:g id="NAME">%s</xliff:g>-г бүтэн дэлгэцээр нээнэ үү"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Дуудлага хийгдэж байна"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Ирсэн дуудлагыг харуулж байна"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Ангилаагүй"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Урамшуулал"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Сошиал"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Мэдээ"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Зөвлөмж"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Та эдгээр мэдэгдлийн ач холбогдлыг тогтоосон."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Оролцсон хүмүүсээс шалтгаалан энэ нь өндөр ач холбогдолтой."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Аппын захиалгат мэдэгдэл"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Дэлгэц дээрх хандалтын товчлол сонгогч"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Хандалтын товчлол"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Мэдэгдлийн хураангуй самбарыг хаах"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Цэс"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Медиаг тоглуулах/түр зогсоох"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad дээш"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad доош"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad зүүн"</string>
@@ -2433,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Хаалттай орон зай"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Эмзэг мэдэгдлийн контентыг нуусан"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Аюулгүй байдлын улмаас аппын контентыг дэлгэц хуваалцахаас нуусан"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Аюулгүй байдлын үүднээс аппын контентыг дэлгэц хуваалцахаас нуусан"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Хиймэл дагуулд автоматаар холбогдсон"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Та мобайл эсвэл Wi-Fi сүлжээгүйгээр мессеж илгээх болон хүлээн авах боломжтой"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Мессежийг нээх"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Энэ хэрхэн ажилладаг вэ?"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Хүлээгдэж буй..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Хурууны хээгээр түгжээ тайлахыг дахин тохируулна уу"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> сайн ажиллахгүй байсан тул хурууны хээг устгасан"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> болон <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> сайн ажиллахгүй байсан тул эдгээр хурууны хээг устгасан"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> сайн ажиллахгүй байсан тул үүнийг устгасан. Утасныхаа түгжээг хурууны хээгээр тайлахын тулд хурууны хээг дахин тохируулна уу."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> сайн ажиллахгүй байсан тул эдгээрийг устгасан. Утасныхаа түгжээг хурууныхаа хээгээр тайлахын тулд хоёр хурууны хээг дахин тохируулна уу."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>-г цаашид таних боломжгүй."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> болон <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-г цаашид таних боломжгүй."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>-г цаашид таних боломжгүй. Хурууны хээгээр түгжээ тайлахыг дахин тохируулна уу."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> болон <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-г цаашид таних боломжгүй. Хурууны хээгээр түгжээ тайлахыг дахин тохируулна уу."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Царайгаар түгжээ тайлахыг дахин тохируулна уу"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Таны нүүрний загвар сайн ажиллахгүй байсан бөгөөд үүнийг устгасан. Утасныхаа түгжээг царайгаар тайлахын тулд нүүрний загварыг дахин тохируулна уу."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Таны нүүрний загварыг цаашид таних боломжгүй. Царайгаар түгжээ тайлахыг дахин тохируулна уу."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Тохируулах"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Одоо биш"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>-н сэрүүлэг"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Хэрэглэгч сэлгэх"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Дууг хаах"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Дууг хаахын тулд товшино уу"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 3525c62e0418..3874200418c6 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"वायरलेस डीबगिंग बंद करण्यासाठी निवडा."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"टेस्ट हार्नेस मोड सुरू केला आहे"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"टेस्ट हार्नेस मोड बंद करण्यासाठी फॅक्टरी रीसेट करा."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM च्या बिल्डचे कॉन्फिगरेशन चुकीचे आहे"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"या डिव्हाइसची हेडलेस सिस्टीम वापरकर्ता मोड स्थिती ही बिल्डच्या कॉंफिगरेशनपेक्षा वेगळी आहे. कृपया डिव्हाइस फॅक्टरी रीसेट करा."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"सिरीअल कन्सोल सुरू केला आहे"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"परफॉर्मन्सवर परिणाम होतो. बंद करण्यासाठी, बूटलोडर तपासा."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"प्रायोगिक MTE सुरू केले आहे"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू केला आहे."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केले आहे."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"व्हॉल्यूम की रिलीझ करा. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू करण्यासाठी, दोन्ही व्हॉल्यूम की पुन्हा प्रेस करा आणि तीन सेकंदांसाठी धरून ठेवा."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"वैशिष्‍ट्य निवडा"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"वैशिष्‍ट्य निवडा"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"वैशिष्‍ट्य निवडा"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"तुम्ही पुढील वेळी अ‍ॅक्सेसिबिलिटी बटणावर टॅप कराल, तेव्हा वैशिष्ट्य उघडेल"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"तुम्ही पुढील वेळी हा शॉर्टकट वापराल, तेव्हा वैशिष्ट्य उघडेल. २ बोटांनी तुमच्या स्क्रीनच्या तळापासून वर स्वाइप करा आणि पटकन रिलीझ करा."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"तुम्ही पुढील वेळी हा शॉर्टकट वापराल, तेव्हा वैशिष्ट्य उघडेल. ३ बोटांनी तुमच्या स्क्रीनच्या तळापासून वर स्वाइप करा आणि पटकन रिलीझ करा."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"मॅग्निफिकेशन"</string>
<string name="user_switched" msgid="7249833311585228097">"वर्तमान वापरकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> वर स्विच करत आहे…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"पिन खूप लहान आहे. किमान 4 अंकांचा असणे आवश्‍यक आहे."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"नंतर पुन्हा प्रयत्न करा"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"पूर्ण स्क्रीनवर पाहत आहात"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"बाहेर पडण्यासाठी, तुमच्या स्क्रीनच्या सर्वात वरून खाली स्वाइप करा"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"समजले"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"अधिक चांगल्या दृश्यासाठी फिरवा"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"अधिक चांगल्या दृश्यासाठी <xliff:g id="NAME">%s</xliff:g> हे फुल स्क्रीनमध्ये उघडा"</string>
@@ -2434,12 +2425,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ते कसे काम करते"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"प्रलंबित आहे..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फिंगरप्रिंट अनलॉक पुन्हा सेट करा"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> योग्यरीत्या काम करत नव्हती, त्यामुळे ती हटवली आहे"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> आणि <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> योग्यरीत्या काम करत नव्हत्या, त्यामुळे त्या हटवल्या आहेत"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"योग्यरीत्या काम करत नसल्यामुळे <xliff:g id="FINGERPRINT">%s</xliff:g> हटवले गेले आहे. तुमचे फिंगरप्रिंट वापरून फोन अनलॉक करण्यासाठी ते पुन्हा सेट करा."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"परफॉर्मन्समध्ये सुधारणा करण्यासाठी आणि योग्यरीत्या काम करत नसल्यामुळे <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> व <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> हटवली गेली आहेत. तुमचे फिंगरप्रिंट वापरून फोन अनलॉक करण्यासाठी ते पुन्हा सेट करा."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> यापुढे ओळखता येणार नाही."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> आणि <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> यापुढे ओळखता येणार नाहीत."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> यापुढे ओळखता येणार नाही. फिंगरप्रिंट अनलॉक पुन्हा सेट करा."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> आणि <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> यापुढे ओळखता येणार नाहीत. फिंगरप्रिंट अनलॉक पुन्हा सेट करा."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"फेस अनलॉक पुन्हा सेट करा"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"तुमचे फेस मॉडेल योग्यरीत्या काम करत नसल्यामुळे ते हटवले गेले आहे. तुमचा चेहरा वापरून फोन अनलॉक करण्यासाठी ते पुन्हा सेट करा."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"तुमचे फेस मॉडेल यापुढे ओळखता येणार नाही. फेस अनलॉक पुन्हा सेट करा."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेट करा"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"आताच नको"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> साठी अलार्म"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"वापरकर्ता स्विच करा"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"म्यूट करा"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"आवाज म्यूट करण्यासाठी टॅप करा"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"ब्राउझर"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"Contacts"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"ईमेल"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"एसएमएस"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"संगीत"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"Calendar"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"Calculator"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Maps"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"अ‍ॅप्लिकेशन"</string>
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index d03babb24840..cc866b9049b0 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Pilih untuk melumpuhkan penyahpepijatan wayarles."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mod Abah-abah Ujian didayakan"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Laksanakan tetapan semula kilang untuk melumpuhkan Mod Abah-abah Ujian."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Konfigurasi binaan HSUM salah"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Keadaan Mod Pengguna Sistem Tanpa Kepala peranti ini berbeza daripada konfigurasi binaan peranti. Tetapkan semula peranti kepada tetapan kilang."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Konsol bersiri didayakan"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Prestasi terjejas. Untuk melumpuhkan, semak pemuat but."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Percubaan MTE didayakan"</string>
@@ -1440,7 +1438,7 @@
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Paparkan di atas apl lain"</string>
<string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> dipaparkan di atas apl lain"</string>
<string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> dipaparkan di atas apl lain"</string>
- <string name="alert_windows_notification_message" msgid="6538171456970725333">"Jika anda tidak mahu <xliff:g id="NAME">%s</xliff:g> menggunakan ciri ini, ketik untuk membuka tetapan dan matikannya."</string>
+ <string name="alert_windows_notification_message" msgid="6538171456970725333">"Jika anda tidak mahu <xliff:g id="NAME">%s</xliff:g> menggunakan ciri ini, ketik untuk membuka tetapan dan matikan ciri tersebut."</string>
<string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Matikan"</string>
<string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Menyemak <xliff:g id="NAME">%s</xliff:g>…"</string>
<string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Menyemak kandungan semasa"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dihidupkan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dimatikan."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan kekunci kelantangan. Untuk menghidupkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, sila tekan dan tahan kedua-dua kekunci kelantangan sekali lagi selama 3 saat."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Pilih ciri"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Pilih ciri"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Pilih ciri"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Ciri ini akan dibuka pada kali seterusnya anda mengetik butang kebolehaksesan"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Ciri ini akan dibuka pada kali seterusnya anda menggunakan pintasan ini. Leret ke atas menggunakan 2 jari dari bahagian bawah skrin anda dan lepaskan dengan cepat."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Ciri ini akan dibuka pada kali seterusnya anda menggunakan pintasan ini. Leret ke atas menggunakan 3 jari dari bahagian bawah skrin anda dan lepaskan dengan cepat."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pembesaran"</string>
<string name="user_switched" msgid="7249833311585228097">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Beralih kepada <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN terlalu pendek. Mesti sekurang-kurangnya 4 angka."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Cuba sebentar lagi"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Melihat skrin penuh"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Untuk keluar, leret ke bawah daripada bahagian atas skrin anda"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Faham"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Putar untuk mendapatkan paparan yang lebih baik"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Buka <xliff:g id="NAME">%s</xliff:g> dalam skrin penuh untuk mendapatkan paparan yang lebih baik"</string>
@@ -2434,12 +2425,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara ciri ini berfungsi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Belum selesai..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Sediakan Buka Kunci Cap Jari sekali lagi"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan. Sediakan cap jari sekali lagi untuk membuka kunci telefon anda menggunakan cap jari."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan. Sediakan kedua-dua cap jari tersebut sekali lagi untuk membuka kunci telefon anda menggunakan cap jari anda."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dicam lagi."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dicam lagi."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dicam lagi. Sediakan semula Buka Kunci Cap Jari."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dicam lagi. Sediakan semula Buka Kunci Cap Jari."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Sediakan semula Buka Kunci Wajah"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model wajah anda tidak berfungsi dengan baik dan telah dipadamkan. Sediakan model wajah sekali lagi untuk membuka kunci telefon anda menggunakan wajah."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Model wajah anda tidak dapat dicam lagi. Sediakan semula Buka Kunci Wajah."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Sediakan"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Bukan sekarang"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Penggera untuk <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Tukar pengguna"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Redam"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Ketik untuk meredamkan bunyi"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"Penyemak Imbas"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"Kenalan"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"E-mel"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"SMS"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"Muzik"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"Kalendar"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"Kalkulator"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Maps"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"Aplikasi"</string>
</resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index f18df9614f34..fca79cb9ea27 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ကြိုးမဲ့ အမှားရှာပြင်ခြင်းကို ပိတ်ရန် ရွေးပါ။"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"\'စမ်းသပ်ခြင်းစနစ်မုဒ်\' ဖွင့်ထားသည်"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"\'စမ်းသပ်ခြင်းစနစ် မုဒ်\' ကိုပိတ်ရန် စက်ရုံထုတ်အတိုင်း ပြင်ဆင်သတ်မှတ်ပါ။"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM တည်ဆောက်ပုံ စီစဉ်သတ်မှတ်ချက် မှားနေသည်"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"ဤစက်၏ ‘မမြင်နိုင်သော စနစ်အသုံးပြုသူမုဒ်’ အခြေအနေသည် ၎င်း၏ တည်ဆောက်ပုံ စီစဉ်သတ်မှတ်ချက်နှင့် ကွဲလွဲနေသည်။ ဤစက်ကို စက်ရုံထုတ်အတိုင်း ပြင်ဆင်သတ်မှတ်ပါ။"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"အမှတ်စဉ် ကွန်ဆိုးလ်ကို ဖွင့်ထားသည်"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"စွမ်းဆောင်ရည်အပေါ် သက်ရောက်မှုရှိနိုင်ပါသည်။ ပိတ်ရန် bootloader ကို စစ်ဆေးပါ။"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"အစမ်းသုံး MTE ကို ဖွင့်ထားသည်"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်လိုက်သည်။"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ပိတ်လိုက်သည်။"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"အသံထိန်းခလုတ်များကို လွှတ်လိုက်ပါ။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်ရန် အသံထိန်းခလုတ်နှစ်ခုစလုံးကို ၃ စက္ကန့်ကြာအောင် ထပ်နှိပ်ပါ။"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"တူးလ်ရွေးပါ"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"တူးလ်ရွေးပါ"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"တူးလ်ရွေးပါ"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"နောက်တစ်ကြိမ်တွင် သုံးနိုင်မှုခလုတ်ကို တို့သည့်အခါ ဤဝန်ဆောင်မှု ပွင့်လာမည်"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"နောက်တစ်ကြိမ်တွင် ဤဖြတ်လမ်းကို သုံးသည့်အခါ ဤဝန်ဆောင်မှု ပွင့်လာမည်။ သင့်ဖန်သားပြင်အောက်ခြေမှ အပေါ်သို့ လက် ၂ ချောင်းဖြင့် ပွတ်ဆွဲ၍ အမြန်လွှတ်လိုက်ပါ။"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"နောက်တစ်ကြိမ်တွင် ဤဖြတ်လမ်းကို သုံးသည့်အခါ ဤဝန်ဆောင်မှု ပွင့်လာမည်။ သင့်ဖန်သားပြင်အောက်ခြေမှ အပေါ်သို့ လက် ၃ ချောင်းဖြင့် ပွတ်ဆွဲ၍ အမြန်လွှတ်လိုက်ပါ။"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ချဲ့ခြင်း"</string>
<string name="user_switched" msgid="7249833311585228097">"လက်ရှိအသုံးပြုနေသူ <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>သို့ ပြောင်းနေသည်…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"ပင် နံပါတ် တိုလွန်းသည်။. အနည်းဆုံး ဂဏန်း ၄ လုံး ဖြစ်ရမည်။"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"နောက်မှ ပြန်ကြိုးစားပါ"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"မျက်နှာပြင်အပြည့် ကြည့်နေသည်"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"ထွက်ရန် သင့်ဖန်သားပြင်ထိပ်မှ အောက်သို့ ပွတ်ဆွဲပါ"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"ရပါပြီ"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ပိုကောင်းသောမြင်ကွင်းအတွက် လှည့်ပါ"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"ပိုကောင်းသောမြင်ကွင်းအတွက် ဖန်သားပြင်အပြည့်ဖြင့် <xliff:g id="NAME">%s</xliff:g> ကို ဖွင့်ပါ"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"လက်ရှိခေါ်ဆိုမှု"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"အဝင်ခေါ်ဆိုမှုကို စစ်ဆေးနေသည်"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"အမျိုးအစားမခွဲရသေးပါ"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ပရိုမိုးရှင်းများ"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"လူမှုရေး"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"သတင်း"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"အကြံပြုချက်များ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"ဤသတိပေးချက်များ၏ အရေးပါမှုကိုသတ်မှတ်ပြီးပါပြီ။"</string>
<string name="importance_from_person" msgid="4235804979664465383">"ပါဝင်သည့်လူများကြောင့် အရေးပါပါသည်။"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"စိတ်ကြိုက်အက်ပ် အကြောင်းကြားချက်"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ဖန်သားပြင်အတွက် အများသုံးစွဲနိုင်မှုဖြတ်လမ်းလင့်ခ် ရွေးချယ်စနစ်"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"အများသုံးနိုင်မှု ဖြတ်လမ်းလင့်ခ်"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"အကြောင်းကြားစာအကွက်ကို ပယ်ရန်"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"မီနူး"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"မီဒီယာ ဖွင့်ရန်/ခဏရပ်ရန်"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad အပေါ်"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad အောက်"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ဘယ်"</string>
@@ -2433,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"သီးသန့်နေရာ"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"သတိထားရမည့် အကြောင်းကြားချက်ပါ အချက်အလက်ကို ဖျောက်ထားသည်"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"အက်ပ်အကြောင်းအရာသည် လုံခြုံရေးအတွက် မျက်နှာပြင် မျှဝေခြင်းမှ ဖျောက်ထားသည်"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"လုံခြုံရေးအတွက် အက်ပ်အကြောင်းအရာကို ဖန်သားပြင် မျှဝေခြင်းတွင် ဖျောက်ထားသည်"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"ဂြိုဟ်တုနှင့် အလိုအလျောက် ချိတ်ဆက်ထားသည်"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"မိုဘိုင်း (သို့) Wi-Fi ကွန်ရက်မရှိဘဲ မက်ဆေ့ဂျ်များကို ပို့နိုင်၊ လက်ခံနိုင်သည်"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ဖွင့်ရန်"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"အလုပ်လုပ်ပုံ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ဆိုင်းငံ့ထားသည်…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"‘လက်ဗွေသုံး လော့ခ်ဖွင့်ခြင်း’ ကို စနစ်ထပ်မံထည့်သွင်းပါ"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> နှင့် <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> တို့ သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်။ သင့်ဖုန်းကို လက်ဗွေဖြင့်လော့ခ်ဖွင့်ရန် ၎င်းကို စနစ်ထပ်မံထည့်သွင်းပါ။"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> နှင့် <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> တို့ သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်။ သင့်ဖုန်းကို လက်ဗွေဖြင့်လော့ခ်ဖွင့်ရန် ၎င်းတို့ကို စနစ်ထပ်မံထည့်သွင်းပါ။"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ကို မသိရှိနိုင်တော့ပါ။"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> နှင့် <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ကို မသိရှိနိုင်တော့ပါ။"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ကို မသိရှိနိုင်တော့ပါ။ ‘လက်ဗွေသုံး လော့ခ်ဖွင့်ခြင်း’ ထပ်မံစနစ်ထည့်သွင်းပါ။"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> နှင့် <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ကို မသိရှိနိုင်တော့ပါ။ ‘လက်ဗွေသုံး လော့ခ်ဖွင့်ခြင်း’ ထပ်မံစနစ်ထည့်သွင်းပါ။"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"‘မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း’ ကို စနစ်ထပ်မံထည့်သွင်းပါ"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"သင့်မျက်နှာနမူနာ သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်။ သင့်ဖုန်းကို မျက်နှာဖြင့်လော့ခ်ဖွင့်ရန် ၎င်းကို စနစ်ထပ်မံထည့်သွင်းပါ။"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"သင်၏မျက်နှာနမူနာကို မသိရှိနိုင်တော့ပါ။ ‘မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း’ ထပ်မံစနစ်ထည့်သွင်းပါ။"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"စနစ်ထည့်သွင်းရန်"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ယခုမလုပ်ပါ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> အတွက် နှိုးစက်"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"အသုံးပြုသူ ပြောင်းရန်"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"အသံပိတ်ရန်"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"အသံပိတ်ရန် တို့ပါ"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index dd9bd8159e15..03db9c5ac21f 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -264,7 +264,7 @@
<string name="global_action_emergency" msgid="1387617624177105088">"Nødssituasjon"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Feilrapport"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Avslutt økten"</string>
- <string name="global_action_screenshot" msgid="2610053466156478564">"Skjermdump"</string>
+ <string name="global_action_screenshot" msgid="2610053466156478564">"Skjermbilde"</string>
<string name="bugreport_title" msgid="8549990811777373050">"Feilrapport"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Informasjon om tilstanden til enheten din samles inn og sendes som en e-post. Det tar litt tid fra du starter feilrapporten til e-posten er klar, så vær tålmodig."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiv rapport"</string>
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Velg for å slå av trådløs feilsøking."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testrammeverk-modus er slått på"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Tilbakestill enheten til fabrikkstandard for å slå av Testrammeverk-modus."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Feil konfigurasjon for kodebygging for hodeløs systembruker-modus"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Statusen for hodeløs systembruker-modus for denne enheten avviker fra enhetens konfigurasjon for kodebygging. Tilbakestill enheten til fabrikkstandard."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Seriekonsollen er aktivert"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ytelsen er påvirket. Sjekk oppstartsinnlasteren for å deaktivere."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE på forsøksstadiet er aktivert"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått på."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått av."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slipp opp volumtastene. For å slå på <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, trykk og hold på begge volumtastene igjen i 3 sekunder."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Velg en funksjon"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Velg en funksjon"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Velg en funksjon"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funksjonen åpnes neste gang du trykker på Tilgjengelighet-knappen"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funksjonen åpnes neste gang du bruker denne snarveien. Sveip opp med 2 fingre fra nederst på skjermen, og slipp raskt opp."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funksjonen åpnes neste gang du bruker denne snarveien. Sveip opp med 3 fingre fra nederst på skjermen, og slipp raskt opp."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Forstørring"</string>
<string name="user_switched" msgid="7249833311585228097">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Bytter til <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN-koden er for kort. Den må bestå av minst fire sifre."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Prøv på nytt senere"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Visning i fullskjerm"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"For å gå ut, sveip ned fra toppen av skjermen"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Skjønner"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Roter for å få en bedre visning"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Åpne <xliff:g id="NAME">%s</xliff:g> i fullskjerm for å se bedre"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pågående samtale"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrerer et innkommende anrop"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Uten kategori"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoteringer"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sosialt"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Nyheter"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Anbefalinger"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Du angir viktigheten for disse varslene."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Dette er viktig på grunn av folkene som er involvert."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Tilpasset appvarsel"</string>
@@ -2204,16 +2191,14 @@
<string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Hurtiginnstillinger"</string>
<string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialogboks for å slå av/på"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Låseskjerm"</string>
- <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skjermdump"</string>
+ <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skjermbilde"</string>
<string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Hook for hodetelefoner"</string>
<string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Tilgjengelighetssnarvei på skjermen"</string>
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Velger for tilgjengelighetssnarvei på skjermen"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Tilgjengelighetssnarvei"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Lukk varselpanelet"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meny"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media – spill av og sett på pause"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Opp på styrepilene"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Ned på styrepilene"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Venstre på styrepilene"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Slik fungerer det"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Venter …"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer opplåsingen med fingeravtrykk på nytt"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerte ikke skikkelig og ble slettet"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerte ikke skikkelig og ble slettet"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerte ikke skikkelig og ble slettet. Du kan konfigurere det på nytt for å låse opp telefonen med fingeravtrykket."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerte ikke skikkelig og ble slettet. Du kan konfigurere dem på nytt for å låse opp telefonen med fingeravtrykket."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> gjenkjennes ikke lenger."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> gjenkjennes ikke lenger."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> gjenkjennes ikke lenger. Konfigurer opplåsing med fingeravtrykk på nytt."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> gjenkjennes ikke lenger. Konfigurer opplåsing med fingeravtrykk på nytt."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurer ansiktslåsen på nytt"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ansiktsmodellen din fungerte ikke skikkelig og ble slettet. Du kan konfigurere den på nytt for å låse opp telefonen med ansiktet."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Ansiktsmodellen din gjenkjennes ikke lenger. Konfigurer ansiktslåsen på nytt."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfigurer"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ikke nå"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Bytt bruker"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Kutt lyden"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Trykk for å kutte lyden"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 01a6fc7bb582..6c58d16cd77c 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"वायरलेस डिबगिङ असक्षम पार्न यो विकल्प चयन गर्नुहोस्।"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"परीक्षण प्याकेज मोड सक्षम पारियो"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"परीक्षण प्याकेज मोड असक्षम पार्न फ्याक्ट्री रिसेट गर्नुहोस्।"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM बिल्ड कन्फिगुरेसन गलत छ"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"यो डिभाइसको हेडलेस सिस्टम युजर मोडको स्थिति यसको बिल्ड कन्फिगुरेसनभन्दा फरक छ। कृपया यो डिभाइस फ्याक्ट्री रिसेट गर्नुहोस्।"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"क्रमसम्बन्धी कन्सोल सक्षम पारियो"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"पर्फर्मेन्समा प्रभाव परेको छ। यसलाई असक्षम पार्न बुटलोडरको जाँच गर्नुहोस्।"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"परीक्षणका क्रममा रहेको MTE अन गरियो"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन भयो।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अफ भयो।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"भोल्युम बटनहरू थिच्न छाड्नुहोस्। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन गर्न दुवै भोल्युम बटन फेरि ३ सेकेन्डसम्म थिचिराख्नुहोस्।"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"कुनै सुविधा चयन गर्नुहोस्"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"कुनै सुविधा चयन गर्नुहोस्"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"कुनै सुविधा चयन गर्नुहोस्"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"तपाईंले अर्को पटक एक्सेसिबिलिटी बटनमा ट्याप गर्दा यो सुविधा खुल्ने छ"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"तपाईंले अर्को पटक यो सर्टकट प्रयोग गर्दा यो सुविधा खुल्ने छ। २ वटा औँलाले स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् र तुरुन्तै औँला उठाउनुहोस्।"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"तपाईंले अर्को पटक यो सर्टकट प्रयोग गर्दा यो सुविधा खुल्ने छ। ३ वटा औँलाले स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् र तुरुन्तै औँला उठाउनुहोस्।"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"म्याग्निफिकेसन"</string>
<string name="user_switched" msgid="7249833311585228097">"अहिलेको प्रयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"स्विच गरेर <xliff:g id="NAME">%1$s</xliff:g> बनाइँदै..."</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN अति छोटो भयो। कम्तीमा ४ अङ्क हुन आवश्यक छ।"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"पछि पुनः प्रयास गर्नुहोस्"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"पूरा पर्दा हेर्दै"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"यहाँबाट बाहिरिन स्क्रिनको सिरानबाट तलतिर स्वाइप गर्नुहोस्"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"बुझेँ"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"अझ राम्रो दृश्य हेर्न चाहनुहुन्छ भने रोटेट गर्नुहोस्"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"अझ राम्रो दृश्य हेर्न चाहनुहुन्छ भने <xliff:g id="NAME">%s</xliff:g> खोल्नुहोस्"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"भइरहेको कल"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"आगमन कल जाँचिँदै छ"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"वर्गीकरण नगरिएको"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"प्रवर्धनहरू"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"सोसल मिडिया"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"समाचार"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"सिफारिसहरू"</string>
<string name="importance_from_user" msgid="2782756722448800447">"तपाईंले यी सूचनाहरूको महत्त्व सेट गर्नुहोस् ।"</string>
<string name="importance_from_person" msgid="4235804979664465383">"यसमा सङ्लग्न भएका मानिसहरूको कारणले गर्दा यो महत्वपूर्ण छ।"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"एपसम्बन्धी आफ्नो रोजाइअनुसारको सूचना"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"सहज पहुँचका लागि स्क्रिनमा राखिने सर्टकट छान्ने मेनु"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"पहुँचको सर्टकट"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"सूचना कक्ष खारेज गर्नुहोस्"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"मेनु"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"मिडिया प्ले/पज"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad को माथिको बटन"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad को तलको बटन"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad को बायाँको बटन"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यसले काम गर्ने तरिका"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"विचाराधीन..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नुहोस्"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"राम्ररी काम नगरिरहेको हुनाले <xliff:g id="FINGERPRINT">%s</xliff:g> मेटाइएको छ"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"राम्ररी काम नगरिरहेका हुनाले <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> र <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> मेटाइएका छन्"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ले काम गरिरहेको थिएन र त्यसलाई मेटाइयो। फिंगरप्रिन्ट प्रयोग गरी आफ्नो फोन अनलक गर्न त्यसलाई फेरि सेट अप गर्नुहोस्।"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> र <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ले राम्ररी काम गरिरहेका थिएनन् र तिनलाई मेटाइयो। फिंगरप्रिन्ट प्रयोग गरी आफ्नो फोन अनलक गर्न तिनलाई फेरि सेट अप गर्नुहोस्।"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> अब पहिचान गर्न सकिँदैन।"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> र <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> अब पहिचान गर्न सकिँदैन।"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> अब पहिचान गर्न सकिँदैन। फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नुहोस्।"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> र <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> अब पहिचान गर्न सकिँदैन। फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नुहोस्।"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"फेस अनलक फेरि सेटअप गर्नुहोस्"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"तपाईंको फेस मोडेलले राम्ररी काम गरिरहेको थिएन र त्यसलाई मेटाइयो। अनुहार प्रयोग गरी आफ्नो फोन अनलक गर्न फेस मोडेल फेरि सेट अप गर्नुहोस्।"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"तपाईंको फेस मोडेल अब पहिचान गर्न सकिँदैन। फेस अनलक फेरि सेटअप गर्नुहोस्।"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेटअप गर्नुहोस्"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"अहिले होइन"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> का निम्ति अलार्म"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"प्रयोगकर्ता बदल्नुहोस्"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"म्युट गर्नुहोस्"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"साउन्ड म्युट गर्न ट्याप गर्नुहोस्"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 5fdcf85eef25..5fd6d42268a2 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecteer deze optie om draadloze foutopsporing uit te zetten."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test harness-modus staat aan"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Reset de fabrieksinstellingen om de test harness-modus uit te zetten."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Onjuiste HSUM-buildconfiguratie"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"De Headless System User Mode-status van dit apparaat wijkt af van de buildconfiguratie. Zet het apparaat terug op de fabrieksinstellingen."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Seriële console staat aan"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Dit is van invloed op de prestaties. Controleer de bootloader om dit uit te zetten."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimentele MTE aangezet"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat aan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat uit."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Laat de volumeknoppen los. Als je <xliff:g id="SERVICE_NAME">%1$s</xliff:g> wilt aanzetten, houd je beide volumeknoppen weer 3 seconden ingedrukt."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Kies een functie"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Kies een functie"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Kies een functie"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"De functie opent de volgende keer dat je op de knop Toegankelijkheid tikt"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"De functie opent de volgende keer dat je deze snelkoppeling gebruikt. Swipe met 2 vingers omhoog vanaf de onderkant van je scherm en laat snel los."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"De functie opent de volgende keer dat je deze snelkoppeling gebruikt. Swipe met 3 vingers omhoog vanaf de onderkant van je scherm en laat snel los."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergroting"</string>
<string name="user_switched" msgid="7249833311585228097">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Overschakelen naar <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Pincode is te kort. Moet ten minste vier cijfers lang zijn."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Probeer het later opnieuw"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Volledig scherm wordt getoond"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Swipe omlaag vanaf de bovenkant van het scherm om af te sluiten"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Ik snap het"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Draai voor een betere weergave"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Open <xliff:g id="NAME">%s</xliff:g> op volledig scherm voor een betere weergave"</string>
@@ -2427,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Privégedeelte"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Content van gevoelige meldingen verborgen"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App-content verborgen voor scherm delen vanwege beveiligingsrisico\'s"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Vanwege beveiligingsrisico\'s is app-content verborgen voor scherm delen"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch verbonden met satelliet"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Je kunt berichten sturen en krijgen zonder een mobiel of wifi-netwerk"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Berichten openen"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe het werkt"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"In behandeling…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ontgrendelen met vingerafdruk weer instellen"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> werkte niet goed en is verwijderd"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werkten niet goed en zijn verwijderd"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> werkte niet goed en is verwijderd. Stel deze opnieuw in om de telefoon met je vingerafdruk te ontgrendelen."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werkten niet goed en zijn verwijderd. Stel ze opnieuw in om de telefoon met je vingerafdruk te ontgrendelen."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> wordt niet meer herkend."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> worden niet meer herkend."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> wordt niet meer herkend. Stel Ontgrendelen met vingerafdruk opnieuw in."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> worden niet meer herkend. Stel Ontgrendelen met vingerafdruk opnieuw in."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ontgrendelen via gezichtsherkenning weer instellen"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Je gezichtsmodel werkte niet goed en is verwijderd. Stel het opnieuw in om de telefoon met je gezicht te ontgrendelen."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Je gezichtsmodel wordt niet meer herkend. Stel Ontgrendelen via gezichtsherkenning opnieuw in."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Instellen"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Niet nu"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Wekker voor <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Gebruiker wijzigen"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Geluid uitzetten"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tik om het geluid uit te zetten"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 7c86e97d459a..883ef1f58559 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1032,7 +1032,7 @@
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"ଆପଣ ଆପଣଙ୍କର ଅନଲକ୍ ପାଟର୍ନକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଆଙ୍କିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ଥର ଅସଫଳ ଚେଷ୍ଟା ପରେ, ଆପଣଙ୍କୁ Google ସାଇନ୍ଇନ୍ ବ୍ୟବହାର କରି ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ। \n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ମଧ୍ୟରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"ଅନଲକ୍‍ ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ ପ୍ରୟାସ ପରେ, Google ସାଇନ୍‌-ଇନ୍‍ ବ୍ୟବହାର କରି ଆପଣଙ୍କୁ ନିଜ ଫୋନ୍‍କୁ ଅନଲକ୍‍ କରିବାକୁ କୁହାଯିବ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"ଟାବଲେଟ୍‍କୁ ଅନ୍‌ଲକ୍‌ କରିବା ପାଇଁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ ପ୍ରୟାସ ପରେ, ଟାବଲେଟ୍‍ଟି ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍‍ ହୋଇଯିବ ଏବଂ ଆପଣ ସମସ୍ତ ୟୁଜର୍‍ ଡାଟା ହରାଇବେ।"</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ଥର ଅସଫଳ ଚେଷ୍ଟା ପରେ, ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍ ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍ କରାଯିବ ଏବଂ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ହରାଇବ।"</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଆପଣଙ୍କର Android TV ଡିଭାଇସକୁ ଭୁଲ ଭାବେ ଅନଲକ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ଥର ଅସଫଳ ଚେଷ୍ଟା ପରେ ଆପଣଙ୍କର Android TV ଡିଭାଇସ ଫେକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ କରାଯିବ ଏବଂ ସମସ୍ତ ୟୁଜର ଡାଟା ହରାଇବ।"</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"ଫୋନ୍‍ ଅନଲକ୍‍ କରିବାକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ପ୍ରୟାସ କଲେ। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ ପ୍ରୟାସ ପରେ, ଫୋନ୍‍ଟି ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍‍ ହୋଇଯିବ ଏବଂ ଆପଣ ସମସ୍ତ ୟୁଜର୍‍ ଡାଟା ହରାଇବେ।"</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"ଟାବଲେଟ୍‍ ଅନଲକ୍‍ କରିବାକୁ ଆପଣ <xliff:g id="NUMBER">%d</xliff:g> ଥର ଭୁଲ ପ୍ରୟାସ କଲେ। ଟାବଲେଟ୍‍ଟି ବର୍ତ୍ତମାନ ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍‍ ହୋଇଯିବ।"</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"ଆପଣ <xliff:g id="NUMBER">%d</xliff:g> ଥର ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। ବର୍ତ୍ତମାନ ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍ ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍ ହୋଇଯିବ।"</string>
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ୱାୟାରଲେସ୍ ଡିବଗିଂକୁ ଅକ୍ଷମ କରିବା ପାଇଁ ଚୟନ କରନ୍ତୁ।"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ଟେଷ୍ଟ ହାର୍ନେସ୍ ମୋଡ୍ ସକ୍ଷମ ଅଛି"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ଟେଷ୍ଟ ହାର୍‌ନେସ୍ ମୋଡ୍ ଅକ୍ଷମ କରିବାକୁ ଏକ ଫ୍ୟାକ୍ଟରୀ ରିସେଟ୍ କରନ୍ତୁ।"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"ଭୁଲ HSUM ବିଲ୍ଡ କନଫିଗରେସନ"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"ଏହି ଡିଭାଇସର ହେଡଲେସ ସିଷ୍ଟମ ୟୁଜର ମୋଡ ସ୍ଥିତି ଏହାର ବିଲ୍ଡ କନଫିଗରେସନଠାରୁ ଭିନ୍ନ ଅଟେ। ଦୟାକରି ଡିଭାଇସକୁ ଫେକ୍ଟୋରୀ ରିସେଟ କରନ୍ତୁ।"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"କ୍ରମିକ କନ୍‍‍ସୋଲ୍‍କୁ ସକ୍ଷମ କରାଯାଇଛି"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"କାର୍ଯ୍ୟଦକ୍ଷତା ପ୍ରଭାବିତ ହୋଇଛି। ଅକ୍ଷମ କରିବା ପାଇଁ, ବୁଟ୍‌ଲୋଡର୍‍ର ଯାଞ୍ଚ କରନ୍ତୁ।"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ପରୀକ୍ଷାମୂଳକ MTEକୁ ସକ୍ଷମ କରାଯାଇଛି"</string>
@@ -1709,7 +1707,7 @@
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"ଆପଣଙ୍କ ପାସ୍‌ୱର୍ଡକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଟାଇପ୍ କରିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ \n\nପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"ଆପଣଙ୍କ ଲକ୍‍ ଖୋଲିବା ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ \n\nପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"ଟାବଲେଟ୍‌ ଅନଲକ୍‍ କରିବାକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ପ୍ରୟାସ କଲେ। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ ପ୍ରୟାସ ପରେ, ଟାବଲେଟ୍‌ଟି ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍‍ ହୋଇଯିବ ଏବଂ ସମସ୍ତ ୟୁଜର୍‍ ଡାଟା ବାହାରିଯିବ।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ଥର ଅସଫଳ ଚେଷ୍ଟା ପରେ, ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍ ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍ କରାଯିବ ଏବଂ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ହରାଇବ।"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଆପଣଙ୍କର Android TV ଡିଭାଇସକୁ ଭୁଲ ଭାବେ ଅନଲକ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ଥର ଅସଫଳ ଚେଷ୍ଟା ପରେ ଆପଣଙ୍କର Android TV ଡିଭାଇସ ଫେକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ କରାଯିବ ଏବଂ ସମସ୍ତ ୟୁଜର ଡାଟା ହରାଇବ।"</string>
<string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"ଫୋନ୍‌ ଅନଲକ୍‍ କରିବାକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ପ୍ରୟାସ କଲେ। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ ପ୍ରୟାସ ପରେ, ଫୋନ୍‌ଟି ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍‍ ହୋଇଯିବ ଏବଂ ସମସ୍ତ ୟୁଜର୍‍ ଡାଟା ବାହାରିଯିବ।"</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"ଟାବଲେଟ୍‌ ଅନଲକ୍‍ କରିବାକୁ ଆପଣ <xliff:g id="NUMBER">%d</xliff:g> ଥର ଭୁଲ ପ୍ରୟାସ କଲେ। ଟାବଲେଟ୍‌ଟି ବର୍ତ୍ତମାନ ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍‍ ହୋଇଯିବ।"</string>
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"ଆପଣ <xliff:g id="NUMBER">%d</xliff:g> ଥର ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। ବର୍ତ୍ତମାନ ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍ ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍ ହୋଇଯିବ।"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଚାଲୁ ହୋଇଛି।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବନ୍ଦ ହୋଇଛି।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ଭଲ୍ୟୁମ କୀ\'ଗୁଡ଼ିକୁ ରିଲିଜ କରନ୍ତୁ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g>କୁ ଚାଲୁ କରିବା ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ କୀ\'କୁ ପୁଣି 3 ସେକେଣ୍ଡ ପାଇଁ ଦବାଇ ଧରି ରଖନ୍ତୁ।"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"ଏକ ଫିଚର ବାଛନ୍ତୁ"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"ଏକ ଫିଚର ବାଛନ୍ତୁ"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"ଏକ ଫିଚର ବାଛନ୍ତୁ"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ଆପଣ ଆଗାମୀ ଥର ଆକ୍ସେସିବିଲିଟୀ ବଟନରେ ଟାପ କଲେ ଏହି ଫିଚରଟି ଖୋଲିବ"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ଆପଣ ଆଗାମୀ ଥର ଏହି ସର୍ଟକଟକୁ ବ୍ୟବହାର କଲେ ଏହି ଫିଚରଟି ଖୋଲିବ। ଆପଣଙ୍କ ସ୍କ୍ରିନର ନିମ୍ନଭାଗରୁ 2 ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରି ଶୀଘ୍ର ରିଲିଜ କରନ୍ତୁ।"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ଆପଣ ଆଗାମୀ ଥର ଏହି ସର୍ଟକଟକୁ ବ୍ୟବହାର କଲେ ଏହି ଫିଚରଟି ଖୋଲିବ। ଆପଣଙ୍କ ସ୍କ୍ରିନର ନିମ୍ନଭାଗରୁ 3 ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରି ଶୀଘ୍ର ରିଲିଜ କରନ୍ତୁ।"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ମେଗ୍ନିଫିକେସନ"</string>
<string name="user_switched" msgid="7249833311585228097">"ବର୍ତ୍ତମାନର ୟୁଜର୍‌ ହେଉଛନ୍ତି <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ରେ ସ୍ୱିଚ କରନ୍ତୁ…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN ବହୁତ ଛୋଟ। ଅତି କମ୍‍ରେ 4 ସଂଖ୍ୟା ବିଶିଷ୍ଟ ହେବା ଦରକାର।"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନରେ ଦେଖାଯାଉଛି"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"ବାହାରି ଯିବା ପାଇଁ ଆପଣଙ୍କ ସ୍କ୍ରିନର ଶୀର୍ଷରୁ ତଳକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"ବୁଝିଗଲି"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ଏକ ଭଲ ଭ୍ୟୁ ପାଇଁ ରୋଟେଟ କରନ୍ତୁ"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"ଏକ ଭଲ ଭ୍ୟୁ ପାଇଁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନରେ <xliff:g id="NAME">%s</xliff:g> ଖୋଲନ୍ତୁ"</string>
@@ -1994,7 +1985,7 @@
<string name="importance_from_person" msgid="4235804979664465383">"ସମ୍ପୃକ୍ତ ଲୋକଙ୍କ କାରଣରୁ ଏହା ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ ଅଟେ।"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"କଷ୍ଟମ୍ ଆପ୍ ବିଜ୍ଞପ୍ତି"</string>
<string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ (ପୂର୍ବରୁ ଏହି ଆକାଉଣ୍ଟ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ନାମରେ ଅଛି) ଅନୁମତି ଦେବେ?"</string>
- <string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
+ <string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ୟୁଜର ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
<string name="supervised_user_creation_label" msgid="6884904353827427515">"ନିରୀକ୍ଷିତ ୟୁଜର ଯୋଗ କରନ୍ତୁ"</string>
<string name="language_selection_title" msgid="52674936078683285">"ଏକ ଭାଷା ଯୋଗ କରନ୍ତୁ"</string>
<string name="country_selection_title" msgid="5221495687299014379">"ପସନ୍ଦର ଅଞ୍ଚଳ"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ଏହା କିପରି କାମ କରେ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ବାକି ଅଛି…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏହାକୁ ଡିଲିଟ କରାଯାଇଛି"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏଗୁଡ଼ିକୁ ଡିଲିଟ କରାଯାଇଛି"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏହାକୁ ଡିଲିଟ କରାଯାଇଛି। ଟିପଚିହ୍ନ ମାଧ୍ୟମରେ ଆପଣଙ୍କ ଫୋନକୁ ଅନଲକ କରିବାକୁ ଏହାକୁ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏଗୁଡ଼ିକୁ ଡିଲିଟ କରାଯାଇଛି। ଆପଣଙ୍କ ଟିପଚିହ୍ନ ମାଧ୍ୟମରେ ଆପଣଙ୍କ ଫୋନକୁ ଅନଲକ କରିବାକୁ ଏଗୁଡ଼ିକୁ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ।"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ।"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ। ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ। ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ଫେସ୍ ଅନଲକ୍ ପୁଣି ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ଆପଣଙ୍କ ଫେସ ମଡେଲ ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏହାକୁ ଡିଲିଟ କରାଯାଇଛି। ଫେସ ମାଧ୍ୟମରେ ଆପଣଙ୍କ ଫୋନକୁ ଅନଲକ କରିବାକୁ ଏହାକୁ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"ଆପଣଙ୍କ ଫେସ ମଡେଲକୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ। ଫେସ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ସେଟ ଅପ କରନ୍ତୁ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ବର୍ତ୍ତମାନ ନୁହେଁ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>ଙ୍କ ପାଇଁ ଆଲାରାମ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ୟୁଜରଙ୍କୁ ସ୍ୱିଚ କରନ୍ତୁ"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ମ୍ୟୁଟ କରନ୍ତୁ"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ସାଉଣ୍ଡ ମ୍ୟୁଟ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index a91ec2d934f3..fda4943bed41 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ਵਾਇਰਲੈੱਸ ਡੀਬੱਗਿੰਗ ਨੂੰ ਬੰਦ ਕਰਨ ਲਈ ਚੁਣੋ।"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਚਾਲੂ ਹੈ"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਬੰਦ ਕਰਨ ਲਈ ਫੈਕਟਰੀ ਰੀਸੈੱਟ ਕਰੋ।"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"ਗਲਤ HSUM ਬਿਲਡ ਸੰਰੂਪਣ"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"ਇਸ ਡੀਵਾਈਸ ਦੀ ਹੈੱਡਲੈੱਸ ਸਿਸਟਮ ਯੂਜ਼ਰ ਮੋਡ ਸਥਿਤੀ ਇਸਦੇ ਬਿਲਡ ਸੰਰੂਪਣ ਤੋਂ ਵੱਖਰੀ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ ਡੀਵਾਈਸ ਨੂੰ ਫੈਕਟਰੀ ਰੀਸੈੱਟ ਕਰੋ।"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"ਸੀਰੀਅਲ ਕੰਸੋਲ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"ਕਾਰਗੁਜ਼ਾਰੀ ਪ੍ਰਭਾਵਿਤ ਹੋਈ ਹੈ। ਬੰਦ ਕਰਨ ਲਈ, ਬੂਟਲੋਡਰ ਦੇਖੋ।"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ਪ੍ਰਯੋਗਮਈ MTE ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ ਛੱਡੋ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕਰਨ ਲਈ, ਦੋਵੇਂ ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ 3 ਸਕਿੰਟਾਂ ਲਈ ਦੁਬਾਰਾ ਦਬਾਈ ਰੱਖੋ।"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ਅਗਲੀ ਵਾਰ ਜਦੋਂ ਤੁਸੀਂ ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਟੈਪ ਕਰੋਗੇ, ਤਾਂ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਖੁੱਲ੍ਹ ਜਾਵੇਗੀ"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ਅਗਲੀ ਵਾਰ ਜਦੋਂ ਤੁਸੀਂ ਇਸ ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋਗੇ, ਤਾਂ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਖੁੱਲ੍ਹ ਜਾਵੇਗੀ। 2 ਉਂਗਲਾਂ ਨਾਲ ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰ ਕੇ ਤੁਰੰਤ ਛੱਡੋ।"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ਅਗਲੀ ਵਾਰ ਜਦੋਂ ਤੁਸੀਂ ਇਸ ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋਗੇ, ਤਾਂ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਖੁੱਲ੍ਹ ਜਾਵੇਗੀ। 3 ਉਂਗਲਾਂ ਨਾਲ ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰ ਕੇ ਤੁਰੰਤ ਛੱਡੋ।"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ਵੱਡਦਰਸ਼ੀਕਰਨ"</string>
<string name="user_switched" msgid="7249833311585228097">"ਮੌਜੂਦਾ ਉਪਭੋਗਤਾ <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> \'ਤੇ ਸਵਿੱਚ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"ਪਿੰਨ ਬਹੁਤ ਜ਼ਿਆਦਾ ਛੋਟਾ ਹੈ। ਘੱਟੋ-ਘੱਟ 4 ਅੰਕ ਹੋਣੇ ਚਾਹੀਦੇ ਹਨ।"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"ਪੂਰੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦੇਖੋ"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"ਬਾਹਰ ਜਾਣ ਲਈ, ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਸਿਖਰ ਤੋਂ ਹੇਠਾਂ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"ਸਮਝ ਲਿਆ"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਅਨੁਭਵ ਲਈ ਘੁਮਾਓ"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਅਨੁਭਵ ਲਈ <xliff:g id="NAME">%s</xliff:g> ਨੂੰ ਪੂਰੀ-ਸਕ੍ਰੀਨ ਵਿੱਚ ਖੋਲ੍ਹੋ"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ਇਹ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ਵਿਚਾਰ-ਅਧੀਨ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ ਅਤੇ ਉਸਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਹੇ ਸਨ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ ਅਤੇ ਉਸਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ। ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਫਿੰਗਰਪ੍ਰਿੰਟ ਨਾਲ ਅਣਲਾਕ ਕਰਨ ਲਈ ਇਸਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਹੇ ਸੀ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ। ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਆਪਣੇ ਫਿੰਗਰਪ੍ਰਿੰਟ ਨਾਲ ਅਣਲਾਕ ਕਰਨ ਲਈ ਇਨ੍ਹਾਂ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਫਿੰਗਰਪ੍ਰਿੰਟ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਫਿੰਗਰਪ੍ਰਿੰਟ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ਫ਼ੇਸ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ਤੁਹਾਡਾ ਚਿਹਰੇ ਦਾ ਮਾਡਲ ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ ਅਤੇ ਉਸਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ। ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਚਿਹਰੇ ਨਾਲ ਅਣਲਾਕ ਕਰਨ ਲਈ ਇਸਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"ਤੁਹਾਡੇ ਚਿਹਰੇ ਦੇ ਮਾਡਲ ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਫ਼ੇਸ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ਸੈੱਟਅੱਪ ਕਰੋ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ਹੁਣੇ ਨਹੀਂ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> ਲਈ ਅਲਾਰਮ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ਵਰਤੋਂਕਾਰ ਬਦਲੋ"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ਮਿਊਟ ਕਰੋ"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ਧੁਨੀ ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index b1bc74854882..bfaf21ceca07 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1413,10 +1413,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Wybierz, by wyłączyć debugowanie bezprzewodowe."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Tryb jarzma testowego został włączony"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Przywróć ustawienia fabryczne, by wyłączyć tryb jarzma testowego."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Nieprawidłowa konfiguracja kompilacji trybu użytkownika systemowego bez interfejsu graficznego"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Stan trybu użytkownika systemowego bez interfejsu graficznego różni się od konfiguracji kompilacji. Przywróć urządzenie do ustawień fabrycznych."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Konsola szeregowa włączona"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Wpływa na wydajność. Aby wyłączyć, sprawdź program rozruchowy."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Włączono eksperymentalne rozszerzenie MTE"</string>
@@ -1761,18 +1759,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została włączona."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została wyłączona."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Zwolnij przyciski głośności. Aby włączyć usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, naciśnij i przytrzymaj oba przyciski głośności przez 3 sekundy."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Wybierz funkcję"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Wybierz funkcję"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Wybierz funkcję"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcja otworzy się, gdy następnym razem klikniesz przycisk ułatwień dostępu"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcja otworzy się, gdy następnym razem użyjesz tego skrótu. Przesuń 2 palcami z dołu ekranu i szybko je unieś."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcja otworzy się, gdy następnym razem użyjesz tego skrótu. Przesuń 3 palcami z dołu ekranu i szybko je unieś."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Powiększenie"</string>
<string name="user_switched" msgid="7249833311585228097">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Przełączam na użytkownika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1895,8 +1887,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN jest za krótki. Musi mieć co najmniej 4 cyfry."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Spróbuj ponownie później"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Włączony pełny ekran"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Aby zamknąć, przesuń palcem w dół z góry ekranu"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Obróć, aby lepiej widzieć"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Otwórz aplikację <xliff:g id="NAME">%s</xliff:g> na pełnym ekranie, aby lepiej widzieć"</string>
@@ -1988,14 +1979,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Trwa połączenie"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtruję połączenie przychodzące"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Bez kategorii"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocje"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Społecznościowe"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Wiadomości"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekomendacje"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ustawiłeś ważność tych powiadomień."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ta wiadomość jest ważna ze względu na osoby uczestniczące w wątku."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Niestandardowe powiadomienie z aplikacji"</string>
@@ -2212,10 +2199,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Wybierz ekranowy skrót ułatwień dostępu"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Skrót ułatwień dostępu"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Zamknij obszar powiadomień"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Odtwórz/wstrzymaj multimedia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad – w górę"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad – w dół"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad – w lewo"</string>
@@ -2442,12 +2427,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to działa"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Oczekiwanie…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Skonfiguruj ponownie odblokowywanie odciskiem palca"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Odcisk palca <xliff:g id="FINGERPRINT">%s</xliff:g> nie sprawdzał się dobrze i został usunięty"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Odciski palców <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nie sprawdzały się dobrze i zostały usunięte"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Odcisk palca <xliff:g id="FINGERPRINT">%s</xliff:g> nie sprawdzał się dobrze i został usunięty. Skonfiguruj go ponownie, aby odblokowywać telefon odciskiem palca."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Odciski palca <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nie sprawdzały się dobrze i zostały usunięte. Skonfiguruj je ponownie, aby odblokowywać telefon odciskiem palca."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Ten odcisk palca (<xliff:g id="FINGERPRINT">%s</xliff:g>) nie jest już rozpoznawany."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Te odciski palców (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) nie są już rozpoznawane."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Ten odcisk palca (<xliff:g id="FINGERPRINT">%s</xliff:g>) nie jest już rozpoznawany. Skonfiguruj ponownie odblokowywanie odciskiem palca."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Te odciski palców (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) nie są już rozpoznawane. Skonfiguruj ponownie odblokowywanie odciskiem palca."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Skonfiguruj ponownie rozpoznawanie twarzy"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Twój model twarzy nie sprawdzał się dobrze i został usunięty. Skonfiguruj go ponownie, aby odblokowywać telefon za pomocą skanu twarzy."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Model Twojej twarzy nie jest już rozpoznawany. Skonfiguruj ponownie rozpoznawanie twarzy."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Skonfiguruj"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nie teraz"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm dla: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Przełącz konto"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Wycisz"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Kliknij, aby wyciszyć dźwięk"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"Przeglądarka"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"Kontakty"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"E-mail"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"SMS-y"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"Muzyka"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"Kalendarz"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"Kalkulator"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Mapy"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"Aplikacje"</string>
</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 7b4300a19b68..a6c07ef21064 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração por Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo Arcabouço de testes ativado"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Configuração incorreta do build do modo de usuário do sistema headless"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"O estado do modo de usuário do sistema headless deste dispositivo é diferente da configuração do build dele. Faça a redefinição de fábrica do dispositivo."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Console serial ativado"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"O desempenho foi impactado. Para desativar, verifique o carregador de inicialização."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental ativada"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, toque e pressione as duas teclas de volume por três segundos."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Escolha um recurso"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Escolha um recurso"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Escolha um recurso"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"O recurso será aberto na próxima vez que você tocar no botão de acessibilidade"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 2 dedos de baixo para cima na tela e solte rapidamente."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 3 dedos de baixo para cima na tela e solte rapidamente."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Mudando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"O PIN é curto demais. Deve ter pelo menos 4 dígitos."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Tente novamente mais tarde"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Visualização em tela cheia"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Para sair, deslize de cima para baixo na tela"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Entendi"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gire a tela para ter uma visualização melhor"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Abra o app <xliff:g id="NAME">%s</xliff:g> em tela cheia para ter uma melhor visualização"</string>
@@ -2428,19 +2419,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espaço privado"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Conteúdo de notificação sensível oculto"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo do app oculto no compartilhamento de tela por motivos de segurança"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo oculto no compartilhamento de tela por segurança"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurar o Desbloqueio por impressão digital de novo"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não é mais reconhecida."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não são mais reconhecidas."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não é mais reconhecida. Configure o \"Desbloqueio por impressão digital\" de novo."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não são mais reconhecidas. Configure o \"Desbloqueio por impressão digital\" de novo."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial de novo"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Seu modelo de rosto não estava funcionando bem e foi excluído. Configure de novo para desbloquear o smartphone com o rosto."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Seu modelo de rosto não é mais reconhecido. Configure o \"Desbloqueio facial\" de novo."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configuração"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora não"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Trocar usuário"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desativar som"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toque para silenciar"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index adc1d86ca619..6c8840862988 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração sem fios."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo de estrutura de teste ativado"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Efetue uma reposição de dados de fábrica para desativar o Modo de estrutura de teste."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Configuração da compilação do modo de utilizador do sistema sem interface incorreta"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"O estado do modo de utilizador do sistema sem interface deste dispositivo difere da respetiva configuração da compilação. Faça uma reposição de fábrica do dispositivo."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Consola de série ativada"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"O desempenho é afetado. Para desativar, selecione o carregador de arranque."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental ativada"</string>
@@ -1440,7 +1438,7 @@
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Sobreposição a outras apps"</string>
<string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"A app <xliff:g id="NAME">%s</xliff:g> sobrepõe-se a outras aplicações"</string>
- <string name="alert_windows_notification_title" msgid="6331662751095228536">"O <xliff:g id="NAME">%s</xliff:g> sobrepõe-se a outras app"</string>
+ <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> sobrepõe-se a outras app"</string>
<string name="alert_windows_notification_message" msgid="6538171456970725333">"Se não quer que a app <xliff:g id="NAME">%s</xliff:g> utilize esta funcionalidade, toque para abrir as definições e desative-a."</string>
<string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desativar"</string>
<string name="ext_media_checking_notification_title" msgid="8299199995416510094">"A verificar o <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas do volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, prima sem soltar ambas as teclas de volume novamente durante 3 segundos."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Escolha uma funcionalidade"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Escolha uma funcionalidade"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Escolha uma funcionalidade"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"A funcionalidade vai ser aberta da próxima vez que tocar no botão Acessibilidade"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"A funcionalidade vai ser aberta da próxima vez que usar este atalho. Deslize com 2 dedos a partir da parte inferior do ecrã e solte rapidamente."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"A funcionalidade vai ser aberta da próxima vez que usar este atalho. Deslize para cima com 3 dedos a partir da parte inferior do ecrã e solte rapidamente."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string>
<string name="user_switched" msgid="7249833311585228097">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
<string name="user_switching_message" msgid="1912993630661332336">"A mudar para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"O PIN é demasiado pequeno. Deve ter, no mínimo, 4 dígitos."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Tente mais tarde"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Visualização de ecrã inteiro"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Para sair, deslize rapidamente para baixo a partir da parte superior do ecrã"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rode para uma melhor visualização"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Abra <xliff:g id="NAME">%s</xliff:g> em ecrã inteiro para uma melhor visualização"</string>
@@ -2191,7 +2182,7 @@
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"O Bluetooth continuará ativado durante o modo de avião."</string>
<string name="car_loading_profile" msgid="8219978381196748070">"A carregar…"</string>
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # ficheiro}many{{file_name} + # ficheiros}other{{file_name} + # ficheiros}}"</string>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Não existem pessoas recomendadas com quem partilhar"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Sem pessoas recomendadas com quem partilhar"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista de aplicações"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Esta app não recebeu autorização de gravação, mas pode capturar áudio através deste dispositivo USB."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Página inicial"</string>
@@ -2435,12 +2426,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configure o Desbloqueio por impressão digital novamente"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A <xliff:g id="FINGERPRINT">%s</xliff:g> não estava a funcionar bem e foi eliminada"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"A <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam a funcionar bem e foram eliminadas"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A <xliff:g id="FINGERPRINT">%s</xliff:g> não estava a funcionar bem e foi eliminada. Configure-a novamente para desbloquear o telemóvel com a impressão digital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"A <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam a funcionar bem e foram eliminadas. Configure-as novamente para desbloquear o telemóvel com a sua impressão digital."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Já não é possível reconhecer <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Já não é possível reconhecer <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Já não é possível reconhecer <xliff:g id="FINGERPRINT">%s</xliff:g>. Configure o Desbloqueio por impressão digital novamente."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Já não é possível reconhecer <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. Configure o Desbloqueio por impressão digital novamente."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial novamente"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"O seu modelo de rosto não estava a funcionar bem e foi eliminado. Configure-o novamente para desbloquear o telemóvel com o rosto."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Já não é possível reconhecer o seu modelo de rosto. Configure o Desbloqueio facial novamente."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora não"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme de <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Mudar de utilizador"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desativar som"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toque para desativar o som"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"Navegador"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"Contactos"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"Email"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"SMS"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"Música"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"Calendário"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"Calculadora"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Maps"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"Aplicações"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 7b4300a19b68..a6c07ef21064 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração por Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo Arcabouço de testes ativado"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Configuração incorreta do build do modo de usuário do sistema headless"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"O estado do modo de usuário do sistema headless deste dispositivo é diferente da configuração do build dele. Faça a redefinição de fábrica do dispositivo."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Console serial ativado"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"O desempenho foi impactado. Para desativar, verifique o carregador de inicialização."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental ativada"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, toque e pressione as duas teclas de volume por três segundos."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Escolha um recurso"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Escolha um recurso"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Escolha um recurso"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"O recurso será aberto na próxima vez que você tocar no botão de acessibilidade"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 2 dedos de baixo para cima na tela e solte rapidamente."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 3 dedos de baixo para cima na tela e solte rapidamente."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Mudando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"O PIN é curto demais. Deve ter pelo menos 4 dígitos."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Tente novamente mais tarde"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Visualização em tela cheia"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Para sair, deslize de cima para baixo na tela"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Entendi"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gire a tela para ter uma visualização melhor"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Abra o app <xliff:g id="NAME">%s</xliff:g> em tela cheia para ter uma melhor visualização"</string>
@@ -2428,19 +2419,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espaço privado"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Conteúdo de notificação sensível oculto"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo do app oculto no compartilhamento de tela por motivos de segurança"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo oculto no compartilhamento de tela por segurança"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurar o Desbloqueio por impressão digital de novo"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não é mais reconhecida."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não são mais reconhecidas."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não é mais reconhecida. Configure o \"Desbloqueio por impressão digital\" de novo."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não são mais reconhecidas. Configure o \"Desbloqueio por impressão digital\" de novo."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial de novo"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Seu modelo de rosto não estava funcionando bem e foi excluído. Configure de novo para desbloquear o smartphone com o rosto."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Seu modelo de rosto não é mais reconhecido. Configure o \"Desbloqueio facial\" de novo."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configuração"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora não"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Trocar usuário"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desativar som"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toque para silenciar"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index e718f6452526..4a9471590c5a 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selectează pentru a dezactiva remedierea erorilor wireless."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modul Set de testare este activat"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Revino la setările din fabrică pentru a dezactiva modul Set de testare."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Configurare greșită a versiunii HSUM"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Starea Headless System User Mode a acestui dispozitiv diferă de configurarea versiunii. Revino la setările din fabrică ale dispozitivului."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Consola din serie este activată"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performanța este afectată. Pentru a dezactiva, verifică programul bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimentală activată"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S-au apăsat lung tastele de volum. S-a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S-au apăsat lung tastele de volum. S-a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Eliberează butoanele de volum. Pentru a activa <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, apasă lung pe ambele butoane de volum timp de trei secunde încă o dată."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Alege o funcție"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Alege o funcție"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Alege o funcție"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funcția se va deschide data viitoare când atingi butonul de accesibilitate"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funcția se va deschide data viitoare când folosești această comandă rapidă. Glisează în sus cu două degete din partea de jos a ecranului și ridică-le rapid."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funcția se va deschide data viitoare când folosești această comandă rapidă. Glisează în sus cu trei degete din partea de jos a ecranului și ridică-le rapid."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Mărire"</string>
<string name="user_switched" msgid="7249833311585228097">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Se comută la <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Codul PIN este prea scurt. Trebuie să aibă cel puțin 4 cifre."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Reîncearcă mai târziu"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Vizualizare pe ecran complet"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Pentru a ieși, glisează în jos din partea de sus a ecranului"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Am înțeles"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotește pentru o previzualizare mai bună"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Deschide <xliff:g id="NAME">%s</xliff:g> pe ecran complet pentru o imagine mai bună"</string>
@@ -2435,12 +2426,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cum funcționează"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"În așteptare..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurează din nou Deblocarea cu amprenta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nu funcționa bine și a fost ștearsă"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> și <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nu funcționau bine și au fost șterse"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nu funcționa bine și s-a șters. Configureaz-o din nou pentru a-ți debloca telefonul cu amprenta."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> și <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nu funcționau bine și s-au șters. Configurează-le din nou pentru a-ți debloca telefonul cu amprenta."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> nu mai poate fi recunoscută."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> și <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nu mai pot fi recunoscute."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> nu mai poate fi recunoscută. Configurează din nou Deblocarea cu amprenta."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> și <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nu mai pot fi recunoscute. Configurează din nou Deblocarea cu amprenta."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Reconfigurează Deblocarea facială"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Modelul tău facial nu funcționa bine și s-a șters. Configurează-l din nou pentru a-ți debloca telefonul folosindu-ți chipul."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Modelul tău facial nu mai poate fi recunoscut. Configurează din nou Deblocarea facială."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurează"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nu acum"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarmă pentru <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Schimbă utilizatorul"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Dezactivează sunetul"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Atinge pentru a dezactiva sunetul"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 45f93efe4045..96da7325ec5c 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1413,10 +1413,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Нажмите, чтобы отключить отладку по Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Тестовый режим включен"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Чтобы отключить тестовый режим, сбросьте настройки до заводских."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Неверная конфигурация сборки РКСП"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Состояние режима консольного системного пользователя для этого устройства отличается от его конфигурации сборки. Сбросьте настройки устройства до заводских."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Консоль последовательного порта включена"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Производительность устройства снижена. Чтобы отключить консоль, перейдите в загрузчик операционной системы."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Включена экспериментальная функция MTE"</string>
@@ -1761,18 +1759,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" включена."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" отключена."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Отпустите кнопки громкости. Чтобы включить <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, нажмите и удерживайте обе кнопки регулировки громкости в течение трех секунд."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Выберите функцию"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Выберите функцию"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Выберите функцию"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функция теперь будет включаться при нажатии кнопки специальных возможностей."</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функция теперь будет включаться при выполнении действия быстрого запуска. Проведите двумя пальцами по экрану снизу вверх."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функция теперь будет включаться при выполнении действия быстрого запуска. Проведите тремя пальцами по экрану снизу вверх."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увеличение"</string>
<string name="user_switched" msgid="7249833311585228097">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Смена профиля на \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
@@ -1895,8 +1887,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN-код должен содержать не менее 4 символов."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Повторите попытку позже."</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Полноэкранный режим"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Чтобы выйти, проведите вниз от верхнего края экрана"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"ОК"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Поверните, чтобы лучше видеть."</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Откройте приложение \"<xliff:g id="NAME">%s</xliff:g>\" в полноэкранном режиме, чтобы лучше видеть."</string>
@@ -1988,14 +1979,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Текущий вызов"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Фильтрация входящего вызова"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Без категории"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоакции"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Общение"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Новости"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Рекомендации"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Вы определяете важность этих уведомлений."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Важное (люди)"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Уведомление пользовательского приложения"</string>
@@ -2212,10 +2199,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Выбор действия для быстрого включения"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Быстрое включение"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Скрыть панель уведомлений"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Воспроизведение и пауза"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad – вверх"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad – вниз"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad – влево"</string>
@@ -2435,19 +2420,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Частное пространство"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Конфиденциальная информация в уведомлении скрыта"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Содержимое приложения исключено из демонстрации экрана в целях безопасности."</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Для безопасности содержимое приложения при демонстрации экрана скрыто."</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Автоматически подключено к системам спутниковой связи"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Вы можете отправлять и получать сообщения без доступа к мобильной сети или Wi-Fi."</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Открыть Сообщения"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Узнать принцип работы"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Обработка…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Настройте разблокировку по отпечатку пальца заново"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Отпечаток пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" оказался неудачным и был удален."</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Отпечатки пальцев \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" оказались неудачными и были удалены."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Отпечаток пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" оказался неудачным и был удален. Чтобы использовать разблокировку с помощью отпечатка пальца, настройте ее заново."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Отпечатки пальцев \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" оказались неудачными и были удалены. Чтобы использовать разблокировку с помощью отпечатка пальца, настройте ее заново."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Отпечаток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больше нельзя распознать."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Отпечатки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больше нельзя распознать."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Отпечаток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больше нельзя распознать. Настройте разблокировку по отпечатку пальца снова."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Отпечатки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больше нельзя распознать. Настройте разблокировку по отпечатку пальца снова."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Настройте фейсконтроль заново"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Модель лица оказалась неудачной и была удалена. Чтобы пользоваться фейсконтролем, настройте его заново."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Вашу модель лица больше нельзя распознать. Настройте фейсконтроль снова."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Настроить"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сейчас"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будильник пользователя <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Сменить пользователя"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Отключить звук"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Нажмите, чтобы отключить звук."</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index ae30a6489e17..6549a7ef8989 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"නොරැහැන් නිදොස්කරණය අබල කිරීමට තෝරන්න."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"පුරක පරීක්‍ෂා ප්‍රකාරය සබලයි"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"පුරක පරීක්‍ෂා ප්‍රකාරය අබල කිරීමට කර්මාන්තශාලා යළි සැකසීමක් ඉටු කරන්න."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"වැරදි HSUM තැනුම් වින්‍යාසය"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"මෙම උපාංගයෙහි හිස රහිත පද්ධති පරිශීලක ප්‍රකාරය තත්ත්වය එහි තැනුම් වින්‍යාසයෙන් වෙනස් වේ. උපාංගය කර්මාන්තශාලා යළි සකසන්න."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"අනුක්‍රමික කොන්සෝලය සබලයි"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"කාර්ය සාධනය බලපෑමට ලක් වී ඇත. අබල කිරීමට, ආරම්භකය පරීක්ෂා කරන්න."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"අත්හදා බැලීමේ MTE සබලයි"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාත්මකයි."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාවිරහිතයි."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"හඬ පරිමා යතුරු මුදා හරින්න. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> සක්‍රීය කිරීමට, හඬ පරිමා යතුරු දෙකම නැවත තත්පර 3ක් ඔබා අල්ලා සිටින්න."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"විශේෂාංගයක් තෝරා ගන්න"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"විශේෂාංගයක් තෝරා ගන්න"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"විශේෂාංගයක් තෝරා ගන්න"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"මීළඟ වතාවේ ඔබ ප්‍රවේශ්‍යතා බොත්තම තට්ටු කිරීමෙන් විශේෂාංගය විවෘත වේ"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ඔබ මෙම කෙටිමඟ භාවිතා කරන මීළඟ වතාවේ විශේෂාංගය විවෘත වනු ඇත. ඔබේ තිරයෙහි පහළ සිට ඇඟිලි 2කින් ඉහළට ස්වයිප් කර ඉක්මනින් නිදහස් කරන්න."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ඔබ මෙම කෙටිමඟ භාවිතා කරන මීළඟ වතාවේ විශේෂාංගය විවෘත වනු ඇත. ඔබේ තිරයෙහි පහළ සිට ඇඟිලි 3කින් ඉහළට ස්වයිප් කර ඉක්මනින් නිදහස් කරන්න."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"විශාලනය"</string>
<string name="user_switched" msgid="7249833311585228097">"දැනට සිටින පරිශීලකයා <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> වෙත මාරු කරමින්…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN කුඩා වැඩිය. ඉලක්කම් 4 වත් විය යුතුය."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"පසුව නැවත උත්සාහ කරන්න"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"මුළු තිරය බලමින්"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"පිටවීමට, ඔබේ තිරයෙහි ඉහළ සිට පහළට ස්වයිප් කරන්න"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"වැටහුණි"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"වඩා හොඳ දසුනක් සඳහා කරකවන්න"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"වඩා හොඳ දසුනක් සඳහා <xliff:g id="NAME">%s</xliff:g> පූර්ණ තිරයේ විවෘත කරන්න"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"එය ක්‍රියා කරන ආකාරය"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"පොරොත්තුයි..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ඇඟිලි සලකුණු අගුලු හැරීම නැවත සකසන්න"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> හොඳින් ක්‍රියා නොකළ අතර එය මකන ලදි"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> හොඳින් ක්‍රියා නොකළ අතර ඒවා මකන ලදි"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> හොඳින් ක්‍රියා නොකළේය, එය මකන ලදි ඇඟිලි සලකුණ මගින් ඔබේ දුරකථනය අගුලු හැරීමට එය නැවත සකසන්න."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> හොඳින් ක්‍රියා නොකළේය, කාර්යසාධනය දියුණූ කිරීමට ඒවා මකන ලදි. ඔබේ ඇඟිලි සලකුණ මගින් ඔබේ දුරකථනය අගුලු හැරීමට ඒවා නැවත සකසන්න."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක. ඇඟිලි සලකුණු අගුළු හැරීම නැවත පිහිටුවන්න."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක. ඇඟිලි සලකුණු අගුළු හැරීම නැවත පිහිටුවන්න."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"මුහුණෙන් අගුලු හැරීම නැවත සකසන්න"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ඔබේ මුහුණු මාදිලිය හොඳින් ක්‍රියා නොකරයි, එය මකන ලදි. මුහුණ මගින් ඔබේ දුරකථනය අගුලු හැරීමට එය නැවත සකසන්න."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"ඔබේ මුහුණු ආකෘතිය තවදුරටත් හඳුනා ගත නොහැක. මුහුණෙන් අගුළු හැරීම නැවත පිහිටුවන්න."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"සකසන්න"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"දැන් නොවේ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> සඳහා එලාමය"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"පරිශීලක මාරු කරන්න"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"නිහඬ කරන්න"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ශබ්දය නිශ්ශබ්ද කිරීමට තට්ටු කරන්න"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 0368c1325e3f..27500c4526d0 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1200,7 +1200,7 @@
<string name="low_internal_storage_view_text" msgid="8172166728369697835">"Niektoré systémové funkcie nemusia fungovať"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"V úložisku nie je dostatok voľného miesta pre systém. Zaistite, aby ste mali 250 MB voľného miesta a zariadenie reštartujte."</string>
<string name="app_running_notification_title" msgid="8985999749231486569">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je spustená"</string>
- <string name="app_running_notification_text" msgid="5120815883400228566">"Klepnutím zobrazíte ďalšie informácie alebo zastavíte aplikáciu."</string>
+ <string name="app_running_notification_text" msgid="5120815883400228566">"Klepnutím zobrazíte ďalšie informácie alebo aplikáciu zastavíte."</string>
<string name="ok" msgid="2646370155170753815">"OK"</string>
<string name="cancel" msgid="6908697720451760115">"Zrušiť"</string>
<string name="yes" msgid="9069828999585032361">"OK"</string>
@@ -1413,10 +1413,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Výberom zakážete bezdrôtové ladenie."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Režim správcu testov je aktivovaný"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Ak chcete zakázať režim správcu testov, obnovte výrobné nastavenia."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Nesprávna konfigurácia kompilácie pre režim konzolového systémového používateľa"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Stav režimu konzolového systémového používateľa pre toto zariadenie sa líši od jeho konfigurácie kompilácie. Obnovte výrobné nastavenia zariadenia."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Sériová konzola je povolená"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ovplyvňuje výkon. Ak ju chcete zakázať, skontrolujte zavádzací program systému."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Je zapnuté experimentálne rozšírenie MTE"</string>
@@ -1441,7 +1439,7 @@
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Zobrazenie cez iné aplikácie"</string>
<string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> sa zobrazuje cez iné aplikácie"</string>
- <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> sa zobrazuje cez iné aplikácie"</string>
+ <string name="alert_windows_notification_title" msgid="6331662751095228536">"Aplikácia <xliff:g id="NAME">%s</xliff:g> sa zobrazuje nad inými aplikáciami"</string>
<string name="alert_windows_notification_message" msgid="6538171456970725333">"Ak nechcete, aby aplikácia <xliff:g id="NAME">%s</xliff:g> používala túto funkciu, klepnutím otvorte nastavenia a vypnite ju."</string>
<string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Vypnúť"</string>
<string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Kontroluje sa <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1761,18 +1759,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Uvoľnite tlačidlá hlasitosti. Ak chcete zapnúť službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pridržte tri sekundy obe tlačidlá hlasitosti."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Vyberte funkciu"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Vyberte funkciu"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Vyberte funkciu"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Táto funkcia sa otvorí, keď nabudúce klepnete na tlačidlo dostupnosti"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Táto funkcia sa otvorí, keď nabudúce použijete túto skratku. Potiahnite zdola obrazovky dvoma prstami nahor a rýchlo uvoľnite."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Táto funkcia sa otvorí, keď nabudúce použijete túto skratku. Potiahnite zdola obrazovky troma prstami nahor a rýchlo uvoľnite."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zväčšenie"</string>
<string name="user_switched" msgid="7249833311585228097">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prepína sa na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1895,8 +1887,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Kód PIN je príliš krátky. Musí mať minimálne 4 číslice."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Skúste to neskôr"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Zobrazenie na celú obrazovku"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Ukončíte potiahnutím zhora obrazovky nadol"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Dobre"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Otočte zariadenie pre lepšie zobrazenie"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Otvorte <xliff:g id="NAME">%s</xliff:g> na celej obrazovke pre lepšie zobrazenie"</string>
@@ -2429,19 +2420,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Súkromný priestor"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Obsah citlivého upozornenia je skrytý"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Obsah aplikácie bol na účely zabezpečenia skrytý v zdieľaní obrazovky"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Obsah aplikácie je z bezpečnostných dôvodov pri zdieľaní obrazovky skrytý"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Automaticky pripojené k satelitu"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Správy môžete odosielať a prijímať bez mobilnej siete či siete Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvoriť Správy"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ako to funguje"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Nespracovaná…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Znova nastavte odomknutie odtlačkom prsta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Odtlačok <xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správne a bol odstránený"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Odtlačky <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovali správne a boli odstránené"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Odtlačok <xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správne a bol odstránený. Ak chcete odomykať telefón odtlačkom prsta, nastavte ho znova."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Odtlačky <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovali správne a boli odstránené. Ak chcete odomykať telefón odtlačkom prsta, nastavte ich znova."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> sa už nedari rozpoznať."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> sa už nedari rozpoznať."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> sa už nedari rozpoznať. Znova nastavte odomknutie odtlačkom prsta."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> sa už nedari rozpoznať. Znova nastavte odomknutie odtlačkom prsta."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Znova nastavte odomknutie tvárou"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Váš model tváre nefungoval správne a bol odstránený. Ak chcete odomykať telefón tvárou, nastavte ho znova."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Váš model tváre sa už nedari rozpoznať. Znova nastavte odomknutie tvárou."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastaviť"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Teraz nie"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Budík pre používateľa <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Prepnúť používateľa"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ignorovať"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Klepnutím vypnite zvuk"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 2da83ec48c1f..08043ecbbbca 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1413,10 +1413,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Izberite, če želite onemogočiti brezžično odpravljanje napak."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Način preizkusnega ogrodja je omogočen"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Če želite onemogočiti način preizkusnega ogrodja, ponastavite napravo na tovarniške nastavitve."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Napačna konfiguracija gradnje za način sistemskega uporabnika brez grafičnega uporabniškega vmesnika"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Stanje načina sistemskega uporabnika brez grafičnega uporabniškega vmesnika za to napravo se razlikuje od njene konfiguracije gradnje. Napravo ponastavite na tovarniške nastavitve."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola je omogočena"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Učinkovitost delovanja je slabša. Uporabo konzole lahko onemogočite v zagonskem nalagalniku."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Preizkusne razširitve MTE so omogočene"</string>
@@ -1761,18 +1759,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vklopljena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je izklopljena."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Spustite gumba za glasnost. Če želite vklopiti storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pritisnite in 3 sekunde pridržite oba gumba za glasnost."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Izberite funkcijo"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Izberite funkcijo"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Izberite funkcijo"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcija se bo odprla, ko se boste naslednjič dotaknili gumba za dostopnost"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija se bo odprla, ko boste naslednjič uporabili to bližnjico. Z dvema prstoma povlecite navzgor z dna zaslona in hitro spustite."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija se bo odprla, ko boste naslednjič uporabili to bližnjico. S tremi prsti povlecite navzgor z dna zaslona in hitro spustite."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povečava"</string>
<string name="user_switched" msgid="7249833311585228097">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Preklapljanje na uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1895,8 +1887,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN je prekratek. Imeti mora vsaj 4 števke."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Poskusite znova pozneje"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Vklopljen je celozaslonski način"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Če želite zapreti, povlecite navzdol z vrha zaslona"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Razumem"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zasukajte za boljši pregled."</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Aplikacijo <xliff:g id="NAME">%s</xliff:g> odprite v celozaslonskem načinu za boljši pregled."</string>
@@ -1988,14 +1979,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Aktivni klic"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Preverjanje dohodnega klica"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Nekategorizirano"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocije"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Družbeno"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Novice"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Priporočila"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Vi določite raven pomembnosti teh obvestil."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Pomembno zaradi udeleženih ljudi."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Obvestilo po meri iz aplikacije"</string>
@@ -2212,10 +2199,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Izbirnik zaslonske bližnjice za dostopnost"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Bližnjica za dostopnost"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Opusti zaslon z obvestili"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meni"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Predvajaj/začasno zaustavi predstavnost"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Smerni gumb gor"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Smerni gumb dol"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Smerni gumb levo"</string>
@@ -2442,12 +2427,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako deluje"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"V teku …"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vnovična nastavitev odklepanja s prstnim odtisom"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ni deloval pravilno in je bil izbrisan"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> in <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nista delovala pravilno in sta bila izbrisana"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ni deloval pravilno in je bil izbrisan. Znova ga nastavite, če želite telefon odklepati s prstnim odtisom."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> in <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nista delovala pravilno in sta bila izbrisana. Znova ju nastavite, če želite telefon odklepati s prstnim odtisom."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Odtisa »<xliff:g id="FINGERPRINT">%s</xliff:g>« ni več mogoče prepoznati."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Odtisov »<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>« in »<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>« ni več mogoče prepoznati."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Odtisa »<xliff:g id="FINGERPRINT">%s</xliff:g>« ni več mogoče prepoznati. Znova nastavite odklepanje s prstnim odtisom."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Odtisov »<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>« in »<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>« ni več mogoče prepoznati. Znova nastavite odklepanje s prstnim odtisom."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Vnovična nastavitev odklepanja z obrazom"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model obraza ni deloval pravilno in je bil izbrisan. Znova ga nastavite, če želite telefon odklepati z obrazom."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Vašega modela obraza ni več mogoče prepoznati. Znova nastavite odklepanje z obrazom."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastavi"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne zdaj"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za uporabnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Preklop uporabnika"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Izklop zvoka"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dotaknite se za izklop zvoka"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"Brskalnik"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"Stiki"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"E-pošta"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"SMS"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"Glasba"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"Koledar"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"Računalo"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Zemljevidi"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"Aplikacije"</string>
</resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 4b026fdb038f..9adae6714fbc 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Zgjidh për të çaktivizuar korrigjimin përmes Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modaliteti i lidhjes së testimit është aktivizuar"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Kryej një rivendosje në cilësimet e fabrikës për të çaktivizuar \"Modalitetin e lidhjes së testimit\"."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Konfigurim i gabuar i ndërtimit të modalitetit HSUM"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Gjendja e \"Modalitetit të përdoruesit për sistemin pa kokë\" për këtë pajisje ndryshon nga konfigurimi i ndërtimit. Rivendose pajisjen në gjendje fabrike."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Paneli komandues i serisë është aktivizuar"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ndikohet cilësia e funksionimit. Për ta çaktivizuar, kontrollo ngarkuesin e sistemit."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE eksperimentale u aktivizua"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tastet e volumit të mbajtura shtypur. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> i aktivizuar."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tastet e volumit të mbajtura shtypur. U çaktivizua \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lësho tastet e volumit. Për të aktivizuar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, shtyp dhe mbaj shtypur të dy tastet e volumit sërish për 3 sekonda."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Zgjidh një veçori"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Zgjidh një veçori"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Zgjidh një veçori"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Veçoria do të hapet herën tjetër kur të trokasësh te butoni i qasshmërisë"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Veçoria do të hapet herën tjetër kur të përdorësh këtë shkurtore. Rrëshqit shpejt lart me 2 gishta nga fundi i ekranit dhe lëshoje me shpejtësi."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Veçoria do të hapet herën tjetër kur të përdorësh këtë shkurtore. Rrëshqit shpejt lart me 3 gishta nga fundi i ekranit dhe lëshoje me shpejtësi."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zmadhimi"</string>
<string name="user_switched" msgid="7249833311585228097">"Emri i përdoruesit aktual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Po kalon në \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN-i është shumë i shkurtër. Duhet të jetë të paktën 4 shifra."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Provo sërish më vonë"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Po shikon ekranin e plotë"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Për të dalë, rrëshqit shpejt poshtë nga kreu i ekranit"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"E kuptova"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rrotullo për një pamje më të mirë"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Hape <xliff:g id="NAME">%s</xliff:g> në ekran të plotë për pamje më të mirë"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Telefonatë në vazhdim"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Po filtron një telefonatë hyrëse"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"E pakategorizuara"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promovime"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sociale"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Lajme"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekomandime"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ke caktuar rëndësinë e këtyre njoftimeve."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Është i rëndësishëm për shkak të personave të përfshirë."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Njoftim i personalizuar për aplikacionin"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Zgjedhësi i shkurtores së qasshmërisë në ekran"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Shkurtorja e qasshmërisë"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Hiq \"Strehën e njoftimeve\""</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menyja"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Luaj/vendos në pauzë median"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Lart në bllokun e drejtimit"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Poshtë në bllokun e drejtimit"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Majtas në bllokun e drejtimit"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Si funksionon"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Në pritje..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguro përsëri \"Shkyçjen me gjurmën e gishtit\""</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk po funksiononte mirë dhe u fshi"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk po funksiononin mirë dhe u fshinë"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk po funksiononte mirë dhe u fshi. Konfiguroje përsëri për ta shkyçur telefonin tënd me gjurmën e gishtit."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk po funksiononin mirë dhe u fshinë. Konfiguroji përsëri për ta shkyçur telefonin tënd me gjurmën e gishtit."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk mund të njihet më."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk mund të njihen më."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk mund të njihet më. Konfiguro përsëri \"Shkyçjen me gjurmën e gishtit\"."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk mund të njihen më. Konfiguro përsëri \"Shkyçjen me gjurmën e gishtit\"."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfiguro \"Shkyçjen me fytyrë\" përsëri"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Modeli yt i fytyrës nuk po funksiononte mirë dhe u fshi. Konfiguroje përsëri për ta shkyçur telefonin tënd me fytyrën."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Modeli yt i fytyrës nuk mund të njihet më. Konfiguro \"Shkyçjen me fytyrë\" përsëri."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfiguro"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Jo tani"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarmi për <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Ndërro përdoruesin"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Hiqi zërin"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Trokit për t\'i hequr zërin"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index cb37cc30ea99..6cea89f898d2 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -517,11 +517,11 @@
<string name="permlab_activityRecognition" msgid="1782303296053990884">"препознавање физичких активности"</string>
<string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ова апликација може да препозна физичке активности."</string>
<string name="permlab_camera" msgid="6320282492904119413">"снимање фотографија и видеа"</string>
- <string name="permdesc_camera" msgid="5240801376168647151">"Ова апликација може да снима слике и видео снимке помоћу камере док се апликација користи."</string>
- <string name="permlab_backgroundCamera" msgid="7549917926079731681">"да снима слике и видео снимке у позадини"</string>
+ <string name="permdesc_camera" msgid="5240801376168647151">"Ова апликација може да снима слике и видео помоћу камере док се апликација користи."</string>
+ <string name="permlab_backgroundCamera" msgid="7549917926079731681">"да снима слике и видео у позадини"</string>
<string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ова апликација може да снима фотографије и видео снимке помоћу камере у било ком тренутку."</string>
<string name="permlab_systemCamera" msgid="3642917457796210580">"Дозволите некој апликацији или услузи да приступа камерама система да би снимала слике и видео снимке"</string>
- <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ова привилегована системска апликација може да снима слике и видео снимке помоћу камере система у било ком тренутку. Апликација треба да има и дозволу android.permission.CAMERA"</string>
+ <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ова привилегована системска апликација може да снима слике и видео помоћу камере система у било ком тренутку. Апликација треба да има и дозволу android.permission.CAMERA"</string>
<string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Дозволите апликацији или услузи да добија повратне позиве о отварању или затварању уређаја са камером."</string>
<string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Ова апликација може да добија повратне позиве када се било који уређај са камером отвара или затвара (помоћу неке апликације)."</string>
<string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"Дозволите апликацији или услузи да приступа камери као корисник система без графичког корисничког интерфејса."</string>
@@ -1412,10 +1412,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Изаберите да бисте онемогућили бежично отклањање грешака."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Омогућен је режим пробног коришћења"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Обавите ресетовање на фабричка подешавања да бисте онемогућили режим пробног коришћења."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Погрешна HSUM конфигурација"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Статус корисничког режима система без графичког корисничког интерфејса за овај уређај разликује се од његове конфигурације. Ресетујте уређај на фабричка подешавања."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Серијска конзола је омогућена"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Перформансе су смањене. Да бисте онемогући конзолу, проверите покретачки програм."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Експериментални MTE је омогућен"</string>
@@ -1760,18 +1758,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Пустите тастере за јачину звука. Да бисте укључили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, поново притисните и задржите оба тастера за јачину звука 3 секунде."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Изаберите функцију"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Изаберите функцију"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Изаберите функцију"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функција ће се отворити када следећи пут додирнете дугме Приступачност"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функција ће се отворити када следећи пут будете користили ову пречицу. Превуците нагоре од дна екрана са 2 прста и брзо пустите."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функција ће се отворити када следећи пут будете користили ову пречицу. Превуците нагоре од дна екрана са 3 прста и брзо пустите."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увећање"</string>
<string name="user_switched" msgid="7249833311585228097">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Пребацивање на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1894,8 +1886,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN је прекратак. Мора да има бар 4 цифре."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Пробајте поново касније"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Приказује се цео екран"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Да бисте затворили, превуците надоле од врха екрана"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Важи"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Ротирајте ради бољег приказа"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Отворите апликацију <xliff:g id="NAME">%s</xliff:g> преко целог екрана да бисте боље видели"</string>
@@ -2435,12 +2426,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Принцип рада"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"На чекању..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поново подесите откључавање отиском прста"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> није функционисао и избрисали смо га"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> нису функционисали и избрисали смо их"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> није функционисао и избрисали смо га. Поново га подесите да бисте телефон откључавали отиском прста."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> нису функционисали и избрисали смо их. Поново их подесите да бисте телефон откључавали отиском прста."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> више не може да се препозна."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> више не могу да се препознају."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> више не може да се препозна. Поново подесите откључавање отиском прста."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> више не могу да се препознају. Поново подесите откључавање отиском прста."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Поново подесите откључавање лицем"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ваш модел лица није функционисао и избрисали смо га. Поново га подесите да бисте телефон откључавали лицем."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Ваш модел лица више не може да се препозна. Поново подесите откључавање лицем."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Подеси"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сада"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Аларм за: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Промени корисника"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Искључи звук"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Додирните да бисте искључили звук"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 06d32b8c09a5..53f1408b6115 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Välj för att inaktivera trådlös felsökning."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Läget för testverktyg har aktiverats"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Inaktivera testverktygsläget genom att göra en återställning till standardinställningarna."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Fel HSUM-byggkonfigurering"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Statusen för läget fönsterlös systemanvändare för den här enheten skiljer sig från dess byggkonfigurering. Återställ standardinställningarna på enheten."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Seriekonsolen är aktiverad"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Prestandan påverkas. Inaktivera via starthanteraren."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimentell MTE har aktiverats"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har aktiverats."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har inaktiverats."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Släpp volymknapparna. Du kan aktivera <xliff:g id="SERVICE_NAME">%1$s</xliff:g> genom att hålla båda volymknapparna nedtryckta i tre sekunder igen."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Välj en funktion"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Välj en funktion"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Välj en funktion"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funktionen öppnas nästa gång du trycker på tillgänglighetsknappen"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funktionen öppnas nästa gång du använder kortkommandot. Svep uppåt med två fingrar från skärmens nederkant och släpp snabbt."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funktionen öppnas nästa gång du använder kortkommandot. Svep uppåt med tre fingrar från skärmens nederkant och släpp snabbt."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Förstoring"</string>
<string name="user_switched" msgid="7249833311585228097">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Byter till <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Pinkoden är för kort. Måste vara minst fyra siffror."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Försök igen senare"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Visar på fullskärm"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Svep nedåt från skärmens överkant för att avsluta"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotera för att få en bättre vy"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Öppna <xliff:g id="NAME">%s</xliff:g> i fullskärmsläget för att få en bättre vy"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Så fungerar det"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Väntar …"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurera fingeravtryckslås igen"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerade inte bra och har raderats"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> och <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerade inte bra och har raderats"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerade inte bra och har raderats. Konfigurera det igen för att låsa upp telefonen med fingeravtryck."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> och <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerade inte bra och har raderats. Konfigurera dem igen för att låsa upp telefonen med fingeravtryck."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Det går inte längre att känna igen <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Det går inte längre att känna igen <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> och <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Det går inte längre att känna igen <xliff:g id="FINGERPRINT">%s</xliff:g>. Konfigurera fingeravtryckslås igen."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Det går inte längre att känna igen <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> och <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. Konfigurera fingeravtryckslås igen."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurera ansiktslås igen"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ansiktsmodellen fungerade inte bra och har raderats. Konfigurera den igen för att låsa upp telefonen med ansiktet."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Det går inte längre att känna igen din ansiktsmodell. Konfigurera ansiktslåset på nytt."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ställ in"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Inte nu"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm för <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Byt användare"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ljud av"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tryck för att stänga av ljudet"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index bb1a3637b1fe..c096d4b74135 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Chagua ili uzime utatuzi usiotumia waya."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Hali ya Muunganisho wa Majaribio imewashwa"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Rejesha mipangilio iliyotoka nayo kiwandani ili uzime hali ya Muunganisho wa Majaribio."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Mipangilio ya muundo wa HSUM si sahihi"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Hali ya Mtumiaji wa Mfumo usio na Skrini, Kiolesura au Vifaa Vinavyochomekwa katika kifaa hiki inatofautiana na mipangilio ya muundo wa kifaa. Tafadhali rejesha mipangilio ambayo kifaa kilitoka nayo kiwandani."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Muunganisho kupitia mlango umewashwa"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Utendaji unaathirika. lli uzime, teua programu ya kuwasha mfumo wa uendeshaji."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Kipengele cha majaribio cha MTE kimeruhusiwa"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Vitufe vya sauti vilivyoshikiliwa. Umewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Vitufe vya sauti vimeshikiliwa. Umezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Achilia vitufe vya sauti. Ili uwashe <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, bonyeza na ushikilie tena vitufe vyote vya sauti kwa sekunde 3."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Chagua kipengele"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Chagua kipengele"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Chagua kipengele"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Kipengele kitafunguka utakapogusa tena kitufe cha zana za ufikivu"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Kipengele kitafunguka utakapotumia tena njia hii ya mkato. Telezesha vidole 2 kuanzia sehemu ya chini ya skrini yako kwenda juu kisha uachilie haraka."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Kipengele kitafunguka utakapotumia tena njia hii ya mkato. Telezesha vidole 3 kuanzia sehemu ya chini ya skrini yako kwenda juu kisha uachilie haraka."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ukuzaji"</string>
<string name="user_switched" msgid="7249833311585228097">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Inaenda kwa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN ni fupi mno. Lazima iwe angalau tarakimu 4."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Jaribu tena baadaye"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Unatazama skrini nzima"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Telezesha kidole chini kutoka sehemu ya juu ya skrini yako ili ufunge"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Nimeelewa"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zungusha ili upate mwonekano bora"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Fungua <xliff:g id="NAME">%s</xliff:g> kwenye skrini nzima ili uone maudhui kwa urahisi"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Utaratibu wake"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Inashughulikiwa..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Weka tena mipangilio ya Kufungua kwa Alama ya Kidole"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Alama ya <xliff:g id="FINGERPRINT">%s</xliff:g> ilikuwa na hitilafu na imefutwa"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Alama za <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> zilikuwa na hitilafu na zimefutwa"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Alama ya <xliff:g id="FINGERPRINT">%s</xliff:g> ilikuwa na hitilafu na imefutwa. Iweke tena ili ufungue simu yako kwa alama ya kidole."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Alama za <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> zilikuwa na hitilafu na zimefutwa. Ziweke tena ili ufungue simu yako kwa alama ya kidole."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> haitambuliki tena."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> havitambuliki tena."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> haitambuliki tena. Weka tena mipangilio ya Kufungua kwa Alama ya Kidole."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> havitambuliki tena. Weka tena mipangilio ya Kufungua kwa Alama ya Kidole."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Weka tena mipangilio ya Kufungua kwa Uso"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Muundo wako wa uso ulikuwa na hitilafu na umefutwa. Uweke tena ili ufungue simu yako kwa uso."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Muundo wa uso wako hautambuliki tena. Weka tena mipangilio ya Kufungua kwa Uso."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Weka mipangilio"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Si sasa"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"King\'ora cha <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Badilisha mtumiaji"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Zima sauti"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Gusa ili uzime sauti"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 8246af869a50..429862b65a82 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"வைஃபை பிழைதிருத்தத்தை முடக்க தேர்ந்தெடுக்கவும்."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"\'தன்னியக்க சோதனைப்\' பயன்முறை இயக்கப்பட்டது"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"’தன்னியக்க சோதனைப்\' பயன்முறையை முடக்க ஆரம்பநிலைக்கு மீட்டமைக்கவும்."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"தவறான HSUM பதிப்பு உள்ளமைப்பு"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"இந்தச் சாதனத்தின் காட்சி இடைமுகமற்ற சிஸ்டம் பயனர் பயன்முறையின் நிலை அதன் பதிப்பு உள்ளமைப்பிலிருந்து வேறுபடுகிறது. சாதனத்தை ஆரம்பநிலைக்கு மீட்டமையுங்கள்."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"சீரியல் கன்சோல் இயக்கப்பட்டது"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"செயல்திறன் பாதிக்கப்பட்டுள்ளது. முடக்குவதற்கு பூட்லோடரைத் தேர்வுசெய்யவும்."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"பரிசோதனை MTE இயக்கப்பட்டது"</string>
@@ -1527,7 +1525,7 @@
<string name="forward_intent_to_work" msgid="3620262405636021151">"பணிக் கணக்கில் பயன்பாட்டைப் பயன்படுத்துகிறீர்கள்"</string>
<string name="input_method_binding_label" msgid="1166731601721983656">"உள்ளீட்டு முறை"</string>
<string name="sync_binding_label" msgid="469249309424662147">"ஒத்திசை"</string>
- <string name="accessibility_binding_label" msgid="1974602776545801715">"அணுகல்தன்மை"</string>
+ <string name="accessibility_binding_label" msgid="1974602776545801715">"மாற்றுத்திறன் வசதி"</string>
<string name="wallpaper_binding_label" msgid="1197440498000786738">"வால்பேப்பர்"</string>
<string name="chooser_wallpaper" msgid="3082405680079923708">"வால்பேப்பரை மாற்று"</string>
<string name="notification_listener_binding_label" msgid="2702165274471499713">"அறிவிப்புகளைக் கண்காணிக்கும் சேவை"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆன் செய்யப்பட்டது."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆஃப் செய்யப்பட்டது."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ஒலியளவு பட்டன்களை அழுத்துவதை நிறுத்துங்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> சேவையை இயக்க, ஒலியளவு பட்டன்கள் இரண்டையும் 3 வினாடிகளுக்கு மீண்டும் அழுத்திப் பிடிக்கவும்."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"அம்சத்தைத் தேர்வுசெய்யுங்கள்"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"அம்சத்தைத் தேர்வுசெய்யுங்கள்"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"அம்சத்தைத் தேர்வுசெய்யுங்கள்"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"அடுத்த முறை மாற்றுத்திறன் பட்டனை நீங்கள் தட்டும்போது அம்சம் திறக்கும்"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"அடுத்த முறை இந்த ஷார்ட்கட்டை நீங்கள் பயன்படுத்தும்போது அம்சம் திறக்கும். 2 விரல்களால் திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்து விரைவாக விரல்களை எடுக்கவும்."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"அடுத்த முறை இந்த ஷார்ட்கட்டை நீங்கள் பயன்படுத்தும்போது அம்சம் திறக்கும். 3 விரல்களால் திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்து விரைவாக விரல்களை எடுக்கவும்."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"பெரிதாக்கல்"</string>
<string name="user_switched" msgid="7249833311585228097">"நடப்பு பயனர் <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>க்கு மாறுகிறது…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"பின் மிகவும் சிறியதாக உள்ளது. குறைந்தது 4 இலக்கங்கள் இருக்க வேண்டும்."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"மீண்டும் முயற்சிக்கவும்"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"முழுத் திரையில் காட்டுகிறது"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"வெளியேற, உங்கள் திரையின் மேலிருந்து கீழ்நோக்கி ஸ்வைப் செய்யவும்"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"புரிந்தது"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"சிறந்த காட்சிக்கு சுழற்றுங்கள்"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"சிறந்த காட்சிக்கு, <xliff:g id="NAME">%s</xliff:g> ஆப்ஸை முழுத்திரைப் பயன்முறையில் திறக்கவும்"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"செயலில் இருக்கும் அழைப்பு"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"உள்வரும் அழைப்பை மதிப்பாய்வு செய்கிறது"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"வகைப்படுத்தப்படாதவை"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"சலுகைகள்"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"சமூகம்"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"செய்திகள்"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"பரிந்துரைகள்"</string>
<string name="importance_from_user" msgid="2782756722448800447">"இந்த அறிவிப்புகளின் முக்கியத்துவத்தை அமைத்துள்ளீர்கள்."</string>
<string name="importance_from_person" msgid="4235804979664465383">"ஈடுபட்டுள்ளவர்களின் காரணமாக, இது முக்கியமானது."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"பிரத்தியேக ஆப்ஸ் அறிவிப்பு"</string>
@@ -2072,7 +2059,7 @@
<string name="app_category_news" msgid="1172762719574964544">"செய்திகளும் பத்திரிகைகளும்"</string>
<string name="app_category_maps" msgid="6395725487922533156">"வரைபடங்களும் வழிசெலுத்தலும்"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"உற்பத்தித்திறன்"</string>
- <string name="app_category_accessibility" msgid="6643521607848547683">"அணுகல்தன்மை"</string>
+ <string name="app_category_accessibility" msgid="6643521607848547683">"மாற்றுத்திறன் வசதி"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"சாதனச் சேமிப்பகம்"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB பிழைதிருத்தம்"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"மணி"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"திரையிலுள்ள அணுகல்தன்மை ஷார்ட்கட்டிற்கான தேர்வி"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"அணுகல்தன்மை ஷார்ட்கட்"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"அறிவிப்பு விவரத்தை நிராகரி"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"மெனு"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"மீடியாவை இயக்குதல்/இடைநிறுத்துதல்"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"மேல் திசை காட்டும் பட்டன்"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"கீழ் திசை காட்டும் பட்டன்"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"இடது திசை காட்டும் பட்டன்"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"இது செயல்படும் விதம்"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"நிலுவையிலுள்ளது..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"கைரேகை அன்லாக் அம்சத்தை மீண்டும் அமையுங்கள்"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அது நீக்கப்பட்டது"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> மற்றும் <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அவை நீக்கப்பட்டன"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அது நீக்கபட்டது. கைரேகை மூலம் உங்கள் மொபைலை அன்லாக் செய்ய அதை மீண்டும் அமையுங்கள்."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> மற்றும் <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அவை நீக்கப்பட்டன. கைரேகை மூலம் உங்கள் மொபைலை அன்லாக் செய்ய அவற்றை மீண்டும் அமையுங்கள்."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>ஐ இனி அடையாளம் காண முடியாது."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ஆகியவற்றை இனி அடையாளம் காண முடியாது."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>ஐ இனி அடையாளம் காண முடியாது. கைரேகை அன்லாக் அம்சத்தை மீண்டும் அமையுங்கள்."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ஆகியவற்றை இனி அடையாளம் காண முடியாது. கைரேகை அன்லாக் அம்சத்தை மீண்டும் அமையுங்கள்."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"\'முகம் காட்டித் திறத்தல்\' அம்சத்தை மீண்டும் அமையுங்கள்"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"உங்கள் முகத் தோற்றப் பதிவு சரியாகச் செயல்படவில்லை என்பதால் அது நீக்கப்பட்டது. உங்கள் முகத்தைப் பயன்படுத்தி மொபைலை அன்லாக் செய்ய அதை மீண்டும் அமையுங்கள்."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"உங்கள் முகத் தோற்றப் பதிவை இனி அடையாளம் காண முடியாது. முகம் காட்டித் திறத்தல் அம்சத்தை மீண்டும் அமையுங்கள்."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"அமை"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"இப்போது வேண்டாம்"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>க்கான அலாரம்"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"பயனரை மாற்றுங்கள்"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ஒலியடக்கு"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ஒலியடக்க தட்டவும்"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 749a5d672da1..830c4f64e37f 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"వైర్‌లెస్ డీబగ్గింగ్‌ను డిజేబుల్ చేయడానికి ఎంచుకోండి."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"పరీక్ష నియంత్రణ మోడ్ ప్రారంభించబడింది"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"పరీక్ష నియంత్రణ మోడ్‌ను నిలిపివేయడానికి ఫ్యాక్టరీ రీసెట్‍‌ను అమలు చేయండి."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"తప్పు HSUM బిల్డ్ కాన్ఫిగరేషన్"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"ఈ పరికరానికి సంబంధించిన హెడ్‌లెస్ సిస్టమ్ యూజర్ మోడ్ స్టేట్, దాని బిల్డ్ కాన్ఫిగరేషన్ కంటే భిన్నంగా ఉంటుంది. దయచేసి పరికరాన్ని ఫ్యాక్టరీ రీసెట్ చేయండి."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"సీరియల్ కన్సోల్ ప్రారంభించబడింది"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"పని తీరు ప్రభావితమైంది. నిలిపివేయడానికి, బూట్‌లోడర్‌ను చెక్ చేయండి."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ప్రయోగాత్మక MTE ఎనేబుల్ చేయబడింది"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"వాల్యూమ్ కీలను రిలీజ్ చేయండి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>‌ను ఆన్ చేయడానికి, రెండు వాల్యూమ్ కీలను మళ్లీ 3 సెకన్ల పాటు నొక్కి పట్టుకోండి."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"ఒక ఫీచర్‌ను ఎంచుకోండి"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"ఒక ఫీచర్‌ను ఎంచుకోండి"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"ఒక ఫీచర్‌ను ఎంచుకోండి"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"తర్వాతిసారి మీరు యాక్సెసిబిలిటీ బటన్‌ను ట్యాప్ చేసినప్పుడు ఈ ఫీచర్ తెరుచుకుంటుంది"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"తర్వాతిసారి మీరు ఈ షార్ట్‌కట్‌ను ఉపయోగించినప్పుడు ఈ ఫీచర్ తెరుచుకుంటుంది. మీ స్క్రీన్ దిగువ నుండి 2 వేళ్లతో పైకి స్వైప్ చేసి, వెంటనే వదలండి."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"తర్వాతిసారి మీరు ఈ షార్ట్‌కట్‌ను ఉపయోగించినప్పుడు ఈ ఫీచర్ తెరుచుకుంటుంది. మీ స్క్రీన్ దిగువ నుండి 3 వేళ్లతో పైకి స్వైప్ చేసి, వెంటనే వదలండి."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"మ్యాగ్నిఫికేషన్"</string>
<string name="user_switched" msgid="7249833311585228097">"ప్రస్తుత వినియోగదారు <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> యూజర్‌కు స్విచ్ అవుతోంది…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"పిన్‌ చాలా చిన్నదిగా ఉంది. తప్పనిసరిగా కనీసం 4 అంకెలు ఉండాలి."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"తర్వాత మళ్లీ ట్రై చేయండి"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"ఫుల్-స్క్రీన్‌లో వీక్షిస్తున్నారు"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"ఎగ్జిట్ అవ్వడానికి, మీ స్క్రీన్ పై నుండి కిందికి స్వైప్ చేయండి"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"అర్థమైంది"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"మెరుగైన వీక్షణ కోసం తిప్పండి"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"మెరుగైన వీక్షణ కోసం <xliff:g id="NAME">%s</xliff:g>‌ను ఫుల్ స్క్రీన్‌లో తెరవండి"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ఇది ఎలా పని చేస్తుంది"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"పెండింగ్‌లో ఉంది..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"వేలిముద్ర అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> సరిగ్గా పని చేయడం లేదు, తొలగించబడింది"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> బాగా పని చేయడం లేదు, తొలగించబడ్డాయి"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> సరిగ్గా పని చేయడం లేదు, తొలగించబడింది. వేలిముద్రతో మీ ఫోన్‌ను అన్‌లాక్ చేయడానికి దాన్ని మళ్లీ సెటప్ చేయండి."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> బాగా పని చేయడం లేదు, తొలగించబడ్డాయి. మీ వేలిముద్రతో మీ ఫోన్‌ను అన్‌లాక్ చేయడానికి వాటిని మళ్లీ సెటప్ చేయండి."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>‌ను ఇకపై గుర్తించడం సాధ్యం కాదు."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‌లను ఇకపై గుర్తించడం సాధ్యం కాదు."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>‌ను ఇకపై గుర్తించడం సాధ్యం కాదు. వేలిముద్ర అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‌లను ఇకపై గుర్తించడం సాధ్యం కాదు. వేలిముద్ర అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ఫేస్ అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"మీ ఫేస్ మోడల్ సరిగ్గా పని చేయడం లేదు, తొలగించబడింది. ఫేస్‌తో మీ ఫోన్‌ను అన్‌లాక్ చేయడానికి దాన్ని మళ్లీ సెటప్ చేయండి."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"మీ ఫేస్ మోడల్‌ను ఇకపై గుర్తించడం సాధ్యం కాదు. ఫేస్ అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"సెటప్ చేయండి"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ఇప్పుడు కాదు"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> కోసం అలారం"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"యూజర్‌ను మార్చండి"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"మ్యూట్ చేయండి"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"సౌండ్‌ను మ్యూట్ చేయడానికి ట్యాప్ చేయండి"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index f27155fb8278..b4f39791fb0d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"เลือกเพื่อปิดใช้การแก้ไขข้อบกพร่องผ่าน Wi-Fi"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"โหมดโปรแกรมทดสอบอัตโนมัติเปิดใช้อยู่"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"รีเซ็ตเป็นค่าเริ่มต้นเพื่อปิดใช้โหมดโปรแกรมทดสอบอัตโนมัติ"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"การกำหนดค่าบิลด์ HSUM ไม่ถูกต้อง"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"สถานะโหมดผู้ใช้ระบบแบบไม่มีส่วนหัวของอุปกรณ์นี้แตกต่างจากการกำหนดค่าบิลด์ โปรดรีเซ็ตอุปกรณ์เป็นค่าเริ่มต้น"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"เปิดใช้คอนโซลการเรียงอันดับแล้ว"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"ประสิทธิภาพได้รับผลกระทบ ตรวจสอบ Bootloader เพื่อปิดใช้งาน"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"เปิดใช้ MTE เชิงทดสอบอยู่"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว เปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว ปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ปล่อยปุ่มปรับระดับเสียง หากต้องการเปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ให้กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้อีกครั้งเป็นเวลา 3 วินาที"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"เลือกฟีเจอร์"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"เลือกฟีเจอร์"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"เลือกฟีเจอร์"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ฟีเจอร์นี้จะเปิดขึ้นในครั้งถัดไปที่คุณแตะปุ่มการช่วยเหลือพิเศษ"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ฟีเจอร์นี้จะเปิดขึ้นในครั้งถัดไปที่คุณใช้ทางลัดนี้ ใช้ 2 นิ้วปัดขึ้นจากด้านล่างของหน้าจอและปล่อยอย่างรวดเร็ว"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ฟีเจอร์นี้จะเปิดขึ้นในครั้งถัดไปที่คุณใช้ทางลัดนี้ ใช้ 3 นิ้วปัดขึ้นจากด้านล่างของหน้าจอและปล่อยอย่างรวดเร็ว"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"การขยาย"</string>
<string name="user_switched" msgid="7249833311585228097">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"กำลังเปลี่ยนเป็น<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN สั้นเกินไป ต้องมีอย่างน้อย 4 หลัก"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"ลองอีกครั้งในภายหลัง"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"กำลังดูแบบเต็มหน้าจอ"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"หากต้องการออก ให้ปัดลงจากด้านบนของหน้าจอ"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"รับทราบ"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"หมุนเพื่อรับมุมมองที่ดียิ่งขึ้น"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"เปิด <xliff:g id="NAME">%s</xliff:g> ในโหมดเต็มหน้าจอเพื่อรับมุมมองที่ดียิ่งขึ้น"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"สายที่สนทนาอยู่"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"กำลังสกรีนสายเรียกเข้า"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"ไม่จัดอยู่ในหมวดหมู่ใดๆ"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"โปรโมชัน"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"โซเชียล"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ข่าว"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"การแนะนำ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"คุณตั้งค่าความสำคัญของการแจ้งเตือนเหล่านี้"</string>
<string name="importance_from_person" msgid="4235804979664465383">"ข้อความนี้สำคัญเนื่องจากบุคคลที่เกี่ยวข้อง"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"การแจ้งเตือนที่กำหนดเองของแอป"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ตัวเลือกทางลัดการช่วยเหลือพิเศษบนหน้าจอ"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ทางลัดการช่วยเหลือพิเศษ"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ปิดหน้าต่างแจ้งเตือน"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"เมนู"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"เล่น/หยุดสื่อชั่วคราว"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ขึ้น"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ลง"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ซ้าย"</string>
@@ -2433,19 +2418,32 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"พื้นที่ส่วนตัว"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"เนื้อหาการแจ้งเตือนที่ละเอียดอ่อนซ่อนอยู่"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ซ่อนเนื้อหาแอปจากการแชร์หน้าจอเพื่อความปลอดภัย"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ซ่อนเนื้อหาแอปจากการแชร์หน้าจอแล้วเพื่อความปลอดภัย"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"เชื่อมต่อกับดาวเทียมโดยอัตโนมัติ"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"คุณรับส่งข้อความผ่านดาวเทียมได้โดยไม่ต้องใช้เครือข่ายมือถือหรือ Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"เปิด Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"วิธีการทำงาน"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"รอดำเนินการ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ตั้งค่าการปลดล็อกด้วยลายนิ้วมืออีกครั้ง"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ทำงานได้ไม่ดีและถูกลบออกไปแล้ว"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> และ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ทำงานได้ไม่ดีและถูกลบออกไปแล้ว"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g>ทำงานได้ไม่ดีและถูกลบออกไปแล้ว ตั้งค่าอีกครั้งเพื่อปลดล็อกโทรศัพท์ด้วยลายนิ้วมือ"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> และ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ทำงานได้ไม่ดีและถูกลบออกไปแล้ว ตั้งค่าอีกครั้งเพื่อปลดล็อกโทรศัพท์ด้วยลายนิ้วมือ"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"ระบบไม่จดจำ <xliff:g id="FINGERPRINT">%s</xliff:g> อีกต่อไป"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"ระบบไม่จดจำ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> และ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> อีกต่อไป"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"ระบบไม่จดจำ <xliff:g id="FINGERPRINT">%s</xliff:g> อีกต่อไป ตั้งค่าการปลดล็อกด้วยลายนิ้วมืออีกครั้ง"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"ระบบไม่จดจำ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> และ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> อีกต่อไป ตั้งค่าการปลดล็อกด้วยลายนิ้วมืออีกครั้ง"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ตั้งค่าการปลดล็อกด้วยใบหน้าอีกครั้ง"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"รูปแบบใบหน้าของคุณทำงานได้ไม่ดีและถูกลบออกไปแล้ว ตั้งค่าอีกครั้งเพื่อปลดล็อกโทรศัพท์ด้วยใบหน้า"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"ระบบไม่จดจำรูปแบบใบหน้าของคุณอีกต่อไป ตั้งค่าการปลดล็อกด้วยใบหน้าอีกครั้ง"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ตั้งค่า"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ไว้ทีหลัง"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"นาฬิกาปลุกสำหรับ <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"สลับผู้ใช้"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ปิดเสียง"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"แตะเพื่อปิดเสียง"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"เบราว์เซอร์"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"รายชื่อติดต่อ"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"อีเมล"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"SMS"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"เพลง"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"ปฏิทิน"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"เครื่องคิดเลข"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"แผนที่"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"แอปพลิเคชัน"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index ecaf0049c63b..bebc2b45eb08 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Piliin para i-disable ang wireless na pag-debug."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Naka-enable ang Test Harness Mode"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Mag-factory reset para i-disable ang Test Harness Mode."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Maling configuration ng build ng HSUM"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Ang status na Headless System User Mode ng device na ito ay naiiba sa configuration ng build nito. Paki-factory reset ang device."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Naka-enable ang serial console"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Naaapektuhan ang performance. Para i-disable, lagyan ng check ang bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Na-enable ang Pang-eksperimentong MTE"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pinindot nang matagal ang volume keys. Na-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pinindot nang matagal ang volume keys. Na-off ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Bitawan ang mga volume key. Para i-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, muling pindutin nang matagal ang dalawang volume key sa loob ng 3 segundo."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Pumili ng feature"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Pumili ng feature"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Pumili ng feature"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Magbubukas ang feature sa susunod na i-tap mo ang button ng accessibility"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Magbubukas ang feature sa susunod na gamitin mo ang shortcut na ito. Mag-swipe pataas gamit ang 2 daliri mula sa ibaba ng iyong screen at mabilis na i-release."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Magbubukas ang feature sa susunod na gamitin mo ang shortcut na ito. Mag-swipe pataas gamit ang 3 daliri mula sa ibaba ng iyong screen at mabilis na i-release."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pag-magnify"</string>
<string name="user_switched" msgid="7249833311585228097">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Lumilipat kay <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Masyadong maikli ang PIN. Hindi dapat mas maikli sa 4 na digit."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Subukang muli sa ibang pagkakataon"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Panonood sa full screen"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Para lumabas, mag-swipe pababa mula sa itaas ng iyong screen"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Nakuha ko"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"I-rotate para sa mas magandang view"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Buksan ang <xliff:g id="NAME">%s</xliff:g> sa full screen para sa mas magandang view"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Kasalukuyang tawag"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Nagsi-screen ng papasok na tawag"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Di-nakategorya"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Mga Promosyon"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Balita"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Mga Rekomendasyon"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ikaw ang magtatakda sa kahalagahan ng mga notification na ito."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Mahalaga ito dahil sa mga taong kasangkot."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom na notification ng app"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Tagapili ng Shortcut ng Accessibility sa Screen"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Shortcut ng Accessibility"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"I-dismiss ang Notification Shade"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"I-Play/I-Pause ang Media"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Up"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Down"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Left"</string>
@@ -2440,12 +2425,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Paano ito gumagana"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Nakabinbin..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"I-set up ulit ang Pag-unlock Gamit ang Fingerprint"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT">%s</xliff:g> at na-delete ito"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> at <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> at na-delete ang mga ito"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT">%s</xliff:g> at na-delete na ito. I-set up ulit ito para ma-unlock ang iyong telepono sa pamamagitan ng fingerprint."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> at <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> at na-delete na ang mga ito. I-set up ulit ang mga ito para ma-unlock ang iyong telepono gamit ang fingerprint mo."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Hindi na makilala ang <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Hindi na makilala ang <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> at <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Hindi na makilala ang <xliff:g id="FINGERPRINT">%s</xliff:g>. I-set up ulit ang Pag-unlock Gamit ang Fingerprint."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Hindi na makilala ang <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> at <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. I-set up ulit ang Pag-unlock Gamit ang Fingerprint."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"I-set up ulit ang Pag-unlock Gamit ang Mukha"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Hindi gumagana nang maayos ang iyong face model at na-delete na ito. I-set up ulit ito para ma-unlock ang iyong telepono sa pamamagitan ng mukha."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Hindi na makilala ang iyong face model. I-set up ulit ang Pag-unlock Gamit ang Mukha."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"I-set up"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Huwag muna"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm para kay <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Magpalit ng user"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"I-mute"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"I-tap para i-mute ang tunog"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"Browser"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"Mga Contact"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"Email"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"SMS"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"Musika"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"Kalendaryo"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"Calculator"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Mga Mapa"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"Mga Application"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 6c948997f405..72404af417fb 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Kablosuz hata ayıklamayı devre dışı bırakmak için seçin."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Bandı Modu etkin"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Test Bandı Modu\'nu devre dışı bırakmak için cihazı fabrika ayarlarına sıfırlayın."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Gözetimsiz Sistem Kullanıcı Modu derleme yapılandırması yanlış"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Bu cihazın Gözetimsiz Sistem Kullanıcı Modu durumu, derleme yapılandırmasından farklı. Lütfen cihazı fabrika ayarlarına sıfırlayın."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Seri konsol etkinleştirildi"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performans etkilendi. Devre dışı bırakmak için bootloader\'ı kontrol edin."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Deneysel MTE etkinleştirildi"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> açıldı."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kapatıldı."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Ses seviyesi tuşlarını bırakın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini etkinleştirmek için her iki ses seviyesi tuşuna yeniden basıp 3 saniye boyunca basılı tutun."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Özellik seçin"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Özellik seçin"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Özellik seçin"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Özellik, erişilebilirlik düğmesine bir sonraki dokunuşunuzda açılır."</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Özellik, bu kısayolu bir sonraki kullanışınızda açılır. Ekranın alt kısmından 2 parmağınızla yukarı doğru kaydırın ve hızlıca bırakın."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Özellik, bu kısayolu bir sonraki kullanışınızda açılır. Ekranın alt kısmından 3 parmağınızla yukarı doğru kaydırın ve hızlıca bırakın."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Büyütme"</string>
<string name="user_switched" msgid="7249833311585228097">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adlı kullanıcıya geçiliyor…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN çok kısa. En az 4 basamaklı olmalı."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Daha sonra tekrar deneyin"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Tam ekran olarak görüntüleme"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Çıkmak için ekranın üst kısmından aşağı doğru kaydırın"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Anladım"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Daha iyi bir görünüm elde etmek için ekranı döndürün"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Daha iyi görünüm için <xliff:g id="NAME">%s</xliff:g> uygulamasını açın"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"İşleyiş şekli"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Bekliyor..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Parmak İzi Kilidi\'ni tekrar kurun"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> iyi çalışmadığı için silindi"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> iyi çalışmadığı için silindi"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> iyi çalışmadığı için silindi. Telefonunuzun kilidini parmak iziyle açmak için tekrar kurun."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> iyi çalışmadığı için silindi. Telefonunuzun kilidini parmak izinizle açmak için tekrar kurun."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> artık tanınamayacak."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artık tanınamayacak."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> artık tanınamayacak. Parmak İzi Kilidi\'ni tekrar kurun."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artık tanınamayacak. Parmak İzi Kilidi\'ni tekrar kurun."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Yüz Tanıma Kilidi\'ni tekrar kurun"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Yüz modeliniz iyi çalışmadığı için silindi. Telefonunuzun kilidini yüzünüzle açmak için tekrar kurun."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Yüz modeliniz artık tanınamayacak. Yüz Tanıma Kilidi\'ni tekrar kurun."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ayarla"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Şimdi değil"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> için alarm"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Kullanıcı değiştir"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Sesi kapat"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Sesi kapat düğmesine dokunun"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index d34e80188b02..246cce925e9a 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1413,10 +1413,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Натисніть, щоб вимкнути налагодження."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Увімкнено режим автоматизованого тестування"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Щоб вимкнути режим автоматизованого тестування, відновіть заводські налаштування."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Неправильна конфігурація складання HSUM"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Стан пристрою в режимі користувача системи без графічного інтерфейсу (HSUM) відрізняється від його конфігурації складання. Скиньте налаштування пристрою."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Послідовну консоль увімкнено"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Продуктивність зазнала впливу. Щоб вимкнути, перевірте завантажувач операційної системи."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Експериментальний запуск з MTE ввімкнено"</string>
@@ -1761,18 +1759,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> увімкнено."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> вимкнено."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Відпустіть клавіші гучності. Щоб увімкнути сервіс <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, натисніть і втримуйте обидві клавіші гучності протягом 3 секунд."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Виберіть функцію"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Виберіть функцію"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Виберіть функцію"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функція відкриється, коли ви наступного разу натиснете кнопку функцій доступності"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функція відкриється, коли ви наступного разу скористаєтеся цією швидкою командою. Проведіть двома пальцями вгору від низу екрана й швидко відпустіть."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функція відкриється, коли ви наступного разу скористаєтеся цією швидкою командою. Проведіть трьома пальцями вгору від низу екрана й швидко відпустіть."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Збільшення"</string>
<string name="user_switched" msgid="7249833311585228097">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Перехід у режим \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
@@ -1895,8 +1887,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN-код закороткий. Має бути принаймні 4 цифри."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Спробуйте пізніше"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Перегляд на весь екран"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Щоб вийти, проведіть пальцем униз від верхнього краю екрана"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Оберніть для кращого огляду"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Для кращого огляду відкрийте додаток <xliff:g id="NAME">%s</xliff:g> на весь екран"</string>
@@ -1988,14 +1979,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Активний виклик"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Вхідний виклик (Фільтр)"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Без категорії"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоакції"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Соцмережі"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Новини"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Рекомендації"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ви вказуєте пріоритет цих сповіщень."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Важливе з огляду на учасників."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Користувацьке сповіщення додатка"</string>
@@ -2212,10 +2199,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Вибір екранного засобу спеціальних можливостей"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Засіб спеціальних можливостей"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Закрити панель сповіщень"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Відтворити/призупинити медіаконтент"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Кнопка \"вгору\" панелі керування"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Кнопка \"вниз\" панелі керування"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Кнопка \"вліво\" панелі керування"</string>
@@ -2442,12 +2427,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як це працює"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Обробка…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Налаштуйте розблокування відбитком пальця повторно"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Відбиток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" працював неналежним чином, і його видалено"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Відбитки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" працювали неналежним чином, і їх видалено"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Відбиток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" працював неналежним чином, і його видалено. Налаштуйте його ще раз, щоб розблоковувати телефон за допомогою відбитка пальця."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Відбитки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" працювали неналежним чином, і їх видалено. Налаштуйте їх ще раз, щоб розблоковувати телефон за допомогою відбитка пальця."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Відбиток пальця <xliff:g id="FINGERPRINT">%s</xliff:g> більше не розпізнається."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Відбитки пальців <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> і <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> більше не розпізнаються."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Відбиток пальця <xliff:g id="FINGERPRINT">%s</xliff:g> більше не розпізнається. Налаштуйте розблокування відбитком пальця повторно."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Відбитки пальців <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> і <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> більше не розпізнаються. Налаштуйте розблокування відбитком пальця повторно."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Налаштуйте фейс-контроль повторно"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Модель обличчя працювала неналежним чином, і її видалено. Налаштуйте її ще раз, щоб розблоковувати телефон за допомогою фейс-контролю."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Модель вашого обличчя більше не розпізнається. Налаштуйте фейс-контроль повторно."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Налаштувати"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не зараз"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будильник користувача <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Змінити користувача"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Вимкнути звук"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Натисніть, щоб вимкнути звук"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index a67752b0b236..e613dd72d56b 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"وائرلیس ڈیبگنگ کو غیر فعال کرنے کے ليے منتخب کریں۔"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ٹیسٹ ہارنیس موڈ فعال ہے"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ٹیسٹ ہارنیس موڈ غیر فعال کرنے کے لیے فیکٹری ری سیٹ کریں۔"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"‏‫HSUM کی غلط بلڈ کنفیگریشن"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"اس آلہ کی ہیڈ لیس سسٹم یوزر موڈ کی حیثیت اس کی بلڈ کنفیگریشن سے مختلف ہوتی ہے۔ براہ کرم آلہ کو فیکٹری ری سیٹ کریں۔"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"شمار کونسول فعال ہے"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"کارکردگی پر اثر پڑا ہے۔ غیر فعال کرنے کے ليے، بوٹ لوڈر چیک کریں۔"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"‏تجرباتی MTE کو فعال کیا گیا"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آن ہے۔"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آف ہے۔"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"والیوم کی کلیدوں کو ریلیز کریں <xliff:g id="SERVICE_NAME">%1$s</xliff:g> کو آن کرنے کے لیے، والیوم کی دونوں کلیدوں کو دوبارہ 3 سیکنڈ تک چھوئیں اور دبائے رکھیں۔"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"ایک خصوصیت منتخب کریں"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"ایک خصوصیت منتخب کریں"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"ایک خصوصیت منتخب کریں"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"اگلی بار جب آپ ایکسیسبیلٹی بٹن پر تھپتھپائیں گے تو خصوصیت کھل جائے گی"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"اگلی بار جب آپ یہ شارٹ کٹ استعمال کریں گے تو خصوصیت کھل جائے گی۔ اپنی اسکرین کے نیچے سے 2 انگلیوں سے اوپر کی طرف سوائپ کریں اور تیزی سے ریلیز کریں۔"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"اگلی بار جب آپ یہ شارٹ کٹ استعمال کریں گے تو خصوصیت کھل جائے گی۔ اپنی اسکرین کے نیچے سے 3 انگلیوں سے اوپر کی طرف سوائپ کریں اور تیزی سے ریلیز کریں۔"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"میگنیفکیشن"</string>
<string name="user_switched" msgid="7249833311585228097">"موجودہ صارف <xliff:g id="NAME">%1$s</xliff:g>۔"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> پر سوئچ کیا جا رہا ہے…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"‏PIN کافی چھوٹا ہے۔ کم از کم 4 ہندسے ہونا ضروری ہے۔"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"بعد میں دوبارہ کوشش کریں"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"پوری اسکرین میں دیکھ رہے ہیں"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"باہر نکلنے کے لیے اپنی اسکرین کے اوپری حصے سے نیچے کی طرف سوائپ کریں"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"سمجھ آ گئی"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"بہتر منظر کے لیے گھمائیں"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"بہتر منظر کے لیے <xliff:g id="NAME">%s</xliff:g> کو فُل اسکرین میں کھولیں"</string>
@@ -2434,12 +2425,25 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"اس کے کام کرنے کا طریقہ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"زیر التواء..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"فنگر پرنٹ اَن لاک کو دوبارہ سیٹ اپ کریں"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> اچھی طرح کام نہیں کر رہا تھا اور حذف کر دیا گیا تھا"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> اور <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> اچھی طرح کام نہیں کر رہے تھے اور انہیں حذف کر دیا گیا تھا"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> اچھی طرح کام نہیں کر رہا تھا اور حذف کر دیا گیا تھا۔ اپنے فون کو فنگر پرنٹ سے غیر مقفل کرنے کے لیے، اسے دوبارہ سیٹ اپ کریں۔"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> اور <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> اچھی طرح کام نہیں کر رہے تھے اور انہیں حذف کر دیا گیا تھا۔ اپنے فون کو اپنے فنگر پرنٹ سے غیر مقفل کرنے کے لیے انہیں دوبارہ سیٹ اپ کریں۔"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> مزید پہچانا نہیں جا سکتا۔"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> اور <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> کو مزید پہچانا نہیں جا سکتا۔"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> مزید پہچانا نہیں جا سکتا۔ فنگر پرنٹ اَن لاک کو دوبارہ سیٹ اپ کریں۔"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> اور <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> کو مزید پہچانا نہیں جا سکتا۔ فنگر پرنٹ اَن لاک کو دوبارہ سیٹ اپ کریں۔"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"فیس اَن لاک کو دوبارہ سیٹ اپ کریں"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"آپ کے چہرے کا ماڈل اچھی طرح کام نہیں کر رہا تھا اور حذف کر دیا گیا تھا۔ اپنے فون کو چہرے سے غیر مقفل کرنے کے لیے، اسے دوبارہ سیٹ اپ کریں۔"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"آپ کے چہرے کا ماڈل مزید پہچانا نہیں جا سکتا۔ فیس اَن لاک کو دوبارہ سیٹ اپ کریں۔"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"سیٹ اپ کریں"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ابھی نہیں"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> کیلئے الارم"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"صارف سوئچ کریں"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"خاموش کریں"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"آواز کو خاموش کرنے کے لیے تھپتھپائیں"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"براؤزر"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"رابطے"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"ای میل"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"SMS"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"موسیقی"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"کیلنڈر"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"کیلکولیٹر"</string>
+ <string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"نقشے"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"ایپلیکیشنز"</string>
</resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index dfc510ca511e..994950cec574 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Uni faolsizlantirish uchun bosing."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Xavfsizlik sinovi rejimi yoqildi"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Xavfsizlik sinovi rejimini faolsizlantirish uchun zavod sozlamalariga qaytaring."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM nashr konfiguratsiyasida xato"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Bu qurilmadagi Headless System User Mode holati uning konfiguratsiyasidan farq qiladi. Qurilma sozlamalarini tozalang."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Ketma-ket port konsoli yoqildi"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Qurilma samaradorligi pasaydi. Konsolni faolsizlantirish uchun operatsion tizim yuklagichini oching."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Tajribaviy MTE yoqildi"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> yoqildi."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> faolsizlantirildi."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Tovush tugmalarini qoʻyib yuboring. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmatini yoqish uchun ikkala tovush tugmasini 3 soniya bosib turing."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Funksiyani tanlang"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Funksiyani tanlang"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Funksiyani tanlang"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Keyingi safar qulayliklar tugmasini bosganingizda funksiya ochiladi"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 2 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 3 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Kattalashtirish"</string>
<string name="user_switched" msgid="7249833311585228097">"Joriy foydalanuvchi <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Bunga almashilmoqda: <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN kod juda qisqa, kamida 4 ta raqam kiriting."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Keyinroq urinib ko‘ring"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Butun ekranli rejim"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Chiqish uchun ekranning tepasidan pastga suring"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Yaxshiroq koʻrish uchun kamerani buring"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Yaxshiroq koʻrish uchun butun ekranda <xliff:g id="NAME">%s</xliff:g> ilovasini oching"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Joriy chaqiruv"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Kiruvchi chaqiruvni filtrlash"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Turkumlanmagan"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoaksiyalar"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Ijtimoiy"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Yangiliklar"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Tavsiyalar"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Siz ushbu bildirishnomalarning muhimligini belgilagansiz."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Bu odamlar siz uchun muhim."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Maxsus ilova bildirishnomasi"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekranda tezkor ishga tushirishni tanlagich"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Tezkor ishga tushirish"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Eslatma soyasini yopish"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menyu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media ijro/pauza"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad – tepaga"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad – pastga"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad – chapga"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ishlash tartibi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Kutilmoqda..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmoq izi bilan ochish funksiyasini qayta sozlang"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi."</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> va <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi. Telefonni barmoq izi bilan ochish uchun uni qayta sozlang."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> va <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi. Telefonni barmoq izi bilan ochish uchun ularni qayta sozlang."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> endi tanilmaydi."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> va <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> endi tanilmaydi."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> endi tanilmaydi. Barmoq izi bilan ochishni qayta sozlang."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> va <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> endi tanilmaydi. Barmoq izi bilan ochishni qayta sozlang."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Yuz bilan ochishni qayta sozlash"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Yuzingiz mobeli yaxshi ishlamadi va oʻchirib tashlandi. Telefonni yuz bilan ochish uchun uni qayta sozlang."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Yuzingiz modeli endi tanilmaydi. Yuz bilan ochishni qayta sozlang."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Sozlash"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Hozir emas"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> uchun signal"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Foydalanuvchini almashtirish"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ovozsiz qilish"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tovushsiz qilish uchun bosing"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 73889262675c..f825f7b501ee 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Chọn để tắt tính năng gỡ lỗi qua Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Đã bật Chế độ khai thác kiểm thử"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Khôi phục cài đặt gốc để tắt Chế độ khai thác kiểm thử."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Cấu hình bản dựng HSUM không chính xác"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Trạng thái Chế độ người dùng hệ thống không có giao diện người dùng (HSUM) của thiết bị này khác với cấu hình bản dựng của thiết bị. Vui lòng đặt lại thiết bị về trạng thái ban đầu."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Đã bật bảng điều khiển cổng nối tiếp"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Hiệu suất sẽ bị ảnh hưởng. Để tắt, hãy chọn trình tải khởi động."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Đã bật MTE thử nghiệm"</string>
@@ -1439,7 +1437,7 @@
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Hiển thị trên các ứng dụng khác"</string>
<string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> hiển thị trên các ứng dụng khác"</string>
- <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> hiển thị trên ứng dụng khác"</string>
+ <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> đang hiện trên các ứng dụng khác"</string>
<string name="alert_windows_notification_message" msgid="6538171456970725333">"Nếu bạn không muốn <xliff:g id="NAME">%s</xliff:g> sử dụng tính năng này, hãy nhấn để mở cài đặt và tắt tính năng này."</string>
<string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Tắt"</string>
<string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Đang kiểm tra <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã bật."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã tắt."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Thả phím âm lượng. Để bật <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, hãy nhấn và giữ cả 2 phím âm lượng trong 3 giây một lần nữa."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Chọn một tính năng"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Chọn một tính năng"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Chọn một tính năng"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Tính năng này sẽ được mở vào lần tới bạn nhấn nút hỗ trợ tiếp cận"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Tính năng này sẽ được mở vào lần tới bạn dùng lối tắt này. Hãy dùng 2 ngón tay vuốt từ cuối màn hình lên rồi thả tay nhanh."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Tính năng này sẽ được mở vào lần tới bạn dùng lối tắt này. Hãy dùng 3 ngón tay vuốt từ cuối màn hình lên rồi thả tay nhanh."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Phóng to"</string>
<string name="user_switched" msgid="7249833311585228097">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Đang chuyển sang <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Mã PIN quá ngắn. Phải có ít nhất 4 chữ số."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Hãy thử lại sau"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Xem toàn màn hình"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Để thoát, hãy vuốt xuống từ đầu màn hình"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Xoay để xem dễ hơn"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Mở <xliff:g id="NAME">%s</xliff:g> ở chế độ toàn màn hình để xem dễ hơn"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Cuộc gọi đang thực hiện"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Đang sàng lọc cuộc gọi đến"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Chưa được phân loại"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Khuyến mãi"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Mạng xã hội"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Tin tức"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Đề xuất"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Bạn đặt tầm quan trọng của các thông báo này."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Thông báo này quan trọng vì những người có liên quan."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Thông báo tùy chỉnh cho ứng dụng"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Bộ chọn lối tắt hỗ trợ tiếp cận trên màn hình"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Lối tắt hỗ trợ tiếp cận"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Đóng Ngăn thông báo"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Trình đơn"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Phát/Tạm dừng nội dung nghe nhìn"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Chuyển lên trên bằng bàn phím di chuyển"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Chuyển xuống dưới bằng bàn phím di chuyển"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Chuyển sang trái bằng bàn phím di chuyển"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cách hoạt động"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Đang chờ xử lý..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Thiết lập lại tính năng Mở khoá bằng vân tay"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> không dùng được và đã bị xoá"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> không dùng được và đã bị xoá"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> không dùng được và đã bị xoá. Hãy thiết lập lại để mở khoá điện thoại bằng vân tay."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> không dùng được và đã bị xoá. Hãy thiết lập lại để mở khoá điện thoại bằng vân tay."</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Không nhận dạng được <xliff:g id="FINGERPRINT">%s</xliff:g> nữa."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Không nhận dạng được <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nữa."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Không nhận dạng được <xliff:g id="FINGERPRINT">%s</xliff:g> nữa. Hãy thiết lập lại tính năng Mở khoá bằng vân tay."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Không nhận dạng được <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nữa. Hãy thiết lập lại tính năng Mở khoá bằng vân tay."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Thiết lập lại tính năng Mở khoá bằng khuôn mặt"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Mẫu khuôn mặt của bạn không dùng được và đã bị xoá. Hãy thiết lập lại để mở khoá điện thoại bằng khuôn mặt."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Không nhận dạng được mẫu khuôn mặt của bạn nữa. Hãy thiết lập lại tính năng Mở khoá bằng khuôn mặt."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Thiết lập"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Để sau"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Chuông báo cho <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Chuyển đổi người dùng"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Tắt tiếng"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Nhấn để tắt tiếng"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-watch/colors.xml b/core/res/res/values-watch/colors.xml
deleted file mode 100644
index e2b7505f3c6e..000000000000
--- a/core/res/res/values-watch/colors.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!-- Watch specific system colors. -->
-<resources>
- <color name="system_error_light">#B3261E</color>
- <color name="system_on_error_light">#FFFFFF</color>
- <color name="system_error_container_light">#F7DCDA</color>
- <color name="system_on_error_container_light">#410E0B</color>
-
- <color name="system_error_dark">#F2B8B5</color>
- <color name="system_on_error_dark">#601410</color>
- <color name="system_error_container_dark">#FF8986</color>
- <color name="system_on_error_container_dark">#410E0B</color>
-
- <!-- With material deprecation of 'background' in favor of 'surface' we flatten these
- on watches to match the black background requirements -->
- <color name="system_surface_dark">#000000</color>
- <color name="system_surface_dim_dark">#000000</color>
- <color name="system_surface_bright_dark">#000000</color>
-
- <!-- Wear flattens the typical 5 container layers to 3; container + high & low -->
- <color name="system_surface_container_dark">#303030</color>
- <color name="system_surface_variant_dark">#303030</color>
- <color name="system_surface_container_high_dark">#474747</color>
- <color name="system_surface_container_highest_dark">#474747</color>
- <color name="system_surface_container_low_dark">#252626</color>
- <color name="system_surface_container_lowest_dark">#252626</color>
-
-</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index c84c16c6de5a..2d1873dc8170 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"选择即可停用无线调试功能。"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"自动化测试框架模式已启用"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"恢复出厂设置以停用自动化测试框架模式。"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM build 配置不正确"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"此设备的无头系统用户模式状态与其 build 配置不同。请将设备恢复出厂设置。"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"已启用序列控制台"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"性能受到影响。要停用,请查看引导加载程序。"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"已启用实验性 MTE"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"松开音量键。如要启用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,请再次同时按住两个音量键 3 秒。"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"请选择功能"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"请选择功能"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"请选择功能"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"下次点按“无障碍”按钮时,将打开此功能"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用此快捷手势时,将打开此功能。用 2 根手指从画面底部向上滑动,然后快速松开。"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用此快捷手势时,将打开此功能。用 3 根手指从画面底部向上滑动,然后快速松开。"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大功能"</string>
<string name="user_switched" msgid="7249833311585228097">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"正在切换为<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN码太短,至少应包含4位数字。"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"稍后重试"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"目前处于全屏模式"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"若要退出,请从屏幕顶部向下滑动"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"知道了"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"旋转可改善预览效果"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"在全屏模式下打开“<xliff:g id="NAME">%s</xliff:g>”可改善预览效果"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"正在通话"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"正在过滤来电"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"未分类"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"促销"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"社交"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"资讯"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"建议"</string>
<string name="importance_from_user" msgid="2782756722448800447">"这些通知的重要程度由您来设置。"</string>
<string name="importance_from_person" msgid="4235804979664465383">"这条通知涉及特定的人,因此被归为重要通知。"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"自定义应用通知"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"屏幕上的无障碍功能快捷方式选择器"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"无障碍功能快捷方式"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"关闭通知栏"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"菜单"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"媒体播放/暂停"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"向上方向键"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"向下方向键"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"向左方向键"</string>
@@ -2433,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"私密空间"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"已隐藏敏感通知内容"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"为安全起见而在屏幕共享画面中处于隐藏状态的应用内容"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"为安全起见,屏幕共享画面已隐藏此应用的内容"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"自动连接到卫星"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"您无需使用移动网络或 WLAN 网络便能收发消息"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"打开“信息”应用"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"运作方式"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"待归档…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新设置指纹解锁功能"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"“<xliff:g id="FINGERPRINT">%s</xliff:g>”无法正常使用,已被删除"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"“<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>”和“<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>”无法正常使用,已被删除"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"“<xliff:g id="FINGERPRINT">%s</xliff:g>”无法正常使用,系统已将其删除。如要通过指纹解锁功能来解锁手机,请重新设置。"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"“<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>”和“<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>”无法正常使用,系统已将它们删除。如要通过指纹解锁功能来解锁手机,请重新设置。"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"系统无法再识别<xliff:g id="FINGERPRINT">%s</xliff:g>。"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"系统无法再识别<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"系统无法再识别<xliff:g id="FINGERPRINT">%s</xliff:g>。请重新设置指纹解锁功能。"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"系统无法再识别<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。请重新设置指纹解锁功能。"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"重新设置“人脸解锁”功能"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"您的脸部模型无法正常使用,系统已将其删除。如要通过人脸解锁功能来解锁手机,请重新设置。"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"系统无法再识别您的脸部模型。请重新设置人脸解锁功能。"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"设置"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"以后再说"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>的闹钟"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"切换用户"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"静音"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"点按即可设为静音"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index b229f27e87e4..ca88600b2c6b 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"選取即可停用無線偵錯功能。"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"已啟用測試工具模式"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"請將裝置回復原廠設定,以停用測試工具模式。"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM 版本設定錯誤"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"此裝置的無使用者介面系統使用者模式狀態與裝置的版本設定不符。請將裝置回復原廠設定。"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"已啟用序列控制器"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"效能受到影響,勾選啟動程式即可停用。"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"實驗版 MTE 已啟用"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已開啟。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已關閉。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"鬆開音量鍵。如果要開 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,請同時㩒住兩個音量鍵 3 秒。"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"選擇功能"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"選擇功能"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"選擇功能"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"下次輕按無障礙功能按鈕時,就會開啟此功能"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用此快速鍵時,就會開啟此功能。請用 2 隻手指從螢幕底部向上滑動並快速放開。"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用此快速鍵時,就會開啟此功能。請用 3 隻手指從螢幕底部向上滑動並快速放開。"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大"</string>
<string name="user_switched" msgid="7249833311585228097">"目前的使用者是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN 碼太短,至少必須為 4 位數。"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"稍後再試"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"開啟全螢幕"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"如要離開,請從螢幕頂部向下滑動"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"知道了"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"旋轉以改善預覽效果"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"以全螢幕模式開啟「<xliff:g id="NAME">%s</xliff:g>」,以改善預覽效果"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"正在過濾來電"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"未分類"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"宣傳"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"社交"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"新聞"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"建議"</string>
<string name="importance_from_user" msgid="2782756722448800447">"你可以設定這些通知的重要性。"</string>
<string name="importance_from_person" msgid="4235804979664465383">"列為重要的原因:涉及的人。"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"自訂應用程式通知"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"螢幕無障礙功能捷徑選擇器"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"無障礙功能捷徑"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"關閉通知欄"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"選單"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"媒體播放/暫停"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"十字鍵向上鍵"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"十字鍵向下鍵"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"十字鍵向左鍵"</string>
@@ -2440,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定「指紋解鎖」功能"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"由於「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,因此系統已將其刪除"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"由於「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,因此系統已將其刪除。"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"由於「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能使用指紋解鎖手機。"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"由於「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能使用指紋解鎖手機。"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"無法再辨識<xliff:g id="FINGERPRINT">%s</xliff:g>。"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"無法再辨識<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"無法再辨識<xliff:g id="FINGERPRINT">%s</xliff:g>。請重新設定「指紋解鎖」功能。"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"無法再辨識<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。請重新設定「指紋解鎖」功能。"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"重新設定「面孔解鎖」功能"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"由於面部模型無法正常運作,因此系統已將其刪除。請重新設定,才能使用面孔解鎖手機。"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"無法再辨識你的面部模型。請重新設定「面孔解鎖」功能。"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"暫時不要"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>的鬧鐘"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"切換使用者"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"靜音"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"輕按即可靜音"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 13c3ff78be01..b22ad0ad62f9 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1197,7 +1197,7 @@
<string name="low_internal_storage_view_title" msgid="9024241779284783414">"儲存空間即將用盡"</string>
<string name="low_internal_storage_view_text" msgid="8172166728369697835">"部分系統功能可能無法運作"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"系統儲存空間不足。請確定你已釋出 250MB 的可用空間,然後重新啟動。"</string>
- <string name="app_running_notification_title" msgid="8985999749231486569">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」目前正在執行"</string>
+ <string name="app_running_notification_title" msgid="8985999749231486569">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在執行中"</string>
<string name="app_running_notification_text" msgid="5120815883400228566">"輕觸即可瞭解詳情或停止應用程式。"</string>
<string name="ok" msgid="2646370155170753815">"確定"</string>
<string name="cancel" msgid="6908697720451760115">"取消"</string>
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"選取即可停用無線偵錯功能。"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"測試控管工具模式已啟用"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"恢復原廠設定以停用測試控管工具模式。"</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"HSUM 建構設定錯誤"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"這部裝置的無頭系統使用者模式狀態與其建構設定不同,請將裝置恢復原廠設定。"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"已啟用序列主控台"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"效能已受到影響。如要停用,請檢查系統啟動載入程式。"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"已啟用實驗 MTE"</string>
@@ -1439,7 +1437,7 @@
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"在其他應用程式上面顯示"</string>
<string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"「<xliff:g id="NAME">%s</xliff:g>」在其他應用程式上顯示內容"</string>
- <string name="alert_windows_notification_title" msgid="6331662751095228536">"「<xliff:g id="NAME">%s</xliff:g>」正在其他應用程式上顯示內容"</string>
+ <string name="alert_windows_notification_title" msgid="6331662751095228536">"「<xliff:g id="NAME">%s</xliff:g>」正重疊顯示在其他應用程式上方"</string>
<string name="alert_windows_notification_message" msgid="6538171456970725333">"如果你不想讓「<xliff:g id="NAME">%s</xliff:g>」使用這項功能,請輕觸開啟設定頁面,然後停用此功能。"</string>
<string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"關閉"</string>
<string name="ext_media_checking_notification_title" msgid="8299199995416510094">"正在檢查 <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已開啟。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已關閉。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"放開音量鍵。如要開啟 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,請同時按住音量調高鍵和調低鍵 3 秒。"</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"選擇功能"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"選擇功能"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"選擇功能"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"下次輕觸無障礙工具按鈕時,就會開啟這項功能"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用這個捷徑時,就會開啟這項功能。請用 2 指從螢幕底部向上滑動並快速放開。"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用這個捷徑時,就會開啟這項功能。請用 3 指從螢幕底部向上滑動並快速放開。"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大"</string>
<string name="user_switched" msgid="7249833311585228097">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN 長度太短,至少必須為 4 位數。"</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"稍後再試"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"以全螢幕檢視"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"如要離開,請從螢幕頂端向下滑動"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"知道了"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"旋轉螢幕以瀏覽完整的檢視畫面"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"如要享有更優質的預覽體驗,可透過全螢幕模式開啟「<xliff:g id="NAME">%s</xliff:g>」"</string>
@@ -1986,14 +1977,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"正在過濾來電"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"未分類"</string>
- <!-- no translation found for promotional_notification_channel_label (7414844730492860233) -->
- <skip />
- <!-- no translation found for social_notification_channel_label (106520267132019945) -->
- <skip />
- <!-- no translation found for news_notification_channel_label (4299937455247883311) -->
- <skip />
- <!-- no translation found for recs_notification_channel_label (4945985121418684297) -->
- <skip />
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"促銷"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"社群"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"新聞"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"建議"</string>
<string name="importance_from_user" msgid="2782756722448800447">"這些通知的重要性由你決定。"</string>
<string name="importance_from_person" msgid="4235804979664465383">"這則通知涉及特定人士,因此被歸為重要通知。"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"自訂應用程式通知"</string>
@@ -2210,10 +2197,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"螢幕上的無障礙捷徑選擇器"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"無障礙捷徑"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"關閉通知欄"</string>
- <!-- no translation found for accessibility_system_action_menu_label (3385283204496447040) -->
- <skip />
- <!-- no translation found for accessibility_system_action_media_play_pause_label (1905647491347119748) -->
- <skip />
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"選單"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"媒體播放/暫停"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad 向上移"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad 向下移"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad 向左移"</string>
@@ -2433,19 +2418,41 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"私人空間"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"系統已隱藏含有私密資訊的通知內容"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"為安全起見,分享螢幕畫面未顯示應用程式內容"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"為安全起見,分享螢幕畫面隱藏了這個應用程式的內容"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"已自動連上衛星"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"你可以收發訊息,沒有行動/Wi-Fi 網路也無妨"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」應用程式"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定指紋解鎖"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,系統已將其刪除"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,系統已將其刪除"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能用指紋解鎖手機。"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能用指紋解鎖手機。"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"系統無法再辨識「<xliff:g id="FINGERPRINT">%s</xliff:g>」。"</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"系統無法再辨識「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」。"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"系統無法再辨識「<xliff:g id="FINGERPRINT">%s</xliff:g>」,請重新設定指紋解鎖。"</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"系統無法再辨識「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」,請重新設定指紋解鎖。"</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"重新設定人臉解鎖"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"臉部模型無法正常運作,因此系統已將其刪除。請重新設定,才能用臉解鎖手機。"</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"系統無法再辨識你的臉部模型,請重新設定人臉解鎖。"</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"暫時不要"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>的鬧鐘"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"切換使用者"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"靜音"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"輕觸即可設為靜音"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 53b5507400ca..f9aa9253776a 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1411,10 +1411,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Khetha ukukhubaza ukulungisa amaphutha okungenantambo."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Imodi yokuhlola i-harness inikwe amandla"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Yenza ukusetha kabusha kwasekuqaleni ukuze ukhubaze imodi yokuqina yokuhlola."</string>
- <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
- <skip />
- <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
- <skip />
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Ukulungiselelwa okungalungile kwesakho se-HSUM"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"Isimo Semodi Yomsebenzisi Yesistimu Engenakhanda yale divayisi siyahluka ekucushweni kwesakhiwo sayo. Sicela usethe kabusha njengasekuqaleni idivayisi."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"I-serial console inikwe amandla"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ukusebenza kuyathinteka. Ukuze ukhubaze, hlola i-bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"I-Experimental MTE inikwe amandla"</string>
@@ -1759,18 +1757,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivuliwe."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivaliwe."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Khipha okhiye bevolumu. Ukuze uvule i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>, cindezela bese ubamba bobabili okhiye bevolumu futhi imizuzwana emi-3."</string>
- <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
- <skip />
- <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
- <skip />
- <!-- no translation found for accessibility_button_instructional_text (8029780800681458835) -->
- <skip />
- <!-- no translation found for accessibility_gesture_instructional_text (1485998586929977949) -->
- <skip />
- <!-- no translation found for accessibility_gesture_3finger_instructional_text (3430237316928654219) -->
- <skip />
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Khetha isakhi"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Khetha isakhi"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Khetha isakhi"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Isakhi sizovuleka ngokulandelayo uma uthepha inkinobho yokufinyeleleka"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Lesi sakhi sizovuleka ngokulandelayo uma usebenzisa lesi sinqamuleli. Swayiphela phezulu ngeminwe engu-2 kusukela ngaphansi kwesikrini sakho uphinde udedele ngokushesha."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Lesi sakhi sizovuleka ngokulandelayo uma usebenzisa lesi sinqamuleli. Swayiphela phezulu ngeminwe engu-3 kusukela ngaphansi kwesikrini sakho uphinde udedele ngokushesha."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ukukhuliswa"</string>
<string name="user_switched" msgid="7249833311585228097">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Ishintshela ku-<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1893,8 +1885,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"I-PIN yimfushane kakhulu. Okungenani kumele ibe namadijithi angu-4."</string>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Zama futhi emva kwesikhathi"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Ukubuka isikrini esigcwele"</string>
- <!-- no translation found for immersive_cling_description (2896205051090870978) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2896205051090870978">"Ukuze uphume, swayiphela phansi kusukela phezulu esikrinini sakho"</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Ngiyitholile"</string>
<string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zungezisa ukuze uthole ukubuka okungcono"</string>
<string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Vula i-<xliff:g id="NAME">%s</xliff:g> kusikrini esigcwele ngokubuka okungcono"</string>
@@ -2434,12 +2425,34 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Indlela esebenza ngayo"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ilindile..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setha Ukuvula ngesigxivizo somunwe futhi"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> ibingasebenzi kahle futhi isuliwe"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ibingasebenzi kahle futhi isuliwe"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> ibingasebenzi kahle futhi isuliwe. Phinde uyisethe ukuze uvule ifoni yakho ngesigxivizo somunwe."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ibingasebenzi kahle futhi isuliwe. Phinde uyisethe ukuze uvule ifoni yakho ngesigxivizo somunwe wakho"</string>
+ <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> angeke isaziwa."</string>
+ <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> angeke isaziwa."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> angeke isaziwa. Setha Ukuvula Ngesigxivizo Somunwe futhi."</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> angeke isaziwa. Setha Ukuvula Ngesigxivizo Somunwe futhi."</string>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Setha Ukuvula Ngobuso futhi"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Imodeli yobuso yakho ibingasebenzi kahle futhi isuliwe. Phinde uyisethe ukuze uvule ifoni yakho ngobuso."</string>
+ <string name="face_dangling_notification_msg" msgid="746235263598985384">"Imodeli yobuso yakho angeke isabonwa. Setha Ukuvula Ngobuso futhi."</string>
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Setha"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Hhayi manje"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"I-alamu ka-<xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Shintsha umsebenzisi"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Thulisa"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Thepha ukuze uthulise umsindo"</string>
+ <!-- no translation found for keyboard_shortcut_group_applications_browser (6535007304687100909) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_contacts (2750702518068326356) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_email (4229037666415353683) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_sms (3523799286376321137) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_music (2051507523525651067) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calendar (3571770335653387606) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_calculator (6753209559716091507) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications_maps (7950000659522589471) -->
+ <skip />
+ <!-- no translation found for keyboard_shortcut_group_applications (3010389163951364798) -->
+ <skip />
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 488382783331..0975eda3f9ff 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2184,6 +2184,344 @@
<enum name="KEYCODE_DEMO_APP_2" value="302" />
<enum name="KEYCODE_DEMO_APP_3" value="303" />
<enum name="KEYCODE_DEMO_APP_4" value="304" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_DOWN" value="305" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_UP" value="306" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE" value="307" />
+ <enum name="KEYCODE_STYLUS_BUTTON_PRIMARY" value="308" />
+ <enum name="KEYCODE_STYLUS_BUTTON_SECONDARY" value="309" />
+ <enum name="KEYCODE_STYLUS_BUTTON_TERTIARY" value="310" />
+ <enum name="KEYCODE_STYLUS_BUTTON_TAIL" value="311" />
+ <enum name="KEYCODE_RECENT_APPS" value="312" />
+ <enum name="KEYCODE_MACRO_1" value="313" />
+ <enum name="KEYCODE_MACRO_2" value="314" />
+ <enum name="KEYCODE_MACRO_3" value="315" />
+ <enum name="KEYCODE_MACRO_4" value="316" />
+ <enum name="KEYCODE_EMOJI_PICKER" value="317" />
+ <enum name="KEYCODE_SCREENSHOT" value="318" />
+ </attr>
+
+ <!-- @hide same as keycode enum defined above, but to be used to define keycode output.
+ (redefining it to allow keycode and outKeycode to be part of same styleable attribute) -->
+ <attr name="outKeycode">
+ <enum name="KEYCODE_UNKNOWN" value="0" />
+ <enum name="KEYCODE_SOFT_LEFT" value="1" />
+ <enum name="KEYCODE_SOFT_RIGHT" value="2" />
+ <enum name="KEYCODE_HOME" value="3" />
+ <enum name="KEYCODE_BACK" value="4" />
+ <enum name="KEYCODE_CALL" value="5" />
+ <enum name="KEYCODE_ENDCALL" value="6" />
+ <enum name="KEYCODE_0" value="7" />
+ <enum name="KEYCODE_1" value="8" />
+ <enum name="KEYCODE_2" value="9" />
+ <enum name="KEYCODE_3" value="10" />
+ <enum name="KEYCODE_4" value="11" />
+ <enum name="KEYCODE_5" value="12" />
+ <enum name="KEYCODE_6" value="13" />
+ <enum name="KEYCODE_7" value="14" />
+ <enum name="KEYCODE_8" value="15" />
+ <enum name="KEYCODE_9" value="16" />
+ <enum name="KEYCODE_STAR" value="17" />
+ <enum name="KEYCODE_POUND" value="18" />
+ <enum name="KEYCODE_DPAD_UP" value="19" />
+ <enum name="KEYCODE_DPAD_DOWN" value="20" />
+ <enum name="KEYCODE_DPAD_LEFT" value="21" />
+ <enum name="KEYCODE_DPAD_RIGHT" value="22" />
+ <enum name="KEYCODE_DPAD_CENTER" value="23" />
+ <enum name="KEYCODE_VOLUME_UP" value="24" />
+ <enum name="KEYCODE_VOLUME_DOWN" value="25" />
+ <enum name="KEYCODE_POWER" value="26" />
+ <enum name="KEYCODE_CAMERA" value="27" />
+ <enum name="KEYCODE_CLEAR" value="28" />
+ <enum name="KEYCODE_A" value="29" />
+ <enum name="KEYCODE_B" value="30" />
+ <enum name="KEYCODE_C" value="31" />
+ <enum name="KEYCODE_D" value="32" />
+ <enum name="KEYCODE_E" value="33" />
+ <enum name="KEYCODE_F" value="34" />
+ <enum name="KEYCODE_G" value="35" />
+ <enum name="KEYCODE_H" value="36" />
+ <enum name="KEYCODE_I" value="37" />
+ <enum name="KEYCODE_J" value="38" />
+ <enum name="KEYCODE_K" value="39" />
+ <enum name="KEYCODE_L" value="40" />
+ <enum name="KEYCODE_M" value="41" />
+ <enum name="KEYCODE_N" value="42" />
+ <enum name="KEYCODE_O" value="43" />
+ <enum name="KEYCODE_P" value="44" />
+ <enum name="KEYCODE_Q" value="45" />
+ <enum name="KEYCODE_R" value="46" />
+ <enum name="KEYCODE_S" value="47" />
+ <enum name="KEYCODE_T" value="48" />
+ <enum name="KEYCODE_U" value="49" />
+ <enum name="KEYCODE_V" value="50" />
+ <enum name="KEYCODE_W" value="51" />
+ <enum name="KEYCODE_X" value="52" />
+ <enum name="KEYCODE_Y" value="53" />
+ <enum name="KEYCODE_Z" value="54" />
+ <enum name="KEYCODE_COMMA" value="55" />
+ <enum name="KEYCODE_PERIOD" value="56" />
+ <enum name="KEYCODE_ALT_LEFT" value="57" />
+ <enum name="KEYCODE_ALT_RIGHT" value="58" />
+ <enum name="KEYCODE_SHIFT_LEFT" value="59" />
+ <enum name="KEYCODE_SHIFT_RIGHT" value="60" />
+ <enum name="KEYCODE_TAB" value="61" />
+ <enum name="KEYCODE_SPACE" value="62" />
+ <enum name="KEYCODE_SYM" value="63" />
+ <enum name="KEYCODE_EXPLORER" value="64" />
+ <enum name="KEYCODE_ENVELOPE" value="65" />
+ <enum name="KEYCODE_ENTER" value="66" />
+ <enum name="KEYCODE_DEL" value="67" />
+ <enum name="KEYCODE_GRAVE" value="68" />
+ <enum name="KEYCODE_MINUS" value="69" />
+ <enum name="KEYCODE_EQUALS" value="70" />
+ <enum name="KEYCODE_LEFT_BRACKET" value="71" />
+ <enum name="KEYCODE_RIGHT_BRACKET" value="72" />
+ <enum name="KEYCODE_BACKSLASH" value="73" />
+ <enum name="KEYCODE_SEMICOLON" value="74" />
+ <enum name="KEYCODE_APOSTROPHE" value="75" />
+ <enum name="KEYCODE_SLASH" value="76" />
+ <enum name="KEYCODE_AT" value="77" />
+ <enum name="KEYCODE_NUM" value="78" />
+ <enum name="KEYCODE_HEADSETHOOK" value="79" />
+ <enum name="KEYCODE_FOCUS" value="80" />
+ <enum name="KEYCODE_PLUS" value="81" />
+ <enum name="KEYCODE_MENU" value="82" />
+ <enum name="KEYCODE_NOTIFICATION" value="83" />
+ <enum name="KEYCODE_SEARCH" value="84" />
+ <enum name="KEYCODE_MEDIA_PLAY_PAUSE" value="85" />
+ <enum name="KEYCODE_MEDIA_STOP" value="86" />
+ <enum name="KEYCODE_MEDIA_NEXT" value="87" />
+ <enum name="KEYCODE_MEDIA_PREVIOUS" value="88" />
+ <enum name="KEYCODE_MEDIA_REWIND" value="89" />
+ <enum name="KEYCODE_MEDIA_FAST_FORWARD" value="90" />
+ <enum name="KEYCODE_MUTE" value="91" />
+ <enum name="KEYCODE_PAGE_UP" value="92" />
+ <enum name="KEYCODE_PAGE_DOWN" value="93" />
+ <enum name="KEYCODE_PICTSYMBOLS" value="94" />
+ <enum name="KEYCODE_SWITCH_CHARSET" value="95" />
+ <enum name="KEYCODE_BUTTON_A" value="96" />
+ <enum name="KEYCODE_BUTTON_B" value="97" />
+ <enum name="KEYCODE_BUTTON_C" value="98" />
+ <enum name="KEYCODE_BUTTON_X" value="99" />
+ <enum name="KEYCODE_BUTTON_Y" value="100" />
+ <enum name="KEYCODE_BUTTON_Z" value="101" />
+ <enum name="KEYCODE_BUTTON_L1" value="102" />
+ <enum name="KEYCODE_BUTTON_R1" value="103" />
+ <enum name="KEYCODE_BUTTON_L2" value="104" />
+ <enum name="KEYCODE_BUTTON_R2" value="105" />
+ <enum name="KEYCODE_BUTTON_THUMBL" value="106" />
+ <enum name="KEYCODE_BUTTON_THUMBR" value="107" />
+ <enum name="KEYCODE_BUTTON_START" value="108" />
+ <enum name="KEYCODE_BUTTON_SELECT" value="109" />
+ <enum name="KEYCODE_BUTTON_MODE" value="110" />
+ <enum name="KEYCODE_ESCAPE" value="111" />
+ <enum name="KEYCODE_FORWARD_DEL" value="112" />
+ <enum name="KEYCODE_CTRL_LEFT" value="113" />
+ <enum name="KEYCODE_CTRL_RIGHT" value="114" />
+ <enum name="KEYCODE_CAPS_LOCK" value="115" />
+ <enum name="KEYCODE_SCROLL_LOCK" value="116" />
+ <enum name="KEYCODE_META_LEFT" value="117" />
+ <enum name="KEYCODE_META_RIGHT" value="118" />
+ <enum name="KEYCODE_FUNCTION" value="119" />
+ <enum name="KEYCODE_SYSRQ" value="120" />
+ <enum name="KEYCODE_BREAK" value="121" />
+ <enum name="KEYCODE_MOVE_HOME" value="122" />
+ <enum name="KEYCODE_MOVE_END" value="123" />
+ <enum name="KEYCODE_INSERT" value="124" />
+ <enum name="KEYCODE_FORWARD" value="125" />
+ <enum name="KEYCODE_MEDIA_PLAY" value="126" />
+ <enum name="KEYCODE_MEDIA_PAUSE" value="127" />
+ <enum name="KEYCODE_MEDIA_CLOSE" value="128" />
+ <enum name="KEYCODE_MEDIA_EJECT" value="129" />
+ <enum name="KEYCODE_MEDIA_RECORD" value="130" />
+ <enum name="KEYCODE_F1" value="131" />
+ <enum name="KEYCODE_F2" value="132" />
+ <enum name="KEYCODE_F3" value="133" />
+ <enum name="KEYCODE_F4" value="134" />
+ <enum name="KEYCODE_F5" value="135" />
+ <enum name="KEYCODE_F6" value="136" />
+ <enum name="KEYCODE_F7" value="137" />
+ <enum name="KEYCODE_F8" value="138" />
+ <enum name="KEYCODE_F9" value="139" />
+ <enum name="KEYCODE_F10" value="140" />
+ <enum name="KEYCODE_F11" value="141" />
+ <enum name="KEYCODE_F12" value="142" />
+ <enum name="KEYCODE_NUM_LOCK" value="143" />
+ <enum name="KEYCODE_NUMPAD_0" value="144" />
+ <enum name="KEYCODE_NUMPAD_1" value="145" />
+ <enum name="KEYCODE_NUMPAD_2" value="146" />
+ <enum name="KEYCODE_NUMPAD_3" value="147" />
+ <enum name="KEYCODE_NUMPAD_4" value="148" />
+ <enum name="KEYCODE_NUMPAD_5" value="149" />
+ <enum name="KEYCODE_NUMPAD_6" value="150" />
+ <enum name="KEYCODE_NUMPAD_7" value="151" />
+ <enum name="KEYCODE_NUMPAD_8" value="152" />
+ <enum name="KEYCODE_NUMPAD_9" value="153" />
+ <enum name="KEYCODE_NUMPAD_DIVIDE" value="154" />
+ <enum name="KEYCODE_NUMPAD_MULTIPLY" value="155" />
+ <enum name="KEYCODE_NUMPAD_SUBTRACT" value="156" />
+ <enum name="KEYCODE_NUMPAD_ADD" value="157" />
+ <enum name="KEYCODE_NUMPAD_DOT" value="158" />
+ <enum name="KEYCODE_NUMPAD_COMMA" value="159" />
+ <enum name="KEYCODE_NUMPAD_ENTER" value="160" />
+ <enum name="KEYCODE_NUMPAD_EQUALS" value="161" />
+ <enum name="KEYCODE_NUMPAD_LEFT_PAREN" value="162" />
+ <enum name="KEYCODE_NUMPAD_RIGHT_PAREN" value="163" />
+ <enum name="KEYCODE_VOLUME_MUTE" value="164" />
+ <enum name="KEYCODE_INFO" value="165" />
+ <enum name="KEYCODE_CHANNEL_UP" value="166" />
+ <enum name="KEYCODE_CHANNEL_DOWN" value="167" />
+ <enum name="KEYCODE_ZOOM_IN" value="168" />
+ <enum name="KEYCODE_ZOOM_OUT" value="169" />
+ <enum name="KEYCODE_TV" value="170" />
+ <enum name="KEYCODE_WINDOW" value="171" />
+ <enum name="KEYCODE_GUIDE" value="172" />
+ <enum name="KEYCODE_DVR" value="173" />
+ <enum name="KEYCODE_BOOKMARK" value="174" />
+ <enum name="KEYCODE_CAPTIONS" value="175" />
+ <enum name="KEYCODE_SETTINGS" value="176" />
+ <enum name="KEYCODE_TV_POWER" value="177" />
+ <enum name="KEYCODE_TV_INPUT" value="178" />
+ <enum name="KEYCODE_STB_POWER" value="179" />
+ <enum name="KEYCODE_STB_INPUT" value="180" />
+ <enum name="KEYCODE_AVR_POWER" value="181" />
+ <enum name="KEYCODE_AVR_INPUT" value="182" />
+ <enum name="KEYCODE_PROG_GRED" value="183" />
+ <enum name="KEYCODE_PROG_GREEN" value="184" />
+ <enum name="KEYCODE_PROG_YELLOW" value="185" />
+ <enum name="KEYCODE_PROG_BLUE" value="186" />
+ <enum name="KEYCODE_APP_SWITCH" value="187" />
+ <enum name="KEYCODE_BUTTON_1" value="188" />
+ <enum name="KEYCODE_BUTTON_2" value="189" />
+ <enum name="KEYCODE_BUTTON_3" value="190" />
+ <enum name="KEYCODE_BUTTON_4" value="191" />
+ <enum name="KEYCODE_BUTTON_5" value="192" />
+ <enum name="KEYCODE_BUTTON_6" value="193" />
+ <enum name="KEYCODE_BUTTON_7" value="194" />
+ <enum name="KEYCODE_BUTTON_8" value="195" />
+ <enum name="KEYCODE_BUTTON_9" value="196" />
+ <enum name="KEYCODE_BUTTON_10" value="197" />
+ <enum name="KEYCODE_BUTTON_11" value="198" />
+ <enum name="KEYCODE_BUTTON_12" value="199" />
+ <enum name="KEYCODE_BUTTON_13" value="200" />
+ <enum name="KEYCODE_BUTTON_14" value="201" />
+ <enum name="KEYCODE_BUTTON_15" value="202" />
+ <enum name="KEYCODE_BUTTON_16" value="203" />
+ <enum name="KEYCODE_LANGUAGE_SWITCH" value="204" />
+ <enum name="KEYCODE_MANNER_MODE" value="205" />
+ <enum name="KEYCODE_3D_MODE" value="206" />
+ <enum name="KEYCODE_CONTACTS" value="207" />
+ <enum name="KEYCODE_CALENDAR" value="208" />
+ <enum name="KEYCODE_MUSIC" value="209" />
+ <enum name="KEYCODE_CALCULATOR" value="210" />
+ <enum name="KEYCODE_ZENKAKU_HANKAKU" value="211" />
+ <enum name="KEYCODE_EISU" value="212" />
+ <enum name="KEYCODE_MUHENKAN" value="213" />
+ <enum name="KEYCODE_HENKAN" value="214" />
+ <enum name="KEYCODE_KATAKANA_HIRAGANA" value="215" />
+ <enum name="KEYCODE_YEN" value="216" />
+ <enum name="KEYCODE_RO" value="217" />
+ <enum name="KEYCODE_KANA" value="218" />
+ <enum name="KEYCODE_ASSIST" value="219" />
+ <enum name="KEYCODE_BRIGHTNESS_DOWN" value="220" />
+ <enum name="KEYCODE_BRIGHTNESS_UP" value="221" />
+ <enum name="KEYCODE_MEDIA_AUDIO_TRACK" value="222" />
+ <enum name="KEYCODE_MEDIA_SLEEP" value="223" />
+ <enum name="KEYCODE_MEDIA_WAKEUP" value="224" />
+ <enum name="KEYCODE_PAIRING" value="225" />
+ <enum name="KEYCODE_MEDIA_TOP_MENU" value="226" />
+ <enum name="KEYCODE_11" value="227" />
+ <enum name="KEYCODE_12" value="228" />
+ <enum name="KEYCODE_LAST_CHANNEL" value="229" />
+ <enum name="KEYCODE_TV_DATA_SERVICE" value="230" />
+ <enum name="KEYCODE_VOICE_ASSIST" value="231" />
+ <enum name="KEYCODE_TV_RADIO_SERVICE" value="232" />
+ <enum name="KEYCODE_TV_TELETEXT" value="233" />
+ <enum name="KEYCODE_TV_NUMBER_ENTRY" value="234" />
+ <enum name="KEYCODE_TV_TERRESTRIAL_ANALOG" value="235" />
+ <enum name="KEYCODE_TV_TERRESTRIAL_DIGITAL" value="236" />
+ <enum name="KEYCODE_TV_SATELLITE" value="237" />
+ <enum name="KEYCODE_TV_SATELLITE_BS" value="238" />
+ <enum name="KEYCODE_TV_SATELLITE_CS" value="239" />
+ <enum name="KEYCODE_TV_SATELLITE_SERVICE" value="240" />
+ <enum name="KEYCODE_TV_NETWORK" value="241" />
+ <enum name="KEYCODE_TV_ANTENNA_CABLE" value="242" />
+ <enum name="KEYCODE_TV_INPUT_HDMI_1" value="243" />
+ <enum name="KEYCODE_TV_INPUT_HDMI_2" value="244" />
+ <enum name="KEYCODE_TV_INPUT_HDMI_3" value="245" />
+ <enum name="KEYCODE_TV_INPUT_HDMI_4" value="246" />
+ <enum name="KEYCODE_TV_INPUT_COMPOSITE_1" value="247" />
+ <enum name="KEYCODE_TV_INPUT_COMPOSITE_2" value="248" />
+ <enum name="KEYCODE_TV_INPUT_COMPONENT_1" value="249" />
+ <enum name="KEYCODE_TV_INPUT_COMPONENT_2" value="250" />
+ <enum name="KEYCODE_TV_INPUT_VGA_1" value="251" />
+ <enum name="KEYCODE_TV_AUDIO_DESCRIPTION" value="252" />
+ <enum name="KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP" value="253" />
+ <enum name="KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN" value="254" />
+ <enum name="KEYCODE_TV_ZOOM_MODE" value="255" />
+ <enum name="KEYCODE_TV_CONTENTS_MENU" value="256" />
+ <enum name="KEYCODE_TV_MEDIA_CONTEXT_MENU" value="257" />
+ <enum name="KEYCODE_TV_TIMER_PROGRAMMING" value="258" />
+ <enum name="KEYCODE_HELP" value="259" />
+ <enum name="KEYCODE_NAVIGATE_PREVIOUS" value="260" />
+ <enum name="KEYCODE_NAVIGATE_NEXT" value="261" />
+ <enum name="KEYCODE_NAVIGATE_IN" value="262" />
+ <enum name="KEYCODE_NAVIGATE_OUT" value="263" />
+ <enum name="KEYCODE_STEM_PRIMARY" value="264" />
+ <enum name="KEYCODE_STEM_1" value="265" />
+ <enum name="KEYCODE_STEM_2" value="266" />
+ <enum name="KEYCODE_STEM_3" value="267" />
+ <enum name="KEYCODE_DPAD_UP_LEFT" value="268" />
+ <enum name="KEYCODE_DPAD_DOWN_LEFT" value="269" />
+ <enum name="KEYCODE_DPAD_UP_RIGHT" value="270" />
+ <enum name="KEYCODE_DPAD_DOWN_RIGHT" value="271" />
+ <enum name="KEYCODE_MEDIA_SKIP_FORWARD" value="272" />
+ <enum name="KEYCODE_MEDIA_SKIP_BACKWARD" value="273" />
+ <enum name="KEYCODE_MEDIA_STEP_FORWARD" value="274" />
+ <enum name="KEYCODE_MEDIA_STEP_BACKWARD" value="275" />
+ <enum name="KEYCODE_SOFT_SLEEP" value="276" />
+ <enum name="KEYCODE_CUT" value="277" />
+ <enum name="KEYCODE_COPY" value="278" />
+ <enum name="KEYCODE_PASTE" value="279" />
+ <enum name="KEYCODE_SYSTEM_NAVIGATION_UP" value="280" />
+ <enum name="KEYCODE_SYSTEM_NAVIGATION_DOWN" value="281" />
+ <enum name="KEYCODE_SYSTEM_NAVIGATION_LEFT" value="282" />
+ <enum name="KEYCODE_SYSTEM_NAVIGATION_RIGHT" value="283" />
+ <enum name="KEYCODE_ALL_APPS" value="284" />
+ <enum name="KEYCODE_REFRESH" value="285" />
+ <enum name="KEYCODE_THUMBS_UP" value="286" />
+ <enum name="KEYCODE_THUMBS_DOWN" value="287" />
+ <enum name="KEYCODE_PROFILE_SWITCH" value="288" />
+ <enum name="KEYCODE_VIDEO_APP_1" value="289" />
+ <enum name="KEYCODE_VIDEO_APP_2" value="290" />
+ <enum name="KEYCODE_VIDEO_APP_3" value="291" />
+ <enum name="KEYCODE_VIDEO_APP_4" value="292" />
+ <enum name="KEYCODE_VIDEO_APP_5" value="293" />
+ <enum name="KEYCODE_VIDEO_APP_6" value="294" />
+ <enum name="KEYCODE_VIDEO_APP_7" value="295" />
+ <enum name="KEYCODE_VIDEO_APP_8" value="296" />
+ <enum name="KEYCODE_FEATURED_APP_1" value="297" />
+ <enum name="KEYCODE_FEATURED_APP_2" value="298" />
+ <enum name="KEYCODE_FEATURED_APP_3" value="299" />
+ <enum name="KEYCODE_FEATURED_APP_4" value="300" />
+ <enum name="KEYCODE_DEMO_APP_1" value="301" />
+ <enum name="KEYCODE_DEMO_APP_2" value="302" />
+ <enum name="KEYCODE_DEMO_APP_3" value="303" />
+ <enum name="KEYCODE_DEMO_APP_4" value="304" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_DOWN" value="305" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_UP" value="306" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE" value="307" />
+ <enum name="KEYCODE_STYLUS_BUTTON_PRIMARY" value="308" />
+ <enum name="KEYCODE_STYLUS_BUTTON_SECONDARY" value="309" />
+ <enum name="KEYCODE_STYLUS_BUTTON_TERTIARY" value="310" />
+ <enum name="KEYCODE_STYLUS_BUTTON_TAIL" value="311" />
+ <enum name="KEYCODE_RECENT_APPS" value="312" />
+ <enum name="KEYCODE_MACRO_1" value="313" />
+ <enum name="KEYCODE_MACRO_2" value="314" />
+ <enum name="KEYCODE_MACRO_3" value="315" />
+ <enum name="KEYCODE_MACRO_4" value="316" />
+ <enum name="KEYCODE_EMOJI_PICKER" value="317" />
+ <enum name="KEYCODE_SCREENSHOT" value="318" />
</attr>
<!-- ***************************************************************** -->
@@ -3966,7 +4304,7 @@
<attr name="settingsActivity" format="string" />
<!-- Component name of an activity that allows the user to modify
on-screen keyboards variants (e.g. different language or layout) for this service. -->
- <!-- @FlaggedApi("android.view.inputmethod.ime_switcher_revamp") -->
+ <!-- @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") -->
<attr name="languageSettingsActivity" format="string"/>
<!-- Set to true in all of the configurations for which this input
method should be considered an option as the default. -->
@@ -9704,6 +10042,8 @@
<declare-styleable name="PointerIconVectorTheme">
<attr name="pointerIconVectorFill" format="color" />
<attr name="pointerIconVectorFillInverse" format="color" />
+ <attr name="pointerIconVectorStroke" format="color" />
+ <attr name="pointerIconVectorStrokeInverse" format="color" />
</declare-styleable>
<declare-styleable name="Storage">
@@ -9844,6 +10184,63 @@
<attr name="productId" format="integer" />
</declare-styleable>
+ <!-- @hide -->
+ <declare-styleable name="KeyboardGlyphMap">
+ <attr name="glyphMap" format="reference" />
+ <attr name="vendorId" format="integer" />
+ <attr name="productId" format="integer" />
+ </declare-styleable>
+
+ <!-- @hide -->
+ <declare-styleable name="KeyGlyph">
+ <attr name="keycode" />
+ <attr name="glyphDrawable" format="reference" />
+ </declare-styleable>
+
+ <!-- @hide -->
+ <declare-styleable name="ModifierGlyph">
+ <!-- The values are taken from public constants for modifier state defined in
+ {@see KeyEvent.java}. Here we explicitly allow only one modifier bit as value, since
+ this represents the modifier key -->
+ <attr name="modifier">
+ <enum name="META" value="0x10000" />
+ <enum name="CTRL" value="0x1000" />
+ <enum name="ALT" value="0x02" />
+ <enum name="SHIFT" value="0x1" />
+ <enum name="SYM" value="0x4" />
+ <enum name="FUNCTION" value="0x8" />
+ <enum name="CAPS_LOCK" value="0x100000" />
+ <enum name="NUM_LOCK" value="0x200000" />
+ <enum name="SCROLL_LOCK" value="0x400000" />
+ </attr>
+ <attr name="glyphDrawable" format="reference" />
+ </declare-styleable>
+
+ <!-- @hide -->
+ <declare-styleable name="HardwareDefinedShortcut">
+ <attr name="keycode" />
+ <!-- The values are taken from public constants for modifier state defined in
+ {@see KeyEvent.java}. Here we allow multiple modifier flags as value, since this
+ represents the modifier state -->
+ <attr name="modifierState">
+ <flag name="META" value="0x10000" />
+ <flag name="CTRL" value="0x1000" />
+ <flag name="ALT" value="0x02" />
+ <flag name="SHIFT" value="0x1" />
+ <flag name="SYM" value="0x4" />
+ <flag name="FUNCTION" value="0x8" />
+ <flag name="CAPS_LOCK" value="0x100000" />
+ <flag name="NUM_LOCK" value="0x200000" />
+ <flag name="SCROLL_LOCK" value="0x400000" />
+ </attr>
+ <attr name="outKeycode" />
+ </declare-styleable>
+
+ <!-- @hide -->
+ <declare-styleable name="FunctionRowKey">
+ <attr name="keycode" />
+ </declare-styleable>
+
<declare-styleable name="MediaRouteButton">
<!-- This drawable is a state list where the "activated" state
indicates active media routing. Non-activated indicates
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index f94c8ab0350e..2e3dbda5e41c 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1052,6 +1052,19 @@
<!-- The font weight adjustment value has changed. Used to reflect the user increasing font
weight. -->
<flag name="fontWeightAdjustment" value="0x10000000" />
+ <!-- The assets paths have changed. For example a runtime overlay is installed and enabled.
+ Corresponds to {@link android.content.pm.ActivityInfo#CONFIG_ASSETS_PATHS}. -->
+ <flag name="assetsPaths" value="0x80000000" />
+ <!-- This is probably not the flag you want, the resources compiler supports a less
+ dangerous version of it, 'allKnown', that only suppresses all currently existing
+ configuration change restarts depending on your target SDK rather than whatever the
+ latest SDK supports, allowing the application to work with resources on future Platform
+ versions.
+ Activity doesn't use Android Resources at all and doesn't need to be restarted on any
+ configuration changes. This overrides all other flags, and this is recommended to be
+ used individually. Corresponds to
+ {@link android.content.pm.ActivityInfo#CONFIG_RESOURCES_UNUSED}. -->
+ <flag name="resourcesUnused" value="0x8000000" />
</attr>
<!-- Indicate that the activity can be launched as the embedded child of another
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 335b74025da3..dc3d9355f148 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -533,6 +533,9 @@
<!-- If this is true, key chords can be used to take a screenshot on the device. -->
<bool name="config_enableScreenshotChord">true</bool>
+ <!-- If this is true, accessibility events on notifications are sent. -->
+ <bool name="config_enableNotificationAccessibilityEvents">true</bool>
+
<!-- If this is true, allow wake from theater mode when plugged in or unplugged. -->
<bool name="config_allowTheaterModeWakeFromUnplug">false</bool>
<!-- If this is true, allow wake from theater mode from gesture. -->
@@ -4133,8 +4136,8 @@
and should depend on the touch feedback intensity user setting -->
<item name="config_keyboardHapticFeedbackFixedAmplitude" format="float" type="dimen">-1</item>
- <!-- The default value for keyboard vibration toggle in settings. -->
- <bool name="config_defaultKeyboardVibrationEnabled">true</bool>
+ <!-- Indicating if keyboard vibration settings supported or not. -->
+ <bool name="config_keyboardVibrationSettingsSupported">false</bool>
<!-- If the device should still vibrate even in low power mode, for certain priority vibrations
(e.g. accessibility, alarms). This is mainly for Wear devices that don't have speakers. -->
diff --git a/core/res/res/values/locale_config.xml b/core/res/res/values/locale_config.xml
index bd93aa9402c3..77d2e873682f 100644
--- a/core/res/res/values/locale_config.xml
+++ b/core/res/res/values/locale_config.xml
@@ -14,6 +14,11 @@
limitations under the License.
-->
+<!--
+ ICU Version: 75.1
+ CLDR Data Version: 45
+-->
+
<resources>
<string-array translatable="false" name="supported_locales">
@@ -88,6 +93,11 @@
<item>bem-ZM</item> <!-- Bemba (Zambia) -->
<item>bez-TZ</item> <!-- Bena (Tanzania) -->
<item>bg-BG</item> <!-- Bulgarian (Bulgaria) -->
+ <item>bgc-IN</item> <!-- Haryanvi (India) -->
+ <item>bgc-IN-u-nu-latn</item> <!-- Haryanvi (India, Western Digits) -->
+ <item>bho-IN</item> <!-- Bhojpuri (India) -->
+ <item>bho-IN-u-nu-latn</item> <!-- Bhojpuri (India, Western Digits) -->
+ <item>blo-BJ</item> <!-- Anii (Benin) -->
<item>bm-ML</item> <!-- Bambara (Mali) -->
<item>bn-BD</item> <!-- Bangla (Bangladesh) -->
<item>bn-BD-u-nu-latn</item> <!-- Bangla (Bangladesh, Western Digits) -->
@@ -108,6 +118,7 @@
<item>cgg-UG</item> <!-- Chiga (Uganda) -->
<item>chr-US</item> <!-- Cherokee (United States) -->
<item>cs-CZ</item> <!-- Czech (Czechia) -->
+ <item>csw-CA</item> <!-- Swampy Cree (Canada) -->
<item>cv-RU</item> <!-- Chuvash (Russia) -->
<item>cy-GB</item> <!-- Welsh (United Kingdom) -->
<item>da-DK</item> <!-- Danish (Denmark) -->
@@ -170,6 +181,7 @@
<item>en-GU</item> <!-- English (Guam) -->
<item>en-GY</item> <!-- English (Guyana) -->
<item>en-HK</item> <!-- English (Hong Kong) -->
+ <item>en-ID</item> <!-- English (Indonesia) -->
<item>en-IE</item> <!-- English (Ireland) -->
<item>en-IL</item> <!-- English (Israel) -->
<item>en-IM</item> <!-- English (Isle of Man) -->
@@ -237,6 +249,7 @@
<item>en-ZA</item> <!-- English (South Africa) -->
<item>en-ZM</item> <!-- English (Zambia) -->
<item>en-ZW</item> <!-- English (Zimbabwe) -->
+ <item>eo-001</item> <!-- Esperanto (world) -->
<item>es-AR</item> <!-- Spanish (Argentina) -->
<item>es-BO</item> <!-- Spanish (Bolivia) -->
<item>es-BR</item> <!-- Spanish (Brazil) -->
@@ -381,6 +394,7 @@
<item>hu-HU</item> <!-- Hungarian (Hungary) -->
<item>hy-AM</item> <!-- Armenian (Armenia) -->
<item>ia-001</item> <!-- Interlingua (world) -->
+ <item>ie-EE</item> <!-- Interlingue (Estonia) -->
<item>ig-NG</item> <!-- Igbo (Nigeria) -->
<item>ii-CN</item> <!-- Sichuan Yi (China) -->
<item>in-ID</item> <!-- Indonesian (Indonesia) -->
@@ -408,6 +422,7 @@
<item>kln-KE</item> <!-- Kalenjin (Kenya) -->
<item>km-KH</item> <!-- Khmer (Cambodia) -->
<item>kn-IN</item> <!-- Kannada (India) -->
+ <item>ko-CN</item> <!-- Korean (China) -->
<item>ko-KP</item> <!-- Korean (North Korea) -->
<item>ko-KR</item> <!-- Korean (South Korea) -->
<item>kok-IN</item> <!-- Konkani (India) -->
@@ -417,12 +432,19 @@
<item>ksb-TZ</item> <!-- Shambala (Tanzania) -->
<item>ksf-CM</item> <!-- Bafia (Cameroon) -->
<item>ksh-DE</item> <!-- Colognian (Germany) -->
+ <item>ku-TR</item> <!-- Kurdish (Türkiye) -->
<item>kw-GB</item> <!-- Cornish (United Kingdom) -->
+ <item>kxv-Deva-IN</item> <!-- Kuvi (Devanagari, India) -->
+ <item>kxv-Latn-IN</item> <!-- Kuvi (Latin, India) -->
+ <item>kxv-Orya-IN</item> <!-- Kuvi (Odia, India) -->
+ <item>kxv-Telu-IN</item> <!-- Kuvi (Telugu, India) -->
<item>ky-KG</item> <!-- Kyrgyz (Kyrgyzstan) -->
<item>lag-TZ</item> <!-- Langi (Tanzania) -->
<item>lb-LU</item> <!-- Luxembourgish (Luxembourg) -->
<item>lg-UG</item> <!-- Ganda (Uganda) -->
+ <item>lij-IT</item> <!-- Ligurian (Italy) -->
<item>lkt-US</item> <!-- Lakota (United States) -->
+ <item>lmo-IT</item> <!-- Lombard (Italy) -->
<item>ln-AO</item> <!-- Lingala (Angola) -->
<item>ln-CD</item> <!-- Lingala (Congo - Kinshasa) -->
<item>ln-CF</item> <!-- Lingala (Central African Republic) -->
@@ -462,6 +484,8 @@
<item>nb-NO</item> <!-- Norwegian Bokmål (Norway) -->
<item>nb-SJ</item> <!-- Norwegian Bokmål (Svalbard & Jan Mayen) -->
<item>nd-ZW</item> <!-- North Ndebele (Zimbabwe) -->
+ <item>nds-DE</item> <!-- Low German (Germany) -->
+ <item>nds-NL</item> <!-- Low German (Netherlands) -->
<item>ne-IN</item> <!-- Nepali (India) -->
<item>ne-IN-u-nu-latn</item> <!-- Nepali (India, Western Digits) -->
<item>ne-NP</item> <!-- Nepali (Nepal) -->
@@ -475,8 +499,12 @@
<item>nl-SX</item> <!-- Dutch (Sint Maarten) -->
<item>nn-NO</item> <!-- Norwegian Nynorsk (Norway) -->
<item>nnh-CM</item> <!-- Ngiemboon (Cameroon) -->
+ <item>nqo-GN</item> <!-- N’Ko (Guinea) -->
+ <item>nqo-GN-u-nu-latn</item> <!-- N’Ko (Guinea, Western Digits) -->
<item>nus-SS</item> <!-- Nuer (South Sudan) -->
<item>nyn-UG</item> <!-- Nyankole (Uganda) -->
+ <item>oc-ES</item> <!-- Occitan (Spain) -->
+ <item>oc-FR</item> <!-- Occitan (France) -->
<item>om-ET</item> <!-- Oromo (Ethiopia) -->
<item>om-KE</item> <!-- Oromo (Kenya) -->
<item>or-IN</item> <!-- Odia (India) -->
@@ -487,6 +515,7 @@
<item>pa-Guru-IN</item> <!-- Punjabi (Gurmukhi, India) -->
<item>pcm-NG</item> <!-- Nigerian Pidgin (Nigeria) -->
<item>pl-PL</item> <!-- Polish (Poland) -->
+ <item>prg-PL</item> <!-- Prussian (Poland) -->
<item>ps-AF</item> <!-- Pashto (Afghanistan) -->
<item>ps-AF-u-nu-latn</item> <!-- Pashto (Afghanistan, Western Digits) -->
<item>ps-PK</item> <!-- Pashto (Pakistan) -->
@@ -566,6 +595,9 @@
<item>sw-KE</item> <!-- Swahili (Kenya) -->
<item>sw-TZ</item> <!-- Swahili (Tanzania) -->
<item>sw-UG</item> <!-- Swahili (Uganda) -->
+ <item>syr-IQ</item> <!-- Syriac (Iraq) -->
+ <item>syr-SY</item> <!-- Syriac (Syria) -->
+ <item>szl-PL</item> <!-- Silesian (Poland) -->
<item>ta-IN</item> <!-- Tamil (India) -->
<item>ta-LK</item> <!-- Tamil (Sri Lanka) -->
<item>ta-MY</item> <!-- Tamil (Malaysia) -->
@@ -580,7 +612,7 @@
<item>tk-TM</item> <!-- Turkmen (Turkmenistan) -->
<item>to-TO</item> <!-- Tongan (Tonga) -->
<item>tr-CY</item> <!-- Turkish (Cyprus) -->
- <item>tr-TR</item> <!-- Turkish (Turkey) -->
+ <item>tr-TR</item> <!-- Turkish (Türkiye) -->
<item>tt-RU</item> <!-- Tatar (Russia) -->
<item>twq-NE</item> <!-- Tasawaq (Niger) -->
<item>tzm-MA</item> <!-- Central Atlas Tamazight (Morocco) -->
@@ -594,11 +626,14 @@
<item>uz-Arab-AF-u-nu-latn</item> <!-- Uzbek (Arabic, Afghanistan, Western Digits) -->
<item>uz-Cyrl-UZ</item> <!-- Uzbek (Cyrillic, Uzbekistan) -->
<item>uz-Latn-UZ</item> <!-- Uzbek (Latin, Uzbekistan) -->
+ <item>vec-IT</item> <!-- Venetian (Italy) -->
<item>vi-VN</item> <!-- Vietnamese (Vietnam) -->
+ <item>vmw-MZ</item> <!-- Makhuwa (Mozambique) -->
<item>vun-TZ</item> <!-- Vunjo (Tanzania) -->
<item>wae-CH</item> <!-- Walser (Switzerland) -->
<item>wo-SN</item> <!-- Wolof (Senegal) -->
<item>xh-ZA</item> <!-- Xhosa (South Africa) -->
+ <item>xnr-IN</item> <!-- Kangri (India) -->
<item>xog-UG</item> <!-- Soga (Uganda) -->
<item>yav-CM</item> <!-- Yangben (Cameroon) -->
<item>yo-BJ</item> <!-- Yoruba (Benin) -->
@@ -608,6 +643,7 @@
<item>yrl-VE</item> <!-- Nheengatu (Venezuela) -->
<item>yue-Hans-CN</item> <!-- Cantonese (Simplified, China) -->
<item>yue-Hant-HK</item> <!-- Cantonese (Traditional, Hong Kong) -->
+ <item>za-CN</item> <!-- Zhuang (China) -->
<item>zgh-MA</item> <!-- Standard Moroccan Tamazight (Morocco) -->
<item>zh-Hans-CN</item> <!-- Chinese (Simplified, China) -->
<item>zh-Hans-HK</item> <!-- Chinese (Simplified, Hong Kong) -->
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index b64334f7f95a..b74b41c666c8 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -114,7 +114,7 @@
<public name="optional"/>
<!-- @FlaggedApi("android.media.tv.flags.enable_ad_service_fw") -->
<public name="adServiceTypes" />
- <!-- @FlaggedApi("android.view.inputmethod.ime_switcher_revamp") -->
+ <!-- @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") -->
<public name="languageSettingsActivity"/>
<!-- @FlaggedApi("android.service.controls.flags.Flags.FLAG_HOME_PANEL_DREAM") -->
<public name="dreamCategory"/>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 6b71f97e3f17..46b154163224 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -6534,4 +6534,23 @@ ul.</string>
<string name="bg_user_sound_notification_button_mute">Mute</string>
<!-- Notification text to mute the sound from the background user [CHAR LIMIT=NOTIF_BODY]-->
<string name="bg_user_sound_notification_message">Tap to mute sound</string>
+
+ <!-- User visible title for the keyboard shortcut that takes the user to the browser app. [CHAR LIMIT=70] -->
+ <string name="keyboard_shortcut_group_applications_browser">Browser</string>
+ <!-- User visible title for the keyboard shortcut that takes the user to the contacts app. [CHAR LIMIT=70] -->
+ <string name="keyboard_shortcut_group_applications_contacts">Contacts</string>
+ <!-- User visible title for the keyboard shortcut that takes the user to the email app. [CHAR LIMIT=70] -->
+ <string name="keyboard_shortcut_group_applications_email">Email</string>
+ <!-- User visible title for the keyboard shortcut that takes the user to the SMS messaging app. [CHAR LIMIT=70] -->
+ <string name="keyboard_shortcut_group_applications_sms">SMS</string>
+ <!-- User visible title for the keyboard shortcut that takes the user to the music app. [CHAR LIMIT=70] -->
+ <string name="keyboard_shortcut_group_applications_music">Music</string>
+ <!-- User visible title for the keyboard shortcut that takes the user to the calendar app. [CHAR LIMIT=70] -->
+ <string name="keyboard_shortcut_group_applications_calendar">Calendar</string>
+ <!-- User visible title for the keyboard shortcut that takes the user to the calculator app. [CHAR LIMIT=70] -->
+ <string name="keyboard_shortcut_group_applications_calculator">Calculator</string>
+ <!-- User visible title for the keyboard shortcut that takes the user to the maps app. [CHAR LIMIT=70] -->
+ <string name="keyboard_shortcut_group_applications_maps">Maps</string>
+ <!-- User visible title for the keyboard shortcut group containing system-wide application launch shortcuts. [CHAR-LIMIT=70] -->
+ <string name="keyboard_shortcut_group_applications">Applications</string>
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 50c3b1a93d75..aabc8ca5aef6 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1527,6 +1527,24 @@ please see styles_device_defaults.xml.
</style>
<!-- @hide -->
+ <style name="PointerIconVectorStyleStrokeWhite">
+ <item name="pointerIconVectorStroke">@color/white</item>
+ <item name="pointerIconVectorStrokeInverse">@color/black</item>
+ </style>
+
+ <!-- @hide -->
+ <style name="PointerIconVectorStyleStrokeBlack">
+ <item name="pointerIconVectorStroke">@color/black</item>
+ <item name="pointerIconVectorStrokeInverse">@color/white</item>
+ </style>
+
+ <!-- @hide -->
+ <style name="PointerIconVectorStyleStrokeNone">
+ <item name="pointerIconVectorStroke">@color/transparent</item>
+ <item name="pointerIconVectorStrokeInverse">@color/transparent</item>
+ </style>
+
+ <!-- @hide -->
<style name="aerr_list_item" parent="Widget.Material.Light.Button.Borderless">
<item name="minHeight">?attr/listPreferredItemHeightSmall</item>
<item name="textAppearance">?attr/textAppearanceListItemSmall</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7d50d227ee13..c50b961f74cd 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1704,6 +1704,10 @@
<java-symbol type="style" name="PointerIconVectorStyleFillPink" />
<java-symbol type="style" name="PointerIconVectorStyleFillBlue" />
<java-symbol type="attr" name="pointerIconVectorFill" />
+ <java-symbol type="style" name="PointerIconVectorStyleStrokeWhite" />
+ <java-symbol type="style" name="PointerIconVectorStyleStrokeBlack" />
+ <java-symbol type="style" name="PointerIconVectorStyleStrokeNone" />
+ <java-symbol type="attr" name="pointerIconVectorStroke" />
<java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Title" />
<java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Info" />
@@ -2002,6 +2006,7 @@
<java-symbol type="array" name="config_notificationFallbackVibeWaveform" />
<java-symbol type="bool" name="config_enableServerNotificationEffectsForAutomotive" />
<java-symbol type="bool" name="config_useAttentionLight" />
+ <java-symbol type="bool" name="config_enableNotificationAccessibilityEvents" />
<java-symbol type="bool" name="config_adaptive_sleep_available" />
<java-symbol type="bool" name="config_camera_autorotate"/>
<java-symbol type="bool" name="config_animateScreenLights" />
@@ -2121,7 +2126,7 @@
<java-symbol type="integer" name="config_defaultVibrationAmplitude" />
<java-symbol type="dimen" name="config_hapticChannelMaxVibrationAmplitude" />
<java-symbol type="dimen" name="config_keyboardHapticFeedbackFixedAmplitude" />
- <java-symbol type="bool" name="config_defaultKeyboardVibrationEnabled" />
+ <java-symbol type="bool" name="config_keyboardVibrationSettingsSupported" />
<java-symbol type="integer" name="config_vibrationWaveformRampStepDuration" />
<java-symbol type="bool" name="config_ignoreVibrationsOnWirelessCharger" />
<java-symbol type="integer" name="config_vibrationWaveformRampDownDuration" />
@@ -4055,6 +4060,7 @@
<java-symbol type="id" name="snooze_button" />
<java-symbol type="dimen" name="text_size_body_2_material" />
<java-symbol type="dimen" name="notification_icon_circle_size" />
+ <java-symbol type="drawable" name="notification_icon_circle" />
<java-symbol type="dimen" name="messaging_avatar_size" />
<java-symbol type="dimen" name="messaging_group_sending_progress_size" />
<java-symbol type="dimen" name="messaging_image_rounding" />
@@ -5555,4 +5561,15 @@
<java-symbol type="string" name="bg_user_sound_notification_button_switch_user" />
<java-symbol type="string" name="bg_user_sound_notification_button_mute" />
<java-symbol type="string" name="bg_user_sound_notification_message" />
+
+ <!-- Keyboard Shortcut default category names. -->
+ <java-symbol type="string" name="keyboard_shortcut_group_applications_browser" />
+ <java-symbol type="string" name="keyboard_shortcut_group_applications_calculator" />
+ <java-symbol type="string" name="keyboard_shortcut_group_applications_calendar" />
+ <java-symbol type="string" name="keyboard_shortcut_group_applications_contacts" />
+ <java-symbol type="string" name="keyboard_shortcut_group_applications_email" />
+ <java-symbol type="string" name="keyboard_shortcut_group_applications_maps" />
+ <java-symbol type="string" name="keyboard_shortcut_group_applications_music" />
+ <java-symbol type="string" name="keyboard_shortcut_group_applications_sms" />
+ <java-symbol type="string" name="keyboard_shortcut_group_applications" />
</resources>
diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml
index fc63657f04d0..f67ad3f5575e 100644
--- a/core/res/res/xml/power_profile.xml
+++ b/core/res/res/xml/power_profile.xml
@@ -33,14 +33,14 @@
There must be one of these for each display, labeled:
ambient.on.display0, ambient.on.display1, etc...
- Each display suffix number should match it's ordinal in its display device config.
+ Each display suffix number should match its ordinal in its display device config.
-->
<item name="ambient.on.display0">0.1</item> <!-- ~100mA -->
<!-- Average battery current draw of display0 while on without backlight.
There must be one of these for each display, labeled:
screen.on.display0, screen.on.display1, etc...
- Each display suffix number should match it's ordinal in its display device config.
+ Each display suffix number should match its ordinal in its display device config.
-->
<item name="screen.on.display0">0.1</item> <!-- ~100mA -->
<!-- Average battery current draw of the backlight at full brightness.
@@ -50,7 +50,7 @@
There must be one of these for each display, labeled:
screen.full.display0, screen.full.display1, etc...
- Each display suffix number should match it's ordinal in its display device config.
+ Each display suffix number should match its ordinal in its display device config.
-->
<item name="screen.full.display0">0.1</item> <!-- ~100mA -->
diff --git a/core/tests/InputMethodCoreTests/src/android/view/inputmethod/InputMethodInfoTest.java b/core/tests/InputMethodCoreTests/src/android/view/inputmethod/InputMethodInfoTest.java
index 36ab0d4b0868..ce85a76f478d 100644
--- a/core/tests/InputMethodCoreTests/src/android/view/inputmethod/InputMethodInfoTest.java
+++ b/core/tests/InputMethodCoreTests/src/android/view/inputmethod/InputMethodInfoTest.java
@@ -70,7 +70,7 @@ public class InputMethodInfoTest {
assertThat(imi.supportsInlineSuggestionsWithTouchExploration(), is(false));
assertThat(imi.supportsStylusHandwriting(), is(false));
assertThat(imi.createStylusHandwritingSettingsActivityIntent(), equalTo(null));
- if (Flags.imeSwitcherRevamp()) {
+ if (Flags.imeSwitcherRevampApi()) {
assertThat(imi.createImeLanguageSettingsActivityIntent(), equalTo(null));
}
}
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index d2771691c50c..41696dfa782e 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -63,7 +63,6 @@ android_test {
"-c fa",
],
static_libs: [
- "A11yChecker",
"collector-device-lib-platform",
"frameworks-base-testutils",
"core-test-rules", // for libcore.dalvik.system.CloseGuardSupport
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index e9ad1c28578a..ef6ff0518dac 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -84,6 +84,8 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+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;
import android.text.Spannable;
@@ -545,12 +547,26 @@ public class NotificationTest {
}
@Test
+ @DisableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
public void testBuilder_setSilent_emptyGroupKey_groupKeySilent() {
Notification emptyGroupKeyNotif = new Notification.Builder(mContext, "channelId")
.setGroup("")
.setSilent(true)
.build();
- assertEquals(GROUP_KEY_SILENT, emptyGroupKeyNotif.getGroup());
+ assertThat(emptyGroupKeyNotif.getGroup()).isEqualTo(GROUP_KEY_SILENT);
+ assertThat(emptyGroupKeyNotif.isSilent()).isTrue();
+ }
+
+ @Test
+ @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+ public void testBuilder_setSilent_flagSilent() {
+ final String groupKey = "groupKey";
+ Notification emptyGroupKeyNotif = new Notification.Builder(mContext, "channelId")
+ .setGroup(groupKey)
+ .setSilent(true)
+ .build();
+ assertThat(emptyGroupKeyNotif.getGroup()).isEqualTo(groupKey);
+ assertThat(emptyGroupKeyNotif.isSilent()).isTrue();
}
@Test
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index f87a9e2b3643..e8a0762f70c0 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -25,8 +25,6 @@ import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
-import static com.android.window.flags.Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG;
-
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
@@ -810,7 +808,6 @@ public class ActivityThreadTest {
@Test
public void testActivityWindowInfoChanged_activityLaunch() {
- mSetFlagsRule.enableFlags(FLAG_ACTIVITY_WINDOW_INFO_FLAG);
ClientTransactionListenerController.getInstance().registerActivityWindowInfoChangedListener(
mActivityWindowInfoListener);
@@ -825,7 +822,6 @@ public class ActivityThreadTest {
@Test
public void testActivityWindowInfoChanged_activityRelaunch() {
- mSetFlagsRule.enableFlags(FLAG_ACTIVITY_WINDOW_INFO_FLAG);
ClientTransactionListenerController.getInstance().registerActivityWindowInfoChangedListener(
mActivityWindowInfoListener);
@@ -866,7 +862,6 @@ public class ActivityThreadTest {
@Test
public void testActivityWindowInfoChanged_activityConfigurationChanged() {
- mSetFlagsRule.enableFlags(FLAG_ACTIVITY_WINDOW_INFO_FLAG);
ClientTransactionListenerController.getInstance().registerActivityWindowInfoChangedListener(
mActivityWindowInfoListener);
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
index 0b270d485b97..d2a444f0d0df 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
@@ -53,8 +53,6 @@ import android.window.WindowTokenClient;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.window.flags.Flags;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -167,8 +165,6 @@ public class ClientTransactionListenerControllerTest {
@Test
public void testActivityWindowInfoChangedListener() {
- mSetFlagsRule.enableFlags(Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG);
-
mController.registerActivityWindowInfoChangedListener(mActivityWindowInfoListener);
final ActivityWindowInfo activityWindowInfo = new ActivityWindowInfo();
activityWindowInfo.set(true /* isEmbedded */, new Rect(0, 0, 1000, 2000),
diff --git a/core/tests/coretests/src/android/inputmethodservice/ImsConfigurationTrackerTest.java b/core/tests/coretests/src/android/inputmethodservice/ImsConfigurationTrackerTest.java
index 064439e9b113..6998c32978c1 100644
--- a/core/tests/coretests/src/android/inputmethodservice/ImsConfigurationTrackerTest.java
+++ b/core/tests/coretests/src/android/inputmethodservice/ImsConfigurationTrackerTest.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
+import android.platform.test.annotations.RequiresFlagsEnabled;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -74,4 +75,33 @@ public class ImsConfigurationTrackerTest {
assertFalse("IME shouldn't restart since it handles configChanges",
didReset.get());
}
+
+ @Test
+ @RequiresFlagsEnabled(android.content.res.Flags.FLAG_HANDLE_ALL_CONFIG_CHANGES)
+ public void testShouldImeRestart_handleResourceUnused() throws Exception {
+ Configuration config = mContext.getResources().getConfiguration();
+ mImsConfigTracker.onInitialize(0 /* handledConfigChanges */);
+ mImsConfigTracker.onBindInput(mContext.getResources());
+ Configuration newConfig = new Configuration(config);
+
+ final AtomicBoolean didReset = new AtomicBoolean();
+ Runnable resetStateRunner = () -> didReset.set(true);
+
+ mImsConfigTracker.onConfigurationChanged(newConfig, resetStateRunner);
+ assertFalse("IME shouldn't restart if config hasn't changed",
+ didReset.get());
+
+ // Screen density changed but IME doesn't handle configChanges
+ newConfig.densityDpi = 99;
+ mImsConfigTracker.onConfigurationChanged(newConfig, resetStateRunner);
+ assertTrue("IME should restart for unhandled configChanges",
+ didReset.get());
+
+ didReset.set(false);
+ // opt-in IME to handle all configuration changes.
+ mImsConfigTracker.setHandledConfigChanges(ActivityInfo.CONFIG_RESOURCES_UNUSED);
+ mImsConfigTracker.onConfigurationChanged(newConfig, resetStateRunner);
+ assertFalse("IME shouldn't restart since it handles configChanges",
+ didReset.get());
+ }
}
diff --git a/core/tests/coretests/src/android/util/SequenceUtilsTest.java b/core/tests/coretests/src/android/util/SequenceUtilsTest.java
index 020520dbcf85..6ca1751a675b 100644
--- a/core/tests/coretests/src/android/util/SequenceUtilsTest.java
+++ b/core/tests/coretests/src/android/util/SequenceUtilsTest.java
@@ -19,7 +19,7 @@ package android.util;
import static android.util.SequenceUtils.getInitSeq;
import static android.util.SequenceUtils.getNextSeq;
-import static android.util.SequenceUtils.isIncomingSeqNewer;
+import static android.util.SequenceUtils.isIncomingSeqStale;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -60,30 +60,35 @@ public class SequenceUtilsTest {
}
@Test
- public void testIsIncomingSeqNewer() {
- assertTrue(isIncomingSeqNewer(getInitSeq() + 1, getInitSeq() + 10));
- assertFalse(isIncomingSeqNewer(getInitSeq() + 10, getInitSeq() + 1));
- assertTrue(isIncomingSeqNewer(-100, 100));
- assertFalse(isIncomingSeqNewer(100, -100));
- assertTrue(isIncomingSeqNewer(1, 2));
- assertFalse(isIncomingSeqNewer(2, 1));
+ public void testIsIncomingSeqStale() {
+ assertFalse(isIncomingSeqStale(getInitSeq() + 1, getInitSeq() + 10));
+ assertTrue(isIncomingSeqStale(getInitSeq() + 10, getInitSeq() + 1));
+ assertFalse(isIncomingSeqStale(-100, 100));
+ assertTrue(isIncomingSeqStale(100, -100));
+ assertFalse(isIncomingSeqStale(1, 2));
+ assertTrue(isIncomingSeqStale(2, 1));
// Possible incoming seq are all newer than the initial seq.
- assertTrue(isIncomingSeqNewer(getInitSeq(), getInitSeq() + 1));
- assertTrue(isIncomingSeqNewer(getInitSeq(), -100));
- assertTrue(isIncomingSeqNewer(getInitSeq(), 0));
- assertTrue(isIncomingSeqNewer(getInitSeq(), 100));
- assertTrue(isIncomingSeqNewer(getInitSeq(), Integer.MAX_VALUE));
- assertTrue(isIncomingSeqNewer(getInitSeq(), getNextSeq(Integer.MAX_VALUE)));
+ assertFalse(isIncomingSeqStale(getInitSeq(), getInitSeq()));
+ assertFalse(isIncomingSeqStale(getInitSeq(), getInitSeq() + 1));
+ assertFalse(isIncomingSeqStale(getInitSeq(), -100));
+ assertFalse(isIncomingSeqStale(getInitSeq(), 0));
+ assertFalse(isIncomingSeqStale(getInitSeq(), 100));
+ assertFalse(isIncomingSeqStale(getInitSeq(), Integer.MAX_VALUE));
+ assertFalse(isIncomingSeqStale(getInitSeq(), getNextSeq(Integer.MAX_VALUE)));
// False for the same seq.
- assertFalse(isIncomingSeqNewer(getInitSeq(), getInitSeq()));
- assertFalse(isIncomingSeqNewer(100, 100));
- assertFalse(isIncomingSeqNewer(Integer.MAX_VALUE, Integer.MAX_VALUE));
+ assertFalse(isIncomingSeqStale(100, 100));
+ assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, Integer.MAX_VALUE));
- // True when there is a large jump (overflow).
- assertTrue(isIncomingSeqNewer(Integer.MAX_VALUE, getInitSeq() + 1));
- assertTrue(isIncomingSeqNewer(Integer.MAX_VALUE, getInitSeq() + 100));
- assertTrue(isIncomingSeqNewer(Integer.MAX_VALUE, getNextSeq(Integer.MAX_VALUE)));
+ // False when there is a large jump (overflow).
+ assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getInitSeq() + 1));
+ assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getInitSeq() + 100));
+ assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getNextSeq(Integer.MAX_VALUE)));
+
+ // True when the large jump is opposite (curSeq is newer).
+ assertTrue(isIncomingSeqStale(getInitSeq() + 1, Integer.MAX_VALUE));
+ assertTrue(isIncomingSeqStale(getInitSeq() + 100, Integer.MAX_VALUE));
+ assertTrue(isIncomingSeqStale(getNextSeq(Integer.MAX_VALUE), Integer.MAX_VALUE));
}
}
diff --git a/core/tests/coretests/src/android/view/ViewFrameRateTest.java b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
index c01b51dcade8..b68ff78107ca 100644
--- a/core/tests/coretests/src/android/view/ViewFrameRateTest.java
+++ b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
@@ -29,11 +29,9 @@ import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
import static android.view.flags.Flags.toolkitFrameRateBySizeReadOnly;
import static android.view.flags.Flags.toolkitFrameRateDefaultNormalReadOnly;
import static android.view.flags.Flags.toolkitFrameRateSmallUsesPercentReadOnly;
-import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly;
import static junit.framework.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.annotation.NonNull;
@@ -100,9 +98,8 @@ public class ViewFrameRateTest {
}
@Test
- @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API,
- FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
- public void frameRateChangesWhenContentMoves() throws Throwable {
+ @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY)
+ public void highHintWhenContentMoves() throws Throwable {
if (!ViewProperties.vrr_enabled().orElse(true)) {
return;
}
@@ -110,21 +107,15 @@ public class ViewFrameRateTest {
mActivityRule.runOnUiThread(() -> {
mMovingView.offsetLeftAndRight(100);
runAfterDraw(() -> {
- if (toolkitFrameRateVelocityMappingReadOnly()) {
- float frameRate = mViewRoot.getLastPreferredFrameRate();
- assertTrue(frameRate > 0);
- } else {
- assertEquals(FRAME_RATE_CATEGORY_HIGH,
- mViewRoot.getLastPreferredFrameRateCategory());
- }
+ assertEquals(FRAME_RATE_CATEGORY_HIGH_HINT,
+ mViewRoot.getLastPreferredFrameRateCategory());
});
});
waitForAfterDraw();
}
@Test
- @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API,
- FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
+ @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY)
public void inputMethodWithContentMoves() throws Throwable {
if (!ViewProperties.vrr_enabled().orElse(true)) {
return;
@@ -136,6 +127,8 @@ public class ViewFrameRateTest {
final WindowManager.LayoutParams attrs = mViewRoot.mWindowAttributes;
attrs.type = TYPE_INPUT_METHOD;
instrumentation.runOnMainSync(() -> {
+ attrs.width = 1;
+ attrs.height = 1;
mViewRoot.setLayoutParams(attrs, false);
});
instrumentation.waitForIdleSync();
@@ -147,14 +140,13 @@ public class ViewFrameRateTest {
mActivityRule.runOnUiThread(() -> {
mMovingView.offsetLeftAndRight(100);
runAfterDraw(() -> {
- if (toolkitFrameRateVelocityMappingReadOnly()) {
- float frameRate = mViewRoot.getLastPreferredFrameRate();
- // frame rate shouldn't be boost with TYPE_INPUT_METHOD window type
- assertTrue(frameRate == 0);
- } else {
- assertEquals(FRAME_RATE_CATEGORY_HIGH,
- mViewRoot.getLastPreferredFrameRateCategory());
- }
+ int expected = toolkitFrameRateBySizeReadOnly()
+ ? FRAME_RATE_CATEGORY_LOW : FRAME_RATE_CATEGORY_NORMAL;
+ float frameRate = mViewRoot.getLastPreferredFrameRate();
+ // frame rate shouldn't be boost with TYPE_INPUT_METHOD window type
+ assertTrue(frameRate == 0);
+ assertEquals(expected,
+ mViewRoot.getLastPreferredFrameRateCategory());
});
});
waitForAfterDraw();
@@ -177,7 +169,7 @@ public class ViewFrameRateTest {
@Test
- @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
+ @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY)
public void highHintWhenActionMove() throws Throwable {
if (!ViewProperties.vrr_enabled().orElse(true)) {
return;
@@ -227,62 +219,59 @@ public class ViewFrameRateTest {
move.setSource(InputDevice.SOURCE_TOUCHSCREEN);
instrumentation.sendPointerSync(move);
- // We should continue to enable touch boost even when GTE compatibility is present.
+ // Should continue to enable touch boost.
mActivityRule.runOnUiThread(() -> {
mMovingView.offsetLeftAndRight(10);
assertTrue(mViewRoot.getIsTouchBoosting());
});
- now = SystemClock.uptimeMillis();
- MotionEvent up = MotionEvent.obtain(
- now, // downTime
- now, // eventTime
- MotionEvent.ACTION_UP, // action
- position[0], // x
- position[1], // y
- 0 // metaState
- );
- up.setSource(InputDevice.SOURCE_TOUCHSCREEN);
- instrumentation.sendPointerSync(up);
-
- // No touch boost when there is no ongoing pressed gesture.
- mActivityRule.runOnUiThread(() -> {
- mMovingView.offsetLeftAndRight(10);
- assertFalse(mViewRoot.getIsTouchBoosting());
- });
-
down.recycle();
move.recycle();
- up.recycle();
}
+ // When the size of a View is changed, we should boost the frame rate.
@Test
- @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
- public void frameBoostDisable() throws Throwable {
+ @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY)
+ public void highHintWhenSizeChanged() throws Throwable {
if (!ViewProperties.vrr_enabled().orElse(true)) {
return;
}
+ waitForFrameRateCategoryToSettle();
+ assertEquals(FRAME_RATE_CATEGORY_LOW,
+ mViewRoot.getLastPreferredFrameRateCategory());
+
+ int width = mMovingView.getWidth();
+ int height = mMovingView.getHeight();
+
+ ViewGroup.LayoutParams params = mMovingView.getLayoutParams();
+ params.width = width * 2;
+ params.height = height * 2;
+
+ // frame rate category should be HIGH_HINT when the size is changed
mActivityRule.runOnUiThread(() -> {
- long now = SystemClock.uptimeMillis();
- MotionEvent down = MotionEvent.obtain(
- /* downTime */ now,
- /* eventTime */ now,
- /* action */ MotionEvent.ACTION_DOWN,
- /* x */ 0f,
- /* y */ 0f,
- /* metaState */ 0
- );
- mActivity.dispatchTouchEvent(down);
- mMovingView.offsetLeftAndRight(10);
- });
- mActivityRule.runOnUiThread(() -> {
- mMovingView.invalidate();
+ mMovingView.setLayoutParams(params);
+ runAfterDraw(() -> {
+ assertTrue(mMovingView.getWidth() > width);
+ assertTrue(mMovingView.getHeight() > height);
+ assertEquals(FRAME_RATE_CATEGORY_HIGH_HINT,
+ mViewRoot.getLastPreferredFrameRateCategory());
+ });
});
+ waitForAfterDraw();
+ // set it back to the original size
+ params.width = width;
+ params.height = height;
mActivityRule.runOnUiThread(() -> {
- assertFalse(mViewRoot.getIsTouchBoosting());
- assertFalse(mViewRoot.getIsFrameRateBoosting());
+ mMovingView.setLayoutParams(params);
+ runAfterDraw(() -> {
+ assertEquals(width, mMovingView.getWidth());
+ assertEquals(height, mMovingView.getHeight());
+ assertEquals(FRAME_RATE_CATEGORY_HIGH_HINT,
+ mViewRoot.getLastPreferredFrameRateCategory());
+ });
});
+ waitForAfterDraw();
}
@Test
@@ -804,6 +793,12 @@ public class ViewFrameRateTest {
down.setSource(InputDevice.SOURCE_TOUCHSCREEN);
instrumentation.sendPointerSync(down);
assertEquals(FRAME_RATE_CATEGORY_HIGH_HINT, mViewRoot.getLastPreferredFrameRateCategory());
+
+ // Should still be boost with position changed
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.offsetLeftAndRight(10);
+ assertTrue(mViewRoot.getIsTouchBoosting());
+ });
}
@LargeTest
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index 9337bf67625a..c5b75ff50da7 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -16,6 +16,8 @@
package android.view;
+import static android.util.SequenceUtils.getInitSeq;
+import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING;
import static android.view.Surface.FRAME_RATE_CATEGORY_DEFAULT;
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT;
@@ -493,8 +495,8 @@ public class ViewRootImplTest {
0, displayInfo, new DisplayAdjustments());
ViewRootImpl viewRootImpl = new ViewRootImpl(sContext, display);
- boolean result = viewRootImpl.performHapticFeedback(
- HapticFeedbackConstants.CONTEXT_CLICK, true, false /* fromIme */);
+ boolean result = viewRootImpl.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK,
+ FLAG_IGNORE_GLOBAL_SETTING, 0 /* privFlags */);
assertThat(result).isFalse();
}
@@ -1555,9 +1557,9 @@ public class ViewRootImplTest {
final InsetsState state0 = new InsetsState();
final InsetsState state1 = new InsetsState();
state0.setDisplayFrame(new Rect(0, 0, 500, 1000));
- state0.setSeq(10000);
+ state0.setSeq(getInitSeq() + 10000);
state1.setDisplayFrame(new Rect(0, 0, 1500, 2000));
- state1.setSeq(10001);
+ state1.setSeq(getInitSeq() + 10001);
final InsetsSourceControl.Array array = new InsetsSourceControl.Array();
sInstrumentation.runOnMainSync(() -> {
diff --git a/core/tests/coretests/src/android/view/accessibility/a11ychecker/OWNERS b/core/tests/coretests/src/android/view/accessibility/a11ychecker/OWNERS
deleted file mode 100644
index 872a1804555b..000000000000
--- a/core/tests/coretests/src/android/view/accessibility/a11ychecker/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Android Accessibility Framework owners
-include /core/java/android/view/accessibility/a11ychecker/OWNERS
-include /services/accessibility/OWNERS
-
-yaraabdullatif@google.com
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index d4482f243939..9ae96a0fc9d8 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -348,12 +348,16 @@ public class WindowOnBackInvokedDispatcherTest {
waitForIdle();
verify(mCallback1).onBackStarted(any(BackEvent.class));
+ assertTrue(mDispatcher.mProgressAnimator.isBackAnimationInProgress());
mDispatcher.unregisterOnBackInvokedCallback(mCallback1);
waitForIdle();
verify(mCallback1).onBackCancelled();
verify(mWindowSession).setOnBackInvokedCallbackInfo(Mockito.eq(mWindow), isNull());
+ // Verify that ProgressAnimator is reset (and thus does not cause further callback event
+ // dispatching)
+ assertFalse(mDispatcher.mProgressAnimator.isBackAnimationInProgress());
}
@Test
diff --git a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
index f76398465378..5af272c8bead 100644
--- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
@@ -38,6 +38,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.SystemClock;
import android.provider.DeviceConfig;
+import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewAttachTestActivity;
@@ -67,6 +68,7 @@ public class InteractionJankMonitorTest {
private View mView;
private Handler mHandler;
private HandlerThread mWorker;
+ private SurfaceControl mSurfaceControl;
@Rule
public ActivityScenarioRule<ViewAttachTestActivity> mRule =
@@ -79,6 +81,9 @@ public class InteractionJankMonitorTest {
public void setup() {
mRule.getScenario().onActivity(activity -> mActivity = activity);
mView = mActivity.getWindow().getDecorView();
+ mSurfaceControl = mView.getViewRootImpl().getSurfaceControl();
+ // Set mNativeObject to a non-zero value to make it a valid SurfaceControl.
+ mSurfaceControl.mNativeObject = 1;
assertThat(mView.isAttachedToWindow()).isTrue();
mHandler = spy(new Handler(mActivity.getMainLooper()));
@@ -88,7 +93,7 @@ public class InteractionJankMonitorTest {
}
@Test
- public void testBeginEnd() {
+ public void testBeginEnd_inputView() {
InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
FrameTracker tracker = createMockedFrameTracker();
doReturn(tracker).when(monitor).createFrameTracker(any());
@@ -103,6 +108,22 @@ public class InteractionJankMonitorTest {
}
@Test
+ public void testBeginEnd_inputSurfaceControl() {
+ InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
+ FrameTracker tracker = createMockedFrameTracker();
+ doReturn(tracker).when(monitor).createFrameTracker(any());
+ doNothing().when(tracker).begin();
+ doReturn(true).when(tracker).end(anyInt());
+
+ // Simulate a trace session and see if begin / end are invoked.
+ assertThat(monitor.begin(mSurfaceControl, mActivity.getApplicationContext(),
+ Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
+ verify(tracker).begin();
+ assertThat(monitor.end(Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
+ verify(tracker).end(REASON_END_NORMAL);
+ }
+
+ @Test
public void testDisabledThroughDeviceConfig() {
InteractionJankMonitor monitor = new InteractionJankMonitor(mWorker);
diff --git a/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
index b90480a1e794..92a7d8ef890d 100644
--- a/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
@@ -68,6 +68,7 @@ import org.mockito.ArgumentCaptor;
import java.nio.charset.StandardCharsets;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -316,6 +317,40 @@ public class LockPatternUtilsTest {
assertNotEquals(UserHandle.USER_CURRENT_OR_SELF, LockPatternUtils.USER_REPAIR_MODE);
}
+ @Test
+ public void testWriteRepairModeCredential_mainThread() {
+ createTestLockSettings();
+ var context = InstrumentationRegistry.getTargetContext();
+
+ var future = new CompletableFuture<Exception>();
+ context.getMainThreadHandler().post(() -> {
+ try {
+ mLockPatternUtils.writeRepairModeCredential(USER_ID);
+ future.complete(null);
+ } catch (Exception e) {
+ future.complete(e);
+ }
+ });
+
+ var e = future.join();
+ assertThat(e).isNotNull();
+ assertThat(e.getMessage()).contains("should not be called from the main thread");
+ }
+
+ @Test
+ public void testWriteRepairModeCredential() throws Exception {
+ var ils = createTestLockSettings();
+
+ when(ils.writeRepairModeCredential(USER_ID)).thenReturn(false);
+ assertThat(mLockPatternUtils.writeRepairModeCredential(USER_ID)).isFalse();
+
+ when(ils.writeRepairModeCredential(USER_ID)).thenReturn(true);
+ assertThat(mLockPatternUtils.writeRepairModeCredential(USER_ID)).isTrue();
+
+ when(ils.writeRepairModeCredential(USER_ID)).thenThrow(new RemoteException());
+ assertThat(mLockPatternUtils.writeRepairModeCredential(USER_ID)).isFalse();
+ }
+
private TestStrongAuthTracker createStrongAuthTracker() {
final Context context = new ContextWrapper(InstrumentationRegistry.getTargetContext());
return new TestStrongAuthTracker(context, Looper.getMainLooper());
diff --git a/core/tests/overlaytests/handle_config_change/Android.bp b/core/tests/overlaytests/handle_config_change/Android.bp
new file mode 100644
index 000000000000..2b31d0adab17
--- /dev/null
+++ b/core/tests/overlaytests/handle_config_change/Android.bp
@@ -0,0 +1,45 @@
+// 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 {
+ // 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"],
+ default_team: "trendy_team_android_resources",
+}
+
+java_test_host {
+ name: "HandleConfigChangeHostTests",
+ srcs: ["src/**/*.java"],
+ libs: [
+ "tradefed",
+ "compatibility-host-util",
+ ],
+ static_libs: [
+ "compatibility-host-util-axt",
+ "flag-junit-host",
+ "android.content.res.flags-aconfig-java-host",
+ ],
+ test_suites: [
+ "device-tests",
+ ],
+ // All APKs required by the tests
+ data: [
+ ":OverlayResApp",
+ ],
+ per_testcase_directory: true,
+}
diff --git a/core/tests/overlaytests/handle_config_change/AndroidTest.xml b/core/tests/overlaytests/handle_config_change/AndroidTest.xml
new file mode 100644
index 000000000000..05ea03686484
--- /dev/null
+++ b/core/tests/overlaytests/handle_config_change/AndroidTest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<configuration description="Config for the handle config change test cases">
+ <option name="test-tag" value="HandleConfigChangeHostTests" />
+ <option name="test-suite-tag" value="apct" />
+
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <option name="force-skip-system-props" value="true" />
+ <option name="set-global-setting" key="verifier_engprod" value="1" />
+ <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" />
+ <option name="restore-settings" value="true" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="OverlayResApp.apk" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.HostTest">
+ <option name="class" value="com.android.overlaytest.HandleConfigChangeHostTests" />
+ </test>
+</configuration>
diff --git a/core/tests/overlaytests/handle_config_change/src/com/android/overlaytest/HandleConfigChangeHostTests.java b/core/tests/overlaytests/handle_config_change/src/com/android/overlaytest/HandleConfigChangeHostTests.java
new file mode 100644
index 000000000000..e91716ab04b3
--- /dev/null
+++ b/core/tests/overlaytests/handle_config_change/src/com/android/overlaytest/HandleConfigChangeHostTests.java
@@ -0,0 +1,47 @@
+/*
+ * 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.overlaytest;
+
+import android.content.res.Flags;
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.host.HostFlagsValueProvider;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
+public class HandleConfigChangeHostTests extends BaseHostJUnit4Test {
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ HostFlagsValueProvider.createCheckFlagsRule(this::getDevice);
+ private static final String DEVICE_TEST_PKG1 = "com.android.overlaytest.overlayresapp";
+ private static final String DEVICE_TEST_CLASS = "OverlayResTest";
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_HANDLE_ALL_CONFIG_CHANGES)
+ public void testOverlayRes() throws Exception {
+ runDeviceTests(DEVICE_TEST_PKG1, DEVICE_TEST_PKG1 + "." + DEVICE_TEST_CLASS,
+ "overlayRes_onConfigurationChanged");
+ }
+}
diff --git a/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/Android.bp b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/Android.bp
new file mode 100644
index 000000000000..e0f101229080
--- /dev/null
+++ b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/Android.bp
@@ -0,0 +1,43 @@
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "OverlayResApp",
+ srcs: ["src/**/*.java"],
+ resource_dirs: ["res"],
+ platform_apis: true,
+ certificate: "platform",
+
+ static_libs: [
+ "androidx.annotation_annotation",
+ "androidx.test.rules",
+ "androidx.test.core",
+ "compatibility-device-util-axt",
+ "truth",
+ ],
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ ],
+ test_suites: [
+ "device-tests",
+ ],
+
+ manifest: "AndroidManifest.xml",
+}
diff --git a/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/AndroidManifest.xml b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/AndroidManifest.xml
new file mode 100644
index 000000000000..617e8796317a
--- /dev/null
+++ b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.overlaytest.overlayresapp"
+ xmlns:tools="http://schemas.android.com/tools">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity
+ android:name=".OverlayResActivity"
+ android:exported="false"
+ android:configChanges="assetsPaths">
+ </activity>
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.overlaytest.overlayresapp" />
+
+</manifest>
diff --git a/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/res/values/integers.xml b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/res/values/integers.xml
new file mode 100644
index 000000000000..493333f8268b
--- /dev/null
+++ b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/res/values/integers.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<resources>
+ <integer name="test_integer">0</integer>
+</resources> \ No newline at end of file
diff --git a/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/res/values/strings.xml b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/res/values/strings.xml
new file mode 100644
index 000000000000..72820d37fdc7
--- /dev/null
+++ b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<resources>
+ <string name="app_name">My Application</string>
+ <string name="test_string">Test String</string>
+</resources> \ No newline at end of file
diff --git a/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/src/com/android/overlaytest/overlayresapp/OverlayResActivity.java b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/src/com/android/overlaytest/overlayresapp/OverlayResActivity.java
new file mode 100644
index 000000000000..96143ae4e1e1
--- /dev/null
+++ b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/src/com/android/overlaytest/overlayresapp/OverlayResActivity.java
@@ -0,0 +1,50 @@
+/*
+ * 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.overlaytest.overlayresapp;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * A test activity to verify that the assets paths configuration changes are received if the
+ * overlay targeting state is changed.
+ */
+public class OverlayResActivity extends Activity {
+ private Runnable mConfigurationChangedCallback;
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onConfigurationChanged(@NonNull Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ final Runnable callback = mConfigurationChangedCallback;
+ if (callback != null) {
+ callback.run();
+ }
+ }
+
+ /** Registers the callback of onConfigurationChanged. */
+ public void setConfigurationChangedCallback(Runnable callback) {
+ mConfigurationChangedCallback = callback;
+ }
+}
diff --git a/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/src/com/android/overlaytest/overlayresapp/OverlayResTest.java b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/src/com/android/overlaytest/overlayresapp/OverlayResTest.java
new file mode 100644
index 000000000000..1c377192f0ea
--- /dev/null
+++ b/core/tests/overlaytests/handle_config_change/test-apps/OverlayResApp/src/com/android/overlaytest/overlayresapp/OverlayResTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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.overlaytest.overlayresapp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static junit.framework.Assert.assertNotNull;
+
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.content.om.FabricatedOverlay;
+import android.content.om.OverlayInfo;
+import android.content.om.OverlayManager;
+import android.content.om.OverlayManagerTransaction;
+import android.content.res.Resources;
+import android.os.UserHandle;
+import android.util.TypedValue;
+
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(JUnit4.class)
+public class OverlayResTest {
+ // Default timeout value
+ private static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5);
+ private static final String TEST_OVERLAY_NAME = "Test";
+ private static final String TEST_RESOURCE_INTEGER = "integer/test_integer";
+ private static final String TEST_RESOURCE_STRING = "string/test_string";
+ private static final int TEST_INTEGER = 0;
+ private static final int TEST_FRRO_INTEGER = 1;
+ private static final String TEST_STRING = "Test String";
+ private static final String TEST_FRRO_STRING = "FRRO Test String";
+ private OverlayResActivity mActivity;
+ private Context mContext;
+ private OverlayManager mOverlayManager;
+ private int mUserId;
+ private UserHandle mUserHandle;
+
+ @Rule
+ public ActivityScenarioRule<OverlayResActivity> mActivityScenarioRule =
+ new ActivityScenarioRule<>(OverlayResActivity.class);
+
+ @Before
+ public void setUp() {
+ mActivityScenarioRule.getScenario().onActivity(activity -> {
+ assertThat(activity).isNotNull();
+ mActivity = activity;
+ });
+ mContext = mActivity.getApplicationContext();
+ mOverlayManager = mContext.getSystemService(OverlayManager.class);
+ mUserId = UserHandle.myUserId();
+ mUserHandle = UserHandle.of(mUserId);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ final OverlayManagerTransaction.Builder cleanUp = new OverlayManagerTransaction.Builder();
+ mOverlayManager.getOverlayInfosForTarget(mContext.getPackageName(), mUserHandle).forEach(
+ info -> {
+ if (info.isFabricated()) {
+ cleanUp.unregisterFabricatedOverlay(info.getOverlayIdentifier());
+ }
+ });
+ mOverlayManager.commit(cleanUp.build());
+
+ }
+
+ @Test
+ public void overlayRes_onConfigurationChanged() throws Exception {
+ final CountDownLatch latch1 = new CountDownLatch(1);
+ mActivity.setConfigurationChangedCallback(() -> {
+ Resources r = mActivity.getApplicationContext().getResources();
+ assertThat(r.getInteger(R.integer.test_integer)).isEqualTo(TEST_FRRO_INTEGER);
+ assertThat(r.getString(R.string.test_string)).isEqualTo(TEST_FRRO_STRING);
+ latch1.countDown();
+ });
+
+ // Create and enable FRRO
+ final FabricatedOverlay overlay = new FabricatedOverlay.Builder(
+ mContext.getPackageName(), TEST_OVERLAY_NAME, mContext.getPackageName())
+ .setResourceValue(TEST_RESOURCE_INTEGER, TypedValue.TYPE_INT_DEC, TEST_FRRO_INTEGER)
+ .setResourceValue(TEST_RESOURCE_STRING, TypedValue.TYPE_STRING, TEST_FRRO_STRING)
+ .build();
+
+ mOverlayManager.commit(new OverlayManagerTransaction.Builder()
+ .registerFabricatedOverlay(overlay)
+ .build());
+
+ OverlayInfo info = mOverlayManager.getOverlayInfo(overlay.getIdentifier(), mUserHandle);
+ assertNotNull(info);
+ assertThat(info.isEnabled()).isFalse();
+
+ mOverlayManager.commit(new OverlayManagerTransaction.Builder()
+ .setEnabled(overlay.getIdentifier(), true, mUserId)
+ .build());
+
+ info = mOverlayManager.getOverlayInfo(overlay.getIdentifier(), mUserHandle);
+ assertNotNull(info);
+ assertThat(info.isEnabled()).isTrue();
+
+ if (!latch1.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ fail("Fail to wait configuration changes for build and enabling frro, "
+ + "onConfigurationChanged() has not been invoked.");
+ }
+
+ final CountDownLatch latch2 = new CountDownLatch(1);
+ mActivity.setConfigurationChangedCallback(() -> {
+ Resources r = mActivity.getApplicationContext().getResources();
+ assertThat(r.getInteger(R.integer.test_integer)).isEqualTo(TEST_INTEGER);
+ assertThat(r.getString(R.string.test_string)).isEqualTo(TEST_STRING);
+ latch2.countDown();
+ });
+
+ // unregister FRRO
+ mOverlayManager.commit(new OverlayManagerTransaction.Builder()
+ .unregisterFabricatedOverlay(overlay.getIdentifier())
+ .build());
+
+ if (!latch2.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ fail("Fail to wait configuration changes after unregister frro,"
+ + " onConfigurationChanged() has not been invoked.");
+ }
+ }
+}
diff --git a/core/tests/resourceflaggingtests/Android.bp b/core/tests/resourceflaggingtests/Android.bp
new file mode 100644
index 000000000000..e8bb71010006
--- /dev/null
+++ b/core/tests/resourceflaggingtests/Android.bp
@@ -0,0 +1,75 @@
+// 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 {
+ // 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"],
+ default_team: "trendy_team_android_resources",
+}
+
+genrule {
+ name: "resource-flagging-test-app-resources-compile",
+ tools: ["aapt2"],
+ srcs: [
+ "flagged_resources_res/values/bools.xml",
+ ],
+ out: ["values_bools.arsc.flat"],
+ cmd: "$(location aapt2) compile $(in) -o $(genDir) " +
+ "--feature-flags test.package.falseFlag:ro=false,test.package.trueFlag:ro=true",
+}
+
+genrule {
+ name: "resource-flagging-test-app-apk",
+ tools: ["aapt2"],
+ // The first input file in the list must be the manifest
+ srcs: [
+ "TestAppAndroidManifest.xml",
+ ":resource-flagging-test-app-resources-compile",
+ ],
+ out: ["resapp.apk"],
+ cmd: "$(location aapt2) link -o $(out) --manifest $(in)",
+}
+
+java_genrule {
+ name: "resource-flagging-apk-as-resource",
+ srcs: [
+ ":resource-flagging-test-app-apk",
+ ],
+ out: ["apks_as_resources.res.zip"],
+ tools: ["soong_zip"],
+
+ cmd: "mkdir -p $(genDir)/res/raw && " +
+ "cp $(in) $(genDir)/res/raw/$$(basename $(in)) && " +
+ "$(location soong_zip) -o $(out) -C $(genDir)/res -D $(genDir)/res",
+}
+
+android_test {
+ name: "ResourceFlaggingTests",
+ srcs: [
+ "src/**/*.java",
+ ],
+ platform_apis: true,
+ certificate: "platform",
+ static_libs: [
+ "androidx.test.rules",
+ "testng",
+ "compatibility-device-util-axt",
+ ],
+ resource_zips: [":resource-flagging-apk-as-resource"],
+ test_suites: ["device-tests"],
+}
diff --git a/core/tests/resourceflaggingtests/AndroidManifest.xml b/core/tests/resourceflaggingtests/AndroidManifest.xml
new file mode 100644
index 000000000000..938463b14e64
--- /dev/null
+++ b/core/tests/resourceflaggingtests/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.resourceflaggingtests">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.resourceflaggingtests"
+ android:label="Resource Flagging Tests" />
+
+</manifest> \ No newline at end of file
diff --git a/core/tests/resourceflaggingtests/OWNERS b/core/tests/resourceflaggingtests/OWNERS
new file mode 100644
index 000000000000..10950a193b25
--- /dev/null
+++ b/core/tests/resourceflaggingtests/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/RESOURCES_OWNERS
diff --git a/core/tests/resourceflaggingtests/TestAppAndroidManifest.xml b/core/tests/resourceflaggingtests/TestAppAndroidManifest.xml
new file mode 100644
index 000000000000..d6cdeb7b5231
--- /dev/null
+++ b/core/tests/resourceflaggingtests/TestAppAndroidManifest.xml
@@ -0,0 +1,4 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.intenal.flaggedresources">
+ <application/>
+</manifest> \ No newline at end of file
diff --git a/core/tests/resourceflaggingtests/flagged_resources_res/values/bools.xml b/core/tests/resourceflaggingtests/flagged_resources_res/values/bools.xml
new file mode 100644
index 000000000000..f4defd94831c
--- /dev/null
+++ b/core/tests/resourceflaggingtests/flagged_resources_res/values/bools.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <bool name="res1">true</bool>
+ <bool name="res1" android:featureFlag="test.package.falseFlag">false</bool>
+
+ <bool name="res2">false</bool>
+ <bool name="res2" android:featureFlag="test.package.trueFlag">true</bool>
+</resources> \ No newline at end of file
diff --git a/core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java b/core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java
new file mode 100644
index 000000000000..a0cbe3cf05c3
--- /dev/null
+++ b/core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.resourceflaggingtests;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.FileUtils;
+import android.util.DisplayMetrics;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.File;
+import java.io.InputStream;
+
+@RunWith(JUnit4.class)
+@SmallTest
+public class ResourceFlaggingTest {
+ private Context mContext;
+ private Resources mResources;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getTargetContext();
+ AssetManager assets = new AssetManager();
+ assertThat(assets.addAssetPath(extractApkAndGetPath(R.raw.resapp))).isNotEqualTo(0);
+
+ final DisplayMetrics dm = new DisplayMetrics();
+ dm.setToDefaults();
+ mResources = new Resources(assets, dm, new Configuration());
+ }
+
+ @Test
+ public void testFlagDisabled() {
+ assertThat(getBoolean("res1")).isTrue();
+ }
+
+ @Test
+ public void testFlagEnabled() {
+ assertThat(getBoolean("res2")).isTrue();
+ }
+
+ private boolean getBoolean(String name) {
+ int resId = mResources.getIdentifier(name, "bool", "com.android.intenal.flaggedresources");
+ assertThat(resId).isNotEqualTo(0);
+ return mResources.getBoolean(resId);
+ }
+
+ private String extractApkAndGetPath(int id) throws Exception {
+ final Resources resources = mContext.getResources();
+ try (InputStream is = resources.openRawResource(id)) {
+ File path = new File(mContext.getFilesDir(), resources.getResourceEntryName(id));
+ path.deleteOnExit();
+ FileUtils.copyToFileOrThrow(is, path);
+ return path.getAbsolutePath();
+ }
+ }
+}
diff --git a/data/etc/OWNERS b/data/etc/OWNERS
index 701d145fe805..85dae631cac3 100644
--- a/data/etc/OWNERS
+++ b/data/etc/OWNERS
@@ -1,6 +1,5 @@
include /PACKAGE_MANAGER_OWNERS
-alanstokes@google.com
cbrubaker@google.com
hackbod@android.com
hackbod@google.com
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 4b367e0e5b4b..f9fd3694835e 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -66,6 +66,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import javax.security.auth.x500.X500Principal;
@@ -376,6 +377,8 @@ public final class KeyChain {
*/
public static final int KEY_ATTESTATION_FAILURE = 4;
+ private static final int BIND_KEY_CHAIN_SERVICE_TIMEOUT_MS = 30 * 1000;
+
/**
* Used by DPC or delegated app in
* {@link android.app.admin.DeviceAdminReceiver#onChoosePrivateKeyAlias} or
@@ -1120,7 +1123,10 @@ public final class KeyChain {
context.unbindService(keyChainServiceConnection);
throw new AssertionError("could not bind to KeyChainService");
}
- countDownLatch.await();
+ if (!countDownLatch.await(BIND_KEY_CHAIN_SERVICE_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ context.unbindService(keyChainServiceConnection);
+ throw new AssertionError("binding to KeyChainService timeout");
+ }
IKeyChainService service = keyChainService.get();
if (service != null) {
return new KeyChainConnection(context, keyChainServiceConnection, service);
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
index 822a07c23950..544f0f38f48c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
@@ -894,9 +894,7 @@ class DividerPresenter implements View.OnTouchListener {
private static boolean isDraggingToFullscreenAllowed(
@NonNull DividerAttributes dividerAttributes) {
- // TODO(b/293654166) Use DividerAttributes.isDraggingToFullscreenAllowed when extension is
- // updated to v7.
- return false;
+ return dividerAttributes.isDraggingToFullscreenAllowed();
}
/**
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index 612b38762d2d..1eb95c1efb08 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -50,6 +50,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
import java.util.Map;
import java.util.concurrent.Executor;
@@ -69,10 +70,6 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
@NonNull
private final TaskFragmentCallback mCallback;
- @VisibleForTesting
- @Nullable
- TaskFragmentAnimationController mAnimationController;
-
/**
* Callback that notifies the controller about changes to task fragments.
*/
@@ -90,25 +87,6 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
mCallback = callback;
}
- @Override
- public void unregisterOrganizer() {
- if (mAnimationController != null) {
- mAnimationController.unregisterRemoteAnimations();
- mAnimationController = null;
- }
- super.unregisterOrganizer();
- }
-
- /**
- * Overrides the animation for transitions of embedded activities organized by this organizer.
- */
- void overrideSplitAnimation() {
- if (mAnimationController == null) {
- mAnimationController = new TaskFragmentAnimationController(this);
- }
- mAnimationController.registerRemoteAnimations();
- }
-
/**
* Starts a new Activity and puts it into split with an existing Activity side-by-side.
* @param launchingFragmentToken token for the launching TaskFragment. If it exists, it will
@@ -393,19 +371,31 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
if (splitAttributes == null) {
return TaskFragmentAnimationParams.DEFAULT;
}
+ final TaskFragmentAnimationParams.Builder builder =
+ new TaskFragmentAnimationParams.Builder();
final int animationBackgroundColor = getAnimationBackgroundColor(splitAttributes);
- TaskFragmentAnimationParams.Builder builder = new TaskFragmentAnimationParams.Builder();
- if (animationBackgroundColor != DEFAULT_ANIMATION_BACKGROUND_COLOR) {
- builder.setAnimationBackgroundColor(animationBackgroundColor);
+ builder.setAnimationBackgroundColor(animationBackgroundColor);
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ final int openAnimationResId =
+ splitAttributes.getAnimationParams().getOpenAnimationResId();
+ builder.setOpenAnimationResId(openAnimationResId);
+ final int closeAnimationResId =
+ splitAttributes.getAnimationParams().getCloseAnimationResId();
+ builder.setCloseAnimationResId(closeAnimationResId);
+ final int changeAnimationResId =
+ splitAttributes.getAnimationParams().getChangeAnimationResId();
+ builder.setChangeAnimationResId(changeAnimationResId);
}
- // TODO(b/293658614): Allow setting custom open/close/changeAnimationResId.
return builder.build();
}
@ColorInt
private static int getAnimationBackgroundColor(@NonNull SplitAttributes splitAttributes) {
int animationBackgroundColor = DEFAULT_ANIMATION_BACKGROUND_COLOR;
- final AnimationBackground animationBackground = splitAttributes.getAnimationBackground();
+ AnimationBackground animationBackground = splitAttributes.getAnimationBackground();
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ animationBackground = splitAttributes.getAnimationParams().getAnimationBackground();
+ }
if (animationBackground instanceof AnimationBackground.ColorBackground colorBackground) {
animationBackgroundColor = colorBackground.getColor();
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 7ddda1f98809..8e1fde066277 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.window.ActivityWindowInfo.getActivityWindowInfo;
import static android.window.TaskFragmentOperation.OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_OP_TYPE;
@@ -80,6 +81,7 @@ import android.window.ActivityWindowInfo;
import android.window.TaskFragmentAnimationParams;
import android.window.TaskFragmentInfo;
import android.window.TaskFragmentOperation;
+import android.window.TaskFragmentOrganizer;
import android.window.TaskFragmentParentInfo;
import android.window.TaskFragmentTransaction;
import android.window.WindowContainerTransaction;
@@ -114,7 +116,6 @@ import java.util.function.BiConsumer;
public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmentCallback,
ActivityEmbeddingComponent, DividerPresenter.DragEventCallback {
static final String TAG = "SplitController";
- static final boolean ENABLE_SHELL_TRANSITIONS = true;
// TODO(b/243518738): Move to WM Extensions if we have requirement of overlay without
// association. It's not set in WM Extensions nor Wm Jetpack library currently.
@@ -205,11 +206,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
/** Listener registered to {@link ClientTransactionListenerController}. */
@GuardedBy("mLock")
- @Nullable
+ @NonNull
private final BiConsumer<IBinder, ActivityWindowInfo> mActivityWindowInfoListener =
- Flags.activityWindowInfoFlag()
- ? this::onActivityWindowInfoChanged
- : null;
+ this::onActivityWindowInfoChanged;
private final Handler mHandler;
private final MainThreadExecutor mExecutor;
@@ -2556,9 +2555,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return ActivityThread.currentActivityThread().getActivity(activityToken);
}
- @VisibleForTesting
@Nullable
- ActivityThread.ActivityClientRecord getActivityClientRecord(@NonNull Activity activity) {
+ private ActivityThread.ActivityClientRecord getActivityClientRecord(
+ @NonNull Activity activity) {
return ActivityThread.currentActivityThread()
.getActivityClient(activity.getActivityToken());
}
@@ -3095,22 +3094,14 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
*/
@Override
public boolean isActivityEmbedded(@NonNull Activity activity) {
- Objects.requireNonNull(activity);
synchronized (mLock) {
- if (Flags.activityWindowInfoFlag()) {
- final ActivityWindowInfo activityWindowInfo = getActivityWindowInfo(activity);
- return activityWindowInfo != null && activityWindowInfo.isEmbedded();
- }
- return mPresenter.isActivityEmbedded(activity.getActivityToken());
+ return TaskFragmentOrganizer.isActivityEmbedded(activity);
}
}
@Override
public void setEmbeddedActivityWindowInfoCallback(@NonNull Executor executor,
@NonNull Consumer<EmbeddedActivityWindowInfo> callback) {
- if (!Flags.activityWindowInfoFlag()) {
- return;
- }
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
synchronized (mLock) {
@@ -3124,9 +3115,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@Override
public void clearEmbeddedActivityWindowInfoCallback() {
- if (!Flags.activityWindowInfoFlag()) {
- return;
- }
synchronized (mLock) {
if (mEmbeddedActivityWindowInfoCallback == null) {
return;
@@ -3147,9 +3135,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@Nullable
@Override
public EmbeddedActivityWindowInfo getEmbeddedActivityWindowInfo(@NonNull Activity activity) {
- if (!Flags.activityWindowInfoFlag()) {
- return null;
- }
synchronized (mLock) {
final ActivityWindowInfo activityWindowInfo = getActivityWindowInfo(activity);
return activityWindowInfo != null
@@ -3180,15 +3165,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
}
- @Nullable
- private ActivityWindowInfo getActivityWindowInfo(@NonNull Activity activity) {
- if (activity.isFinishing()) {
- return null;
- }
- final ActivityThread.ActivityClientRecord record = getActivityClientRecord(activity);
- return record != null ? record.getActivityWindowInfo() : null;
- }
-
@NonNull
private static EmbeddedActivityWindowInfo translateActivityWindowInfo(
@NonNull Activity activity, @NonNull ActivityWindowInfo activityWindowInfo) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index eb1fc23d6b00..ea60b1531a3f 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -166,11 +166,6 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
mWindowLayoutComponent = windowLayoutComponent;
mController = controller;
registerOrganizer();
- if (!SplitController.ENABLE_SHELL_TRANSITIONS) {
- // TODO(b/207070762): cleanup with legacy app transition
- // Animation will be handled by WM Shell when Shell transition is enabled.
- overrideSplitAnimation();
- }
}
/**
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationAdapter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationAdapter.java
deleted file mode 100644
index 33220c44a3b5..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationAdapter.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.extensions.embedding;
-
-import static android.graphics.Matrix.MTRANS_X;
-import static android.graphics.Matrix.MTRANS_Y;
-import static android.view.RemoteAnimationTarget.MODE_CLOSING;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.view.Choreographer;
-import android.view.RemoteAnimationTarget;
-import android.view.SurfaceControl;
-import android.view.animation.Animation;
-import android.view.animation.Transformation;
-
-import androidx.annotation.NonNull;
-
-/**
- * Wrapper to handle the TaskFragment animation update in one {@link SurfaceControl.Transaction}.
- *
- * The base adapter can be used for {@link RemoteAnimationTarget} that is simple open/close.
- */
-class TaskFragmentAnimationAdapter {
-
- /**
- * If {@link #mOverrideLayer} is set to this value, we don't want to override the surface layer.
- */
- private static final int LAYER_NO_OVERRIDE = -1;
-
- @NonNull
- final Animation mAnimation;
- @NonNull
- final RemoteAnimationTarget mTarget;
- @NonNull
- final SurfaceControl mLeash;
- /** Area in absolute coordinate that the animation surface shouldn't go beyond. */
- @NonNull
- private final Rect mWholeAnimationBounds = new Rect();
- /**
- * Area in absolute coordinate that should represent all the content to show for this window.
- * This should be the end bounds for opening window, and start bounds for closing window in case
- * the window is resizing during the open/close transition.
- */
- @NonNull
- private final Rect mContentBounds = new Rect();
- /** Offset relative to the window parent surface for {@link #mContentBounds}. */
- @NonNull
- private final Point mContentRelOffset = new Point();
-
- @NonNull
- final Transformation mTransformation = new Transformation();
- @NonNull
- final float[] mMatrix = new float[9];
- @NonNull
- final float[] mVecs = new float[4];
- @NonNull
- final Rect mRect = new Rect();
- private boolean mIsFirstFrame = true;
- private int mOverrideLayer = LAYER_NO_OVERRIDE;
-
- TaskFragmentAnimationAdapter(@NonNull Animation animation,
- @NonNull RemoteAnimationTarget target) {
- this(animation, target, target.leash, target.screenSpaceBounds);
- }
-
- /**
- * @param leash the surface to animate.
- * @param wholeAnimationBounds area in absolute coordinate that the animation surface shouldn't
- * go beyond.
- */
- TaskFragmentAnimationAdapter(@NonNull Animation animation,
- @NonNull RemoteAnimationTarget target, @NonNull SurfaceControl leash,
- @NonNull Rect wholeAnimationBounds) {
- mAnimation = animation;
- mTarget = target;
- mLeash = leash;
- mWholeAnimationBounds.set(wholeAnimationBounds);
- if (target.mode == MODE_CLOSING) {
- // When it is closing, we want to show the content at the start position in case the
- // window is resizing as well. For example, when the activities is changing from split
- // to stack, the bottom TaskFragment will be resized to fullscreen when hiding.
- final Rect startBounds = target.startBounds;
- final Rect endBounds = target.screenSpaceBounds;
- mContentBounds.set(startBounds);
- mContentRelOffset.set(target.localBounds.left, target.localBounds.top);
- mContentRelOffset.offset(
- startBounds.left - endBounds.left,
- startBounds.top - endBounds.top);
- } else {
- mContentBounds.set(target.screenSpaceBounds);
- mContentRelOffset.set(target.localBounds.left, target.localBounds.top);
- }
- }
-
- /**
- * Surface layer to be set at the first frame of the animation. We will not set the layer if it
- * is set to {@link #LAYER_NO_OVERRIDE}.
- */
- final void overrideLayer(int layer) {
- mOverrideLayer = layer;
- }
-
- /** Called on frame update. */
- final void onAnimationUpdate(@NonNull SurfaceControl.Transaction t, long currentPlayTime) {
- if (mIsFirstFrame) {
- t.show(mLeash);
- if (mOverrideLayer != LAYER_NO_OVERRIDE) {
- t.setLayer(mLeash, mOverrideLayer);
- }
- mIsFirstFrame = false;
- }
-
- // Extract the transformation to the current time.
- mAnimation.getTransformation(Math.min(currentPlayTime, mAnimation.getDuration()),
- mTransformation);
- t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
- onAnimationUpdateInner(t);
- }
-
- /** To be overridden by subclasses to adjust the animation surface change. */
- void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) {
- // Update the surface position and alpha.
- mTransformation.getMatrix().postTranslate(mContentRelOffset.x, mContentRelOffset.y);
- t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix);
- t.setAlpha(mLeash, mTransformation.getAlpha());
-
- // Get current surface bounds in absolute coordinate.
- // positionX/Y are in local coordinate, so minus the local offset to get the slide amount.
- final int positionX = Math.round(mMatrix[MTRANS_X]);
- final int positionY = Math.round(mMatrix[MTRANS_Y]);
- final Rect cropRect = new Rect(mContentBounds);
- cropRect.offset(positionX - mContentRelOffset.x, positionY - mContentRelOffset.y);
-
- // Store the current offset of the surface top left from (0,0) in absolute coordinate.
- final int offsetX = cropRect.left;
- final int offsetY = cropRect.top;
-
- // Intersect to make sure the animation happens within the whole animation bounds.
- if (!cropRect.intersect(mWholeAnimationBounds)) {
- // Hide the surface when it is outside of the animation area.
- t.setAlpha(mLeash, 0);
- }
-
- // cropRect is in absolute coordinate, so we need to translate it to surface top left.
- cropRect.offset(-offsetX, -offsetY);
- t.setCrop(mLeash, cropRect);
- }
-
- /** Called after animation finished. */
- final void onAnimationEnd(@NonNull SurfaceControl.Transaction t) {
- onAnimationUpdate(t, mAnimation.getDuration());
- }
-
- final long getDurationHint() {
- return mAnimation.computeDurationHint();
- }
-
- /**
- * Should be used for the animation of the snapshot of a {@link RemoteAnimationTarget} that has
- * size change.
- */
- static class SnapshotAdapter extends TaskFragmentAnimationAdapter {
-
- SnapshotAdapter(@NonNull Animation animation, @NonNull RemoteAnimationTarget target) {
- // Start leash is the snapshot of the starting surface.
- super(animation, target, target.startLeash, target.screenSpaceBounds);
- }
-
- @Override
- void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) {
- // Snapshot should always be placed at the top left of the animation leash.
- mTransformation.getMatrix().postTranslate(0, 0);
- t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix);
- t.setAlpha(mLeash, mTransformation.getAlpha());
- }
- }
-
- /**
- * Should be used for the animation of the {@link RemoteAnimationTarget} that has size change.
- */
- static class BoundsChangeAdapter extends TaskFragmentAnimationAdapter {
-
- BoundsChangeAdapter(@NonNull Animation animation, @NonNull RemoteAnimationTarget target) {
- super(animation, target);
- }
-
- @Override
- void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) {
- mTransformation.getMatrix().postTranslate(
- mTarget.localBounds.left, mTarget.localBounds.top);
- t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix);
- t.setAlpha(mLeash, mTransformation.getAlpha());
-
- // The following applies an inverse scale to the clip-rect so that it crops "after" the
- // scale instead of before.
- mVecs[1] = mVecs[2] = 0;
- mVecs[0] = mVecs[3] = 1;
- mTransformation.getMatrix().mapVectors(mVecs);
- mVecs[0] = 1.f / mVecs[0];
- mVecs[3] = 1.f / mVecs[3];
- final Rect clipRect = mTransformation.getClipRect();
- mRect.left = (int) (clipRect.left * mVecs[0] + 0.5f);
- mRect.right = (int) (clipRect.right * mVecs[0] + 0.5f);
- mRect.top = (int) (clipRect.top * mVecs[3] + 0.5f);
- mRect.bottom = (int) (clipRect.bottom * mVecs[3] + 0.5f);
- t.setWindowCrop(mLeash, mRect);
- }
- }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java
deleted file mode 100644
index d7eb9a01f57c..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.extensions.embedding;
-
-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_TASK_FRAGMENT_CHANGE;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
-
-import android.util.Log;
-import android.view.RemoteAnimationAdapter;
-import android.view.RemoteAnimationDefinition;
-import android.window.TaskFragmentOrganizer;
-
-import androidx.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/** Controls the TaskFragment remote animations. */
-class TaskFragmentAnimationController {
-
- private static final String TAG = "TaskFragAnimationCtrl";
- static final boolean DEBUG = false;
-
- private final TaskFragmentOrganizer mOrganizer;
- private final TaskFragmentAnimationRunner mRemoteRunner = new TaskFragmentAnimationRunner();
- @VisibleForTesting
- final RemoteAnimationDefinition mDefinition;
- private boolean mIsRegistered;
-
- TaskFragmentAnimationController(@NonNull TaskFragmentOrganizer organizer) {
- mOrganizer = organizer;
- mDefinition = new RemoteAnimationDefinition();
- final RemoteAnimationAdapter animationAdapter =
- new RemoteAnimationAdapter(mRemoteRunner, 0, 0, true /* changeNeedsSnapshot */);
- mDefinition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, animationAdapter);
- mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, animationAdapter);
- mDefinition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_CLOSE, animationAdapter);
- mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, animationAdapter);
- mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, animationAdapter);
- }
-
- void registerRemoteAnimations() {
- if (DEBUG) {
- Log.v(TAG, "registerRemoteAnimations");
- }
- if (mIsRegistered) {
- return;
- }
- mOrganizer.registerRemoteAnimations(mDefinition);
- mIsRegistered = true;
- }
-
- void unregisterRemoteAnimations() {
- if (DEBUG) {
- Log.v(TAG, "unregisterRemoteAnimations");
- }
- if (!mIsRegistered) {
- return;
- }
- mOrganizer.unregisterRemoteAnimations();
- mIsRegistered = false;
- }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
deleted file mode 100644
index d9b73a8290f5..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.extensions.embedding;
-
-import static android.os.Process.THREAD_PRIORITY_DISPLAY;
-import static android.view.RemoteAnimationTarget.MODE_CHANGING;
-import static android.view.RemoteAnimationTarget.MODE_CLOSING;
-import static android.view.RemoteAnimationTarget.MODE_OPENING;
-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_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.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET;
-
-import android.animation.Animator;
-import android.animation.ValueAnimator;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.IRemoteAnimationFinishedCallback;
-import android.view.IRemoteAnimationRunner;
-import android.view.RemoteAnimationTarget;
-import android.view.SurfaceControl;
-import android.view.WindowManager;
-import android.view.animation.Animation;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.BiFunction;
-
-/** To run the TaskFragment animations. */
-class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
-
- private static final String TAG = "TaskFragAnimationRunner";
- private final Handler mHandler;
- private final TaskFragmentAnimationSpec mAnimationSpec;
-
- TaskFragmentAnimationRunner() {
- HandlerThread animationThread = new HandlerThread(
- "androidx.window.extensions.embedding", THREAD_PRIORITY_DISPLAY);
- animationThread.start();
- mHandler = animationThread.getThreadHandler();
- mAnimationSpec = new TaskFragmentAnimationSpec(mHandler);
- }
-
- @Nullable
- private Animator mAnimator;
-
- @Override
- public void onAnimationStart(@WindowManager.TransitionOldType int transit,
- @NonNull RemoteAnimationTarget[] apps,
- @NonNull RemoteAnimationTarget[] wallpapers,
- @NonNull RemoteAnimationTarget[] nonApps,
- @NonNull IRemoteAnimationFinishedCallback finishedCallback) {
- if (wallpapers.length != 0 || nonApps.length != 0) {
- throw new IllegalArgumentException("TaskFragment shouldn't handle animation with"
- + "wallpaper or non-app windows.");
- }
- if (TaskFragmentAnimationController.DEBUG) {
- Log.v(TAG, "onAnimationStart transit=" + transit);
- }
- mHandler.post(() -> startAnimation(transit, apps, finishedCallback));
- }
-
- @Override
- public void onAnimationCancelled() {
- mHandler.post(this::cancelAnimation);
- }
-
- /** Creates and starts animation. */
- private void startAnimation(@WindowManager.TransitionOldType int transit,
- @NonNull RemoteAnimationTarget[] targets,
- @NonNull IRemoteAnimationFinishedCallback finishedCallback) {
- if (mAnimator != null) {
- Log.w(TAG, "start new animation when the previous one is not finished yet.");
- mAnimator.cancel();
- }
- mAnimator = createAnimator(transit, targets, finishedCallback);
- mAnimator.start();
- }
-
- /** Cancels animation. */
- private void cancelAnimation() {
- if (mAnimator == null) {
- return;
- }
- mAnimator.cancel();
- mAnimator = null;
- }
-
- /** Creates the animator given the transition type and windows. */
- @NonNull
- private Animator createAnimator(@WindowManager.TransitionOldType int transit,
- @NonNull RemoteAnimationTarget[] targets,
- @NonNull IRemoteAnimationFinishedCallback finishedCallback) {
- final List<TaskFragmentAnimationAdapter> adapters =
- createAnimationAdapters(transit, targets);
- long duration = 0;
- for (TaskFragmentAnimationAdapter adapter : adapters) {
- duration = Math.max(duration, adapter.getDurationHint());
- }
- final ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
- animator.setDuration(duration);
- animator.addUpdateListener((anim) -> {
- // Update all adapters in the same transaction.
- final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
- for (TaskFragmentAnimationAdapter adapter : adapters) {
- adapter.onAnimationUpdate(t, animator.getCurrentPlayTime());
- }
- t.apply();
- });
- animator.addListener(new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {}
-
- @Override
- public void onAnimationEnd(Animator animation) {
- final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
- for (TaskFragmentAnimationAdapter adapter : adapters) {
- adapter.onAnimationEnd(t);
- }
- t.apply();
-
- try {
- finishedCallback.onAnimationFinished();
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- mAnimator = null;
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {}
-
- @Override
- public void onAnimationRepeat(Animator animation) {}
- });
- return animator;
- }
-
- /** List of {@link TaskFragmentAnimationAdapter} to handle animations on all window targets. */
- @NonNull
- private List<TaskFragmentAnimationAdapter> createAnimationAdapters(
- @WindowManager.TransitionOldType int transit,
- @NonNull RemoteAnimationTarget[] targets) {
- switch (transit) {
- case TRANSIT_OLD_ACTIVITY_OPEN:
- case TRANSIT_OLD_TASK_FRAGMENT_OPEN:
- return createOpenAnimationAdapters(targets);
- case TRANSIT_OLD_ACTIVITY_CLOSE:
- case TRANSIT_OLD_TASK_FRAGMENT_CLOSE:
- return createCloseAnimationAdapters(targets);
- case TRANSIT_OLD_TASK_FRAGMENT_CHANGE:
- return createChangeAnimationAdapters(targets);
- default:
- throw new IllegalArgumentException("Unhandled transit type=" + transit);
- }
- }
-
- @NonNull
- private List<TaskFragmentAnimationAdapter> createOpenAnimationAdapters(
- @NonNull RemoteAnimationTarget[] targets) {
- return createOpenCloseAnimationAdapters(targets, true /* isOpening */,
- mAnimationSpec::loadOpenAnimation);
- }
-
- @NonNull
- private List<TaskFragmentAnimationAdapter> createCloseAnimationAdapters(
- @NonNull RemoteAnimationTarget[] targets) {
- return createOpenCloseAnimationAdapters(targets, false /* isOpening */,
- mAnimationSpec::loadCloseAnimation);
- }
-
- /**
- * Creates {@link TaskFragmentAnimationAdapter} for OPEN and CLOSE types of transition.
- * @param isOpening {@code true} for OPEN type, {@code false} for CLOSE type.
- */
- @NonNull
- private List<TaskFragmentAnimationAdapter> createOpenCloseAnimationAdapters(
- @NonNull RemoteAnimationTarget[] targets, boolean isOpening,
- @NonNull BiFunction<RemoteAnimationTarget, Rect, Animation> animationProvider) {
- // We need to know if the target window is only a partial of the whole animation screen.
- // If so, we will need to adjust it to make the whole animation screen looks like one.
- final List<RemoteAnimationTarget> openingTargets = new ArrayList<>();
- final List<RemoteAnimationTarget> closingTargets = new ArrayList<>();
- final Rect openingWholeScreenBounds = new Rect();
- final Rect closingWholeScreenBounds = new Rect();
- for (RemoteAnimationTarget target : targets) {
- if (target.mode != MODE_CLOSING) {
- openingTargets.add(target);
- openingWholeScreenBounds.union(target.screenSpaceBounds);
- } else {
- closingTargets.add(target);
- closingWholeScreenBounds.union(target.screenSpaceBounds);
- // Union the start bounds since this may be the ClosingChanging animation.
- closingWholeScreenBounds.union(target.startBounds);
- }
- }
-
- // For OPEN transition, open windows should be above close windows.
- // For CLOSE transition, open windows should be below close windows.
- int offsetLayer = TYPE_LAYER_OFFSET;
- final List<TaskFragmentAnimationAdapter> adapters = new ArrayList<>();
- for (RemoteAnimationTarget target : openingTargets) {
- final TaskFragmentAnimationAdapter adapter = createOpenCloseAnimationAdapter(target,
- animationProvider, openingWholeScreenBounds);
- if (isOpening) {
- adapter.overrideLayer(offsetLayer++);
- }
- adapters.add(adapter);
- }
- for (RemoteAnimationTarget target : closingTargets) {
- final TaskFragmentAnimationAdapter adapter = createOpenCloseAnimationAdapter(target,
- animationProvider, closingWholeScreenBounds);
- if (!isOpening) {
- adapter.overrideLayer(offsetLayer++);
- }
- adapters.add(adapter);
- }
- return adapters;
- }
-
- @NonNull
- private TaskFragmentAnimationAdapter createOpenCloseAnimationAdapter(
- @NonNull RemoteAnimationTarget target,
- @NonNull BiFunction<RemoteAnimationTarget, Rect, Animation> animationProvider,
- @NonNull Rect wholeAnimationBounds) {
- final Animation animation = animationProvider.apply(target, wholeAnimationBounds);
- return new TaskFragmentAnimationAdapter(animation, target, target.leash,
- wholeAnimationBounds);
- }
-
- @NonNull
- private List<TaskFragmentAnimationAdapter> createChangeAnimationAdapters(
- @NonNull RemoteAnimationTarget[] targets) {
- if (shouldUseJumpCutForChangeAnimation(targets)) {
- return new ArrayList<>();
- }
-
- final List<TaskFragmentAnimationAdapter> adapters = new ArrayList<>();
- for (RemoteAnimationTarget target : targets) {
- if (target.mode == MODE_CHANGING) {
- // This is the target with bounds change.
- final Animation[] animations =
- mAnimationSpec.createChangeBoundsChangeAnimations(target);
- // Adapter for the starting snapshot leash.
- adapters.add(new TaskFragmentAnimationAdapter.SnapshotAdapter(
- animations[0], target));
- // Adapter for the ending bounds changed leash.
- adapters.add(new TaskFragmentAnimationAdapter.BoundsChangeAdapter(
- animations[1], target));
- continue;
- }
-
- // These are the other targets that don't have bounds change in the same transition.
- final Animation animation;
- if (target.hasAnimatingParent) {
- // No-op if it will be covered by the changing parent window.
- animation = TaskFragmentAnimationSpec.createNoopAnimation(target);
- } else if (target.mode == MODE_CLOSING) {
- animation = mAnimationSpec.createChangeBoundsCloseAnimation(target);
- } else {
- animation = mAnimationSpec.createChangeBoundsOpenAnimation(target);
- }
- adapters.add(new TaskFragmentAnimationAdapter(animation, target));
- }
- return adapters;
- }
-
- /**
- * Whether we should use jump cut for the change transition.
- * This normally happens when opening a new secondary with the existing primary using a
- * different split layout. This can be complicated, like from horizontal to vertical split with
- * new split pairs.
- * Uses a jump cut animation to simplify.
- */
- private boolean shouldUseJumpCutForChangeAnimation(@NonNull RemoteAnimationTarget[] targets) {
- boolean hasOpeningWindow = false;
- boolean hasClosingWindow = false;
- for (RemoteAnimationTarget target : targets) {
- if (target.hasAnimatingParent) {
- continue;
- }
- hasOpeningWindow |= target.mode == MODE_OPENING;
- hasClosingWindow |= target.mode == MODE_CLOSING;
- }
- return hasOpeningWindow && hasClosingWindow;
- }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java
deleted file mode 100644
index 1f866c3b99c9..000000000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.extensions.embedding;
-
-import static android.view.RemoteAnimationTarget.MODE_CLOSING;
-
-import android.app.ActivityThread;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.provider.Settings;
-import android.view.RemoteAnimationTarget;
-import android.view.WindowManager;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.AnimationUtils;
-import android.view.animation.ClipRectAnimation;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-import android.view.animation.ScaleAnimation;
-import android.view.animation.TranslateAnimation;
-
-import androidx.annotation.NonNull;
-
-import com.android.internal.R;
-import com.android.internal.policy.AttributeCache;
-import com.android.internal.policy.TransitionAnimation;
-
-/** Animation spec for TaskFragment transition. */
-// TODO(b/206557124): provide an easier way to customize animation
-class TaskFragmentAnimationSpec {
-
- private static final String TAG = "TaskFragAnimationSpec";
- private static final int CHANGE_ANIMATION_DURATION = 517;
- private static final int CHANGE_ANIMATION_FADE_DURATION = 80;
- private static final int CHANGE_ANIMATION_FADE_OFFSET = 30;
-
- private final Context mContext;
- private final TransitionAnimation mTransitionAnimation;
- private final Interpolator mFastOutExtraSlowInInterpolator;
- private final LinearInterpolator mLinearInterpolator;
- private float mTransitionAnimationScaleSetting;
-
- TaskFragmentAnimationSpec(@NonNull Handler handler) {
- mContext = ActivityThread.currentActivityThread().getApplication();
- mTransitionAnimation = new TransitionAnimation(mContext, false /* debug */, TAG);
- // Initialize the AttributeCache for the TransitionAnimation.
- AttributeCache.init(mContext);
- mFastOutExtraSlowInInterpolator = AnimationUtils.loadInterpolator(
- mContext, android.R.interpolator.fast_out_extra_slow_in);
- mLinearInterpolator = new LinearInterpolator();
-
- // The transition animation should be adjusted based on the developer option.
- final ContentResolver resolver = mContext.getContentResolver();
- mTransitionAnimationScaleSetting = getTransitionAnimationScaleSetting();
- resolver.registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE), false,
- new SettingsObserver(handler));
- }
-
- /** For target that doesn't need to be animated. */
- @NonNull
- static Animation createNoopAnimation(@NonNull RemoteAnimationTarget target) {
- // Noop but just keep the target showing/hiding.
- final float alpha = target.mode == MODE_CLOSING ? 0f : 1f;
- return new AlphaAnimation(alpha, alpha);
- }
-
- /** Animation for target that is opening in a change transition. */
- @NonNull
- Animation createChangeBoundsOpenAnimation(@NonNull RemoteAnimationTarget target) {
- final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds();
- final Rect bounds = target.screenSpaceBounds;
- final int startLeft;
- final int startTop;
- if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) {
- // The window will be animated in from left or right depending on its position.
- startTop = 0;
- startLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width();
- } else {
- // The window will be animated in from top or bottom depending on its position.
- startTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height();
- startLeft = 0;
- }
-
- // The position should be 0-based as we will post translate in
- // TaskFragmentAnimationAdapter#onAnimationUpdate
- final Animation animation = new TranslateAnimation(startLeft, 0, startTop, 0);
- animation.setInterpolator(mFastOutExtraSlowInInterpolator);
- animation.setDuration(CHANGE_ANIMATION_DURATION);
- animation.initialize(bounds.width(), bounds.height(), bounds.width(), bounds.height());
- animation.scaleCurrentDuration(mTransitionAnimationScaleSetting);
- return animation;
- }
-
- /** Animation for target that is closing in a change transition. */
- @NonNull
- Animation createChangeBoundsCloseAnimation(@NonNull RemoteAnimationTarget target) {
- final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds();
- // Use startBounds if the window is closing in case it may also resize.
- final Rect bounds = target.startBounds;
- final int endTop;
- final int endLeft;
- if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) {
- // The window will be animated out to left or right depending on its position.
- endTop = 0;
- endLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width();
- } else {
- // The window will be animated out to top or bottom depending on its position.
- endTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height();
- endLeft = 0;
- }
-
- // The position should be 0-based as we will post translate in
- // TaskFragmentAnimationAdapter#onAnimationUpdate
- final Animation animation = new TranslateAnimation(0, endLeft, 0, endTop);
- animation.setInterpolator(mFastOutExtraSlowInInterpolator);
- animation.setDuration(CHANGE_ANIMATION_DURATION);
- animation.initialize(bounds.width(), bounds.height(), bounds.width(), bounds.height());
- animation.scaleCurrentDuration(mTransitionAnimationScaleSetting);
- return animation;
- }
-
- /**
- * Animation for target that is changing (bounds change) in a change transition.
- * @return the return array always has two elements. The first one is for the start leash, and
- * the second one is for the end leash.
- */
- @NonNull
- Animation[] createChangeBoundsChangeAnimations(@NonNull RemoteAnimationTarget target) {
- // Both start bounds and end bounds are in screen coordinates. We will post translate
- // to the local coordinates in TaskFragmentAnimationAdapter#onAnimationUpdate
- final Rect startBounds = target.startBounds;
- final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds();
- final Rect endBounds = target.screenSpaceBounds;
- float scaleX = ((float) startBounds.width()) / endBounds.width();
- float scaleY = ((float) startBounds.height()) / endBounds.height();
- // Start leash is a child of the end leash. Reverse the scale so that the start leash won't
- // be scaled up with its parent.
- float startScaleX = 1.f / scaleX;
- float startScaleY = 1.f / scaleY;
-
- // The start leash will be fade out.
- final AnimationSet startSet = new AnimationSet(false /* shareInterpolator */);
- final Animation startAlpha = new AlphaAnimation(1f, 0f);
- startAlpha.setInterpolator(mLinearInterpolator);
- startAlpha.setDuration(CHANGE_ANIMATION_FADE_DURATION);
- startAlpha.setStartOffset(CHANGE_ANIMATION_FADE_OFFSET);
- startSet.addAnimation(startAlpha);
- final Animation startScale = new ScaleAnimation(startScaleX, startScaleX, startScaleY,
- startScaleY);
- startScale.setInterpolator(mFastOutExtraSlowInInterpolator);
- startScale.setDuration(CHANGE_ANIMATION_DURATION);
- startSet.addAnimation(startScale);
- startSet.initialize(startBounds.width(), startBounds.height(), endBounds.width(),
- endBounds.height());
- startSet.scaleCurrentDuration(mTransitionAnimationScaleSetting);
-
- // The end leash will be moved into the end position while scaling.
- final AnimationSet endSet = new AnimationSet(true /* shareInterpolator */);
- endSet.setInterpolator(mFastOutExtraSlowInInterpolator);
- final Animation endScale = new ScaleAnimation(scaleX, 1, scaleY, 1);
- endScale.setDuration(CHANGE_ANIMATION_DURATION);
- endSet.addAnimation(endScale);
- // The position should be 0-based as we will post translate in
- // TaskFragmentAnimationAdapter#onAnimationUpdate
- final Animation endTranslate = new TranslateAnimation(startBounds.left - endBounds.left, 0,
- startBounds.top - endBounds.top, 0);
- endTranslate.setDuration(CHANGE_ANIMATION_DURATION);
- endSet.addAnimation(endTranslate);
- // The end leash is resizing, we should update the window crop based on the clip rect.
- final Rect startClip = new Rect(startBounds);
- final Rect endClip = new Rect(endBounds);
- startClip.offsetTo(0, 0);
- endClip.offsetTo(0, 0);
- final Animation clipAnim = new ClipRectAnimation(startClip, endClip);
- clipAnim.setDuration(CHANGE_ANIMATION_DURATION);
- endSet.addAnimation(clipAnim);
- endSet.initialize(startBounds.width(), startBounds.height(), parentBounds.width(),
- parentBounds.height());
- endSet.scaleCurrentDuration(mTransitionAnimationScaleSetting);
-
- return new Animation[]{startSet, endSet};
- }
-
- @NonNull
- Animation loadOpenAnimation(@NonNull RemoteAnimationTarget target,
- @NonNull Rect wholeAnimationBounds) {
- final boolean isEnter = target.mode != MODE_CLOSING;
- final Animation animation;
- // Background color on TaskDisplayArea has already been set earlier in
- // WindowContainer#getAnimationAdapter.
- if (target.showBackdrop) {
- animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
- ? com.android.internal.R.anim.task_fragment_clear_top_open_enter
- : com.android.internal.R.anim.task_fragment_clear_top_open_exit);
- } else {
- animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
- ? com.android.internal.R.anim.task_fragment_open_enter
- : com.android.internal.R.anim.task_fragment_open_exit);
- }
- // Use the whole animation bounds instead of the change bounds, so that when multiple change
- // targets are opening at the same time, the animation applied to each will be the same.
- // Otherwise, we may see gap between the activities that are launching together.
- animation.initialize(wholeAnimationBounds.width(), wholeAnimationBounds.height(),
- wholeAnimationBounds.width(), wholeAnimationBounds.height());
- animation.scaleCurrentDuration(mTransitionAnimationScaleSetting);
- return animation;
- }
-
- @NonNull
- Animation loadCloseAnimation(@NonNull RemoteAnimationTarget target,
- @NonNull Rect wholeAnimationBounds) {
- final boolean isEnter = target.mode != MODE_CLOSING;
- final Animation animation;
- if (target.showBackdrop) {
- animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
- ? com.android.internal.R.anim.task_fragment_clear_top_close_enter
- : com.android.internal.R.anim.task_fragment_clear_top_close_exit);
- } else {
- animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
- ? com.android.internal.R.anim.task_fragment_close_enter
- : com.android.internal.R.anim.task_fragment_close_exit);
- }
- // Use the whole animation bounds instead of the change bounds, so that when multiple change
- // targets are closing at the same time, the animation applied to each will be the same.
- // Otherwise, we may see gap between the activities that are finishing together.
- animation.initialize(wholeAnimationBounds.width(), wholeAnimationBounds.height(),
- wholeAnimationBounds.width(), wholeAnimationBounds.height());
- animation.scaleCurrentDuration(mTransitionAnimationScaleSetting);
- return animation;
- }
-
- private float getTransitionAnimationScaleSetting() {
- return WindowManager.fixScale(Settings.Global.getFloat(mContext.getContentResolver(),
- Settings.Global.TRANSITION_ANIMATION_SCALE, mContext.getResources().getFloat(
- R.dimen.config_appTransitionAnimationDurationScaleDefault)));
- }
-
- private class SettingsObserver extends ContentObserver {
- SettingsObserver(@NonNull Handler handler) {
- super(handler);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- mTransitionAnimationScaleSetting = getTransitionAnimationScaleSetting();
- }
- }
-}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
index 4267749dfa6b..c5aaddc4e0ed 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
@@ -29,6 +29,7 @@ import android.view.WindowManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.window.extensions.embedding.AnimationBackground;
+import androidx.window.extensions.embedding.AnimationParams;
import androidx.window.extensions.embedding.SplitAttributes;
import org.junit.Before;
@@ -112,5 +113,13 @@ public class WindowExtensionsTest {
.isEqualTo(new SplitAttributes.SplitType.RatioSplitType(0.5f));
assertThat(splitAttributes.getAnimationBackground())
.isEqualTo(AnimationBackground.ANIMATION_BACKGROUND_DEFAULT);
+ assertThat(splitAttributes.getAnimationParams().getAnimationBackground())
+ .isEqualTo(AnimationBackground.ANIMATION_BACKGROUND_DEFAULT);
+ assertThat(splitAttributes.getAnimationParams().getOpenAnimationResId())
+ .isEqualTo(AnimationParams.DEFAULT_ANIMATION_RESOURCES_ID);
+ assertThat(splitAttributes.getAnimationParams().getCloseAnimationResId())
+ .isEqualTo(AnimationParams.DEFAULT_ANIMATION_RESOURCES_ID);
+ assertThat(splitAttributes.getAnimationParams().getChangeAnimationResId())
+ .isEqualTo(AnimationParams.DEFAULT_ANIMATION_RESOURCES_ID);
}
}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
index 7b473b04548c..ad41b18dcbc6 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
@@ -23,8 +23,6 @@ import static androidx.window.extensions.embedding.EmbeddingTestUtils.createTest
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -86,24 +84,6 @@ public class JetpackTaskFragmentOrganizerTest {
}
@Test
- public void testUnregisterOrganizer() {
- mOrganizer.overrideSplitAnimation();
- mOrganizer.unregisterOrganizer();
-
- verify(mOrganizer).unregisterRemoteAnimations();
- }
-
- @Test
- public void testOverrideSplitAnimation() {
- assertNull(mOrganizer.mAnimationController);
-
- mOrganizer.overrideSplitAnimation();
-
- assertNotNull(mOrganizer.mAnimationController);
- verify(mOrganizer).registerRemoteAnimations(mOrganizer.mAnimationController.mDefinition);
- }
-
- @Test
public void testExpandTaskFragment() {
final TaskContainer taskContainer = createTestTaskContainer();
doReturn(taskContainer).when(mSplitController).getTaskContainer(anyInt());
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index efeec82b782e..d852204b88a8 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -103,8 +103,6 @@ import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.extensions.layout.WindowLayoutComponentImpl;
import androidx.window.extensions.layout.WindowLayoutInfo;
-import com.android.window.flags.Flags;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -167,6 +165,7 @@ public class SplitControllerTest {
private Consumer<List<SplitInfo>> mEmbeddingCallback;
private List<SplitInfo> mSplitInfos;
private TransactionManager mTransactionManager;
+ private ActivityThread mCurrentActivityThread;
@Before
public void setUp() {
@@ -183,10 +182,12 @@ public class SplitControllerTest {
};
mSplitController.setSplitInfoCallback(mEmbeddingCallback);
mTransactionManager = mSplitController.mTransactionManager;
+ mCurrentActivityThread = ActivityThread.currentActivityThread();
spyOn(mSplitController);
spyOn(mSplitPresenter);
spyOn(mEmbeddingCallback);
spyOn(mTransactionManager);
+ spyOn(mCurrentActivityThread);
doNothing().when(mSplitPresenter).applyTransaction(any(), anyInt(), anyBoolean());
final Configuration activityConfig = new Configuration();
activityConfig.windowConfiguration.setBounds(TASK_BOUNDS);
@@ -1557,8 +1558,6 @@ public class SplitControllerTest {
@Test
public void testIsActivityEmbedded() {
- mSetFlagRule.enableFlags(Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG);
-
assertFalse(mSplitController.isActivityEmbedded(mActivity));
doReturn(true).when(mActivityWindowInfo).isEmbedded();
@@ -1568,8 +1567,6 @@ public class SplitControllerTest {
@Test
public void testGetEmbeddedActivityWindowInfo() {
- mSetFlagRule.enableFlags(Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG);
-
final boolean isEmbedded = true;
final Rect taskBounds = new Rect(0, 0, 1000, 2000);
final Rect activityStackBounds = new Rect(0, 0, 500, 2000);
@@ -1584,8 +1581,6 @@ public class SplitControllerTest {
@Test
public void testSetEmbeddedActivityWindowInfoCallback() {
- mSetFlagRule.enableFlags(Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG);
-
final ClientTransactionListenerController controller = ClientTransactionListenerController
.getInstance();
spyOn(controller);
@@ -1676,7 +1671,8 @@ public class SplitControllerTest {
final IBinder activityToken = new Binder();
doReturn(activityToken).when(activity).getActivityToken();
doReturn(activity).when(mSplitController).getActivity(activityToken);
- doReturn(activityClientRecord).when(mSplitController).getActivityClientRecord(activity);
+ doReturn(activityClientRecord).when(mCurrentActivityThread).getActivityClient(
+ activityToken);
doReturn(taskId).when(activity).getTaskId();
doReturn(new ActivityInfo()).when(activity).getActivityInfo();
doReturn(DEFAULT_DISPLAY).when(activity).getDisplayId();
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java
deleted file mode 100644
index a1e9f08585f6..000000000000
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java
+++ /dev/null
@@ -1,88 +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 androidx.window.extensions.embedding;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-
-import static org.mockito.Mockito.never;
-
-import android.platform.test.annotations.Presubmit;
-import android.window.TaskFragmentOrganizer;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-/**
- * Test class for {@link TaskFragmentAnimationController}.
- *
- * Build/Install/Run:
- * atest WMJetpackUnitTests:TaskFragmentAnimationControllerTest
- */
-@Presubmit
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class TaskFragmentAnimationControllerTest {
- @Rule
- public MockitoRule rule = MockitoJUnit.rule();
-
- @Mock
- private TaskFragmentOrganizer mOrganizer;
- private TaskFragmentAnimationController mAnimationController;
-
- @Before
- public void setup() {
- mAnimationController = new TaskFragmentAnimationController(mOrganizer);
- }
-
- @Test
- public void testRegisterRemoteAnimations() {
- mAnimationController.registerRemoteAnimations();
-
- verify(mOrganizer).registerRemoteAnimations(mAnimationController.mDefinition);
-
- mAnimationController.registerRemoteAnimations();
-
- // No extra call if it has been registered.
- verify(mOrganizer).registerRemoteAnimations(mAnimationController.mDefinition);
- }
-
- @Test
- public void testUnregisterRemoteAnimations() {
- mAnimationController.unregisterRemoteAnimations();
-
- // No call if it is not registered.
- verify(mOrganizer, never()).unregisterRemoteAnimations();
-
- mAnimationController.registerRemoteAnimations();
- mAnimationController.unregisterRemoteAnimations();
-
- verify(mOrganizer).unregisterRemoteAnimations();
-
- mAnimationController.unregisterRemoteAnimations();
-
- // No extra call if it has been unregistered.
- verify(mOrganizer).unregisterRemoteAnimations();
- }
-}
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 1e6824196687..a00d003001e6 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -190,6 +190,15 @@ java_library {
],
}
+java_library {
+ name: "WindowManager-Shell-shared-desktopMode",
+
+ srcs: [
+ "shared/**/desktopmode/*.java",
+ "shared/**/desktopmode/*.kt",
+ ],
+}
+
android_library {
name: "WindowManager-Shell",
srcs: [
@@ -215,7 +224,6 @@ android_library {
"//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
"//frameworks/libs/systemui:iconloader_base",
"com_android_wm_shell_flags_lib",
- "com.android.window.flags.window-aconfig-java",
"WindowManager-Shell-proto",
"WindowManager-Shell-shared",
"perfetto_trace_java_protos",
diff --git a/libs/WindowManager/Shell/OWNERS b/libs/WindowManager/Shell/OWNERS
index ebebd8a52c9a..cb422eab372b 100644
--- a/libs/WindowManager/Shell/OWNERS
+++ b/libs/WindowManager/Shell/OWNERS
@@ -1,5 +1,5 @@
xutan@google.com
# Give submodule owners in shell resource approval
-per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, jorgegil@google.com, lbill@google.com, madym@google.com, nmusgrave@google.com, pbdr@google.com, tkachenkoi@google.com, mpodolian@google.com, liranb@google.com
+per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, jorgegil@google.com, lbill@google.com, madym@google.com, vaniadesmonda@google.com, pbdr@google.com, tkachenkoi@google.com, mpodolian@google.com, liranb@google.com
per-file res*/*/tv_*.xml = bronger@google.com
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index 3ff40e0886a4..56ea7c201e53 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -113,16 +113,6 @@ flag {
}
flag {
- name: "animate_bubble_size_change"
- namespace: "multitasking"
- description: "Turns on the animation for bubble bar icons size change"
- bug: "335575529"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "enable_taskbar_on_phones"
namespace: "multitasking"
description: "Enables taskbar on phones"
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp b/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp
index c6dbd9b25e7f..1871203c7600 100644
--- a/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp
@@ -22,6 +22,40 @@ package {
default_team: "trendy_team_multitasking_windowing",
}
+android_app {
+ name: "WMShellRobolectricScreenshotTestApp",
+ platform_apis: true,
+ certificate: "platform",
+ static_libs: [
+ "WindowManager-Shell",
+ "platform-screenshot-diff-core",
+ ],
+ asset_dirs: ["goldens/robolectric"],
+ manifest: "AndroidManifestRobolectric.xml",
+ use_resource_processor: true,
+}
+
+android_robolectric_test {
+ name: "WMShellRobolectricScreenshotTests",
+ instrumentation_for: "WMShellRobolectricScreenshotTestApp",
+ upstream: true,
+ java_resource_dirs: [
+ "robolectric/config",
+ ],
+ srcs: [
+ "src/**/*.kt",
+ ],
+ static_libs: [
+ "junit",
+ "androidx.test.runner",
+ "androidx.test.rules",
+ "androidx.test.ext.junit",
+ "truth",
+ "platform-parametric-runner-lib",
+ ],
+ auto_gen_config: true,
+}
+
android_test {
name: "WMShellMultivalentScreenshotTestsOnDevice",
srcs: [
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml b/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml
index a7a3f1313a9b..b4bdaeaf0eac 100644
--- a/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml
@@ -16,7 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.wm.shell.multivalentscreenshot">
<application android:debuggable="true" android:supportsRtl="true">
- <uses-library android:name="android.test.runner" />
<activity
android:name="platform.test.screenshot.ScreenshotActivity"
android:exported="true">
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/dark_portrait_bubbles_education.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/dark_portrait_bubbles_education.png
new file mode 100644
index 000000000000..e02c89ae07bd
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/dark_portrait_bubbles_education.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/light_portrait_bubbles_education.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/light_portrait_bubbles_education.png
new file mode 100644
index 000000000000..e02c89ae07bd
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/light_portrait_bubbles_education.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties b/libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties
index 7a0527ccaafb..d50d976c9e84 100644
--- a/libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties
@@ -1,2 +1,3 @@
sdk=NEWEST_SDK
+graphicsMode=NATIVE
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_open_in_browser.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_open_in_browser.xml
new file mode 100644
index 000000000000..7d912a24c443
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_open_in_browser.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="960" android:viewportHeight="960" android:tint="?attr/colorControlNormal">
+ <path android:fillColor="@android:color/black" android:pathData="M160,880Q127,880 103.5,856.5Q80,833 80,800L80,440Q80,407 103.5,383.5Q127,360 160,360L240,360L240,160Q240,127 263.5,103.5Q287,80 320,80L800,80Q833,80 856.5,103.5Q880,127 880,160L880,520Q880,553 856.5,576.5Q833,600 800,600L720,600L720,800Q720,833 696.5,856.5Q673,880 640,880L160,880ZM160,800L640,800Q640,800 640,800Q640,800 640,800L640,520L160,520L160,800Q160,800 160,800Q160,800 160,800ZM720,520L800,520Q800,520 800,520Q800,520 800,520L800,240L320,240L320,360L640,360Q673,360 696.5,383.5Q720,407 720,440L720,520Z"/>
+</vector>
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 d5724cc6a420..864f7cd421ee 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
@@ -19,6 +19,10 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/desktop_mode_handle_menu_width"
android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:paddingBottom="@dimen/desktop_mode_handle_menu_pill_elevation"
+ android:paddingRight="@dimen/desktop_mode_handle_menu_pill_elevation"
android:orientation="vertical">
<LinearLayout
@@ -27,7 +31,7 @@
android:layout_height="@dimen/desktop_mode_handle_menu_app_info_pill_height"
android:layout_marginTop="@dimen/desktop_mode_handle_menu_margin_top"
android:layout_marginStart="1dp"
- android:elevation="1dp"
+ android:elevation="@dimen/desktop_mode_handle_menu_pill_elevation"
android:orientation="horizontal"
android:background="@drawable/desktop_mode_decor_handle_menu_background"
android:gravity="center_vertical">
@@ -73,7 +77,7 @@
android:layout_marginTop="@dimen/desktop_mode_handle_menu_pill_spacing_margin"
android:layout_marginStart="1dp"
android:orientation="horizontal"
- android:elevation="1dp"
+ android:elevation="@dimen/desktop_mode_handle_menu_pill_elevation"
android:background="@drawable/desktop_mode_decor_handle_menu_background"
android:gravity="center_vertical">
@@ -124,7 +128,7 @@
android:layout_marginTop="@dimen/desktop_mode_handle_menu_pill_spacing_margin"
android:layout_marginStart="1dp"
android:orientation="vertical"
- android:elevation="1dp"
+ android:elevation="@dimen/desktop_mode_handle_menu_pill_elevation"
android:background="@drawable/desktop_mode_decor_handle_menu_background">
<Button
@@ -135,5 +139,24 @@
android:drawableTint="?androidprv:attr/materialColorOnSurface"
style="@style/DesktopModeHandleMenuActionButton"/>
</LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/open_in_browser_pill"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/desktop_mode_handle_menu_open_in_browser_pill_height"
+ android:layout_marginTop="@dimen/desktop_mode_handle_menu_pill_spacing_margin"
+ android:layout_marginStart="1dp"
+ android:orientation="vertical"
+ android:elevation="@dimen/desktop_mode_handle_menu_pill_elevation"
+ android:background="@drawable/desktop_mode_decor_handle_menu_background">
+
+ <Button
+ android:id="@+id/open_in_browser_button"
+ android:contentDescription="@string/open_in_browser_text"
+ android:text="@string/open_in_browser_text"
+ android:drawableStart="@drawable/desktop_mode_ic_handle_menu_open_in_browser"
+ android:drawableTint="?androidprv:attr/materialColorOnSurface"
+ style="@style/DesktopModeHandleMenuActionButton"/>
+ </LinearLayout>
</LinearLayout>
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 8b328e2c79cf..6e8a679928f0 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -118,6 +118,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Sweef"</string>
<string name="select_text" msgid="5139083974039906583">"Kies"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Skermskoot"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Maak toe"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Maak kieslys toe"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Maak kieslys oop"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index b005a01711eb..ac7935d76bfd 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"አረፋ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ያቀናብሩ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"አረፋ ተሰናብቷል።"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"አረፋዎች"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"አረፋዎችን አሳይ"</string>
<string name="restart_button_description" msgid="4564728020654658478">"ለተሻለ ዕይታ ይህን መተግበሪያ እንደገና ለመጀመር መታ ያድርጉ"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"የዚህን መተግበሪያ ምጥጥነ ገፅታ በቅንብሮች ውስጥ ይለውጡ"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"የምጥጥነ ገፅታ ለውጥ"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"ተንሳፋፊ"</string>
<string name="select_text" msgid="5139083974039906583">"ምረጥ"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ቅጽበታዊ ገፅ ዕይታ"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ዝጋ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"ምናሌን ክፈት"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 8c283d33eff6..53ff6da41d34 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"فقاعة"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"إدارة"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"تم إغلاق الفقاعة."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"الفقاعات"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"إظهار الفقاعات"</string>
<string name="restart_button_description" msgid="4564728020654658478">"انقر لإعادة تشغيل هذا التطبيق للحصول على تجربة عرض أفضل."</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"يمكنك تغيير نسبة العرض إلى الارتفاع لهذا التطبيق من خلال \"الإعدادات\"."</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"تغيير نسبة العرض إلى الارتفاع"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"نافذة عائمة"</string>
<string name="select_text" msgid="5139083974039906583">"اختيار"</string>
<string name="screenshot_text" msgid="1477704010087786671">"لقطة شاشة"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"إغلاق"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"إغلاق القائمة"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"فتح القائمة"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index ef92587ad274..b94ab2e73e9c 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"পৰিচালনা কৰক"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল অগ্ৰাহ্য কৰা হৈছে"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"বাবল"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"বাবল দেখুৱাওক"</string>
<string name="restart_button_description" msgid="4564728020654658478">"উন্নত ভিউ পোৱাৰ বাবে এপ্‌টো ৰিষ্টাৰ্ট কৰিবলৈ টিপক"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ছেটিঙলৈ গৈ এই এপ্‌টোৰ আকাৰৰ অনুপাত সলনি কৰক"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"আকাৰৰ অনুপাত সলনি কৰক"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"ওপঙা"</string>
<string name="select_text" msgid="5139083974039906583">"বাছনি কৰক"</string>
<string name="screenshot_text" msgid="1477704010087786671">"স্ক্ৰীনশ্বট"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"ব্ৰাউজাৰত খোলক"</string>
<string name="close_text" msgid="4986518933445178928">"বন্ধ কৰক"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"মেনু বন্ধ কৰক"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"মেনু খোলক"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 04b2f1c23bc4..dd3e0e3b03f4 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Qabarcıq"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"İdarə edin"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Qabarcıqdan imtina edilib."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Yumrucuq"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Yumrucuqları göstərin"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Yaxşı görünüş üçün toxunaraq bu tətbiqi yenidən başladın"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Ayarlarda bu tətbiqin tərəflər nisbətini dəyişin"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Tərəflər nisbətini dəyişin"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Üzən pəncərə"</string>
<string name="select_text" msgid="5139083974039906583">"Seçin"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Skrinşot"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Bağlayın"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyunu bağlayın"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Menyunu açın"</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 47bc105f19bc..af695e73161d 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljajte"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Oblačići"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Prikaži oblačiće"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Dodirnite da biste restartovali ovu aplikaciju radi boljeg prikaza"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Promenite razmeru ove aplikacije u Podešavanjima"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Promeni razmeru"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Plutajuće"</string>
<string name="select_text" msgid="5139083974039906583">"Izaberite"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Snimak ekrana"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Otvorite u pregledaču"</string>
<string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite meni"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Otvorite meni"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 6ad7553a8383..dbbc07fe2407 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Усплывальнае апавяшчэнне"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Кіраваць"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Усплывальнае апавяшчэнне адхілена."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Успл. чаты"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Паказ усплывальных чатаў"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Націсніце, каб перазапусціць гэту праграму для зручнейшага прагляду"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Змяніць суадносіны бакоў для гэтай праграмы ў наладах"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Змяніць суадносіны бакоў"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Зрабіць рухомым акном"</string>
<string name="select_text" msgid="5139083974039906583">"Выбраць"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Здымак экрана"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Адкрыць у браўзеры"</string>
<string name="close_text" msgid="4986518933445178928">"Закрыць"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыць меню"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Адкрыць меню"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index a9e0bce81376..bba2f999c8ea 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Управление"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отхвърлено."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Балончета"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Показване на балончетата"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Докоснете, за да рестартирате това приложение с цел по-добър изглед"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Променете съотношението на това приложение в „Настройки“"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Промяна на съотношението"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Плаващо"</string>
<string name="select_text" msgid="5139083974039906583">"Избиране"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Екранна снимка"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Затваряне"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затваряне на менюто"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Отваряне на менюто"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 29de1007e311..cb081821d719 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ম্যানেজ করুন"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল বাতিল করা হয়েছে।"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"বাবল"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"বাবল দেখুন"</string>
<string name="restart_button_description" msgid="4564728020654658478">"আরও ভাল ভিউয়ের জন্য এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"সেটিংস থেকে এই অ্যাপের অ্যাস্পেক্ট রেশিও পরিবর্তন করুন"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"অ্যাস্পেক্ট রেশিও পরিবর্তন করুন"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"ফ্লোট"</string>
<string name="select_text" msgid="5139083974039906583">"বেছে নিন"</string>
<string name="screenshot_text" msgid="1477704010087786671">"স্ক্রিনশট"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"বন্ধ করুন"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"\'মেনু\' বন্ধ করুন"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"মেনু খুলুন"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 5f1da7571d95..e7505e50f749 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljaj"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Oblačići"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Prikaz oblačića"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Dodirnite da ponovo pokrenete ovu aplikaciju radi boljeg prikaza"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Promijenite format slike aplikacije u Postavkama"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Promijenite format slike"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Lebdeći"</string>
<string name="select_text" msgid="5139083974039906583">"Odabir"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Snimak ekrana"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Otvori u pregledniku"</string>
<string name="close_text" msgid="4986518933445178928">"Zatvaranje"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvaranje menija"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Otvaranje menija"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index d70de794ba17..ce9f54798120 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bombolla"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gestiona"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"La bombolla s\'ha ignorat."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bombolles"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Mostra les bombolles"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Toca per reiniciar aquesta aplicació i obtenir una millor visualització"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Canvia la relació d\'aspecte d\'aquesta aplicació a Configuració"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Canvia la relació d\'aspecte"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Flotant"</string>
<string name="select_text" msgid="5139083974039906583">"Selecciona"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Obre al navegador"</string>
<string name="close_text" msgid="4986518933445178928">"Tanca"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tanca el menú"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Obre el menú"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index ca00fec12e86..06941f6db248 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovat"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina byla zavřena."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bubliny"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Zobrazovat bubliny"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Klepnutím tuto aplikaci restartujete kvůli lepšímu zobrazení"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Změnit v Nastavení poměr stran této aplikace"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Změnit poměr stran"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Plovoucí"</string>
<string name="select_text" msgid="5139083974039906583">"Vybrat"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Snímek obrazovky"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zavřít"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavřít nabídku"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Otevřít nabídku"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index d50d2f0f135d..7883bb0fab8b 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen blev lukket."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bobler"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Vis bobler"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Tryk for at genstarte denne app, så visningen forbedres"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Skift denne apps billedformat i Indstillinger"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Skift billedformat"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Svævende"</string>
<string name="select_text" msgid="5139083974039906583">"Vælg"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Luk"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Luk menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Åbn menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 7f44f83a1790..6bb85239f397 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Verwalten"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble verworfen."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bubbles"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Bubbles anzeigen"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Tippen, um diese App neu zu starten und die Ansicht zu verbessern"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Seitenverhältnis der App in den Einstellungen ändern"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Seitenverhältnis ändern"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Frei schwebend"</string>
<string name="select_text" msgid="5139083974039906583">"Auswählen"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Schließen"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Menü öffnen"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index a3a5ccd839e4..a640b941dd6e 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Συννεφάκι"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Διαχείριση"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Το συννεφάκι παραβλέφθηκε."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Συννεφάκια"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Εμφάνιση συννεφακίων"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Πατήστε για να επανεκκινήσετε αυτή την εφαρμογή για καλύτερη προβολή"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Αλλάξτε τον λόγο διαστάσεων αυτής της εφαρμογής στις Ρυθμίσεις"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Αλλαγή λόγου διαστάσεων"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Κινούμενο"</string>
<string name="select_text" msgid="5139083974039906583">"Επιλογή"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Στιγμιότυπο οθόνης"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Κλείσιμο"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Κλείσιμο μενού"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Άνοιγμα μενού"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index edc4f4e25c2a..4708d5fcd54e 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bubbles"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Show bubbles"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Tap to restart this app for a better view"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Change this app\'s aspect ratio in Settings"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Change aspect ratio"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
<string name="select_text" msgid="5139083974039906583">"Select"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Open menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index d7e23fd8dfd8..bd8a63690ba3 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -116,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
<string name="select_text" msgid="5139083974039906583">"Select"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Open Menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index edc4f4e25c2a..4708d5fcd54e 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bubbles"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Show bubbles"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Tap to restart this app for a better view"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Change this app\'s aspect ratio in Settings"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Change aspect ratio"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
<string name="select_text" msgid="5139083974039906583">"Select"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Open menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index edc4f4e25c2a..4708d5fcd54e 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bubbles"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Show bubbles"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Tap to restart this app for a better view"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Change this app\'s aspect ratio in Settings"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Change aspect ratio"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
<string name="select_text" msgid="5139083974039906583">"Select"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Open menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index 1da8c275ce54..35030808f4fd 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -116,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎Float‎‏‎‎‏‎"</string>
<string name="select_text" msgid="5139083974039906583">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‎‏‎‎‎‏‎‏‏‏‎Select‎‏‎‎‏‎"</string>
<string name="screenshot_text" msgid="1477704010087786671">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎Screenshot‎‏‎‎‏‎"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎Open in browser‎‏‎‎‏‎"</string>
<string name="close_text" msgid="4986518933445178928">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‏‎‎‎‎‎Close‎‏‎‎‏‎"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‎Close Menu‎‏‎‎‏‎"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎‎‎Open Menu‎‏‎‎‏‎"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 8653e5932a04..72bafcd61e5a 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Cuadro"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Administrar"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Se descartó el cuadro."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Burbujas"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Mostrar burbujas"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Presiona para reiniciar esta app y tener una mejor vista"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Cambiar la relación de aspecto de esta app en Configuración"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Cambiar relación de aspecto"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
<string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Cerrar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Abrir el menú"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 8f59c9c91d20..d907a56d15c4 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Burbuja"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionar"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbuja cerrada."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Burbujas"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Mostrar burbujas"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Toca para reiniciar esta aplicación y obtener una mejor vista"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Cambiar la relación de aspecto de esta aplicación en Ajustes"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Cambiar relación de aspecto"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
<string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Cerrar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Abrir menú"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 3d86eb4a91d9..7d8103edf664 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Mull"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Halda"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Mullist loobuti."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Mullid"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Kuva mullid"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Puudutage, et see rakendus parema vaate jaoks taaskäivitada"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Muutke selle rakenduse kuvasuhet jaotises Seaded"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Muutke kuvasuhet"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Hõljuv"</string>
<string name="select_text" msgid="5139083974039906583">"Vali"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Ekraanipilt"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Sule"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Sule menüü"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Ava menüü"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 4e7bdd246d10..19e028f0f706 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Burbuila"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Kudeatu"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Baztertu da globoa."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Burbuilak"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Erakutsi burbuilak"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Hobeto ikusteko, sakatu hau, eta aplikazioa berrabiarazi egingo da"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Aldatu aplikazioaren aspektu-erlazioa ezarpenetan"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Aldatu aspektu-erlazioa"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Leiho gainerakorra"</string>
<string name="select_text" msgid="5139083974039906583">"Hautatu"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Pantaila-argazkia"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Itxi"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Itxi menua"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Ireki menua"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 4b9be47f8023..2bb9415d83a6 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"حباب"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"مدیریت"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"حبابک رد شد."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"حبابک"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"نمایش حبابک"</string>
<string name="restart_button_description" msgid="4564728020654658478">"برای داشتن نمایی بهتر، تک‌ضرب بزنید تا این برنامه بازراه‌اندازی شود"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"نسبت ابعادی این برنامه را در «تنظیمات» تغییر دهید"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"تغییر نسبت ابعادی"</string>
@@ -96,7 +94,7 @@
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"دوربین مشکلی ندارد؟ برای بستن تک‌ضرب بزنید."</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"از چندین برنامه به‌طور هم‌زمان استفاده کنید"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"برای حالت صفحهٔ دونیمه، در برنامه‌ای دیگر بکشید"</string>
- <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"برای جابه‌جا کردن برنامه، بیرون از آن دوضربه بزنید"</string>
+ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"برای جابه‌جا کردن برنامه، بیرون از آن دو تک‌ضرب بزنید"</string>
<string name="letterbox_education_got_it" msgid="4057634570866051177">"متوجه‌ام"</string>
<string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"برای اطلاعات بیشتر، گسترده کنید."</string>
<string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"برای نمایش بهتر بازراه‌اندازی شود؟"</string>
@@ -104,7 +102,7 @@
<string name="letterbox_restart_cancel" msgid="1342209132692537805">"لغو کردن"</string>
<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>
+ <string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"برای جابه‌جا کردن این برنامه\nدو تک‌ضرب بزنید"</string>
<string name="maximize_button_text" msgid="1650859196290301963">"بزرگ کردن"</string>
<string name="minimize_button_text" msgid="271592547935841753">"کوچک کردن"</string>
<string name="close_button_text" msgid="2913281996024033299">"بستن"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"شناور"</string>
<string name="select_text" msgid="5139083974039906583">"انتخاب"</string>
<string name="screenshot_text" msgid="1477704010087786671">"نماگرفت"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"بستن"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"بستن منو"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"باز کردن منو"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index 577d625ba8f8..fcc4150f6fc1 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Kupla"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Ylläpidä"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Kupla ohitettu."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Kuplat"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Näytä kuplat"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Napauta, niin sovellus käynnistyy uudelleen paremmin näytölle sopivana"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Muuta tämän sovelluksen kuvasuhdetta Asetuksissa"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Vaihda kuvasuhdetta"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Kelluva ikkuna"</string>
<string name="select_text" msgid="5139083974039906583">"Valitse"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Kuvakaappaus"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Sulje"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Sulje valikko"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Avaa valikko"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 74d822ac02c0..268b409e6eef 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -31,11 +31,11 @@
<string name="accessibility_action_pip_resize" msgid="4623966104749543182">"Redimensionner"</string>
<string name="accessibility_action_pip_stash" msgid="4060775037619702641">"Ajouter à la réserve"</string>
<string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Retirer de la réserve"</string>
- <string name="dock_forced_resizable" msgid="7429086980048964687">"L\'application peut ne pas fonctionner avec l\'écran partagé"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"L\'application ne prend pas en charge l\'écran partagé"</string>
- <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Cette application ne peut être ouverte que dans une seule fenêtre."</string>
- <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string>
+ <string name="dock_forced_resizable" msgid="7429086980048964687">"L\'appli peut ne pas fonctionner avec l\'écran partagé"</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"L\'appli ne prend pas en charge l\'écran partagé"</string>
+ <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Cette appli ne peut être ouverte que dans une seule fenêtre."</string>
+ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'appli ne fonctionne pas sur un écran secondaire."</string>
+ <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'appli ne peut pas être lancée sur des écrans secondaires."</string>
<string name="accessibility_divider" msgid="6407584574218956849">"Séparateur d\'écran partagé"</string>
<string name="divider_title" msgid="1963391955593749442">"Séparateur d\'écran partagé"</string>
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Plein écran à la gauche"</string>
@@ -56,7 +56,7 @@
<string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pour quitter, balayez l\'écran du bas vers le haut, ou touchez n\'importe où sur l\'écran en haut de l\'appli"</string>
<string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Démarrer le mode Une main"</string>
<string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Quitter le mode Une main"</string>
- <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Paramètres pour les bulles de l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Paramètres pour les bulles de l\'appli <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Menu déroulant"</string>
<string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Replacer sur la pile"</string>
<string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
@@ -73,7 +73,7 @@
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Clavarder en utilisant des bulles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes (de bulles). Touchez une bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Paramètres des bulles"</string>
- <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Toucher Gérer pour désactiver les bulles de cette application"</string>
+ <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Toucher Gérer pour désactiver les bulles de cette appli"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Aucune bulle récente"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Les bulles récentes et les bulles ignorées s\'afficheront ici"</string>
@@ -84,33 +84,31 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle ignorée."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
- <string name="restart_button_description" msgid="4564728020654658478">"Touchez pour redémarrer cette application afin d\'obtenir un meilleur affichage"</string>
- <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Changer les proportions de cette application dans les paramètres"</string>
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bulles"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Afficher les bulles"</string>
+ <string name="restart_button_description" msgid="4564728020654658478">"Touchez pour redémarrer cette appli afin d\'obtenir un meilleur affichage"</string>
+ <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Changer les proportions de cette appli dans les paramètres"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Modifier les proportions"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo?\nTouchez pour réajuster"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu?\nTouchez pour rétablir"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo? Touchez pour ignorer."</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Voir et en faire plus"</string>
- <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Faites glisser une autre application pour utiliser l\'écran partagé"</string>
- <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Touchez deux fois à côté d\'une application pour la repositionner"</string>
+ <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Faites glisser une autre appli pour utiliser l\'écran partagé"</string>
+ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Touchez deux fois à côté d\'une appli pour la repositionner"</string>
<string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
<string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développer pour en savoir plus."</string>
<string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Redémarrer pour un meilleur affichage?"</string>
- <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Vous pouvez redémarrer l\'application pour qu\'elle s\'affiche mieux sur votre écran, mais il se peut que vous perdiez votre progression ou toute modification non enregistrée"</string>
+ <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Vous pouvez redémarrer l\'appli pour qu\'elle s\'affiche mieux sur votre écran, mais il se peut que vous perdiez votre progression ou toute modification non enregistrée"</string>
<string name="letterbox_restart_cancel" msgid="1342209132692537805">"Annuler"</string>
<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 application"</string>
+ <string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Toucher deux fois pour\ndéplacer cette appli"</string>
<string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string>
<string name="close_button_text" msgid="2913281996024033299">"Fermer"</string>
<string name="back_button_text" msgid="1469718707134137085">"Retour"</string>
<string name="handle_text" msgid="1766582106752184456">"Identifiant"</string>
- <string name="app_icon_text" msgid="2823268023931811747">"Icône de l\'application"</string>
+ <string name="app_icon_text" msgid="2823268023931811747">"Icône de l\'appli"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
<string name="desktop_text" msgid="1077633567027630454">"Mode Bureau"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Écran divisé"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Flottant"</string>
<string name="select_text" msgid="5139083974039906583">"Sélectionner"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Capture d\'écran"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Fermer"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Ouvrir le menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 4d14d0b85f3e..1762a2921863 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle fermée."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bulles"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Afficher les bulles"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Appuyez pour redémarrer cette appli et obtenir une meilleure vue."</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Modifiez le format de cette appli dans les Paramètres."</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Modifier le format"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Flottante"</string>
<string name="select_text" msgid="5139083974039906583">"Sélectionner"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Capture d\'écran"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Fermer"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Ouvrir le menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index e5b67c2aaad1..94e7ad5bcd4e 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -118,6 +118,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
<string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
<string name="close_text" msgid="4986518933445178928">"Pechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Pechar o menú"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Abrir menú"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index e2a52dccd8ea..8a03a4d33b87 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"બબલ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"મેનેજ કરો"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"બબલ છોડી દેવાયો."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"બબલ"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"બબલ બતાવો"</string>
<string name="restart_button_description" msgid="4564728020654658478">"વધુ સારા વ્યૂ માટે, આ ઍપને ફરી શરૂ કરવા ટૅપ કરો"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"સેટિંગમાં આ ઍપનો સાપેક્ષ ગુણોત્તર બદલો"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"સાપેક્ષ ગુણોત્તર બદલો"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"ફ્લોટિંગ વિન્ડો"</string>
<string name="select_text" msgid="5139083974039906583">"પસંદ કરો"</string>
<string name="screenshot_text" msgid="1477704010087786671">"સ્ક્રીનશૉટ"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"બંધ કરો"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"મેનૂ બંધ કરો"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"મેનૂ ખોલો"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index f75e0e0528e1..b73f449e4e83 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"मैनेज करें"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल खारिज किया गया."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"बबल्स"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"बबल्स दिखाएं"</string>
<string name="restart_button_description" msgid="4564728020654658478">"बेहतर व्यू पाने के लिए, टैप करके ऐप्लिकेशन को रीस्टार्ट करें"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"सेटिंग में जाकर इस ऐप्लिकेशन का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"फ़्लोट"</string>
<string name="select_text" msgid="5139083974039906583">"चुनें"</string>
<string name="screenshot_text" msgid="1477704010087786671">"स्क्रीनशॉट"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"बंद करें"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेन्यू बंद करें"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"मेन्यू खोलें"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index ed80c505d756..000b0e63bf8e 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić odbačen."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Oblačići"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Prikaži oblačiće"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Dodirnite da biste ponovo pokrenuli tu aplikaciju kako biste bolje vidjeli"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Promijeni omjer slike ove aplikacije u postavkama"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Promijeni omjer slike"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Plutajući"</string>
<string name="select_text" msgid="5139083974039906583">"Odaberite"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Snimka zaslona"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Otvori u pregledniku"</string>
<string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Otvaranje izbornika"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index 32a31063bd90..f4cf75472bb7 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Buborék"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Kezelés"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Buborék elvetve."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Buborékok"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Buborékok megjelenítése"</string>
<string name="restart_button_description" msgid="4564728020654658478">"A jobb nézet érdekében koppintson az alkalmazás újraindításához."</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Az app méretarányát a Beállításokban módosíthatja"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Méretarány módosítása"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Lebegő"</string>
<string name="select_text" msgid="5139083974039906583">"Kiválasztás"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Képernyőkép"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Bezárás"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü bezárása"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Menü megnyitása"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 65ca704ded09..1d2d2ff76912 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Պղպջակ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Կառավարել"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ամպիկը փակվեց։"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Ամպիկներ"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Ցույց տալ ամպիկներ"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Հպեք՝ հավելվածը վերագործարկելու և ավելի հարմար տեսք ընտրելու համար"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Փոխել հավելվածի կողմերի հարաբերակցությունը Կարգավորումներում"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Փոխել չափերի հարաբերակցությունը"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Լողացող պատուհան"</string>
<string name="select_text" msgid="5139083974039906583">"Ընտրել"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Սքրինշոթ"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Բացել դիտարկիչում"</string>
<string name="close_text" msgid="4986518933445178928">"Փակել"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Փակել ընտրացանկը"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Բացել ընտրացանկը"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 975dd72f67d7..0e662f65e1e1 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Kelola"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon ditutup."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Balon"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Tampilkan Balon"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Ketuk untuk memulai ulang aplikasi ini agar mendapatkan tampilan yang lebih baik"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Ubah rasio aspek aplikasi ini di Setelan"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Ubah rasio aspek"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Mengambang"</string>
<string name="select_text" msgid="5139083974039906583">"Pilih"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Tutup"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Buka Menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 11c47189dce0..fb1df4db5d71 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Blaðra"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Stjórna"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Blöðru lokað."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Blöðrur"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Sýna blöðrur"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Ýttu til að endurræsa forritið og fá betri sýn"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Breyta myndhlutfalli þessa forrits í stillingunum"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Breyta myndhlutfalli"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Reikult"</string>
<string name="select_text" msgid="5139083974039906583">"Velja"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Skjámynd"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Loka"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Loka valmynd"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Opna valmynd"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 168c8cc5936f..9c825bee57ce 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Fumetto"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gestisci"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Fumetto ignorato."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bolle"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Mostra bolle"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Tocca per riavviare l\'app e migliorare la visualizzazione"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Cambia le proporzioni dell\'app nelle Impostazioni"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Cambia proporzioni"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Mobile"</string>
<string name="select_text" msgid="5139083974039906583">"Seleziona"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Chiudi"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Chiudi il menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Apri menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index fd4cd1adaa2a..abd0f6b34178 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"בועה"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ניהול"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"הבועה נסגרה."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"בועות"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"הצגת הבועות"</string>
<string name="restart_button_description" msgid="4564728020654658478">"כדי לראות טוב יותר יש להקיש ולהפעיל את האפליקציה הזו מחדש"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"אפשר לשנות את יחס הגובה-רוחב של האפליקציה הזו ב\'הגדרות\'"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"שינוי יחס גובה-רוחב"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"בלונים"</string>
<string name="select_text" msgid="5139083974039906583">"בחירה"</string>
<string name="screenshot_text" msgid="1477704010087786671">"צילום מסך"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"סגירה"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"סגירת התפריט"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"פתיחת התפריט"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 64ddec9450ae..55fd8b16f2a2 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"バブル"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ふきだしが非表示になっています。"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"バブル"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"バブルを表示"</string>
<string name="restart_button_description" msgid="4564728020654658478">"タップしてこのアプリを再起動すると、表示が適切になります"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"このアプリのアスペクト比を [設定] で変更します"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"アスペクト比を変更"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"フローティング"</string>
<string name="select_text" msgid="5139083974039906583">"選択"</string>
<string name="screenshot_text" msgid="1477704010087786671">"スクリーンショット"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"ブラウザで開く"</string>
<string name="close_text" msgid="4986518933445178928">"閉じる"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"メニューを閉じる"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"メニューを開く"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index cab8807b86d1..235420812937 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ბუშტი"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"მართვა"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ბუშტი დაიხურა."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"ბუშტები"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"ბუშტების ჩვენება"</string>
<string name="restart_button_description" msgid="4564728020654658478">"შეხებით გადატვირთეთ ეს აპი უკეთესი ხედის მისაღებად"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"შეცვალეთ ამ აპის თანაფარდობა პარამეტრებიდან"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"თანაფარდობის შეცვლა"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"ფარფატი"</string>
<string name="select_text" msgid="5139083974039906583">"არჩევა"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ეკრანის ანაბეჭდი"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"ბრაუზერში გახსნა"</string>
<string name="close_text" msgid="4986518933445178928">"დახურვა"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"მენიუს დახურვა"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"მენიუს გახსნა"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 4ff5b85b36fd..18183739cb99 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Көпіршік"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Басқару"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Қалқыма хабар жабылды."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Қалқыма хабарлар"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Қалқыма хабарлар көрсету"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Көріністі жақсарту үшін осы қолданбаны түртіп, қайта ашыңыз."</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Осы қолданбаның арақатынасын параметрлерден өзгертуге болады."</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Арақатынасты өзгерту"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Қалқыма"</string>
<string name="select_text" msgid="5139083974039906583">"Таңдау"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Жабу"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Мәзірді жабу"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Мәзірді ашу"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index ba7a32495659..69c0e1eabc05 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ពពុះ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"គ្រប់គ្រង"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"បានច្រានចោល​សារលេចឡើង។"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"ផ្ទាំងអណ្ដែត"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"បង្ហាញផ្ទាំងអណ្ដែត"</string>
<string name="restart_button_description" msgid="4564728020654658478">"ចុចដើម្បី​ចាប់ផ្ដើម​កម្មវិធី​នេះឡើងវិញសម្រាប់ទិដ្ឋភាពកាន់តែប្រសើរ"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ផ្លាស់ប្ដូរសមាមាត្រ​របស់កម្មវិធីនេះនៅក្នុងការកំណត់"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ប្ដូរ​​សមាមាត្រ"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"អណ្ដែត"</string>
<string name="select_text" msgid="5139083974039906583">"ជ្រើសរើស"</string>
<string name="screenshot_text" msgid="1477704010087786671">"រូបថតអេក្រង់"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"បើកក្នុងកម្មវិធីរុករកតាមអ៊ីនធឺណិត"</string>
<string name="close_text" msgid="4986518933445178928">"បិទ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"បិទ​ម៉ឺនុយ"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"បើកម៉ឺនុយ"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 423e8d53a654..88a29df525e9 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ಬಬಲ್"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ನಿರ್ವಹಿಸಿ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ಬಬಲ್ ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"ಬಬಲ್ಸ್"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"ಬಬಲ್ಸ್ ತೋರಿಸಿ"</string>
<string name="restart_button_description" msgid="4564728020654658478">"ಉತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಈ ಆ್ಯಪ್‌ನ ದೃಶ್ಯಾನುಪಾತವನ್ನು ಬದಲಾಯಿಸಿ"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ದೃಶ್ಯಾನುಪಾತವನ್ನು ಬದಲಾಯಿಸಿ"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"ಫ್ಲೋಟ್"</string>
<string name="select_text" msgid="5139083974039906583">"ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"ಬ್ರೌಸರ್‌ನಲ್ಲಿ ತೆರೆಯಿರಿ"</string>
<string name="close_text" msgid="4986518933445178928">"ಮುಚ್ಚಿ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ಮೆನು ಮುಚ್ಚಿ"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"ಮೆನು ತೆರೆಯಿರಿ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 0d1c6216776b..a22667d83858 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"버블"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"관리"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"대화창을 닫았습니다."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"대화창"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"대화창 표시"</string>
<string name="restart_button_description" msgid="4564728020654658478">"탭하면 앱을 다시 시작하여 보기를 개선합니다."</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"설정에서 앱의 가로세로 비율을 변경합니다."</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"가로세로 비율 변경"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"플로팅"</string>
<string name="select_text" msgid="5139083974039906583">"선택"</string>
<string name="screenshot_text" msgid="1477704010087786671">"스크린샷"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"닫기"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"메뉴 닫기"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"메뉴 열기"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index f17e9ca891c0..289d930ecedd 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Көбүк"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Башкаруу"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Калкып чыкма билдирме жабылды."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Калкып чыкма билдирмелер"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Калкып чыкма билдирмелерди көрсөтүү"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Жакшыраак көрүү үчүн бул колдонмону өчүрүп күйгүзүңүз. Ал үчүн таптап коюңуз"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Бул колдонмонун тараптарынын катнашын параметрлерден өзгөртүү"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Тараптардын катнашын өзгөртүү"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Калкыма"</string>
<string name="select_text" msgid="5139083974039906583">"Тандоо"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Серепчиден ачуу"</string>
<string name="close_text" msgid="4986518933445178928">"Жабуу"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Менюну жабуу"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Менюну ачуу"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 195e4d56a1c1..0b84d2c45957 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ຟອງ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ຈັດການ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ປິດ Bubble ໄສ້ແລ້ວ."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"ຟອງ"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"ສະແດງຟອງ"</string>
<string name="restart_button_description" msgid="4564728020654658478">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ເພື່ອມຸມມອງທີ່ດີຂຶ້ນ"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ປ່ຽນອັດຕາສ່ວນຂອງແອັບນີ້ໃນການຕັ້ງຄ່າ"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ປ່ຽນອັດຕາສ່ວນ"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"ລອຍ"</string>
<string name="select_text" msgid="5139083974039906583">"ເລືອກ"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ຮູບໜ້າຈໍ"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"ເປີດໃນໂປຣແກຣມທ່ອງເວັບ"</string>
<string name="close_text" msgid="4986518933445178928">"ປິດ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ປິດເມນູ"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"ເປີດເມນູ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 63ad580a81cc..5b0e6b7a7047 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Debesėlis"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Tvarkyti"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Debesėlio atsisakyta."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Burbulai"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Rodyti burbulus"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Palieskite, kad iš naujo paleistumėte šią programą ir matytumėte aiškiau"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Pakeiskite šios programos kraštinių santykį"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Keisti kraštinių santykį"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Slankusis langas"</string>
<string name="select_text" msgid="5139083974039906583">"Pasirinkti"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Ekrano kopija"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Uždaryti"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Uždaryti meniu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Atidaryti meniu"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 268d89324f54..704b2ed43f92 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Burbulis"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Pārvaldīt"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbulis ir noraidīts."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Burbuļi"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Rādīt burbuļus"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Pieskarieties, lai restartētu šo lietotni un uzlabotu attēlojumu."</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Iestatījumos mainiet šīs lietotnes malu attiecību."</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Mainīt malu attiecību"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Peldošs"</string>
<string name="select_text" msgid="5139083974039906583">"Atlasīt"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Ekrānuzņēmums"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Aizvērt"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Aizvērt izvēlni"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Atvērt izvēlni"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 0a0027fa1bae..b257f802f294 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Управувајте"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отфрлено."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Балончиња"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Прикажи „Балончиња“"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Допрете за да ја рестартирате апликацијава за подобар приказ"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Промени го соодносот на апликацијава во „Поставки“"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Променување на соодносот"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Лебдечко"</string>
<string name="select_text" msgid="5139083974039906583">"Изберете"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Слика од екранот"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Затворете"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворете го менито"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Отвори го менито"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 07809e1a0014..2efd983b3342 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ബബിൾ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"മാനേജ് ചെയ്യുക"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ബബിൾ ഡിസ്മിസ് ചെയ്തു."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"ബബിൾ"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"ബബിൾ കാണിക്കുക"</string>
<string name="restart_button_description" msgid="4564728020654658478">"മികച്ച കാഴ്‌ചയ്‌ക്കായി ഈ ആപ്പ് റീസ്‌റ്റാർട്ട് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ഈ ആപ്പിന്റെ വീക്ഷണ അനുപാതം, ക്രമീകരണത്തിൽ മാറ്റുക"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"വീക്ഷണ അനുപാതം മാറ്റുക"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"ഫ്ലോട്ട്"</string>
<string name="select_text" msgid="5139083974039906583">"തിരഞ്ഞെടുക്കുക"</string>
<string name="screenshot_text" msgid="1477704010087786671">"സ്ക്രീൻഷോട്ട്"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"ബ്രൗസറിൽ തുറക്കുക"</string>
<string name="close_text" msgid="4986518933445178928">"അടയ്ക്കുക"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"മെനു അടയ്ക്കുക"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"മെനു തുറക്കുക"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 99bd2dffca53..a343065d2506 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Бөмбөлөг"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Удирдах"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Бөмбөлгийг үл хэрэгссэн."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Бөмбөлгүүд"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Бөмбөлгүүдийг харуулах"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Харагдах байдлыг сайжруулахын тулд энэ аппыг товшиж, дахин эхлүүлнэ үү"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Энэ аппын харьцааг Тохиргоонд өөрчилнө үү"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Харьцааг өөрчлөх"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Хөвөгч"</string>
<string name="select_text" msgid="5139083974039906583">"Сонгох"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Дэлгэцийн агшин"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Хаах"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Цэсийг хаах"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Цэс нээх"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index ac57e0a549b4..ef71e864a809 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापित करा"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल डिसमिस केला."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"बबल"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"बबल दाखवा"</string>
<string name="restart_button_description" msgid="4564728020654658478">"अधिक चांगल्या दृश्यासाठी हे अ‍ॅप रीस्टार्ट करण्याकरिता टॅप करा"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"सेटिंग्ज मध्ये या ॲपचा आस्पेक्ट रेशो बदला"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"आस्पेक्ट रेशो बदला"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string>
<string name="select_text" msgid="5139083974039906583">"निवडा"</string>
<string name="screenshot_text" msgid="1477704010087786671">"स्क्रीनशॉट"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"ब्राउझरमध्ये उघडा"</string>
<string name="close_text" msgid="4986518933445178928">"बंद करा"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनू बंद करा"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"मेनू उघडा"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 6bc2fbb27c51..a9a97d8112c6 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Gelembung"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Urus"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Gelembung diketepikan."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Gelembung"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Tunjukkan Gelembung"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Ketik untuk memulakan semula apl ini untuk mendapatkan paparan yang lebih baik"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Tukar nisbah bidang apl ini dalam Tetapan"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Tukar nisbah bidang"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Terapung"</string>
<string name="select_text" msgid="5139083974039906583">"Pilih"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Tangkapan skrin"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Buka dalam penyemak imbas"</string>
<string name="close_text" msgid="4986518933445178928">"Tutup"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Buka Menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 12c19edcaeb1..781148d83a4a 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ပူဖောင်းဖောက်သံ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"စီမံရန်"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ပူဖောင်းကွက် ဖယ်လိုက်သည်။"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"ပူဖောင်းကွက်"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"ပူဖောင်းကွက်များ ပြပါ"</string>
<string name="restart_button_description" msgid="4564728020654658478">"ပိုကောင်းသောမြင်ကွင်းအတွက် ဤအက်ပ်ပြန်စရန် တို့ပါ"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ဆက်တင်များတွင် ဤအက်ပ်၏အချိုးအစားကို ပြောင်းရန်"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"အချိုးစား ပြောင်းရန်"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"မျှောရန်"</string>
<string name="select_text" msgid="5139083974039906583">"ရွေးရန်"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ပိတ်ရန်"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"မီနူး ပိတ်ရန်"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"မီနူး ဖွင့်ရန်"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 1161eb608405..9dc8501692a6 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen er avvist."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bobler"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Vis bobler"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Trykk for å starte denne appen på nytt og få en bedre visning"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Endre høyde/bredde-forholdet for denne appen i Innstillinger"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Endre høyde/bredde-forholdet"</string>
@@ -117,7 +115,9 @@
<string name="more_button_text" msgid="3655388105592893530">"Mer"</string>
<string name="float_button_text" msgid="9221657008391364581">"Svevende"</string>
<string name="select_text" msgid="5139083974039906583">"Velg"</string>
- <string name="screenshot_text" msgid="1477704010087786671">"Skjermdump"</string>
+ <string name="screenshot_text" msgid="1477704010087786671">"Skjermbilde"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Lukk"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Lukk menyen"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Åpne menyen"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 25d033738c86..7cc4a437905b 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापन गर्नुहोस्"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल हटाइयो।"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"बबलहरू"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"बबलहरू देखाउनुहोस्"</string>
<string name="restart_button_description" msgid="4564728020654658478">"अझ राम्रो भ्यू प्राप्त गर्नका लागि यो एप रिस्टार्ट गर्न ट्याप गर्नुहोस्"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"सेटिङमा गई यो एपको एस्पेक्ट रेसियो परिवर्तन गर्नुहोस्"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"एस्पेक्ट रेसियो परिवर्तन गर्नुहोस्"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string>
<string name="select_text" msgid="5139083974039906583">"चयन गर्नुहोस्"</string>
<string name="screenshot_text" msgid="1477704010087786671">"स्क्रिनसट"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"ब्राउजरमा खोल्नुहोस्"</string>
<string name="close_text" msgid="4986518933445178928">"बन्द गर्नुहोस्"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनु बन्द गर्नुहोस्"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"मेनु खोल्नुहोस्"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 4ad343cb1a4e..7480add2ab0a 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubbel"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Beheren"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubbel gesloten."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bubbels"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Bubbels tonen"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Tik om deze app opnieuw op te starten voor een betere weergave"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Wijzig de beeldverhouding van deze app in Instellingen"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Beeldverhouding wijzigen"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Zwevend"</string>
<string name="select_text" msgid="5139083974039906583">"Selecteren"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Openen in browser"</string>
<string name="close_text" msgid="4986518933445178928">"Sluiten"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menu sluiten"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Menu openen"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index 966d40440ac7..5412bb8c4a85 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ବବଲ୍"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ପରିଚାଳନା କରନ୍ତୁ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ବବଲ୍ ଖାରଜ କରାଯାଇଛି।"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"ବବଲ"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"ବବଲ ଦେଖାନ୍ତୁ"</string>
<string name="restart_button_description" msgid="4564728020654658478">"ଏକ ଆହୁରି ଭଲ ଭ୍ୟୁ ପାଇଁ ଏହି ଆପ ରିଷ୍ଟାର୍ଟ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ସେଟିଂସରେ ଏହି ଆପର ଚଉଡ଼ା ଓ ଉଚ୍ଚତାର ଅନୁପାତ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ଚଉଡ଼ା ଓ ଉଚ୍ଚତାର ଅନୁପାତ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"ଫ୍ଲୋଟ"</string>
<string name="select_text" msgid="5139083974039906583">"ଚୟନ କରନ୍ତୁ"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ସ୍କ୍ରିନସଟ"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ମେନୁ ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"ମେନୁ ଖୋଲନ୍ତୁ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 9feaf41cda7f..abff90d32cc1 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ਬੁਲਬੁਲਾ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ਬਬਲ ਨੂੰ ਖਾਰਜ ਕੀਤਾ ਗਿਆ।"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"ਬਬਲ"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"ਬਬਲ ਦਿਖਾਓ"</string>
<string name="restart_button_description" msgid="4564728020654658478">"ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਵਾਸਤੇ ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਇਸ ਐਪ ਦੇ ਆਕਾਰ ਅਨੁਪਾਤ ਨੂੰ ਬਦਲੋ"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ਆਕਾਰ ਅਨੁਪਾਤ ਬਦਲੋ"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"ਫ਼ਲੋਟ"</string>
<string name="select_text" msgid="5139083974039906583">"ਚੁਣੋ"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ਬੰਦ ਕਰੋ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ਮੀਨੂ ਬੰਦ ਕਰੋ"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"ਮੀਨੂ ਖੋਲ੍ਹੋ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 1c7fbf8e80d3..1c268bd34d55 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Dymek"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Zarządzaj"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Zamknięto dymek"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Dymki"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Pokaż dymki"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Kliknij w celu zrestartowania aplikacji, aby lepiej się wyświetlała."</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Zmień proporcje obrazu aplikacji w Ustawieniach"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Zmień proporcje obrazu"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Pływające"</string>
<string name="select_text" msgid="5139083974039906583">"Wybierz"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Zrzut ekranu"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Otwórz w przeglądarce"</string>
<string name="close_text" msgid="4986518933445178928">"Zamknij"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zamknij menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Otwórz menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 5c2de2ad0d31..82566fedf890 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Balões"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Mostrar balões"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Toque para reiniciar o app e atualizar a visualização"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Mude o tamanho da janela deste app nas Configurações"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Mudar a proporção"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Ponto flutuante"</string>
<string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de tela"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Abrir o menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 6f76525473eb..b2e89182ace4 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Balão"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gerir"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão ignorado."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Balões"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Mostrar balões"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Toque para reiniciar esta app e ficar com uma melhor visão"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Altere o formato desta app nas Definições"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Altere o formato"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Flutuar"</string>
<string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de ecrã"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Abrir menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 5c2de2ad0d31..82566fedf890 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Balões"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Mostrar balões"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Toque para reiniciar o app e atualizar a visualização"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Mude o tamanho da janela deste app nas Configurações"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Mudar a proporção"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Ponto flutuante"</string>
<string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de tela"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Abrir o menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 6e85e7849d95..67dc389816a6 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionează"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balonul a fost respins."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Baloane"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Afișează Baloane"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Atinge ca să repornești aplicația pentru o vizualizare mai bună"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Schimbă raportul de dimensiuni al aplicației din Setări"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Schimbă raportul de dimensiuni"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Flotantă"</string>
<string name="select_text" msgid="5139083974039906583">"Selectează"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captură de ecran"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Închide"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Închide meniul"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Deschide meniul"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 1b41983cd1a3..b2a60302bd1a 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Всплывающая подсказка"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Настроить"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Всплывающий чат закрыт."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Чаты"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Всплывающие чаты"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Нажмите, чтобы перезапустить приложение и оптимизировать размер"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Изменить соотношение сторон приложения в настройках"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Изменить соотношение сторон"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Плавающее окно"</string>
<string name="select_text" msgid="5139083974039906583">"Выбрать"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Открыть в браузере"</string>
<string name="close_text" msgid="4986518933445178928">"Закрыть"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыть меню"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Открыть меню"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 6fd37e91c8b0..34eaad0825f6 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"බුබුළු"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"කළමනා කරන්න"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"බුබුල ඉවත දමා ඇත."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"බුබුළු"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"බුබුළු පෙන්වන්න"</string>
<string name="restart_button_description" msgid="4564728020654658478">"වඩා හොඳ දසුනක් සඳහා මෙම යෙදුම යළි ඇරඹීමට තට්ටු කරන්න"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"සැකසීම් තුළ මෙම යෙදුමේ දර්ශන අනුපාතය වෙනස් කරන්න"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"දර්ශන අනුපාතය වෙනස් කරන්න"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"පාවෙන"</string>
<string name="select_text" msgid="5139083974039906583">"තෝරන්න"</string>
<string name="screenshot_text" msgid="1477704010087786671">"තිර රුව"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"වසන්න"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"මෙනුව වසන්න"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"මෙනුව විවෘත කරන්න"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index dabbf397d38f..4687f39cb308 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovať"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina bola zavretá."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bubliny"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Zobraziť bubliny"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Ak chcete zlepšiť zobrazenie, klepnutím túto aplikáciu reštartujte"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Zmeniť pomer strán tejto aplikácie v Nastaveniach"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Zmeniť pomer strán"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Plávajúce"</string>
<string name="select_text" msgid="5139083974039906583">"Vybrať"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Snímka obrazovky"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zavrieť"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavrieť ponuku"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Otvoriť ponuku"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 3ade33810cc8..5848f9261d9b 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Mehurček"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblaček je bil opuščen."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Oblački"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Prikaži oblačke"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Če želite boljši prikaz, se dotaknite za vnovični zagon te aplikacije."</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Razmerje stranic te aplikacije spremenite v nastavitvah."</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Sprememba razmerja stranic"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Lebdeče"</string>
<string name="select_text" msgid="5139083974039906583">"Izberi"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Posnetek zaslona"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Odpri v brskalniku"</string>
<string name="close_text" msgid="4986518933445178928">"Zapri"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zapri meni"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Odpri meni"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index ee1aa00c5cbe..5f8f97e8b7df 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Flluskë"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Menaxho"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Flluska u hoq."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Flluskat"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Shfaq \"Flluskat\""</string>
<string name="restart_button_description" msgid="4564728020654658478">"Trokit për ta rinisur këtë aplikacion për një pamje më të mirë"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Ndrysho raportin e pamjes së këtij aplikacioni te \"Cilësimet\""</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Ndrysho raportin e pamjes"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Pluskuese"</string>
<string name="select_text" msgid="5139083974039906583">"Zgjidh"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Pamja e ekranit"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Mbyll"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Mbyll menynë"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Hap menynë"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index b2868ca84dac..8402eef99c38 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Облачић"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Управљајте"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Облачић је одбачен."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Облачићи"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Прикажи облачиће"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Додирните да бисте рестартовали ову апликацију ради бољег приказа"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Промените размеру ове апликације у Подешавањима"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Промени размеру"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Плутајуће"</string>
<string name="select_text" msgid="5139083974039906583">"Изаберите"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Снимак екрана"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Отворите у прегледачу"</string>
<string name="close_text" msgid="4986518933445178928">"Затворите"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворите мени"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Отворите мени"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 66118efd5da7..a991152ddc06 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubbla"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Hantera"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubblan ignorerades."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bubblor"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Visa bubblor"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Tryck för att starta om appen och få en bättre vy"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Ändra appens bildformat i inställningarna"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Ändra bildformat"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Svävande"</string>
<string name="select_text" msgid="5139083974039906583">"Välj"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Skärmbild"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Stäng"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Stäng menyn"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Öppna menyn"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 863b49b1f010..94ea2f2ad02e 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Kiputo"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Dhibiti"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Umeondoa kiputo."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Viputo"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Onyesha Viputo"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Gusa ili uzime kisha uwashe programu hii, ili upate mwonekano bora"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Badilisha uwiano wa programu hii katika Mipangilio"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Badilisha uwiano wa kipengele"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Inayoelea"</string>
<string name="select_text" msgid="5139083974039906583">"Chagua"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Picha ya skrini"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Funga"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Funga Menyu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Fungua Menyu"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 74e0207bf62e..866fe568c470 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"பபிள்"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"நிர்வகி"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"குமிழ் நிராகரிக்கப்பட்டது."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"குமிழ்கள்"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"குமிழ்களைக் காட்டு"</string>
<string name="restart_button_description" msgid="4564728020654658478">"இங்கு தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கி, ஆப்ஸ் காட்டப்படும் விதத்தை இன்னும் சிறப்பாக்கலாம்"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"அமைப்புகளில் இந்த ஆப்ஸின் தோற்ற விகிதத்தை மாற்றும்"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"தோற்ற விகிதத்தை மாற்றும்"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"மிதக்கும் சாளரம்"</string>
<string name="select_text" msgid="5139083974039906583">"தேர்ந்தெடுக்கும்"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ஸ்கிரீன்ஷாட்"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"மூடும்"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"மெனுவை மூடும்"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"மெனுவைத் திற"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 35711567e760..ef094fcc8e64 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"బబుల్"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"మేనేజ్ చేయండి"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"బబుల్ విస్మరించబడింది."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"బబుల్స్"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"బబుల్స్ చూడండి"</string>
<string name="restart_button_description" msgid="4564728020654658478">"మెరుగైన వీక్షణ కోసం ఈ యాప్‌ను రీస్టార్ట్ చేయడానికి ట్యాప్ చేయండి"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"సెట్టింగ్‌లలో ఈ యాప్ ఆకార నిష్పత్తిని మార్చండి"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ఆకార నిష్పత్తిని మార్చండి"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"ఫ్లోట్"</string>
<string name="select_text" msgid="5139083974039906583">"ఎంచుకోండి"</string>
<string name="screenshot_text" msgid="1477704010087786671">"స్క్రీన్‌షాట్"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"బ్రౌజర్‌లో తెరవండి"</string>
<string name="close_text" msgid="4986518933445178928">"మూసివేయండి"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"మెనూను మూసివేయండి"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"మెనూను తెరవండి"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 47694164270e..762a81a0305a 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"บับเบิล"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"จัดการ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ปิดบับเบิลแล้ว"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"บับเบิล"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"แสดงบับเบิล"</string>
<string name="restart_button_description" msgid="4564728020654658478">"แตะเพื่อรีสตาร์ทแอปนี้และรับมุมมองที่ดียิ่งขึ้น"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"เปลี่ยนสัดส่วนภาพของแอปนี้ในการตั้งค่า"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"เปลี่ยนอัตราส่วนกว้างยาว"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"ล่องลอย"</string>
<string name="select_text" msgid="5139083974039906583">"เลือก"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ภาพหน้าจอ"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"เปิดในเบราว์เซอร์"</string>
<string name="close_text" msgid="4986518933445178928">"ปิด"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ปิดเมนู"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"เปิดเมนู"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index be18d88194c1..418f500aac80 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Pamahalaan"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Na-dismiss na ang bubble."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Mga Bubble"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Ipakita ang Mga Bubble"</string>
<string name="restart_button_description" msgid="4564728020654658478">"I-tap para i-restart ang app na ito para sa mas magandang view"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Baguhin ang aspect ratio ng app na ito sa Mga Setting"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Baguhin ang aspect ratio"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
<string name="select_text" msgid="5139083974039906583">"Piliin"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Buksan sa browser"</string>
<string name="close_text" msgid="4986518933445178928">"Isara"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Isara ang Menu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Buksan ang Menu"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 4c8c53610711..e70f1708fb75 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Baloncuk"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Yönet"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon kapatıldı."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Baloncuklar"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Baloncukları göster"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Bu uygulamayı yeniden başlatarak daha iyi bir görünüm elde etmek için dokunun"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Bu uygulamanın en boy oranını Ayarlar\'dan değiştirin"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"En boy oranını değiştir"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Havada Süzülen"</string>
<string name="select_text" msgid="5139083974039906583">"Seç"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Ekran görüntüsü"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Kapat"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menüyü kapat"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Menüyü Aç"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index 7cc1a0406f97..b243a153af8f 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Спливаюче сповіщення"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Налаштувати"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Спливаюче сповіщення закрито."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Спл. чати"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Показувати спливаючі чати"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Натисніть, щоб перезапустити цей додаток для зручнішого перегляду"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Змінити формат для цього додатка в налаштуваннях"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Змінити формат"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Плаваюче вікно"</string>
<string name="select_text" msgid="5139083974039906583">"Вибрати"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Знімок екрана"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Закрити"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрити меню"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Відкрити меню"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 8b9f29969d80..2cf9f325892d 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"بلبلہ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"نظم کریں"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"بلبلہ برخاست کر دیا گیا۔"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"بلبلے"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"بلبلے دکھائیں"</string>
<string name="restart_button_description" msgid="4564728020654658478">"بہتر منظر کے لیے اس ایپ کو ری اسٹارٹ کرنے کی خاطر تھپتھپائیں"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ترتیبات میں اس ایپ کی تناسبی شرح کو تبدیل کریں"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"تناسبی شرح کو تبدیل کریں"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"فلوٹ"</string>
<string name="select_text" msgid="5139083974039906583">"منتخب کریں"</string>
<string name="screenshot_text" msgid="1477704010087786671">"اسکرین شاٹ"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"براؤزر میں کھولیں"</string>
<string name="close_text" msgid="4986518933445178928">"بند کریں"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"مینیو بند کریں"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"مینو کھولیں"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 55c6b32c909b..f8cd43f9d6fa 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Pufaklar"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Boshqarish"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulutcha yopildi."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bulutchalar"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Bulutchalarni chiqarish"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Yaxshiroq koʻrish maqsadida bu ilovani qayta ishga tushirish uchun bosing"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Sozlamalar orqali bu ilovaning tomonlar nisbatini oʻzgartiring"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Tomonlar nisbatini oʻzgartirish"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Pufakli"</string>
<string name="select_text" msgid="5139083974039906583">"Tanlash"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Skrinshot"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Brauzerda ochish"</string>
<string name="close_text" msgid="4986518933445178928">"Yopish"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyuni yopish"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Menyuni ochish"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 07a6b6f6c2b4..a813b265a4dc 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bong bóng"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Quản lý"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Đã đóng bong bóng."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bong bóng"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Hiện bong bóng"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Nhấn nút khởi động lại ứng dụng này để xem dễ hơn"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Thay đổi tỷ lệ khung hình của ứng dụng này thông qua phần Cài đặt"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Thay đổi tỷ lệ khung hình"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"Nổi"</string>
<string name="select_text" msgid="5139083974039906583">"Chọn"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Ảnh chụp màn hình"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Đóng"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Đóng trình đơn"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Mở Trình đơn"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 908095a163a7..6f21fdfa250e 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"气泡"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已关闭消息气泡。"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"消息气泡"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"显示消息气泡"</string>
<string name="restart_button_description" msgid="4564728020654658478">"点按即可重启此应用,获得更好的视觉体验"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"在“设置”中更改此应用的宽高比"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"更改高宽比"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"悬浮"</string>
<string name="select_text" msgid="5139083974039906583">"选择"</string>
<string name="screenshot_text" msgid="1477704010087786671">"屏幕截图"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"关闭"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"关闭菜单"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"打开菜单"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index c8550b4e0611..159db8f0e82d 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"氣泡"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"對話氣泡已關閉。"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"對話氣泡"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"顯示對話氣泡"</string>
<string name="restart_button_description" msgid="4564728020654658478">"輕按並重新啟動此應用程式,以取得更佳的觀看體驗"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"前往「設定」變更此應用程式的長寬比"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"變更長寬比"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"浮動"</string>
<string name="select_text" msgid="5139083974039906583">"選取"</string>
<string name="screenshot_text" msgid="1477704010087786671">"螢幕截圖"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"關閉"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"打開選單"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 67048335de64..8a1b2bf2b14e 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"泡泡"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已關閉泡泡。"</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"對話框"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"顯示對話框"</string>
<string name="restart_button_description" msgid="4564728020654658478">"輕觸此按鈕重新啟動這個應用程式,即可獲得更良好的觀看體驗"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"前往「設定」變更這個應用程式的顯示比例"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"變更顯示比例"</string>
@@ -118,6 +116,8 @@
<string name="float_button_text" msgid="9221657008391364581">"浮動"</string>
<string name="select_text" msgid="5139083974039906583">"選取"</string>
<string name="screenshot_text" msgid="1477704010087786671">"螢幕截圖"</string>
+ <!-- no translation found for open_in_browser_text (9181692926376072904) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"關閉"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"開啟選單"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 96b4faec06b8..ba3df301df54 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Ibhamuza"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Phatha"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ibhamuza licashisiwe."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Amabhamuza"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Bonisa Amabhamuza"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Thepha ukuze uqale kabusha le app ukuze ibonakale kangcono"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Shintsha ukubukeka kwesilinganiselo kwe-app kuMasethingi"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Shintsha ukubukeka kwesilinganiselo"</string>
@@ -118,6 +116,7 @@
<string name="float_button_text" msgid="9221657008391364581">"Iflowuthi"</string>
<string name="select_text" msgid="5139083974039906583">"Khetha"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Isithombe-skrini"</string>
+ <string name="open_in_browser_text" msgid="9181692926376072904">"Vula kubhrawuza"</string>
<string name="close_text" msgid="4986518933445178928">"Vala"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Vala Imenyu"</string>
<string name="expand_menu_text" msgid="3847736164494181168">"Vula Imenyu"</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 595d34664cfa..269a58693a24 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -495,9 +495,16 @@
<!-- The radius of the Maximize menu shadow. -->
<dimen name="desktop_mode_maximize_menu_shadow_radius">8dp</dimen>
- <!-- The width of the handle menu in desktop mode. -->
+ <!-- The width of the handle menu in desktop mode. -->
<dimen name="desktop_mode_handle_menu_width">216dp</dimen>
+ <!-- The maximum height of the handle menu in desktop mode. Four pills (52dp each) plus 2dp
+ spacing between them plus 4dp top padding. -->
+ <dimen name="desktop_mode_handle_menu_height">218dp</dimen>
+
+ <!-- The elevation set on the handle menu pills. -->
+ <dimen name="desktop_mode_handle_menu_pill_elevation">1dp</dimen>
+
<!-- The height of the handle menu's "App Info" pill in desktop mode. -->
<dimen name="desktop_mode_handle_menu_app_info_pill_height">52dp</dimen>
@@ -507,8 +514,11 @@
<!-- The height of the handle menu's "More Actions" pill in desktop mode. -->
<dimen name="desktop_mode_handle_menu_more_actions_pill_height">52dp</dimen>
- <!-- The height of the handle menu in desktop mode. -->
- <dimen name="desktop_mode_handle_menu_height">328dp</dimen>
+ <!-- The height of the handle menu's "Open in browser" pill in desktop mode. -->
+ <dimen name="desktop_mode_handle_menu_open_in_browser_pill_height">52dp</dimen>
+
+ <!-- The margin between pills of the handle menu in desktop mode. -->
+ <dimen name="desktop_mode_handle_menu_pill_spacing_margin">2dp</dimen>
<!-- The top margin of the handle menu in desktop mode. -->
<dimen name="desktop_mode_handle_menu_margin_top">4dp</dimen>
@@ -516,9 +526,6 @@
<!-- The start margin of the handle menu in desktop mode. -->
<dimen name="desktop_mode_handle_menu_margin_start">6dp</dimen>
- <!-- The margin between pills of the handle menu in desktop mode. -->
- <dimen name="desktop_mode_handle_menu_pill_spacing_margin">2dp</dimen>
-
<!-- The radius of the caption menu corners. -->
<dimen name="desktop_mode_handle_menu_corner_radius">26dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 47846746b205..4e7cfb638a12 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -280,6 +280,8 @@
<string name="select_text">Select</string>
<!-- Accessibility text for the handle menu screenshot button [CHAR LIMIT=NONE] -->
<string name="screenshot_text">Screenshot</string>
+ <!-- Accessibility text for the handle menu open in browser button [CHAR LIMIT=NONE] -->
+ <string name="open_in_browser_text">Open in browser</string>
<!-- Accessibility text for the handle menu close button [CHAR LIMIT=NONE] -->
<string name="close_text">Close</string>
<!-- Accessibility text for the handle menu close menu button [CHAR LIMIT=NONE] -->
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
new file mode 100644
index 000000000000..f0d80a02243a
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
@@ -0,0 +1,154 @@
+/*
+ * 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.wm.shell.shared.desktopmode
+
+import android.content.Context
+import android.provider.Settings
+import android.util.Log
+import com.android.window.flags.Flags
+
+/*
+ * A shared class to check desktop mode flags state.
+ *
+ * The class computes whether a Desktop Windowing flag should be enabled by using the aconfig flag
+ * value and the developer option override state (if applicable).
+ **/
+enum class DesktopModeFlags(
+ // Function called to obtain aconfig flag value.
+ private val flagFunction: () -> Boolean,
+ // Whether the flag state should be affected by developer option.
+ private val shouldOverrideByDevOption: Boolean
+) {
+ // All desktop mode related flags will be added here
+ DESKTOP_WINDOWING_MODE(Flags::enableDesktopWindowingMode, true),
+ WALLPAPER_ACTIVITY(Flags::enableDesktopWindowingWallpaperActivity, true);
+
+ /**
+ * Determines state of flag based on the actual flag and desktop mode developer option overrides.
+ *
+ * Note, this method makes sure that a constant developer toggle overrides is read until reboot.
+ */
+ fun isEnabled(context: Context): Boolean =
+ if (!Flags.showDesktopWindowingDevOption() ||
+ !shouldOverrideByDevOption ||
+ context.contentResolver == null) {
+ flagFunction()
+ } else {
+ val shouldToggleBeEnabledByDefault = DesktopModeStatus.shouldDevOptionBeEnabledByDefault()
+ when (getToggleOverride(context)) {
+ ToggleOverride.OVERRIDE_UNSET -> flagFunction()
+ // When toggle override matches its default state, don't override flags. This helps users
+ // reset their feature overrides.
+ ToggleOverride.OVERRIDE_OFF ->
+ if (shouldToggleBeEnabledByDefault) false else flagFunction()
+ ToggleOverride.OVERRIDE_ON -> if (shouldToggleBeEnabledByDefault) flagFunction() else true
+ }
+ }
+
+ private fun getToggleOverride(context: Context): ToggleOverride {
+ val override =
+ cachedToggleOverride
+ ?: run {
+ val override = getToggleOverrideFromSystem(context)
+ // Cache toggle override the first time we encounter context. Override does not change
+ // with context, as context is just used to fetch System Property and Settings.Global
+ cachedToggleOverride = override
+ Log.d(TAG, "Toggle override initialized to: $override")
+ override
+ }
+
+ return override
+ }
+
+ private fun getToggleOverrideFromSystem(context: Context): ToggleOverride {
+ // A non-persistent System Property is used to store override to ensure it remains
+ // constant till reboot.
+ val overrideFromSystemProperties: ToggleOverride? =
+ System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, null).convertToToggleOverride()
+ return overrideFromSystemProperties
+ ?: run {
+ // Read Setting Global if System Property is not present (just after reboot)
+ // or not valid (user manually changed the value)
+ val overrideFromSettingsGlobal =
+ convertToToggleOverrideWithFallback(
+ Settings.Global.getInt(
+ context.contentResolver,
+ Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES,
+ ToggleOverride.OVERRIDE_UNSET.setting),
+ ToggleOverride.OVERRIDE_UNSET)
+ // Initialize System Property
+ System.setProperty(
+ SYSTEM_PROPERTY_OVERRIDE_KEY, overrideFromSettingsGlobal.setting.toString())
+
+ overrideFromSettingsGlobal
+ }
+ }
+
+ /**
+ * Override state of desktop mode developer option toggle.
+ *
+ * @property setting The integer value that is associated with the developer option toggle
+ * override
+ */
+ enum class ToggleOverride(val setting: Int) {
+ /** No override is set. */
+ OVERRIDE_UNSET(-1),
+ /** Override to off. */
+ OVERRIDE_OFF(0),
+ /** Override to on. */
+ OVERRIDE_ON(1)
+ }
+
+ private fun String?.convertToToggleOverride(): ToggleOverride? {
+ val intValue = this?.toIntOrNull() ?: return null
+ return settingToToggleOverrideMap[intValue]
+ ?: run {
+ Log.w(TAG, "Unknown toggleOverride int $intValue")
+ null
+ }
+ }
+
+ companion object {
+ private const val TAG = "DesktopModeFlags"
+
+ /**
+ * Key for non-persistent System Property which is used to store desktop windowing developer
+ * option overrides.
+ */
+ private const val SYSTEM_PROPERTY_OVERRIDE_KEY = "sys.wmshell.desktopmode.dev_toggle_override"
+
+ /**
+ * Local cache for toggle override, which is initialized once on its first access. It needs to
+ * be refreshed only on reboots as overridden state takes effect on reboots.
+ */
+ private var cachedToggleOverride: ToggleOverride? = null
+
+ private val settingToToggleOverrideMap = ToggleOverride.entries.associateBy { it.setting }
+
+ @JvmStatic
+ fun convertToToggleOverrideWithFallback(
+ overrideInt: Int,
+ fallbackOverride: ToggleOverride
+ ): ToggleOverride {
+ return settingToToggleOverrideMap[overrideInt]
+ ?: run {
+ Log.w(TAG, "Unknown toggleOverride int $overrideInt")
+ fallbackOverride
+ }
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
index 92084e403846..fc4710f8f67b 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
@@ -14,15 +14,11 @@
* limitations under the License.
*/
-package com.android.wm.shell.shared;
-
-import static android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES;
+package com.android.wm.shell.shared.desktopmode;
import android.annotation.NonNull;
import android.content.Context;
import android.os.SystemProperties;
-import android.provider.Settings;
-import android.util.Log;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -31,6 +27,7 @@ import com.android.window.flags.Flags;
/**
* Constants for desktop mode feature
*/
+// TODO(b/237575897): Move this file to the `com.android.wm.shell.shared.desktopmode` package
public class DesktopModeStatus {
private static final String TAG = "DesktopModeStatus";
@@ -104,16 +101,6 @@ public class DesktopModeStatus {
"persist.wm.debug.desktop_max_task_limit", DEFAULT_MAX_TASK_LIMIT);
/**
- * Return {@code true} if desktop windowing flag is enabled. Only to be used for testing.
- * Callers should use {@link #canEnterDesktopMode(Context)} to query the state of desktop
- * windowing.
- */
- @VisibleForTesting
- public static boolean isDesktopModeFlagEnabled() {
- return Flags.enableDesktopWindowingMode();
- }
-
- /**
* Return {@code true} if veiled resizing is active. If false, fluid resizing is used.
*/
public static boolean isVeiledResizeEnabled() {
@@ -169,7 +156,7 @@ public class DesktopModeStatus {
/** Returns if desktop mode dev option should be enabled if there is no user override. */
public static boolean shouldDevOptionBeEnabledByDefault() {
- return isDesktopModeFlagEnabled();
+ return Flags.enableDesktopWindowingMode();
}
/**
@@ -178,19 +165,7 @@ public class DesktopModeStatus {
public static boolean canEnterDesktopMode(@NonNull Context context) {
if (!isDeviceEligibleForDesktopMode(context)) return false;
- // If dev option has ever been manually toggled by the user, return its value
- // TODO(b/348193756) : Move the logic for DW override based on toggle overides to a common
- // infrastructure and add caching for the computation
- int defaultOverrideState = -1;
- int toggleState = Settings.Global.getInt(context.getContentResolver(),
- DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, defaultOverrideState);
- if (toggleState != defaultOverrideState) {
- Log.d(TAG, "Using Desktop mode dev option overridden state");
- return toggleState != 0;
- }
-
- // Return Desktop windowing flag value
- return isDesktopModeFlagEnabled();
+ return DesktopModeFlags.DESKTOP_WINDOWING_MODE.isEnabled(context);
}
/**
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/OWNERS b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/OWNERS
new file mode 100644
index 000000000000..2fabd4a33586
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/OWNERS
@@ -0,0 +1 @@
+file:/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index ebdea1bba942..f014e559d4b4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -24,6 +24,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static com.android.wm.shell.compatui.impl.CompatUIEventsKt.CAMERA_CONTROL_STATE_UPDATE;
+import static com.android.wm.shell.compatui.impl.CompatUIEventsKt.SIZE_COMPAT_RESTART_BUTTON_APPEARED;
+import static com.android.wm.shell.compatui.impl.CompatUIEventsKt.SIZE_COMPAT_RESTART_BUTTON_CLICKED;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
@@ -31,7 +34,6 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager.RunningTaskInfo;
-import android.app.CameraCompatTaskInfo.CameraCompatControlState;
import android.app.TaskInfo;
import android.app.WindowConfiguration;
import android.content.LocusId;
@@ -57,6 +59,11 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.wm.shell.common.ScreenshotUtils;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.compatui.CompatUIController;
+import com.android.wm.shell.compatui.api.CompatUIHandler;
+import com.android.wm.shell.compatui.api.CompatUIInfo;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.CameraControlStateUpdated;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonAppeared;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonClicked;
import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.startingsurface.StartingWindowController;
import com.android.wm.shell.sysui.ShellCommandHandler;
@@ -75,8 +82,7 @@ import java.util.function.Consumer;
* Unified task organizer for all components in the shell.
* TODO(b/167582004): may consider consolidating this class and TaskOrganizer
*/
-public class ShellTaskOrganizer extends TaskOrganizer implements
- CompatUIController.CompatUICallback {
+public class ShellTaskOrganizer extends TaskOrganizer {
private static final String TAG = "ShellTaskOrganizer";
// Intentionally using negative numbers here so the positive numbers can be used
@@ -194,12 +200,11 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
* In charge of showing compat UI. Can be {@code null} if the device doesn't support size
* compat or if this isn't the main {@link ShellTaskOrganizer}.
*
- * <p>NOTE: only the main {@link ShellTaskOrganizer} should have a {@link CompatUIController},
- * and register itself as a {@link CompatUIController.CompatUICallback}. Subclasses should be
- * initialized with a {@code null} {@link CompatUIController}.
+ * <p>NOTE: only the main {@link ShellTaskOrganizer} should have a {@link CompatUIHandler},
+ * Subclasses should be initialized with a {@code null} {@link CompatUIHandler}.
*/
@Nullable
- private final CompatUIController mCompatUI;
+ private final CompatUIHandler mCompatUI;
@NonNull
private final ShellCommandHandler mShellCommandHandler;
@@ -223,7 +228,7 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
public ShellTaskOrganizer(ShellInit shellInit,
ShellCommandHandler shellCommandHandler,
- @Nullable CompatUIController compatUI,
+ @Nullable CompatUIHandler compatUI,
Optional<UnfoldAnimationController> unfoldAnimationController,
Optional<RecentTasksController> recentTasks,
ShellExecutor mainExecutor) {
@@ -235,7 +240,7 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
protected ShellTaskOrganizer(ShellInit shellInit,
ShellCommandHandler shellCommandHandler,
ITaskOrganizerController taskOrganizerController,
- @Nullable CompatUIController compatUI,
+ @Nullable CompatUIHandler compatUI,
Optional<UnfoldAnimationController> unfoldAnimationController,
Optional<RecentTasksController> recentTasks,
ShellExecutor mainExecutor) {
@@ -252,7 +257,21 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
private void onInit() {
mShellCommandHandler.addDumpCallback(this::dump, this);
if (mCompatUI != null) {
- mCompatUI.setCompatUICallback(this);
+ mCompatUI.setCallback(compatUIEvent -> {
+ switch(compatUIEvent.getEventId()) {
+ case SIZE_COMPAT_RESTART_BUTTON_APPEARED:
+ onSizeCompatRestartButtonAppeared(compatUIEvent.asType());
+ break;
+ case SIZE_COMPAT_RESTART_BUTTON_CLICKED:
+ onSizeCompatRestartButtonClicked(compatUIEvent.asType());
+ break;
+ case CAMERA_CONTROL_STATE_UPDATE:
+ onCameraControlStateUpdated(compatUIEvent.asType());
+ break;
+ default:
+
+ }
+ });
}
registerOrganizer();
}
@@ -680,6 +699,22 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
}
}
+ /**
+ * Shows/hides the given task surface. Not for general use as changing the task visibility may
+ * conflict with other Transitions. This is currently ONLY used to temporarily hide a task
+ * while a drag is in session.
+ */
+ public void setTaskSurfaceVisibility(int taskId, boolean visible) {
+ synchronized (mLock) {
+ final TaskAppearedInfo info = mTasks.get(taskId);
+ if (info != null) {
+ SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ t.setVisibility(info.getLeash(), visible);
+ t.apply();
+ }
+ }
+ }
+
private boolean updateTaskListenerIfNeeded(RunningTaskInfo taskInfo, SurfaceControl leash,
TaskListener oldListener, TaskListener newListener) {
if (oldListener == newListener) return false;
@@ -727,8 +762,26 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
}
}
- @Override
- public void onSizeCompatRestartButtonAppeared(int taskId) {
+ /** Reparents a child window surface to the task surface. */
+ public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+ SurfaceControl.Transaction t) {
+ final TaskListener taskListener;
+ synchronized (mLock) {
+ taskListener = mTasks.contains(taskId)
+ ? getTaskListener(mTasks.get(taskId).getTaskInfo())
+ : null;
+ }
+ if (taskListener == null) {
+ ProtoLog.w(WM_SHELL_TASK_ORG, "Failed to find Task to reparent surface taskId=%d",
+ taskId);
+ return;
+ }
+ taskListener.reparentChildSurfaceToTask(taskId, sc, t);
+ }
+
+ @VisibleForTesting
+ void onSizeCompatRestartButtonAppeared(@NonNull SizeCompatRestartButtonAppeared compatUIEvent) {
+ final int taskId = compatUIEvent.getTaskId();
final TaskAppearedInfo info;
synchronized (mLock) {
info = mTasks.get(taskId);
@@ -740,8 +793,9 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
FrameworkStatsLog.SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED__EVENT__APPEARED);
}
- @Override
- public void onSizeCompatRestartButtonClicked(int taskId) {
+ @VisibleForTesting
+ void onSizeCompatRestartButtonClicked(@NonNull SizeCompatRestartButtonClicked compatUIEvent) {
+ final int taskId = compatUIEvent.getTaskId();
final TaskAppearedInfo info;
synchronized (mLock) {
info = mTasks.get(taskId);
@@ -754,8 +808,10 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
restartTaskTopActivityProcessIfVisible(info.getTaskInfo().token);
}
- @Override
- public void onCameraControlStateUpdated(int taskId, @CameraCompatControlState int state) {
+ @VisibleForTesting
+ void onCameraControlStateUpdated(@NonNull CameraControlStateUpdated compatUIEvent) {
+ final int taskId = compatUIEvent.getTaskId();
+ final int state = compatUIEvent.getState();
final TaskAppearedInfo info;
synchronized (mLock) {
info = mTasks.get(taskId);
@@ -766,22 +822,6 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
updateCameraCompatControlState(info.getTaskInfo().token, state);
}
- /** Reparents a child window surface to the task surface. */
- public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
- SurfaceControl.Transaction t) {
- final TaskListener taskListener;
- synchronized (mLock) {
- taskListener = mTasks.contains(taskId)
- ? getTaskListener(mTasks.get(taskId).getTaskInfo())
- : null;
- }
- if (taskListener == null) {
- ProtoLog.w(WM_SHELL_TASK_ORG, "Failed to find Task to reparent surface taskId=%d",
- taskId);
- return;
- }
- taskListener.reparentChildSurfaceToTask(taskId, sc, t);
- }
private void logSizeCompatRestartButtonEventReported(@NonNull TaskAppearedInfo info,
int event) {
@@ -810,10 +850,10 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
// on this Task if there is any.
if (taskListener == null || !taskListener.supportCompatUI()
|| !taskInfo.appCompatTaskInfo.hasCompatUI() || !taskInfo.isVisible) {
- mCompatUI.onCompatInfoChanged(taskInfo, null /* taskListener */);
+ mCompatUI.onCompatInfoChanged(new CompatUIInfo(taskInfo, null /* taskListener */));
return;
}
- mCompatUI.onCompatInfoChanged(taskInfo, taskListener);
+ mCompatUI.onCompatInfoChanged(new CompatUIInfo(taskInfo, taskListener));
}
private TaskListener getTaskListener(RunningTaskInfo runningTaskInfo) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index d270d2b4ccf1..5696a544152c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -266,6 +266,9 @@ class ActivityEmbeddingAnimationRunner {
final Animation animation =
animationProvider.get(info, change, openingWholeScreenBounds);
if (shouldUseJumpCutForAnimation(animation)) {
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ return new ArrayList<>();
+ }
continue;
}
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
@@ -291,6 +294,9 @@ class ActivityEmbeddingAnimationRunner {
final Animation animation =
animationProvider.get(info, change, closingWholeScreenBounds);
if (shouldUseJumpCutForAnimation(animation)) {
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ return new ArrayList<>();
+ }
continue;
}
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
index f49b90d08a75..3046307702c2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
@@ -97,7 +97,7 @@ class ActivityEmbeddingAnimationSpec {
Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- final Animation customAnimation = loadCustomAnimation(info, change);
+ final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
if (customAnimation != null) {
return customAnimation;
}
@@ -131,7 +131,7 @@ class ActivityEmbeddingAnimationSpec {
Animation createChangeBoundsCloseAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- final Animation customAnimation = loadCustomAnimation(info, change);
+ final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
if (customAnimation != null) {
return customAnimation;
}
@@ -172,7 +172,7 @@ class ActivityEmbeddingAnimationSpec {
// TODO(b/293658614): Support more complicated animations that may need more than a noop
// animation as the start leash.
final Animation noopAnimation = createNoopAnimation(change);
- final Animation customAnimation = loadCustomAnimation(info, change);
+ final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
if (customAnimation != null) {
return new Animation[]{noopAnimation, customAnimation};
}
@@ -227,7 +227,7 @@ class ActivityEmbeddingAnimationSpec {
Animation loadOpenAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) {
final boolean isEnter = TransitionUtil.isOpeningType(change.getMode());
- final Animation customAnimation = loadCustomAnimation(info, change);
+ final Animation customAnimation = loadCustomAnimation(info, change, change.getMode());
final Animation animation;
if (customAnimation != null) {
animation = customAnimation;
@@ -254,7 +254,7 @@ class ActivityEmbeddingAnimationSpec {
Animation loadCloseAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) {
final boolean isEnter = TransitionUtil.isOpeningType(change.getMode());
- final Animation customAnimation = loadCustomAnimation(info, change);
+ final Animation customAnimation = loadCustomAnimation(info, change, change.getMode());
final Animation animation;
if (customAnimation != null) {
animation = customAnimation;
@@ -287,14 +287,14 @@ class ActivityEmbeddingAnimationSpec {
@Nullable
private Animation loadCustomAnimation(@NonNull TransitionInfo info,
- @NonNull TransitionInfo.Change change) {
+ @NonNull TransitionInfo.Change change, @WindowManager.TransitionType int mode) {
final TransitionInfo.AnimationOptions options;
if (Flags.moveAnimationOptionsToChange()) {
options = change.getAnimationOptions();
} else {
options = info.getAnimationOptions();
}
- return loadCustomAnimationFromOptions(options, change.getMode());
+ return loadCustomAnimationFromOptions(options, mode);
}
@Nullable
@@ -319,8 +319,14 @@ class ActivityEmbeddingAnimationSpec {
return null;
}
- final Animation anim = mTransitionAnimation.loadAnimationRes(options.getPackageName(),
- resId);
+ final Animation anim;
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ // TODO(b/293658614): Consider allowing custom animations from non-default packages.
+ // Enforce limiting to animations from the default "android" package for now.
+ anim = mTransitionAnimation.loadDefaultAnimationRes(resId);
+ } else {
+ anim = mTransitionAnimation.loadAnimationRes(options.getPackageName(), resId);
+ }
if (anim != null) {
return anim;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java
index 196f89d5794e..df80946a99aa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java
@@ -107,4 +107,24 @@ public interface BackAnimation {
* @param pilferCallback the callback to pilfer pointers.
*/
void setPilferPointerCallback(Runnable pilferCallback);
+
+ /**
+ * Set a callback to requestTopUi.
+ * @param topUiRequest the callback to requestTopUi.
+ */
+ void setTopUiRequestCallback(TopUiRequest topUiRequest);
+
+ /**
+ * Callback to request SysUi to call
+ * {@link android.app.IActivityManager#setHasTopUi(boolean)}.
+ */
+ interface TopUiRequest {
+
+ /**
+ * Request {@link android.app.IActivityManager#setHasTopUi(boolean)} to be called.
+ * @param requestTopUi whether topUi should be requested or not
+ * @param tag tag of the request-source
+ */
+ void requestTopUi(boolean requestTopUi, String tag);
+ }
}
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 ece02711070e..bb239adfe73f 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
@@ -179,6 +179,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
@BackNavigationInfo.BackTargetType
private int mPreviousNavigationType;
private Runnable mPilferPointerCallback;
+ private BackAnimation.TopUiRequest mRequestTopUiCallback;
public BackAnimationController(
@NonNull ShellInit shellInit,
@@ -357,6 +358,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
mPilferPointerCallback = callback;
});
}
+
+ @Override
+ public void setTopUiRequestCallback(TopUiRequest topUiRequest) {
+ mShellExecutor.execute(() -> mRequestTopUiCallback = topUiRequest);
+ }
}
private static class IBackAnimationImpl extends IBackAnimation.Stub
@@ -422,6 +428,12 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
@VisibleForTesting
public void onThresholdCrossed() {
mThresholdCrossed = true;
+ // There was no focus window when calling startBackNavigation, still pilfer pointers so
+ // the next focus window won't receive motion events.
+ if (mBackNavigationInfo == null) {
+ tryPilferPointers();
+ return;
+ }
// Dispatch onBackStarted, only to app callbacks.
// System callbacks will receive onBackStarted when the remote animation starts.
final boolean shouldDispatchToAnimator = shouldDispatchToAnimator();
@@ -542,6 +554,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
if (backNavigationInfo == null) {
ProtoLog.e(WM_SHELL_BACK_PREVIEW, "Received BackNavigationInfo is null.");
cancelLatencyTracking();
+ tryPilferPointers();
return;
}
final int backType = backNavigationInfo.getType();
@@ -550,6 +563,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
if (!mShellBackAnimationRegistry.startGesture(backType)) {
mActiveCallback = null;
}
+ requestTopUi(true, backType);
tryPilferPointers();
} else {
mActiveCallback = mBackNavigationInfo.getOnBackInvokedCallback();
@@ -899,6 +913,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
mPreviousNavigationType = mBackNavigationInfo.getType();
mBackNavigationInfo.onBackNavigationFinished(triggerBack);
mBackNavigationInfo = null;
+ requestTopUi(false, mPreviousNavigationType);
}
}
@@ -962,6 +977,13 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
}
+ private void requestTopUi(boolean hasTopUi, int backType) {
+ if (mRequestTopUiCallback != null && (backType == BackNavigationInfo.TYPE_CROSS_TASK
+ || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY)) {
+ mRequestTopUiCallback.requestTopUi(hasTopUi, TAG);
+ }
+ }
+
/**
* Validate animation targets.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
index 4988a9481d21..e24df0bdc05d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
@@ -30,7 +30,7 @@ import android.window.IOnBackInvokedCallback;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.Cuj.CujType;
-import com.android.wm.shell.common.InteractionJankMonitorUtils;
+import com.android.internal.jank.InteractionJankMonitor;
/**
* Used to register the animation callback and runner, it will trigger result if gesture was finish
@@ -86,20 +86,21 @@ public class BackAnimationRunner {
*/
void startAnimation(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
RemoteAnimationTarget[] nonApps, Runnable finishedCallback) {
+ InteractionJankMonitor interactionJankMonitor = InteractionJankMonitor.getInstance();
final IRemoteAnimationFinishedCallback callback =
new IRemoteAnimationFinishedCallback.Stub() {
@Override
public void onAnimationFinished() {
if (shouldMonitorCUJ(apps)) {
- InteractionJankMonitorUtils.endTracing(mCujType);
+ interactionJankMonitor.end(mCujType);
}
finishedCallback.run();
}
};
mWaitingAnimation = false;
if (shouldMonitorCUJ(apps)) {
- InteractionJankMonitorUtils.beginTracing(
- mCujType, mContext, apps[0].leash, /* tag */ null);
+ interactionJankMonitor.begin(
+ apps[0].leash, mContext, mCujType);
}
try {
getRunner().onAnimationStart(TRANSIT_OLD_UNSET, apps, wallpapers,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
index 4f04c5c28412..4e0c82b9628f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
@@ -61,8 +61,7 @@ abstract class CrossActivityBackAnimation(
private val context: Context,
private val background: BackAnimationBackground,
private val rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
- protected val transaction: SurfaceControl.Transaction,
- private val choreographer: Choreographer
+ protected val transaction: SurfaceControl.Transaction
) : ShellBackAnimation() {
protected val startClosingRect = RectF()
@@ -269,7 +268,9 @@ abstract class CrossActivityBackAnimation(
.setSpring(postCommitFlingSpring)
flingAnimation.start()
// do an animation-frame immediately to prevent idle frame
- flingAnimation.doAnimationFrame(choreographer.lastFrameTimeNanos / TimeUtils.NANOS_PER_MS)
+ flingAnimation.doAnimationFrame(
+ Choreographer.getInstance().lastFrameTimeNanos / TimeUtils.NANOS_PER_MS
+ )
val valueAnimator =
ValueAnimator.ofFloat(1f, 0f).setDuration(getPostCommitAnimationDuration())
@@ -362,7 +363,7 @@ abstract class CrossActivityBackAnimation(
}
protected fun applyTransaction() {
- transaction.setFrameTimelineVsync(choreographer.vsyncId)
+ transaction.setFrameTimelineVsync(Choreographer.getInstance().vsyncId)
transaction.apply()
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
index 103a65422504..e2b0513c951f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
@@ -52,7 +52,6 @@ import com.android.internal.policy.SystemBarUtils;
import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
-import com.android.wm.shell.shared.annotations.ShellMainThread;
import javax.inject.Inject;
@@ -69,7 +68,6 @@ import javax.inject.Inject;
* IOnBackInvokedCallback} with WM Shell and receives back dispatches when a back navigation to
* launcher starts.
*/
-@ShellMainThread
public class CrossTaskBackAnimation extends ShellBackAnimation {
private static final int BACKGROUNDCOLOR = 0x43433A;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt
index e266e2cd7eea..b02f97bf7784 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt
@@ -19,7 +19,6 @@ import android.content.Context
import android.graphics.Rect
import android.graphics.RectF
import android.util.MathUtils
-import android.view.Choreographer
import android.view.SurfaceControl
import android.view.animation.Animation
import android.view.animation.Transformation
@@ -31,27 +30,23 @@ import com.android.internal.policy.TransitionAnimation
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.protolog.ShellProtoLogGroup
-import com.android.wm.shell.shared.annotations.ShellMainThread
import javax.inject.Inject
import kotlin.math.max
import kotlin.math.min
/** Class that handles customized predictive cross activity back animations. */
-@ShellMainThread
class CustomCrossActivityBackAnimation(
context: Context,
background: BackAnimationBackground,
rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
transaction: SurfaceControl.Transaction,
- choreographer: Choreographer,
private val customAnimationLoader: CustomAnimationLoader
) :
CrossActivityBackAnimation(
context,
background,
rootTaskDisplayAreaOrganizer,
- transaction,
- choreographer
+ transaction
) {
private var enterAnimation: Animation? = null
@@ -70,7 +65,6 @@ class CustomCrossActivityBackAnimation(
background,
rootTaskDisplayAreaOrganizer,
SurfaceControl.Transaction(),
- Choreographer.getInstance(),
CustomAnimationLoader(
TransitionAnimation(context, false /* debug */, "CustomCrossActivityBackAnimation")
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/DefaultCrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/DefaultCrossActivityBackAnimation.kt
index 3b5eb3613d2a..c747e1e98956 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/DefaultCrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/DefaultCrossActivityBackAnimation.kt
@@ -16,18 +16,15 @@
package com.android.wm.shell.back
import android.content.Context
-import android.view.Choreographer
import android.view.SurfaceControl
import android.window.BackEvent
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.animation.Interpolators
-import com.android.wm.shell.shared.annotations.ShellMainThread
import javax.inject.Inject
import kotlin.math.max
/** Class that defines cross-activity animation. */
-@ShellMainThread
class DefaultCrossActivityBackAnimation
@Inject
constructor(
@@ -39,8 +36,7 @@ constructor(
context,
background,
rootTaskDisplayAreaOrganizer,
- SurfaceControl.Transaction(),
- Choreographer.getInstance()
+ SurfaceControl.Transaction()
) {
private val postCommitInterpolator = Interpolators.EMPHASIZED
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt
index a124f95d7431..c93c11eb2fc2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt
@@ -20,10 +20,10 @@ import android.app.Activity
import android.content.pm.ShortcutManager
import android.graphics.drawable.Icon
import android.os.Bundle
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.Flags
import com.android.wm.shell.R
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES
-import com.android.wm.shell.util.KtProtoLog
/** Activity to create a shortcut to open bubbles */
class CreateBubbleShortcutActivity : Activity() {
@@ -31,7 +31,7 @@ class CreateBubbleShortcutActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Flags.enableRetrievableBubbles()) {
- KtProtoLog.d(WM_SHELL_BUBBLES, "Creating a shortcut for bubbles")
+ ProtoLog.d(WM_SHELL_BUBBLES, "Creating a shortcut for bubbles")
createShortcut()
}
finish()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt
index ae7940ca1b65..e578e9e76979 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt
@@ -21,9 +21,9 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.Flags
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES
-import com.android.wm.shell.util.KtProtoLog
/** Activity that sends a broadcast to open bubbles */
class ShowBubblesActivity : Activity() {
@@ -37,7 +37,7 @@ class ShowBubblesActivity : Activity() {
// Set the package as the receiver is not exported
`package` = packageName
}
- KtProtoLog.v(WM_SHELL_BUBBLES, "Sending broadcast to show bubbles")
+ ProtoLog.v(WM_SHELL_BUBBLES, "Sending broadcast to show bubbles")
sendBroadcast(intent)
}
finish()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java
index bfee820870f1..736d954513b1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java
@@ -54,4 +54,11 @@ public class HandlerExecutor implements ShellExecutor {
public boolean hasCallback(Runnable r) {
return mHandler.hasCallbacks(r);
}
+
+ @Override
+ public void assertCurrentThread() {
+ if (!mHandler.getLooper().isCurrentThread()) {
+ throw new IllegalStateException("must be called on " + mHandler);
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
deleted file mode 100644
index 86f00b83cadd..000000000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
+++ /dev/null
@@ -1,84 +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.wm.shell.common;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.text.TextUtils;
-import android.view.SurfaceControl;
-import android.view.View;
-
-import com.android.internal.jank.Cuj.CujType;
-import com.android.internal.jank.InteractionJankMonitor;
-
-/** Utils class for simplfy InteractionJank trancing call */
-public class InteractionJankMonitorUtils {
-
- /**
- * Begin a trace session.
- *
- * @param cujType the specific {@link CujType}.
- * @param view the view to trace
- * @param tag the tag to distinguish different flow of same type CUJ.
- */
- public static void beginTracing(@CujType int cujType,
- @NonNull View view, @Nullable String tag) {
- final InteractionJankMonitor.Configuration.Builder builder =
- InteractionJankMonitor.Configuration.Builder.withView(cujType, view);
- if (!TextUtils.isEmpty(tag)) {
- builder.setTag(tag);
- }
- InteractionJankMonitor.getInstance().begin(builder);
- }
-
- /**
- * Begin a trace session.
- *
- * @param cujType the specific {@link CujType}.
- * @param context the context
- * @param surface the surface to trace
- * @param tag the tag to distinguish different flow of same type CUJ.
- */
- public static void beginTracing(@CujType int cujType,
- @NonNull Context context, @NonNull SurfaceControl surface, @Nullable String tag) {
- final InteractionJankMonitor.Configuration.Builder builder =
- InteractionJankMonitor.Configuration.Builder.withSurface(cujType, context, surface);
- if (!TextUtils.isEmpty(tag)) {
- builder.setTag(tag);
- }
- InteractionJankMonitor.getInstance().begin(builder);
- }
-
- /**
- * End a trace session.
- *
- * @param cujType the specific {@link CujType}.
- */
- public static void endTracing(@CujType int cujType) {
- InteractionJankMonitor.getInstance().end(cujType);
- }
-
- /**
- * Cancel the trace session.
- *
- * @param cujType the specific {@link CujType}.
- */
- public static void cancelTracing(@CujType int cujType) {
- InteractionJankMonitor.getInstance().cancel(cujType);
- }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt
index 81592c35e4ac..e92b0b59d2ef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt
@@ -17,8 +17,8 @@ package com.android.wm.shell.common
import android.window.WindowContainerToken
import android.window.WindowContainerTransaction
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG
-import com.android.wm.shell.util.KtProtoLog
/**
* Controller to manage behavior of activities launched with
@@ -30,7 +30,7 @@ class LaunchAdjacentController(private val syncQueue: SyncTransactionQueue) {
var launchAdjacentEnabled: Boolean = true
set(value) {
if (field != value) {
- KtProtoLog.d(WM_SHELL_TASK_ORG, "set launch adjacent flag root enabled=%b", value)
+ ProtoLog.d(WM_SHELL_TASK_ORG, "set launch adjacent flag root enabled=%b", value)
field = value
container?.let { c ->
if (value) {
@@ -52,7 +52,7 @@ class LaunchAdjacentController(private val syncQueue: SyncTransactionQueue) {
* @see WindowContainerTransaction.setLaunchAdjacentFlagRoot
*/
fun setLaunchAdjacentRoot(container: WindowContainerToken) {
- KtProtoLog.d(WM_SHELL_TASK_ORG, "set new launch adjacent flag root container")
+ ProtoLog.d(WM_SHELL_TASK_ORG, "set new launch adjacent flag root container")
this.container = container
if (launchAdjacentEnabled) {
enableContainer(container)
@@ -67,7 +67,7 @@ class LaunchAdjacentController(private val syncQueue: SyncTransactionQueue) {
* @see WindowContainerTransaction.clearLaunchAdjacentFlagRoot
*/
fun clearLaunchAdjacentRoot() {
- KtProtoLog.d(WM_SHELL_TASK_ORG, "clear launch adjacent flag root container")
+ ProtoLog.d(WM_SHELL_TASK_ORG, "clear launch adjacent flag root container")
container?.let {
disableContainer(it)
container = null
@@ -75,14 +75,14 @@ class LaunchAdjacentController(private val syncQueue: SyncTransactionQueue) {
}
private fun enableContainer(container: WindowContainerToken) {
- KtProtoLog.v(WM_SHELL_TASK_ORG, "enable launch adjacent flag root container")
+ ProtoLog.v(WM_SHELL_TASK_ORG, "enable launch adjacent flag root container")
val wct = WindowContainerTransaction()
wct.setLaunchAdjacentFlagRoot(container)
syncQueue.queue(wct)
}
private fun disableContainer(container: WindowContainerToken) {
- KtProtoLog.v(WM_SHELL_TASK_ORG, "disable launch adjacent flag root container")
+ ProtoLog.v(WM_SHELL_TASK_ORG, "disable launch adjacent flag root container")
val wct = WindowContainerTransaction()
wct.clearLaunchAdjacentFlagRoot(container)
syncQueue.queue(wct)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt
index 9e8dfb5f0c6f..a6be64070ac1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt
@@ -23,9 +23,9 @@ import android.content.pm.PackageManager
import android.os.UserHandle
import android.view.WindowManager.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI
import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.R
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL
-import com.android.wm.shell.util.KtProtoLog
import java.util.Arrays
/**
@@ -52,7 +52,7 @@ class MultiInstanceHelper @JvmOverloads constructor(
val packageName = componentName.packageName
for (pkg in staticAppsSupportingMultiInstance) {
if (pkg == packageName) {
- KtProtoLog.v(WM_SHELL, "application=%s in allowlist supports multi-instance",
+ ProtoLog.v(WM_SHELL, "application=%s in allowlist supports multi-instance",
packageName)
return true
}
@@ -70,10 +70,10 @@ class MultiInstanceHelper @JvmOverloads constructor(
// If the above call doesn't throw a NameNotFoundException, then the activity property
// should override the application property value
if (activityProp.isBoolean) {
- KtProtoLog.v(WM_SHELL, "activity=%s supports multi-instance", componentName)
+ ProtoLog.v(WM_SHELL, "activity=%s supports multi-instance", componentName)
return activityProp.boolean
} else {
- KtProtoLog.w(WM_SHELL, "Warning: property=%s for activity=%s has non-bool type=%d",
+ ProtoLog.w(WM_SHELL, "Warning: property=%s for activity=%s has non-bool type=%d",
PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName, activityProp.type)
}
} catch (nnfe: PackageManager.NameNotFoundException) {
@@ -85,10 +85,10 @@ class MultiInstanceHelper @JvmOverloads constructor(
val appProp = packageManager.getProperty(
PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName)
if (appProp.isBoolean) {
- KtProtoLog.v(WM_SHELL, "application=%s supports multi-instance", packageName)
+ ProtoLog.v(WM_SHELL, "application=%s supports multi-instance", packageName)
return appProp.boolean
} else {
- KtProtoLog.w(WM_SHELL,
+ ProtoLog.w(WM_SHELL,
"Warning: property=%s for application=%s has non-bool type=%d",
PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName, appProp.type)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
index f729164ed303..2c2961fd4b65 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
@@ -96,4 +96,11 @@ public interface ShellExecutor extends Executor {
* See {@link android.os.Handler#hasCallbacks(Runnable)}.
*/
boolean hasCallback(Runnable runnable);
+
+ /**
+ * May throw if the caller is not on the same thread as the executor.
+ */
+ default void assertCurrentThread() {
+ return;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index 3ad60e7031e5..1bc179551825 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -492,6 +492,11 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
return mHideHandle;
}
+ /** Returns true if the divider is currently being physically controlled by the user. */
+ boolean isMoving() {
+ return mMoving;
+ }
+
private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDoubleTap(MotionEvent e) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
index de016d3ae400..5097ed8866c9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
@@ -269,7 +269,9 @@ public class SplitDecorManager extends WindowlessWindowManager {
if (update) {
if (immediately) {
+ t.setAlpha(mBackgroundLeash, showVeil ? 1f : 0f);
t.setVisibility(mBackgroundLeash, showVeil);
+ t.setAlpha(mIconLeash, showVeil ? 1f : 0f);
t.setVisibility(mIconLeash, showVeil);
} else {
startFadeAnimation(showVeil, false, null);
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 d3c349f9c866..51f9de8305f8 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
@@ -59,6 +59,7 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -67,7 +68,6 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.InteractionJankMonitorUtils;
import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition;
import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
@@ -131,6 +131,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
private final boolean mDimNonImeSide;
private final boolean mAllowLeftRightSplitInPortrait;
+ private final InteractionJankMonitor mInteractionJankMonitor;
private boolean mIsLeftRightSplit;
private ValueAnimator mDividerFlingAnimator;
@@ -163,6 +164,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
mRootBounds.set(configuration.windowConfiguration.getBounds());
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
+ mInteractionJankMonitor = InteractionJankMonitor.getInstance();
resetDividerPosition();
updateInvisibleRect();
}
@@ -569,12 +571,11 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
}
void onStartDragging() {
- InteractionJankMonitorUtils.beginTracing(CUJ_SPLIT_SCREEN_RESIZE, mContext,
- getDividerLeash(), null /* tag */);
+ mInteractionJankMonitor.begin(getDividerLeash(), mContext, CUJ_SPLIT_SCREEN_RESIZE);
}
void onDraggingCancelled() {
- InteractionJankMonitorUtils.cancelTracing(CUJ_SPLIT_SCREEN_RESIZE);
+ mInteractionJankMonitor.cancel(CUJ_SPLIT_SCREEN_RESIZE);
}
void onDoubleTappedDivider() {
@@ -638,7 +639,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
if (flingFinishedCallback != null) {
flingFinishedCallback.run();
}
- InteractionJankMonitorUtils.endTracing(
+ mInteractionJankMonitor.end(
CUJ_SPLIT_SCREEN_RESIZE);
return;
}
@@ -651,9 +652,18 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
.ofInt(from, to)
.setDuration(duration);
mDividerFlingAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+
+ // If the divider is being physically controlled by the user, we use a cool parallax effect
+ // on the task windows. So if this "snap" animation is an extension of a user-controlled
+ // movement, we pass in true here to continue the parallax effect smoothly.
+ boolean isBeingMovedByUser = mSplitWindowManager.getDividerView() != null
+ && mSplitWindowManager.getDividerView().isMoving();
+
mDividerFlingAnimator.addUpdateListener(
animation -> updateDividerBounds(
- (int) animation.getAnimatedValue(), false /* shouldUseParallaxEffect */)
+ (int) animation.getAnimatedValue(),
+ isBeingMovedByUser /* shouldUseParallaxEffect */
+ )
);
mDividerFlingAnimator.addListener(new AnimatorListenerAdapter() {
@Override
@@ -661,7 +671,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
if (flingFinishedCallback != null) {
flingFinishedCallback.run();
}
- InteractionJankMonitorUtils.endTracing(
+ mInteractionJankMonitor.end(
CUJ_SPLIT_SCREEN_RESIZE);
mDividerFlingAnimator = null;
}
@@ -707,8 +717,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
- InteractionJankMonitorUtils.beginTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER,
- mContext, getDividerLeash(), null /*tag*/);
+ mInteractionJankMonitor.begin(getDividerLeash(),
+ mContext, CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
}
@Override
@@ -716,12 +726,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
mDividerPosition = dividerPos;
updateBounds(mDividerPosition);
finishCallback.accept(insets);
- InteractionJankMonitorUtils.endTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
+ mInteractionJankMonitor.end(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
}
@Override
public void onAnimationCancel(Animator animation) {
- InteractionJankMonitorUtils.cancelTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
+ mInteractionJankMonitor.cancel(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
}
});
set.start();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
index 5d121c23c6e1..46c1a43f9efe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
@@ -37,7 +37,6 @@ import android.view.LayoutInflater;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
import android.view.SurfaceSession;
-import android.view.View;
import android.view.WindowManager;
import android.view.WindowlessWindowManager;
@@ -192,7 +191,7 @@ public final class SplitWindowManager extends WindowlessWindowManager {
mDividerView.setInteractive(interactive, hideHandle, from);
}
- View getDividerView() {
+ DividerView getDividerView() {
return mDividerView;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt
index 6781d08c9904..d1b2347a4411 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt
@@ -19,6 +19,16 @@
package com.android.wm.shell.compatui
import android.app.TaskInfo
-fun isSingleTopActivityTranslucent(task: TaskInfo) =
- task.isTopActivityTransparent && task.numActivities == 1
+import android.content.Context
+import com.android.internal.R
+// TODO(b/347289970): Consider replacing with API
+fun isTopActivityExemptFromDesktopWindowing(context: Context, task: TaskInfo) =
+ isSystemUiTask(context, task) || (task.isTopActivityTransparent && task.numActivities == 1
+ && !task.isTopActivityStyleFloating)
+
+private fun isSystemUiTask(context: Context, task: TaskInfo): Boolean {
+ val sysUiPackageName: String =
+ context.resources.getString(R.string.config_systemUi)
+ return task.baseActivity?.packageName == sysUiPackageName
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index 2520c25613e7..c02c9cf3fd72 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -20,7 +20,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.CameraCompatTaskInfo.CameraCompatControlState;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.Context;
@@ -50,6 +49,10 @@ import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.compatui.api.CompatUIEvent;
+import com.android.wm.shell.compatui.api.CompatUIHandler;
+import com.android.wm.shell.compatui.api.CompatUIInfo;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonClicked;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
@@ -71,17 +74,7 @@ import java.util.function.Predicate;
* activities are in compatibility mode.
*/
public class CompatUIController implements OnDisplaysChangedListener,
- DisplayImeController.ImePositionProcessor, KeyguardChangeListener {
-
- /** Callback for compat UI interaction. */
- public interface CompatUICallback {
- /** Called when the size compat restart button appears. */
- void onSizeCompatRestartButtonAppeared(int taskId);
- /** Called when the size compat restart button is clicked. */
- void onSizeCompatRestartButtonClicked(int taskId);
- /** Called when the camera compat control state is updated. */
- void onCameraControlStateUpdated(int taskId, @CameraCompatControlState int state);
- }
+ DisplayImeController.ImePositionProcessor, KeyguardChangeListener, CompatUIHandler {
private static final String TAG = "CompatUIController";
@@ -170,7 +163,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
private final Function<Integer, Integer> mDisappearTimeSupplier;
@Nullable
- private CompatUICallback mCompatUICallback;
+ private Consumer<CompatUIEvent> mCallback;
// Indicates if the keyguard is currently showing, in which case compat UIs shouldn't
// be shown.
@@ -230,20 +223,21 @@ public class CompatUIController implements OnDisplaysChangedListener,
mCompatUIShellCommandHandler.onInit();
}
- /** Sets the callback for Compat UI interactions. */
- public void setCompatUICallback(@NonNull CompatUICallback compatUiCallback) {
- mCompatUICallback = compatUiCallback;
+ /** Sets the callback for UI interactions. */
+ @Override
+ public void setCallback(@Nullable Consumer<CompatUIEvent> callback) {
+ mCallback = callback;
}
/**
* Called when the Task info changed. Creates and updates the compat UI if there is an
* activity in size compat, or removes the UI if there is no size compat activity.
*
- * @param taskInfo {@link TaskInfo} task the activity is in.
- * @param taskListener listener to handle the Task Surface placement.
+ * @param compatUIInfo {@link CompatUIInfo} encapsulates information about the task and listener
*/
- public void onCompatInfoChanged(@NonNull TaskInfo taskInfo,
- @Nullable ShellTaskOrganizer.TaskListener taskListener) {
+ public void onCompatInfoChanged(@NonNull CompatUIInfo compatUIInfo) {
+ final TaskInfo taskInfo = compatUIInfo.getTaskInfo();
+ final ShellTaskOrganizer.TaskListener taskListener = compatUIInfo.getListener();
if (taskInfo != null && !taskInfo.appCompatTaskInfo.topActivityInSizeCompat) {
mSetOfTaskIdsShowingRestartDialog.remove(taskInfo.taskId);
}
@@ -466,7 +460,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
CompatUIWindowManager createCompatUiWindowManager(Context context, TaskInfo taskInfo,
ShellTaskOrganizer.TaskListener taskListener) {
return new CompatUIWindowManager(context,
- taskInfo, mSyncQueue, mCompatUICallback, taskListener,
+ taskInfo, mSyncQueue, mCallback, taskListener,
mDisplayController.getDisplayLayout(taskInfo.displayId), mCompatUIHintsState,
mCompatUIConfiguration, this::onRestartButtonClicked);
}
@@ -478,9 +472,9 @@ public class CompatUIController implements OnDisplaysChangedListener,
taskInfoState.first)) {
// We need to show the dialog
mSetOfTaskIdsShowingRestartDialog.add(taskInfoState.first.taskId);
- onCompatInfoChanged(taskInfoState.first, taskInfoState.second);
+ onCompatInfoChanged(new CompatUIInfo(taskInfoState.first, taskInfoState.second));
} else {
- mCompatUICallback.onSizeCompatRestartButtonClicked(taskInfoState.first.taskId);
+ mCallback.accept(new SizeCompatRestartButtonClicked(taskInfoState.first.taskId));
}
}
@@ -575,13 +569,13 @@ public class CompatUIController implements OnDisplaysChangedListener,
private void onRestartDialogCallback(
Pair<TaskInfo, ShellTaskOrganizer.TaskListener> stateInfo) {
mTaskIdToRestartDialogWindowManagerMap.remove(stateInfo.first.taskId);
- mCompatUICallback.onSizeCompatRestartButtonClicked(stateInfo.first.taskId);
+ mCallback.accept(new SizeCompatRestartButtonClicked(stateInfo.first.taskId));
}
private void onRestartDialogDismissCallback(
Pair<TaskInfo, ShellTaskOrganizer.TaskListener> stateInfo) {
mSetOfTaskIdsShowingRestartDialog.remove(stateInfo.first.taskId);
- onCompatInfoChanged(stateInfo.first, stateInfo.second);
+ onCompatInfoChanged(new CompatUIInfo(stateInfo.first, stateInfo.second));
}
private void createOrUpdateReachabilityEduLayout(@NonNull TaskInfo taskInfo,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
index 3ab1fad2b203..1931212df548 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
@@ -40,8 +40,10 @@ import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.compatui.CompatUIController.CompatUICallback;
import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState;
+import com.android.wm.shell.compatui.api.CompatUIEvent;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.CameraControlStateUpdated;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonAppeared;
import java.util.function.Consumer;
@@ -50,10 +52,13 @@ import java.util.function.Consumer;
*/
class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
- private final CompatUICallback mCallback;
+ @NonNull
+ private final Consumer<CompatUIEvent> mCallback;
+ @NonNull
private final CompatUIConfiguration mCompatUIConfiguration;
+ @NonNull
private final Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnRestartButtonClicked;
// Remember the last reported states in case visibility changes due to keyguard or IME updates.
@@ -65,6 +70,7 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
int mCameraCompatControlState = CAMERA_COMPAT_CONTROL_HIDDEN;
@VisibleForTesting
+ @NonNull
CompatUIHintsState mCompatUIHintsState;
@Nullable
@@ -73,11 +79,15 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
private final float mHideScmTolerance;
- CompatUIWindowManager(Context context, TaskInfo taskInfo,
- SyncTransactionQueue syncQueue, CompatUICallback callback,
- ShellTaskOrganizer.TaskListener taskListener, DisplayLayout displayLayout,
- CompatUIHintsState compatUIHintsState, CompatUIConfiguration compatUIConfiguration,
- Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> onRestartButtonClicked) {
+ CompatUIWindowManager(@NonNull Context context, @NonNull TaskInfo taskInfo,
+ @NonNull SyncTransactionQueue syncQueue,
+ @NonNull Consumer<CompatUIEvent> callback,
+ @Nullable ShellTaskOrganizer.TaskListener taskListener,
+ @Nullable DisplayLayout displayLayout,
+ @NonNull CompatUIHintsState compatUIHintsState,
+ @NonNull CompatUIConfiguration compatUIConfiguration,
+ @NonNull Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>>
+ onRestartButtonClicked) {
super(context, taskInfo, syncQueue, taskListener, displayLayout);
mCallback = callback;
mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat;
@@ -122,7 +132,7 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
updateVisibilityOfViews();
if (mHasSizeCompat) {
- mCallback.onSizeCompatRestartButtonAppeared(mTaskId);
+ mCallback.accept(new SizeCompatRestartButtonAppeared(mTaskId));
}
return mLayout;
@@ -177,7 +187,7 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
mCameraCompatControlState == CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED
? CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED
: CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
- mCallback.onCameraControlStateUpdated(mTaskId, mCameraCompatControlState);
+ mCallback.accept(new CameraControlStateUpdated(mTaskId, mCameraCompatControlState));
mLayout.updateCameraTreatmentButton(mCameraCompatControlState);
}
@@ -188,7 +198,7 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
return;
}
mCameraCompatControlState = CAMERA_COMPAT_CONTROL_DISMISSED;
- mCallback.onCameraControlStateUpdated(mTaskId, CAMERA_COMPAT_CONTROL_DISMISSED);
+ mCallback.accept(new CameraControlStateUpdated(mTaskId, CAMERA_COMPAT_CONTROL_DISMISSED));
mLayout.setCameraControlVisibility(/* show= */ false);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIEvent.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIEvent.kt
new file mode 100644
index 000000000000..4a0cf9843722
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIEvent.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.wm.shell.compatui.api
+
+/**
+ * Abstraction for all the possible Compat UI Component events.
+ */
+interface CompatUIEvent {
+ /**
+ * Unique event identifier
+ */
+ val eventId: Int
+
+ @Suppress("UNCHECKED_CAST")
+ fun <T : CompatUIEvent> asType(): T? = this as? T
+
+ fun <T : CompatUIEvent> asType(clazz: Class<T>): T? {
+ return if (clazz.isInstance(this)) clazz.cast(this) else null
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIHandler.kt
new file mode 100644
index 000000000000..817e554b550e
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIHandler.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.wm.shell.compatui.api
+
+import java.util.function.Consumer
+
+/**
+ * Abstraction for the objects responsible to handle all the CompatUI components and the
+ * communication with the server.
+ */
+interface CompatUIHandler {
+ /**
+ * Invoked when a new model is coming from the server.
+ */
+ fun onCompatInfoChanged(compatUIInfo: CompatUIInfo)
+
+ /**
+ * Optional reference to the object responsible to send {@link CompatUIEvent}
+ */
+ fun setCallback(compatUIEventSender: Consumer<CompatUIEvent>?)
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIInfo.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIInfo.kt
new file mode 100644
index 000000000000..dbbf049792f5
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIInfo.kt
@@ -0,0 +1,25 @@
+/*
+ * 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.wm.shell.compatui.api
+
+import android.app.TaskInfo
+import com.android.wm.shell.ShellTaskOrganizer
+
+/**
+ * Encapsulate the info of the message from core.
+ */
+data class CompatUIInfo(val taskInfo: TaskInfo, val listener: ShellTaskOrganizer.TaskListener?) \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIRepository.kt
new file mode 100644
index 000000000000..cb54d89a5714
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIRepository.kt
@@ -0,0 +1,39 @@
+/*
+ * 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.wm.shell.compatui.api
+
+/**
+ * Abstraction for the repository of all the available CompatUISpec
+ */
+interface CompatUIRepository {
+ /**
+ * Adds a {@link CompatUISpec} to the repository
+ * @throws IllegalStateException in case of illegal spec
+ */
+ fun addSpec(spec: CompatUISpec)
+
+ /**
+ * Iterates on the list of available {@link CompatUISpec} invoking
+ * fn for each of them.
+ */
+ fun iterateOn(fn: (CompatUISpec) -> Unit)
+
+ /**
+ * Returns the {@link CompatUISpec} for a given key
+ */
+ fun findSpec(name: String): CompatUISpec?
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt
new file mode 100644
index 000000000000..24c2c8c2aedf
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.wm.shell.compatui.api
+
+/**
+ * Describes each compat ui component to the framework.
+ */
+data class CompatUISpec(
+ // Unique name for the component. It's used for debug and for generating the
+ // unique component identifier in the system.
+ val name: String
+) \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt
new file mode 100644
index 000000000000..58ce8ed6c978
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.wm.shell.compatui.impl
+
+import android.app.AppCompatTaskInfo
+import android.app.CameraCompatTaskInfo
+import com.android.wm.shell.compatui.api.CompatUIEvent
+
+internal const val SIZE_COMPAT_RESTART_BUTTON_APPEARED = 0
+internal const val SIZE_COMPAT_RESTART_BUTTON_CLICKED = 1
+internal const val CAMERA_CONTROL_STATE_UPDATE = 2
+
+/**
+ * All the {@link CompatUIEvent} the Compat UI Framework can handle
+ */
+sealed class CompatUIEvents(override val eventId: Int) : CompatUIEvent {
+ /** Sent when the size compat restart button appears. */
+ data class SizeCompatRestartButtonAppeared(val taskId: Int) :
+ CompatUIEvents(SIZE_COMPAT_RESTART_BUTTON_APPEARED)
+
+ /** Sent when the size compat restart button is clicked. */
+ data class SizeCompatRestartButtonClicked(val taskId: Int) :
+ CompatUIEvents(SIZE_COMPAT_RESTART_BUTTON_CLICKED)
+
+ /** Sent when the camera compat control state is updated. */
+ data class CameraControlStateUpdated(
+ val taskId: Int,
+ @CameraCompatTaskInfo.CameraCompatControlState val state: Int
+ ) : CompatUIEvents(CAMERA_CONTROL_STATE_UPDATE)
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt
new file mode 100644
index 000000000000..8408ea6ebc31
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.wm.shell.compatui.impl
+
+import com.android.wm.shell.compatui.api.CompatUIEvent
+import com.android.wm.shell.compatui.api.CompatUIHandler
+import com.android.wm.shell.compatui.api.CompatUIInfo
+import com.android.wm.shell.compatui.api.CompatUIRepository
+import java.util.function.Consumer
+
+/**
+ * Default implementation of {@link CompatUIHandler} to handle CompatUI components
+ */
+class DefaultCompatUIHandler(
+ private val compatUIRepository: CompatUIRepository
+) : CompatUIHandler {
+
+ private var compatUIEventSender: Consumer<CompatUIEvent>? = null
+ override fun onCompatInfoChanged(compatUIInfo: CompatUIInfo) {
+ // Empty at the moment
+ }
+
+ override fun setCallback(compatUIEventSender: Consumer<CompatUIEvent>?) {
+ this.compatUIEventSender = compatUIEventSender
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepository.kt
new file mode 100644
index 000000000000..10d9425c85ea
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepository.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.wm.shell.compatui.impl
+
+import com.android.wm.shell.compatui.api.CompatUIRepository
+import com.android.wm.shell.compatui.api.CompatUISpec
+
+/**
+ * Default {@link CompatUIRepository} implementation
+ */
+class DefaultCompatUIRepository : CompatUIRepository {
+
+ private val allSpecs = mutableMapOf<String, CompatUISpec>()
+
+ override fun addSpec(spec: CompatUISpec) {
+ if (allSpecs[spec.name] != null) {
+ throw IllegalStateException("Spec with id:${spec.name} already present")
+ }
+ allSpecs[spec.name] = spec
+ }
+
+ override fun iterateOn(fn: (CompatUISpec) -> Unit) =
+ allSpecs.values.forEach(fn)
+
+ override fun findSpec(name: String): CompatUISpec? =
+ allSpecs[name]
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 609e5af5c5b0..4b548cbe77cc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -71,6 +71,10 @@ import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.compatui.CompatUIConfiguration;
import com.android.wm.shell.compatui.CompatUIController;
import com.android.wm.shell.compatui.CompatUIShellCommandHandler;
+import com.android.wm.shell.compatui.api.CompatUIHandler;
+import com.android.wm.shell.compatui.api.CompatUIRepository;
+import com.android.wm.shell.compatui.impl.DefaultCompatUIHandler;
+import com.android.wm.shell.compatui.impl.DefaultCompatUIRepository;
import com.android.wm.shell.desktopmode.DesktopMode;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
import com.android.wm.shell.desktopmode.DesktopTasksController;
@@ -88,12 +92,12 @@ import com.android.wm.shell.recents.RecentTasks;
import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.recents.RecentsTransitionHandler;
import com.android.wm.shell.recents.TaskStackTransitionObserver;
-import com.android.wm.shell.shared.DesktopModeStatus;
import com.android.wm.shell.shared.ShellTransitions;
import com.android.wm.shell.shared.annotations.ShellAnimationThread;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.shared.annotations.ShellSplashscreenThread;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.startingsurface.StartingSurface;
@@ -211,7 +215,7 @@ public abstract class WMShellBaseModule {
Context context,
ShellInit shellInit,
ShellCommandHandler shellCommandHandler,
- Optional<CompatUIController> compatUI,
+ Optional<CompatUIHandler> compatUI,
Optional<UnfoldAnimationController> unfoldAnimationController,
Optional<RecentTasksController> recentTasksOptional,
@ShellMainThread ShellExecutor mainExecutor) {
@@ -230,7 +234,7 @@ public abstract class WMShellBaseModule {
@WMSingleton
@Provides
- static Optional<CompatUIController> provideCompatUIController(
+ static Optional<CompatUIHandler> provideCompatUIController(
Context context,
ShellInit shellInit,
ShellController shellController,
@@ -243,10 +247,14 @@ public abstract class WMShellBaseModule {
Lazy<DockStateReader> dockStateReader,
Lazy<CompatUIConfiguration> compatUIConfiguration,
Lazy<CompatUIShellCommandHandler> compatUIShellCommandHandler,
- Lazy<AccessibilityManager> accessibilityManager) {
+ Lazy<AccessibilityManager> accessibilityManager,
+ CompatUIRepository compatUIRepository) {
if (!context.getResources().getBoolean(R.bool.config_enableCompatUIController)) {
return Optional.empty();
}
+ if (Flags.appCompatUiFramework()) {
+ return Optional.of(new DefaultCompatUIHandler(compatUIRepository));
+ }
return Optional.of(
new CompatUIController(
context,
@@ -266,6 +274,12 @@ public abstract class WMShellBaseModule {
@WMSingleton
@Provides
+ static CompatUIRepository provideCompatUIRepository() {
+ return new DefaultCompatUIRepository();
+ }
+
+ @WMSingleton
+ @Provides
static SyncTransactionQueue provideSyncTransactionQueue(TransactionPool pool,
@ShellMainThread ShellExecutor mainExecutor) {
return new SyncTransactionQueue(pool, mainExecutor);
@@ -898,7 +912,7 @@ public abstract class WMShellBaseModule {
// Use optional-of-lazy for the dependency that this provider relies on.
// Lazy ensures that this provider will not be the cause the dependency is created
// when it will not be returned due to the condition below.
- return desktopTasksController.flatMap((lazy)-> {
+ return desktopTasksController.flatMap((lazy) -> {
if (DesktopModeStatus.canEnterDesktopMode(context)) {
return Optional.of(lazy.get());
}
@@ -917,7 +931,7 @@ public abstract class WMShellBaseModule {
// Use optional-of-lazy for the dependency that this provider relies on.
// Lazy ensures that this provider will not be the cause the dependency is created
// when it will not be returned due to the condition below.
- return desktopModeTaskRepository.flatMap((lazy)-> {
+ return desktopModeTaskRepository.flatMap((lazy) -> {
if (DesktopModeStatus.canEnterDesktopMode(context)) {
return Optional.of(lazy.get());
}
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 4ea41d5256f9..45feff5b0ccc 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
@@ -24,7 +24,6 @@ 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 com.android.internal.jank.InteractionJankMonitor;
@@ -78,10 +77,10 @@ import com.android.wm.shell.onehanded.OneHandedController;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.recents.RecentsTransitionHandler;
-import com.android.wm.shell.shared.DesktopModeStatus;
import com.android.wm.shell.shared.annotations.ShellAnimationThread;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
@@ -222,7 +221,8 @@ public abstract class WMShellModule {
SyncTransactionQueue syncQueue,
Transitions transitions,
Optional<DesktopTasksController> desktopTasksController,
- RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ InteractionJankMonitor interactionJankMonitor) {
if (DesktopModeStatus.canEnterDesktopMode(context)) {
return new DesktopModeWindowDecorViewModel(
context,
@@ -239,12 +239,16 @@ public abstract class WMShellModule {
syncQueue,
transitions,
desktopTasksController,
- rootTaskDisplayAreaOrganizer);
+ rootTaskDisplayAreaOrganizer,
+ interactionJankMonitor);
}
return new CaptionWindowDecorViewModel(
context,
mainHandler,
+ mainExecutor,
mainChoreographer,
+ windowManager,
+ shellInit,
taskOrganizer,
displayController,
rootTaskDisplayAreaOrganizer,
@@ -402,8 +406,7 @@ public abstract class WMShellModule {
Optional<RecentTasksController> recentTasksController,
HomeTransitionObserver homeTransitionObserver) {
return new RecentsTransitionHandler(shellInit, transitions,
- recentTasksController.orElse(null), homeTransitionObserver,
- SurfaceControl.Transaction::new);
+ recentTasksController.orElse(null), homeTransitionObserver);
}
//
@@ -577,17 +580,18 @@ public abstract class WMShellModule {
@WMSingleton
@Provides
static ToggleResizeDesktopTaskTransitionHandler provideToggleResizeDesktopTaskTransitionHandler(
- Transitions transitions) {
- return new ToggleResizeDesktopTaskTransitionHandler(transitions);
+ Transitions transitions, InteractionJankMonitor interactionJankMonitor) {
+ return new ToggleResizeDesktopTaskTransitionHandler(transitions, interactionJankMonitor);
}
@WMSingleton
@Provides
static ExitDesktopTaskTransitionHandler provideExitDesktopTaskTransitionHandler(
Transitions transitions,
- Context context
- ) {
- return new ExitDesktopTaskTransitionHandler(transitions, context);
+ Context context,
+ InteractionJankMonitor interactionJankMonitor) {
+ return new ExitDesktopTaskTransitionHandler(
+ transitions, context, interactionJankMonitor);
}
@WMSingleton
@@ -603,11 +607,12 @@ public abstract class WMShellModule {
Context context,
Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
Transitions transitions,
+ ShellTaskOrganizer shellTaskOrganizer,
ShellInit shellInit
) {
return desktopModeTaskRepository.flatMap(repository ->
Optional.of(new DesktopTasksTransitionObserver(
- context, repository, transitions, shellInit))
+ context, repository, transitions, shellTaskOrganizer, shellInit))
);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
index 240cf3b96e89..1a9c304e2aee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
@@ -38,12 +38,10 @@ import com.android.wm.shell.common.pip.PipMediaController;
import com.android.wm.shell.common.pip.PipPerfHintController;
import com.android.wm.shell.common.pip.PipSnapAlgorithm;
import com.android.wm.shell.common.pip.PipUiEventLogger;
-import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.dagger.WMShellBaseModule;
import com.android.wm.shell.dagger.WMSingleton;
import com.android.wm.shell.onehanded.OneHandedController;
-import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
@@ -79,7 +77,7 @@ import java.util.Optional;
public abstract class Pip1Module {
@WMSingleton
@Provides
- static Optional<Pip> providePip1(Context context,
+ static Optional<PipController.PipImpl> providePip1(Context context,
ShellInit shellInit,
ShellCommandHandler shellCommandHandler,
ShellController shellController,
@@ -104,20 +102,16 @@ public abstract class Pip1Module {
TabletopModeController pipTabletopController,
Optional<OneHandedController> oneHandedController,
@ShellMainThread ShellExecutor mainExecutor) {
- if (PipUtils.isPip2ExperimentEnabled()) {
- return Optional.empty();
- } else {
- return Optional.ofNullable(PipController.create(
- context, shellInit, shellCommandHandler, shellController,
- displayController, pipAnimationController, pipAppOpsListener,
- pipBoundsAlgorithm,
- pipKeepClearAlgorithm, pipBoundsState, pipDisplayLayoutState,
- pipMotionHelper, pipMediaController, phonePipMenuController, pipTaskOrganizer,
- pipTransitionState, pipTouchHandler, pipTransitionController,
- windowManagerShellWrapper, taskStackListener, pipParamsChangedForwarder,
- displayInsetsController, pipTabletopController, oneHandedController,
- mainExecutor));
- }
+ return Optional.ofNullable(PipController.create(
+ context, shellInit, shellCommandHandler, shellController,
+ displayController, pipAnimationController, pipAppOpsListener,
+ pipBoundsAlgorithm,
+ pipKeepClearAlgorithm, pipBoundsState, pipDisplayLayoutState,
+ pipMotionHelper, pipMediaController, phonePipMenuController, pipTaskOrganizer,
+ pipTransitionState, pipTouchHandler, pipTransitionController,
+ windowManagerShellWrapper, taskStackListener, pipParamsChangedForwarder,
+ displayInsetsController, pipTabletopController, oneHandedController,
+ mainExecutor));
}
// Handler is used by Icon.loadDrawableAsync
@@ -212,13 +206,12 @@ public abstract class Pip1Module {
@WMSingleton
@Provides
static PipMotionHelper providePipMotionHelper(Context context,
- @ShellMainThread ShellExecutor mainExecutor,
PipBoundsState pipBoundsState, PipTaskOrganizer pipTaskOrganizer,
PhonePipMenuController menuController, PipSnapAlgorithm pipSnapAlgorithm,
PipTransitionController pipTransitionController,
FloatingContentCoordinator floatingContentCoordinator,
Optional<PipPerfHintController> pipPerfHintControllerOptional) {
- return new PipMotionHelper(context, mainExecutor, pipBoundsState, pipTaskOrganizer,
+ return new PipMotionHelper(context, pipBoundsState, pipTaskOrganizer,
menuController, pipSnapAlgorithm, pipTransitionController,
floatingContentCoordinator, pipPerfHintControllerOptional);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
index 696831747865..ea7e9685dd92 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
@@ -81,6 +81,16 @@ public abstract class Pip2Module {
@WMSingleton
@Provides
+ static Optional<PipController.PipImpl> providePip2(Optional<PipController> pipController) {
+ if (pipController.isEmpty()) {
+ return Optional.empty();
+ } else {
+ return Optional.ofNullable(pipController.get().getPipImpl());
+ }
+ }
+
+ @WMSingleton
+ @Provides
static Optional<PipController> providePipController(Context context,
ShellInit shellInit,
ShellCommandHandler shellCommandHandler,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/PipModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/PipModule.java
index f2631eff890d..a3afe7860f2e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/PipModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/PipModule.java
@@ -18,12 +18,16 @@ package com.android.wm.shell.dagger.pip;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.dagger.WMSingleton;
+import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipTransitionController;
+import com.android.wm.shell.pip2.phone.PipController;
import com.android.wm.shell.pip2.phone.PipTransition;
import dagger.Module;
import dagger.Provides;
+import java.util.Optional;
+
/**
* Provides dependencies for external components / modules reference PiP and extracts away the
* selection of legacy and new PiP implementation.
@@ -44,4 +48,17 @@ public abstract class PipModule {
return legacyPipTransition;
}
}
+
+ @WMSingleton
+ @Provides
+ static Optional<Pip> providePip(
+ Optional<com.android.wm.shell.pip.phone.PipController.PipImpl> pip1,
+ Optional<PipController.PipImpl> pip2) {
+ if (PipUtils.isPip2ExperimentEnabled()) {
+ return Optional.ofNullable(pip2.orElse(null));
+
+ } else {
+ return Optional.ofNullable(pip1.orElse(null));
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
index fbc11c19a5a2..400882a8da9a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
@@ -16,9 +16,9 @@
package com.android.wm.shell.desktopmode
+import com.android.internal.protolog.ProtoLog
import com.android.internal.util.FrameworkStatsLog
import com.android.wm.shell.protolog.ShellProtoLogGroup
-import com.android.wm.shell.util.KtProtoLog
/** Event logger for logging desktop mode session events */
class DesktopModeEventLogger {
@@ -27,7 +27,7 @@ class DesktopModeEventLogger {
* entering desktop mode
*/
fun logSessionEnter(sessionId: Int, enterReason: EnterReason) {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Logging session enter, session: %s reason: %s",
sessionId,
@@ -47,7 +47,7 @@ class DesktopModeEventLogger {
* exiting desktop mode
*/
fun logSessionExit(sessionId: Int, exitReason: ExitReason) {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Logging session exit, session: %s reason: %s",
sessionId,
@@ -67,7 +67,7 @@ class DesktopModeEventLogger {
* session id [sessionId]
*/
fun logTaskAdded(sessionId: Int, taskUpdate: TaskUpdate) {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Logging task added, session: %s taskId: %s",
sessionId,
@@ -99,7 +99,7 @@ class DesktopModeEventLogger {
* session id [sessionId]
*/
fun logTaskRemoved(sessionId: Int, taskUpdate: TaskUpdate) {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Logging task remove, session: %s taskId: %s",
sessionId,
@@ -131,7 +131,7 @@ class DesktopModeEventLogger {
* having session id [sessionId]
*/
fun logTaskInfoChanged(sessionId: Int, taskUpdate: TaskUpdate) {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Logging task info changed, session: %s taskId: %s",
sessionId,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
index a67dee3a4a8d..066b5ad39d0f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
@@ -46,11 +46,10 @@ import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_KEYBOARD_SHORTCUT
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_TASK_DRAG
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.util.KtProtoLog
/**
* A [Transitions.TransitionObserver] that observes transitions and the proposed changes to log
@@ -106,7 +105,7 @@ class DesktopModeLoggerTransitionObserver(
) {
// this was a new recents animation
if (info.isExitToRecentsTransition() && tasksSavedForRecents.isEmpty()) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Recents animation running, saving tasks for later"
)
@@ -132,7 +131,7 @@ class DesktopModeLoggerTransitionObserver(
info.flags == 0 &&
tasksSavedForRecents.isNotEmpty()
) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Canceled recents animation, restoring tasks"
)
@@ -202,7 +201,7 @@ class DesktopModeLoggerTransitionObserver(
}
}
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: taskInfo map after processing changes %s",
postTransitionFreeformTasks.size()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
index 81891ce91e04..247cc42e51ed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
@@ -26,8 +26,8 @@ import android.window.WindowContainerToken
import androidx.core.util.forEach
import androidx.core.util.keyIterator
import androidx.core.util.valueIterator
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
-import com.android.wm.shell.util.KtProtoLog
import java.io.PrintWriter
import java.util.concurrent.Executor
import java.util.function.Consumer
@@ -88,14 +88,17 @@ class DesktopModeTaskRepository {
/** Add a [VisibleTasksListener] to be notified when freeform tasks are visible or not. */
fun addVisibleTasksListener(visibleTasksListener: VisibleTasksListener, executor: Executor) {
visibleTasksListeners[visibleTasksListener] = executor
- displayData.keyIterator().forEach { displayId ->
- val visibleTasksCount = getVisibleTaskCount(displayId)
+ displayData.keyIterator().forEach {
executor.execute {
- visibleTasksListener.onTasksVisibilityChanged(displayId, visibleTasksCount)
+ visibleTasksListener.onTasksVisibilityChanged(it, visibleTaskCount(it))
}
}
}
+ /** Returns a list of all [DisplayData]. */
+ private fun displayDataList(): Sequence<DisplayData> =
+ displayData.valueIterator().asSequence()
+
/**
* Add a Consumer which will inform other classes of changes to exclusion regions for all
* Desktop tasks.
@@ -142,7 +145,7 @@ class DesktopModeTaskRepository {
val added = displayData.getOrCreate(displayId).activeTasks.add(taskId)
if (added) {
- KtProtoLog.d(
+ ProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTaskRepo: add active task=%d displayId=%d",
taskId,
@@ -167,7 +170,7 @@ class DesktopModeTaskRepository {
}
}
if (result) {
- KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remove active task=%d", taskId)
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remove active task=%d", taskId)
}
return result
}
@@ -180,7 +183,7 @@ class DesktopModeTaskRepository {
fun addClosingTask(displayId: Int, taskId: Int): Boolean {
val added = displayData.getOrCreate(displayId).closingTasks.add(taskId)
if (added) {
- KtProtoLog.d(
+ ProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTaskRepo: added closing task=%d displayId=%d",
taskId,
@@ -203,42 +206,22 @@ class DesktopModeTaskRepository {
}
}
if (removed) {
- KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remove closing task=%d", taskId)
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remove closing task=%d", taskId)
}
return removed
}
- /** Check if a task with the given [taskId] was marked as an active task */
- fun isActiveTask(taskId: Int): Boolean {
- return displayData.valueIterator().asSequence().any { data ->
- data.activeTasks.contains(taskId)
- }
- }
-
- /** Check if a task with the given [taskId] was marked as a closing task */
- fun isClosingTask(taskId: Int): Boolean =
- displayData.valueIterator().asSequence().any { data -> taskId in data.closingTasks }
-
- /** Whether a task is visible. */
- fun isVisibleTask(taskId: Int): Boolean {
- return displayData.valueIterator().asSequence().any { data ->
- data.visibleTasks.contains(taskId)
- }
- }
-
- /** Return whether the given Task is minimized. */
- fun isMinimizedTask(taskId: Int): Boolean {
- return displayData.valueIterator().asSequence().any { data ->
- data.minimizedTasks.contains(taskId)
- }
- }
+ fun isActiveTask(taskId: Int) = displayDataList().any { taskId in it.activeTasks }
+ fun isClosingTask(taskId: Int) = displayDataList().any { taskId in it.closingTasks }
+ fun isVisibleTask(taskId: Int) = displayDataList().any { taskId in it.visibleTasks }
+ fun isMinimizedTask(taskId: Int) = displayDataList().any { taskId in it.minimizedTasks }
/**
* Check if a task with the given [taskId] is the only visible, non-closing, not-minimized task
* on its display
*/
fun isOnlyVisibleNonClosingTask(taskId: Int): Boolean =
- displayData.valueIterator().asSequence().any { data ->
+ displayDataList().any { data ->
data.visibleTasks
.subtract(data.closingTasks)
.subtract(data.minimizedTasks)
@@ -250,11 +233,9 @@ class DesktopModeTaskRepository {
return ArraySet(displayData[displayId]?.activeTasks)
}
- /**
- * Returns whether Desktop Mode is currently showing any tasks, i.e. whether any Desktop Tasks
- * are visible.
- */
- fun isDesktopModeShowing(displayId: Int): Boolean = getVisibleTaskCount(displayId) > 0
+ /** Returns the minimized tasks for the given [displayId]. */
+ fun getMinimizedTasks(displayId: Int): ArraySet<Int> =
+ ArraySet(displayData[displayId]?.minimizedTasks)
/**
* Returns a list of Tasks IDs representing all active non-minimized Tasks on the given display,
@@ -301,25 +282,25 @@ class DesktopModeTaskRepository {
return
}
- val prevCount = getVisibleTaskCount(displayId)
+ val prevCount = visibleTaskCount(displayId)
if (visible) {
displayData.getOrCreate(displayId).visibleTasks.add(taskId)
unminimizeTask(displayId, taskId)
} else {
displayData[displayId]?.visibleTasks?.remove(taskId)
}
- val newCount = getVisibleTaskCount(displayId)
+ val newCount = visibleTaskCount(displayId)
// Check if count changed
if (prevCount != newCount) {
- KtProtoLog.d(
+ ProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTaskRepo: update task visibility taskId=%d visible=%b displayId=%d",
taskId,
visible,
displayId
)
- KtProtoLog.d(
+ ProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTaskRepo: visibleTaskCount has changed from %d to %d",
prevCount,
@@ -336,8 +317,8 @@ class DesktopModeTaskRepository {
}
/** Get number of tasks that are marked as visible on given [displayId] */
- fun getVisibleTaskCount(displayId: Int): Int {
- KtProtoLog.d(
+ fun visibleTaskCount(displayId: Int): Int {
+ ProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTaskRepo: visibleTaskCount= %d",
displayData[displayId]?.visibleTasks?.size ?: 0
@@ -349,7 +330,7 @@ class DesktopModeTaskRepository {
// TODO(b/342417921): Identify if there is additional checks needed to move tasks for
// multi-display scenarios.
fun addOrMoveFreeformTaskToTop(displayId: Int, taskId: Int) {
- KtProtoLog.d(
+ ProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTaskRepo: add or move task to top: display=%d, taskId=%d",
displayId,
@@ -361,7 +342,7 @@ class DesktopModeTaskRepository {
/** Mark a Task as minimized. */
fun minimizeTask(displayId: Int, taskId: Int) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopModeTaskRepository: minimize Task: display=%d, task=%d",
displayId,
@@ -372,7 +353,7 @@ class DesktopModeTaskRepository {
/** Mark a Task as non-minimized. */
fun unminimizeTask(displayId: Int, taskId: Int) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopModeTaskRepository: unminimize Task: display=%d, task=%d",
displayId,
@@ -383,7 +364,7 @@ class DesktopModeTaskRepository {
/** Remove the task from the ordered list. */
fun removeFreeformTask(displayId: Int, taskId: Int) {
- KtProtoLog.d(
+ ProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTaskRepo: remove freeform task from ordered list: display=%d, taskId=%d",
displayId,
@@ -391,7 +372,7 @@ class DesktopModeTaskRepository {
)
displayData[displayId]?.freeformTasksInZOrder?.remove(taskId)
boundsBeforeMaximizeByTaskId.remove(taskId)
- KtProtoLog.d(
+ ProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTaskRepo: remaining freeform tasks: %s",
displayData[displayId]?.freeformTasksInZOrder?.toDumpString() ?: ""
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 d8e8c57148ab..9a1a8a20ae0e 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
@@ -50,6 +50,7 @@ import android.window.WindowContainerTransaction
import androidx.annotation.BinderThread
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.policy.ScreenDecorationsUtils
+import com.android.internal.protolog.ProtoLog
import com.android.window.flags.Flags
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
@@ -66,7 +67,7 @@ import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
-import com.android.wm.shell.compatui.isSingleTopActivityTranslucent
+import com.android.wm.shell.compatui.isTopActivityExemptFromDesktopWindowing
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.DragToDesktopStateListener
import com.android.wm.shell.draganddrop.DragAndDropController
@@ -74,9 +75,9 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.recents.RecentTasksController
import com.android.wm.shell.recents.RecentsTransitionHandler
import com.android.wm.shell.recents.RecentsTransitionStateListener
-import com.android.wm.shell.shared.DesktopModeStatus
-import com.android.wm.shell.shared.DesktopModeStatus.DESKTOP_DENSITY_OVERRIDE
-import com.android.wm.shell.shared.DesktopModeStatus.useDesktopOverrideDensity
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.DESKTOP_DENSITY_OVERRIDE
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.useDesktopOverrideDensity
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.shared.annotations.ExternalThread
import com.android.wm.shell.shared.annotations.ShellMainThread
@@ -88,7 +89,6 @@ import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.sysui.ShellSharedConstants
import com.android.wm.shell.transition.OneShotRemoteHandler
import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.util.KtProtoLog
import com.android.wm.shell.windowdecor.DragPositioningCallbackUtility
import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
@@ -158,20 +158,6 @@ class DesktopTasksController(
visualIndicator = null
}
}
- private val sysUIPackageName = context.resources.getString(
- com.android.internal.R.string.config_systemUi)
-
- private val transitionAreaHeight
- get() =
- context.resources.getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_height
- )
-
- private val transitionAreaWidth
- get() =
- context.resources.getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_transition_area_width
- )
/** Task id of the task currently being dragged from fullscreen/split. */
val draggingTaskId
@@ -188,7 +174,7 @@ class DesktopTasksController(
}
private fun onInit() {
- KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopTasksController")
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopTasksController")
shellCommandHandler.addDumpCallback(this::dump, this)
shellCommandHandler.addCommandCallback("desktopmode", desktopModeShellCommandHandler, this)
shellController.addExternalInterface(
@@ -202,7 +188,7 @@ class DesktopTasksController(
recentsTransitionHandler.addTransitionStateListener(
object : RecentsTransitionStateListener {
override fun onAnimationStateChanged(running: Boolean) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: recents animation state changed running=%b",
running
@@ -219,11 +205,6 @@ class DesktopTasksController(
return visualIndicator
}
- // TODO(b/347289970): Consider replacing with API
- private fun isSystemUIApplication(taskInfo: RunningTaskInfo): Boolean {
- return taskInfo.baseActivity?.packageName == sysUIPackageName
- }
-
fun setOnTaskResizeAnimationListener(listener: OnTaskResizeAnimationListener) {
toggleResizeDesktopTaskTransitionHandler.setOnTaskResizeAnimationListener(listener)
enterDesktopTaskTransitionHandler.setOnTaskResizeAnimationListener(listener)
@@ -236,15 +217,23 @@ class DesktopTasksController(
dragToDesktopTransitionHandler.setSplitScreenController(controller)
}
+ /** Returns the transition type for the given remote transition. */
+ private fun transitionType(remoteTransition: RemoteTransition?): Int {
+ if (remoteTransition == null) {
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: remoteTransition is null")
+ return TRANSIT_NONE
+ }
+ return TRANSIT_TO_FRONT
+ }
+
/** Show all tasks, that are part of the desktop, on top of launcher */
fun showDesktopApps(displayId: Int, remoteTransition: RemoteTransition? = null) {
- KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: showDesktopApps")
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: showDesktopApps")
val wct = WindowContainerTransaction()
bringDesktopAppsToFront(displayId, wct)
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- // TODO(b/309014605): ensure remote transition is supplied once state is introduced
- val transitionType = if (remoteTransition == null) TRANSIT_NONE else TRANSIT_TO_FRONT
+ val transitionType = transitionType(remoteTransition)
val handler =
remoteTransition?.let {
OneShotRemoteHandler(transitions.mainExecutor, remoteTransition)
@@ -257,10 +246,12 @@ class DesktopTasksController(
}
}
- /** Get number of tasks that are marked as visible */
- fun getVisibleTaskCount(displayId: Int): Int {
- return desktopModeTaskRepository.getVisibleTaskCount(displayId)
- }
+ /** Gets number of visible tasks in [displayId]. */
+ fun visibleTaskCount(displayId: Int): Int =
+ desktopModeTaskRepository.visibleTaskCount(displayId)
+
+ /** Returns true if any tasks are visible in Desktop Mode. */
+ fun isDesktopModeShowing(displayId: Int): Boolean = visibleTaskCount(displayId) > 0
/** Enter desktop by using the focused task in given `displayId` */
fun moveFocusedTaskToDesktop(displayId: Int, transitionSource: DesktopModeTransitionSource) {
@@ -289,7 +280,7 @@ class DesktopTasksController(
moveToDesktop(allFocusedTasks[0].taskId, transitionSource = transitionSource)
}
else -> {
- KtProtoLog.w(
+ ProtoLog.w(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: Cannot enter desktop, expected less " +
"than 3 focused tasks but found %d",
@@ -319,7 +310,7 @@ class DesktopTasksController(
transitionSource: DesktopModeTransitionSource,
): Boolean {
recentTasksController?.findTaskInBackground(taskId)?.let {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: moveToDesktopFromNonRunningTask taskId=%d",
taskId
@@ -351,23 +342,16 @@ class DesktopTasksController(
wct: WindowContainerTransaction = WindowContainerTransaction(),
transitionSource: DesktopModeTransitionSource,
) {
- if (Flags.enableDesktopWindowingModalsPolicy() && isSingleTopActivityTranslucent(task)) {
- KtProtoLog.w(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: Cannot enter desktop, " +
- "translucent top activity found. This is likely a modal dialog."
- )
- return
- }
- if (isSystemUIApplication(task)) {
- KtProtoLog.w(
+ if (Flags.enableDesktopWindowingModalsPolicy()
+ && isTopActivityExemptFromDesktopWindowing(context, task)) {
+ ProtoLog.w(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: Cannot enter desktop, " +
- "systemUI top activity found."
+ "ineligible top activity found."
)
return
}
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: moveToDesktop taskId=%d",
task.taskId
@@ -394,7 +378,7 @@ class DesktopTasksController(
taskInfo: RunningTaskInfo,
dragToDesktopValueAnimator: MoveToDesktopAnimator,
) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: startDragToDesktop taskId=%d",
taskInfo.taskId
@@ -410,14 +394,14 @@ class DesktopTasksController(
* [startDragToDesktop].
*/
private fun finalizeDragToDesktop(taskInfo: RunningTaskInfo, freeformBounds: Rect) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: finalizeDragToDesktop taskId=%d",
taskInfo.taskId
)
val wct = WindowContainerTransaction()
exitSplitIfApplicable(wct, taskInfo)
- moveHomeTaskToFront(wct)
+ moveHomeTask(wct, toTop = true)
val taskToMinimize =
bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId)
addMoveToDesktopChanges(wct, taskInfo)
@@ -454,7 +438,7 @@ class DesktopTasksController(
}
if (!desktopModeTaskRepository.addClosingTask(displayId, taskId)) {
// Could happen if the task hasn't been removed from closing list after it disappeared
- KtProtoLog.w(
+ ProtoLog.w(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: the task with taskId=%d is already closing!",
taskId
@@ -478,7 +462,7 @@ class DesktopTasksController(
/** Move a desktop app to split screen. */
fun moveToSplit(task: RunningTaskInfo) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: moveToSplit taskId=%d",
task.taskId
@@ -511,7 +495,7 @@ class DesktopTasksController(
* [startDragToDesktop].
*/
fun cancelDragToDesktop(task: RunningTaskInfo) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: cancelDragToDesktop taskId=%d",
task.taskId
@@ -526,7 +510,7 @@ class DesktopTasksController(
position: Point,
transitionSource: DesktopModeTransitionSource
) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: moveToFullscreen with animation taskId=%d",
task.taskId
@@ -554,7 +538,7 @@ class DesktopTasksController(
/** Move a task to the front */
fun moveTaskToFront(taskInfo: RunningTaskInfo) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: moveTaskToFront taskId=%d",
taskInfo.taskId
@@ -585,10 +569,10 @@ class DesktopTasksController(
fun moveToNextDisplay(taskId: Int) {
val task = shellTaskOrganizer.getRunningTaskInfo(taskId)
if (task == null) {
- KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: taskId=%d not found", taskId)
+ ProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: taskId=%d not found", taskId)
return
}
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"moveToNextDisplay: taskId=%d taskDisplayId=%d",
taskId,
@@ -603,7 +587,7 @@ class DesktopTasksController(
newDisplayId = displayIds.firstOrNull { displayId -> displayId < task.displayId }
}
if (newDisplayId == null) {
- KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: next display not found")
+ ProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: next display not found")
return
}
moveToDisplay(task, newDisplayId)
@@ -615,7 +599,7 @@ class DesktopTasksController(
* No-op if task is already on that display per [RunningTaskInfo.displayId].
*/
private fun moveToDisplay(task: RunningTaskInfo, displayId: Int) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"moveToDisplay: taskId=%d displayId=%d",
task.taskId,
@@ -623,13 +607,13 @@ class DesktopTasksController(
)
if (task.displayId == displayId) {
- KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "moveToDisplay: task already on display")
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "moveToDisplay: task already on display")
return
}
val displayAreaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)
if (displayAreaInfo == null) {
- KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToDisplay: display not found")
+ ProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToDisplay: display not found")
return
}
@@ -784,18 +768,19 @@ class DesktopTasksController(
wct: WindowContainerTransaction,
newTaskIdInFront: Int? = null
): RunningTaskInfo? {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: bringDesktopAppsToFront, newTaskIdInFront=%s",
newTaskIdInFront ?: "null"
)
- if (Flags.enableDesktopWindowingWallpaperActivity()) {
+ // Move home to front, ensures that we go back home when all desktop windows are closed
+ moveHomeTask(wct, toTop = true)
+
+ // Currently, we only handle the desktop on the default display really.
+ if (displayId == DEFAULT_DISPLAY && Flags.enableDesktopWindowingWallpaperActivity()) {
// Add translucent wallpaper activity to show the wallpaper underneath
addWallpaperActivity(wct)
- } else {
- // Move home to front
- moveHomeTaskToFront(wct)
}
val nonMinimizedTasksOrderedFrontToBack =
@@ -821,15 +806,15 @@ class DesktopTasksController(
return taskToMinimize
}
- private fun moveHomeTaskToFront(wct: WindowContainerTransaction) {
+ private fun moveHomeTask(wct: WindowContainerTransaction, toTop: Boolean) {
shellTaskOrganizer
.getRunningTasks(context.displayId)
.firstOrNull { task -> task.activityType == ACTIVITY_TYPE_HOME }
- ?.let { homeTask -> wct.reorder(homeTask.getToken(), true /* onTop */) }
+ ?.let { homeTask -> wct.reorder(homeTask.getToken(), toTop /* onTop */) }
}
private fun addWallpaperActivity(wct: WindowContainerTransaction) {
- KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: addWallpaper")
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: addWallpaper")
val intent = Intent(context, DesktopWallpaperActivity::class.java)
val options =
ActivityOptions.makeBasic().apply {
@@ -849,7 +834,7 @@ class DesktopTasksController(
private fun removeWallpaperActivity(wct: WindowContainerTransaction) {
desktopModeTaskRepository.wallpaperActivityToken?.let { token ->
- KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: removeWallpaper")
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: removeWallpaper")
wct.removeTask(token)
}
}
@@ -887,7 +872,7 @@ class DesktopTasksController(
transition: IBinder,
request: TransitionRequestInfo
): WindowContainerTransaction? {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: handleRequest request=%s",
request
@@ -929,7 +914,7 @@ class DesktopTasksController(
}
if (!shouldHandleRequest) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: skipping handleRequest reason=%s",
reason
@@ -942,10 +927,8 @@ class DesktopTasksController(
when {
// Check if the closing task needs to be handled
TransitionUtil.isClosingType(request.type) -> handleTaskClosing(task)
- // Check if the task has a top transparent activity
- shouldLaunchAsModal(task) -> handleIncompatibleTaskLaunch(task)
- // Check if the task has a top systemUI activity
- isSystemUIApplication(task) -> handleIncompatibleTaskLaunch(task)
+ // Check if the top task shouldn't be allowed to enter desktop mode
+ isIncompatibleTask(task) -> handleIncompatibleTaskLaunch(task)
// Check if fullscreen task should be updated
task.isFullscreen -> handleFullscreenTaskLaunch(task, transition)
// Check if freeform task should be updated
@@ -955,7 +938,7 @@ class DesktopTasksController(
}
}
}
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: handleRequest result=%s",
result ?: "null"
@@ -979,9 +962,9 @@ class DesktopTasksController(
.forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) }
}
- // TODO(b/347289970): Consider replacing with API
- private fun shouldLaunchAsModal(task: TaskInfo) =
- Flags.enableDesktopWindowingModalsPolicy() && isSingleTopActivityTranslucent(task)
+ private fun isIncompatibleTask(task: TaskInfo) =
+ Flags.enableDesktopWindowingModalsPolicy()
+ && isTopActivityExemptFromDesktopWindowing(context, task)
private fun shouldHandleTaskClosing(request: TransitionRequestInfo): Boolean {
return Flags.enableDesktopWindowingWallpaperActivity() &&
@@ -993,15 +976,15 @@ class DesktopTasksController(
task: RunningTaskInfo,
transition: IBinder
): WindowContainerTransaction? {
- KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFreeformTaskLaunch")
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFreeformTaskLaunch")
if (keyguardManager.isKeyguardLocked) {
// Do NOT handle freeform task launch when locked.
// It will be launched in fullscreen windowing mode (Details: b/160925539)
- KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: skip keyguard is locked")
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: skip keyguard is locked")
return null
}
- if (!desktopModeTaskRepository.isDesktopModeShowing(task.displayId)) {
- KtProtoLog.d(
+ if (!isDesktopModeShowing(task.displayId)) {
+ ProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: bring desktop tasks to front on transition" +
" taskId=%d",
@@ -1030,9 +1013,9 @@ class DesktopTasksController(
task: RunningTaskInfo,
transition: IBinder
): WindowContainerTransaction? {
- KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFullscreenTaskLaunch")
- if (desktopModeTaskRepository.isDesktopModeShowing(task.displayId)) {
- KtProtoLog.d(
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFullscreenTaskLaunch")
+ if (isDesktopModeShowing(task.displayId)) {
+ ProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: switch fullscreen task to freeform on transition" +
" taskId=%d",
@@ -1040,6 +1023,9 @@ class DesktopTasksController(
)
return WindowContainerTransaction().also { wct ->
addMoveToDesktopChanges(wct, task)
+ // In some launches home task is moved behind new task being launched. Make sure
+ // that's not the case for launches in desktop.
+ moveHomeTask(wct, toTop = false)
// Desktop Mode is already showing and we're launching a new Task - we might need to
// minimize another Task.
val taskToMinimize = addAndGetMinimizeChangesIfNeeded(task.displayId, wct, task)
@@ -1061,24 +1047,27 @@ class DesktopTasksController(
/** Handle task closing by removing wallpaper activity if it's the last active task */
private fun handleTaskClosing(task: RunningTaskInfo): WindowContainerTransaction? {
- val wct = if (
- desktopModeTaskRepository.isOnlyVisibleNonClosingTask(task.taskId) &&
- desktopModeTaskRepository.wallpaperActivityToken != null
- ) {
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleTaskClosing")
+ val wct = WindowContainerTransaction()
+ if (desktopModeTaskRepository.isOnlyVisibleNonClosingTask(task.taskId)
+ && desktopModeTaskRepository.wallpaperActivityToken != null) {
// Remove wallpaper activity when the last active task is removed
- WindowContainerTransaction().also { wct -> removeWallpaperActivity(wct) }
- } else {
- null
+ removeWallpaperActivity(wct)
}
if (!desktopModeTaskRepository.addClosingTask(task.displayId, task.taskId)) {
// Could happen if the task hasn't been removed from closing list after it disappeared
- KtProtoLog.w(
+ ProtoLog.w(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: the task with taskId=%d is already closing!",
task.taskId
)
}
- return wct
+ // If a CLOSE or TO_BACK is triggered on a desktop task, remove the task.
+ if (Flags.enableDesktopWindowingBackNavigation() &&
+ desktopModeTaskRepository.isVisibleTask(task.taskId)) {
+ wct.removeTask(task.token)
+ }
+ return if (wct.isEmpty) null else wct
}
private fun addMoveToDesktopChanges(
@@ -1123,6 +1112,10 @@ class DesktopTasksController(
if (useDesktopOverrideDensity()) {
wct.setDensityDpi(taskInfo.token, getDefaultDensityDpi())
}
+ if (desktopModeTaskRepository.isOnlyVisibleNonClosingTask(taskInfo.taskId)) {
+ // Remove wallpaper activity when leaving desktop mode
+ removeWallpaperActivity(wct)
+ }
}
/**
@@ -1138,6 +1131,10 @@ class DesktopTasksController(
// The task's density may have been overridden in freeform; revert it here as we don't
// want it overridden in multi-window.
wct.setDensityDpi(taskInfo.token, getDefaultDensityDpi())
+ if (desktopModeTaskRepository.isOnlyVisibleNonClosingTask(taskInfo.taskId)) {
+ // Remove wallpaper activity when leaving desktop mode
+ removeWallpaperActivity(wct)
+ }
}
/** Returns the ID of the Task that will be minimized, or null if no task will be minimized. */
@@ -1401,8 +1398,7 @@ class DesktopTasksController(
onFinishCallback: Consumer<Boolean>
): Boolean {
// TODO(b/320797628): Pass through which display we are dropping onto
- val activeTasks = desktopModeTaskRepository.getActiveTasks(DEFAULT_DISPLAY)
- if (!activeTasks.any { desktopModeTaskRepository.isVisibleTask(it) }) {
+ if (!isDesktopModeShowing(DEFAULT_DISPLAY)) {
// Not currently in desktop mode, ignore the drop
return false
}
@@ -1411,7 +1407,7 @@ class DesktopTasksController(
if (!multiInstanceHelper.supportsMultiInstanceSplit(launchComponent)) {
// TODO(b/320797628): Should only return early if there is an existing running task, and
// notify the user as well. But for now, just ignore the drop.
- KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "Dropped intent does not support multi-instance")
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "Dropped intent does not support multi-instance")
return false
}
@@ -1502,7 +1498,7 @@ class DesktopTasksController(
private val listener: VisibleTasksListener =
object : VisibleTasksListener {
override fun onTasksVisibilityChanged(displayId: Int, visibleTasksCount: Int) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"IDesktopModeImpl: onVisibilityChanged display=%d visible=%d",
displayId,
@@ -1547,11 +1543,11 @@ class DesktopTasksController(
}
override fun stashDesktopApps(displayId: Int) {
- KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "IDesktopModeImpl: stashDesktopApps is deprecated")
+ ProtoLog.w(WM_SHELL_DESKTOP_MODE, "IDesktopModeImpl: stashDesktopApps is deprecated")
}
override fun hideStashedDesktopApps(displayId: Int) {
- KtProtoLog.w(
+ ProtoLog.w(
WM_SHELL_DESKTOP_MODE,
"IDesktopModeImpl: hideStashedDesktopApps is deprecated"
)
@@ -1561,8 +1557,8 @@ class DesktopTasksController(
val result = IntArray(1)
executeRemoteCallWithTaskPermission(
controller,
- "getVisibleTaskCount",
- { controller -> result[0] = controller.getVisibleTaskCount(displayId) },
+ "visibleTaskCount",
+ { controller -> result[0] = controller.visibleTaskCount(displayId) },
true /* blocking */
)
return result[0]
@@ -1578,7 +1574,7 @@ class DesktopTasksController(
}
override fun setTaskListener(listener: IDesktopTaskListener?) {
- KtProtoLog.v(
+ ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"IDesktopModeImpl: set task listener=%s",
listener ?: "null"
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 0f88384ec2ac..534cc22ada47 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
@@ -23,12 +23,12 @@ import android.view.WindowManager.TRANSIT_TO_BACK
import android.window.TransitionInfo
import android.window.WindowContainerTransaction
import androidx.annotation.VisibleForTesting
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.protolog.ShellProtoLogGroup
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.transition.Transitions.TransitionObserver
-import com.android.wm.shell.util.KtProtoLog
/**
* Limits the number of tasks shown in Desktop Mode.
@@ -42,9 +42,12 @@ class DesktopTasksLimiter (
private val shellTaskOrganizer: ShellTaskOrganizer,
) {
private val minimizeTransitionObserver = MinimizeTransitionObserver()
+ @VisibleForTesting
+ val leftoverMinimizedTasksRemover = LeftoverMinimizedTasksRemover()
init {
transitions.registerObserver(minimizeTransitionObserver)
+ taskRepository.addActiveTaskListener(leftoverMinimizedTasksRemover)
}
private data class TaskDetails (val displayId: Int, val taskId: Int)
@@ -68,7 +71,7 @@ class DesktopTasksLimiter (
if (!taskRepository.isActiveTask(taskToMinimize.taskId)) return
if (!isTaskReorderedToBackOrInvisible(info, taskToMinimize)) {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopTasksLimiter: task %d is not reordered to back nor invis",
taskToMinimize.taskId)
@@ -106,19 +109,48 @@ class DesktopTasksLimiter (
}
override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopTasksLimiter: transition %s finished", transition)
mPendingTransitionTokensAndTasks.remove(transition)
}
}
+ @VisibleForTesting
+ inner class LeftoverMinimizedTasksRemover : DesktopModeTaskRepository.ActiveTasksListener {
+ override fun onActiveTasksChanged(displayId: Int) {
+ val wct = WindowContainerTransaction()
+ removeLeftoverMinimizedTasks(displayId, wct)
+ shellTaskOrganizer.applyTransaction(wct)
+ }
+
+ fun removeLeftoverMinimizedTasks(displayId: Int, wct: WindowContainerTransaction) {
+ if (taskRepository
+ .getActiveNonMinimizedTasksOrderedFrontToBack(displayId).isNotEmpty()) {
+ return
+ }
+ val remainingMinimizedTasks = taskRepository.getMinimizedTasks(displayId)
+ if (remainingMinimizedTasks.isEmpty()) {
+ return
+ }
+ ProtoLog.v(
+ ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksLimiter: removing leftover minimized tasks: $remainingMinimizedTasks")
+ remainingMinimizedTasks.forEach { taskIdToRemove ->
+ val taskToRemove = shellTaskOrganizer.getRunningTaskInfo(taskIdToRemove)
+ if (taskToRemove != null) {
+ wct.removeTask(taskToRemove.token)
+ }
+ }
+ }
+ }
+
/**
* Mark a task as minimized, this should only be done after the corresponding transition has
* finished so we don't minimize the task if the transition fails.
*/
private fun markTaskMinimized(displayId: Int, taskId: Int) {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopTasksLimiter: marking %d as minimized", taskId)
taskRepository.minimizeTask(displayId, taskId)
@@ -137,7 +169,7 @@ class DesktopTasksLimiter (
wct: WindowContainerTransaction,
newFrontTaskInfo: RunningTaskInfo,
): RunningTaskInfo? {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopTasksLimiter: addMinimizeBackTaskChangesIfNeeded, newFrontTask=%d",
newFrontTaskInfo.taskId)
@@ -185,7 +217,7 @@ class DesktopTasksLimiter (
visibleFreeformTaskIdsOrderedFrontToBack: List<Int>
): RunningTaskInfo? {
if (visibleFreeformTaskIdsOrderedFrontToBack.size <= getMaxTaskLimit()) {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopTasksLimiter: no need to minimize; tasks below limit")
// No need to minimize anything
@@ -195,7 +227,7 @@ class DesktopTasksLimiter (
shellTaskOrganizer.getRunningTaskInfo(
visibleFreeformTaskIdsOrderedFrontToBack.last())
if (taskToMinimize == null) {
- KtProtoLog.e(
+ ProtoLog.e(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopTasksLimiter: taskToMinimize == null")
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 dae75f90e3ae..246fd9281975 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
@@ -21,35 +21,38 @@ import android.os.IBinder
import android.view.SurfaceControl
import android.view.WindowManager
import android.window.TransitionInfo
+import android.window.WindowContainerTransaction
+import com.android.internal.protolog.ProtoLog
import com.android.window.flags.Flags.enableDesktopWindowingWallpaperActivity
+import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
-import com.android.wm.shell.shared.DesktopModeStatus
+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.util.KtProtoLog
/**
- * A [Transitions.TransitionObserver] that observes shell transitions and updates
- * the [DesktopModeTaskRepository] state TODO: b/332682201
- * This observes transitions related to desktop mode
- * and other transitions that originate both within and outside shell.
+ * A [Transitions.TransitionObserver] that observes shell transitions and updates the
+ * [DesktopModeTaskRepository] state TODO: b/332682201 This observes transitions related to desktop
+ * mode and other transitions that originate both within and outside shell.
*/
class DesktopTasksTransitionObserver(
context: Context,
private val desktopModeTaskRepository: DesktopModeTaskRepository,
private val transitions: Transitions,
+ private val shellTaskOrganizer: ShellTaskOrganizer,
shellInit: ShellInit
) : Transitions.TransitionObserver {
init {
- if (Transitions.ENABLE_SHELL_TRANSITIONS &&
- DesktopModeStatus.canEnterDesktopMode(context)) {
+ if (
+ Transitions.ENABLE_SHELL_TRANSITIONS && DesktopModeStatus.canEnterDesktopMode(context)
+ ) {
shellInit.addInitCallback(::onInit, this)
}
}
fun onInit() {
- KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTasksTransitionObserver: onInit")
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTasksTransitionObserver: onInit")
transitions.registerObserver(this)
}
@@ -83,8 +86,16 @@ class DesktopTasksTransitionObserver(
change.taskInfo?.let { taskInfo ->
if (DesktopWallpaperActivity.isWallpaperTask(taskInfo)) {
when (change.mode) {
- WindowManager.TRANSIT_OPEN ->
+ WindowManager.TRANSIT_OPEN -> {
desktopModeTaskRepository.wallpaperActivityToken = taskInfo.token
+ // After the task for the wallpaper is created, set it non-trimmable.
+ // This is important to prevent recents from trimming and removing the
+ // task.
+ shellTaskOrganizer.applyTransaction(
+ WindowContainerTransaction()
+ .setTaskTrimmableFromRecents(taskInfo.token, false)
+ )
+ }
WindowManager.TRANSIT_CLOSE ->
desktopModeTaskRepository.wallpaperActivityToken = null
else -> {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
index c4a4474689fa..1c2415c236ad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
@@ -21,8 +21,8 @@ import android.app.ActivityManager
import android.content.ComponentName
import android.os.Bundle
import android.view.WindowManager
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
-import com.android.wm.shell.util.KtProtoLog
/**
* A transparent activity used in the desktop mode to show the wallpaper under the freeform windows.
@@ -36,7 +36,7 @@ import com.android.wm.shell.util.KtProtoLog
class DesktopWallpaperActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
- KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopWallpaperActivity: onCreate")
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopWallpaperActivity: onCreate")
super.onCreate(savedInstanceState)
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
}
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 d99b724c936f..ddee8fac8f44 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
@@ -29,6 +29,7 @@ import android.window.TransitionInfo.Change
import android.window.TransitionRequestInfo
import android.window.WindowContainerToken
import android.window.WindowContainerTransaction
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
@@ -42,7 +43,6 @@ import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_CANCEL_D
import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP
import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP
import com.android.wm.shell.transition.Transitions.TransitionHandler
-import com.android.wm.shell.util.KtProtoLog
import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
import com.android.wm.shell.windowdecor.MoveToDesktopAnimator.Companion.DRAG_FREEFORM_SCALE
import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
@@ -114,7 +114,7 @@ class DragToDesktopTransitionHandler(
dragToDesktopAnimator: MoveToDesktopAnimator,
) {
if (inProgress) {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DragToDesktop: Drag to desktop transition already in progress."
)
@@ -599,7 +599,7 @@ class DragToDesktopTransitionHandler(
) {
val state = transitionState ?: return
if (aborted && state.startTransitionToken == transition) {
- KtProtoLog.v(
+ ProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DragToDesktop: onTransitionConsumed() start transition aborted"
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
index 891f75cfdbda..171378f9a164 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
@@ -42,6 +42,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.jank.Cuj;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource;
import com.android.wm.shell.transition.Transitions;
@@ -60,6 +62,7 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
private final Context mContext;
private final Transitions mTransitions;
+ private final InteractionJankMonitor mInteractionJankMonitor;
private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
private Consumer<SurfaceControl.Transaction> mOnAnimationFinishedCallback;
private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
@@ -67,17 +70,21 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
public ExitDesktopTaskTransitionHandler(
Transitions transitions,
- Context context) {
- this(transitions, SurfaceControl.Transaction::new, context);
+ Context context,
+ InteractionJankMonitor interactionJankMonitor
+ ) {
+ this(transitions, SurfaceControl.Transaction::new, context, interactionJankMonitor);
}
private ExitDesktopTaskTransitionHandler(
Transitions transitions,
Supplier<SurfaceControl.Transaction> supplier,
- Context context) {
+ Context context,
+ InteractionJankMonitor interactionJankMonitor) {
mTransitions = transitions;
mTransactionSupplier = supplier;
mContext = context;
+ mInteractionJankMonitor = interactionJankMonitor;
}
/**
@@ -146,6 +153,8 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
final int screenHeight = metrics.heightPixels;
final SurfaceControl sc = change.getLeash();
final Rect endBounds = change.getEndAbsBounds();
+ mInteractionJankMonitor
+ .begin(sc, mContext, Cuj.CUJ_DESKTOP_MODE_EXIT_MODE);
// Hide the first (fullscreen) frame because the animation will start from the freeform
// size.
startT.hide(sc)
@@ -175,6 +184,7 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
if (mOnAnimationFinishedCallback != null) {
mOnAnimationFinishedCallback.accept(finishT);
}
+ mInteractionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_EXIT_MODE);
mTransitions.getMainExecutor().execute(
() -> finishCallback.onTransitionFinished(null));
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
index 5335c0b69a24..c35d77a1d74a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
@@ -28,7 +28,7 @@ import android.window.TransitionRequestInfo
import android.window.WindowContainerTransaction
import androidx.core.animation.addListener
import com.android.internal.jank.Cuj
-import com.android.wm.shell.common.InteractionJankMonitorUtils
+import com.android.internal.jank.InteractionJankMonitor
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE
import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
@@ -37,7 +37,8 @@ import java.util.function.Supplier
/** Handles the animation of quick resizing of desktop tasks. */
class ToggleResizeDesktopTaskTransitionHandler(
private val transitions: Transitions,
- private val transactionSupplier: Supplier<SurfaceControl.Transaction>
+ private val transactionSupplier: Supplier<SurfaceControl.Transaction>,
+ private val interactionJankMonitor: InteractionJankMonitor
) : Transitions.TransitionHandler {
private val rectEvaluator = RectEvaluator(Rect())
@@ -46,8 +47,9 @@ class ToggleResizeDesktopTaskTransitionHandler(
private var boundsAnimator: Animator? = null
constructor(
- transitions: Transitions
- ) : this(transitions, Supplier { SurfaceControl.Transaction() })
+ transitions: Transitions,
+ interactionJankMonitor: InteractionJankMonitor
+ ) : this(transitions, Supplier { SurfaceControl.Transaction() }, interactionJankMonitor)
/** Starts a quick resize transition. */
fun startTransition(wct: WindowContainerTransaction) {
@@ -105,7 +107,7 @@ class ToggleResizeDesktopTaskTransitionHandler(
onTaskResizeAnimationListener.onAnimationEnd(taskId)
finishCallback.onTransitionFinished(null)
boundsAnimator = null
- InteractionJankMonitorUtils.endTracing(
+ interactionJankMonitor.end(
Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW)
}
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
index b1cbe8d98397..84f6af4125b8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
@@ -68,7 +68,7 @@ adb shell dumpsys SurfaceFlinger
## Tracing global SurfaceControl transaction updates
While Winscope traces are very useful, it sometimes doesn't give you enough information about which
-part of the code is initiating the transaction updates. In such cases, it can be helpful to get
+part of the code is initiating the transaction updates. In such cases, it can be helpful to get
stack traces when specific surface transaction calls are made, which is possible by enabling the
following system properties for example:
```shell
@@ -81,9 +81,11 @@ adb logcat -s "SurfaceControlRegistry"
# Disabling logging
adb shell setprop persist.wm.debug.sc.tx.log_match_call \"\"
adb shell setprop persist.wm.debug.sc.tx.log_match_name \"\"
-adb reboot
```
+A reboot is required to enable the logging. Once enabled, reboot is not needed to update the
+properties.
+
It is not necessary to set both `log_match_call` and `log_match_name`, but note logs can be quite
noisy if unfiltered.
@@ -97,7 +99,7 @@ adb reboot
adb logcat -s "SurfaceControlRegistry"
```
-## Tracing activity starts in the app process
+## Tracing activity starts & finishes in the app process
It's sometimes useful to know when to see a stack trace of when an activity starts in the app code
(ie. if you are repro'ing a bug related to activity starts). You can enable this system property to
@@ -113,6 +115,19 @@ adb shell setprop persist.wm.debug.start_activity \"\"
adb reboot
```
+Likewise, to trace where a finish() call may be made in the app process, you can enable this system
+property:
+```shell
+# Enabling
+adb shell setprop persist.wm.debug.finish_activity true
+adb reboot
+adb logcat -s "Instrumentation"
+
+# Disabling
+adb shell setprop persist.wm.debug.finish_activity \"\"
+adb reboot
+```
+
## Dumps
Because the Shell library is built as a part of SystemUI, dumping the state is currently done as a
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
index b3c3a3dcf272..e00353d6ac82 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
@@ -52,6 +52,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
+import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import androidx.annotation.BinderThread;
@@ -301,7 +302,7 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
break;
}
}
- if (pd == null || !pd.isHandlingDrag) {
+ if (pd == null || pd.activeDragCount <= 0 || !pd.isHandlingDrag) {
// Not currently dragging
return;
}
@@ -332,9 +333,10 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
mActiveDragDisplay = displayId;
pd.isHandlingDrag = DragUtils.canHandleDrag(event);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
- "Clip description: handlingDrag=%b itemCount=%d mimeTypes=%s",
+ "Clip description: handlingDrag=%b itemCount=%d mimeTypes=%s flags=%s",
pd.isHandlingDrag, event.getClipData().getItemCount(),
- DragUtils.getMimeTypesConcatenated(description));
+ DragUtils.getMimeTypesConcatenated(description),
+ DragUtils.dragFlagsToString(event.getDragFlags()));
}
if (!pd.isHandlingDrag) {
@@ -353,6 +355,12 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
pd.dragSession.initialize();
pd.activeDragCount++;
pd.dragLayout.prepare(pd.dragSession, mLogger.logStart(pd.dragSession));
+ if (pd.dragSession.hideDragSourceTaskId != -1) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Hiding task surface: taskId=%d", pd.dragSession.hideDragSourceTaskId);
+ mShellTaskOrganizer.setTaskSurfaceVisibility(
+ pd.dragSession.hideDragSourceTaskId, false /* visible */);
+ }
setDropTargetWindowVisibility(pd, View.VISIBLE);
notifyListeners(l -> {
l.onDragStarted();
@@ -382,6 +390,13 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
if (pd.dragLayout.hasDropped()) {
mLogger.logDrop();
} else {
+ if (pd.dragSession.hideDragSourceTaskId != -1) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Re-showing task surface: taskId=%d",
+ pd.dragSession.hideDragSourceTaskId);
+ mShellTaskOrganizer.setTaskSurfaceVisibility(
+ pd.dragSession.hideDragSourceTaskId, true /* visible */);
+ }
pd.activeDragCount--;
pd.dragLayout.hide(event, () -> {
if (pd.activeDragCount == 0) {
@@ -435,7 +450,16 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
private boolean handleDrop(DragEvent event, PerDisplay pd) {
final SurfaceControl dragSurface = event.getDragSurface();
pd.activeDragCount--;
- return pd.dragLayout.drop(event, dragSurface, () -> {
+ // Find the token of the task to hide as a part of entering split
+ WindowContainerToken hideTaskToken = null;
+ if (pd.dragSession.hideDragSourceTaskId != -1) {
+ ActivityManager.RunningTaskInfo info = mShellTaskOrganizer.getRunningTaskInfo(
+ pd.dragSession.hideDragSourceTaskId);
+ if (info != null) {
+ hideTaskToken = info.token;
+ }
+ }
+ return pd.dragLayout.drop(event, dragSurface, hideTaskToken, () -> {
if (pd.activeDragCount == 0) {
// Hide the window if another drag hasn't been started while animating the drop
setDropTargetWindowVisibility(pd, View.INVISIBLE);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
index 9c7476d1a1b0..95fe8b6f1f4e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
@@ -59,6 +59,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
+import android.window.WindowContainerToken;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
@@ -234,8 +235,13 @@ public class DragAndDropPolicy {
return null;
}
+ /**
+ * Handles the drop on a given {@param target}. If a {@param hideTaskToken} is set, then the
+ * handling of the drop will attempt to hide the given task as a part of the same window
+ * container transaction if possible.
+ */
@VisibleForTesting
- void handleDrop(Target target) {
+ void handleDrop(Target target, @Nullable WindowContainerToken hideTaskToken) {
if (target == null || !mTargets.contains(target)) {
return;
}
@@ -254,16 +260,17 @@ public class DragAndDropPolicy {
? mFullscreenStarter
: mSplitscreenStarter;
if (mSession.appData != null) {
- launchApp(mSession, starter, position);
+ launchApp(mSession, starter, position, hideTaskToken);
} else {
- launchIntent(mSession, starter, position);
+ launchIntent(mSession, starter, position, hideTaskToken);
}
}
/**
* Launches an app provided by SysUI.
*/
- private void launchApp(DragSession session, Starter starter, @SplitPosition int position) {
+ private void launchApp(DragSession session, Starter starter, @SplitPosition int position,
+ @Nullable WindowContainerToken hideTaskToken) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Launching app data at position=%d",
position);
final ClipDescription description = session.getClipDescription();
@@ -283,8 +290,12 @@ public class DragAndDropPolicy {
if (isTask) {
final int taskId = session.appData.getIntExtra(EXTRA_TASK_ID, INVALID_TASK_ID);
- starter.startTask(taskId, position, opts);
+ starter.startTask(taskId, position, opts, hideTaskToken);
} else if (isShortcut) {
+ if (hideTaskToken != null) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Can not hide task token with starting shortcut");
+ }
final String packageName = session.appData.getStringExtra(EXTRA_PACKAGE_NAME);
final String id = session.appData.getStringExtra(EXTRA_SHORTCUT_ID);
starter.startShortcut(packageName, id, position, opts, user);
@@ -297,14 +308,15 @@ public class DragAndDropPolicy {
}
}
starter.startIntent(launchIntent, user.getIdentifier(), null /* fillIntent */,
- position, opts);
+ position, opts, hideTaskToken);
}
}
/**
* Launches an intent sender provided by an application.
*/
- private void launchIntent(DragSession session, Starter starter, @SplitPosition int position) {
+ private void launchIntent(DragSession session, Starter starter, @SplitPosition int position,
+ @Nullable WindowContainerToken hideTaskToken) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Launching intent at position=%d",
position);
final ActivityOptions baseActivityOpts = ActivityOptions.makeBasic();
@@ -319,18 +331,20 @@ public class DragAndDropPolicy {
final Bundle opts = baseActivityOpts.toBundle();
starter.startIntent(session.launchableIntent,
session.launchableIntent.getCreatorUserHandle().getIdentifier(),
- null /* fillIntent */, position, opts);
+ null /* fillIntent */, position, opts, hideTaskToken);
}
/**
* Interface for actually committing the task launches.
*/
public interface Starter {
- void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options);
+ void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options,
+ @Nullable WindowContainerToken hideTaskToken);
void startShortcut(String packageName, String shortcutId, @SplitPosition int position,
@Nullable Bundle options, UserHandle user);
void startIntent(PendingIntent intent, int userId, Intent fillInIntent,
- @SplitPosition int position, @Nullable Bundle options);
+ @SplitPosition int position, @Nullable Bundle options,
+ @Nullable WindowContainerToken hideTaskToken);
void enterSplitScreen(int taskId, boolean leftOrTop);
/**
@@ -352,7 +366,12 @@ public class DragAndDropPolicy {
}
@Override
- public void startTask(int taskId, int position, @Nullable Bundle options) {
+ public void startTask(int taskId, int position, @Nullable Bundle options,
+ @Nullable WindowContainerToken hideTaskToken) {
+ if (hideTaskToken != null) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Default starter does not support hide task token");
+ }
try {
ActivityTaskManager.getService().startActivityFromRecents(taskId, options);
} catch (RemoteException e) {
@@ -375,7 +394,12 @@ public class DragAndDropPolicy {
@Override
public void startIntent(PendingIntent intent, int userId, @Nullable Intent fillInIntent,
- int position, @Nullable Bundle options) {
+ int position, @Nullable Bundle options,
+ @Nullable WindowContainerToken hideTaskToken) {
+ if (hideTaskToken != null) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Default starter does not support hide task token");
+ }
try {
intent.send(mContext, 0, fillInIntent, null, null, null, options);
} catch (PendingIntent.CanceledException e) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
index 910175ef3023..e4aa115347eb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
@@ -51,8 +51,10 @@ import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.WindowInsets.Type;
import android.widget.LinearLayout;
+import android.window.WindowContainerToken;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.internal.logging.InstanceId;
import com.android.internal.protolog.ProtoLog;
@@ -291,6 +293,8 @@ public class DragLayout extends LinearLayout
int bgColor1 = getResizingBackgroundColor(taskInfo1).toArgb();
mDropZoneView1.setAppInfo(bgColor1, icon1);
mDropZoneView2.setAppInfo(bgColor1, icon1);
+ mDropZoneView1.setForceIgnoreBottomMargin(false);
+ mDropZoneView2.setForceIgnoreBottomMargin(false);
updateDropZoneSizes(null, null); // passing null splits the views evenly
} else {
// We use the first drop zone to show the fullscreen highlight, and don't need
@@ -483,13 +487,13 @@ public class DragLayout extends LinearLayout
/**
* Handles the drop onto a target and animates out the visible drop targets.
*/
- public boolean drop(DragEvent event, SurfaceControl dragSurface,
- Runnable dropCompleteCallback) {
+ public boolean drop(DragEvent event, @NonNull SurfaceControl dragSurface,
+ @Nullable WindowContainerToken hideTaskToken, Runnable dropCompleteCallback) {
final boolean handledDrop = mCurrentTarget != null;
mHasDropped = true;
// Process the drop
- mPolicy.handleDrop(mCurrentTarget);
+ mPolicy.handleDrop(mCurrentTarget, hideTaskToken);
// Start animating the drop UI out with the drag surface
hide(event, dropCompleteCallback);
@@ -499,7 +503,7 @@ public class DragLayout extends LinearLayout
return handledDrop;
}
- private void hideDragSurface(SurfaceControl dragSurface) {
+ private void hideDragSurface(@NonNull SurfaceControl dragSurface) {
final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
final ValueAnimator dragSurfaceAnimator = ValueAnimator.ofFloat(0f, 1f);
// Currently the splash icon animation runs with the default ValueAnimator duration of
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
index 3bedef21184e..dcbdfa349687 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
@@ -18,6 +18,7 @@ package com.android.wm.shell.draganddrop;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.ClipDescription.EXTRA_HIDE_DRAG_SOURCE_TASK_ID;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
@@ -27,6 +28,7 @@ import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.os.PersistableBundle;
import androidx.annotation.Nullable;
@@ -63,6 +65,7 @@ public class DragSession {
@WindowConfiguration.ActivityType
int runningTaskActType = ACTIVITY_TYPE_STANDARD;
boolean dragItemSupportsSplitscreen;
+ int hideDragSourceTaskId = -1;
DragSession(ActivityTaskManager activityTaskManager,
DisplayLayout dispLayout, ClipData data, int dragFlags) {
@@ -70,6 +73,11 @@ public class DragSession {
mInitialDragData = data;
mInitialDragFlags = dragFlags;
displayLayout = dispLayout;
+ hideDragSourceTaskId = data.getDescription().getExtras() != null
+ ? data.getDescription().getExtras().getInt(EXTRA_HIDE_DRAG_SOURCE_TASK_ID, -1)
+ : -1;
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Extracting drag source taskId: taskId=%d", hideDragSourceTaskId);
}
/**
@@ -84,16 +92,27 @@ public class DragSession {
* Updates the running task for this drag session.
*/
void updateRunningTask() {
+ final boolean hideDragSourceTask = hideDragSourceTaskId != -1;
final List<ActivityManager.RunningTaskInfo> tasks =
- mActivityTaskManager.getTasks(1, false /* filterOnlyVisibleRecents */);
+ mActivityTaskManager.getTasks(hideDragSourceTask ? 2 : 1,
+ false /* filterOnlyVisibleRecents */);
if (!tasks.isEmpty()) {
- final ActivityManager.RunningTaskInfo task = tasks.get(0);
- runningTaskInfo = task;
- runningTaskWinMode = task.getWindowingMode();
- runningTaskActType = task.getActivityType();
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
- "Running task: id=%d component=%s", task.taskId,
- task.baseIntent != null ? task.baseIntent.getComponent() : "null");
+ for (int i = tasks.size() - 1; i >= 0; i--) {
+ final ActivityManager.RunningTaskInfo task = tasks.get(i);
+ if (hideDragSourceTask && hideDragSourceTaskId == task.taskId) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Skipping running task: id=%d component=%s", task.taskId,
+ task.baseIntent != null ? task.baseIntent.getComponent() : "null");
+ continue;
+ }
+ runningTaskInfo = task;
+ runningTaskWinMode = task.getWindowingMode();
+ runningTaskActType = task.getActivityType();
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Running task: id=%d component=%s", task.taskId,
+ task.baseIntent != null ? task.baseIntent.getComponent() : "null");
+ break;
+ }
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java
index e215870f1894..22cfa328bfda 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java
@@ -19,16 +19,28 @@ package com.android.wm.shell.draganddrop;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
+import static android.view.View.DRAG_FLAG_ACCESSIBILITY_ACTION;
+import static android.view.View.DRAG_FLAG_GLOBAL;
+import static android.view.View.DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION;
+import static android.view.View.DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION;
+import static android.view.View.DRAG_FLAG_GLOBAL_SAME_APPLICATION;
+import static android.view.View.DRAG_FLAG_GLOBAL_URI_READ;
+import static android.view.View.DRAG_FLAG_GLOBAL_URI_WRITE;
+import static android.view.View.DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START;
+import static android.view.View.DRAG_FLAG_OPAQUE;
+import static android.view.View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION;
+import static android.view.View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG;
import android.app.PendingIntent;
import android.content.ClipData;
import android.content.ClipDescription;
import android.view.DragEvent;
-import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import java.util.StringJoiner;
+
/** Collection of utility classes for handling drag and drop. */
public class DragUtils {
private static final String TAG = "DragUtils";
@@ -76,7 +88,7 @@ public class DragUtils {
*/
@Nullable
public static PendingIntent getLaunchIntent(@NonNull ClipData data, int dragFlags) {
- if ((dragFlags & View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG) == 0) {
+ if ((dragFlags & DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG) == 0) {
// Disallow launching the intent if the app does not want to delegate it to the system
return null;
}
@@ -105,4 +117,35 @@ public class DragUtils {
}
return mimeTypes;
}
+
+ /**
+ * Returns the string description of the given {@param dragFlags}.
+ */
+ public static String dragFlagsToString(int dragFlags) {
+ StringJoiner str = new StringJoiner("|");
+ if ((dragFlags & DRAG_FLAG_GLOBAL) != 0) {
+ str.add("GLOBAL");
+ } else if ((dragFlags & DRAG_FLAG_GLOBAL_URI_READ) != 0) {
+ str.add("GLOBAL_URI_READ");
+ } else if ((dragFlags & DRAG_FLAG_GLOBAL_URI_WRITE) != 0) {
+ str.add("GLOBAL_URI_WRITE");
+ } else if ((dragFlags & DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION) != 0) {
+ str.add("GLOBAL_PERSISTABLE_URI_PERMISSION");
+ } else if ((dragFlags & DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION) != 0) {
+ str.add("GLOBAL_PREFIX_URI_PERMISSION");
+ } else if ((dragFlags & DRAG_FLAG_OPAQUE) != 0) {
+ str.add("OPAQUE");
+ } else if ((dragFlags & DRAG_FLAG_ACCESSIBILITY_ACTION) != 0) {
+ str.add("ACCESSIBILITY_ACTION");
+ } else if ((dragFlags & DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION) != 0) {
+ str.add("REQUEST_SURFACE_FOR_RETURN_ANIMATION");
+ } else if ((dragFlags & DRAG_FLAG_GLOBAL_SAME_APPLICATION) != 0) {
+ str.add("GLOBAL_SAME_APPLICATION");
+ } else if ((dragFlags & DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG) != 0) {
+ str.add("START_INTENT_SENDER_ON_UNHANDLED_DRAG");
+ } else if ((dragFlags & DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START) != 0) {
+ str.add("HIDE_CALLING_TASK_ON_DRAG_START");
+ }
+ return str.toString();
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
index b6b49a87484e..18cd2d84d32d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
@@ -151,6 +151,10 @@ public class DropZoneView extends FrameLayout {
/** Ignores the bottom margin provided by the insets. */
public void setForceIgnoreBottomMargin(boolean ignoreBottomMargin) {
+ if (DEBUG_LAYOUT) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "setForceIgnoreBottomMargin: ignore=%b", ignoreBottomMargin);
+ }
mIgnoreBottomMargin = ignoreBottomMargin;
if (mMarginPercent > 0) {
mMarginView.invalidate();
@@ -159,8 +163,14 @@ public class DropZoneView extends FrameLayout {
/** Sets the bottom inset so the drop zones are above bottom navigation. */
public void setBottomInset(float bottom) {
+ if (DEBUG_LAYOUT) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "setBottomInset: inset=%f",
+ bottom);
+ }
mBottomInset = bottom;
- ((LayoutParams) mSplashScreenView.getLayoutParams()).bottomMargin = (int) bottom;
+ final LayoutParams lp = (LayoutParams) mSplashScreenView.getLayoutParams();
+ lp.bottomMargin = (int) bottom;
+ mSplashScreenView.setLayoutParams(lp);
if (mMarginPercent > 0) {
mMarginView.invalidate();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index 1641668a98a1..4531967d6f93 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -29,7 +29,7 @@ import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import com.android.wm.shell.shared.DesktopModeStatus;
+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.windowdecor.WindowDecorViewModel;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
index b27c428f1693..a749019046f8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
@@ -16,12 +16,10 @@
package com.android.wm.shell.pip;
-import android.annotation.NonNull;
import android.graphics.Rect;
import com.android.wm.shell.shared.annotations.ExternalThread;
-import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
@@ -71,10 +69,9 @@ public interface Pip {
default void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) { }
/**
- * Register {@link PipTransitionController.PipTransitionCallback} to listen on PiP transition
- * started / finished callbacks.
+ * @return {@link PipTransitionController} instance.
*/
- default void registerPipTransitionCallback(
- @NonNull PipTransitionController.PipTransitionCallback callback,
- @NonNull Executor executor) { }
+ default PipTransitionController getPipTransitionController() {
+ return null;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index dc449d1aaf74..a8346a9b3b48 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -17,6 +17,7 @@
package com.android.wm.shell.pip;
import static android.util.RotationUtils.rotateBounds;
+import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
@@ -625,6 +626,14 @@ public class PipAnimationController {
}
} else {
adjustedSourceRectHint.set(sourceRectHint);
+ if (isInPipDirection(direction)
+ && rotationDelta == ROTATION_0
+ && taskInfo.displayCutoutInsets != null) {
+ // TODO: this is to special case the issues on Foldable device
+ // with display cutout. This aligns with what's in SwipePipToHomeAnimator.
+ adjustedSourceRectHint.offset(taskInfo.displayCutoutInsets.left,
+ taskInfo.displayCutoutInsets.top);
+ }
}
final Rect sourceHintRectInsets = new Rect();
if (!adjustedSourceRectHint.isEmpty()) {
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 6a6e2ecacae8..8d63ff2a3a5d 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
@@ -423,8 +423,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
});
mPipTransitionController.setPipOrganizer(this);
displayController.addDisplayWindowListener(this);
- pipTransitionController.registerPipTransitionCallback(
- mPipTransitionCallback, mMainExecutor);
+ pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback);
}
}
@@ -1981,12 +1980,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
}
clearContentOverlay();
}
- if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) {
- // Avoid double removal, which is fatal.
- ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: trying to remove overlay (%s) while in UNDEFINED state", TAG, surface);
- return;
- }
if (surface == null || !surface.isValid()) {
ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: trying to remove invalid content overlay (%s)", TAG, surface);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index 8d36db97c511..b1dd4f1c1395 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -53,9 +53,8 @@ import com.android.wm.shell.transition.DefaultMixedHandler;
import com.android.wm.shell.transition.Transitions;
import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
+import java.util.ArrayList;
+import java.util.List;
/**
* Responsible supplying PiP Transitions.
@@ -67,7 +66,7 @@ public abstract class PipTransitionController implements Transitions.TransitionH
protected final ShellTaskOrganizer mShellTaskOrganizer;
protected final PipMenuController mPipMenuController;
protected final Transitions mTransitions;
- private final Map<PipTransitionCallback, Executor> mPipTransitionCallbacks = new HashMap<>();
+ private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>();
protected PipTaskOrganizer mPipOrganizer;
protected DefaultMixedHandler mMixedHandler;
@@ -184,18 +183,16 @@ public abstract class PipTransitionController implements Transitions.TransitionH
/**
* Registers {@link PipTransitionCallback} to receive transition callbacks.
*/
- public void registerPipTransitionCallback(
- @NonNull PipTransitionCallback callback, @NonNull Executor executor) {
- mPipTransitionCallbacks.put(callback, executor);
+ public void registerPipTransitionCallback(PipTransitionCallback callback) {
+ mPipTransitionCallbacks.add(callback);
}
protected void sendOnPipTransitionStarted(
@PipAnimationController.TransitionDirection int direction) {
final Rect pipBounds = mPipBoundsState.getBounds();
- for (Map.Entry<PipTransitionCallback, Executor> entry
- : mPipTransitionCallbacks.entrySet()) {
- entry.getValue().execute(
- () -> entry.getKey().onPipTransitionStarted(direction, pipBounds));
+ for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
+ final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
+ callback.onPipTransitionStarted(direction, pipBounds);
}
if (isInPipDirection(direction) && Flags.enablePipUiStateCallbackOnEntering()) {
try {
@@ -212,10 +209,9 @@ public abstract class PipTransitionController implements Transitions.TransitionH
protected void sendOnPipTransitionFinished(
@PipAnimationController.TransitionDirection int direction) {
- for (Map.Entry<PipTransitionCallback, Executor> entry
- : mPipTransitionCallbacks.entrySet()) {
- entry.getValue().execute(
- () -> entry.getKey().onPipTransitionFinished(direction));
+ for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
+ final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
+ callback.onPipTransitionFinished(direction);
}
if (isInPipDirection(direction) && Flags.enablePipUiStateCallbackOnEntering()) {
try {
@@ -232,10 +228,9 @@ public abstract class PipTransitionController implements Transitions.TransitionH
protected void sendOnPipTransitionCancelled(
@PipAnimationController.TransitionDirection int direction) {
- for (Map.Entry<PipTransitionCallback, Executor> entry
- : mPipTransitionCallbacks.entrySet()) {
- entry.getValue().execute(
- () -> entry.getKey().onPipTransitionCanceled(direction));
+ for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
+ final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
+ callback.onPipTransitionCanceled(direction);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index d1d82755d12c..26b7e58bc602 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -106,7 +106,6 @@ import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
-import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
@@ -374,7 +373,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
* Instantiates {@link PipController}, returns {@code null} if the feature not supported.
*/
@Nullable
- public static Pip create(Context context,
+ public static PipImpl create(Context context,
ShellInit shellInit,
ShellCommandHandler shellCommandHandler,
ShellController shellController,
@@ -479,7 +478,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
mShellCommandHandler.addDumpCallback(this::dump, this);
mPipInputConsumer = new PipInputConsumer(WindowManagerGlobal.getWindowManagerService(),
INPUT_CONSUMER_PIP, mMainExecutor);
- mPipTransitionController.registerPipTransitionCallback(this, mMainExecutor);
+ mPipTransitionController.registerPipTransitionCallback(this);
mPipTaskOrganizer.registerOnDisplayIdChangeCallback((int displayId) -> {
mPipDisplayLayoutState.setDisplayId(displayId);
onDisplayChanged(mDisplayController.getDisplayLayout(displayId),
@@ -1177,7 +1176,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
/**
* The interface for calls from outside the Shell, within the host process.
*/
- private class PipImpl implements Pip {
+ public class PipImpl implements Pip {
@Override
public void expandPip() {
mMainExecutor.execute(() -> {
@@ -1221,11 +1220,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
}
@Override
- public void registerPipTransitionCallback(
- PipTransitionController.PipTransitionCallback callback,
- Executor executor) {
- mMainExecutor.execute(() -> mPipTransitionController.registerPipTransitionCallback(
- callback, executor));
+ public PipTransitionController getPipTransitionController() {
+ return mPipTransitionController;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index df3803d54d9d..e8d6576bab3b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -38,7 +38,6 @@ import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.FloatProperties;
import com.android.wm.shell.common.FloatingContentCoordinator;
-import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
import com.android.wm.shell.common.pip.PipAppOpsListener;
import com.android.wm.shell.common.pip.PipBoundsState;
@@ -48,7 +47,6 @@ import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.animation.PhysicsAnimator;
-import com.android.wm.shell.shared.annotations.ShellMainThread;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
@@ -173,9 +171,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
public void onPipTransitionCanceled(int direction) {}
};
- public PipMotionHelper(Context context,
- @ShellMainThread ShellExecutor mainExecutor,
- @NonNull PipBoundsState pipBoundsState,
+ public PipMotionHelper(Context context, @NonNull PipBoundsState pipBoundsState,
PipTaskOrganizer pipTaskOrganizer, PhonePipMenuController menuController,
PipSnapAlgorithm snapAlgorithm, PipTransitionController pipTransitionController,
FloatingContentCoordinator floatingContentCoordinator,
@@ -187,7 +183,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
mSnapAlgorithm = snapAlgorithm;
mFloatingContentCoordinator = floatingContentCoordinator;
mPipPerfHintController = pipPerfHintControllerOptional.orElse(null);
- pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback, mainExecutor);
+ pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback);
mResizePipUpdateListener = (target, values) -> {
if (mPipBoundsState.getMotionBoundsState().isInMotion()) {
mPipTaskOrganizer.scheduleUserResizePip(getBounds(),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
index 0ed5079b7fba..62c0944f230b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
@@ -257,7 +257,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
}
private void onInit() {
- mPipTransitionController.registerPipTransitionCallback(this, mMainExecutor);
+ mPipTransitionController.registerPipTransitionCallback(this);
reloadResources();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index 06adad626e9f..b939b169d8bd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -55,6 +55,8 @@ 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.common.pip.PipUtils;
+import com.android.wm.shell.pip.Pip;
+import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.sysui.ConfigurationChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
@@ -62,6 +64,7 @@ import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import java.io.PrintWriter;
+import java.util.function.Consumer;
/**
* Manages the picture-in-picture (PIP) UI and states for Phones.
@@ -86,6 +89,8 @@ public class PipController implements ConfigurationChangeListener,
private final ShellTaskOrganizer mShellTaskOrganizer;
private final PipTransitionState mPipTransitionState;
private final ShellExecutor mMainExecutor;
+ private final PipImpl mImpl;
+ private Consumer<Boolean> mOnIsInPipStateChangedListener;
// Wrapper for making Binder calls into PiP animation listener hosted in launcher's Recents.
private PipAnimationListener mPipRecentsAnimationListener;
@@ -140,6 +145,7 @@ public class PipController implements ConfigurationChangeListener,
mPipTransitionState = pipTransitionState;
mPipTransitionState.addPipTransitionStateChangedListener(this);
mMainExecutor = mainExecutor;
+ mImpl = new PipImpl();
if (PipUtils.isPip2ExperimentEnabled()) {
shellInit.addInitCallback(this::onInit, this);
@@ -174,6 +180,10 @@ public class PipController implements ConfigurationChangeListener,
pipTransitionState, mainExecutor);
}
+ public PipImpl getPipImpl() {
+ return mImpl;
+ }
+
private void onInit() {
mShellCommandHandler.addDumpCallback(this::dump, this);
// Ensure that we have the display info in case we get calls to update the bounds before the
@@ -310,22 +320,29 @@ public class PipController implements ConfigurationChangeListener,
@Override
public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState,
@PipTransitionState.TransitionState int newState, @Nullable Bundle extra) {
- if (newState == PipTransitionState.SWIPING_TO_PIP) {
- Preconditions.checkState(extra != null,
- "No extra bundle for " + mPipTransitionState);
-
- SurfaceControl overlay = extra.getParcelable(
- SWIPE_TO_PIP_OVERLAY, SurfaceControl.class);
- Rect appBounds = extra.getParcelable(
- SWIPE_TO_PIP_APP_BOUNDS, Rect.class);
-
- Preconditions.checkState(appBounds != null,
- "App bounds can't be null for " + mPipTransitionState);
- mPipTransitionState.setSwipePipToHomeState(overlay, appBounds);
- } else if (newState == PipTransitionState.ENTERED_PIP) {
- if (mPipTransitionState.isInSwipePipToHomeTransition()) {
- mPipTransitionState.resetSwipePipToHomeState();
- }
+ switch (newState) {
+ case PipTransitionState.SWIPING_TO_PIP:
+ Preconditions.checkState(extra != null,
+ "No extra bundle for " + mPipTransitionState);
+
+ SurfaceControl overlay = extra.getParcelable(
+ SWIPE_TO_PIP_OVERLAY, SurfaceControl.class);
+ Rect appBounds = extra.getParcelable(
+ SWIPE_TO_PIP_APP_BOUNDS, Rect.class);
+
+ Preconditions.checkState(appBounds != null,
+ "App bounds can't be null for " + mPipTransitionState);
+ mPipTransitionState.setSwipePipToHomeState(overlay, appBounds);
+ break;
+ case PipTransitionState.ENTERED_PIP:
+ if (mPipTransitionState.isInSwipePipToHomeTransition()) {
+ mPipTransitionState.resetSwipePipToHomeState();
+ }
+ mOnIsInPipStateChangedListener.accept(true /* inPip */);
+ break;
+ case PipTransitionState.EXITED_PIP:
+ mOnIsInPipStateChangedListener.accept(false /* inPip */);
+ break;
}
}
@@ -355,6 +372,48 @@ public class PipController implements ConfigurationChangeListener,
mPipTransitionState.dump(pw, innerPrefix);
}
+ private void setOnIsInPipStateChangedListener(Consumer<Boolean> callback) {
+ mOnIsInPipStateChangedListener = callback;
+ if (mOnIsInPipStateChangedListener != null) {
+ callback.accept(mPipTransitionState.isInPip());
+ }
+ }
+
+ /**
+ * The interface for calls from outside the Shell, within the host process.
+ */
+ public class PipImpl implements Pip {
+ @Override
+ public void expandPip() {}
+
+ @Override
+ public void onSystemUiStateChanged(boolean isSysUiStateValid, long flag) {}
+
+ @Override
+ public void setOnIsInPipStateChangedListener(Consumer<Boolean> callback) {
+ mMainExecutor.execute(() -> {
+ PipController.this.setOnIsInPipStateChangedListener(callback);
+ });
+ }
+
+ @Override
+ public void addPipExclusionBoundsChangeListener(Consumer<Rect> listener) {
+ mMainExecutor.execute(() -> {
+ mPipBoundsState.addPipExclusionBoundsChangeCallback(listener);
+ });
+ }
+
+ @Override
+ public void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) {
+ mMainExecutor.execute(() -> {
+ mPipBoundsState.removePipExclusionBoundsChangeCallback(listener);
+ });
+ }
+
+ @Override
+ public void showPictureInPictureMenu() {}
+ }
+
/**
* The interface for calls from outside the host process.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
index e277a8dbeb13..ea02de9d9704 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
@@ -816,6 +816,26 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded();
mSpringingToTouch = false;
mDismissalPending = false;
+
+ // Check whether new bounds after fling imply we need to update stash state too.
+ stashEndActionIfNeeded();
+ }
+
+ private void stashEndActionIfNeeded() {
+ boolean isStashing = mPipBoundsState.getBounds().right > mPipBoundsState
+ .getDisplayBounds().width() || mPipBoundsState.getBounds().left < 0;
+ if (!isStashing) {
+ return;
+ }
+
+ if (mPipBoundsState.getBounds().left < 0
+ && mPipBoundsState.getStashedState() != STASH_TYPE_LEFT) {
+ mPipBoundsState.setStashed(STASH_TYPE_LEFT);
+ } else if (mPipBoundsState.getBounds().left >= 0
+ && mPipBoundsState.getStashedState() != STASH_TYPE_RIGHT) {
+ mPipBoundsState.setStashed(STASH_TYPE_RIGHT);
+ }
+ mMenuController.hideMenu();
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
index 0c4ed268fd28..53b80e8b7542 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
@@ -106,9 +106,6 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
private float mStashVelocityThreshold;
- // The reference inset bounds, used to determine the dismiss fraction
- private final Rect mInsetBounds = new Rect();
-
// Used to workaround an issue where the WM rotation happens before we are notified, allowing
// us to send stale bounds
private int mDeferResizeToNormalBoundsUntilRotation = -1;
@@ -206,17 +203,10 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
mMotionHelper, mainExecutor);
mTouchState = new PipTouchState(ViewConfiguration.get(context),
() -> {
- if (mPipBoundsState.isStashed()) {
- animateToUnStashedState();
- mPipUiEventLogger.log(
- PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_STASH_UNSTASHED);
- mPipBoundsState.setStashed(STASH_TYPE_NONE);
- } else {
- mMenuController.showMenuWithPossibleDelay(MENU_STATE_FULL,
- mPipBoundsState.getBounds(), true /* allowMenuTimeout */,
- willResizeMenu(),
- shouldShowResizeHandle());
- }
+ mMenuController.showMenuWithPossibleDelay(MENU_STATE_FULL,
+ mPipBoundsState.getBounds(), true /* allowMenuTimeout */,
+ willResizeMenu(),
+ shouldShowResizeHandle());
},
menuController::hideMenu,
mainExecutor);
@@ -438,7 +428,6 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
mPipBoundsState.setNormalMovementBounds(normalMovementBounds);
mPipBoundsState.setExpandedMovementBounds(expandedMovementBounds);
mDisplayRotation = displayRotation;
- mInsetBounds.set(insetBounds);
updateMovementBounds();
mMovementBoundsExtraOffsets = extraOffset;
@@ -748,10 +737,13 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
final Rect pipBounds = mPipBoundsState.getBounds();
final boolean onLeftEdge = pipBounds.left < mPipBoundsState.getDisplayBounds().left;
final Rect unStashedBounds = new Rect(0, pipBounds.top, 0, pipBounds.bottom);
- unStashedBounds.left = onLeftEdge ? mInsetBounds.left
- : mInsetBounds.right - pipBounds.width();
- unStashedBounds.right = onLeftEdge ? mInsetBounds.left + pipBounds.width()
- : mInsetBounds.right;
+
+ Rect insetBounds = new Rect();
+ mPipBoundsAlgorithm.getInsetBounds(insetBounds);
+ unStashedBounds.left = onLeftEdge ? insetBounds.left
+ : insetBounds.right - pipBounds.width();
+ unStashedBounds.right = onLeftEdge ? insetBounds.left + pipBounds.width()
+ : insetBounds.right;
mMotionHelper.animateToUnStashedBounds(unStashedBounds);
}
@@ -899,8 +891,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
// Reset the touch state on up before the fling settles
mTouchState.reset();
if (mEnableStash && shouldStash(vel, getPossiblyMotionBounds())) {
- // mMotionHelper.stashToEdge(vel.x, vel.y,
- // this::stashEndAction /* endAction */);
+ mMotionHelper.stashToEdge(vel.x, vel.y, null /* endAction */);
} else {
if (mPipBoundsState.isStashed()) {
// Reset stashed state if previously stashed
@@ -1030,8 +1021,10 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
* resized.
*/
private void updateMovementBounds() {
+ Rect insetBounds = new Rect();
+ mPipBoundsAlgorithm.getInsetBounds(insetBounds);
mPipBoundsAlgorithm.getMovementBounds(mPipBoundsState.getBounds(),
- mInsetBounds, mPipBoundsState.getMovementBounds(), mIsImeShowing ? mImeHeight : 0);
+ insetBounds, mPipBoundsState.getMovementBounds(), mIsImeShowing ? mImeHeight : 0);
mMotionHelper.onMovementBoundsChanged();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 814eaae1ea74..9539a456502f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -37,6 +37,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.IRecentsAnimationRunner;
+import android.window.WindowContainerToken;
import androidx.annotation.BinderThread;
import androidx.annotation.NonNull;
@@ -52,9 +53,9 @@ import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import com.android.wm.shell.shared.DesktopModeStatus;
import com.android.wm.shell.shared.annotations.ExternalThread;
import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
@@ -457,11 +458,31 @@ public class RecentTasksController implements TaskStackListenerCallback,
}
/**
- * Find the background task that match the given component.
+ * Returns the top running leaf task ignoring {@param ignoreTaskToken} if it is specified.
+ * NOTE: This path currently makes assumptions that ignoreTaskToken is for the top task.
+ */
+ @Nullable
+ public ActivityManager.RunningTaskInfo getTopRunningTask(
+ @Nullable WindowContainerToken ignoreTaskToken) {
+ List<ActivityManager.RunningTaskInfo> tasks = mActivityTaskManager.getTasks(2,
+ false /* filterOnlyVisibleRecents */);
+ for (int i = tasks.size() - 1; i >= 0; i--) {
+ final ActivityManager.RunningTaskInfo task = tasks.get(i);
+ if (task.token.equals(ignoreTaskToken)) {
+ continue;
+ }
+ return task;
+ }
+ return null;
+ }
+
+ /**
+ * Find the background task that match the given component. Ignores tasks match
+ * {@param ignoreTaskToken} if it is non-null.
*/
@Nullable
public ActivityManager.RecentTaskInfo findTaskInBackground(ComponentName componentName,
- int userId) {
+ int userId, @Nullable WindowContainerToken ignoreTaskToken) {
if (componentName == null) {
return null;
}
@@ -473,6 +494,9 @@ public class RecentTasksController implements TaskStackListenerCallback,
if (task.isVisible) {
continue;
}
+ if (task.token.equals(ignoreTaskToken)) {
+ continue;
+ }
if (componentName.equals(task.baseIntent.getComponent()) && userId == task.userId) {
return task;
}
@@ -640,7 +664,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
@Override
public ActivityManager.RunningTaskInfo[] getRunningTasks(int maxNum) {
final ActivityManager.RunningTaskInfo[][] tasks =
- new ActivityManager.RunningTaskInfo[][] {null};
+ new ActivityManager.RunningTaskInfo[][]{null};
executeRemoteCallWithTaskPermission(mController, "getRunningTasks",
(controller) -> tasks[0] = ActivityTaskManager.getInstance().getTasks(maxNum)
.toArray(new ActivityManager.RunningTaskInfo[0]),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index e46625debcc6..234b4d0f86db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -74,7 +74,6 @@ import com.android.wm.shell.transition.Transitions;
import java.util.ArrayList;
import java.util.function.Consumer;
-import java.util.function.Supplier;
/**
* Handles the Recents (overview) animation. Only one of these can run at a time. A recents
@@ -85,7 +84,6 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
private final Transitions mTransitions;
private final ShellExecutor mExecutor;
- private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
@Nullable
private final RecentTasksController mRecentTasksController;
private IApplicationThread mAnimApp = null;
@@ -103,13 +101,11 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
public RecentsTransitionHandler(ShellInit shellInit, Transitions transitions,
@Nullable RecentTasksController recentTasksController,
- HomeTransitionObserver homeTransitionObserver,
- Supplier<SurfaceControl.Transaction> transactionSupplier) {
+ HomeTransitionObserver homeTransitionObserver) {
mTransitions = transitions;
mExecutor = transitions.getMainExecutor();
mRecentTasksController = recentTasksController;
mHomeTransitionObserver = homeTransitionObserver;
- mTransactionSupplier = transactionSupplier;
if (!Transitions.ENABLE_SHELL_TRANSITIONS) return;
if (recentTasksController == null) return;
shellInit.addInitCallback(() -> {
@@ -1060,7 +1056,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
final Transitions.TransitionFinishCallback finishCB = mFinishCB;
mFinishCB = null;
- SurfaceControl.Transaction t = mFinishTransaction;
+ final SurfaceControl.Transaction t = mFinishTransaction;
final WindowContainerTransaction wct = new WindowContainerTransaction();
if (mKeyguardLocked && mRecentsTask != null) {
@@ -1110,16 +1106,6 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
}
}
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, " normal finish");
- if (toHome && !mOpeningTasks.isEmpty()) {
- // Attempting to start a task after swipe to home, don't show it,
- // move recents to top
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " attempting to start a task after swipe to home");
- t = mTransactionSupplier.get();
- wct.reorder(mRecentsTask, true /*onTop*/);
- mClosingTasks.addAll(mOpeningTasks);
- mOpeningTasks.clear();
- }
// The general case: committing to recents, going home, or switching tasks.
for (int i = 0; i < mOpeningTasks.size(); ++i) {
t.show(mOpeningTasks.get(i).mTaskSurface);
@@ -1188,10 +1174,6 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
mPipTransaction = null;
}
}
- if (t != mFinishTransaction) {
- // apply after merges because these changes are accounting for finishWCT changes.
- mTransitions.setAfterMergeFinishTransaction(mTransition, t);
- }
cleanUp();
finishCB.onTransitionFinished(wct.isEmpty() ? null : wct);
if (runnerFinishCb != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index b4941a5b49b5..e659151fee7f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -64,6 +64,7 @@ import android.view.SurfaceSession;
import android.view.WindowManager;
import android.widget.Toast;
import android.window.RemoteTransition;
+import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import androidx.annotation.BinderThread;
@@ -526,7 +527,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
mStageCoordinator.requestEnterSplitSelect(taskInfo, wct, splitPosition, taskBounds);
}
- public void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options) {
+ /**
+ * Starts an existing task into split.
+ * TODO(b/351900580): We should remove this path and use StageCoordinator#startTask() instead
+ * @param hideTaskToken is not supported.
+ */
+ public void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options,
+ @Nullable WindowContainerToken hideTaskToken) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Legacy startTask does not support hide task token");
final int[] result = new int[1];
IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() {
@Override
@@ -584,8 +593,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
if (options == null) options = new Bundle();
final ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
- if (samePackage(packageName, getPackageName(reverseSplitPosition(position)),
- user.getIdentifier(), getUserId(reverseSplitPosition(position)))) {
+ if (samePackage(packageName, getPackageName(reverseSplitPosition(position), null),
+ user.getIdentifier(), getUserId(reverseSplitPosition(position), null))) {
if (mMultiInstanceHelpher.supportsMultiInstanceSplit(
getShortcutComponent(packageName, shortcutId, user, mLauncherApps))) {
activityOptions.setApplyMultipleTaskFlagForShortcut(true);
@@ -676,10 +685,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
* See {@link #startIntent(PendingIntent, int, Intent, int, Bundle)}
* @param instanceId to be used by {@link SplitscreenEventLogger}
*/
- public void startIntent(PendingIntent intent, int userId, @Nullable Intent fillInIntent,
- @SplitPosition int position, @Nullable Bundle options, @NonNull InstanceId instanceId) {
+ public void startIntentWithInstanceId(PendingIntent intent, int userId,
+ @Nullable Intent fillInIntent, @SplitPosition int position, @Nullable Bundle options,
+ @NonNull InstanceId instanceId) {
mStageCoordinator.onRequestToSplit(instanceId, ENTER_REASON_LAUNCHER);
- startIntent(intent, userId, fillInIntent, position, options);
+ startIntent(intent, userId, fillInIntent, position, options, null /* hideTaskToken */);
}
private void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1,
@@ -825,9 +835,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
instanceId);
}
+ /**
+ * Starts the given intent into split.
+ * @param hideTaskToken If non-null, a task matching this token will be moved to back in the
+ * same window container transaction as the starting of the intent.
+ */
@Override
public void startIntent(PendingIntent intent, int userId1, @Nullable Intent fillInIntent,
- @SplitPosition int position, @Nullable Bundle options) {
+ @SplitPosition int position, @Nullable Bundle options,
+ @Nullable WindowContainerToken hideTaskToken) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
"startIntent(): intent=%s user=%d fillInIntent=%s position=%d", intent, userId1,
fillInIntent, position);
@@ -838,23 +854,24 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
fillInIntent.addFlags(FLAG_ACTIVITY_NO_USER_ACTION);
final String packageName1 = SplitScreenUtils.getPackageName(intent);
- final String packageName2 = getPackageName(reverseSplitPosition(position));
- final int userId2 = getUserId(reverseSplitPosition(position));
+ final String packageName2 = getPackageName(reverseSplitPosition(position), hideTaskToken);
+ final int userId2 = getUserId(reverseSplitPosition(position), hideTaskToken);
final ComponentName component = intent.getIntent().getComponent();
// To prevent accumulating large number of instances in the background, reuse task
// in the background. If we don't explicitly reuse, new may be created even if the app
// isn't multi-instance because WM won't automatically remove/reuse the previous instance
final ActivityManager.RecentTaskInfo taskInfo = mRecentTasksOptional
- .map(recentTasks -> recentTasks.findTaskInBackground(component, userId1))
+ .map(recentTasks -> recentTasks.findTaskInBackground(component, userId1,
+ hideTaskToken))
.orElse(null);
if (taskInfo != null) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
"Found suitable background task=%s", taskInfo);
if (ENABLE_SHELL_TRANSITIONS) {
- mStageCoordinator.startTask(taskInfo.taskId, position, options);
+ mStageCoordinator.startTask(taskInfo.taskId, position, options, hideTaskToken);
} else {
- startTask(taskInfo.taskId, position, options);
+ startTask(taskInfo.taskId, position, options, hideTaskToken);
}
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Start task in background");
return;
@@ -879,19 +896,23 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
}
- mStageCoordinator.startIntent(intent, fillInIntent, position, options);
+ mStageCoordinator.startIntent(intent, fillInIntent, position, options, hideTaskToken);
}
- /** Retrieve package name of a specific split position if split screen is activated, otherwise
- * returns the package name of the top running task. */
+ /**
+ * Retrieve package name of a specific split position if split screen is activated, otherwise
+ * returns the package name of the top running task.
+ * TODO(b/351900580): Merge this with getUserId() so we don't make multiple binder calls
+ */
@Nullable
- private String getPackageName(@SplitPosition int position) {
+ private String getPackageName(@SplitPosition int position,
+ @Nullable WindowContainerToken ignoreTaskToken) {
ActivityManager.RunningTaskInfo taskInfo;
if (isSplitScreenVisible()) {
taskInfo = getTaskInfo(position);
} else {
taskInfo = mRecentTasksOptional
- .map(recentTasks -> recentTasks.getTopRunningTask())
+ .map(recentTasks -> recentTasks.getTopRunningTask(ignoreTaskToken))
.orElse(null);
if (!isValidToSplit(taskInfo)) {
return null;
@@ -901,15 +922,19 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return taskInfo != null ? SplitScreenUtils.getPackageName(taskInfo.baseIntent) : null;
}
- /** Retrieve user id of a specific split position if split screen is activated, otherwise
- * returns the user id of the top running task. */
- private int getUserId(@SplitPosition int position) {
+ /**
+ * Retrieve user id of a specific split position if split screen is activated, otherwise
+ * returns the user id of the top running task.
+ * TODO: Merge this with getPackageName() so we don't make multiple binder calls
+ */
+ private int getUserId(@SplitPosition int position,
+ @Nullable WindowContainerToken ignoreTaskToken) {
ActivityManager.RunningTaskInfo taskInfo;
if (isSplitScreenVisible()) {
taskInfo = getTaskInfo(position);
} else {
taskInfo = mRecentTasksOptional
- .map(recentTasks -> recentTasks.getTopRunningTask())
+ .map(recentTasks -> recentTasks.getTopRunningTask(ignoreTaskToken))
.orElse(null);
if (!isValidToSplit(taskInfo)) {
return -1;
@@ -1290,7 +1315,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
@Override
public void startTask(int taskId, int position, @Nullable Bundle options) {
executeRemoteCallWithTaskPermission(mController, "startTask",
- (controller) -> controller.startTask(taskId, position, options));
+ (controller) -> controller.startTask(taskId, position, options,
+ null /* hideTaskToken */));
}
@Override
@@ -1402,8 +1428,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
public void startIntent(PendingIntent intent, int userId, Intent fillInIntent, int position,
@Nullable Bundle options, InstanceId instanceId) {
executeRemoteCallWithTaskPermission(mController, "startIntent",
- (controller) -> controller.startIntent(intent, userId, fillInIntent, position,
- options, instanceId));
+ (controller) -> controller.startIntentWithInstanceId(intent, userId,
+ fillInIntent, position, options, instanceId));
}
@Override
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 d9e97766e4fe..9bcd9b0a11c8 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
@@ -592,12 +592,21 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
}
- /** Use this method to launch an existing Task via a taskId */
- void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options) {
+ /**
+ * Use this method to launch an existing Task via a taskId.
+ * @param hideTaskToken If non-null, a task matching this token will be moved to back in the
+ * same window container transaction as the starting of the intent.
+ */
+ void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options,
+ @Nullable WindowContainerToken hideTaskToken) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startTask: task=%d position=%d", taskId, position);
mSplitRequest = new SplitRequest(taskId, position);
final WindowContainerTransaction wct = new WindowContainerTransaction();
options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
+ if (hideTaskToken != null) {
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "Reordering hide-task to bottom");
+ wct.reorder(hideTaskToken, false /* onTop */);
+ }
wct.startTask(taskId, options);
// If this should be mixed, send the task to avoid split handle transition directly.
if (mMixedHandler != null && mMixedHandler.isTaskInPip(taskId, mTaskOrganizer)) {
@@ -623,9 +632,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
extraTransitType, !mIsDropEntering);
}
- /** Launches an activity into split. */
+ /**
+ * Launches an activity into split.
+ * @param hideTaskToken If non-null, a task matching this token will be moved to back in the
+ * same window container transaction as the starting of the intent.
+ */
void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
- @Nullable Bundle options) {
+ @Nullable Bundle options, @Nullable WindowContainerToken hideTaskToken) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startIntent: intent=%s position=%d", intent.getIntent(),
position);
mSplitRequest = new SplitRequest(intent.getIntent(), position);
@@ -636,6 +649,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
final WindowContainerTransaction wct = new WindowContainerTransaction();
options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
+ if (hideTaskToken != null) {
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "Reordering hide-task to bottom");
+ wct.reorder(hideTaskToken, false /* onTop */);
+ }
wct.sendPendingIntent(intent, fillInIntent, options);
// If this should be mixed, just send the intent to avoid split handle transition directly.
@@ -3556,7 +3573,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
pw.println(innerPrefix + "mDividerVisible=" + mDividerVisible);
pw.println(innerPrefix + "isSplitActive=" + isSplitActive());
pw.println(innerPrefix + "isSplitVisible=" + isSplitScreenVisible());
- pw.println(innerPrefix + "isLeftRightSplit=" + mSplitLayout.isLeftRightSplit());
+ pw.println(innerPrefix + "isLeftRightSplit="
+ + (mSplitLayout != null ? mSplitLayout.isLeftRightSplit() : "null"));
pw.println(innerPrefix + "MainStage");
pw.println(childPrefix + "stagePosition=" + splitPositionToString(getMainStagePosition()));
pw.println(childPrefix + "isActive=" + mMainStage.isActive());
@@ -3568,7 +3586,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSideStage.dump(pw, childPrefix);
pw.println(innerPrefix + "SideStageListener");
mSideStageListener.dump(pw, childPrefix);
- mSplitLayout.dump(pw, childPrefix);
+ if (mSplitLayout != null) {
+ mSplitLayout.dump(pw, childPrefix);
+ }
if (!mPausingTasks.isEmpty()) {
pw.println(childPrefix + "mPausingTasks=" + mPausingTasks);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java
index 6325c686a682..ea8c0eb30061 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java
@@ -390,7 +390,8 @@ public class SplashScreenExitAnimationUtils {
SurfaceControl firstWindowSurface, ViewGroup splashScreenView,
TransactionPool transactionPool, Rect firstWindowFrame,
int mainWindowShiftLength, float roundedCornerRadius) {
- mFromYDelta = fromYDelta - Math.max(firstWindowFrame.top, roundedCornerRadius);
+ mFromYDelta = firstWindowFrame.top
+ - Math.max(firstWindowFrame.top, roundedCornerRadius);
mToYDelta = toYDelta;
mOccludeHoleView = occludeHoleView;
mApplier = new SyncRtSurfaceTransactionApplier(occludeHoleView);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
index 3a680097554f..dd4595a70211 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
@@ -27,6 +27,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.ArrayList;
@@ -75,6 +76,7 @@ public class ShellInit {
*/
@VisibleForTesting
public void init() {
+ ProtoLog.registerGroups(ShellProtoLogGroup.values());
ProtoLog.v(WM_SHELL_INIT, "Initializing Shell Components: %d", mInitCallbacks.size());
SurfaceControl.setDebugUsageAfterRelease(true);
// Init in order of registration
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
index a126cbe41b00..9750d3ec99f5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
@@ -535,7 +535,8 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
WindowContainerTransaction wct = new WindowContainerTransaction();
if (mCaptionInsets != null) {
wct.addInsetsSource(mTaskToken, mCaptionInsetsOwner, 0,
- WindowInsets.Type.captionBar(), mCaptionInsets, null /* boundingRects */);
+ WindowInsets.Type.captionBar(), mCaptionInsets, null /* boundingRects */,
+ 0 /* flags */);
} else {
wct.removeInsetsSource(mTaskToken, mCaptionInsetsOwner, 0,
WindowInsets.Type.captionBar());
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 4f4b8097cfac..766a6b3f48ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -353,7 +353,7 @@ public class DefaultMixedHandler implements MixedTransitionHandler,
return this::setRecentsTransitionDuringKeyguard;
} else if (mDesktopTasksController != null
// Check on the default display. Recents/gesture nav is only available there
- && mDesktopTasksController.getVisibleTaskCount(DEFAULT_DISPLAY) > 0) {
+ && mDesktopTasksController.visibleTaskCount(DEFAULT_DISPLAY) > 0) {
return this::setRecentsTransitionDuringDesktop;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 73b32a24246a..778478405dda 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -19,6 +19,7 @@ package com.android.wm.shell.transition;
import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
import static android.app.ActivityOptions.ANIM_CUSTOM;
import static android.app.ActivityOptions.ANIM_NONE;
+import static android.app.ActivityOptions.ANIM_FROM_STYLE;
import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
import static android.app.ActivityOptions.ANIM_SCALE_UP;
import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
@@ -40,6 +41,7 @@ import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECI
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_RELAUNCH;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_OWNER_THUMBNAIL;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_WORK_THUMBNAIL;
import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS;
@@ -62,6 +64,7 @@ import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITI
import static com.android.wm.shell.transition.TransitionAnimationHelper.edgeExtendWindow;
import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet;
import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionTypeFromInfo;
+import static com.android.wm.shell.transition.TransitionAnimationHelper.isCoveredByOpaqueFullscreenChange;
import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation;
import android.animation.Animator;
@@ -352,6 +355,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
continue;
}
final boolean isTask = change.getTaskInfo() != null;
+ final boolean isFreeform = isTask && change.getTaskInfo().isFreeform();
final int mode = change.getMode();
boolean isSeamlessDisplayChange = false;
@@ -458,6 +462,16 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final int layer = zSplitLine + numChanges - i;
startTransaction.setLayer(change.getLeash(), layer);
}
+ } else if (!isCoveredByOpaqueFullscreenChange(info, change)
+ && isFreeform
+ && TransitionUtil.isOpeningMode(type)
+ && change.getMode() == TRANSIT_TO_BACK) {
+ // Reparent the minimize-change to the root task so the minimizing Task
+ // isn't shown in front of other Tasks.
+ mRootTDAOrganizer.reparentToDisplayArea(
+ change.getTaskInfo().displayId,
+ change.getLeash(),
+ startTransaction);
} else if (isOnlyTranslucent && TransitionUtil.isOpeningType(info.getType())
&& TransitionUtil.isClosingType(mode)) {
// If there is a closing translucent task in an OPENING transition, we will
@@ -985,7 +999,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final int animType = options.getType();
return animType == ANIM_CUSTOM || animType == ANIM_SCALE_UP
|| animType == ANIM_THUMBNAIL_SCALE_UP || animType == ANIM_THUMBNAIL_SCALE_DOWN
- || animType == ANIM_CLIP_REVEAL || animType == ANIM_OPEN_CROSS_PROFILE_APPS;
+ || animType == ANIM_CLIP_REVEAL || animType == ANIM_OPEN_CROSS_PROFILE_APPS
+ || animType == ANIM_FROM_STYLE;
}
private static void applyTransformation(long time, SurfaceControl.Transaction t,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
index a5f071af6973..75e7ddf53f9f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
@@ -36,6 +36,7 @@ import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITI
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.WindowConfiguration;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -72,6 +73,9 @@ public class TransitionAnimationHelper {
final int changeFlags = change.getFlags();
final boolean enter = TransitionUtil.isOpeningType(changeMode);
final boolean isTask = change.getTaskInfo() != null;
+ final boolean isFreeform = isTask && change.getTaskInfo().isFreeform();
+ final boolean isCoveredByOpaqueFullscreenChange =
+ isCoveredByOpaqueFullscreenChange(info, change);
final TransitionInfo.AnimationOptions options;
if (Flags.moveAnimationOptionsToChange()) {
options = change.getAnimationOptions();
@@ -107,6 +111,24 @@ public class TransitionAnimationHelper {
animAttr = enter
? R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
: R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
+ } else if (!isCoveredByOpaqueFullscreenChange
+ && isFreeform
+ && TransitionUtil.isOpeningMode(type)
+ && change.getMode() == TRANSIT_TO_BACK) {
+ // Set translucent here so TransitionAnimation loads the appropriate animations for
+ // translucent activities and tasks later
+ translucent = (changeFlags & FLAG_TRANSLUCENT) != 0;
+ // The main Task is launching or being brought to front, this Task is being minimized
+ animAttr = R.styleable.WindowAnimation_activityCloseExitAnimation;
+ } else if (!isCoveredByOpaqueFullscreenChange
+ && isFreeform
+ && type == TRANSIT_TO_FRONT
+ && change.getMode() == TRANSIT_TO_FRONT) {
+ // Set translucent here so TransitionAnimation loads the appropriate animations for
+ // translucent activities and tasks later
+ translucent = (changeFlags & FLAG_TRANSLUCENT) != 0;
+ // Bring the minimized Task back to front
+ animAttr = R.styleable.WindowAnimation_activityOpenEnterAnimation;
} else if (type == TRANSIT_OPEN) {
// We will translucent open animation for translucent activities and tasks. Choose
// WindowAnimation_activityOpenEnterAnimation and set translucent here, then
@@ -417,4 +439,25 @@ public class TransitionAnimationHelper {
return edgeExtensionLayer;
}
+
+ /**
+ * Returns whether there is an opaque fullscreen Change positioned in front of the given Change
+ * in the given TransitionInfo.
+ */
+ static boolean isCoveredByOpaqueFullscreenChange(
+ TransitionInfo info, TransitionInfo.Change change) {
+ // TransitionInfo#getChanges() are ordered from front to back
+ for (TransitionInfo.Change coveringChange : info.getChanges()) {
+ if (coveringChange == change) {
+ return false;
+ }
+ if ((coveringChange.getFlags() & FLAG_TRANSLUCENT) == 0
+ && coveringChange.getTaskInfo() != null
+ && coveringChange.getTaskInfo().getWindowingMode()
+ == WindowConfiguration.WINDOWING_MODE_FULLSCREEN) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index ec6802da85f6..fc8b1d27ad02 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -28,14 +28,17 @@ import static android.view.WindowManager.TRANSIT_SLEEP;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.fixScale;
+import static android.view.WindowManager.transitTypeToString;
import static android.window.TransitionInfo.FLAGS_IS_NON_APP_WINDOW;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
+import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_NO_ANIMATION;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
+import static com.android.window.flags.Flags.enforceShellThreadModel;
import static com.android.window.flags.Flags.ensureWallpaperInTransitions;
import static com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary;
import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
@@ -241,13 +244,6 @@ public class Transitions implements RemoteCallable<Transitions>,
/** Ordered list of transitions which have been merged into this one. */
private ArrayList<ActiveTransition> mMerged;
- /**
- * @deprecated DO NOT USE THIS unless absolutely necessary. It will be removed once
- * everything migrates off finishWCT.
- */
- @java.lang.Deprecated
- SurfaceControl.Transaction mAfterMergeFinishT;
-
ActiveTransition(IBinder token) {
mToken = token;
}
@@ -803,14 +799,16 @@ public class Transitions implements RemoteCallable<Transitions>,
final int changeSize = info.getChanges().size();
boolean taskChange = false;
boolean transferStartingWindow = false;
- int noAnimationBehindStartingWindow = 0;
+ int animBehindStartingWindow = 0;
boolean allOccluded = changeSize > 0;
for (int i = changeSize - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
taskChange |= change.getTaskInfo() != null;
transferStartingWindow |= change.hasFlags(FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT);
- if (change.hasAllFlags(FLAG_IS_BEHIND_STARTING_WINDOW | FLAG_NO_ANIMATION)) {
- noAnimationBehindStartingWindow++;
+ if (change.hasAllFlags(FLAG_IS_BEHIND_STARTING_WINDOW | FLAG_NO_ANIMATION)
+ || change.hasAllFlags(
+ FLAG_IS_BEHIND_STARTING_WINDOW | FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY)) {
+ animBehindStartingWindow++;
}
if (!change.hasFlags(FLAG_IS_OCCLUDED)) {
allOccluded = false;
@@ -828,11 +826,11 @@ public class Transitions implements RemoteCallable<Transitions>,
// There does not need animation when:
// A. Transfer starting window. Apply transfer starting window directly if there is no other
// task change. Since this is an activity->activity situation, we can detect it by selecting
- // transitions with only 2 changes where
- // 1. neither are tasks, and
+ // transitions with changes where
+ // 1. none are tasks, and
// 2. one is a starting-window recipient, or all change is behind starting window.
- if (!taskChange && (transferStartingWindow || noAnimationBehindStartingWindow == changeSize)
- && changeSize == 2
+ if (!taskChange && (transferStartingWindow || animBehindStartingWindow == changeSize)
+ && changeSize >= 1
// B. It's visibility change if the TRANSIT_TO_BACK/TO_FRONT happened when all
// changes are underneath another change.
|| ((info.getType() == TRANSIT_TO_BACK || info.getType() == TRANSIT_TO_FRONT)
@@ -918,9 +916,12 @@ public class Transitions implements RemoteCallable<Transitions>,
}
// An existing animation is playing, so see if we can merge.
final ActiveTransition playing = track.mActiveTransition;
+ final IBinder playingToken = playing.mToken;
+ final IBinder readyToken = ready.mToken;
+
if (ready.mAborted) {
// record as merged since it is no-op. Calls back into processReadyQueue
- onMerged(playing, ready);
+ onMerged(playingToken, readyToken);
return;
}
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition %s ready while"
@@ -928,14 +929,31 @@ public class Transitions implements RemoteCallable<Transitions>,
+ " in case they can be merged", ready, playing);
mTransitionTracer.logMergeRequested(ready.mInfo.getDebugId(), playing.mInfo.getDebugId());
playing.mHandler.mergeAnimation(ready.mToken, ready.mInfo, ready.mStartT,
- playing.mToken, (wct) -> onMerged(playing, ready));
+ playing.mToken, (wct) -> onMerged(playingToken, readyToken));
}
- private void onMerged(@NonNull ActiveTransition playing, @NonNull ActiveTransition merged) {
+ private void onMerged(@NonNull IBinder playingToken, @NonNull IBinder mergedToken) {
+ if (enforceShellThreadModel()) {
+ mMainExecutor.assertCurrentThread();
+ }
+
+ ActiveTransition playing = mKnownTransitions.get(playingToken);
+ if (playing == null) {
+ Log.e(TAG, "Merging into a non-existent transition: " + playingToken);
+ return;
+ }
+
+ ActiveTransition merged = mKnownTransitions.get(mergedToken);
+ if (merged == null) {
+ Log.e(TAG, "Merging a non-existent transition: " + mergedToken);
+ return;
+ }
+
if (playing.getTrack() != merged.getTrack()) {
throw new IllegalStateException("Can't merge across tracks: " + merged + " into "
+ playing);
}
+
final Track track = mTracks.get(playing.getTrack());
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition was merged: %s into %s",
merged, playing);
@@ -1033,20 +1051,6 @@ public class Transitions implements RemoteCallable<Transitions>,
return null;
}
- /** @deprecated */
- @java.lang.Deprecated
- public void setAfterMergeFinishTransaction(IBinder transition,
- SurfaceControl.Transaction afterMergeFinishT) {
- final ActiveTransition at = mKnownTransitions.get(transition);
- if (at == null) return;
- if (at.mAfterMergeFinishT != null) {
- Log.e(TAG, "Setting after-merge-t >1 time on transition: " + at.mInfo.getDebugId());
- at.mAfterMergeFinishT.merge(afterMergeFinishT);
- return;
- }
- at.mAfterMergeFinishT = afterMergeFinishT;
- }
-
/** Aborts a transition. This will still queue it up to maintain order. */
private void onAbort(ActiveTransition transition) {
final Track track = mTracks.get(transition.getTrack());
@@ -1079,13 +1083,17 @@ public class Transitions implements RemoteCallable<Transitions>,
info.releaseAnimSurfaces();
}
- private void onFinish(IBinder token,
- @Nullable WindowContainerTransaction wct) {
+ private void onFinish(IBinder token, @Nullable WindowContainerTransaction wct) {
+ if (enforceShellThreadModel()) {
+ mMainExecutor.assertCurrentThread();
+ }
+
final ActiveTransition active = mKnownTransitions.get(token);
if (active == null) {
Log.e(TAG, "Trying to finish a non-existent transition: " + token);
return;
}
+
final Track track = mTracks.get(active.getTrack());
if (track == null || track.mActiveTransition != active) {
Log.e(TAG, "Trying to finish a non-running transition. Either remote crashed or "
@@ -1107,7 +1115,6 @@ public class Transitions implements RemoteCallable<Transitions>,
}
// Merge all associated transactions together
SurfaceControl.Transaction fullFinish = active.mFinishT;
- SurfaceControl.Transaction afterMergeFinish = active.mAfterMergeFinishT;
if (active.mMerged != null) {
for (int iM = 0; iM < active.mMerged.size(); ++iM) {
final ActiveTransition toMerge = active.mMerged.get(iM);
@@ -1127,21 +1134,6 @@ public class Transitions implements RemoteCallable<Transitions>,
fullFinish.merge(toMerge.mFinishT);
}
}
- if (toMerge.mAfterMergeFinishT != null) {
- if (afterMergeFinish == null) {
- afterMergeFinish = toMerge.mAfterMergeFinishT;
- } else {
- afterMergeFinish.merge(toMerge.mAfterMergeFinishT);
- }
- toMerge.mAfterMergeFinishT = null;
- }
- }
- }
- if (afterMergeFinish != null) {
- if (fullFinish == null) {
- fullFinish = afterMergeFinish;
- } else {
- fullFinish.merge(afterMergeFinish);
}
}
if (fullFinish != null) {
@@ -1231,7 +1223,7 @@ public class Transitions implements RemoteCallable<Transitions>,
public IBinder startTransition(@WindowManager.TransitionType int type,
@NonNull WindowContainerTransaction wct, @Nullable TransitionHandler handler) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Directly starting a new transition "
- + "type=%d wct=%s handler=%s", type, wct, handler);
+ + "type=%s wct=%s handler=%s", transitTypeToString(type), wct, handler);
final ActiveTransition active =
new ActiveTransition(mOrganizer.startNewTransition(type, wct));
active.mHandler = handler;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt
deleted file mode 100644
index ee6c81a3fa04..000000000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.wm.shell.util
-
-import android.util.Log
-import com.android.internal.protolog.common.IProtoLogGroup
-import com.android.internal.protolog.ProtoLog
-
-/**
- * Log messages using an API similar to [com.android.internal.protolog.ProtoLog]. Useful for
- * logging from Kotlin classes as ProtoLog does not have support for Kotlin.
- *
- * All messages are logged to logcat if logging is enabled for that [IProtoLogGroup].
- */
-// TODO(b/168581922): remove once ProtoLog adds support for Kotlin
-class KtProtoLog {
- companion object {
- /** @see [com.android.internal.protolog.ProtoLog.d] */
- fun d(group: IProtoLogGroup, messageString: String, vararg args: Any) {
- if (group.isLogToLogcat) {
- Log.d(group.tag, String.format(messageString, *args))
- }
- }
-
- /** @see [com.android.internal.protolog.ProtoLog.v] */
- fun v(group: IProtoLogGroup, messageString: String, vararg args: Any) {
- if (group.isLogToLogcat) {
- Log.v(group.tag, String.format(messageString, *args))
- }
- }
-
- /** @see [com.android.internal.protolog.ProtoLog.i] */
- fun i(group: IProtoLogGroup, messageString: String, vararg args: Any) {
- if (group.isLogToLogcat) {
- Log.i(group.tag, String.format(messageString, *args))
- }
- }
-
- /** @see [com.android.internal.protolog.ProtoLog.w] */
- fun w(group: IProtoLogGroup, messageString: String, vararg args: Any) {
- if (group.isLogToLogcat) {
- Log.w(group.tag, String.format(messageString, *args))
- }
- }
-
- /** @see [com.android.internal.protolog.ProtoLog.e] */
- fun e(group: IProtoLogGroup, messageString: String, vararg args: Any) {
- if (group.isLogToLogcat) {
- Log.e(group.tag, String.format(messageString, *args))
- }
- }
-
- /** @see [com.android.internal.protolog.ProtoLog.wtf] */
- fun wtf(group: IProtoLogGroup, messageString: String, vararg args: Any) {
- if (group.isLogToLogcat) {
- Log.wtf(group.tag, String.format(messageString, *args))
- }
- }
- }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 95e0d79c212e..b9cb6d3d5007 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -26,12 +26,20 @@ import static android.view.WindowManager.TRANSIT_CHANGE;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ContentResolver;
import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Point;
import android.graphics.Rect;
+import android.graphics.Region;
+import android.hardware.input.InputManager;
import android.os.Handler;
+import android.os.RemoteException;
import android.provider.Settings;
+import android.util.Log;
import android.util.SparseArray;
import android.view.Choreographer;
import android.view.Display;
+import android.view.ISystemGestureExclusionListener;
+import android.view.IWindowManager;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
@@ -45,39 +53,74 @@ import com.android.wm.shell.R;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
/**
* View model for the window decoration with a caption and shadows. Works with
* {@link CaptionWindowDecoration}.
*/
public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
+ private static final String TAG = "CaptionWindowDecorViewModel";
+
private final ShellTaskOrganizer mTaskOrganizer;
+ private final IWindowManager mWindowManager;
private final Context mContext;
private final Handler mMainHandler;
+ private final ShellExecutor mMainExecutor;
private final Choreographer mMainChoreographer;
private final DisplayController mDisplayController;
private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
private final SyncTransactionQueue mSyncQueue;
private final Transitions mTransitions;
+ private final Region mExclusionRegion = Region.obtain();
+ private final InputManager mInputManager;
private TaskOperations mTaskOperations;
+ /**
+ * Whether to pilfer the next motion event to send cancellations to the windows below.
+ * Useful when the caption window is spy and the gesture should be handled by the system
+ * instead of by the app for their custom header content.
+ */
+ private boolean mShouldPilferCaptionEvents;
+
private final SparseArray<CaptionWindowDecoration> mWindowDecorByTaskId = new SparseArray<>();
+ private final ISystemGestureExclusionListener mGestureExclusionListener =
+ new ISystemGestureExclusionListener.Stub() {
+ @Override
+ public void onSystemGestureExclusionChanged(int displayId,
+ Region systemGestureExclusion, Region systemGestureExclusionUnrestricted) {
+ if (mContext.getDisplayId() != displayId) {
+ return;
+ }
+ mMainExecutor.execute(() -> {
+ mExclusionRegion.set(systemGestureExclusion);
+ });
+ }
+ };
+
public CaptionWindowDecorViewModel(
Context context,
Handler mainHandler,
+ ShellExecutor shellExecutor,
Choreographer mainChoreographer,
+ IWindowManager windowManager,
+ ShellInit shellInit,
ShellTaskOrganizer taskOrganizer,
DisplayController displayController,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
SyncTransactionQueue syncQueue,
Transitions transitions) {
mContext = context;
+ mMainExecutor = shellExecutor;
mMainHandler = mainHandler;
+ mWindowManager = windowManager;
mMainChoreographer = mainChoreographer;
mTaskOrganizer = taskOrganizer;
mDisplayController = displayController;
@@ -87,6 +130,18 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
mTaskOperations = new TaskOperations(null, mContext, mSyncQueue);
}
+ mInputManager = mContext.getSystemService(InputManager.class);
+
+ shellInit.addInitCallback(this::onInit, this);
+ }
+
+ private void onInit() {
+ try {
+ mWindowManager.registerSystemGestureExclusionListener(mGestureExclusionListener,
+ mContext.getDisplayId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register window manager callbacks", e);
+ }
}
@Override
@@ -178,8 +233,12 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
}
private void setupCaptionColor(RunningTaskInfo taskInfo, CaptionWindowDecoration decoration) {
- final int statusBarColor = taskInfo.taskDescription.getStatusBarColor();
- decoration.setCaptionColor(statusBarColor);
+ if (TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo)) {
+ decoration.setCaptionColor(Color.TRANSPARENT);
+ } else {
+ final int statusBarColor = taskInfo.taskDescription.getStatusBarColor();
+ decoration.setCaptionColor(statusBarColor);
+ }
}
private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) {
@@ -301,6 +360,49 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
mSyncQueue.queue(wct);
}
}
+ final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
+
+ final int actionMasked = e.getActionMasked();
+ final boolean isDown = actionMasked == MotionEvent.ACTION_DOWN;
+ final boolean isUpOrCancel = actionMasked == MotionEvent.ACTION_CANCEL
+ || actionMasked == MotionEvent.ACTION_UP;
+ if (isDown) {
+ final boolean downInCustomizableCaptionRegion =
+ decoration.checkTouchEventInCustomizableRegion(e);
+ final boolean downInExclusionRegion = mExclusionRegion.contains(
+ (int) e.getRawX(), (int) e.getRawY());
+ final boolean isTransparentCaption =
+ TaskInfoKt.isTransparentCaptionBarAppearance(decoration.mTaskInfo);
+ // MotionEvent's coordinates are relative to view, we want location in window
+ // to offset position relative to caption as a whole.
+ int[] viewLocation = new int[2];
+ v.getLocationInWindow(viewLocation);
+ final boolean isResizeEvent = decoration.shouldResizeListenerHandleEvent(e,
+ new Point(viewLocation[0], viewLocation[1]));
+ // The caption window may be a spy window when the caption background is
+ // transparent, which means events will fall through to the app window. Make
+ // sure to cancel these events if they do not happen in the intersection of the
+ // customizable region and what the app reported as exclusion areas, because
+ // the drag-move or other caption gestures should take priority outside those
+ // regions.
+ mShouldPilferCaptionEvents = !(downInCustomizableCaptionRegion
+ && downInExclusionRegion && isTransparentCaption) && !isResizeEvent;
+ }
+
+ if (!mShouldPilferCaptionEvents) {
+ // The event will be handled by a window below or pilfered by resize handler.
+ return false;
+ }
+ // Otherwise pilfer so that windows below receive cancellations for this gesture, and
+ // continue normal handling as a caption gesture.
+ if (mInputManager != null) {
+ // TODO(b/352127475): Only pilfer once per gesture
+ mInputManager.pilferPointers(v.getViewRootImpl().getInputToken());
+ }
+ if (isUpOrCancel) {
+ // Gesture is finished, reset state.
+ mShouldPilferCaptionEvents = false;
+ }
return mDragDetector.onMotionEvent(e);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index d0ca5b0fdce6..7e1b973a98f4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -21,6 +21,7 @@ import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getLarge
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResizeEdgeHandleSize;
import android.annotation.NonNull;
+import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.WindowConfiguration;
import android.app.WindowConfiguration.WindowingMode;
@@ -28,22 +29,27 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Color;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.VectorDrawable;
import android.os.Handler;
import android.util.Size;
import android.view.Choreographer;
+import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.WindowManager;
import android.window.WindowContainerTransaction;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
/**
* Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
@@ -177,12 +183,44 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
shouldSetTaskPositionAndCrop);
}
+ @VisibleForTesting
+ static void updateRelayoutParams(
+ RelayoutParams relayoutParams,
+ ActivityManager.RunningTaskInfo taskInfo,
+ boolean applyStartTransactionOnDraw,
+ boolean setTaskCropAndPosition) {
+ relayoutParams.reset();
+ relayoutParams.mRunningTaskInfo = taskInfo;
+ relayoutParams.mLayoutResId = R.layout.caption_window_decor;
+ relayoutParams.mCaptionHeightId = getCaptionHeightIdStatic(taskInfo.getWindowingMode());
+ relayoutParams.mShadowRadiusId = taskInfo.isFocused
+ ? R.dimen.freeform_decor_shadow_focused_thickness
+ : R.dimen.freeform_decor_shadow_unfocused_thickness;
+ relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
+ relayoutParams.mSetTaskPositionAndCrop = setTaskCropAndPosition;
+
+ if (TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo)) {
+ // If the app is requesting to customize the caption bar, allow input to fall
+ // through to the windows below so that the app can respond to input events on
+ // their custom content.
+ relayoutParams.mInputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY;
+ }
+ final RelayoutParams.OccludingCaptionElement backButtonElement =
+ new RelayoutParams.OccludingCaptionElement();
+ backButtonElement.mWidthResId = R.dimen.caption_left_buttons_width;
+ backButtonElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.START;
+ relayoutParams.mOccludingCaptionElements.add(backButtonElement);
+ // Then, the right-aligned section (minimize, maximize and close buttons).
+ final RelayoutParams.OccludingCaptionElement controlsElement =
+ new RelayoutParams.OccludingCaptionElement();
+ controlsElement.mWidthResId = R.dimen.caption_right_buttons_width;
+ controlsElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.END;
+ relayoutParams.mOccludingCaptionElements.add(controlsElement);
+ }
+
void relayout(RunningTaskInfo taskInfo,
SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
boolean applyStartTransactionOnDraw, boolean setTaskCropAndPosition) {
- final int shadowRadiusID = taskInfo.isFocused
- ? R.dimen.freeform_decor_shadow_focused_thickness
- : R.dimen.freeform_decor_shadow_unfocused_thickness;
final boolean isFreeform =
taskInfo.getWindowingMode() == WindowConfiguration.WINDOWING_MODE_FREEFORM;
final boolean isDragResizeable = isFreeform && taskInfo.isResizeable;
@@ -191,13 +229,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
final WindowContainerTransaction wct = new WindowContainerTransaction();
- mRelayoutParams.reset();
- mRelayoutParams.mRunningTaskInfo = taskInfo;
- mRelayoutParams.mLayoutResId = R.layout.caption_window_decor;
- mRelayoutParams.mCaptionHeightId = getCaptionHeightId(taskInfo.getWindowingMode());
- mRelayoutParams.mShadowRadiusId = shadowRadiusID;
- mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
- mRelayoutParams.mSetTaskPositionAndCrop = setTaskCropAndPosition;
+ updateRelayoutParams(mRelayoutParams, taskInfo, applyStartTransactionOnDraw,
+ setTaskCropAndPosition);
relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
// After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
@@ -303,6 +336,17 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
mDragResizeListener = null;
}
+ /**
+ * Checks whether the touch event falls inside the customizable caption region.
+ */
+ boolean checkTouchEventInCustomizableRegion(MotionEvent ev) {
+ return mResult.mCustomizableCaptionRegion.contains((int) ev.getRawX(), (int) ev.getRawY());
+ }
+
+ boolean shouldResizeListenerHandleEvent(@NonNull MotionEvent e, @NonNull Point offset) {
+ return mDragResizeListener != null && mDragResizeListener.shouldHandleEvent(e, offset);
+ }
+
@Override
public void close() {
closeDragResizeListener();
@@ -311,6 +355,10 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
@Override
int getCaptionHeightId(@WindowingMode int windowingMode) {
+ return getCaptionHeightIdStatic(windowingMode);
+ }
+
+ private static int getCaptionHeightIdStatic(@WindowingMode int windowingMode) {
return R.dimen.freeform_decor_caption_height;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index a05dbf844db0..d12b9060bee3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_HOVER_ENTER;
@@ -32,7 +33,7 @@ import static android.view.WindowInsets.Type.statusBars;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
-import static com.android.wm.shell.compatui.AppCompatUtils.isSingleTopActivityTranslucent;
+import static com.android.wm.shell.compatui.AppCompatUtils.isTopActivityExemptFromDesktopWindowing;
import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
@@ -41,12 +42,17 @@ import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityTaskManager;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.input.InputManager;
+import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
@@ -73,6 +79,7 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.Cuj;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.protolog.ProtoLog;
import com.android.window.flags.Flags;
import com.android.wm.shell.R;
@@ -81,7 +88,6 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.InteractionJankMonitorUtils;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource;
@@ -91,7 +97,7 @@ import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition;
import com.android.wm.shell.desktopmode.DesktopWallpaperActivity;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -105,7 +111,6 @@ import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
import java.io.PrintWriter;
-import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
@@ -131,6 +136,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private final SyncTransactionQueue mSyncQueue;
private final DesktopTasksController mDesktopTasksController;
private final InputManager mInputManager;
+ private final InteractionJankMonitor mInteractionJankMonitor;
private boolean mTransitionDragActive;
private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -186,7 +192,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
SyncTransactionQueue syncQueue,
Transitions transitions,
Optional<DesktopTasksController> desktopTasksController,
- RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ InteractionJankMonitor interactionJankMonitor
) {
this(
context,
@@ -207,7 +214,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
new InputMonitorFactory(),
SurfaceControl.Transaction::new,
rootTaskDisplayAreaOrganizer,
- new SparseArray<>());
+ new SparseArray<>(),
+ interactionJankMonitor);
}
@VisibleForTesting
@@ -230,7 +238,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
InputMonitorFactory inputMonitorFactory,
Supplier<SurfaceControl.Transaction> transactionFactory,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
- SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId) {
+ SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId,
+ InteractionJankMonitor interactionJankMonitor) {
mContext = context;
mMainExecutor = shellExecutor;
mMainHandler = mainHandler;
@@ -253,6 +262,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mWindowDecorByTaskId = windowDecorByTaskId;
mSysUIPackageName = mContext.getResources().getString(
com.android.internal.R.string.config_systemUi);
+ mInteractionJankMonitor = interactionJankMonitor;
shellInit.addInitCallback(this::onInit, this);
}
@@ -388,8 +398,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
if (decoration == null) {
return;
}
- InteractionJankMonitorUtils.beginTracing(
- Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, mContext, decoration.mTaskSurface, tag);
+ mInteractionJankMonitor.begin(
+ decoration.mTaskSurface, mContext, Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, tag);
mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo);
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
@@ -406,6 +416,26 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
decoration.closeMaximizeMenu();
}
+ private void onOpenInBrowser(@NonNull DesktopModeWindowDecoration decor, @NonNull Uri uri) {
+ openInBrowser(uri);
+ decor.closeHandleMenu();
+ decor.closeMaximizeMenu();
+ }
+
+ private void openInBrowser(Uri uri) {
+ final Intent intent = new Intent(Intent.ACTION_VIEW, uri)
+ .setComponent(getDefaultBrowser())
+ .addFlags(FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ }
+
+ private ComponentName getDefaultBrowser() {
+ final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://"));
+ final ResolveInfo info = mContext.getPackageManager()
+ .resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ return info.getComponentInfo().getComponentName();
+ }
+
private class DesktopModeTouchEventListener extends GestureDetector.SimpleOnGestureListener
implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener,
View.OnGenericMotionListener, DragDetector.MotionEventHandler {
@@ -485,6 +515,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
} else if (id == R.id.split_screen_button) {
decoration.closeHandleMenu();
mDesktopTasksController.requestSplit(decoration.mTaskInfo);
+ } else if (id == R.id.open_in_browser_button) {
+ // TODO(b/346441962): let the decoration handle the click gesture and only call back
+ // to the ViewModel via #setOpenInBrowserClickListener
+ decoration.onOpenInBrowserClick();
} else if (id == R.id.collapse_menu_button) {
decoration.closeHandleMenu();
} else if (id == R.id.maximize_window) {
@@ -1006,7 +1040,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private void createInputChannel(int displayId) {
final InputManager inputManager = mContext.getSystemService(InputManager.class);
final InputMonitor inputMonitor =
- mInputMonitorFactory.create(inputManager, mContext);
+ mInputMonitorFactory.create(inputManager, displayId);
final EventReceiver eventReceiver = new EventReceiver(inputMonitor,
inputMonitor.getInputChannel(), Looper.myLooper());
mEventReceiversByDisplay.put(displayId, eventReceiver);
@@ -1029,12 +1063,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
&& taskInfo.isFocused) {
return false;
}
- // TODO(b/347289970): Consider replacing with API
if (Flags.enableDesktopWindowingModalsPolicy()
- && isSingleTopActivityTranslucent(taskInfo)) {
- return false;
- }
- if (isSystemUIApplication(taskInfo)) {
+ && isTopActivityExemptFromDesktopWindowing(mContext, taskInfo)) {
return false;
}
return DesktopModeStatus.canEnterDesktopMode(mContext)
@@ -1077,7 +1107,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
} else {
dragPositioningCallback = new VeiledResizeTaskPositioner(
mTaskOrganizer, windowDecoration, mDisplayController,
- mDragStartListener, mTransitions);
+ mDragStartListener, mTransitions, mInteractionJankMonitor);
windowDecoration.setTaskDragResizer(
(VeiledResizeTaskPositioner) dragPositioningCallback);
}
@@ -1091,6 +1121,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
windowDecoration.setOnRightSnapClickListener((taskId, tag) -> {
onSnapResize(taskId, false /* isLeft */);
});
+ windowDecoration.setOpenInBrowserClickListener(this::onOpenInBrowser);
windowDecoration.setCaptionListeners(
touchEventListener, touchEventListener, touchEventListener, touchEventListener);
windowDecoration.setExclusionRegionListener(mExclusionRegionListener);
@@ -1113,14 +1144,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
&& mSplitScreenController.isTaskInSplitScreen(taskId);
}
- // TODO(b/347289970): Consider replacing with API
- private boolean isSystemUIApplication(RunningTaskInfo taskInfo) {
- if (taskInfo.baseActivity != null) {
- return (Objects.equals(taskInfo.baseActivity.getPackageName(), mSysUIPackageName));
- }
- return false;
- }
-
private void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.println(prefix + "DesktopModeWindowDecorViewModel");
@@ -1171,8 +1194,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
}
static class InputMonitorFactory {
- InputMonitor create(InputManager inputManager, Context context) {
- return inputManager.monitorGestureInput("caption-touch", context.getDisplayId());
+ InputMonitor create(InputManager inputManager, int displayId) {
+ return inputManager.monitorGestureInput("caption-touch", displayId);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index f53c21d352b3..5d662b20ebb9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -31,6 +31,7 @@ import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResiz
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.WindowConfiguration.WindowingMode;
+import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -43,6 +44,7 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.os.Handler;
import android.os.Trace;
import android.util.Log;
@@ -67,7 +69,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.windowdecor.common.OnTaskActionClickListener;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
@@ -87,6 +89,7 @@ import java.util.function.Supplier;
*/
public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {
private static final String TAG = "DesktopModeWindowDecoration";
+ private static final int CAPTURED_LINK_TIMEOUT_MS = 7000;
@VisibleForTesting
static final long CLOSE_MAXIMIZE_MENU_DELAY_MS = 150L;
@@ -123,6 +126,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
private Bitmap mResizeVeilBitmap;
private CharSequence mAppName;
+ private CapturedLink mCapturedLink;
+ private OpenInBrowserClickListener mOpenInBrowserClickListener;
private ExclusionRegionListener mExclusionRegionListener;
@@ -137,6 +142,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
// being hovered. There's a small delay after stopping the hover, to allow a quick reentry
// to cancel the close.
private final Runnable mCloseMaximizeWindowRunnable = this::closeMaximizeMenu;
+ private final Runnable mCapturedLinkExpiredRunnable = this::onCapturedLinkExpired;
DesktopModeWindowDecoration(
Context context,
@@ -152,8 +158,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
handler, choreographer, syncQueue, rootTaskDisplayAreaOrganizer,
SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
WindowContainerTransaction::new, SurfaceControl::new,
- new SurfaceControlViewHostFactory() {},
- DefaultMaximizeMenuFactory.INSTANCE);
+ new SurfaceControlViewHostFactory() {}, DefaultMaximizeMenuFactory.INSTANCE);
}
DesktopModeWindowDecoration(
@@ -231,6 +236,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mDragDetector.setTouchSlop(ViewConfiguration.get(mContext).getScaledTouchSlop());
}
+ void setOpenInBrowserClickListener(OpenInBrowserClickListener listener) {
+ mOpenInBrowserClickListener = listener;
+ }
+
@Override
void relayout(ActivityManager.RunningTaskInfo taskInfo) {
final SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
@@ -322,6 +331,11 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
Trace.beginSection("DesktopModeWindowDecoration#updateRelayoutParamsAndSurfaces");
+
+ if (Flags.enableDesktopWindowingAppToWeb()) {
+ setCapturedLink(taskInfo.capturedLink, taskInfo.capturedLinkTimestamp);
+ }
+
if (isHandleMenuActive()) {
mHandleMenu.relayout(startT);
}
@@ -366,6 +380,28 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
Trace.endSection(); // DesktopModeWindowDecoration#updateRelayoutParamsAndSurfaces
}
+ private void setCapturedLink(Uri capturedLink, long timeStamp) {
+ if (capturedLink == null
+ || (mCapturedLink != null && mCapturedLink.mTimeStamp == timeStamp)) {
+ return;
+ }
+ mCapturedLink = new CapturedLink(capturedLink, timeStamp);
+ mHandler.postDelayed(mCapturedLinkExpiredRunnable, CAPTURED_LINK_TIMEOUT_MS);
+ }
+
+ private void onCapturedLinkExpired() {
+ mHandler.removeCallbacks(mCapturedLinkExpiredRunnable);
+ if (mCapturedLink != null) {
+ mCapturedLink.setExpired();
+ }
+ }
+
+ void onOpenInBrowserClick() {
+ if (mOpenInBrowserClickListener == null || mCapturedLink == null) return;
+ mOpenInBrowserClickListener.onClick(this, mCapturedLink.mUri);
+ onCapturedLinkExpired();
+ }
+
private void updateDragResizeListener(SurfaceControl oldDecorationSurface) {
if (!isDragResizable(mTaskInfo)) {
if (!mTaskInfo.positionInParent.equals(mPositionInParent)) {
@@ -600,12 +636,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
if (mAppIconBitmap != null && mAppName != null) {
return;
}
- final ActivityInfo activityInfo = mTaskInfo.topActivityInfo;
- if (activityInfo == null) {
- Log.e(TAG, "Top activity info not found in task");
+ final ComponentName baseActivity = mTaskInfo.baseActivity;
+ if (baseActivity == null) {
+ Log.e(TAG, "Base activity component not found in task");
return;
}
- PackageManager pm = mContext.getApplicationContext().getPackageManager();
+ final PackageManager pm = mContext.getApplicationContext().getPackageManager();
+ final ActivityInfo activityInfo = pm.getActivityInfo(baseActivity, 0 /* flags */);
final IconProvider provider = new IconProvider(mContext);
final Drawable appIconDrawable = provider.getIcon(activityInfo);
final BaseIconFactory headerIconFactory = createIconFactory(mContext,
@@ -619,6 +656,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
mAppName = pm.getApplicationLabel(applicationInfo);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Base activity's component name cannot be found on the system");
} finally {
Trace.endSection();
}
@@ -813,21 +852,28 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
*/
void createHandleMenu(SplitScreenController splitScreenController) {
loadAppInfoIfNeeded();
- mHandleMenu = new HandleMenu.Builder(this)
- .setAppIcon(mAppIconBitmap)
- .setAppName(mAppName)
- .setOnClickListener(mOnCaptionButtonClickListener)
- .setOnTouchListener(mOnCaptionTouchListener)
- .setLayoutId(mRelayoutParams.mLayoutResId)
- .setWindowingButtonsVisible(DesktopModeStatus.canEnterDesktopMode(mContext))
- .setCaptionHeight(mResult.mCaptionHeight)
- .setDisplayController(mDisplayController)
- .setSplitScreenController(splitScreenController)
- .build();
+ mHandleMenu = new HandleMenu(
+ this,
+ mRelayoutParams.mLayoutResId,
+ mOnCaptionButtonClickListener,
+ mOnCaptionTouchListener,
+ mAppIconBitmap,
+ mAppName,
+ mDisplayController,
+ splitScreenController,
+ DesktopModeStatus.canEnterDesktopMode(mContext),
+ browserLinkAvailable(),
+ mResult.mCaptionHeight
+ );
mWindowDecorViewHolder.onHandleMenuOpened();
mHandleMenu.show();
}
+ @VisibleForTesting
+ boolean browserLinkAvailable() {
+ return mCapturedLink != null && !mCapturedLink.mExpired;
+ }
+
/**
* Close the handle menu window.
*/
@@ -1117,6 +1163,31 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
}
}
+ @VisibleForTesting
+ static class CapturedLink {
+ private final long mTimeStamp;
+ private final Uri mUri;
+ private boolean mExpired;
+
+ CapturedLink(@NonNull Uri uri, long timeStamp) {
+ mUri = uri;
+ mTimeStamp = timeStamp;
+ mExpired = false;
+ }
+
+ void setExpired() {
+ mExpired = true;
+ }
+ }
+
+
+ /** Listener for the handle menu's "Open in browser" button */
+ interface OpenInBrowserClickListener {
+
+ /** Inform the implementing class that the "Open in browser" button has been clicked */
+ void onClick(DesktopModeWindowDecoration decoration, Uri uri);
+ }
+
interface ExclusionRegionListener {
/** Inform the implementing class of this task's change in region resize handles */
void onExclusionRegionChanged(int taskId, Region region);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
index d48ce536f2b3..2fd3eaa37ec3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
@@ -33,7 +33,7 @@ import androidx.annotation.NonNull;
import com.android.window.flags.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
/**
* Utility class that contains logic common to classes implementing {@link DragPositioningCallback}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index a3616f65f3b2..32df8b3b2c7c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -468,8 +468,7 @@ class DragResizeInputListener implements AutoCloseable {
case MotionEvent.ACTION_HOVER_ENTER:
case MotionEvent.ACTION_HOVER_MOVE: {
updateCursorType(e.getDisplayId(), e.getDeviceId(),
- e.getPointerId(/*pointerIndex=*/0), e.getXCursorPosition(),
- e.getYCursorPosition());
+ e.getPointerId(/*pointerIndex=*/0), e.getX(), e.getY());
result = true;
break;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
index b5d1d4a76342..ba5f0791a010 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
@@ -33,9 +33,6 @@ import android.graphics.Region;
import android.util.Size;
import android.view.MotionEvent;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
import com.android.wm.shell.R;
import java.util.Objects;
@@ -44,11 +41,6 @@ import java.util.Objects;
* Geometry for a drag resize region for a particular window.
*/
final class DragResizeWindowGeometry {
- // TODO(b/337264971) clean up when no longer needed
- @VisibleForTesting static final boolean DEBUG = true;
- // The additional width to apply to edge resize bounds just for logging when a touch is
- // close.
- @VisibleForTesting static final int EDGE_DEBUG_BUFFER = 15;
private final int mTaskCornerRadius;
private final Size mTaskSize;
// The size of the handle applied to the edges of the window, for the user to drag resize.
@@ -60,8 +52,6 @@ final class DragResizeWindowGeometry {
private final @NonNull TaskCorners mFineTaskCorners;
// The bounds for each edge drag region, which can resize the task in one direction.
private final @NonNull TaskEdges mTaskEdges;
- // Extra-large edge bounds for logging to help debug when an edge resize is ignored.
- private final @Nullable TaskEdges mDebugTaskEdges;
DragResizeWindowGeometry(int taskCornerRadius, @NonNull Size taskSize,
int resizeHandleThickness, int fineCornerSize, int largeCornerSize) {
@@ -74,11 +64,6 @@ final class DragResizeWindowGeometry {
// Save touch areas for each edge.
mTaskEdges = new TaskEdges(mTaskSize, mResizeHandleThickness);
- if (DEBUG) {
- mDebugTaskEdges = new TaskEdges(mTaskSize, mResizeHandleThickness + EDGE_DEBUG_BUFFER);
- } else {
- mDebugTaskEdges = null;
- }
}
/**
@@ -120,13 +105,7 @@ final class DragResizeWindowGeometry {
*/
void union(@NonNull Region region) {
// Apply the edge resize regions.
- if (inDebugMode()) {
- // Use the larger edge sizes if we are debugging, to be able to log if we ignored a
- // touch due to the size of the edge region.
- mDebugTaskEdges.union(region);
- } else {
- mTaskEdges.union(region);
- }
+ mTaskEdges.union(region);
if (enableWindowingEdgeDragResize()) {
// Apply the corners as well for the larger corners, to ensure we capture all possible
@@ -219,10 +198,6 @@ final class DragResizeWindowGeometry {
@DragPositioningCallback.CtrlType
private int calculateEdgeResizeCtrlType(float x, float y) {
- if (inDebugMode() && (mDebugTaskEdges.contains((int) x, (int) y)
- && !mTaskEdges.contains((int) x, (int) y))) {
- return CTRL_TYPE_UNDEFINED;
- }
int ctrlType = CTRL_TYPE_UNDEFINED;
// mTaskCornerRadius is only used in comparing with corner regions. Comparisons with
// sides will use the bounds specified in setGeometry and not go into task bounds.
@@ -313,9 +288,7 @@ final class DragResizeWindowGeometry {
&& this.mResizeHandleThickness == other.mResizeHandleThickness
&& this.mFineTaskCorners.equals(other.mFineTaskCorners)
&& this.mLargeTaskCorners.equals(other.mLargeTaskCorners)
- && (inDebugMode()
- ? this.mDebugTaskEdges.equals(other.mDebugTaskEdges)
- : this.mTaskEdges.equals(other.mTaskEdges));
+ && this.mTaskEdges.equals(other.mTaskEdges);
}
@Override
@@ -326,11 +299,7 @@ final class DragResizeWindowGeometry {
mResizeHandleThickness,
mFineTaskCorners,
mLargeTaskCorners,
- (inDebugMode() ? mDebugTaskEdges : mTaskEdges));
- }
-
- private boolean inDebugMode() {
- return DEBUG && mDebugTaskEdges != null;
+ mTaskEdges);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
deleted file mode 100644
index df0836c1121d..000000000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.wm.shell.windowdecor;
-
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.view.MotionEvent.ACTION_DOWN;
-import static android.view.MotionEvent.ACTION_UP;
-
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActivityManager.RunningTaskInfo;
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.view.MotionEvent;
-import android.view.SurfaceControl;
-import android.view.View;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.window.SurfaceSyncGroup;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.window.flags.Flags;
-import com.android.wm.shell.R;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.splitscreen.SplitScreenController;
-import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer;
-import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer;
-
-/**
- * Handle menu opened when the appropriate button is clicked on.
- *
- * Displays up to 3 pills that show the following:
- * App Info: App name, app icon, and collapse button to close the menu.
- * Windowing Options(Proto 2 only): Buttons to change windowing modes.
- * Additional Options: Miscellaneous functions including screenshot and closing task.
- */
-class HandleMenu {
- private static final String TAG = "HandleMenu";
- private static final boolean SHOULD_SHOW_MORE_ACTIONS_PILL = false;
- private final Context mContext;
- private final DesktopModeWindowDecoration mParentDecor;
- @VisibleForTesting
- AdditionalViewContainer mHandleMenuViewContainer;
- // Position of the handle menu used for laying out the handle view.
- @VisibleForTesting
- final PointF mHandleMenuPosition = new PointF();
- // With the introduction of {@link AdditionalSystemViewContainer}, {@link mHandleMenuPosition}
- // may be in a different coordinate space than the input coordinates. Therefore, we still care
- // about the menu's coordinates relative to the display as a whole, so we need to maintain
- // those as well.
- final Point mGlobalMenuPosition = new Point();
- private final boolean mShouldShowWindowingPill;
- private final Bitmap mAppIconBitmap;
- private final CharSequence mAppName;
- private final View.OnClickListener mOnClickListener;
- private final View.OnTouchListener mOnTouchListener;
- private final RunningTaskInfo mTaskInfo;
- private final DisplayController mDisplayController;
- private final SplitScreenController mSplitScreenController;
- private final int mLayoutResId;
- private int mMarginMenuTop;
- private int mMarginMenuStart;
- private int mMenuHeight;
- private int mMenuWidth;
- private final int mCaptionHeight;
- private HandleMenuAnimator mHandleMenuAnimator;
-
-
- HandleMenu(DesktopModeWindowDecoration parentDecor, int layoutResId,
- View.OnClickListener onClickListener, View.OnTouchListener onTouchListener,
- Bitmap appIcon, CharSequence appName, DisplayController displayController,
- SplitScreenController splitScreenController, boolean shouldShowWindowingPill,
- int captionHeight) {
- mParentDecor = parentDecor;
- mContext = mParentDecor.mDecorWindowContext;
- mTaskInfo = mParentDecor.mTaskInfo;
- mDisplayController = displayController;
- mSplitScreenController = splitScreenController;
- mLayoutResId = layoutResId;
- mOnClickListener = onClickListener;
- mOnTouchListener = onTouchListener;
- mAppIconBitmap = appIcon;
- mAppName = appName;
- mShouldShowWindowingPill = shouldShowWindowingPill;
- mCaptionHeight = captionHeight;
- loadHandleMenuDimensions();
- updateHandleMenuPillPositions();
- }
-
- void show() {
- final SurfaceSyncGroup ssg = new SurfaceSyncGroup(TAG);
- SurfaceControl.Transaction t = new SurfaceControl.Transaction();
-
- createHandleMenuViewContainer(t, ssg);
- ssg.addTransaction(t);
- ssg.markSyncReady();
- setupHandleMenu();
- animateHandleMenu();
- }
-
- private void createHandleMenuViewContainer(SurfaceControl.Transaction t,
- SurfaceSyncGroup ssg) {
- final int x = (int) mHandleMenuPosition.x;
- final int y = (int) mHandleMenuPosition.y;
- if (!mTaskInfo.isFreeform() && Flags.enableAdditionalWindowsAboveStatusBar()) {
- mHandleMenuViewContainer = new AdditionalSystemViewContainer(mContext,
- R.layout.desktop_mode_window_decor_handle_menu, mTaskInfo.taskId,
- x, y, mMenuWidth, mMenuHeight);
- } else {
- mHandleMenuViewContainer = mParentDecor.addWindow(
- R.layout.desktop_mode_window_decor_handle_menu, "Handle Menu",
- t, ssg, x, y, mMenuWidth, mMenuHeight);
- }
- final View handleMenuView = mHandleMenuViewContainer.getView();
- mHandleMenuAnimator = new HandleMenuAnimator(handleMenuView, mMenuWidth, mCaptionHeight);
- }
-
- /**
- * Animates the appearance of the handle menu and its three pills.
- */
- private void animateHandleMenu() {
- if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
- || mTaskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW) {
- mHandleMenuAnimator.animateCaptionHandleExpandToOpen();
- } else {
- mHandleMenuAnimator.animateOpen();
- }
- }
-
- /**
- * Set up all three pills of the handle menu: app info pill, windowing pill, & more actions
- * pill.
- */
- private void setupHandleMenu() {
- final View handleMenu = mHandleMenuViewContainer.getView();
- handleMenu.setOnTouchListener(mOnTouchListener);
- setupAppInfoPill(handleMenu);
- if (mShouldShowWindowingPill) {
- setupWindowingPill(handleMenu);
- }
- setupMoreActionsPill(handleMenu);
- }
-
- /**
- * Set up interactive elements of handle menu's app info pill.
- */
- private void setupAppInfoPill(View handleMenu) {
- final HandleMenuImageButton collapseBtn =
- handleMenu.findViewById(R.id.collapse_menu_button);
- final ImageView appIcon = handleMenu.findViewById(R.id.application_icon);
- final TextView appName = handleMenu.findViewById(R.id.application_name);
- collapseBtn.setOnClickListener(mOnClickListener);
- collapseBtn.setTaskInfo(mTaskInfo);
- appIcon.setImageBitmap(mAppIconBitmap);
- appName.setText(mAppName);
- }
-
- /**
- * Set up interactive elements and color of handle menu's windowing pill.
- */
- private void setupWindowingPill(View handleMenu) {
- final ImageButton fullscreenBtn = handleMenu.findViewById(
- R.id.fullscreen_button);
- final ImageButton splitscreenBtn = handleMenu.findViewById(
- R.id.split_screen_button);
- final ImageButton floatingBtn = handleMenu.findViewById(R.id.floating_button);
- // TODO: Remove once implemented.
- floatingBtn.setVisibility(View.GONE);
-
- final ImageButton desktopBtn = handleMenu.findViewById(R.id.desktop_button);
- fullscreenBtn.setOnClickListener(mOnClickListener);
- splitscreenBtn.setOnClickListener(mOnClickListener);
- floatingBtn.setOnClickListener(mOnClickListener);
- desktopBtn.setOnClickListener(mOnClickListener);
- // The button corresponding to the windowing mode that the task is currently in uses a
- // different color than the others.
- final ColorStateList[] iconColors = getWindowingIconColor();
- final ColorStateList inActiveColorStateList = iconColors[0];
- final ColorStateList activeColorStateList = iconColors[1];
- final int windowingMode = mTaskInfo.getWindowingMode();
- fullscreenBtn.setImageTintList(windowingMode == WINDOWING_MODE_FULLSCREEN
- ? activeColorStateList : inActiveColorStateList);
- splitscreenBtn.setImageTintList(windowingMode == WINDOWING_MODE_MULTI_WINDOW
- ? activeColorStateList : inActiveColorStateList);
- floatingBtn.setImageTintList(windowingMode == WINDOWING_MODE_PINNED
- ? activeColorStateList : inActiveColorStateList);
- desktopBtn.setImageTintList(windowingMode == WINDOWING_MODE_FREEFORM
- ? activeColorStateList : inActiveColorStateList);
- }
-
- /**
- * Set up interactive elements & height of handle menu's more actions pill
- */
- private void setupMoreActionsPill(View handleMenu) {
- if (!SHOULD_SHOW_MORE_ACTIONS_PILL) {
- handleMenu.findViewById(R.id.more_actions_pill).setVisibility(View.GONE);
- }
- }
-
- /**
- * Returns array of windowing icon color based on current UI theme. First element of the
- * array is for inactive icons and the second is for active icons.
- */
- private ColorStateList[] getWindowingIconColor() {
- final int mode = mContext.getResources().getConfiguration().uiMode
- & Configuration.UI_MODE_NIGHT_MASK;
- final boolean isNightMode = (mode == Configuration.UI_MODE_NIGHT_YES);
- final TypedArray typedArray = mContext.obtainStyledAttributes(new int[]{
- com.android.internal.R.attr.materialColorOnSurface,
- com.android.internal.R.attr.materialColorPrimary});
- final int inActiveColor = typedArray.getColor(0, isNightMode ? Color.WHITE : Color.BLACK);
- final int activeColor = typedArray.getColor(1, isNightMode ? Color.WHITE : Color.BLACK);
- typedArray.recycle();
- return new ColorStateList[]{ColorStateList.valueOf(inActiveColor),
- ColorStateList.valueOf(activeColor)};
- }
-
- /**
- * Updates handle menu's position variables to reflect its next position.
- */
- private void updateHandleMenuPillPositions() {
- int menuX;
- final int menuY;
- final Rect taskBounds = mTaskInfo.getConfiguration().windowConfiguration.getBounds();
- updateGlobalMenuPosition(taskBounds);
- if (mLayoutResId == R.layout.desktop_mode_app_header) {
- // Align the handle menu to the left side of the caption.
- menuX = mMarginMenuStart;
- menuY = mMarginMenuTop;
- } else {
- if (Flags.enableAdditionalWindowsAboveStatusBar()) {
- // In a focused decor, we use global coordinates for handle menu. Therefore we
- // need to account for other factors like split stage and menu/handle width to
- // center the menu.
- final DisplayLayout layout = mDisplayController
- .getDisplayLayout(mTaskInfo.displayId);
- menuX = mGlobalMenuPosition.x + ((mMenuWidth - layout.width()) / 2);
- menuY = mGlobalMenuPosition.y + ((mMenuHeight - layout.height()) / 2);
- } else {
- menuX = (taskBounds.width() / 2) - (mMenuWidth / 2);
- menuY = mMarginMenuTop;
- }
- }
- // Handle Menu position setup.
- mHandleMenuPosition.set(menuX, menuY);
- }
-
- private void updateGlobalMenuPosition(Rect taskBounds) {
- if (mTaskInfo.isFreeform()) {
- mGlobalMenuPosition.set(taskBounds.left + mMarginMenuStart,
- taskBounds.top + mMarginMenuTop);
- } else if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
- mGlobalMenuPosition.set(
- (taskBounds.width() / 2) - (mMenuWidth / 2) + mMarginMenuStart,
- mMarginMenuTop
- );
- } else if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW) {
- final int splitPosition = mSplitScreenController.getSplitPosition(mTaskInfo.taskId);
- final Rect leftOrTopStageBounds = new Rect();
- final Rect rightOrBottomStageBounds = new Rect();
- mSplitScreenController.getStageBounds(leftOrTopStageBounds,
- rightOrBottomStageBounds);
- // TODO(b/343561161): This needs to be calculated differently if the task is in
- // top/bottom split.
- if (splitPosition == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
- mGlobalMenuPosition.set(leftOrTopStageBounds.width()
- + (rightOrBottomStageBounds.width() / 2)
- - (mMenuWidth / 2) + mMarginMenuStart,
- mMarginMenuTop);
- } else if (splitPosition == SPLIT_POSITION_TOP_OR_LEFT) {
- mGlobalMenuPosition.set((leftOrTopStageBounds.width() / 2)
- - (mMenuWidth / 2) + mMarginMenuStart,
- mMarginMenuTop);
- }
- }
- }
-
- /**
- * Update pill layout, in case task changes have caused positioning to change.
- */
- void relayout(SurfaceControl.Transaction t) {
- if (mHandleMenuViewContainer != null) {
- updateHandleMenuPillPositions();
- mHandleMenuViewContainer.setPosition(t, mHandleMenuPosition.x, mHandleMenuPosition.y);
- }
- }
-
- /**
- * Check a passed MotionEvent if a click or hover has occurred on any button on this caption
- * Note this should only be called when a regular onClick/onHover is not possible
- * (i.e. the button was clicked through status bar layer)
- *
- * @param ev the MotionEvent to compare against.
- */
- void checkMotionEvent(MotionEvent ev) {
- // If the menu view is above status bar, we can let the views handle input directly.
- if (isViewAboveStatusBar()) return;
- final View handleMenu = mHandleMenuViewContainer.getView();
- final HandleMenuImageButton collapse = handleMenu.findViewById(R.id.collapse_menu_button);
- final PointF inputPoint = translateInputToLocalSpace(ev);
- final boolean inputInCollapseButton = pointInView(collapse, inputPoint.x, inputPoint.y);
- final int action = ev.getActionMasked();
- collapse.setHovered(inputInCollapseButton && action != ACTION_UP);
- collapse.setPressed(inputInCollapseButton && action == ACTION_DOWN);
- if (action == ACTION_UP && inputInCollapseButton) {
- collapse.performClick();
- }
- }
-
- private boolean isViewAboveStatusBar() {
- return Flags.enableAdditionalWindowsAboveStatusBar()
- && !mTaskInfo.isFreeform();
- }
-
- // Translate the input point from display coordinates to the same space as the handle menu.
- private PointF translateInputToLocalSpace(MotionEvent ev) {
- return new PointF(ev.getX() - mHandleMenuPosition.x,
- ev.getY() - mHandleMenuPosition.y);
- }
-
- /**
- * A valid menu input is one of the following:
- * An input that happens in the menu views.
- * Any input before the views have been laid out.
- *
- * @param inputPoint the input to compare against.
- */
- boolean isValidMenuInput(PointF inputPoint) {
- if (!viewsLaidOut()) return true;
- if (!isViewAboveStatusBar()) {
- return pointInView(
- mHandleMenuViewContainer.getView(),
- inputPoint.x - mHandleMenuPosition.x,
- inputPoint.y - mHandleMenuPosition.y);
- } else {
- // Handle menu exists in a different coordinate space when added to WindowManager.
- // Therefore we must compare the provided input coordinates to global menu coordinates.
- // This includes factoring for split stage as input coordinates are relative to split
- // stage position, not relative to the display as a whole.
- PointF inputRelativeToMenu = new PointF(
- inputPoint.x - mGlobalMenuPosition.x,
- inputPoint.y - mGlobalMenuPosition.y
- );
- if (mSplitScreenController.getSplitPosition(mTaskInfo.taskId)
- == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
- // TODO(b/343561161): This also needs to be calculated differently if
- // the task is in top/bottom split.
- Rect leftStageBounds = new Rect();
- mSplitScreenController.getStageBounds(leftStageBounds, new Rect());
- inputRelativeToMenu.x += leftStageBounds.width();
- }
- return pointInView(
- mHandleMenuViewContainer.getView(),
- inputRelativeToMenu.x,
- inputRelativeToMenu.y);
- }
- }
-
- private boolean pointInView(View v, float x, float y) {
- return v != null && v.getLeft() <= x && v.getRight() >= x
- && v.getTop() <= y && v.getBottom() >= y;
- }
-
- /**
- * Check if the views for handle menu can be seen.
- */
- private boolean viewsLaidOut() {
- return mHandleMenuViewContainer.getView().isLaidOut();
- }
-
- private void loadHandleMenuDimensions() {
- final Resources resources = mContext.getResources();
- mMenuWidth = loadDimensionPixelSize(resources,
- R.dimen.desktop_mode_handle_menu_width);
- mMenuHeight = getHandleMenuHeight(resources);
- mMarginMenuTop = loadDimensionPixelSize(resources,
- R.dimen.desktop_mode_handle_menu_margin_top);
- mMarginMenuStart = loadDimensionPixelSize(resources,
- R.dimen.desktop_mode_handle_menu_margin_start);
- }
-
- /**
- * Determines handle menu height based on if windowing pill should be shown.
- */
- private int getHandleMenuHeight(Resources resources) {
- int menuHeight = loadDimensionPixelSize(resources, R.dimen.desktop_mode_handle_menu_height);
- if (!mShouldShowWindowingPill) {
- menuHeight -= loadDimensionPixelSize(resources,
- R.dimen.desktop_mode_handle_menu_windowing_pill_height);
- }
- if (!SHOULD_SHOW_MORE_ACTIONS_PILL) {
- menuHeight -= loadDimensionPixelSize(resources,
- R.dimen.desktop_mode_handle_menu_more_actions_pill_height);
- }
- return menuHeight;
- }
-
- private int loadDimensionPixelSize(Resources resources, int resourceId) {
- if (resourceId == Resources.ID_NULL) {
- return 0;
- }
- return resources.getDimensionPixelSize(resourceId);
- }
-
- void close() {
- final Runnable after = () -> {
- mHandleMenuViewContainer.releaseView();
- mHandleMenuViewContainer = null;
- };
- if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
- || mTaskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW) {
- mHandleMenuAnimator.animateCollapseIntoHandleClose(after);
- } else {
- mHandleMenuAnimator.animateClose(after);
- }
- }
-
- static final class Builder {
- private final DesktopModeWindowDecoration mParent;
- private CharSequence mName;
- private Bitmap mAppIcon;
- private View.OnClickListener mOnClickListener;
- private View.OnTouchListener mOnTouchListener;
- private int mLayoutId;
- private boolean mShowWindowingPill;
- private int mCaptionHeight;
- private DisplayController mDisplayController;
- private SplitScreenController mSplitScreenController;
-
- Builder(@NonNull DesktopModeWindowDecoration parent) {
- mParent = parent;
- }
-
- Builder setAppName(@Nullable CharSequence name) {
- mName = name;
- return this;
- }
-
- Builder setAppIcon(@Nullable Bitmap appIcon) {
- mAppIcon = appIcon;
- return this;
- }
-
- Builder setOnClickListener(@Nullable View.OnClickListener onClickListener) {
- mOnClickListener = onClickListener;
- return this;
- }
-
- Builder setOnTouchListener(@Nullable View.OnTouchListener onTouchListener) {
- mOnTouchListener = onTouchListener;
- return this;
- }
-
- Builder setLayoutId(int layoutId) {
- mLayoutId = layoutId;
- return this;
- }
-
- Builder setWindowingButtonsVisible(boolean windowingButtonsVisible) {
- mShowWindowingPill = windowingButtonsVisible;
- return this;
- }
-
- Builder setCaptionHeight(int captionHeight) {
- mCaptionHeight = captionHeight;
- return this;
- }
-
- Builder setDisplayController(DisplayController displayController) {
- mDisplayController = displayController;
- return this;
- }
-
- Builder setSplitScreenController(SplitScreenController splitScreenController) {
- mSplitScreenController = splitScreenController;
- return this;
- }
-
- HandleMenu build() {
- return new HandleMenu(mParent, mLayoutId, mOnClickListener,
- mOnTouchListener, mAppIcon, mName, mDisplayController, mSplitScreenController,
- mShowWindowingPill, mCaptionHeight);
- }
- }
-}
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
new file mode 100644
index 000000000000..bce233fb0b52
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
@@ -0,0 +1,484 @@
+/*
+ * 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.
+ */
+package com.android.wm.shell.windowdecor
+
+import android.annotation.DimenRes
+import android.app.ActivityManager
+import android.app.WindowConfiguration
+import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
+import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
+import android.app.WindowConfiguration.WINDOWING_MODE_PINNED
+import android.content.Context
+import android.content.res.ColorStateList
+import android.content.res.Configuration
+import android.content.res.Resources
+import android.graphics.Bitmap
+import android.graphics.Color
+import android.graphics.Point
+import android.graphics.PointF
+import android.graphics.Rect
+import android.view.MotionEvent
+import android.view.SurfaceControl
+import android.view.View
+import android.widget.Button
+import android.widget.ImageButton
+import android.widget.ImageView
+import android.widget.TextView
+import android.window.SurfaceSyncGroup
+import androidx.annotation.VisibleForTesting
+import com.android.window.flags.Flags
+import com.android.wm.shell.R
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.split.SplitScreenConstants
+import com.android.wm.shell.splitscreen.SplitScreenController
+import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
+import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer
+import com.android.wm.shell.windowdecor.extension.isFullscreen
+
+/**
+ * Handle menu opened when the appropriate button is clicked on.
+ *
+ * Displays up to 3 pills that show the following:
+ * App Info: App name, app icon, and collapse button to close the menu.
+ * Windowing Options(Proto 2 only): Buttons to change windowing modes.
+ * Additional Options: Miscellaneous functions including screenshot and closing task.
+ */
+class HandleMenu(
+ private val parentDecor: DesktopModeWindowDecoration,
+ private val layoutResId: Int,
+ private val onClickListener: View.OnClickListener?,
+ private val onTouchListener: View.OnTouchListener?,
+ private val appIconBitmap: Bitmap?,
+ private val appName: CharSequence?,
+ private val displayController: DisplayController,
+ private val splitScreenController: SplitScreenController,
+ private val shouldShowWindowingPill: Boolean,
+ private val shouldShowBrowserPill: Boolean,
+ private val captionHeight: Int
+) {
+ private val context: Context = parentDecor.mDecorWindowContext
+ private val taskInfo: ActivityManager.RunningTaskInfo = parentDecor.mTaskInfo
+
+ private val isViewAboveStatusBar: Boolean
+ get() = (Flags.enableAdditionalWindowsAboveStatusBar() && !taskInfo.isFreeform)
+
+ private val pillElevation: Int = loadDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_pill_elevation)
+ private val pillTopMargin: Int = loadDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_pill_spacing_margin)
+ private val menuWidth = loadDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_width) + pillElevation
+ private val menuHeight = getHandleMenuHeight()
+ private val marginMenuTop = loadDimensionPixelSize(R.dimen.desktop_mode_handle_menu_margin_top)
+ private val marginMenuStart = loadDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_margin_start)
+
+ private var handleMenuAnimator: HandleMenuAnimator? = null
+
+ @VisibleForTesting
+ var handleMenuViewContainer: AdditionalViewContainer? = null
+
+ // Position of the handle menu used for laying out the handle view.
+ @VisibleForTesting
+ val handleMenuPosition: PointF = PointF()
+
+ // With the introduction of {@link AdditionalSystemViewContainer}, {@link mHandleMenuPosition}
+ // may be in a different coordinate space than the input coordinates. Therefore, we still care
+ // about the menu's coordinates relative to the display as a whole, so we need to maintain
+ // those as well.
+ private val globalMenuPosition: Point = Point()
+
+ /**
+ * An a array of windowing icon color based on current UI theme. First element of the
+ * array is for inactive icons and the second is for active icons.
+ */
+ private val windowingIconColor: Array<ColorStateList>
+ get() {
+ val mode = (context.resources.configuration.uiMode
+ and Configuration.UI_MODE_NIGHT_MASK)
+ val isNightMode = (mode == Configuration.UI_MODE_NIGHT_YES)
+ val typedArray = context.obtainStyledAttributes(
+ intArrayOf(
+ com.android.internal.R.attr.materialColorOnSurface,
+ com.android.internal.R.attr.materialColorPrimary
+ )
+ )
+ val inActiveColor =
+ typedArray.getColor(0, if (isNightMode) Color.WHITE else Color.BLACK)
+ val activeColor = typedArray.getColor(1, if (isNightMode) Color.WHITE else Color.BLACK)
+ typedArray.recycle()
+ return arrayOf(
+ ColorStateList.valueOf(inActiveColor),
+ ColorStateList.valueOf(activeColor)
+ )
+ }
+
+ init {
+ updateHandleMenuPillPositions()
+ }
+
+ fun show() {
+ val ssg = SurfaceSyncGroup(TAG)
+ val t = SurfaceControl.Transaction()
+
+ createHandleMenuViewContainer(t, ssg)
+ ssg.addTransaction(t)
+ ssg.markSyncReady()
+ setupHandleMenu()
+ animateHandleMenu()
+ }
+
+ private fun createHandleMenuViewContainer(
+ t: SurfaceControl.Transaction,
+ ssg: SurfaceSyncGroup
+ ) {
+ val x = handleMenuPosition.x.toInt()
+ val y = handleMenuPosition.y.toInt()
+ handleMenuViewContainer =
+ if (!taskInfo.isFreeform && Flags.enableAdditionalWindowsAboveStatusBar()) {
+ AdditionalSystemViewContainer(
+ context = context,
+ layoutId = R.layout.desktop_mode_window_decor_handle_menu,
+ taskId = taskInfo.taskId,
+ x = x,
+ y = y,
+ width = menuWidth,
+ height = menuHeight
+ )
+ } else {
+ parentDecor.addWindow(
+ R.layout.desktop_mode_window_decor_handle_menu, "Handle Menu",
+ t, ssg, x, y, menuWidth, menuHeight
+ )
+ }
+ handleMenuViewContainer?.view?.let { view ->
+ handleMenuAnimator =
+ HandleMenuAnimator(view, menuWidth, captionHeight.toFloat())
+ }
+ }
+
+ /**
+ * Animates the appearance of the handle menu and its three pills.
+ */
+ private fun animateHandleMenu() {
+ when (taskInfo.windowingMode) {
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
+ WINDOWING_MODE_MULTI_WINDOW -> {
+ handleMenuAnimator?.animateCaptionHandleExpandToOpen()
+ }
+ else -> {
+ handleMenuAnimator?.animateOpen()
+ }
+ }
+ }
+
+ /**
+ * Set up all three pills of the handle menu: app info pill, windowing pill, & more actions
+ * pill.
+ */
+ private fun setupHandleMenu() {
+ val handleMenu = handleMenuViewContainer?.view ?: return
+ handleMenu.setOnTouchListener(onTouchListener)
+ setupAppInfoPill(handleMenu)
+ if (shouldShowWindowingPill) {
+ setupWindowingPill(handleMenu)
+ }
+ setupMoreActionsPill(handleMenu)
+ setupOpenInBrowserPill(handleMenu)
+ }
+
+ /**
+ * Set up interactive elements of handle menu's app info pill.
+ */
+ private fun setupAppInfoPill(handleMenu: View) {
+ val collapseBtn = handleMenu.findViewById<HandleMenuImageButton>(R.id.collapse_menu_button)
+ val appIcon = handleMenu.findViewById<ImageView>(R.id.application_icon)
+ val appName = handleMenu.findViewById<TextView>(R.id.application_name)
+ collapseBtn.setOnClickListener(onClickListener)
+ collapseBtn.taskInfo = taskInfo
+ appIcon.setImageBitmap(appIconBitmap)
+ appName.text = this.appName
+ }
+
+ /**
+ * Set up interactive elements and color of handle menu's windowing pill.
+ */
+ private fun setupWindowingPill(handleMenu: View) {
+ val fullscreenBtn = handleMenu.findViewById<ImageButton>(R.id.fullscreen_button)
+ val splitscreenBtn = handleMenu.findViewById<ImageButton>(R.id.split_screen_button)
+ val floatingBtn = handleMenu.findViewById<ImageButton>(R.id.floating_button)
+ // TODO: Remove once implemented.
+ floatingBtn.visibility = View.GONE
+
+ val desktopBtn = handleMenu.findViewById<ImageButton>(R.id.desktop_button)
+ fullscreenBtn.setOnClickListener(onClickListener)
+ splitscreenBtn.setOnClickListener(onClickListener)
+ floatingBtn.setOnClickListener(onClickListener)
+ desktopBtn.setOnClickListener(onClickListener)
+ // The button corresponding to the windowing mode that the task is currently in uses a
+ // different color than the others.
+ val iconColors = windowingIconColor
+ val inActiveColorStateList = iconColors[0]
+ val activeColorStateList = iconColors[1]
+ fullscreenBtn.imageTintList = if (taskInfo.isFullscreen) {
+ activeColorStateList
+ } else {
+ inActiveColorStateList
+ }
+ splitscreenBtn.imageTintList = if (taskInfo.windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
+ activeColorStateList
+ } else {
+ inActiveColorStateList
+ }
+ floatingBtn.imageTintList = if (taskInfo.windowingMode == WINDOWING_MODE_PINNED) {
+ activeColorStateList
+ } else {
+ inActiveColorStateList
+ }
+ desktopBtn.imageTintList = if (taskInfo.isFreeform) {
+ activeColorStateList
+ } else {
+ inActiveColorStateList
+ }
+ }
+
+ /**
+ * Set up interactive elements & height of handle menu's more actions pill
+ */
+ private fun setupMoreActionsPill(handleMenu: View) {
+ if (!SHOULD_SHOW_MORE_ACTIONS_PILL) {
+ handleMenu.findViewById<View>(R.id.more_actions_pill).visibility = View.GONE
+ }
+ }
+
+ private fun setupOpenInBrowserPill(handleMenu: View) {
+ if (!shouldShowBrowserPill) {
+ handleMenu.findViewById<View>(R.id.open_in_browser_pill).visibility = View.GONE
+ return
+ }
+ val browserButton = handleMenu.findViewById<Button>(R.id.open_in_browser_button)
+ browserButton.setOnClickListener(onClickListener)
+ }
+
+ /**
+ * Updates handle menu's position variables to reflect its next position.
+ */
+ private fun updateHandleMenuPillPositions() {
+ val menuX: Int
+ val menuY: Int
+ val taskBounds = taskInfo.getConfiguration().windowConfiguration.bounds
+ updateGlobalMenuPosition(taskBounds)
+ if (layoutResId == R.layout.desktop_mode_app_header) {
+ // Align the handle menu to the left side of the caption.
+ menuX = marginMenuStart
+ menuY = marginMenuTop
+ } else {
+ if (Flags.enableAdditionalWindowsAboveStatusBar()) {
+ // In a focused decor, we use global coordinates for handle menu. Therefore we
+ // need to account for other factors like split stage and menu/handle width to
+ // center the menu.
+ menuX = globalMenuPosition.x
+ menuY = globalMenuPosition.y
+ } else {
+ menuX = (taskBounds.width() / 2) - (menuWidth / 2)
+ menuY = marginMenuTop
+ }
+ }
+ // Handle Menu position setup.
+ handleMenuPosition.set(menuX.toFloat(), menuY.toFloat())
+ }
+
+ private fun updateGlobalMenuPosition(taskBounds: Rect) {
+ when (taskInfo.windowingMode) {
+ WINDOWING_MODE_FREEFORM -> {
+ globalMenuPosition.set(
+ /* x = */ taskBounds.left + marginMenuStart,
+ /* y = */ taskBounds.top + marginMenuTop
+ )
+ }
+ WINDOWING_MODE_FULLSCREEN -> {
+ globalMenuPosition.set(
+ /* x = */ taskBounds.width() / 2 - (menuWidth / 2),
+ /* y = */ marginMenuTop
+ )
+ }
+ WINDOWING_MODE_MULTI_WINDOW -> {
+ val splitPosition = splitScreenController.getSplitPosition(taskInfo.taskId)
+ val leftOrTopStageBounds = Rect()
+ val rightOrBottomStageBounds = Rect()
+ splitScreenController.getStageBounds(leftOrTopStageBounds, rightOrBottomStageBounds)
+ // TODO(b/343561161): This needs to be calculated differently if the task is in
+ // top/bottom split.
+ when (splitPosition) {
+ SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT -> {
+ globalMenuPosition.set(
+ /* x = */ leftOrTopStageBounds.width()
+ + (rightOrBottomStageBounds.width() / 2)
+ - (menuWidth / 2),
+ /* y = */ marginMenuTop
+ )
+ }
+ SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT -> {
+ globalMenuPosition.set(
+ /* x = */ (leftOrTopStageBounds.width() / 2)
+ - (menuWidth / 2),
+ /* y = */ marginMenuTop
+ )
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Update pill layout, in case task changes have caused positioning to change.
+ */
+ fun relayout(t: SurfaceControl.Transaction) {
+ handleMenuViewContainer?.let { container ->
+ updateHandleMenuPillPositions()
+ container.setPosition(t, handleMenuPosition.x, handleMenuPosition.y)
+ }
+ }
+
+ /**
+ * Check a passed MotionEvent if a click or hover has occurred on any button on this caption
+ * Note this should only be called when a regular onClick/onHover is not possible
+ * (i.e. the button was clicked through status bar layer)
+ *
+ * @param ev the MotionEvent to compare against.
+ */
+ fun checkMotionEvent(ev: MotionEvent) {
+ // If the menu view is above status bar, we can let the views handle input directly.
+ if (isViewAboveStatusBar) return
+ val handleMenu = handleMenuViewContainer?.view ?: return
+ val collapse = handleMenu.findViewById<HandleMenuImageButton>(R.id.collapse_menu_button)
+ val inputPoint = translateInputToLocalSpace(ev)
+ val inputInCollapseButton = pointInView(collapse, inputPoint.x, inputPoint.y)
+ val action = ev.actionMasked
+ collapse.isHovered = inputInCollapseButton && action != MotionEvent.ACTION_UP
+ collapse.isPressed = inputInCollapseButton && action == MotionEvent.ACTION_DOWN
+ if (action == MotionEvent.ACTION_UP && inputInCollapseButton) {
+ collapse.performClick()
+ }
+ }
+
+ // Translate the input point from display coordinates to the same space as the handle menu.
+ private fun translateInputToLocalSpace(ev: MotionEvent): PointF {
+ return PointF(
+ ev.x - handleMenuPosition.x,
+ ev.y - handleMenuPosition.y
+ )
+ }
+
+ /**
+ * A valid menu input is one of the following:
+ * An input that happens in the menu views.
+ * Any input before the views have been laid out.
+ *
+ * @param inputPoint the input to compare against.
+ */
+ fun isValidMenuInput(inputPoint: PointF): Boolean {
+ if (!viewsLaidOut()) return true
+ if (!isViewAboveStatusBar) {
+ return pointInView(
+ handleMenuViewContainer?.view,
+ inputPoint.x - handleMenuPosition.x,
+ inputPoint.y - handleMenuPosition.y
+ )
+ } else {
+ // Handle menu exists in a different coordinate space when added to WindowManager.
+ // Therefore we must compare the provided input coordinates to global menu coordinates.
+ // This includes factoring for split stage as input coordinates are relative to split
+ // stage position, not relative to the display as a whole.
+ val inputRelativeToMenu = PointF(
+ inputPoint.x - globalMenuPosition.x,
+ inputPoint.y - globalMenuPosition.y
+ )
+ if (splitScreenController.getSplitPosition(taskInfo.taskId)
+ == SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT) {
+ // TODO(b/343561161): This also needs to be calculated differently if
+ // the task is in top/bottom split.
+ val leftStageBounds = Rect()
+ splitScreenController.getStageBounds(leftStageBounds, Rect())
+ inputRelativeToMenu.x += leftStageBounds.width().toFloat()
+ }
+ return pointInView(
+ handleMenuViewContainer?.view,
+ inputRelativeToMenu.x,
+ inputRelativeToMenu.y
+ )
+ }
+ }
+
+ private fun pointInView(v: View?, x: Float, y: Float): Boolean {
+ return v != null && v.left <= x && v.right >= x && v.top <= y && v.bottom >= y
+ }
+
+ /**
+ * Check if the views for handle menu can be seen.
+ */
+ private fun viewsLaidOut(): Boolean = handleMenuViewContainer?.view?.isLaidOut ?: false
+
+ /**
+ * Determines handle menu height based the max size and the visibility of pills.
+ */
+ private fun getHandleMenuHeight(): Int {
+ var menuHeight = loadDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_height) + pillElevation
+ if (!shouldShowWindowingPill) {
+ menuHeight -= loadDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_windowing_pill_height)
+ menuHeight -= pillTopMargin
+ }
+ if (!SHOULD_SHOW_MORE_ACTIONS_PILL) {
+ menuHeight -= loadDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_more_actions_pill_height)
+ menuHeight -= pillTopMargin
+ }
+ if (!shouldShowBrowserPill) {
+ menuHeight -= loadDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_open_in_browser_pill_height)
+ menuHeight -= pillTopMargin
+ }
+ return menuHeight
+ }
+
+ private fun loadDimensionPixelSize(@DimenRes resourceId: Int): Int {
+ if (resourceId == Resources.ID_NULL) {
+ return 0
+ }
+ return context.resources.getDimensionPixelSize(resourceId)
+ }
+
+ fun close() {
+ val after = {
+ handleMenuViewContainer?.releaseView()
+ handleMenuViewContainer = null
+ }
+ if (taskInfo.windowingMode == WINDOWING_MODE_FULLSCREEN ||
+ taskInfo.windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
+ handleMenuAnimator?.animateCollapseIntoHandleClose(after)
+ } else {
+ handleMenuAnimator?.animateClose(after)
+ }
+ }
+
+ companion object {
+ private const val TAG = "HandleMenu"
+ private const val SHOULD_SHOW_MORE_ACTIONS_PILL = false
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuAnimator.kt
index 8c5d4a2c2ffb..e3d22342cc9b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuAnimator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuAnimator.kt
@@ -26,6 +26,7 @@ import android.view.View.SCALE_Y
import android.view.View.TRANSLATION_Y
import android.view.View.TRANSLATION_Z
import android.view.ViewGroup
+import android.widget.Button
import androidx.core.animation.doOnEnd
import androidx.core.view.children
import com.android.wm.shell.R
@@ -72,6 +73,7 @@ class HandleMenuAnimator(
private val appInfoPill: ViewGroup = handleMenu.requireViewById(R.id.app_info_pill)
private val windowingPill: ViewGroup = handleMenu.requireViewById(R.id.windowing_pill)
private val moreActionsPill: ViewGroup = handleMenu.requireViewById(R.id.more_actions_pill)
+ private val openInBrowserPill: ViewGroup = handleMenu.requireViewById(R.id.open_in_browser_pill)
/** Animates the opening of the handle menu. */
fun animateOpen() {
@@ -80,6 +82,7 @@ class HandleMenuAnimator(
animateAppInfoPillOpen()
animateWindowingPillOpen()
animateMoreActionsPillOpen()
+ animateOpenInBrowserPill()
runAnimations()
}
@@ -94,6 +97,7 @@ class HandleMenuAnimator(
animateAppInfoPillOpen()
animateWindowingPillOpen()
animateMoreActionsPillOpen()
+ animateOpenInBrowserPill()
runAnimations()
}
@@ -104,11 +108,12 @@ class HandleMenuAnimator(
*
* @param after runs after the animation finishes.
*/
- fun animateCollapseIntoHandleClose(after: Runnable) {
+ fun animateCollapseIntoHandleClose(after: () -> Unit) {
appInfoCollapseToHandle()
animateAppInfoPillFadeOut()
windowingPillClose()
moreActionsPillClose()
+ openInBrowserPillClose()
runAnimations(after)
}
@@ -120,11 +125,12 @@ class HandleMenuAnimator(
* @param after runs after animation finishes.
*
*/
- fun animateClose(after: Runnable) {
+ fun animateClose(after: () -> Unit) {
appInfoPillCollapse()
animateAppInfoPillFadeOut()
windowingPillClose()
moreActionsPillClose()
+ openInBrowserPillClose()
runAnimations(after)
}
@@ -137,6 +143,7 @@ class HandleMenuAnimator(
appInfoPill.children.forEach { it.alpha = 0f }
windowingPill.alpha = 0f
moreActionsPill.alpha = 0f
+ openInBrowserPill.alpha = 0f
// Setup pivots.
handleMenu.pivotX = menuWidth / 2f
@@ -147,6 +154,9 @@ class HandleMenuAnimator(
moreActionsPill.pivotX = menuWidth / 2f
moreActionsPill.pivotY = appInfoPill.measuredHeight.toFloat()
+
+ openInBrowserPill.pivotX = menuWidth / 2f
+ openInBrowserPill.pivotY = appInfoPill.measuredHeight.toFloat()
}
private fun animateAppInfoPillOpen() {
@@ -268,12 +278,50 @@ class HandleMenuAnimator(
// More Actions Content Opacity Animation
moreActionsPill.children.forEach {
animators +=
- ObjectAnimator.ofFloat(it, ALPHA, 1f).apply {
+ ObjectAnimator.ofFloat(it, ALPHA, 1f).apply {
+ startDelay = BODY_ALPHA_OPEN_DELAY
+ duration = BODY_CONTENT_ALPHA_OPEN_DURATION
+ interpolator = Interpolators.FAST_OUT_SLOW_IN
+ }
+ }
+ }
+
+ private fun animateOpenInBrowserPill() {
+ // Open in Browser X & Y Scaling Animation
+ animators +=
+ ObjectAnimator.ofFloat(openInBrowserPill, SCALE_X, HALF_INITIAL_SCALE, 1f).apply {
+ startDelay = BODY_SCALE_OPEN_DELAY
+ duration = BODY_SCALE_OPEN_DURATION
+ }
+
+ animators +=
+ ObjectAnimator.ofFloat(openInBrowserPill, SCALE_Y, HALF_INITIAL_SCALE, 1f).apply {
+ startDelay = BODY_SCALE_OPEN_DELAY
+ duration = BODY_SCALE_OPEN_DURATION
+ }
+
+ // Open in Browser Opacity Animation
+ animators +=
+ ObjectAnimator.ofFloat(openInBrowserPill, ALPHA, 1f).apply {
+ startDelay = BODY_ALPHA_OPEN_DELAY
+ duration = BODY_ALPHA_OPEN_DURATION
+ }
+
+ // Open in Browser Elevation Animation
+ animators +=
+ ObjectAnimator.ofFloat(openInBrowserPill, TRANSLATION_Z, 1f).apply {
+ startDelay = ELEVATION_OPEN_DELAY
+ duration = BODY_ELEVATION_OPEN_DURATION
+ }
+
+ // Open in Browser Button Opacity Animation
+ val button = openInBrowserPill.requireViewById<Button>(R.id.open_in_browser_button)
+ animators +=
+ ObjectAnimator.ofFloat(button, ALPHA, 1f).apply {
startDelay = BODY_ALPHA_OPEN_DELAY
duration = BODY_CONTENT_ALPHA_OPEN_DURATION
interpolator = Interpolators.FAST_OUT_SLOW_IN
}
- }
}
private fun appInfoPillCollapse() {
@@ -379,14 +427,45 @@ class HandleMenuAnimator(
}
}
+ private fun openInBrowserPillClose() {
+ // Open in Browser X & Y Scaling Animation
+ animators +=
+ ObjectAnimator.ofFloat(openInBrowserPill, SCALE_X, HALF_INITIAL_SCALE).apply {
+ duration = BODY_CLOSE_DURATION
+ }
+
+ animators +=
+ ObjectAnimator.ofFloat(openInBrowserPill, SCALE_Y, HALF_INITIAL_SCALE).apply {
+ duration = BODY_CLOSE_DURATION
+ }
+
+ // Open in Browser Opacity Animation
+ animators +=
+ ObjectAnimator.ofFloat(openInBrowserPill, ALPHA, 0f).apply {
+ duration = BODY_CLOSE_DURATION
+ }
+
+ animators +=
+ ObjectAnimator.ofFloat(openInBrowserPill, ALPHA, 0f).apply {
+ duration = BODY_CLOSE_DURATION
+ }
+
+ // Upward Open in Browser y-translation Animation
+ val yStart: Float = -captionHeight / 2
+ animators +=
+ ObjectAnimator.ofFloat(openInBrowserPill, TRANSLATION_Y, yStart).apply {
+ duration = BODY_CLOSE_DURATION
+ }
+ }
+
/**
* Runs the list of hide animators concurrently.
*
* @param after runs after animation finishes.
*/
- private fun runAnimations(after: Runnable? = null) {
+ private fun runAnimations(after: (() -> Unit)? = null) {
runningAnimation?.apply {
- // Remove all listeners, so that after runnable isn't triggered upon cancel.
+ // Remove all listeners, so that the after function isn't triggered upon cancel.
removeAllListeners()
// If an animation runs while running animation is triggered, gracefully cancel.
cancel()
@@ -396,7 +475,7 @@ class HandleMenuAnimator(
playTogether(animators)
animators.clear()
doOnEnd {
- after?.run()
+ after?.invoke()
runningAnimation = null
}
start()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
index 956d04c548f7..b5b476d90d0e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
@@ -18,6 +18,7 @@ package com.android.wm.shell.windowdecor;
import static android.view.WindowManager.TRANSIT_CHANGE;
+import static com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_DRAG_WINDOW;
import static com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_RESIZE_WINDOW;
import android.graphics.Point;
@@ -33,9 +34,9 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.InteractionJankMonitorUtils;
import com.android.wm.shell.transition.Transitions;
import java.util.function.Supplier;
@@ -59,6 +60,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
private final PointF mRepositionStartPoint = new PointF();
private final Rect mRepositionTaskBounds = new Rect();
private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
+ private final InteractionJankMonitor mInteractionJankMonitor;
private int mCtrlType;
private boolean mIsResizingOrAnimatingResize;
@Surface.Rotation private int mRotation;
@@ -67,22 +69,24 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
DesktopModeWindowDecoration windowDecoration,
DisplayController displayController,
DragPositioningCallbackUtility.DragStartListener dragStartListener,
- Transitions transitions) {
+ Transitions transitions, InteractionJankMonitor interactionJankMonitor) {
this(taskOrganizer, windowDecoration, displayController, dragStartListener,
- SurfaceControl.Transaction::new, transitions);
+ SurfaceControl.Transaction::new, transitions, interactionJankMonitor);
}
public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer,
DesktopModeWindowDecoration windowDecoration,
DisplayController displayController,
DragPositioningCallbackUtility.DragStartListener dragStartListener,
- Supplier<SurfaceControl.Transaction> supplier, Transitions transitions) {
+ Supplier<SurfaceControl.Transaction> supplier, Transitions transitions,
+ InteractionJankMonitor interactionJankMonitor) {
mDesktopWindowDecoration = windowDecoration;
mTaskOrganizer = taskOrganizer;
mDisplayController = displayController;
mDragStartListener = dragStartListener;
mTransactionSupplier = supplier;
mTransitions = transitions;
+ mInteractionJankMonitor = interactionJankMonitor;
}
@Override
@@ -93,14 +97,16 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
mRepositionStartPoint.set(x, y);
if (isResizing()) {
// Capture CUJ for re-sizing window in DW mode.
- InteractionJankMonitorUtils.beginTracing(CUJ_DESKTOP_MODE_RESIZE_WINDOW,
- mDesktopWindowDecoration.mContext, mDesktopWindowDecoration.mTaskSurface,
- /* tag= */ null);
+ mInteractionJankMonitor.begin(mDesktopWindowDecoration.mTaskSurface,
+ mDesktopWindowDecoration.mContext, CUJ_DESKTOP_MODE_RESIZE_WINDOW);
if (!mDesktopWindowDecoration.mTaskInfo.isFocused) {
WindowContainerTransaction wct = new WindowContainerTransaction();
wct.reorder(mDesktopWindowDecoration.mTaskInfo.token, true);
mTaskOrganizer.applyTransaction(wct);
}
+ } else {
+ mInteractionJankMonitor.begin(mDesktopWindowDecoration.mTaskSurface,
+ mDesktopWindowDecoration.mContext, CUJ_DESKTOP_MODE_DRAG_WINDOW);
}
mDragStartListener.onDragStart(mDesktopWindowDecoration.mTaskInfo.taskId);
mRepositionTaskBounds.set(mTaskBoundsAtDragStart);
@@ -153,13 +159,18 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
// won't be called.
resetVeilIfVisible();
}
- InteractionJankMonitorUtils.endTracing(CUJ_DESKTOP_MODE_RESIZE_WINDOW);
+ mInteractionJankMonitor.end(CUJ_DESKTOP_MODE_RESIZE_WINDOW);
} else {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds,
mTaskBoundsAtDragStart, mRepositionStartPoint, x, y);
- wct.setBounds(mDesktopWindowDecoration.mTaskInfo.token, mRepositionTaskBounds);
- mTransitions.startTransition(TRANSIT_CHANGE, wct, this);
+ if (!mTaskBoundsAtDragStart.equals(mRepositionTaskBounds)) {
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ wct.setBounds(mDesktopWindowDecoration.mTaskInfo.token, mRepositionTaskBounds);
+ mTransitions.startTransition(TRANSIT_CHANGE, wct, this);
+ } else {
+ // Drag-move ended where it originally started, no need to update WM.
+ mInteractionJankMonitor.end(CUJ_DESKTOP_MODE_DRAG_WINDOW);
+ }
}
mCtrlType = CTRL_TYPE_UNDEFINED;
@@ -200,6 +211,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
mCtrlType = CTRL_TYPE_UNDEFINED;
finishCallback.onTransitionFinished(null);
mIsResizingOrAnimatingResize = false;
+ mInteractionJankMonitor.end(CUJ_DESKTOP_MODE_DRAG_WINDOW);
return true;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 216990c35247..d212f2131ed4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -19,6 +19,7 @@ package com.android.wm.shell.windowdecor;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.res.Configuration.DENSITY_DPI_UNDEFINED;
+import static android.view.InsetsSource.FLAG_FORCE_CONSUMING;
import static android.view.WindowInsets.Type.captionBar;
import static android.view.WindowInsets.Type.mandatorySystemGestures;
import static android.view.WindowInsets.Type.statusBars;
@@ -53,9 +54,10 @@ import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.windowdecor.WindowDecoration.RelayoutParams.OccludingCaptionElement;
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer;
@@ -105,7 +107,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
* System-wide context. Only used to create context with overridden configurations.
*/
final Context mContext;
- final DisplayController mDisplayController;
+ final @NonNull DisplayController mDisplayController;
final ShellTaskOrganizer mTaskOrganizer;
final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier;
final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier;
@@ -158,7 +160,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
WindowDecoration(
Context context,
- DisplayController displayController,
+ @NonNull DisplayController displayController,
ShellTaskOrganizer taskOrganizer,
RunningTaskInfo taskInfo,
@NonNull SurfaceControl taskSurface,
@@ -759,9 +761,12 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
}
void addOrUpdate(WindowContainerTransaction wct) {
- wct.addInsetsSource(mToken, mOwner, INDEX, captionBar(), mFrame, mBoundingRects);
+ final @InsetsSource.Flags int captionSourceFlags =
+ Flags.enableCaptionCompatInsetForceConsumption() ? FLAG_FORCE_CONSUMING : 0;
+ wct.addInsetsSource(mToken, mOwner, INDEX, captionBar(), mFrame, mBoundingRects,
+ captionSourceFlags);
wct.addInsetsSource(mToken, mOwner, INDEX, mandatorySystemGestures(), mFrame,
- mBoundingRects);
+ mBoundingRects, 0 /* flags */);
}
void remove(WindowContainerTransaction wct) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
index 6c2c8fd46bc9..4897f76a20cf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
@@ -18,6 +18,7 @@ package com.android.wm.shell.windowdecor.additionalviewcontainer
import android.content.Context
import android.graphics.PixelFormat
+import android.view.Gravity
import android.view.LayoutInflater
import android.view.SurfaceControl
import android.view.View
@@ -45,9 +46,11 @@ class AdditionalSystemViewContainer(
WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSPARENT
- )
- lp.title = "Additional view container of Task=$taskId"
- lp.setTrustedOverlay()
+ ).apply {
+ title = "Additional view container of Task=$taskId"
+ gravity = Gravity.LEFT or Gravity.TOP
+ setTrustedOverlay()
+ }
val wm: WindowManager? = context.getSystemService(WindowManager::class.java)
wm?.addView(view, lp)
}
diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS
index b8a19ad35307..a77fd51d5fcb 100644
--- a/libs/WindowManager/Shell/tests/OWNERS
+++ b/libs/WindowManager/Shell/tests/OWNERS
@@ -9,7 +9,7 @@ hwwang@google.com
chenghsiuchang@google.com
atsjenk@google.com
jorgegil@google.com
-nmusgrave@google.com
+vaniadesmonda@google.com
pbdr@google.com
tkachenkoi@google.com
mpodolian@google.com
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index a0a61fe2cf72..d0e8215e662e 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -117,12 +117,10 @@ class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(fli
/**
* Checks that all parts of the screen are covered at the start and end of the transition
- *
- * TODO b/197726599 Prevents all states from being checked
*/
@Presubmit
@Test
- fun entireScreenCoveredAtStartAndEnd() = flicker.entireScreenCovered(allStates = false)
+ fun entireScreenCoveredAtStartAndEnd() = flicker.entireScreenCovered()
/** Checks [pipApp] window remains visible and on top throughout the transition */
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt
index d485b82f5ddb..430f80b9a927 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt
@@ -20,18 +20,23 @@ import android.tools.flicker.AssertionInvocationGroup
import android.tools.flicker.assertors.assertions.AppLayerIsInvisibleAtEnd
import android.tools.flicker.assertors.assertions.AppLayerIsVisibleAlways
import android.tools.flicker.assertors.assertions.AppLayerIsVisibleAtStart
+import android.tools.flicker.assertors.assertions.AppWindowBecomesVisible
import android.tools.flicker.assertors.assertions.AppWindowHasDesktopModeInitialBoundsAtTheEnd
-import android.tools.flicker.assertors.assertions.AppWindowIsVisibleAlways
+import android.tools.flicker.assertors.assertions.AppWindowHasSizeOfAtLeast
+import android.tools.flicker.assertors.assertions.AppWindowIsInvisibleAtEnd
import android.tools.flicker.assertors.assertions.AppWindowOnTopAtEnd
import android.tools.flicker.assertors.assertions.AppWindowOnTopAtStart
-import android.tools.flicker.assertors.assertions.AppWindowRemainInsideDisplayBounds
-import android.tools.flicker.assertors.assertions.LauncherWindowMovesToTop
+import android.tools.flicker.assertors.assertions.LauncherWindowReplacesAppAsTopWindow
import android.tools.flicker.config.AssertionTemplates
import android.tools.flicker.config.FlickerConfigEntry
import android.tools.flicker.config.ScenarioId
import android.tools.flicker.config.desktopmode.Components
+import android.tools.flicker.config.desktopmode.Components.DESKTOP_WALLPAPER
import android.tools.flicker.extractors.ITransitionMatcher
import android.tools.flicker.extractors.ShellTransitionScenarioExtractor
+import android.tools.flicker.extractors.TaggedCujTransitionMatcher
+import android.tools.flicker.extractors.TaggedScenarioExtractorBuilder
+import android.tools.traces.events.CujType
import android.tools.traces.wm.Transition
import android.tools.traces.wm.TransitionType
@@ -48,6 +53,7 @@ class DesktopModeFlickerScenarios {
transitions: Collection<Transition>
): Collection<Transition> {
return transitions.filter {
+ // TODO(351168217) Use jank CUJ to extract a longer trace
it.type == TransitionType.DESKTOP_MODE_END_DRAG_TO_DESKTOP
}
}
@@ -60,11 +66,14 @@ class DesktopModeFlickerScenarios {
AppWindowOnTopAtEnd(Components.DESKTOP_MODE_APP),
AppWindowHasDesktopModeInitialBoundsAtTheEnd(
Components.DESKTOP_MODE_APP
- )
+ ),
+ AppWindowBecomesVisible(DESKTOP_WALLPAPER)
)
.associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
)
+ // Use this scenario for closing an app in desktop windowing, except the last app. For the
+ // last app use CLOSE_LAST_APP scenario
val CLOSE_APP =
FlickerConfigEntry(
scenarioId = ScenarioId("CLOSE_APP"),
@@ -75,7 +84,13 @@ class DesktopModeFlickerScenarios {
override fun findAll(
transitions: Collection<Transition>
): Collection<Transition> {
- return transitions.filter { it.type == TransitionType.CLOSE }
+ // In case there are multiple windows closing, filter out the
+ // last window closing. It should use the CLOSE_LAST_APP
+ // scenario below.
+ return transitions
+ .filter { it.type == TransitionType.CLOSE }
+ .sortedByDescending { it.id }
+ .drop(1)
}
}
),
@@ -100,19 +115,19 @@ class DesktopModeFlickerScenarios {
transitions: Collection<Transition>
): Collection<Transition> {
val lastTransition =
- transitions.findLast { it.type == TransitionType.CLOSE }
- return if (lastTransition != null) listOf(lastTransition)
- else emptyList()
+ transitions
+ .filter { it.type == TransitionType.CLOSE }
+ .maxByOrNull { it.id }!!
+ return listOf(lastTransition)
}
}
),
assertions =
AssertionTemplates.COMMON_ASSERTIONS +
listOf(
- AppWindowOnTopAtStart(Components.DESKTOP_MODE_APP),
- AppLayerIsVisibleAtStart(Components.DESKTOP_MODE_APP),
- AppLayerIsInvisibleAtEnd(Components.DESKTOP_MODE_APP),
- LauncherWindowMovesToTop()
+ AppWindowIsInvisibleAtEnd(Components.DESKTOP_MODE_APP),
+ LauncherWindowReplacesAppAsTopWindow(Components.DESKTOP_MODE_APP),
+ AppWindowIsInvisibleAtEnd(DESKTOP_WALLPAPER)
)
.associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
)
@@ -121,24 +136,29 @@ class DesktopModeFlickerScenarios {
FlickerConfigEntry(
scenarioId = ScenarioId("CORNER_RESIZE"),
extractor =
- ShellTransitionScenarioExtractor(
- transitionMatcher =
- object : ITransitionMatcher {
- override fun findAll(
- transitions: Collection<Transition>
- ): Collection<Transition> {
- return transitions.filter {
- it.type == TransitionType.CHANGE
- }
- }
- }
- ),
+ TaggedScenarioExtractorBuilder()
+ .setTargetTag(CujType.CUJ_DESKTOP_MODE_RESIZE_WINDOW)
+ .setTransitionMatcher(
+ TaggedCujTransitionMatcher(associatedTransitionRequired = false)
+ )
+ .build(),
+ assertions = AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS
+ )
+
+ val CORNER_RESIZE_TO_MINIMUM_SIZE =
+ FlickerConfigEntry(
+ scenarioId = ScenarioId("CORNER_RESIZE_TO_MINIMUM_SIZE"),
+ extractor =
+ TaggedScenarioExtractorBuilder()
+ .setTargetTag(CujType.CUJ_DESKTOP_MODE_RESIZE_WINDOW)
+ .setTransitionMatcher(
+ TaggedCujTransitionMatcher(associatedTransitionRequired = false)
+ )
+ .build(),
assertions =
- listOf(
- AppWindowIsVisibleAlways(Components.DESKTOP_MODE_APP),
- AppWindowOnTopAtEnd(Components.DESKTOP_MODE_APP),
- AppWindowRemainInsideDisplayBounds(Components.DESKTOP_MODE_APP),
- ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
+ AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS +
+ listOf(AppWindowHasSizeOfAtLeast(Components.DESKTOP_MODE_APP, 770, 700))
+ .associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt
new file mode 100644
index 000000000000..6319cf74ed8f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.wm.shell.flicker.service.desktopmode.flicker
+
+import android.tools.Rotation
+import android.tools.flicker.FlickerConfig
+import android.tools.flicker.annotation.ExpectedScenarios
+import android.tools.flicker.annotation.FlickerConfigProvider
+import android.tools.flicker.config.FlickerConfig
+import android.tools.flicker.config.FlickerServiceConfig
+import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Resize app window using corner resize to the smallest possible height and width in
+ * landscape mode.
+ *
+ * Assert that the minimum window size constraint is maintained.
+ */
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class ResizeAppToMinimumWindowSizeLandscape : ResizeAppWithCornerResize(
+ rotation = Rotation.ROTATION_90,
+ horizontalChange = -1500,
+ verticalChange = 1500) {
+ @ExpectedScenarios(["CORNER_RESIZE_TO_MINIMUM_SIZE"])
+ @Test
+ override fun resizeAppWithCornerResize() = super.resizeAppWithCornerResize()
+
+ companion object {
+ @JvmStatic
+ @FlickerConfigProvider
+ fun flickerConfigProvider(): FlickerConfig =
+ FlickerConfig().use(FlickerServiceConfig.DEFAULT).use(CORNER_RESIZE_TO_MINIMUM_SIZE)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt
new file mode 100644
index 000000000000..431f6e3d3ea2
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.wm.shell.flicker.service.desktopmode.flicker
+
+import android.tools.flicker.FlickerConfig
+import android.tools.flicker.annotation.ExpectedScenarios
+import android.tools.flicker.annotation.FlickerConfigProvider
+import android.tools.flicker.config.FlickerConfig
+import android.tools.flicker.config.FlickerServiceConfig
+import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Resize app window using corner resize to the smallest possible height and width in portrait mode.
+ *
+ * Assert that the minimum window size constraint is maintained.
+ */
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class ResizeAppToMinimumWindowSizePortrait : ResizeAppWithCornerResize(horizontalChange = -1500,
+ verticalChange = 1500) {
+ @ExpectedScenarios(["CORNER_RESIZE_TO_MINIMUM_SIZE"])
+ @Test
+ override fun resizeAppWithCornerResize() = super.resizeAppWithCornerResize()
+
+ companion object {
+ @JvmStatic
+ @FlickerConfigProvider
+ fun flickerConfigProvider(): FlickerConfig =
+ FlickerConfig().use(FlickerServiceConfig.DEFAULT).use(CORNER_RESIZE_TO_MINIMUM_SIZE)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowMultiWindow.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowMultiWindow.kt
new file mode 100644
index 000000000000..bbf0ce5f8165
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowMultiWindow.kt
@@ -0,0 +1,66 @@
+/*
+ * 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.wm.shell.flicker.service.desktopmode.scenarios
+
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.MailAppHelper
+import com.android.server.wm.flicker.helpers.NewTasksAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+
+/** Base scenario test for window drag CUJ with multiple windows. */
+@Ignore("Base Test Class")
+abstract class DragAppWindowMultiWindow : DragAppWindowScenarioTestBase()
+{
+ private val imeAppHelper = ImeAppHelper(instrumentation)
+ private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
+ private val mailApp = DesktopModeAppHelper(MailAppHelper(instrumentation))
+ private val newTasksApp = DesktopModeAppHelper(NewTasksAppHelper(instrumentation))
+ private val imeApp = DesktopModeAppHelper(ImeAppHelper(instrumentation))
+
+ @Before
+ fun setup() {
+ Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+ testApp.enterDesktopWithDrag(wmHelper, device)
+ mailApp.launchViaIntent(wmHelper)
+ newTasksApp.launchViaIntent(wmHelper)
+ imeApp.launchViaIntent(wmHelper)
+ }
+
+ @Test
+ override fun dragAppWindow() {
+ val (startXIme, startYIme) = getWindowDragStartCoordinate(imeAppHelper)
+
+ imeApp.dragWindow(startXIme, startYIme,
+ endX = startXIme + 150, endY = startYIme + 150,
+ wmHelper, device)
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ mailApp.exit(wmHelper)
+ newTasksApp.exit(wmHelper)
+ imeApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowScenarioTestBase.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowScenarioTestBase.kt
new file mode 100644
index 000000000000..a613ca1660ea
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowScenarioTestBase.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.wm.shell.flicker.service.desktopmode.scenarios
+
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.device.apphelpers.StandardAppHelper
+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.flicker.service.common.Utils
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+/** Base test class for window drag CUJ. */
+@Ignore("Base Test Class")
+abstract class DragAppWindowScenarioTestBase {
+
+ val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ val tapl = LauncherInstrumentation()
+ val wmHelper = WindowManagerStateHelper(instrumentation)
+ val device = UiDevice.getInstance(instrumentation)
+
+ @Rule
+ @JvmField
+ val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, Rotation.ROTATION_0)
+
+ @Test abstract fun dragAppWindow()
+
+ /** Return the top-center coordinate of the app header as the start coordinate. */
+ fun getWindowDragStartCoordinate(appHelper: StandardAppHelper): Pair<Int, Int> {
+ val windowRect = wmHelper.getWindowRegion(appHelper).bounds
+ // Set start x-coordinate as center of app header.
+ val startX = windowRect.centerX()
+ val startY = windowRect.top
+ return Pair(startX, startY)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowSingleWindow.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowSingleWindow.kt
new file mode 100644
index 000000000000..0655620d58b7
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowSingleWindow.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.wm.shell.flicker.service.desktopmode.scenarios
+
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+
+/** Base scenario test for window drag CUJ with single window. */
+@Ignore("Base Test Class")
+abstract class DragAppWindowSingleWindow : DragAppWindowScenarioTestBase()
+{
+ private val simpleAppHelper = SimpleAppHelper(instrumentation)
+ private val testApp = DesktopModeAppHelper(simpleAppHelper)
+
+ @Before
+ fun setup() {
+ Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+ testApp.enterDesktopWithDrag(wmHelper, device)
+ }
+
+ @Test
+ override fun dragAppWindow() {
+ val (startXTest, startYTest) = getWindowDragStartCoordinate(simpleAppHelper)
+ testApp.dragWindow(startXTest, startYTest,
+ endX = startXTest + 150, endY = startYTest + 150,
+ wmHelper, device)
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ExitDesktopWithDragToTopDragZone.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ExitDesktopWithDragToTopDragZone.kt
new file mode 100644
index 000000000000..0b6c9af17e7a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ExitDesktopWithDragToTopDragZone.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.wm.shell.flicker.service.desktopmode.scenarios
+
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.Rotation
+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.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.flicker.service.common.Utils
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+
+@Ignore("Base Test Class")
+abstract class ExitDesktopWithDragToTopDragZone
+@JvmOverloads
+constructor(val rotation: Rotation = Rotation.ROTATION_0) {
+
+ private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ private val tapl = LauncherInstrumentation()
+ private val wmHelper = WindowManagerStateHelper(instrumentation)
+ private val device = UiDevice.getInstance(instrumentation)
+ private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
+
+ @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+ @Before
+ fun setup() {
+ Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(rotation.value)
+ testApp.enterDesktopWithDrag(wmHelper, device)
+ }
+
+ @Test
+ open fun exitDesktopWithDragToTopDragZone() {
+ testApp.exitDesktopWithDragToTopDragZone(wmHelper, device)
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt
new file mode 100644
index 000000000000..20e2167c28f2
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.wm.shell.flicker.service.desktopmode.scenarios
+
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.Rotation
+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.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.flicker.service.common.Utils
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+/** Base scenario test for maximize app window CUJ in desktop mode. */
+@Ignore("Base Test Class")
+abstract class MaximizeAppWindow
+{
+ private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ private val tapl = LauncherInstrumentation()
+ private val wmHelper = WindowManagerStateHelper(instrumentation)
+ private val device = UiDevice.getInstance(instrumentation)
+ private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
+
+ @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL,
+ Rotation.ROTATION_0)
+
+ @Before
+ fun setup() {
+ Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+ testApp.enterDesktopWithDrag(wmHelper, device)
+ }
+
+ @Test
+ open fun maximizeAppWindow() {
+ testApp.maximiseDesktopApp(wmHelper, device)
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt
index ac9089a5c1bd..136cf378aa09 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt
@@ -38,7 +38,9 @@ import org.junit.Test
@Ignore("Base Test Class")
abstract class ResizeAppWithCornerResize
@JvmOverloads
-constructor(val rotation: Rotation = Rotation.ROTATION_0) {
+constructor(val rotation: Rotation = Rotation.ROTATION_0,
+ val horizontalChange: Int = 50,
+ val verticalChange: Int = -50) {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val tapl = LauncherInstrumentation()
@@ -46,7 +48,9 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) {
private val device = UiDevice.getInstance(instrumentation)
private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
- @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+ @Rule
+ @JvmField
+ val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
@Before
fun setup() {
@@ -58,7 +62,11 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) {
@Test
open fun resizeAppWithCornerResize() {
- testApp.cornerResize(wmHelper, device, DesktopModeAppHelper.Corners.RIGHT_TOP, 50, -50)
+ testApp.cornerResize(wmHelper,
+ device,
+ DesktopModeAppHelper.Corners.RIGHT_TOP,
+ horizontalChange,
+ verticalChange)
}
@After
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp b/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
index 3f2603aec86a..35b2f56bca92 100644
--- a/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
@@ -107,7 +107,7 @@ android_test {
instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen",
test_config_template: "AndroidTestTemplate.xml",
srcs: [
- ":WMShellFlickerTestsSplitScreenGroup1-src",
+ ":WMShellFlickerTestsSplitScreenGroup2-src",
],
static_libs: [
"WMShellFlickerTestsBase",
@@ -124,7 +124,7 @@ android_test {
instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen",
test_config_template: "AndroidTestTemplate.xml",
srcs: [
- ":WMShellFlickerTestsSplitScreenGroup1-src",
+ ":WMShellFlickerTestsSplitScreenGroup3-src",
],
static_libs: [
"WMShellFlickerTestsBase",
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index 92be4f9f0374..6b6954289a34 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -59,6 +59,7 @@ android_test {
"guava-android-testlib",
"com.android.window.flags.window-aconfig-java",
"platform-test-annotations",
+ "flag-junit",
],
libs: [
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index 8303317d39fc..e91828be4ebe 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -45,6 +45,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.app.ActivityManager.RunningTaskInfo;
+import android.app.TaskInfo;
import android.content.LocusId;
import android.content.pm.ParceledListSlice;
import android.os.Binder;
@@ -63,6 +64,8 @@ import androidx.test.filters.SmallTest;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.compatui.CompatUIController;
+import com.android.wm.shell.compatui.api.CompatUIInfo;
+import com.android.wm.shell.compatui.impl.CompatUIEvents;
import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellInit;
@@ -70,6 +73,7 @@ import com.android.wm.shell.sysui.ShellInit;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -371,7 +375,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
mOrganizer.onTaskAppeared(taskInfo1, /* leash= */ null);
// sizeCompatActivity is null if top activity is not in size compat.
- verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
// sizeCompatActivity is non-null if top activity is in size compat.
clearInvocations(mCompatUI);
@@ -381,7 +385,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
taskInfo2.appCompatTaskInfo.topActivityInSizeCompat = true;
taskInfo2.isVisible = true;
mOrganizer.onTaskInfoChanged(taskInfo2);
- verify(mCompatUI).onCompatInfoChanged(taskInfo2, taskListener);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo2, taskListener);
// Not show size compat UI if task is not visible.
clearInvocations(mCompatUI);
@@ -391,11 +395,11 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
taskInfo3.appCompatTaskInfo.topActivityInSizeCompat = true;
taskInfo3.isVisible = false;
mOrganizer.onTaskInfoChanged(taskInfo3);
- verify(mCompatUI).onCompatInfoChanged(taskInfo3, null /* taskListener */);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo3, null /* taskListener */);
clearInvocations(mCompatUI);
mOrganizer.onTaskVanished(taskInfo1);
- verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
}
@Test
@@ -410,7 +414,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
// Task listener sent to compat UI is null if top activity isn't eligible for letterbox
// education.
- verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
// Task listener is non-null if top activity is eligible for letterbox education and task
// is visible.
@@ -421,7 +425,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
taskInfo2.appCompatTaskInfo.topActivityEligibleForLetterboxEducation = true;
taskInfo2.isVisible = true;
mOrganizer.onTaskInfoChanged(taskInfo2);
- verify(mCompatUI).onCompatInfoChanged(taskInfo2, taskListener);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo2, taskListener);
// Task listener is null if task is invisible.
clearInvocations(mCompatUI);
@@ -431,11 +435,11 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
taskInfo3.appCompatTaskInfo.topActivityEligibleForLetterboxEducation = true;
taskInfo3.isVisible = false;
mOrganizer.onTaskInfoChanged(taskInfo3);
- verify(mCompatUI).onCompatInfoChanged(taskInfo3, null /* taskListener */);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo3, null /* taskListener */);
clearInvocations(mCompatUI);
mOrganizer.onTaskVanished(taskInfo1);
- verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
}
@Test
@@ -451,7 +455,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
// Task listener sent to compat UI is null if top activity doesn't request a camera
// compat control.
- verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
// Task listener is non-null when request a camera compat control for a visible task.
clearInvocations(mCompatUI);
@@ -462,7 +466,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
taskInfo2.isVisible = true;
mOrganizer.onTaskInfoChanged(taskInfo2);
- verify(mCompatUI).onCompatInfoChanged(taskInfo2, taskListener);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo2, taskListener);
// CompatUIController#onCompatInfoChanged is called when requested state for a camera
// compat control changes for a visible task.
@@ -474,7 +478,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
taskInfo3.isVisible = true;
mOrganizer.onTaskInfoChanged(taskInfo3);
- verify(mCompatUI).onCompatInfoChanged(taskInfo3, taskListener);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo3, taskListener);
// CompatUIController#onCompatInfoChanged is called when a top activity goes in size compat
// mode for a visible task that has a compat control.
@@ -487,7 +491,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
taskInfo4.isVisible = true;
mOrganizer.onTaskInfoChanged(taskInfo4);
- verify(mCompatUI).onCompatInfoChanged(taskInfo4, taskListener);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo4, taskListener);
// Task linster is null when a camera compat control is dimissed for a visible task.
clearInvocations(mCompatUI);
@@ -498,7 +502,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
CAMERA_COMPAT_CONTROL_DISMISSED;
taskInfo5.isVisible = true;
mOrganizer.onTaskInfoChanged(taskInfo5);
- verify(mCompatUI).onCompatInfoChanged(taskInfo5, null /* taskListener */);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo5, null /* taskListener */);
// Task linster is null when request a camera compat control for a invisible task.
clearInvocations(mCompatUI);
@@ -509,11 +513,11 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
taskInfo6.isVisible = false;
mOrganizer.onTaskInfoChanged(taskInfo6);
- verify(mCompatUI).onCompatInfoChanged(taskInfo6, null /* taskListener */);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo6, null /* taskListener */);
clearInvocations(mCompatUI);
mOrganizer.onTaskVanished(taskInfo1);
- verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+ verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
}
@Test
@@ -640,7 +644,8 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
mOrganizer.onTaskAppeared(task1, /* leash= */ null);
- mOrganizer.onSizeCompatRestartButtonClicked(task1.taskId);
+ mOrganizer.onSizeCompatRestartButtonClicked(
+ new CompatUIEvents.SizeCompatRestartButtonClicked(task1.taskId));
verify(mTaskOrganizerController).restartTaskTopActivityProcessIfVisible(task1.token);
}
@@ -713,4 +718,13 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
taskInfo.isVisible = true;
return taskInfo;
}
+
+ private void verifyOnCompatInfoChangedInvokedWith(TaskInfo taskInfo,
+ ShellTaskOrganizer.TaskListener listener) {
+ final ArgumentCaptor<CompatUIInfo> capture = ArgumentCaptor.forClass(CompatUIInfo.class);
+ verify(mCompatUI).onCompatInfoChanged(capture.capture());
+ final CompatUIInfo captureValue = capture.getValue();
+ assertEquals(captureValue.getTaskInfo(), taskInfo);
+ assertEquals(captureValue.getListener(), listener);
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomCrossActivityBackAnimationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomCrossActivityBackAnimationTest.kt
index 8bf011192347..080ad901c656 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomCrossActivityBackAnimationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomCrossActivityBackAnimationTest.kt
@@ -25,7 +25,6 @@ import android.graphics.Rect
import android.os.RemoteException
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
-import android.view.Choreographer
import android.view.RemoteAnimationTarget
import android.view.SurfaceControl
import android.view.SurfaceControl.Transaction
@@ -37,8 +36,6 @@ import androidx.test.filters.SmallTest
import com.android.internal.policy.TransitionAnimation
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTestCase
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
import junit.framework.TestCase.assertEquals
import org.junit.Assert
import org.junit.Before
@@ -50,12 +47,13 @@ import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
-import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.kotlin.spy
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
@SmallTest
@TestableLooper.RunWithLooper
@@ -82,7 +80,6 @@ class CustomCrossActivityBackAnimationTest : ShellTestCase() {
backAnimationBackground,
rootTaskDisplayAreaOrganizer,
transaction,
- mock(Choreographer::class.java),
customAnimationLoader
)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java
index 636c6326d213..f5847cc27071 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java
@@ -70,7 +70,7 @@ public class DividerViewTest extends ShellTestCase {
mContext,
configuration, mCallbacks);
splitWindowManager.init(mSplitLayout, new InsetsState(), false /* isRestoring */);
- mDividerView = spy((DividerView) splitWindowManager.getDividerView());
+ mDividerView = spy(splitWindowManager.getDividerView());
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
index 4cd2a366f5eb..ecaf970ae389 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
@@ -16,8 +16,10 @@
package com.android.wm.shell.compatui
+import android.content.ComponentName
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
+import com.android.internal.R
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
import org.junit.Assert.assertFalse
@@ -34,26 +36,55 @@ import org.junit.runner.RunWith
@RunWith(AndroidTestingRunner::class)
@SmallTest
class AppCompatUtilsTest : ShellTestCase() {
-
@Test
- fun testIsSingleTopActivityTranslucent() {
- assertTrue(isSingleTopActivityTranslucent(
+ fun testIsTopActivityExemptFromDesktopWindowing_topActivityTransparent() {
+ assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
createFreeformTask(/* displayId */ 0)
.apply {
isTopActivityTransparent = true
numActivities = 1
}))
- assertFalse(isSingleTopActivityTranslucent(
+ assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
createFreeformTask(/* displayId */ 0)
.apply {
isTopActivityTransparent = true
numActivities = 0
}))
- assertFalse(isSingleTopActivityTranslucent(
+ }
+
+ @Test
+ fun testIsTopActivityExemptFromDesktopWindowing_singleTopActivity() {
+ assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
+ createFreeformTask(/* displayId */ 0)
+ .apply {
+ isTopActivityTransparent = true
+ numActivities = 1
+ }))
+ assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
createFreeformTask(/* displayId */ 0)
.apply {
isTopActivityTransparent = false
numActivities = 1
}))
}
-} \ No newline at end of file
+
+ @Test
+ fun testIsTopActivityExemptFromDesktopWindowing__topActivityStyleFloating() {
+ assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
+ createFreeformTask(/* displayId */ 0)
+ .apply {
+ isTopActivityStyleFloating = true
+ }))
+ }
+
+ @Test
+ fun testIsTopActivityExemptFromDesktopWindowing_systemUiTask() {
+ val systemUIPackageName = context.resources.getString(R.string.config_systemUi)
+ val baseComponent = ComponentName(systemUIPackageName, /* class */ "")
+ assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
+ createFreeformTask(/* displayId */ 0)
+ .apply {
+ baseActivity = baseComponent
+ }))
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index 9c008647104a..fc7a7770b8ca 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -38,6 +38,9 @@ import android.app.CameraCompatTaskInfo.CameraCompatControlState;
import android.app.TaskInfo;
import android.content.Context;
import android.content.res.Configuration;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.AndroidTestingRunner;
import android.view.InsetsSource;
import android.view.InsetsState;
@@ -45,6 +48,7 @@ import android.view.accessibility.AccessibilityManager;
import androidx.test.filters.SmallTest;
+import com.android.window.flags.Flags;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayController;
@@ -55,6 +59,7 @@ import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.compatui.api.CompatUIInfo;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
@@ -63,6 +68,7 @@ import dagger.Lazy;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -82,6 +88,10 @@ public class CompatUIControllerTest extends ShellTestCase {
private static final int DISPLAY_ID = 0;
private static final int TASK_ID = 12;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
private CompatUIController mController;
private ShellInit mShellInit;
@Mock
@@ -168,28 +178,32 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void instantiateController_addInitCallback() {
verify(mShellInit, times(1)).addInitCallback(any(), any());
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void instantiateController_registerKeyguardChangeListener() {
verify(mMockShellController, times(1)).addKeyguardChangeListener(any());
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testListenerRegistered() {
verify(mMockDisplayController).addDisplayWindowListener(mController);
verify(mMockImeController).addPositionProcessor(mController);
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnCompatInfoChanged() {
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
CAMERA_COMPAT_CONTROL_HIDDEN);
// Verify that the compat controls are added with non-null task listener.
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mController).createCompatUiWindowManager(any(), eq(taskInfo), eq(mMockTaskListener));
verify(mController).createLetterboxEduWindowManager(any(), eq(taskInfo),
@@ -202,7 +216,7 @@ public class CompatUIControllerTest extends ShellTestCase {
clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
/* canShow= */ true);
@@ -213,9 +227,9 @@ public class CompatUIControllerTest extends ShellTestCase {
// Verify that compat controls and letterbox education are removed with null task listener.
clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
- mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
+ mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN),
- /* taskListener= */ null);
+ /* taskListener= */ null));
verify(mMockCompatLayout).release();
verify(mMockLetterboxEduLayout).release();
@@ -223,6 +237,7 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnCompatInfoChanged_createLayoutReturnsFalse() {
doReturn(false).when(mMockCompatLayout).createLayout(anyBoolean());
doReturn(false).when(mMockLetterboxEduLayout).createLayout(anyBoolean());
@@ -230,7 +245,7 @@ public class CompatUIControllerTest extends ShellTestCase {
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
CAMERA_COMPAT_CONTROL_HIDDEN);
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mController).createCompatUiWindowManager(any(), eq(taskInfo), eq(mMockTaskListener));
verify(mController).createLetterboxEduWindowManager(any(), eq(taskInfo),
@@ -240,7 +255,7 @@ public class CompatUIControllerTest extends ShellTestCase {
// Verify that the layout is created again.
clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mMockCompatLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
verify(mMockLetterboxEduLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
@@ -253,6 +268,7 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnCompatInfoChanged_updateCompatInfoReturnsFalse() {
doReturn(false).when(mMockCompatLayout).updateCompatInfo(any(), any(), anyBoolean());
doReturn(false).when(mMockLetterboxEduLayout).updateCompatInfo(any(), any(), anyBoolean());
@@ -260,7 +276,7 @@ public class CompatUIControllerTest extends ShellTestCase {
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
CAMERA_COMPAT_CONTROL_HIDDEN);
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mController).createCompatUiWindowManager(any(), eq(taskInfo), eq(mMockTaskListener));
verify(mController).createLetterboxEduWindowManager(any(), eq(taskInfo),
@@ -270,7 +286,7 @@ public class CompatUIControllerTest extends ShellTestCase {
clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mMockRestartDialogLayout,
mController);
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
/* canShow= */ true);
@@ -282,7 +298,7 @@ public class CompatUIControllerTest extends ShellTestCase {
// Verify that the layout is created again.
clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mMockRestartDialogLayout,
mController);
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mMockCompatLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
verify(mMockLetterboxEduLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
@@ -296,6 +312,7 @@ public class CompatUIControllerTest extends ShellTestCase {
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnDisplayAdded() {
mController.onDisplayAdded(DISPLAY_ID);
mController.onDisplayAdded(DISPLAY_ID + 1);
@@ -305,11 +322,11 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnDisplayRemoved() {
mController.onDisplayAdded(DISPLAY_ID);
- mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN),
- mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+ /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
mController.onDisplayRemoved(DISPLAY_ID + 1);
@@ -328,9 +345,10 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnDisplayConfigurationChanged() {
- mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+ /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
mController.onDisplayConfigurationChanged(DISPLAY_ID + 1, new Configuration());
@@ -346,10 +364,11 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testInsetsChanged() {
mController.onDisplayAdded(DISPLAY_ID);
- mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+ /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
InsetsState insetsState = new InsetsState();
InsetsSource insetsSource = new InsetsSource(
InsetsSource.createId(null, 0, navigationBars()), navigationBars());
@@ -373,9 +392,10 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testChangeLayoutsVisibilityOnImeShowHide() {
- mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+ /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
// Verify that the restart button is hidden after IME is showing.
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
@@ -387,7 +407,7 @@ public class CompatUIControllerTest extends ShellTestCase {
// Verify button remains hidden while IME is showing.
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
CAMERA_COMPAT_CONTROL_HIDDEN);
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
/* canShow= */ false);
@@ -405,9 +425,10 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testChangeLayoutsVisibilityOnKeyguardShowingChanged() {
- mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+ /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
// Verify that the restart button is hidden after keyguard becomes showing.
mController.onKeyguardVisibilityChanged(true, false, false);
@@ -419,7 +440,7 @@ public class CompatUIControllerTest extends ShellTestCase {
// Verify button remains hidden while keyguard is showing.
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
CAMERA_COMPAT_CONTROL_HIDDEN);
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
/* canShow= */ false);
@@ -437,9 +458,10 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testLayoutsRemainHiddenOnKeyguardShowingFalseWhenImeIsShowing() {
- mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+ /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
mController.onKeyguardVisibilityChanged(true, false, false);
@@ -466,9 +488,10 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testLayoutsRemainHiddenOnImeHideWhenKeyguardIsShowing() {
- mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
- /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+ /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
mController.onKeyguardVisibilityChanged(true, false, false);
@@ -495,6 +518,7 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testRestartLayoutRecreatedIfNeeded() {
final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN);
@@ -502,14 +526,15 @@ public class CompatUIControllerTest extends ShellTestCase {
.needsToBeRecreated(any(TaskInfo.class),
any(ShellTaskOrganizer.TaskListener.class));
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mMockRestartDialogLayout, times(2))
.createLayout(anyBoolean());
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testRestartLayoutNotRecreatedIfNotNeeded() {
final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN);
@@ -517,14 +542,15 @@ public class CompatUIControllerTest extends ShellTestCase {
.needsToBeRecreated(any(TaskInfo.class),
any(ShellTaskOrganizer.TaskListener.class));
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mMockRestartDialogLayout, times(1))
.createLayout(anyBoolean());
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateActiveTaskInfo_newTask_visibleAndFocused_updated() {
// Simulate user aspect ratio button being shown for previous task
mController.setHasShownUserAspectRatioSettingsButton(true);
@@ -545,6 +571,7 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateActiveTaskInfo_newTask_notVisibleOrFocused_notUpdated() {
// Create new task
final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
@@ -606,6 +633,7 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateActiveTaskInfo_sameTask_notUpdated() {
// Create new task
final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
@@ -634,6 +662,7 @@ public class CompatUIControllerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateActiveTaskInfo_transparentTask_notUpdated() {
// Create new task
final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
@@ -674,7 +703,7 @@ public class CompatUIControllerTest extends ShellTestCase {
CAMERA_COMPAT_CONTROL_HIDDEN);
taskInfo.appCompatTaskInfo.isLetterboxEducationEnabled = false;
- mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+ mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mController, never()).createLetterboxEduWindowManager(any(), eq(taskInfo),
eq(mMockTaskListener));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
index cd3e8cb0e8e1..33d69f5c34c8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
@@ -23,6 +23,7 @@ import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_S
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
@@ -31,6 +32,9 @@ import android.app.ActivityManager;
import android.app.CameraCompatTaskInfo.CameraCompatControlState;
import android.app.TaskInfo;
import android.graphics.Rect;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.AndroidTestingRunner;
import android.util.Pair;
import android.view.LayoutInflater;
@@ -40,16 +44,20 @@ import android.widget.LinearLayout;
import androidx.test.filters.SmallTest;
+import com.android.window.flags.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState;
+import com.android.wm.shell.compatui.api.CompatUIEvent;
+import com.android.wm.shell.compatui.impl.CompatUIEvents;
import junit.framework.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -70,8 +78,12 @@ public class CompatUILayoutTest extends ShellTestCase {
private static final int TASK_ID = 1;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Mock private SyncTransactionQueue mSyncTransactionQueue;
- @Mock private CompatUIController.CompatUICallback mCallback;
+ @Mock private Consumer<CompatUIEvent> mCallback;
@Mock private Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnRestartButtonClicked;
@Mock private ShellTaskOrganizer.TaskListener mTaskListener;
@Mock private SurfaceControlViewHost mViewHost;
@@ -101,6 +113,7 @@ public class CompatUILayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnClickForRestartButton() {
final ImageButton button = mLayout.findViewById(R.id.size_compat_restart_button);
button.performClick();
@@ -117,6 +130,7 @@ public class CompatUILayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnLongClickForRestartButton() {
doNothing().when(mWindowManager).onRestartButtonLongClicked();
@@ -127,6 +141,7 @@ public class CompatUILayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnClickForSizeCompatHint() {
mWindowManager.mHasSizeCompat = true;
mWindowManager.createLayout(/* canShow= */ true);
@@ -137,6 +152,7 @@ public class CompatUILayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateCameraTreatmentButton_treatmentAppliedByDefault() {
mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
mWindowManager.createLayout(/* canShow= */ true);
@@ -145,16 +161,17 @@ public class CompatUILayoutTest extends ShellTestCase {
button.performClick();
verify(mWindowManager).onCameraTreatmentButtonClicked();
- verify(mCallback).onCameraControlStateUpdated(
- TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
+ verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
+ CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
button.performClick();
- verify(mCallback).onCameraControlStateUpdated(
- TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
+ verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
+ CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateCameraTreatmentButton_treatmentSuggestedByDefault() {
mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
mWindowManager.createLayout(/* canShow= */ true);
@@ -163,16 +180,17 @@ public class CompatUILayoutTest extends ShellTestCase {
button.performClick();
verify(mWindowManager).onCameraTreatmentButtonClicked();
- verify(mCallback).onCameraControlStateUpdated(
- TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
+ verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
+ CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
button.performClick();
- verify(mCallback).onCameraControlStateUpdated(
- TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
+ verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
+ CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnCameraDismissButtonClicked() {
mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
mWindowManager.createLayout(/* canShow= */ true);
@@ -181,12 +199,12 @@ public class CompatUILayoutTest extends ShellTestCase {
button.performClick();
verify(mWindowManager).onCameraDismissButtonClicked();
- verify(mCallback).onCameraControlStateUpdated(
- TASK_ID, CAMERA_COMPAT_CONTROL_DISMISSED);
+ verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID, CAMERA_COMPAT_CONTROL_DISMISSED);
verify(mLayout).setCameraControlVisibility(/* show */ false);
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnLongClickForCameraTreatmentButton() {
doNothing().when(mWindowManager).onCameraButtonLongClicked();
@@ -198,6 +216,7 @@ public class CompatUILayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnLongClickForCameraDismissButton() {
doNothing().when(mWindowManager).onCameraButtonLongClicked();
@@ -208,6 +227,7 @@ public class CompatUILayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnClickForCameraCompatHint() {
mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
mWindowManager.createLayout(/* canShow= */ true);
@@ -229,4 +249,15 @@ public class CompatUILayoutTest extends ShellTestCase {
taskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 0, 2000, 2000));
return taskInfo;
}
+
+ private void verifyOnCameraControlStateUpdatedInvokedWith(int taskId, int state) {
+ final ArgumentCaptor<CompatUIEvent> captureValue = ArgumentCaptor.forClass(
+ CompatUIEvent.class);
+ verify(mCallback).accept(captureValue.capture());
+ final CompatUIEvents.CameraControlStateUpdated compatUIEvent =
+ (CompatUIEvents.CameraControlStateUpdated) captureValue.getValue();
+ Assert.assertEquals((compatUIEvent).getTaskId(), taskId);
+ Assert.assertEquals((compatUIEvent).getState(), state);
+ clearInvocations(mCallback);
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
index 41a81c1a9921..eb3da8f65b5d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
@@ -25,6 +25,7 @@ import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -42,6 +43,9 @@ import android.app.CameraCompatTaskInfo;
import android.app.TaskInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.test.flag.junit.SetFlagsRule;
import android.testing.AndroidTestingRunner;
import android.util.Pair;
@@ -60,6 +64,8 @@ import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState;
+import com.android.wm.shell.compatui.api.CompatUIEvent;
+import com.android.wm.shell.compatui.impl.CompatUIEvents;
import junit.framework.Assert;
@@ -85,12 +91,16 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
private static final int TASK_ID = 1;
private static final int TASK_WIDTH = 2000;
private static final int TASK_HEIGHT = 2000;
@Mock private SyncTransactionQueue mSyncTransactionQueue;
- @Mock private CompatUIController.CompatUICallback mCallback;
+ @Mock private Consumer<CompatUIEvent> mCallback;
@Mock private Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnRestartButtonClicked;
@Mock private ShellTaskOrganizer.TaskListener mTaskListener;
@Mock private CompatUILayout mLayout;
@@ -129,6 +139,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testCreateSizeCompatButton() {
// Doesn't create layout if show is false.
mWindowManager.mHasSizeCompat = true;
@@ -174,6 +185,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testCreateCameraCompatControl() {
// Doesn't create layout if show is false.
mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
@@ -212,6 +224,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testRelease() {
mWindowManager.mHasSizeCompat = true;
mWindowManager.createLayout(/* canShow= */ true);
@@ -224,6 +237,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateCompatInfo() {
mWindowManager.mHasSizeCompat = true;
mWindowManager.createLayout(/* canShow= */ true);
@@ -315,6 +329,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateCompatInfoLayoutNotInflatedYet() {
mWindowManager.createLayout(/* canShow= */ false);
@@ -347,6 +362,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateDisplayLayout() {
final DisplayInfo displayInfo = new DisplayInfo();
displayInfo.logicalWidth = 1000;
@@ -366,6 +382,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateDisplayLayoutInsets() {
final DisplayInfo displayInfo = new DisplayInfo();
displayInfo.logicalWidth = 1000;
@@ -390,6 +407,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateVisibility() {
// Create button if it is not created.
mWindowManager.mLayout = null;
@@ -415,6 +433,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testAttachToParentSurface() {
final SurfaceControl.Builder b = new SurfaceControl.Builder();
mWindowManager.attachToParentSurface(b);
@@ -423,37 +442,38 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnCameraDismissButtonClicked() {
mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
mWindowManager.createLayout(/* canShow= */ true);
clearInvocations(mLayout);
mWindowManager.onCameraDismissButtonClicked();
- verify(mCallback).onCameraControlStateUpdated(TASK_ID, CAMERA_COMPAT_CONTROL_DISMISSED);
+ verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID, CAMERA_COMPAT_CONTROL_DISMISSED);
verify(mLayout).setCameraControlVisibility(/* show= */ false);
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnCameraTreatmentButtonClicked() {
mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
mWindowManager.createLayout(/* canShow= */ true);
clearInvocations(mLayout);
mWindowManager.onCameraTreatmentButtonClicked();
- verify(mCallback).onCameraControlStateUpdated(
- TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
- verify(mLayout).updateCameraTreatmentButton(
+ verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
+ verify(mLayout).updateCameraTreatmentButton(CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
mWindowManager.onCameraTreatmentButtonClicked();
- verify(mCallback).onCameraControlStateUpdated(
- TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
- verify(mLayout).updateCameraTreatmentButton(
+ verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
+ verify(mLayout).updateCameraTreatmentButton(CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnRestartButtonClicked() {
mWindowManager.onRestartButtonClicked();
@@ -468,8 +488,9 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnRestartButtonLongClicked_showHint() {
- // Not create hint popup.
+ // Not create hint popup.
mWindowManager.mHasSizeCompat = true;
mWindowManager.mCompatUIHintsState.mHasShownSizeCompatHint = true;
mWindowManager.createLayout(/* canShow= */ true);
@@ -483,6 +504,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnCameraControlLongClicked_showHint() {
// Not create hint popup.
mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
@@ -498,6 +520,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testWhenDockedStateHasChanged_needsToBeRecreated() {
ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
newTaskInfo.configuration.uiMode |= Configuration.UI_MODE_TYPE_DESK;
@@ -506,6 +529,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testShouldShowSizeCompatRestartButton() {
mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_HIDE_SCM_BUTTON);
doReturn(85).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance();
@@ -558,4 +582,15 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
taskInfo.configuration.smallestScreenWidthDp = LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
return taskInfo;
}
+
+ private void verifyOnCameraControlStateUpdatedInvokedWith(int taskId, int state) {
+ final ArgumentCaptor<CompatUIEvent> captureValue = ArgumentCaptor.forClass(
+ CompatUIEvent.class);
+ verify(mCallback).accept(captureValue.capture());
+ final CompatUIEvents.CameraControlStateUpdated compatUIEvent =
+ (CompatUIEvents.CameraControlStateUpdated) captureValue.getValue();
+ Assert.assertEquals((compatUIEvent).getTaskId(), taskId);
+ Assert.assertEquals((compatUIEvent).getState(), state);
+ clearInvocations(mCallback);
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java
index 172c263ab0f6..e8191db13084 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java
@@ -16,12 +16,17 @@
package com.android.wm.shell.compatui;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.AndroidTestingRunner;
import android.view.LayoutInflater;
import android.view.View;
@@ -32,6 +37,7 @@ import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -54,6 +60,10 @@ public class LetterboxEduDialogLayoutTest extends ShellTestCase {
private View mDismissButton;
private View mDialogContainer;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -66,6 +76,7 @@ public class LetterboxEduDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnFinishInflate() {
assertEquals(mLayout.getDialogContainerView(),
mLayout.findViewById(R.id.letterbox_education_dialog_container));
@@ -76,6 +87,7 @@ public class LetterboxEduDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnDismissButtonClicked() {
assertTrue(mDismissButton.performClick());
@@ -83,6 +95,7 @@ public class LetterboxEduDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnBackgroundClicked() {
assertTrue(mLayout.performClick());
@@ -90,6 +103,7 @@ public class LetterboxEduDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnDialogContainerClicked() {
assertTrue(mDialogContainer.performClick());
@@ -97,6 +111,7 @@ public class LetterboxEduDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testSetDismissOnClickListenerNull() {
mLayout.setDismissOnClickListener(null);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
index a60a1cbb435f..b5664ac113fa 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
@@ -19,6 +19,7 @@ package com.android.wm.shell.compatui;
import static android.content.res.Configuration.UI_MODE_NIGHT_YES;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
import static com.google.common.truth.Truth.assertThat;
@@ -37,6 +38,9 @@ import android.app.ActivityManager;
import android.app.TaskInfo;
import android.graphics.Insets;
import android.graphics.Rect;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.AndroidTestingRunner;
import android.util.Pair;
import android.view.DisplayCutout;
@@ -61,6 +65,7 @@ import com.android.wm.shell.transition.Transitions;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -116,6 +121,10 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
private CompatUIConfiguration mCompatUIConfiguration;
private TestShellExecutor mExecutor;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -153,6 +162,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testCreateLayout_notEligible_doesNotCreateLayout() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ false);
@@ -162,6 +172,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testCreateLayout_eligibleAndDocked_doesNotCreateLayout() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */
true, /* isDocked */ true);
@@ -172,6 +183,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testCreateLayout_taskBarEducationIsShowing_doesNotCreateLayout() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true,
USER_ID_1, /* isTaskbarEduShowing= */ true);
@@ -182,6 +194,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testCreateLayout_canShowFalse_returnsTrueButDoesNotCreateLayout() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
@@ -192,6 +205,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testCreateLayout_canShowTrue_createsLayoutCorrectly() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
@@ -238,6 +252,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testCreateLayout_alreadyShownToUser_createsLayoutForOtherUserOnly() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true,
USER_ID_1, /* isTaskbarEduShowing= */ false);
@@ -271,6 +286,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testCreateLayout_windowManagerReleasedBeforeTransitionsIsIdle_doesNotStartAnim() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
@@ -288,6 +304,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateCompatInfo_updatesLayoutCorrectly() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
@@ -316,6 +333,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateCompatInfo_notEligibleUntilUpdate_createsLayoutAfterUpdate() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ false);
@@ -329,6 +347,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateCompatInfo_canShowFalse_doesNothing() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
@@ -343,6 +362,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateDisplayLayout_updatesLayoutCorrectly() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
@@ -364,6 +384,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testRelease_animationIsCancelled() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
@@ -374,6 +395,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testDeviceThemeChange_educationDialogUnseen_recreated() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java
index 4f71b83179b1..0da14d673732 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.compatui;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
@@ -23,6 +25,9 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.app.TaskInfo;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.LayoutInflater;
@@ -34,6 +39,7 @@ import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -62,6 +68,10 @@ public class ReachabilityEduLayoutTest extends ShellTestCase {
@Mock
private TaskInfo mTaskInfo;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -74,6 +84,7 @@ public class ReachabilityEduLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnFinishInflate() {
assertNotNull(mMoveUpButton);
assertNotNull(mMoveDownButton);
@@ -82,6 +93,7 @@ public class ReachabilityEduLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void handleVisibility_educationNotEnabled_buttonsAreHidden() {
mLayout.handleVisibility(/* horizontalEnabled */ false, /* verticalEnabled */
false, /* letterboxVerticalPosition */
@@ -94,6 +106,7 @@ public class ReachabilityEduLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void handleVisibility_horizontalEducationEnableduiConfigurationIsUpdated() {
mLayout.handleVisibility(/* horizontalEnabled */ true, /* verticalEnabled */
false, /* letterboxVerticalPosition */ -1, /* letterboxHorizontalPosition */
@@ -106,6 +119,7 @@ public class ReachabilityEduLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void handleVisibility_verticalEducationEnabled_uiConfigurationIsUpdated() {
mLayout.handleVisibility(/* horizontalEnabled */ false, /* verticalEnabled */
true, /* letterboxVerticalPosition */ 0, /* letterboxHorizontalPosition */
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java
index 5867a8553d53..eafb41470cda 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java
@@ -16,12 +16,17 @@
package com.android.wm.shell.compatui;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import android.app.ActivityManager;
import android.app.TaskInfo;
import android.content.res.Configuration;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
@@ -35,6 +40,7 @@ import com.android.wm.shell.common.SyncTransactionQueue;
import junit.framework.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -65,6 +71,10 @@ public class ReachabilityEduWindowManagerTest extends ShellTestCase {
private TaskInfo mTaskInfo;
private ReachabilityEduWindowManager mWindowManager;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -80,6 +90,7 @@ public class ReachabilityEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testCreateLayout_notEligible_doesNotCreateLayout() {
assertFalse(mWindowManager.createLayout(/* canShow= */ true));
@@ -87,6 +98,7 @@ public class ReachabilityEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testWhenDockedStateHasChanged_needsToBeRecreated() {
ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
newTaskInfo.configuration.uiMode =
@@ -97,6 +109,7 @@ public class ReachabilityEduWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testWhenDarkLightThemeHasChanged_needsToBeRecreated() {
ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
mTaskInfo.configuration.uiMode =
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogLayoutTest.java
index e2dcdb0e91b2..6b0c5dd2e1c7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogLayoutTest.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.compatui;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -23,6 +25,9 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.AndroidTestingRunner;
import android.view.LayoutInflater;
import android.view.View;
@@ -34,6 +39,7 @@ import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -60,6 +66,10 @@ public class RestartDialogLayoutTest extends ShellTestCase {
private View mDialogContainer;
private CheckBox mDontRepeatCheckBox;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -76,6 +86,7 @@ public class RestartDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnFinishInflate() {
assertEquals(mLayout.getDialogContainerView(),
mLayout.findViewById(R.id.letterbox_restart_dialog_container));
@@ -86,6 +97,7 @@ public class RestartDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnDismissButtonClicked() {
assertTrue(mDismissButton.performClick());
@@ -93,6 +105,7 @@ public class RestartDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnRestartButtonClickedWithoutCheckbox() {
mDontRepeatCheckBox.setChecked(false);
assertTrue(mRestartButton.performClick());
@@ -101,6 +114,7 @@ public class RestartDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnRestartButtonClickedWithCheckbox() {
mDontRepeatCheckBox.setChecked(true);
assertTrue(mRestartButton.performClick());
@@ -109,6 +123,7 @@ public class RestartDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnBackgroundClickedDoesntDismiss() {
assertFalse(mLayout.performClick());
@@ -116,6 +131,7 @@ public class RestartDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnDialogContainerClicked() {
assertTrue(mDialogContainer.performClick());
@@ -124,6 +140,7 @@ public class RestartDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testSetDismissOnClickListenerNull() {
mLayout.setDismissOnClickListener(null);
@@ -135,6 +152,7 @@ public class RestartDialogLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testSetRestartOnClickListenerNull() {
mLayout.setRestartOnClickListener(null);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java
index 9f109a1d0f50..cfeef90cb4b6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java
@@ -16,9 +16,14 @@
package com.android.wm.shell.compatui;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
+
import android.app.ActivityManager;
import android.app.TaskInfo;
import android.content.res.Configuration;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.AndroidTestingRunner;
import android.util.Pair;
@@ -33,6 +38,7 @@ import com.android.wm.shell.transition.Transitions;
import junit.framework.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -60,6 +66,10 @@ public class RestartDialogWindowManagerTest extends ShellTestCase {
private RestartDialogWindowManager mWindowManager;
private TaskInfo mTaskInfo;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -76,6 +86,7 @@ public class RestartDialogWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testWhenDockedStateHasChanged_needsToBeRecreated() {
ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
newTaskInfo.configuration.uiMode =
@@ -86,6 +97,7 @@ public class RestartDialogWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testWhenDarkLightThemeHasChanged_needsToBeRecreated() {
ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
mTaskInfo.configuration.uiMode =
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
index 02316125bcc3..3fa21cee0d68 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
@@ -19,6 +19,7 @@ package com.android.wm.shell.compatui;
import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_HIDDEN;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -28,6 +29,9 @@ import android.app.ActivityManager;
import android.app.CameraCompatTaskInfo.CameraCompatControlState;
import android.app.TaskInfo;
import android.content.ComponentName;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.AndroidTestingRunner;
import android.util.Pair;
import android.view.LayoutInflater;
@@ -47,6 +51,7 @@ import com.android.wm.shell.common.SyncTransactionQueue;
import junit.framework.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -86,6 +91,10 @@ public class UserAspectRatioSettingsLayoutTest extends ShellTestCase {
private UserAspectRatioSettingsLayout mLayout;
private TaskInfo mTaskInfo;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -107,6 +116,7 @@ public class UserAspectRatioSettingsLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnClickForUserAspectRatioSettingsButton() {
final ImageButton button = mLayout.findViewById(R.id.user_aspect_ratio_settings_button);
button.performClick();
@@ -123,6 +133,7 @@ public class UserAspectRatioSettingsLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnLongClickForUserAspectRatioButton() {
doNothing().when(mWindowManager).onUserAspectRatioSettingsButtonLongClicked();
@@ -133,6 +144,7 @@ public class UserAspectRatioSettingsLayoutTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnClickForUserAspectRatioSettingsHint() {
mWindowManager.mHasUserAspectRatioSettingsButton = true;
mWindowManager.createLayout(/* canShow= */ true);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
index 94e168ed70ed..9f288cc4bd93 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
@@ -22,6 +22,7 @@ import static android.hardware.usb.UsbManager.ACTION_USB_STATE;
import static android.view.WindowInsets.Type.navigationBars;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -39,6 +40,9 @@ import android.content.ComponentName;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Rect;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.util.Pair;
@@ -61,6 +65,7 @@ import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState;
import junit.framework.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -107,6 +112,10 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
private TestShellExecutor mExecutor;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -138,6 +147,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testCreateUserAspectRatioButton() {
// Doesn't create layout if show is false.
mWindowManager.mHasUserAspectRatioSettingsButton = true;
@@ -178,6 +188,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testRelease() {
mWindowManager.mHasUserAspectRatioSettingsButton = true;
mWindowManager.createLayout(/* canShow= */ true);
@@ -190,6 +201,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateCompatInfo() {
mWindowManager.mHasUserAspectRatioSettingsButton = true;
mWindowManager.createLayout(/* canShow= */ true);
@@ -242,6 +254,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateCompatInfoLayoutNotInflatedYet() {
mWindowManager.mHasUserAspectRatioSettingsButton = true;
mWindowManager.createLayout(/* canShow= */ false);
@@ -267,6 +280,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testEligibleButtonHiddenIfLetterboxBoundsEqualToStableBounds() {
TaskInfo taskInfo = createTaskInfo(/* eligibleForUserAspectRatioButton= */
true, /* topActivityBoundsLetterboxed */ true, ACTION_MAIN, CATEGORY_LAUNCHER);
@@ -292,6 +306,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUserFullscreenOverrideEnabled_buttonAlwaysShown() {
TaskInfo taskInfo = createTaskInfo(/* eligibleForUserAspectRatioButton= */
true, /* topActivityBoundsLetterboxed */ true, ACTION_MAIN, CATEGORY_LAUNCHER);
@@ -310,6 +325,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateDisplayLayout() {
final DisplayInfo displayInfo = new DisplayInfo();
displayInfo.logicalWidth = 1000;
@@ -329,6 +345,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateDisplayLayoutInsets() {
final DisplayInfo displayInfo = new DisplayInfo();
displayInfo.logicalWidth = 1000;
@@ -353,6 +370,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateVisibility() {
// Create button if it is not created.
mWindowManager.removeLayout();
@@ -378,6 +396,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testLayoutHasUserAspectRatioSettingsButton() {
clearInvocations(mWindowManager);
spyOn(mWindowManager);
@@ -411,6 +430,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testAttachToParentSurface() {
final SurfaceControl.Builder b = new SurfaceControl.Builder();
mWindowManager.attachToParentSurface(b);
@@ -419,6 +439,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnUserAspectRatioButtonClicked() {
mWindowManager.onUserAspectRatioSettingsButtonClicked();
@@ -433,6 +454,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testOnUserAspectRatioButtonLongClicked_showHint() {
// Not create hint popup.
mWindowManager.mHasUserAspectRatioSettingsButton = true;
@@ -448,6 +470,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
}
@Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testWhenDockedStateHasChanged_needsToBeRecreated() {
ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
newTaskInfo.configuration.uiMode |= Configuration.UI_MODE_TYPE_DESK;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt
new file mode 100644
index 000000000000..1a86cfd6b69e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt
@@ -0,0 +1,89 @@
+/*
+ * 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.wm.shell.compatui.impl
+
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.compatui.api.CompatUIRepository
+import com.android.wm.shell.compatui.api.CompatUISpec
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests for {@link DefaultCompatUIRepository}.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:DefaultCompatUIRepositoryTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class DefaultCompatUIRepositoryTest {
+
+ lateinit var repository: CompatUIRepository
+
+ @get:Rule
+ val mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
+ @Before
+ fun setUp() {
+ repository = DefaultCompatUIRepository()
+ }
+
+ @Test(expected = IllegalStateException::class)
+ fun `addSpec throws exception with specs with duplicate id`() {
+ repository.addSpec(CompatUISpec("one"))
+ repository.addSpec(CompatUISpec("one"))
+ }
+
+ @Test
+ fun `iterateOn invokes the consumer`() {
+ with(repository) {
+ addSpec(CompatUISpec("one"))
+ addSpec(CompatUISpec("two"))
+ addSpec(CompatUISpec("three"))
+ val consumer = object : (CompatUISpec) -> Unit {
+ var acc = ""
+ override fun invoke(spec: CompatUISpec) {
+ acc += spec.name
+ }
+ }
+ iterateOn(consumer)
+ assertEquals("onetwothree", consumer.acc)
+ }
+ }
+
+ @Test
+ fun `findSpec returns existing specs`() {
+ with(repository) {
+ val one = CompatUISpec("one")
+ val two = CompatUISpec("two")
+ val three = CompatUISpec("three")
+ addSpec(one)
+ addSpec(two)
+ addSpec(three)
+ assertEquals(findSpec("one"), one)
+ assertEquals(findSpec("two"), two)
+ assertEquals(findSpec("three"), three)
+ assertNull(findSpec("abc"))
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIRepository.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIRepository.kt
new file mode 100644
index 000000000000..cdc524aff09f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIRepository.kt
@@ -0,0 +1,39 @@
+/*
+ * 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.wm.shell.compatui.impl
+
+import com.android.wm.shell.compatui.api.CompatUIRepository
+import com.android.wm.shell.compatui.api.CompatUISpec
+
+/**
+ * Fake implementation for {@link CompatUIRepository}
+ */
+class FakeCompatUIRepository : CompatUIRepository {
+ val allSpecs = mutableMapOf<String, CompatUISpec>()
+ override fun addSpec(spec: CompatUISpec) {
+ if (findSpec(spec.name) != null) {
+ throw IllegalStateException("Spec with name:${spec.name} already present")
+ }
+ allSpecs[spec.name] = spec
+ }
+
+ override fun iterateOn(fn: (CompatUISpec) -> Unit) =
+ allSpecs.values.forEach(fn)
+
+ override fun findSpec(name: String): CompatUISpec? =
+ allSpecs[name]
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
index 665bed0c8a88..d4596396840e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
@@ -52,7 +52,7 @@ import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_KEYBOARD_SHORTCUT
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_TASK_DRAG
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_UNKNOWN
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.TransitionInfoBuilder
import com.android.wm.shell.transition.Transitions
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
index 6612aee0cd12..18b08bfb0f47 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
@@ -337,65 +337,65 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
- fun getVisibleTaskCount() {
+ fun visibleTaskCount_defaultDisplay_returnsCorrectCount() {
// No tasks, count is 0
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
// New task increments count to 1
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
// Visibility update to same task does not increase count
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
// Second task visible increments count
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2)
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2)
// Hiding a task decrements count
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = false)
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
// Hiding all tasks leaves count at 0
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = false)
- assertThat(repo.getVisibleTaskCount(displayId = 9)).isEqualTo(0)
+ assertThat(repo.visibleTaskCount(displayId = 9)).isEqualTo(0)
// Hiding a not existing task, count remains at 0
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 999, visible = false)
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
}
@Test
- fun getVisibleTaskCount_multipleDisplays() {
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
- assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
+ fun visibleTaskCount_multipleDisplays_returnsCorrectCount() {
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
// New task on default display increments count for that display only
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
- assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+ assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
// New task on secondary display, increments count for that display only
repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 2, visible = true)
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
- assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+ assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
// Marking task visible on another display, updates counts for both displays
repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 1, visible = true)
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
- assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
// Marking task that is on secondary display, hidden on default display, does not affect
// secondary display
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = false)
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
- assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
// Hiding a task on that display, decrements count
repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 1, visible = false)
- assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
- assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
+ assertThat(repo.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ assertThat(repo.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
}
@Test
@@ -494,28 +494,6 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
}
@Test
- fun isDesktopModeShowing_noActiveTasks_returnsFalse() {
- assertThat(repo.isDesktopModeShowing(displayId = 0)).isFalse()
- }
-
- @Test
- fun isDesktopModeShowing_noTasksVisible_returnsFalse() {
- repo.addActiveTask(displayId = 0, taskId = 1)
- repo.addActiveTask(displayId = 0, taskId = 2)
-
- assertThat(repo.isDesktopModeShowing(displayId = 0)).isFalse()
- }
-
- @Test
- fun isDesktopModeShowing_tasksActiveAndVisible_returnsTrue() {
- repo.addActiveTask(displayId = 0, taskId = 1)
- repo.addActiveTask(displayId = 0, taskId = 2)
- repo.updateVisibleFreeformTasks(displayId = 0, taskId = 1, visible = true)
-
- assertThat(repo.isDesktopModeShowing(displayId = 0)).isTrue()
- }
-
- @Test
fun getActiveNonMinimizedTasksOrderedFrontToBack_returnsFreeformTasksInCorrectOrder() {
repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 1)
repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 2)
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 0bcbe139e31f..da886863cc1f 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
@@ -67,6 +67,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.ExtendedMockito.never
import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.window.flags.Flags
+import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
import com.android.wm.shell.MockToken
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
@@ -89,7 +90,7 @@ import com.android.wm.shell.draganddrop.DragAndDropController
import com.android.wm.shell.recents.RecentTasksController
import com.android.wm.shell.recents.RecentsTransitionHandler
import com.android.wm.shell.recents.RecentsTransitionStateListener
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.sysui.ShellCommandHandler
import com.android.wm.shell.sysui.ShellController
@@ -124,11 +125,11 @@ import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.mock
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.atLeastOnce
import org.mockito.kotlin.capture
import org.mockito.quality.Strictness
+import org.mockito.Mockito.`when` as whenever
/**
* Test class for {@link DesktopTasksController}
@@ -137,6 +138,7 @@ import org.mockito.quality.Strictness
*/
@SmallTest
@RunWith(AndroidTestingRunner::class)
+@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
class DesktopTasksControllerTest : ShellTestCase() {
@JvmField @Rule val setFlagsRule = SetFlagsRule()
@@ -193,7 +195,6 @@ class DesktopTasksControllerTest : ShellTestCase() {
.strictness(Strictness.LENIENT)
.spyStatic(DesktopModeStatus::class.java)
.startMocking()
- whenever(DesktopModeStatus.isDesktopModeFlagEnabled()).thenReturn(true)
doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
shellInit = spy(ShellInit(testExecutor))
@@ -263,8 +264,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun instantiate_flagOff_doNotAddInitCallback() {
- whenever(DesktopModeStatus.isDesktopModeFlagEnabled()).thenReturn(false)
+ fun instantiate_canNotEnterDesktopMode_doNotAddInitCallback() {
+ whenever(DesktopModeStatus.canEnterDesktopMode(context)).thenReturn(false)
clearInvocations(shellInit)
createController()
@@ -310,6 +311,50 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ fun isDesktopModeShowing_noTasks_returnsFalse() {
+ assertThat(controller.isDesktopModeShowing(displayId = 0)).isFalse()
+ }
+
+ @Test
+ fun isDesktopModeShowing_noTasksVisible_returnsFalse() {
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+ markTaskHidden(task1)
+ markTaskHidden(task2)
+
+ assertThat(controller.isDesktopModeShowing(displayId = 0)).isFalse()
+ }
+
+ @Test
+ fun isDesktopModeShowing_tasksActiveAndVisible_returnsTrue() {
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+ markTaskVisible(task1)
+ markTaskHidden(task2)
+
+ assertThat(controller.isDesktopModeShowing(displayId = 0)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun showDesktopApps_onSecondaryDisplay_desktopWallpaperEnabled_shouldNotShowWallpaper() {
+ val homeTask = setUpHomeTask(SECOND_DISPLAY)
+ val task1 = setUpFreeformTask(SECOND_DISPLAY)
+ val task2 = setUpFreeformTask(SECOND_DISPLAY)
+ markTaskHidden(task1)
+ markTaskHidden(task2)
+
+ controller.showDesktopApps(SECOND_DISPLAY, RemoteTransition(TestRemoteTransition()))
+
+ val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
+ assertThat(wct.hierarchyOps).hasSize(3)
+ // Expect order to be from bottom: home, task1, task2 (no wallpaper intent)
+ wct.assertReorderAt(index = 0, homeTask)
+ wct.assertReorderAt(index = 1, task1)
+ wct.assertReorderAt(index = 2, task2)
+ }
+
+ @Test
@DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
fun showDesktopApps_appsAlreadyVisible_bringsToFront_desktopWallpaperDisabled() {
val homeTask = setUpHomeTask()
@@ -329,6 +374,25 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun showDesktopApps_onSecondaryDisplay_desktopWallpaperDisabled_shouldNotMoveLauncher() {
+ val homeTask = setUpHomeTask(SECOND_DISPLAY)
+ val task1 = setUpFreeformTask(SECOND_DISPLAY)
+ val task2 = setUpFreeformTask(SECOND_DISPLAY)
+ markTaskHidden(task1)
+ markTaskHidden(task2)
+
+ controller.showDesktopApps(SECOND_DISPLAY, RemoteTransition(TestRemoteTransition()))
+
+ val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
+ assertThat(wct.hierarchyOps).hasSize(3)
+ // Expect order to be from bottom: home, task1, task2
+ wct.assertReorderAt(index = 0, homeTask)
+ wct.assertReorderAt(index = 1, task1)
+ wct.assertReorderAt(index = 2, task2)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
fun showDesktopApps_appsAlreadyVisible_bringsToFront_desktopWallpaperEnabled() {
val task1 = setUpFreeformTask()
@@ -426,6 +490,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
fun showDesktopApps_twoDisplays_bringsToFrontOnlyOneDisplay_desktopWallpaperEnabled() {
+ val homeTaskDefaultDisplay = setUpHomeTask(DEFAULT_DISPLAY)
val taskDefaultDisplay = setUpFreeformTask(DEFAULT_DISPLAY)
setUpHomeTask(SECOND_DISPLAY)
val taskSecondDisplay = setUpFreeformTask(SECOND_DISPLAY)
@@ -435,10 +500,13 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition()))
val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
- assertThat(wct.hierarchyOps).hasSize(2)
- // Expect order to be from bottom: wallpaper intent, task
- wct.assertPendingIntentAt(index = 0, desktopWallpaperIntent)
- wct.assertReorderAt(index = 1, taskDefaultDisplay)
+ assertThat(wct.hierarchyOps).hasSize(3)
+ // Move home to front
+ wct.assertReorderAt(index = 0, homeTaskDefaultDisplay)
+ // Add desktop wallpaper activity
+ wct.assertPendingIntentAt(index = 1, desktopWallpaperIntent)
+ // Move freeform task to front
+ wct.assertReorderAt(index = 2, taskDefaultDisplay)
}
@Test
@@ -463,7 +531,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
fun showDesktopApps_desktopWallpaperEnabled_dontReorderMinimizedTask() {
- setUpHomeTask()
+ val homeTask = setUpHomeTask()
val freeformTask = setUpFreeformTask()
val minimizedTask = setUpFreeformTask()
@@ -473,40 +541,42 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition()))
val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
- assertThat(wct.hierarchyOps).hasSize(2)
+ assertThat(wct.hierarchyOps).hasSize(3)
+ // Move home to front
+ wct.assertReorderAt(index = 0, homeTask, toTop = true)
// Add desktop wallpaper activity
- wct.assertPendingIntentAt(index = 0, desktopWallpaperIntent)
+ wct.assertPendingIntentAt(index = 1, desktopWallpaperIntent)
// Reorder freeform task to top, don't reorder the minimized task
- wct.assertReorderAt(index = 1, freeformTask, toTop = true)
+ wct.assertReorderAt(index = 2, freeformTask, toTop = true)
}
@Test
- fun getVisibleTaskCount_noTasks_returnsZero() {
- assertThat(controller.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+ fun visibleTaskCount_noTasks_returnsZero() {
+ assertThat(controller.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
}
@Test
- fun getVisibleTaskCount_twoTasks_bothVisible_returnsTwo() {
+ fun visibleTaskCount_twoTasks_bothVisible_returnsTwo() {
setUpHomeTask()
setUpFreeformTask().also(::markTaskVisible)
setUpFreeformTask().also(::markTaskVisible)
- assertThat(controller.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2)
+ assertThat(controller.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2)
}
@Test
- fun getVisibleTaskCount_twoTasks_oneVisible_returnsOne() {
+ fun visibleTaskCount_twoTasks_oneVisible_returnsOne() {
setUpHomeTask()
setUpFreeformTask().also(::markTaskVisible)
setUpFreeformTask().also(::markTaskHidden)
- assertThat(controller.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+ assertThat(controller.visibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
}
@Test
- fun getVisibleTaskCount_twoTasksVisibleOnDifferentDisplays_returnsOne() {
+ fun visibleTaskCount_twoTasksVisibleOnDifferentDisplays_returnsOne() {
setUpHomeTask()
setUpFreeformTask(DEFAULT_DISPLAY).also(::markTaskVisible)
setUpFreeformTask(SECOND_DISPLAY).also(::markTaskVisible)
- assertThat(controller.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
+ assertThat(controller.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
}
@Test
@@ -700,19 +770,37 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun moveToDesktop_topActivityTranslucent_doesNothing() {
- setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun moveToDesktop_topActivityTranslucentWithStyleFloating_taskIsMovedToDesktop() {
val task =
- setUpFullscreenTask().apply {
- isTopActivityTransparent = true
- numActivities = 1
- }
+ setUpFullscreenTask().apply {
+ isTopActivityTransparent = true
+ isTopActivityStyleFloating = true
+ numActivities = 1
+ }
+
+ controller.moveToDesktop(task, transitionSource = UNKNOWN)
+
+ val wct = getLatestEnterDesktopWct()
+ assertThat(wct.changes[task.token.asBinder()]?.windowingMode).isEqualTo(WINDOWING_MODE_FREEFORM)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun moveToDesktop_topActivityTranslucentWithoutStyleFloating_doesNothing() {
+ val task =
+ setUpFullscreenTask().apply {
+ isTopActivityTransparent = true
+ isTopActivityStyleFloating = false
+ numActivities = 1
+ }
controller.moveToDesktop(task, transitionSource = UNKNOWN)
verifyEnterDesktopWCTNotExecuted()
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
fun moveToDesktop_systemUIActivity_doesNothing() {
val task = setUpFullscreenTask()
@@ -842,16 +930,19 @@ class DesktopTasksControllerTest : ShellTestCase() {
val taskLimit = desktopTasksLimiter.getMaxTaskLimit()
val freeformTasks = (1..taskLimit).map { _ -> setUpFreeformTask() }
val newTask = setUpFullscreenTask()
- setUpHomeTask()
+ val homeTask = setUpHomeTask()
controller.moveToDesktop(newTask, transitionSource = UNKNOWN)
val wct = getLatestEnterDesktopWct()
- assertThat(wct.hierarchyOps.size).isEqualTo(taskLimit + 1) // visible tasks + wallpaper
+ assertThat(wct.hierarchyOps.size).isEqualTo(taskLimit + 2) // tasks + home + wallpaper
+ // Move home to front
+ wct.assertReorderAt(0, homeTask)
// Add desktop wallpaper activity
- wct.assertPendingIntentAt(0, desktopWallpaperIntent)
+ wct.assertPendingIntentAt(1, desktopWallpaperIntent)
+ // Bring freeform tasks to front
wct.assertReorderSequenceInRange(
- range = 1..<(taskLimit + 1),
+ range = 2..<(taskLimit + 2),
*freeformTasks.drop(1).toTypedArray(), // Skipping freeformTasks[0]
newTask
)
@@ -869,6 +960,24 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ fun moveToFullscreen_tdaFullscreen_windowingModeUndefined_removesWallpaperActivity() {
+ val task = setUpFreeformTask()
+ val wallpaperToken = MockToken().token()
+
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY))
+ .configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
+
+ controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val taskChange = assertNotNull(wct.changes[task.token.asBinder()])
+ assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED)
+ // Removes wallpaper activity when leaving desktop
+ wct.assertRemoveAt(index = 0, wallpaperToken)
+ }
+
+ @Test
fun moveToFullscreen_tdaFreeform_windowingModeSetToFullscreen() {
val task = setUpFreeformTask()
val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
@@ -880,6 +989,44 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ fun moveToFullscreen_tdaFreeform_windowingModeFullscreen_removesWallpaperActivity() {
+ val task = setUpFreeformTask()
+ val wallpaperToken = MockToken().token()
+
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY))
+ .configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM
+
+ controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val taskChange = assertNotNull(wct.changes[task.token.asBinder()])
+ assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_FULLSCREEN)
+ // Removes wallpaper activity when leaving desktop
+ wct.assertRemoveAt(index = 0, wallpaperToken)
+ }
+
+ @Test
+ fun moveToFullscreen_multipleVisibleNonMinimizedTasks_doesNotRemoveWallpaperActivity() {
+ val task1 = setUpFreeformTask()
+ // Setup task2
+ setUpFreeformTask()
+ val wallpaperToken = MockToken().token()
+
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY))
+ .configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
+
+ controller.moveToFullscreen(task1.taskId, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val task1Change = assertNotNull(wct.changes[task1.token.asBinder()])
+ assertThat(task1Change.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED)
+ // Does not remove wallpaper activity, as desktop still has a visible desktop task
+ assertThat(wct.hierarchyOps).isEmpty()
+ }
+
+ @Test
fun moveToFullscreen_nonExistentTask_doesNothing() {
controller.moveToFullscreen(999, transitionSource = UNKNOWN)
verifyExitDesktopWCTNotExecuted()
@@ -1087,13 +1234,19 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun handleRequest_fullscreenTask_freeformVisible_returnSwitchToFreeformWCT() {
assumeTrue(ENABLE_SHELL_TRANSITIONS)
+ val homeTask = setUpHomeTask()
val freeformTask = setUpFreeformTask()
markTaskVisible(freeformTask)
val fullscreenTask = createFullscreenTask()
- val result = controller.handleRequest(Binder(), createTransition(fullscreenTask))
- assertThat(result?.changes?.get(fullscreenTask.token.asBinder())?.windowingMode)
+ val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask))
+
+ assertNotNull(wct, "should handle request")
+ assertThat(wct.changes[fullscreenTask.token.asBinder()]?.windowingMode)
.isEqualTo(WINDOWING_MODE_FREEFORM)
+
+ assertThat(wct.hierarchyOps).hasSize(2)
+ wct.assertReorderAt(1, homeTask, toTop = false)
}
@Test
@@ -1323,7 +1476,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
.setActivityType(ACTIVITY_TYPE_STANDARD)
.setWindowingMode(WINDOWING_MODE_FULLSCREEN)
.build()
- val transition = createTransition(task = task, type = WindowManager.TRANSIT_CLOSE)
+ val transition = createTransition(task = task, type = TRANSIT_CLOSE)
val result = controller.handleRequest(Binder(), transition)
assertThat(result).isNull()
}
@@ -1368,20 +1521,40 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun handleRequest_shouldLaunchAsModal_returnSwitchToFullscreenWCT() {
- setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun handleRequest_topActivityTransparentWithStyleFloating_returnSwitchToFreeformWCT() {
+ val freeformTask = setUpFreeformTask()
+ markTaskVisible(freeformTask)
+
val task =
- setUpFreeformTask().apply {
- isTopActivityTransparent = true
- numActivities = 1
- }
+ setUpFullscreenTask().apply {
+ isTopActivityTransparent = true
+ isTopActivityStyleFloating = true
+ numActivities = 1
+ }
val result = controller.handleRequest(Binder(), createTransition(task))
assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode)
- .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
+ .isEqualTo(WINDOWING_MODE_FREEFORM)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun handleRequest_topActivityTransparentWithoutStyleFloating_returnSwitchToFullscreenWCT() {
+ val task =
+ setUpFreeformTask().apply {
+ isTopActivityTransparent = true
+ isTopActivityStyleFloating = false
+ numActivities = 1
+ }
+
+ val result = controller.handleRequest(Binder(), createTransition(task))
+ assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode)
+ .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
fun handleRequest_systemUIActivity_returnSwitchToFullscreenWCT() {
val task = setUpFreeformTask()
@@ -1397,8 +1570,11 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_backTransition_singleActiveTaskNoTokenFlagDisabled_doesNotHandle() {
+ @DisableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION,
+ )
+ fun handleRequest_backTransition_singleActiveTaskNoToken_wallpaperDisabled_backNavDisabled_doesNotHandle() {
val task = setUpFreeformTask()
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
@@ -1407,8 +1583,22 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_backTransition_singleActiveTaskNoToken_wallpaperEnabled_backNavEnabled_removesTask() {
+ val task = setUpFreeformTask()
+
+ val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
+
+ assertNotNull(result, "Should handle request").assertRemoveAt(0, task.token)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_backTransition_singleActiveTaskNoTokenFlagEnabled_doesNotHandle() {
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
+ fun handleRequest_backTransition_singleActiveTaskNoToken_backNavigationDisabled_doesNotHandle() {
val task = setUpFreeformTask()
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
@@ -1417,8 +1607,11 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_backTransition_singleActiveTaskWithTokenFlagDisabled_doesNotHandle() {
+ @DisableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_backTransition_singleActiveTaskWithToken_wallpaperDisabled_backNavDisabled_doesNotHandle() {
val task = setUpFreeformTask()
desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
@@ -1428,22 +1621,42 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_backTransition_singleActiveTaskWithToken_wallpaperEnabled_backNavEnabled_removesWallpaperAndTask() {
+ val task = setUpFreeformTask()
+ val wallpaperToken = MockToken().token()
+
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
+
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
+ result.assertRemoveAt(index = 1, task.token)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_backTransition_singleActiveTaskWithTokenFlagEnabled_handlesRequest() {
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
+ fun handleRequest_backTransition_singleActiveTaskWithToken_backNavigationDisabled_removesWallpaper() {
val task = setUpFreeformTask()
val wallpaperToken = MockToken().token()
desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
- assertNotNull(result, "Should handle request")
- // Should create remove wallpaper transaction
- .assertRemoveAt(index = 0, wallpaperToken)
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_backTransition_multipleActiveTasksFlagDisabled_doesNotHandle() {
+ @DisableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_backTransition_multipleTasks_wallpaperDisabled_backNavDisabled_doesNotHandle() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
@@ -1454,8 +1667,24 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_backTransition_multipleTasks_wallpaperEnabled_backNavEnabled_removesTask() {
+ val task1 = setUpFreeformTask()
+ setUpFreeformTask()
+
+ desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+ val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
+
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, task1.token)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_backTransition_multipleActiveTasksFlagEnabled_doesNotHandle() {
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
+ fun handleRequest_backTransition_multipleTasks_backNavigationDisabled_doesNotHandle() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
@@ -1466,8 +1695,28 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_backTransition_multipleTasksSingleNonClosing_wallpaperEnabled_backNavEnabled_removesWallpaperAndTask() {
+ val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val wallpaperToken = MockToken().token()
+
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ desktopModeTaskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
+
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
+ result.assertRemoveAt(index = 1, task1.token)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_backTransition_multipleActiveTasksSingleNonClosing_handlesRequest() {
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
+ fun handleRequest_backTransition_multipleTasksSingleNonClosing_backNavigationDisabled_removesWallpaper() {
val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
@@ -1476,14 +1725,33 @@ class DesktopTasksControllerTest : ShellTestCase() {
desktopModeTaskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
- assertNotNull(result, "Should handle request")
- // Should create remove wallpaper transaction
- .assertRemoveAt(index = 0, wallpaperToken)
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
+ }
+
+ @Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_backTransition_multipleTasksSingleNonMinimized_wallpaperEnabled_backNavEnabled_removesWallpaperAndTask() {
+ val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val wallpaperToken = MockToken().token()
+
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
+
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
+ result.assertRemoveAt(index = 1, task1.token)
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_backTransition_multipleActiveTasksSingleNonMinimized_handlesRequest() {
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
+ fun handleRequest_backTransition_multipleTasksSingleNonMinimized_backNavigationDisabled_removesWallpaper() {
val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
@@ -1492,14 +1760,36 @@ class DesktopTasksControllerTest : ShellTestCase() {
desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
- assertNotNull(result, "Should handle request")
- // Should create remove wallpaper transaction
- .assertRemoveAt(index = 0, wallpaperToken)
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_closeTransition_singleActiveTaskNoTokenFlagDisabled_doesNotHandle() {
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_backTransition_nonMinimizadTask_wallpaperEnabled_backNavEnabled_removesWallpaper() {
+ val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val wallpaperToken = MockToken().token()
+
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ // Task is being minimized so mark it as not visible.
+ desktopModeTaskRepository
+ .updateVisibleFreeformTasks(displayId = DEFAULT_DISPLAY, task2.taskId, false)
+ val result = controller.handleRequest(Binder(), createTransition(task2, type = TRANSIT_TO_BACK))
+
+ assertNull(result, "Should not handle request")
+ }
+
+ @Test
+ @DisableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_closeTransition_singleActiveTaskNoToken_wallpaperDisabled_backNavDisabled_doesNotHandle() {
val task = setUpFreeformTask()
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
@@ -1508,8 +1798,22 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_closeTransition_singleActiveTaskNoToken_wallpaperEnabled_backNavEnabled_removesTask() {
+ val task = setUpFreeformTask()
+
+ val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
+
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, task.token)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_closeTransition_singleActiveTaskNoTokenFlagEnabled_doesNotHandle() {
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
+ fun handleRequest_closeTransition_singleActiveTaskNoToken_backNavigationDisabled_doesNotHandle() {
val task = setUpFreeformTask()
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
@@ -1518,8 +1822,11 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_closeTransition_singleActiveTaskWithTokenFlagDisabled_doesNotHandle() {
+ @DisableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_closeTransition_singleActiveTaskWithToken_wallpaperDisabled_backNavDisabled_doesNotHandle() {
val task = setUpFreeformTask()
desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
@@ -1529,22 +1836,42 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_closeTransition_singleActiveTaskWithToken_wallpaperEnabled_backNavEnabled_removesWallpaperAndTask() {
+ val task = setUpFreeformTask()
+ val wallpaperToken = MockToken().token()
+
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
+
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
+ result.assertRemoveAt(index = 1, task.token)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_closeTransition_singleActiveTaskWithTokenFlagEnabled_handlesRequest() {
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
+ fun handleRequest_closeTransition_singleActiveTaskWithToken_backNavigationDisabled_removesWallpaper() {
val task = setUpFreeformTask()
val wallpaperToken = MockToken().token()
desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
- assertNotNull(result, "Should handle request")
- // Should create remove wallpaper transaction
- .assertRemoveAt(index = 0, wallpaperToken)
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_closeTransition_multipleActiveTasksFlagDisabled_doesNotHandle() {
+ @DisableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_closeTransition_multipleTasks_wallpaperDisabled_backNavDisabled_doesNotHandle() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
@@ -1555,8 +1882,25 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_closeTransition_multipleTasks_wallpaperEnabled_backNavEnabled_removesTask() {
+ val task1 = setUpFreeformTask()
+ setUpFreeformTask()
+
+ desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+ val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
+
+ assertNotNull(result, "Should handle request")
+ result.assertRemoveAt(index = 0, task1.token)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_closeTransition_multipleActiveTasksFlagEnabled_doesNotHandle() {
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
+ fun handleRequest_closeTransition_multipleTasksFlagEnabled_backNavigationDisabled_doesNotHandle() {
val task1 = setUpFreeformTask()
setUpFreeformTask()
@@ -1567,8 +1911,28 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_closeTransition_multipleTasksSingleNonClosing_wallpaperEnabled_backNavEnabled_removesWallpaperAndTask() {
+ val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val wallpaperToken = MockToken().token()
+
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ desktopModeTaskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
+
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
+ result.assertRemoveAt(index = 1, task1.token)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_closeTransition_multipleActiveTasksSingleNonClosing_handlesRequest() {
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
+ fun handleRequest_closeTransition_multipleTasksSingleNonClosing_backNavigationDisabled_removesWallpaper() {
val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
@@ -1577,14 +1941,33 @@ class DesktopTasksControllerTest : ShellTestCase() {
desktopModeTaskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
- assertNotNull(result, "Should handle request")
- // Should create remove wallpaper transaction
- .assertRemoveAt(index = 0, wallpaperToken)
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
+ }
+
+ @Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_closeTransition_multipleTasksOneNonMinimized_wallpaperEnabled_backNavEnabled_removesWallpaperAndTask() {
+ val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val wallpaperToken = MockToken().token()
+
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
+
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
+ result.assertRemoveAt(index = 1, task1.token)
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
- fun handleRequest_closeTransition_multipleActiveTasksSingleNonMinimized_handlesRequest() {
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION)
+ fun handleRequest_closeTransition_multipleTasksSingleNonMinimized_backNavigationDisabled_removesWallpaper() {
val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
val wallpaperToken = MockToken().token()
@@ -1593,9 +1976,28 @@ class DesktopTasksControllerTest : ShellTestCase() {
desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
- assertNotNull(result, "Should handle request")
- // Should create remove wallpaper transaction
- .assertRemoveAt(index = 0, wallpaperToken)
+ // Should create remove wallpaper transaction
+ assertNotNull(result, "Should handle request").assertRemoveAt(index = 0, wallpaperToken)
+ }
+
+ @Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
+ )
+ fun handleRequest_closeTransition_minimizadTask_wallpaperEnabled_backNavEnabled_removesWallpaper() {
+ val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val wallpaperToken = MockToken().token()
+
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+ // Task is being minimized so mark it as not visible.
+ desktopModeTaskRepository
+ .updateVisibleFreeformTasks(displayId = DEFAULT_DISPLAY, task2.taskId, false)
+ val result = controller.handleRequest(Binder(), createTransition(task2, type = TRANSIT_TO_BACK))
+
+ assertNull(result, "Should not handle request")
}
@Test
@@ -1677,6 +2079,49 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ fun moveFocusedTaskToFullscreen_onlyVisibleNonMinimizedTask_removesWallpaperActivity() {
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+ val task3 = setUpFreeformTask()
+ val wallpaperToken = MockToken().token()
+
+ task1.isFocused = false
+ task2.isFocused = true
+ task3.isFocused = false
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, task1.taskId)
+ desktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task3.taskId,
+ visible = false)
+
+ controller.enterFullscreen(DEFAULT_DISPLAY, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val taskChange = assertNotNull(wct.changes[task2.token.asBinder()])
+ assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
+ wct.assertRemoveAt(index = 0, wallpaperToken)
+ }
+
+ @Test
+ fun moveFocusedTaskToFullscreen_multipleVisibleTasks_doesNotRemoveWallpaperActivity() {
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+ val task3 = setUpFreeformTask()
+ val wallpaperToken = MockToken().token()
+
+ task1.isFocused = false
+ task2.isFocused = true
+ task3.isFocused = false
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ controller.enterFullscreen(DEFAULT_DISPLAY, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ val taskChange = assertNotNull(wct.changes[task2.token.asBinder()])
+ assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
+ // Does not remove wallpaper activity, as desktop still has visible desktop tasks
+ assertThat(wct.hierarchyOps).isEmpty()
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
fun dragToDesktop_landscapeDevice_resizable_undefinedOrientation_defaultLandscapeBounds() {
val spyController = spy(controller)
@@ -1885,6 +2330,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
eq(null))
}
+ @Test
fun enterSplit_freeformTaskIsMovedToSplit() {
val task1 = setUpFreeformTask()
val task2 = setUpFreeformTask()
@@ -1894,14 +2340,67 @@ class DesktopTasksControllerTest : ShellTestCase() {
task2.isFocused = true
task3.isFocused = false
- controller.enterSplit(DEFAULT_DISPLAY, false)
+ controller.enterSplit(DEFAULT_DISPLAY, leftOrTop = false)
verify(splitScreenController)
.requestEnterSplitSelect(
- task2,
+ eq(task2),
any(),
- SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT,
- task2.configuration.windowConfiguration.bounds)
+ eq(SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT),
+ eq(task2.configuration.windowConfiguration.bounds))
+ }
+
+ @Test
+ fun enterSplit_onlyVisibleNonMinimizedTask_removesWallpaperActivity() {
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+ val task3 = setUpFreeformTask()
+ val wallpaperToken = MockToken().token()
+
+ task1.isFocused = false
+ task2.isFocused = true
+ task3.isFocused = false
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+ desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, task1.taskId)
+ desktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task3.taskId,
+ visible = false)
+
+ controller.enterSplit(DEFAULT_DISPLAY, leftOrTop = false)
+
+ val wctArgument = ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
+ verify(splitScreenController)
+ .requestEnterSplitSelect(
+ eq(task2),
+ wctArgument.capture(),
+ eq(SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT),
+ eq(task2.configuration.windowConfiguration.bounds))
+ // Removes wallpaper activity when leaving desktop
+ wctArgument.value.assertRemoveAt(index = 0, wallpaperToken)
+ }
+
+ @Test
+ fun enterSplit_multipleVisibleNonMinimizedTasks_removesWallpaperActivity() {
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+ val task3 = setUpFreeformTask()
+ val wallpaperToken = MockToken().token()
+
+ task1.isFocused = false
+ task2.isFocused = true
+ task3.isFocused = false
+ desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+
+ controller.enterSplit(DEFAULT_DISPLAY, leftOrTop = false)
+
+ val wctArgument = ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
+ verify(splitScreenController)
+ .requestEnterSplitSelect(
+ eq(task2),
+ wctArgument.capture(),
+ eq(SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT),
+ eq(task2.configuration.windowConfiguration.bounds))
+ // Does not remove wallpaper activity, as desktop still has visible desktop tasks
+ assertThat(wctArgument.value.hierarchyOps).isEmpty()
}
@Test
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 77f917cc28d8..8d9fd9166050 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
@@ -24,6 +24,7 @@ import android.view.Display.DEFAULT_DISPLAY
import android.view.WindowManager.TRANSIT_OPEN
import android.view.WindowManager.TRANSIT_TO_BACK
import android.window.WindowContainerTransaction
+import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_TASK
import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER
import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito
@@ -32,7 +33,7 @@ import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.transition.TransitionInfoBuilder
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.util.StubTransaction
@@ -205,6 +206,46 @@ class DesktopTasksLimiterTest : ShellTestCase() {
}
@Test
+ fun removeLeftoverMinimizedTasks_activeNonMinimizedTasksStillAround_doesNothing() {
+ desktopTaskRepo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 1)
+ desktopTaskRepo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 2)
+ desktopTaskRepo.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = 2)
+
+ val wct = WindowContainerTransaction()
+ desktopTasksLimiter.leftoverMinimizedTasksRemover.removeLeftoverMinimizedTasks(
+ DEFAULT_DISPLAY, wct)
+
+ assertThat(wct.isEmpty).isTrue()
+ }
+
+ @Test
+ fun removeLeftoverMinimizedTasks_noMinimizedTasks_doesNothing() {
+ val wct = WindowContainerTransaction()
+ desktopTasksLimiter.leftoverMinimizedTasksRemover.removeLeftoverMinimizedTasks(
+ DEFAULT_DISPLAY, wct)
+
+ assertThat(wct.isEmpty).isTrue()
+ }
+
+ @Test
+ fun removeLeftoverMinimizedTasks_onlyMinimizedTasksLeft_removesAllMinimizedTasks() {
+ val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ desktopTaskRepo.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task1.taskId)
+ desktopTaskRepo.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+
+ val wct = WindowContainerTransaction()
+ desktopTasksLimiter.leftoverMinimizedTasksRemover.removeLeftoverMinimizedTasks(
+ DEFAULT_DISPLAY, wct)
+
+ assertThat(wct.hierarchyOps).hasSize(2)
+ assertThat(wct.hierarchyOps[0].type).isEqualTo(HIERARCHY_OP_TYPE_REMOVE_TASK)
+ assertThat(wct.hierarchyOps[0].container).isEqualTo(task1.token.asBinder())
+ assertThat(wct.hierarchyOps[1].type).isEqualTo(HIERARCHY_OP_TYPE_REMOVE_TASK)
+ assertThat(wct.hierarchyOps[1].container).isEqualTo(task2.token.asBinder())
+ }
+
+ @Test
fun addAndGetMinimizeTaskChangesIfNeeded_tasksWithinLimit_noTaskMinimized() {
val taskLimit = desktopTasksLimiter.getMaxTaskLimit()
(1..<taskLimit).forEach { _ -> setUpFreeformTask() }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
index b2467e9a62cf..e5157c974e2d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
@@ -45,6 +45,7 @@ import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource;
@@ -65,6 +66,8 @@ public class ExitDesktopTaskTransitionHandlerTest extends ShellTestCase {
@Mock
private Transitions mTransitions;
@Mock
+ private InteractionJankMonitor mInteractionJankMonitor;
+ @Mock
IBinder mToken;
@Mock
Supplier<SurfaceControl.Transaction> mTransactionFactory;
@@ -94,7 +97,7 @@ public class ExitDesktopTaskTransitionHandlerTest extends ShellTestCase {
.thenReturn(getContext().getResources().getDisplayMetrics());
mExitDesktopTaskTransitionHandler = new ExitDesktopTaskTransitionHandler(mTransitions,
- mContext);
+ mContext, mInteractionJankMonitor);
mPoint = new Point(0, 0);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
index 582fb91559e5..97fa8d6ceca9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
@@ -289,9 +289,9 @@ public class DragAndDropPolicyTest extends ShellTestCase {
ArrayList<Target> targets = assertExactTargetTypes(
mPolicy.getTargets(mInsets), TYPE_FULLSCREEN);
- mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN));
+ mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), null /* hideTaskToken */);
verify(mFullscreenStarter).startIntent(any(), anyInt(), any(),
- eq(SPLIT_POSITION_UNDEFINED), any());
+ eq(SPLIT_POSITION_UNDEFINED), any(), any());
}
private void dragOverFullscreenApp_expectSplitScreenTargets(ClipData data) {
@@ -304,14 +304,14 @@ public class DragAndDropPolicyTest extends ShellTestCase {
ArrayList<Target> targets = assertExactTargetTypes(
mPolicy.getTargets(mInsets), TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT);
- mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_LEFT));
+ mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_LEFT), null /* hideTaskToken */);
verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
- eq(SPLIT_POSITION_TOP_OR_LEFT), any());
+ eq(SPLIT_POSITION_TOP_OR_LEFT), any(), any());
reset(mSplitScreenStarter);
- mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_RIGHT));
+ mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_RIGHT), null /* hideTaskToken */);
verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
- eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any());
+ eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any(), any());
}
private void dragOverFullscreenAppPhone_expectVerticalSplitScreenTargets(ClipData data) {
@@ -324,14 +324,15 @@ public class DragAndDropPolicyTest extends ShellTestCase {
ArrayList<Target> targets = assertExactTargetTypes(
mPolicy.getTargets(mInsets), TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM);
- mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_TOP));
+ mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_TOP), null /* hideTaskToken */);
verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
- eq(SPLIT_POSITION_TOP_OR_LEFT), any());
+ eq(SPLIT_POSITION_TOP_OR_LEFT), any(), any());
reset(mSplitScreenStarter);
- mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_BOTTOM));
+ mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_BOTTOM),
+ null /* hideTaskToken */);
verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
- eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any());
+ eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any(), any());
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
index 3f3cafcf6375..6ec6bed860bd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
@@ -36,7 +36,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index 75d21457b60b..6888de5472e2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -182,7 +182,7 @@ public class PipControllerTest extends ShellTestCase {
@Test
public void instantiatePipController_registersPipTransitionCallback() {
- verify(mMockPipTransitionController).registerPipTransitionCallback(any(), any());
+ verify(mMockPipTransitionController).registerPipTransitionCallback(any());
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
index 66f8c0b9558d..ace09a82d71c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
@@ -114,8 +114,8 @@ public class PipResizeGestureHandlerTest extends ShellTestCase {
final PipBoundsAlgorithm pipBoundsAlgorithm = new PipBoundsAlgorithm(mContext,
mPipBoundsState, pipSnapAlgorithm, pipKeepClearAlgorithm, mPipDisplayLayoutState,
mSizeSpecSource);
- final PipMotionHelper motionHelper = new PipMotionHelper(mContext, mMainExecutor,
- mPipBoundsState, mPipTaskOrganizer, mPhonePipMenuController, pipSnapAlgorithm,
+ final PipMotionHelper motionHelper = new PipMotionHelper(mContext, mPipBoundsState,
+ mPipTaskOrganizer, mPhonePipMenuController, pipSnapAlgorithm,
mMockPipTransitionController, mFloatingContentCoordinator,
Optional.empty() /* pipPerfHintControllerOptional */);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
index 6d18e3696f84..92762fa68550 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
@@ -116,8 +116,8 @@ public class PipTouchHandlerTest extends ShellTestCase {
mPipSnapAlgorithm = new PipSnapAlgorithm();
mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState, mPipSnapAlgorithm,
new PipKeepClearAlgorithmInterface() {}, mPipDisplayLayoutState, mSizeSpecSource);
- PipMotionHelper pipMotionHelper = new PipMotionHelper(mContext, mMainExecutor,
- mPipBoundsState, mPipTaskOrganizer, mPhonePipMenuController, mPipSnapAlgorithm,
+ PipMotionHelper pipMotionHelper = new PipMotionHelper(mContext, mPipBoundsState,
+ mPipTaskOrganizer, mPhonePipMenuController, mPipSnapAlgorithm,
mMockPipTransitionController, mFloatingContentCoordinator,
Optional.empty() /* pipPerfHintControllerOptional */);
mPipTouchHandler = new PipTouchHandler(mContext, mShellInit, mPhonePipMenuController,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index 5c5a1a26f5d2..a0aab2e6c8a4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -68,7 +68,7 @@ import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt
new file mode 100644
index 000000000000..b1d62f485a2a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt
@@ -0,0 +1,456 @@
+/*
+ * 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.wm.shell.shared.desktopmode
+
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import android.provider.Settings
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
+import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY
+import com.android.window.flags.Flags.FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.Companion.convertToToggleOverrideWithFallback
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.DESKTOP_WINDOWING_MODE
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.ToggleOverride.OVERRIDE_OFF
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.ToggleOverride.OVERRIDE_ON
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.ToggleOverride.OVERRIDE_UNSET
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.WALLPAPER_ACTIVITY
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Test class for [DesktopModeFlags]
+ *
+ * Usage: atest WMShellUnitTests:DesktopModeFlagsTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class DesktopModeFlagsTest : ShellTestCase() {
+
+ @JvmField @Rule val setFlagsRule = SetFlagsRule()
+
+ @Before
+ fun setUp() {
+ resetCache()
+ }
+
+ // TODO(b/348193756): Add tests
+ // isEnabled_flagNotOverridable_overrideOff_featureFlagOn_returnsTrue and
+ // isEnabled_flagNotOverridable_overrideOn_featureFlagOff_returnsFalse after adding non
+ // overridable flags to DesktopModeFlags.
+
+ @Test
+ @DisableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_devOptionFlagDisabled_overrideOff_featureFlagOn_returnsTrue() {
+ setOverride(OVERRIDE_OFF.setting)
+
+ // In absence of dev options, follow flag
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @DisableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_devOptionFlagDisabled_overrideOn_featureFlagOff_returnsFalse() {
+ setOverride(OVERRIDE_ON.setting)
+
+ // In absence of dev options, follow flag
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_overrideUnset_featureFlagOn_returnsTrue() {
+ setOverride(OVERRIDE_UNSET.setting)
+
+ // For overridableFlag, for unset overrides, follow flag
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_overrideUnset_featureFlagOff_returnsFalse() {
+ setOverride(OVERRIDE_UNSET.setting)
+
+ // For overridableFlag, for unset overrides, follow flag
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_noOverride_featureFlagOn_returnsTrue() {
+ setOverride(null)
+
+ // For overridableFlag, in absence of overrides, follow flag
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_noOverride_featureFlagOff_returnsFalse() {
+ setOverride(null)
+
+ // For overridableFlag, in absence of overrides, follow flag
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_unrecognizableOverride_featureFlagOn_returnsTrue() {
+ setOverride(-2)
+
+ // For overridableFlag, for recognizable overrides, follow flag
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_unrecognizableOverride_featureFlagOff_returnsFalse() {
+ setOverride(-2)
+
+ // For overridableFlag, for recognizable overrides, follow flag
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_overrideOff_featureFlagOn_returnsFalse() {
+ setOverride(OVERRIDE_OFF.setting)
+
+ // For overridableFlag, follow override if they exist
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_overrideOn_featureFlagOff_returnsTrue() {
+ setOverride(OVERRIDE_ON.setting)
+
+ // For overridableFlag, follow override if they exist
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_overrideOffThenOn_featureFlagOn_returnsFalseAndFalse() {
+ setOverride(OVERRIDE_OFF.setting)
+
+ // For overridableFlag, follow override if they exist
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+
+ setOverride(OVERRIDE_ON.setting)
+
+ // Keep overrides constant through the process
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_overrideOnThenOff_featureFlagOff_returnsTrueAndTrue() {
+ setOverride(OVERRIDE_ON.setting)
+
+ // For overridableFlag, follow override if they exist
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+
+ setOverride(OVERRIDE_OFF.setting)
+
+ // Keep overrides constant through the process
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_noSystemProperty_overrideOn_featureFlagOff_returnsTrueAndStoresPropertyOn() {
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ setOverride(OVERRIDE_ON.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ // Store System Property if not present
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_ON.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_noSystemProperty_overrideUnset_featureFlagOn_returnsTrueAndStoresPropertyUnset() {
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ setOverride(OVERRIDE_UNSET.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ // Store System Property if not present
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_UNSET.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_noSystemProperty_overrideUnset_featureFlagOff_returnsFalseAndStoresPropertyUnset() {
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ setOverride(OVERRIDE_UNSET.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ // Store System Property if not present
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_UNSET.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @Suppress("ktlint:standard:max-line-length")
+ fun isEnabled_systemPropertyNotInteger_overrideOff_featureFlagOn_returnsFalseAndStoresPropertyOff() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, "abc")
+ setOverride(OVERRIDE_OFF.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ // Store System Property if currently invalid
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_OFF.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @Suppress("ktlint:standard:max-line-length")
+ fun isEnabled_systemPropertyInvalidInteger_overrideOff_featureFlagOn_returnsFalseAndStoresPropertyOff() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, "-2")
+ setOverride(OVERRIDE_OFF.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ // Store System Property if currently invalid
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_OFF.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_systemPropertyOff_overrideOn_featureFlagOn_returnsFalseAndDoesNotUpdateProperty() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_OFF.setting.toString())
+ setOverride(OVERRIDE_ON.setting)
+
+ // Have a consistent override until reboot
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_OFF.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_systemPropertyOn_overrideOff_featureFlagOff_returnsTrueAndDoesNotUpdateProperty() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_ON.setting.toString())
+ setOverride(OVERRIDE_OFF.setting)
+
+ // Have a consistent override until reboot
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_ON.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @Suppress("ktlint:standard:max-line-length")
+ fun isEnabled_systemPropertyUnset_overrideOff_featureFlagOn_returnsTrueAndDoesNotUpdateProperty() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_UNSET.setting.toString())
+ setOverride(OVERRIDE_OFF.setting)
+
+ // Have a consistent override until reboot
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_UNSET.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(
+ FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION,
+ FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun isEnabled_dwFlagEnabled_overrideUnset_featureFlagOn_returnsTrue() {
+ setOverride(OVERRIDE_UNSET.setting)
+
+ // For unset overrides, follow flag
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun isEnabled_dwFlagEnabled_overrideUnset_featureFlagOff_returnsFalse() {
+ setOverride(OVERRIDE_UNSET.setting)
+
+ // For unset overrides, follow flag
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(
+ FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION,
+ FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun isEnabled_dwFlagEnabled_overrideOn_featureFlagOn_returnsTrue() {
+ setOverride(OVERRIDE_ON.setting)
+
+ // When toggle override matches its default state (dw flag), don't override flags
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun isEnabled_dwFlagEnabled_overrideOn_featureFlagOff_returnFalse() {
+ setOverride(OVERRIDE_ON.setting)
+
+ // When toggle override matches its default state (dw flag), don't override flags
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(
+ FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION,
+ FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun isEnabled_dwFlagEnabled_overrideOff_featureFlagOn_returnsFalse() {
+ setOverride(OVERRIDE_OFF.setting)
+
+ // Follow override if they exist, and is not equal to default toggle state (dw flag)
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun isEnabled_dwFlagEnabled_overrideOff_featureFlagOff_returnsFalse() {
+ setOverride(OVERRIDE_OFF.setting)
+
+ // Follow override if they exist, and is not equal to default toggle state (dw flag)
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(
+ FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_dwFlagDisabled_overrideUnset_featureFlagOn_returnsTrue() {
+ setOverride(OVERRIDE_UNSET.setting)
+
+ // For unset overrides, follow flag
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(
+ FLAG_ENABLE_DESKTOP_WINDOWING_MODE, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun isEnabled_dwFlagDisabled_overrideUnset_featureFlagOff_returnsFalse() {
+ setOverride(OVERRIDE_UNSET.setting)
+
+ // For unset overrides, follow flag
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(
+ FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_dwFlagDisabled_overrideOn_featureFlagOn_returnsTrue() {
+ setOverride(OVERRIDE_ON.setting)
+
+ // Follow override if they exist, and is not equal to default toggle state (dw flag)
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(
+ FLAG_ENABLE_DESKTOP_WINDOWING_MODE, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun isEnabled_dwFlagDisabled_overrideOn_featureFlagOff_returnTrue() {
+ setOverride(OVERRIDE_ON.setting)
+
+ // Follow override if they exist, and is not equal to default toggle state (dw flag)
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(
+ FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_dwFlagDisabled_overrideOff_featureFlagOn_returnsTrue() {
+ setOverride(OVERRIDE_OFF.setting)
+
+ // When toggle override matches its default state (dw flag), don't override flags
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(
+ FLAG_ENABLE_DESKTOP_WINDOWING_MODE, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun isEnabled_dwFlagDisabled_overrideOff_featureFlagOff_returnsFalse() {
+ setOverride(OVERRIDE_OFF.setting)
+
+ // When toggle override matches its default state (dw flag), don't override flags
+ assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+ }
+
+ @Test
+ fun convertToToggleOverrideWithFallback_validInt_returnsToggleOverride() {
+ assertThat(convertToToggleOverrideWithFallback(0, OVERRIDE_UNSET)).isEqualTo(OVERRIDE_OFF)
+ assertThat(convertToToggleOverrideWithFallback(1, OVERRIDE_UNSET)).isEqualTo(OVERRIDE_ON)
+ assertThat(convertToToggleOverrideWithFallback(-1, OVERRIDE_ON)).isEqualTo(OVERRIDE_UNSET)
+ }
+
+ @Test
+ fun convertToToggleOverrideWithFallback_invalidInt_returnsFallback() {
+ assertThat(convertToToggleOverrideWithFallback(2, OVERRIDE_ON)).isEqualTo(OVERRIDE_ON)
+ assertThat(convertToToggleOverrideWithFallback(-2, OVERRIDE_UNSET)).isEqualTo(OVERRIDE_UNSET)
+ }
+
+ private fun setOverride(setting: Int?) {
+ val contentResolver = mContext.contentResolver
+ val key = Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES
+ if (setting == null) {
+ Settings.Global.putString(contentResolver, key, null)
+ } else {
+ Settings.Global.putInt(contentResolver, key, setting)
+ }
+ }
+
+ private fun resetCache() {
+ val cachedToggleOverride =
+ DesktopModeFlags::class.java.getDeclaredField("cachedToggleOverride")
+ cachedToggleOverride.isAccessible = true
+ cachedToggleOverride.set(null, null)
+
+ // Clear override cache stored in System property
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ }
+
+ private companion object {
+ const val SYSTEM_PROPERTY_OVERRIDE_KEY = "sys.wmshell.desktopmode.dev_toggle_override"
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/OWNERS b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/OWNERS
new file mode 100644
index 000000000000..2fabd4a33586
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/OWNERS
@@ -0,0 +1 @@
+file:/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
index 3c387f0d7c34..5b95b1588814 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -36,6 +36,7 @@ import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -49,6 +50,9 @@ import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
+import android.os.IBinder;
+import android.window.IWindowContainerToken;
+import android.window.WindowContainerToken;
import androidx.test.annotation.UiThreadTest;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -195,10 +199,10 @@ public class SplitScreenControllerTests extends ShellTestCase {
PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
- SPLIT_POSITION_TOP_OR_LEFT, null);
+ SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
verify(mStageCoordinator).startIntent(eq(pendingIntent), mIntentCaptor.capture(),
- eq(SPLIT_POSITION_TOP_OR_LEFT), isNull());
+ eq(SPLIT_POSITION_TOP_OR_LEFT), isNull(), isNull());
assertEquals(FLAG_ACTIVITY_NO_USER_ACTION,
mIntentCaptor.getValue().getFlags() & FLAG_ACTIVITY_NO_USER_ACTION);
}
@@ -213,19 +217,20 @@ public class SplitScreenControllerTests extends ShellTestCase {
ActivityManager.RunningTaskInfo topRunningTask =
createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
+ doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask(any());
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
- SPLIT_POSITION_TOP_OR_LEFT, null);
+ SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
verify(mStageCoordinator).startIntent(eq(pendingIntent), mIntentCaptor.capture(),
- eq(SPLIT_POSITION_TOP_OR_LEFT), isNull());
+ eq(SPLIT_POSITION_TOP_OR_LEFT), isNull(), isNull());
assertEquals(FLAG_ACTIVITY_MULTIPLE_TASK,
mIntentCaptor.getValue().getFlags() & FLAG_ACTIVITY_MULTIPLE_TASK);
}
@Test
public void startIntent_multiInstancesNotSupported_startTaskInBackgroundBeforeSplitActivated() {
- doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any());
+ doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any(), any());
Intent startIntent = createStartIntent("startActivity");
PendingIntent pendingIntent =
PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
@@ -233,15 +238,16 @@ public class SplitScreenControllerTests extends ShellTestCase {
ActivityManager.RunningTaskInfo topRunningTask =
createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
+ doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask(any());
// Put the same component into a task in the background
ActivityManager.RecentTaskInfo sameTaskInfo = new ActivityManager.RecentTaskInfo();
- doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any(), anyInt());
+ doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any(), anyInt(), any());
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
- SPLIT_POSITION_TOP_OR_LEFT, null);
+ SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
- isNull());
+ isNull(), isNull());
verify(mMultiInstanceHelper, never()).supportsMultiInstanceSplit(any());
verify(mStageCoordinator, never()).switchSplitPosition(any());
}
@@ -249,7 +255,7 @@ public class SplitScreenControllerTests extends ShellTestCase {
@Test
public void startIntent_multiInstancesSupported_startTaskInBackgroundAfterSplitActivated() {
doReturn(true).when(mMultiInstanceHelper).supportsMultiInstanceSplit(any());
- doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any());
+ doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any(), any());
Intent startIntent = createStartIntent("startActivity");
PendingIntent pendingIntent =
PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
@@ -261,13 +267,13 @@ public class SplitScreenControllerTests extends ShellTestCase {
SPLIT_POSITION_BOTTOM_OR_RIGHT);
// Put the same component into a task in the background
doReturn(new ActivityManager.RecentTaskInfo()).when(mRecentTasks)
- .findTaskInBackground(any(), anyInt());
+ .findTaskInBackground(any(), anyInt(), any());
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
- SPLIT_POSITION_TOP_OR_LEFT, null);
+ SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
verify(mMultiInstanceHelper, never()).supportsMultiInstanceSplit(any());
verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
- isNull());
+ isNull(), isNull());
}
@Test
@@ -284,7 +290,7 @@ public class SplitScreenControllerTests extends ShellTestCase {
SPLIT_POSITION_BOTTOM_OR_RIGHT);
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
- SPLIT_POSITION_TOP_OR_LEFT, null);
+ SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
verify(mStageCoordinator).switchSplitPosition(anyString());
}
@@ -312,6 +318,7 @@ public class SplitScreenControllerTests extends ShellTestCase {
info.supportsMultiWindow = true;
info.baseIntent = strIntent;
info.baseActivity = strIntent.getComponent();
+ info.token = new WindowContainerToken(mock(IWindowContainerToken.class));
ActivityInfo activityInfo = new ActivityInfo();
activityInfo.packageName = info.baseActivity.getPackageName();
activityInfo.name = info.baseActivity.getClassName();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java
index 754a173ff069..6bc7e499159c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java
@@ -17,6 +17,7 @@
package com.android.wm.shell.transition;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_SLEEP;
@@ -185,6 +186,73 @@ public class DefaultTransitionHandlerTest extends ShellTestCase {
verify(startT, never()).setColor(any(), any());
}
+ @Test
+ public void startAnimation_freeformOpenChange_doesntReparentTask() {
+ final TransitionInfo.Change openChange = new ChangeBuilder(TRANSIT_OPEN)
+ .setTask(createTaskInfo(
+ /* taskId= */ 1, /* windowingMode= */ WINDOWING_MODE_FULLSCREEN))
+ .build();
+ final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(openChange)
+ .build();
+ final IBinder token = new Binder();
+ final SurfaceControl.Transaction startT = MockTransactionPool.create();
+ final SurfaceControl.Transaction finishT = MockTransactionPool.create();
+
+ mTransitionHandler.startAnimation(token, info, startT, finishT,
+ mock(Transitions.TransitionFinishCallback.class));
+
+ verify(startT, never()).reparent(any(), any());
+ }
+
+ @Test
+ public void startAnimation_freeformMinimizeChange_underFullscreenChange_doesntReparentTask() {
+ final TransitionInfo.Change openChange = new ChangeBuilder(TRANSIT_OPEN)
+ .setTask(createTaskInfo(
+ /* taskId= */ 1, /* windowingMode= */ WINDOWING_MODE_FULLSCREEN))
+ .build();
+ final TransitionInfo.Change toBackChange = new ChangeBuilder(TRANSIT_TO_BACK)
+ .setTask(createTaskInfo(
+ /* taskId= */ 2, /* windowingMode= */ WINDOWING_MODE_FREEFORM))
+ .build();
+ final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(openChange)
+ .addChange(toBackChange)
+ .build();
+ final IBinder token = new Binder();
+ final SurfaceControl.Transaction startT = MockTransactionPool.create();
+ final SurfaceControl.Transaction finishT = MockTransactionPool.create();
+
+ mTransitionHandler.startAnimation(token, info, startT, finishT,
+ mock(Transitions.TransitionFinishCallback.class));
+
+ verify(startT, never()).reparent(any(), any());
+ }
+
+ @Test
+ public void startAnimation_freeform_minimizeAnimation_reparentsTask() {
+ final TransitionInfo.Change openChange = new ChangeBuilder(TRANSIT_OPEN)
+ .setTask(createTaskInfo(
+ /* taskId= */ 1, /* windowingMode= */ WINDOWING_MODE_FREEFORM))
+ .build();
+ final TransitionInfo.Change toBackChange = new ChangeBuilder(TRANSIT_TO_BACK)
+ .setTask(createTaskInfo(
+ /* taskId= */ 2, /* windowingMode= */ WINDOWING_MODE_FREEFORM))
+ .build();
+ final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(openChange)
+ .addChange(toBackChange)
+ .build();
+ final IBinder token = new Binder();
+ final SurfaceControl.Transaction startT = MockTransactionPool.create();
+ final SurfaceControl.Transaction finishT = MockTransactionPool.create();
+
+ mTransitionHandler.startAnimation(token, info, startT, finishT,
+ mock(Transitions.TransitionFinishCallback.class));
+
+ verify(startT).reparent(any(), any());
+ }
+
private static void mergeSync(Transitions.TransitionHandler handler, IBinder token) {
handler.mergeAnimation(
new Binder(),
@@ -195,10 +263,14 @@ public class DefaultTransitionHandlerTest extends ShellTestCase {
}
private static RunningTaskInfo createTaskInfo(int taskId) {
+ return createTaskInfo(taskId, WINDOWING_MODE_FULLSCREEN);
+ }
+
+ private static RunningTaskInfo createTaskInfo(int taskId, int windowingMode) {
RunningTaskInfo taskInfo = new RunningTaskInfo();
taskInfo.taskId = taskId;
taskInfo.topActivityType = ACTIVITY_TYPE_STANDARD;
- taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(windowingMode);
taskInfo.configuration.windowConfiguration.setActivityType(taskInfo.topActivityType);
taskInfo.token = mock(WindowContainerToken.class);
return taskInfo;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
index 8331d591fd59..409b87723e79 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
@@ -1191,8 +1191,7 @@ public class ShellTransitionTests extends ShellTestCase {
mMainHandler, mAnimExecutor, mock(HomeTransitionObserver.class));
final RecentsTransitionHandler recentsHandler =
new RecentsTransitionHandler(shellInit, transitions,
- mock(RecentTasksController.class), mock(HomeTransitionObserver.class),
- () -> mock(SurfaceControl.Transaction.class));
+ mock(RecentTasksController.class), mock(HomeTransitionObserver.class));
transitions.replaceDefaultHandlerForTest(mDefaultHandler);
shellInit.init();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TransitionAnimationHelperTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TransitionAnimationHelperTest.kt
new file mode 100644
index 000000000000..bad14bbdb141
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TransitionAnimationHelperTest.kt
@@ -0,0 +1,126 @@
+/*
+ * 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.wm.shell.transition
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.app.WindowConfiguration
+import android.view.WindowManager
+import android.window.TransitionInfo
+import android.window.TransitionInfo.FLAG_TRANSLUCENT
+import com.android.internal.R
+import com.android.internal.policy.TransitionAnimation
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import org.junit.Test
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+
+class TransitionAnimationHelperTest : ShellTestCase() {
+
+ @Mock
+ lateinit var transitionAnimation: TransitionAnimation
+
+ @Test
+ fun loadAttributeAnimation_freeform_taskOpen_taskToBackChange_returnsMinimizeAnim() {
+ val openChange = ChangeBuilder(WindowManager.TRANSIT_OPEN)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FREEFORM))
+ .build()
+ val toBackChange = ChangeBuilder(WindowManager.TRANSIT_TO_BACK)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FREEFORM))
+ .build()
+ val info = TransitionInfoBuilder(WindowManager.TRANSIT_OPEN)
+ .addChange(openChange)
+ .addChange(toBackChange)
+ .build()
+
+ loadAttributeAnimation(WindowManager.TRANSIT_OPEN, info, toBackChange)
+
+ verify(transitionAnimation).loadDefaultAnimationAttr(
+ eq(R.styleable.WindowAnimation_activityCloseExitAnimation), anyBoolean())
+ }
+
+ @Test
+ fun loadAttributeAnimation_freeform_taskToFront_taskToFrontChange_returnsUnminimizeAnim() {
+ val toFrontChange = ChangeBuilder(WindowManager.TRANSIT_TO_FRONT)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FREEFORM))
+ .build()
+ val info = TransitionInfoBuilder(WindowManager.TRANSIT_TO_FRONT)
+ .addChange(toFrontChange)
+ .build()
+
+ loadAttributeAnimation(WindowManager.TRANSIT_TO_FRONT, info, toFrontChange)
+
+ verify(transitionAnimation).loadDefaultAnimationAttr(
+ eq(R.styleable.WindowAnimation_activityOpenEnterAnimation),
+ /* translucent= */ anyBoolean())
+ }
+
+ @Test
+ fun loadAttributeAnimation_fullscreen_taskOpen_returnsTaskOpenEnterAnim() {
+ val openChange = ChangeBuilder(WindowManager.TRANSIT_OPEN)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FULLSCREEN))
+ .build()
+ val info = TransitionInfoBuilder(WindowManager.TRANSIT_OPEN).addChange(openChange).build()
+
+ loadAttributeAnimation(WindowManager.TRANSIT_OPEN, info, openChange)
+
+ verify(transitionAnimation).loadDefaultAnimationAttr(
+ eq(R.styleable.WindowAnimation_taskOpenEnterAnimation),
+ /* translucent= */ anyBoolean())
+ }
+
+ @Test
+ fun loadAttributeAnimation_freeform_taskOpen_taskToBackChange_passesTranslucent() {
+ val openChange = ChangeBuilder(WindowManager.TRANSIT_OPEN)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FREEFORM))
+ .build()
+ val toBackChange = ChangeBuilder(WindowManager.TRANSIT_TO_BACK)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FREEFORM))
+ .setFlags(FLAG_TRANSLUCENT)
+ .build()
+ val info = TransitionInfoBuilder(WindowManager.TRANSIT_OPEN)
+ .addChange(openChange)
+ .addChange(toBackChange)
+ .build()
+
+ loadAttributeAnimation(WindowManager.TRANSIT_OPEN, info, toBackChange)
+
+ verify(transitionAnimation).loadDefaultAnimationAttr(
+ eq(R.styleable.WindowAnimation_activityCloseExitAnimation),
+ /* translucent= */ eq(true))
+ }
+
+ private fun loadAttributeAnimation(
+ @WindowManager.TransitionType type: Int,
+ info: TransitionInfo,
+ change: TransitionInfo.Change,
+ wallpaperTransit: Int = TransitionAnimation.WALLPAPER_TRANSITION_NONE,
+ isDreamTransition: Boolean = false,
+ ) {
+ TransitionAnimationHelper.loadAttributeAnimation(
+ type, info, change, wallpaperTransit, transitionAnimation, isDreamTransition)
+ }
+
+ private fun createTaskInfo(windowingMode: Int): RunningTaskInfo {
+ val taskInfo = TestRunningTaskInfoBuilder()
+ .setWindowingMode(windowingMode)
+ .build()
+ return taskInfo
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt
new file mode 100644
index 000000000000..261d4b5e7d1a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt
@@ -0,0 +1,107 @@
+/*
+ * 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.wm.shell.windowdecor
+
+import android.app.ActivityManager
+import android.app.WindowConfiguration
+import android.content.ComponentName
+import android.testing.AndroidTestingRunner
+import android.view.Display
+import android.view.WindowInsetsController
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.google.common.truth.Truth
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class CaptionWindowDecorationTests : ShellTestCase() {
+ @Test
+ fun updateRelayoutParams_freeformAndTransparentAppearance_allowsInputFallthrough() {
+ val taskInfo = createTaskInfo()
+ taskInfo.configuration.windowConfiguration.windowingMode =
+ WindowConfiguration.WINDOWING_MODE_FREEFORM
+ taskInfo.taskDescription!!.topOpaqueSystemBarsAppearance =
+ WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND
+ val relayoutParams = WindowDecoration.RelayoutParams()
+
+ CaptionWindowDecoration.updateRelayoutParams(
+ relayoutParams,
+ taskInfo,
+ true,
+ false
+ )
+
+ Truth.assertThat(relayoutParams.hasInputFeatureSpy()).isTrue()
+ }
+
+ @Test
+ fun updateRelayoutParams_freeformButOpaqueAppearance_disallowsInputFallthrough() {
+ val taskInfo = createTaskInfo()
+ taskInfo.configuration.windowConfiguration.windowingMode =
+ WindowConfiguration.WINDOWING_MODE_FREEFORM
+ taskInfo.taskDescription!!.topOpaqueSystemBarsAppearance = 0
+ val relayoutParams = WindowDecoration.RelayoutParams()
+
+ CaptionWindowDecoration.updateRelayoutParams(
+ relayoutParams,
+ taskInfo,
+ true,
+ false
+ )
+
+ Truth.assertThat(relayoutParams.hasInputFeatureSpy()).isFalse()
+ }
+
+ @Test
+ fun updateRelayoutParams_addOccludingCaptionElementCorrectly() {
+ val taskInfo = createTaskInfo()
+ val relayoutParams = WindowDecoration.RelayoutParams()
+ CaptionWindowDecoration.updateRelayoutParams(
+ relayoutParams,
+ taskInfo,
+ true,
+ false
+ )
+ Truth.assertThat(relayoutParams.mOccludingCaptionElements.size).isEqualTo(2)
+ Truth.assertThat(relayoutParams.mOccludingCaptionElements[0].mAlignment).isEqualTo(
+ WindowDecoration.RelayoutParams.OccludingCaptionElement.Alignment.START)
+ Truth.assertThat(relayoutParams.mOccludingCaptionElements[1].mAlignment).isEqualTo(
+ WindowDecoration.RelayoutParams.OccludingCaptionElement.Alignment.END)
+ }
+
+ private fun createTaskInfo(): ActivityManager.RunningTaskInfo {
+ val taskDescriptionBuilder =
+ ActivityManager.TaskDescription.Builder()
+ val taskInfo = TestRunningTaskInfoBuilder()
+ .setDisplayId(Display.DEFAULT_DISPLAY)
+ .setTaskDescriptionBuilder(taskDescriptionBuilder)
+ .setVisible(true)
+ .build()
+ taskInfo.realActivity = ComponentName(
+ "com.android.wm.shell.windowdecor",
+ "CaptionWindowDecorationTests"
+ )
+ taskInfo.baseActivity = ComponentName(
+ "com.android.wm.shell.windowdecor",
+ "CaptionWindowDecorationTests"
+ )
+ return taskInfo
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 4c94c2933383..b1803e97b107 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -55,6 +55,7 @@ import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.StaticMockitoSession
+import com.android.internal.jank.InteractionJankMonitor
import com.android.window.flags.Flags
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
@@ -69,7 +70,7 @@ import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.sysui.KeyguardChangeListener
import com.android.wm.shell.sysui.ShellCommandHandler
import com.android.wm.shell.sysui.ShellController
@@ -134,6 +135,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
@Mock private lateinit var mockRootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
@Mock private lateinit var mockShellCommandHandler: ShellCommandHandler
@Mock private lateinit var mockWindowManager: IWindowManager
+ @Mock private lateinit var mockInteractionJankMonitor: InteractionJankMonitor
private val transactionFactory = Supplier<SurfaceControl.Transaction> {
SurfaceControl.Transaction()
@@ -167,7 +169,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
mockInputMonitorFactory,
transactionFactory,
mockRootTaskDisplayAreaOrganizer,
- windowDecorByTaskIdSpy
+ windowDecorByTaskIdSpy, mockInteractionJankMonitor
)
whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
@@ -346,10 +348,35 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
}
@Test
- fun testDecorationIsNotCreatedForTopTranslucentActivities() {
- setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun testDecorationIsCreatedForTopTranslucentActivitiesWithStyleFloating() {
+ val mockitoSession: StaticMockitoSession = mockitoSession()
+ .strictness(Strictness.LENIENT)
+ .spyStatic(DesktopModeStatus::class.java)
+ .startMocking()
+ try {
+ val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true).apply {
+ isTopActivityTransparent = true
+ isTopActivityStyleFloating = true
+ numActivities = 1
+ }
+ doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(any()) }
+ setUpMockDecorationsForTasks(task)
+
+ onTaskOpening(task)
+ verify(mockDesktopModeWindowDecorFactory)
+ .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ } finally {
+ mockitoSession.finishMocking()
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun testDecorationIsNotCreatedForTopTranslucentActivitiesWithoutStyleFloating() {
val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true).apply {
isTopActivityTransparent = true
+ isTopActivityStyleFloating = false
numActivities = 1
}
onTaskOpening(task)
@@ -359,6 +386,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
fun testDecorationIsNotCreatedForSystemUIActivities() {
val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index 36e8a4671a46..d8606093ac5c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -31,6 +31,7 @@ import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
@@ -50,6 +51,7 @@ import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.PointF;
+import android.net.Uri;
import android.os.Handler;
import android.os.SystemProperties;
import android.platform.test.annotations.DisableFlags;
@@ -82,7 +84,7 @@ import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.windowdecor.WindowDecoration.RelayoutParams;
import com.android.wm.shell.windowdecor.common.OnTaskActionClickListener;
@@ -118,6 +120,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
private static final String USE_ROUNDED_CORNERS_SYSPROP_KEY =
"persist.wm.debug.desktop_use_rounded_corners";
+ private static final Uri TEST_URI = Uri.parse("www.google.com");
+
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
@Mock
@@ -150,6 +154,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
private PackageManager mMockPackageManager;
@Mock
private Handler mMockHandler;
+ @Mock
+ private DesktopModeWindowDecoration.OpenInBrowserClickListener mMockOpenInBrowserClickListener;
@Captor
private ArgumentCaptor<Function1<Boolean, Unit>> mOnMaxMenuHoverChangeListener;
@Captor
@@ -170,7 +176,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Before
- public void setUp() {
+ public void setUp() throws PackageManager.NameNotFoundException {
mMockitoSession = mockitoSession()
.strictness(Strictness.LENIENT)
.spyStatic(DesktopModeStatus.class)
@@ -186,6 +192,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
mTestableContext.ensureTestableResources();
mContext.setMockPackageManager(mMockPackageManager);
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("applicationLabel");
+ final ActivityInfo activityInfo = new ActivityInfo();
+ activityInfo.applicationInfo = new ApplicationInfo();
+ when(mMockPackageManager.getActivityInfo(any(), anyInt())).thenReturn(activityInfo);
final Display defaultDisplay = mock(Display.class);
doReturn(defaultDisplay).when(mMockDisplayController).getDisplay(Display.DEFAULT_DISPLAY);
doReturn(mInsetsState).when(mMockDisplayController).getInsetsState(anyInt());
@@ -552,6 +561,65 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
verify(mMockHandler).removeCallbacks(any());
}
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
+ public void capturedLink_postsOnCapturedLinkExpiredRunnable() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+ final ArgumentCaptor<Runnable> runnableArgument = ArgumentCaptor.forClass(Runnable.class);
+ final DesktopModeWindowDecoration decor = createWindowDecoration(taskInfo);
+
+ decor.relayout(taskInfo);
+ // Assert captured link is set
+ assertTrue(decor.browserLinkAvailable());
+ // Asset runnable posted to set captured link to expired
+ verify(mMockHandler).postDelayed(runnableArgument.capture(), anyLong());
+ runnableArgument.getValue().run();
+ assertFalse(decor.browserLinkAvailable());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
+ public void capturedLink_capturedLinkNotResetToSameLink() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+ final DesktopModeWindowDecoration decor = createWindowDecoration(taskInfo);
+ final ArgumentCaptor<Runnable> runnableArgument = ArgumentCaptor.forClass(Runnable.class);
+
+ // Set captured link and run on captured link expired runnable
+ decor.relayout(taskInfo);
+ verify(mMockHandler).postDelayed(runnableArgument.capture(), anyLong());
+ runnableArgument.getValue().run();
+
+ decor.relayout(taskInfo);
+ // Assert captured link not set to same value twice
+ assertFalse(decor.browserLinkAvailable());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
+ public void capturedLink_capturedLinkExpiresAfterClick() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+ final DesktopModeWindowDecoration decor = createWindowDecoration(taskInfo);
+
+ decor.relayout(taskInfo);
+ // Assert captured link is set
+ assertTrue(decor.browserLinkAvailable());
+ decor.onOpenInBrowserClick();
+ //Assert Captured link expires after button is clicked
+ assertFalse(decor.browserLinkAvailable());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
+ public void capturedLink_openInBrowserListenerCalledOnClick() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+ final DesktopModeWindowDecoration decor = createWindowDecoration(taskInfo);
+
+ decor.relayout(taskInfo);
+ decor.onOpenInBrowserClick();
+
+ verify(mMockOpenInBrowserClickListener).onClick(any(), any());
+ }
+
private void createMaximizeMenu(DesktopModeWindowDecoration decoration, MaximizeMenu menu) {
final OnTaskActionClickListener l = (taskId, tag) -> {};
decoration.setOnMaximizeOrRestoreClickListener(l);
@@ -592,11 +660,11 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
mMockHandler, mMockChoreographer, mMockSyncQueue, mMockRootTaskDisplayAreaOrganizer,
SurfaceControl.Builder::new, mMockTransactionSupplier,
WindowContainerTransaction::new, SurfaceControl::new,
- mMockSurfaceControlViewHostFactory,
- maximizeMenuFactory);
+ mMockSurfaceControlViewHostFactory, maximizeMenuFactory);
windowDecor.setCaptionListeners(mMockTouchEventListener, mMockTouchEventListener,
mMockTouchEventListener, mMockTouchEventListener);
windowDecor.setExclusionRegionListener(mMockExclusionRegionListener);
+ windowDecor.setOpenInBrowserClickListener(mMockOpenInBrowserClickListener);
return windowDecor;
}
@@ -608,12 +676,12 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
.setTaskDescriptionBuilder(taskDescriptionBuilder)
.setVisible(visible)
.build();
- taskInfo.topActivityInfo = new ActivityInfo();
- taskInfo.topActivityInfo.applicationInfo = new ApplicationInfo();
taskInfo.realActivity = new ComponentName("com.android.wm.shell.windowdecor",
"DesktopModeWindowDecorationTests");
taskInfo.baseActivity = new ComponentName("com.android.wm.shell.windowdecor",
"DesktopModeWindowDecorationTests");
+ taskInfo.capturedLink = TEST_URI;
+ taskInfo.capturedLinkTimestamp = System.currentTimeMillis();
return taskInfo;
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
index ac5aeec3adc8..e52971120478 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
@@ -34,7 +34,7 @@ import com.android.window.flags.Flags
import com.android.wm.shell.R
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM
import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT
import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
index 4dea5a75a0e8..6a94cd8aa283 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
@@ -55,8 +55,6 @@ public class DragResizeWindowGeometryTests {
private static final Size TASK_SIZE = new Size(500, 1000);
private static final int TASK_CORNER_RADIUS = 10;
private static final int EDGE_RESIZE_THICKNESS = 15;
- private static final int EDGE_RESIZE_DEBUG_THICKNESS = EDGE_RESIZE_THICKNESS
- + (DragResizeWindowGeometry.DEBUG ? DragResizeWindowGeometry.EDGE_DEBUG_BUFFER : 0);
private static final int FINE_CORNER_SIZE = EDGE_RESIZE_THICKNESS * 2 + 10;
private static final int LARGE_CORNER_SIZE = FINE_CORNER_SIZE + 10;
private static final DragResizeWindowGeometry GEOMETRY = new DragResizeWindowGeometry(
@@ -91,14 +89,13 @@ public class DragResizeWindowGeometryTests {
EDGE_RESIZE_THICKNESS + 10, FINE_CORNER_SIZE, LARGE_CORNER_SIZE),
new DragResizeWindowGeometry(TASK_CORNER_RADIUS, TASK_SIZE,
EDGE_RESIZE_THICKNESS + 10, FINE_CORNER_SIZE, LARGE_CORNER_SIZE))
- .addEqualityGroup(new DragResizeWindowGeometry(TASK_CORNER_RADIUS, TASK_SIZE,
- EDGE_RESIZE_THICKNESS, FINE_CORNER_SIZE, LARGE_CORNER_SIZE + 5),
+ .addEqualityGroup(
new DragResizeWindowGeometry(TASK_CORNER_RADIUS, TASK_SIZE,
- EDGE_RESIZE_THICKNESS, FINE_CORNER_SIZE, LARGE_CORNER_SIZE + 5))
- .addEqualityGroup(new DragResizeWindowGeometry(TASK_CORNER_RADIUS, TASK_SIZE,
- EDGE_RESIZE_THICKNESS, FINE_CORNER_SIZE + 4, LARGE_CORNER_SIZE),
+ EDGE_RESIZE_THICKNESS + 10, FINE_CORNER_SIZE,
+ LARGE_CORNER_SIZE + 5),
new DragResizeWindowGeometry(TASK_CORNER_RADIUS, TASK_SIZE,
- EDGE_RESIZE_THICKNESS, FINE_CORNER_SIZE + 4, LARGE_CORNER_SIZE))
+ EDGE_RESIZE_THICKNESS + 10, FINE_CORNER_SIZE,
+ LARGE_CORNER_SIZE + 5))
.testEquals();
}
@@ -124,21 +121,21 @@ public class DragResizeWindowGeometryTests {
private static void verifyHorizontalEdge(@NonNull Region region, @NonNull Point point) {
assertThat(region.contains(point.x, point.y)).isTrue();
// Horizontally along the edge is still contained.
- assertThat(region.contains(point.x + EDGE_RESIZE_DEBUG_THICKNESS, point.y)).isTrue();
- assertThat(region.contains(point.x - EDGE_RESIZE_DEBUG_THICKNESS, point.y)).isTrue();
+ assertThat(region.contains(point.x + EDGE_RESIZE_THICKNESS, point.y)).isTrue();
+ assertThat(region.contains(point.x - EDGE_RESIZE_THICKNESS, point.y)).isTrue();
// Vertically along the edge is not contained.
- assertThat(region.contains(point.x, point.y - EDGE_RESIZE_DEBUG_THICKNESS)).isFalse();
- assertThat(region.contains(point.x, point.y + EDGE_RESIZE_DEBUG_THICKNESS)).isFalse();
+ assertThat(region.contains(point.x, point.y - EDGE_RESIZE_THICKNESS)).isFalse();
+ assertThat(region.contains(point.x, point.y + EDGE_RESIZE_THICKNESS)).isFalse();
}
private static void verifyVerticalEdge(@NonNull Region region, @NonNull Point point) {
assertThat(region.contains(point.x, point.y)).isTrue();
// Horizontally along the edge is not contained.
- assertThat(region.contains(point.x + EDGE_RESIZE_DEBUG_THICKNESS, point.y)).isFalse();
- assertThat(region.contains(point.x - EDGE_RESIZE_DEBUG_THICKNESS, point.y)).isFalse();
+ assertThat(region.contains(point.x + EDGE_RESIZE_THICKNESS, point.y)).isFalse();
+ assertThat(region.contains(point.x - EDGE_RESIZE_THICKNESS, point.y)).isFalse();
// Vertically along the edge is contained.
- assertThat(region.contains(point.x, point.y - EDGE_RESIZE_DEBUG_THICKNESS)).isTrue();
- assertThat(region.contains(point.x, point.y + EDGE_RESIZE_DEBUG_THICKNESS)).isTrue();
+ assertThat(region.contains(point.x, point.y - EDGE_RESIZE_THICKNESS)).isTrue();
+ assertThat(region.contains(point.x, point.y + EDGE_RESIZE_THICKNESS)).isTrue();
}
/**
@@ -151,10 +148,7 @@ public class DragResizeWindowGeometryTests {
public void testRegionUnion_edgeDragResizeEnabled_containsLargeCorners() {
Region region = new Region();
GEOMETRY.union(region);
- // Make sure we're choosing a point outside of any debug region buffer.
- final int cornerRadius = DragResizeWindowGeometry.DEBUG
- ? Math.max(LARGE_CORNER_SIZE / 2, EDGE_RESIZE_DEBUG_THICKNESS)
- : LARGE_CORNER_SIZE / 2;
+ final int cornerRadius = LARGE_CORNER_SIZE / 2;
new TestPoints(TASK_SIZE, cornerRadius).validateRegion(region);
}
@@ -168,9 +162,7 @@ public class DragResizeWindowGeometryTests {
public void testRegionUnion_edgeDragResizeDisabled_containsFineCorners() {
Region region = new Region();
GEOMETRY.union(region);
- final int cornerRadius = DragResizeWindowGeometry.DEBUG
- ? Math.max(LARGE_CORNER_SIZE / 2, EDGE_RESIZE_DEBUG_THICKNESS)
- : LARGE_CORNER_SIZE / 2;
+ final int cornerRadius = FINE_CORNER_SIZE / 2;
new TestPoints(TASK_SIZE, cornerRadius).validateRegion(region);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
index 5582e0f46321..adda9a688172 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
@@ -22,10 +22,10 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
import android.graphics.Bitmap
import android.graphics.Color
+import android.graphics.Point
import android.graphics.Rect
-import android.platform.test.annotations.RequiresFlagsEnabled
-import android.platform.test.flag.junit.CheckFlagsRule
-import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.Display
@@ -33,6 +33,7 @@ import android.view.LayoutInflater
import android.view.SurfaceControl
import android.view.SurfaceControlViewHost
import android.view.View
+import androidx.core.graphics.toPointF
import androidx.test.filters.SmallTest
import com.android.window.flags.Flags
import com.android.wm.shell.R
@@ -46,6 +47,7 @@ import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UND
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer
+import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
@@ -69,7 +71,7 @@ import org.mockito.kotlin.whenever
class HandleMenuTest : ShellTestCase() {
@JvmField
@Rule
- val mCheckFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+ val setFlagsRule: SetFlagsRule = SetFlagsRule()
@Mock
private lateinit var mockDesktopWindowDecoration: DesktopModeWindowDecoration
@@ -92,6 +94,8 @@ class HandleMenuTest : ShellTestCase() {
private lateinit var handleMenu: HandleMenu
+ private val menuWidthWithElevation = MENU_WIDTH + MENU_PILL_ELEVATION
+
@Before
fun setUp() {
val mockAdditionalViewHostViewContainer = AdditionalViewHostViewContainer(
@@ -100,7 +104,7 @@ class HandleMenuTest : ShellTestCase() {
) {
SurfaceControl.Transaction()
}
- val menuView = LayoutInflater.from(context).inflate(
+ val menuView = LayoutInflater.from(mContext).inflate(
R.layout.desktop_mode_window_decor_handle_menu, null)
whenever(mockDesktopWindowDecoration.addWindow(
anyInt(), any(), any(), any(), anyInt(), anyInt(), anyInt(), anyInt())
@@ -110,50 +114,69 @@ class HandleMenuTest : ShellTestCase() {
whenever(displayLayout.width()).thenReturn(DISPLAY_BOUNDS.width())
whenever(displayLayout.height()).thenReturn(DISPLAY_BOUNDS.height())
whenever(displayLayout.isLandscape).thenReturn(true)
- mockDesktopWindowDecoration.mDecorWindowContext = context
+ mContext.orCreateTestableResources.apply {
+ addOverride(R.dimen.desktop_mode_handle_menu_width, MENU_WIDTH)
+ addOverride(R.dimen.desktop_mode_handle_menu_height, MENU_HEIGHT)
+ addOverride(R.dimen.desktop_mode_handle_menu_margin_top, MENU_TOP_MARGIN)
+ addOverride(R.dimen.desktop_mode_handle_menu_margin_start, MENU_START_MARGIN)
+ addOverride(R.dimen.desktop_mode_handle_menu_pill_elevation, MENU_PILL_ELEVATION)
+ addOverride(
+ R.dimen.desktop_mode_handle_menu_pill_spacing_margin, MENU_PILL_SPACING_MARGIN)
+ }
+ mockDesktopWindowDecoration.mDecorWindowContext = mContext
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
+ @EnableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
fun testFullscreenMenuUsesSystemViewContainer() {
createTaskInfo(WINDOWING_MODE_FULLSCREEN, SPLIT_POSITION_UNDEFINED)
val handleMenu = createAndShowHandleMenu()
- assertTrue(handleMenu.mHandleMenuViewContainer is AdditionalSystemViewContainer)
+ assertTrue(handleMenu.handleMenuViewContainer is AdditionalSystemViewContainer)
// Verify menu is created at coordinates that, when added to WindowManager,
// show at the top-center of display.
- assertTrue(handleMenu.mHandleMenuPosition.equals(16f, -512f))
+ val expected = Point(DISPLAY_BOUNDS.centerX() - menuWidthWithElevation / 2, MENU_TOP_MARGIN)
+ assertEquals(expected.toPointF(), handleMenu.handleMenuPosition)
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
+ @EnableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
fun testFreeformMenu_usesViewHostViewContainer() {
createTaskInfo(WINDOWING_MODE_FREEFORM, SPLIT_POSITION_UNDEFINED)
handleMenu = createAndShowHandleMenu()
- assertTrue(handleMenu.mHandleMenuViewContainer is AdditionalViewHostViewContainer)
+ assertTrue(handleMenu.handleMenuViewContainer is AdditionalViewHostViewContainer)
// Verify menu is created near top-left of task.
- assertTrue(handleMenu.mHandleMenuPosition.equals(12f, 8f))
+ val expected = Point(MENU_START_MARGIN, MENU_TOP_MARGIN)
+ assertEquals(expected.toPointF(), handleMenu.handleMenuPosition)
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
+ @EnableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
fun testSplitLeftMenu_usesSystemViewContainer() {
createTaskInfo(WINDOWING_MODE_MULTI_WINDOW, SPLIT_POSITION_TOP_OR_LEFT)
handleMenu = createAndShowHandleMenu()
- assertTrue(handleMenu.mHandleMenuViewContainer is AdditionalSystemViewContainer)
+ assertTrue(handleMenu.handleMenuViewContainer is AdditionalSystemViewContainer)
// Verify menu is created at coordinates that, when added to WindowManager,
- // show at the top of split left task.
- assertTrue(handleMenu.mHandleMenuPosition.equals(-624f, -512f))
+ // show at the top-center of split left task.
+ val expected = Point(
+ SPLIT_LEFT_BOUNDS.centerX() - menuWidthWithElevation / 2,
+ MENU_TOP_MARGIN
+ )
+ assertEquals(expected.toPointF(), handleMenu.handleMenuPosition)
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
+ @EnableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
fun testSplitRightMenu_usesSystemViewContainer() {
createTaskInfo(WINDOWING_MODE_MULTI_WINDOW, SPLIT_POSITION_BOTTOM_OR_RIGHT)
handleMenu = createAndShowHandleMenu()
- assertTrue(handleMenu.mHandleMenuViewContainer is AdditionalSystemViewContainer)
+ assertTrue(handleMenu.handleMenuViewContainer is AdditionalSystemViewContainer)
// Verify menu is created at coordinates that, when added to WindowManager,
- // show at the top of split right task.
- assertTrue(handleMenu.mHandleMenuPosition.equals(656f, -512f))
+ // show at the top-center of split right task.
+ val expected = Point(
+ SPLIT_RIGHT_BOUNDS.centerX() - menuWidthWithElevation / 2,
+ MENU_TOP_MARGIN
+ )
+ assertEquals(expected.toPointF(), handleMenu.handleMenuPosition)
}
private fun createTaskInfo(windowingMode: Int, splitPosition: Int) {
@@ -178,14 +201,10 @@ class HandleMenuTest : ShellTestCase() {
.setBounds(bounds)
.setVisible(true)
.build()
- // Calculate captionX similar to how WindowDecoration calculates it.
- whenever(mockDesktopWindowDecoration.captionX).thenReturn(
- (mockDesktopWindowDecoration.mTaskInfo.configuration.windowConfiguration
- .bounds.width() - context.resources.getDimensionPixelSize(
- R.dimen.desktop_mode_fullscreen_decor_caption_width)) / 2)
whenever(splitScreenController.getSplitPosition(any())).thenReturn(splitPosition)
whenever(splitScreenController.getStageBounds(any(), any())).thenAnswer {
(it.arguments.first() as Rect).set(SPLIT_LEFT_BOUNDS)
+ (it.arguments[1] as Rect).set(SPLIT_RIGHT_BOUNDS)
}
}
@@ -193,12 +212,12 @@ class HandleMenuTest : ShellTestCase() {
val layoutId = if (mockDesktopWindowDecoration.mTaskInfo.isFreeform) {
R.layout.desktop_mode_app_header
} else {
- R.layout.desktop_mode_app_header
+ R.layout.desktop_mode_app_handle
}
val handleMenu = HandleMenu(mockDesktopWindowDecoration, layoutId,
- onClickListener, onTouchListener, appIcon, appName, displayController,
- splitScreenController, true /* shouldShowWindowingPill */,
- 50 /* captionHeight */ )
+ onClickListener, onTouchListener, appIcon, appName, displayController,
+ splitScreenController, true /* shouldShowWindowingPill */,
+ true /* shouldShowBrowserPill */, 50 /* captionHeight */)
handleMenu.show()
return handleMenu
}
@@ -208,5 +227,11 @@ class HandleMenuTest : ShellTestCase() {
private val FREEFORM_BOUNDS = Rect(500, 500, 2000, 1200)
private val SPLIT_LEFT_BOUNDS = Rect(0, 0, 1280, 1600)
private val SPLIT_RIGHT_BOUNDS = Rect(1280, 0, 2560, 1600)
+ private const val MENU_WIDTH = 200
+ private const val MENU_HEIGHT = 400
+ private const val MENU_TOP_MARGIN = 10
+ private const val MENU_START_MARGIN = 20
+ private const val MENU_PILL_ELEVATION = 2
+ private const val MENU_PILL_SPACING_MARGIN = 4
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
index 901ca90b573e..943c313e5b40 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
@@ -33,6 +33,7 @@ import android.view.WindowManager.TRANSIT_CHANGE
import android.window.TransitionInfo
import android.window.WindowContainerToken
import androidx.test.filters.SmallTest
+import com.android.internal.jank.InteractionJankMonitor
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.DisplayController
@@ -104,6 +105,8 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
private lateinit var mockContext: Context
@Mock
private lateinit var mockResources: Resources
+ @Mock
+ private lateinit var mockInteractionJankMonitor: InteractionJankMonitor
private lateinit var taskPositioner: VeiledResizeTaskPositioner
@@ -150,7 +153,8 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
mockDisplayController,
mockDragStartListener,
mockTransactionFactory,
- mockTransitions
+ mockTransitions,
+ mockInteractionJankMonitor
)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index f3603e1d9b46..2d1bf14ffbb3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -18,6 +18,8 @@ package com.android.wm.shell.windowdecor;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
+import static android.view.InsetsSource.FLAG_FORCE_CONSUMING;
import static android.view.WindowInsets.Type.captionBar;
import static android.view.WindowInsets.Type.mandatorySystemGestures;
import static android.view.WindowInsets.Type.statusBars;
@@ -54,6 +56,8 @@ import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.testing.AndroidTestingRunner;
import android.util.DisplayMetrics;
import android.view.AttachedSurfaceControl;
@@ -71,15 +75,17 @@ import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.window.flags.Flags;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.tests.R;
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -105,6 +111,9 @@ public class WindowDecorationTests extends ShellTestCase {
private static final int CORNER_RADIUS = 20;
private static final int STATUS_BAR_INSET_SOURCE_ID = 0;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+
private final WindowDecoration.RelayoutResult<TestView> mRelayoutResult =
new WindowDecoration.RelayoutResult<>();
@@ -260,7 +269,8 @@ public class WindowDecorationTests extends ShellTestCase {
eq(0 /* index */),
eq(WindowInsets.Type.captionBar()),
eq(new Rect(100, 300, 400, 364)),
- any());
+ any(),
+ anyInt());
verify(mMockSurfaceControlStartT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
verify(mMockSurfaceControlFinishT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
@@ -565,9 +575,9 @@ public class WindowDecorationTests extends ShellTestCase {
windowDecor.relayout(taskInfo);
verify(mMockWindowContainerTransaction).addInsetsSource(eq(taskInfo.token), any(),
- eq(0) /* index */, eq(captionBar()), any(), any());
+ eq(0) /* index */, eq(captionBar()), any(), any(), anyInt());
verify(mMockWindowContainerTransaction).addInsetsSource(eq(taskInfo.token), any(),
- eq(0) /* index */, eq(mandatorySystemGestures()), any(), any());
+ eq(0) /* index */, eq(mandatorySystemGestures()), any(), any(), anyInt());
}
@Test
@@ -654,9 +664,9 @@ public class WindowDecorationTests extends ShellTestCase {
// Never added.
verify(mMockWindowContainerTransaction, never()).addInsetsSource(eq(taskInfo.token), any(),
- eq(0) /* index */, eq(captionBar()), any(), any());
+ eq(0) /* index */, eq(captionBar()), any(), any(), anyInt());
verify(mMockWindowContainerTransaction, never()).addInsetsSource(eq(taskInfo.token), any(),
- eq(0) /* index */, eq(mandatorySystemGestures()), any(), any());
+ eq(0) /* index */, eq(mandatorySystemGestures()), any(), any(), anyInt());
// No need to remove them if they were never added.
verify(mMockWindowContainerTransaction, never()).removeInsetsSource(eq(taskInfo.token),
any(), eq(0) /* index */, eq(captionBar()));
@@ -681,9 +691,9 @@ public class WindowDecorationTests extends ShellTestCase {
mInsetsState.getOrCreateSource(STATUS_BAR_INSET_SOURCE_ID, captionBar()).setVisible(true);
windowDecor.relayout(taskInfo);
verify(mMockWindowContainerTransaction).addInsetsSource(eq(taskInfo.token), any(),
- eq(0) /* index */, eq(captionBar()), any(), any());
+ eq(0) /* index */, eq(captionBar()), any(), any(), anyInt());
verify(mMockWindowContainerTransaction).addInsetsSource(eq(taskInfo.token), any(),
- eq(0) /* index */, eq(mandatorySystemGestures()), any(), any());
+ eq(0) /* index */, eq(mandatorySystemGestures()), any(), any(), anyInt());
windowDecor.close();
@@ -738,9 +748,9 @@ public class WindowDecorationTests extends ShellTestCase {
// Insets should be applied twice.
verify(mMockWindowContainerTransaction, times(2)).addInsetsSource(eq(token), any(),
- eq(0) /* index */, eq(captionBar()), any(), any());
+ eq(0) /* index */, eq(captionBar()), any(), any(), anyInt());
verify(mMockWindowContainerTransaction, times(2)).addInsetsSource(eq(token), any(),
- eq(0) /* index */, eq(mandatorySystemGestures()), any(), any());
+ eq(0) /* index */, eq(mandatorySystemGestures()), any(), any(), anyInt());
}
@Test
@@ -765,9 +775,30 @@ public class WindowDecorationTests extends ShellTestCase {
// Insets should only need to be applied once.
verify(mMockWindowContainerTransaction, times(1)).addInsetsSource(eq(token), any(),
- eq(0) /* index */, eq(captionBar()), any(), any());
+ eq(0) /* index */, eq(captionBar()), any(), any(), anyInt());
verify(mMockWindowContainerTransaction, times(1)).addInsetsSource(eq(token), any(),
- eq(0) /* index */, eq(mandatorySystemGestures()), any(), any());
+ eq(0) /* index */, eq(mandatorySystemGestures()), any(), any(), anyInt());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION)
+ public void testRelayout_captionInsetForceConsume() {
+ final Display defaultDisplay = mock(Display.class);
+ doReturn(defaultDisplay).when(mMockDisplayController)
+ .getDisplay(Display.DEFAULT_DISPLAY);
+ final WindowContainerToken token = TestRunningTaskInfoBuilder.createMockWCToken();
+ final TestRunningTaskInfoBuilder builder = new TestRunningTaskInfoBuilder()
+ .setDisplayId(Display.DEFAULT_DISPLAY)
+ .setVisible(true);
+
+ final ActivityManager.RunningTaskInfo taskInfo =
+ builder.setToken(token).setBounds(new Rect(0, 0, 1000, 1000)).build();
+ final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo);
+ windowDecor.relayout(taskInfo);
+
+ // Caption inset source should be force-consuming.
+ verify(mMockWindowContainerTransaction).addInsetsSource(eq(token), any(),
+ eq(0) /* index */, eq(captionBar()), any(), any(), eq(FLAG_FORCE_CONSUMING));
}
@Test
diff --git a/libs/androidfw/StringPool.cpp b/libs/androidfw/StringPool.cpp
index 1cb8df311c89..629f14683b19 100644
--- a/libs/androidfw/StringPool.cpp
+++ b/libs/androidfw/StringPool.cpp
@@ -132,7 +132,7 @@ bool StringPool::StyleRef::operator==(const StyleRef& rhs) const {
auto rhs_iter = rhs.entry_->spans.begin();
for (const Span& span : entry_->spans) {
- const Span& rhs_span = *rhs_iter;
+ const Span& rhs_span = *rhs_iter++;
if (span.first_char != rhs_span.first_char || span.last_char != rhs_span.last_char ||
span.name != rhs_span.name) {
return false;
@@ -297,24 +297,22 @@ void StringPool::Prune() {
template <typename E>
static void SortEntries(
std::vector<std::unique_ptr<E>>& entries,
- const std::function<int(const StringPool::Context&, const StringPool::Context&)>& cmp) {
+ base::function_ref<int(const StringPool::Context&, const StringPool::Context&)> cmp) {
using UEntry = std::unique_ptr<E>;
+ std::sort(entries.begin(), entries.end(), [cmp](const UEntry& a, const UEntry& b) -> bool {
+ int r = cmp(a->context, b->context);
+ if (r == 0) {
+ r = a->value.compare(b->value);
+ }
+ return r < 0;
+ });
+}
- if (cmp != nullptr) {
- std::sort(entries.begin(), entries.end(), [&cmp](const UEntry& a, const UEntry& b) -> bool {
- int r = cmp(a->context, b->context);
- if (r == 0) {
- r = a->value.compare(b->value);
- }
- return r < 0;
- });
- } else {
- std::sort(entries.begin(), entries.end(),
- [](const UEntry& a, const UEntry& b) -> bool { return a->value < b->value; });
- }
+void StringPool::Sort() {
+ Sort([](auto&&, auto&&) { return 0; });
}
-void StringPool::Sort(const std::function<int(const Context&, const Context&)>& cmp) {
+void StringPool::Sort(base::function_ref<int(const Context&, const Context&)> cmp) {
SortEntries(styles_, cmp);
SortEntries(strings_, cmp);
ReAssignIndices();
diff --git a/libs/androidfw/include/androidfw/StringPool.h b/libs/androidfw/include/androidfw/StringPool.h
index 0190ab57bf23..9b2c72a29f48 100644
--- a/libs/androidfw/include/androidfw/StringPool.h
+++ b/libs/androidfw/include/androidfw/StringPool.h
@@ -17,7 +17,6 @@
#ifndef _ANDROID_STRING_POOL_H
#define _ANDROID_STRING_POOL_H
-#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
@@ -25,6 +24,7 @@
#include "BigBuffer.h"
#include "IDiagnostics.h"
+#include "android-base/function_ref.h"
#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/StringPiece.h"
@@ -205,7 +205,8 @@ class StringPool {
// Sorts the strings according to their Context using some comparison function.
// Equal Contexts are further sorted by string value, lexicographically.
// If no comparison function is provided, values are only sorted lexicographically.
- void Sort(const std::function<int(const Context&, const Context&)>& cmp = nullptr);
+ void Sort();
+ void Sort(base::function_ref<int(const Context&, const Context&)> cmp);
// Removes any strings that have no references.
void Prune();
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 341599e79662..e302fa8b1fc3 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -114,16 +114,12 @@ cc_defaults {
"libbase",
"libharfbuzz_ng",
"libminikin",
- "server_configurable_flags",
- "libaconfig_storage_read_api_cc"
],
static_libs: [
"libui-types",
],
- whole_static_libs: ["hwui_flags_cc_lib"],
-
target: {
android: {
shared_libs: [
@@ -145,6 +141,8 @@ cc_defaults {
"libsync",
"libui",
"aconfig_text_flags_c_lib",
+ "server_configurable_flags",
+ "libaconfig_storage_read_api_cc",
],
static_libs: [
"libEGL_blobCache",
@@ -155,6 +153,7 @@ cc_defaults {
"libstatssocket_lazy",
"libtonemap",
],
+ whole_static_libs: ["hwui_flags_cc_lib"],
},
host: {
static_libs: [
@@ -419,7 +418,6 @@ cc_defaults {
],
static_libs: [
- "libnativehelper_lazy",
"libziparchive_for_incfs",
],
@@ -446,6 +444,7 @@ cc_defaults {
],
static_libs: [
"libgif",
+ "libnativehelper_lazy",
"libstatslog_hwui",
"libstatspull_lazy",
"libstatssocket_lazy",
@@ -464,6 +463,7 @@ cc_defaults {
],
static_libs: [
"libandroidfw",
+ "libnativehelper_jvm",
],
},
},
diff --git a/libs/hwui/apex/LayoutlibLoader.cpp b/libs/hwui/apex/LayoutlibLoader.cpp
index 70a9ef04d6f3..b4e6b7243ddc 100644
--- a/libs/hwui/apex/LayoutlibLoader.cpp
+++ b/libs/hwui/apex/LayoutlibLoader.cpp
@@ -28,6 +28,7 @@ using namespace std;
extern int register_android_graphics_Bitmap(JNIEnv*);
extern int register_android_graphics_BitmapFactory(JNIEnv*);
+extern int register_android_graphics_BitmapRegionDecoder(JNIEnv*);
extern int register_android_graphics_ByteBufferStreamAdaptor(JNIEnv* env);
extern int register_android_graphics_Camera(JNIEnv* env);
extern int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env);
@@ -41,6 +42,7 @@ extern int register_android_graphics_Shader(JNIEnv* env);
extern int register_android_graphics_RenderEffect(JNIEnv* env);
extern int register_android_graphics_Typeface(JNIEnv* env);
extern int register_android_graphics_YuvImage(JNIEnv* env);
+extern int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv* env);
namespace android {
@@ -51,7 +53,12 @@ extern int register_android_graphics_ColorFilter(JNIEnv* env);
extern int register_android_graphics_ColorSpace(JNIEnv* env);
extern int register_android_graphics_DrawFilter(JNIEnv* env);
extern int register_android_graphics_FontFamily(JNIEnv* env);
+extern int register_android_graphics_Gainmap(JNIEnv* env);
+extern int register_android_graphics_HardwareBufferRenderer(JNIEnv* env);
+extern int register_android_graphics_HardwareRendererObserver(JNIEnv* env);
extern int register_android_graphics_Matrix(JNIEnv* env);
+extern int register_android_graphics_Mesh(JNIEnv* env);
+extern int register_android_graphics_MeshSpecification(JNIEnv* env);
extern int register_android_graphics_Paint(JNIEnv* env);
extern int register_android_graphics_Path(JNIEnv* env);
extern int register_android_graphics_PathIterator(JNIEnv* env);
@@ -72,6 +79,7 @@ extern int register_android_graphics_text_GraphemeBreak(JNIEnv* env);
extern int register_android_util_PathParser(JNIEnv* env);
extern int register_android_view_DisplayListCanvas(JNIEnv* env);
extern int register_android_view_RenderNode(JNIEnv* env);
+extern int register_android_view_ThreadedRenderer(JNIEnv* env);
#define REG_JNI(name) { name }
struct RegJNIRec {
@@ -83,6 +91,8 @@ struct RegJNIRec {
static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = {
{"android.graphics.Bitmap", REG_JNI(register_android_graphics_Bitmap)},
{"android.graphics.BitmapFactory", REG_JNI(register_android_graphics_BitmapFactory)},
+ {"android.graphics.BitmapRegionDecoder",
+ REG_JNI(register_android_graphics_BitmapRegionDecoder)},
{"android.graphics.ByteBufferStreamAdaptor",
REG_JNI(register_android_graphics_ByteBufferStreamAdaptor)},
{"android.graphics.Camera", REG_JNI(register_android_graphics_Camera)},
@@ -95,11 +105,20 @@ static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = {
REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor)},
{"android.graphics.DrawFilter", REG_JNI(register_android_graphics_DrawFilter)},
{"android.graphics.FontFamily", REG_JNI(register_android_graphics_FontFamily)},
+ {"android.graphics.Gainmap", REG_JNI(register_android_graphics_Gainmap)},
{"android.graphics.Graphics", REG_JNI(register_android_graphics_Graphics)},
+ {"android.graphics.HardwareBufferRenderer",
+ REG_JNI(register_android_graphics_HardwareBufferRenderer)},
+ {"android.graphics.HardwareRenderer", REG_JNI(register_android_view_ThreadedRenderer)},
+ {"android.graphics.HardwareRendererObserver",
+ REG_JNI(register_android_graphics_HardwareRendererObserver)},
{"android.graphics.ImageDecoder", REG_JNI(register_android_graphics_ImageDecoder)},
{"android.graphics.Interpolator", REG_JNI(register_android_graphics_Interpolator)},
{"android.graphics.MaskFilter", REG_JNI(register_android_graphics_MaskFilter)},
{"android.graphics.Matrix", REG_JNI(register_android_graphics_Matrix)},
+ {"android.graphics.Mesh", REG_JNI(register_android_graphics_Mesh)},
+ {"android.graphics.MeshSpecification",
+ REG_JNI(register_android_graphics_MeshSpecification)},
{"android.graphics.NinePatch", REG_JNI(register_android_graphics_NinePatch)},
{"android.graphics.Paint", REG_JNI(register_android_graphics_Paint)},
{"android.graphics.Path", REG_JNI(register_android_graphics_Path)},
@@ -118,6 +137,8 @@ static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = {
REG_JNI(register_android_graphics_animation_NativeInterpolatorFactory)},
{"android.graphics.animation.RenderNodeAnimator",
REG_JNI(register_android_graphics_animation_RenderNodeAnimator)},
+ {"android.graphics.drawable.AnimatedImageDrawable",
+ REG_JNI(register_android_graphics_drawable_AnimatedImageDrawable)},
{"android.graphics.drawable.AnimatedVectorDrawable",
REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable)},
{"android.graphics.drawable.VectorDrawable",
diff --git a/libs/hwui/hwui/DrawTextFunctor.h b/libs/hwui/hwui/DrawTextFunctor.h
index cfca48084d97..0efb2c81af01 100644
--- a/libs/hwui/hwui/DrawTextFunctor.h
+++ b/libs/hwui/hwui/DrawTextFunctor.h
@@ -17,7 +17,6 @@
#include <SkFontMetrics.h>
#include <SkRRect.h>
#include <SkTextBlob.h>
-#include <com_android_graphics_hwui_flags.h>
#include "../utils/Color.h"
#include "Canvas.h"
@@ -30,7 +29,19 @@
#include "hwui/PaintFilter.h"
#include "pipeline/skia/SkiaRecordingCanvas.h"
+#ifdef __ANDROID__
+#include <com_android_graphics_hwui_flags.h>
namespace flags = com::android::graphics::hwui::flags;
+#else
+namespace flags {
+constexpr bool high_contrast_text_luminance() {
+ return false;
+}
+constexpr bool high_contrast_text_small_text_rect() {
+ return false;
+}
+} // namespace flags
+#endif
namespace android {
diff --git a/libs/hwui/jni/MeshSpecification.cpp b/libs/hwui/jni/MeshSpecification.cpp
index ae9792df3d82..b943496ae9f7 100644
--- a/libs/hwui/jni/MeshSpecification.cpp
+++ b/libs/hwui/jni/MeshSpecification.cpp
@@ -126,7 +126,7 @@ static void MeshSpecification_safeUnref(SkMeshSpecification* meshSpec) {
SkSafeUnref(meshSpec);
}
-static jlong getMeshSpecificationFinalizer() {
+static jlong getMeshSpecificationFinalizer(CRITICAL_JNI_PARAMS) {
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&MeshSpecification_safeUnref));
}
diff --git a/libs/hwui/jni/android_graphics_HardwareBufferRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareBufferRenderer.cpp
index e3cdee6e7034..3b1b86160f3a 100644
--- a/libs/hwui/jni/android_graphics_HardwareBufferRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareBufferRenderer.cpp
@@ -135,7 +135,7 @@ static void android_graphics_HardwareBufferRenderer_setLightAlpha(JNIEnv* env, j
proxy->setLightAlpha((uint8_t)(255 * ambientShadowAlpha), (uint8_t)(255 * spotShadowAlpha));
}
-static jlong android_graphics_HardwareBufferRenderer_getFinalizer() {
+static jlong android_graphics_HardwareBufferRenderer_getFinalizer(CRITICAL_JNI_PARAMS) {
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&HardwareBufferRenderer_destroy));
}
diff --git a/location/Android.bp b/location/Android.bp
index c0e102acad4d..bc02d1f852de 100644
--- a/location/Android.bp
+++ b/location/Android.bp
@@ -30,9 +30,6 @@ java_sdk_library {
"app-compat-annotations",
"unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
],
- hidden_api_packages: [
- "com.android.internal.location",
- ],
aidl: {
include_dirs: [
"frameworks/base/location/java",
diff --git a/location/java/com/android/internal/location/package-info.java b/location/java/com/android/internal/location/package-info.java
new file mode 100644
index 000000000000..25573c15ce59
--- /dev/null
+++ b/location/java/com/android/internal/location/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+/**
+ * Exclude from API surfaces
+ *
+ * @hide
+ */
+package com.android.internal.location;
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 124f1f0ddd43..25c767a88b17 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -7435,6 +7435,21 @@ public class AudioManager {
}
/**
+ * @hide
+ * Queries the volume policy
+ * @return the volume policy currently in use
+ */
+ @TestApi
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
+ public @NonNull VolumePolicy getVolumePolicy() {
+ try {
+ return getService().getVolumePolicy();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Set Hdmi Cec system audio mode.
*
* @param on whether to be on system audio mode
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 73deb17d0055..03cd53580b1b 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1797,6 +1797,7 @@ public class AudioTrack extends PlayerBase
(flags != 0 // cannot have any special flags
|| attributes.getUsage() != AudioAttributes.USAGE_MEDIA
|| (attributes.getContentType() != AudioAttributes.CONTENT_TYPE_UNKNOWN
+ && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_SPEECH
&& attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MUSIC
&& attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MOVIE))) {
return false;
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 08cc126fb1a8..d20b7f090e92 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -386,6 +386,8 @@ interface IAudioService {
void setVolumePolicy(in VolumePolicy policy);
+ VolumePolicy getVolumePolicy();
+
boolean hasRegisteredDynamicPolicy();
void registerRecordingCallback(in IRecordingConfigDispatcher rcdb);
@@ -760,14 +762,14 @@ interface IAudioService {
void unregisterLoudnessCodecUpdatesDispatcher(in ILoudnessCodecUpdatesDispatcher dispatcher);
- oneway void startLoudnessCodecUpdates(int sessionId);
+ void startLoudnessCodecUpdates(int sessionId);
- oneway void stopLoudnessCodecUpdates(int sessionId);
+ void stopLoudnessCodecUpdates(int sessionId);
- oneway void addLoudnessCodecInfo(int sessionId, int mediaCodecHash,
+ void addLoudnessCodecInfo(int sessionId, int mediaCodecHash,
in LoudnessCodecInfo codecInfo);
- oneway void removeLoudnessCodecInfo(int sessionId, in LoudnessCodecInfo codecInfo);
+ void removeLoudnessCodecInfo(int sessionId, in LoudnessCodecInfo codecInfo);
PersistableBundle getLoudnessParams(in LoudnessCodecInfo codecInfo);
diff --git a/media/java/android/media/VolumePolicy.java b/media/java/android/media/VolumePolicy.java
index b193b70bac2c..96de72dfd10d 100644
--- a/media/java/android/media/VolumePolicy.java
+++ b/media/java/android/media/VolumePolicy.java
@@ -16,39 +16,53 @@
package android.media;
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
/** @hide */
+@TestApi
+@SuppressLint("UnflaggedApi") // @TestApi without associated feature.
public final class VolumePolicy implements Parcelable {
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
+ @NonNull
public static final VolumePolicy DEFAULT = new VolumePolicy(false, false, false, 400);
/**
* Accessibility volume policy where the STREAM_MUSIC volume (i.e. media volume) affects
* the STREAM_ACCESSIBILITY volume, and vice-versa.
*/
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
public static final int A11Y_MODE_MEDIA_A11Y_VOLUME = 0;
/**
* Accessibility volume policy where the STREAM_ACCESSIBILITY volume is independent from
* any other volume.
*/
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
public static final int A11Y_MODE_INDEPENDENT_A11Y_VOLUME = 1;
/** Allow volume adjustments lower from vibrate to enter ringer mode = silent */
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
public final boolean volumeDownToEnterSilent;
/** Allow volume adjustments higher to exit ringer mode = silent */
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
public final boolean volumeUpToExitSilent;
/** Automatically enter do not disturb when ringer mode = silent */
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
public final boolean doNotDisturbWhenSilent;
/** Only allow volume adjustment from vibrate to silent after this
number of milliseconds since an adjustment from normal to vibrate. */
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
public final int vibrateToSilentDebounce;
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
public VolumePolicy(boolean volumeDownToEnterSilent, boolean volumeUpToExitSilent,
boolean doNotDisturbWhenSilent, int vibrateToSilentDebounce) {
this.volumeDownToEnterSilent = volumeDownToEnterSilent;
@@ -82,19 +96,22 @@ public final class VolumePolicy implements Parcelable {
&& other.vibrateToSilentDebounce == vibrateToSilentDebounce;
}
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
@Override
public int describeContents() {
return 0;
}
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(volumeDownToEnterSilent ? 1 : 0);
dest.writeInt(volumeUpToExitSilent ? 1 : 0);
dest.writeInt(doNotDisturbWhenSilent ? 1 : 0);
dest.writeInt(vibrateToSilentDebounce);
}
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
public static final @android.annotation.NonNull Parcelable.Creator<VolumePolicy> CREATOR
= new Parcelable.Creator<VolumePolicy>() {
@Override
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index 40592915a3a8..999f40e53952 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -312,6 +312,10 @@ public final class MediaProjection {
* <p>Once a MediaProjection has been stopped, it's up to the application to release any
* resources it may be holding (e.g. releasing the {@link VirtualDisplay} and
* {@link Surface}).
+ *
+ * <p>After this callback any call to
+ * {@link MediaProjection#createVirtualDisplay} will fail, even if no such
+ * {@link VirtualDisplay} was ever created for this MediaProjection session.
*/
public void onStop() { }
diff --git a/media/java/android/media/projection/MediaProjectionManager.java b/media/java/android/media/projection/MediaProjectionManager.java
index 7ed67dcde913..7a7137aa7748 100644
--- a/media/java/android/media/projection/MediaProjectionManager.java
+++ b/media/java/android/media/projection/MediaProjectionManager.java
@@ -43,25 +43,31 @@ import java.util.Map;
/**
* Manages the retrieval of certain types of {@link MediaProjection} tokens.
*
- * <p><ol>An example flow of starting a media projection will be:
- * <li>Declare a foreground service with the type {@code mediaProjection} in
- * the {@code AndroidManifest.xml}.
- * </li>
- * <li>Create an intent by calling {@link MediaProjectionManager#createScreenCaptureIntent()}
- * and pass this intent to {@link Activity#startActivityForResult(Intent, int)}.
- * </li>
- * <li>On getting {@link Activity#onActivityResult(int, int, Intent)},
- * start the foreground service with the type
- * {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION}.
- * </li>
- * <li>Retrieve the media projection token by calling
- * {@link MediaProjectionManager#getMediaProjection(int, Intent)} with the result code and
- * intent from the {@link Activity#onActivityResult(int, int, Intent)} above.
- * </li>
- * <li>Start the screen capture session for media projection by calling
- * {@link MediaProjection#createVirtualDisplay(String, int, int, int, int, Surface,
- * android.hardware.display.VirtualDisplay.Callback, Handler)}.
- * </li>
+ * <p>
+ *
+ * <ol>
+ * An example flow of starting a media projection will be:
+ * <li>Declare a foreground service with the type {@code mediaProjection} in the {@code
+ * AndroidManifest.xml}.
+ * <li>Create an intent by calling {@link MediaProjectionManager#createScreenCaptureIntent()} and
+ * pass this intent to {@link Activity#startActivityForResult(Intent, int)}.
+ * <li>On getting {@link Activity#onActivityResult(int, int, Intent)}, start the foreground
+ * service with the type {@link
+ * android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION}.
+ * <li>Retrieve the media projection token by calling {@link
+ * MediaProjectionManager#getMediaProjection(int, Intent)} with the result code and intent
+ * from the {@link Activity#onActivityResult(int, int, Intent)} above.
+ * <li>Register a {@link MediaProjection.Callback} by calling {@link
+ * MediaProjection#registerCallback(MediaProjection.Callback, Handler)}. This is required to
+ * receive notifications about when the {@link MediaProjection} or captured content changes
+ * state. When receiving an `onStop()` callback, the client must clean up any resources it is
+ * holding, e.g. the {@link VirtualDisplay} and {@link Surface}. The MediaProjection may
+ * further no longer create any new {@link VirtualDisplay}s via {@link
+ * MediaProjection#createVirtualDisplay(String, int, int, int, int, Surface,
+ * VirtualDisplay.Callback, Handler)}.
+ * <li>Start the screen capture session for media projection by calling {@link
+ * MediaProjection#createVirtualDisplay(String, int, int, int, int, Surface,
+ * android.hardware.display.VirtualDisplay.Callback, Handler)}.
* </ol>
*/
@SystemService(Context.MEDIA_PROJECTION_SERVICE)
@@ -257,6 +263,7 @@ public final class MediaProjectionManager {
* @see <a href="/guide/topics/large-screens/media-projection">
* Media projection developer guide</a>
*/
+ @Nullable
public MediaProjection getMediaProjection(int resultCode, @NonNull Intent resultData) {
if (resultCode != Activity.RESULT_OK || resultData == null) {
return null;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
index 102d21acfd19..43acbb1eacc8 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
@@ -2246,6 +2246,8 @@ public class CameraTestUtils extends Assert {
clientAttribution.uid = -1; // USE_CALLING_UID
clientAttribution.pid = -1; // USE_CALLING_PID
clientAttribution.deviceId = contextAttribution.deviceId;
+ clientAttribution.packageName = context.getOpPackageName();
+ clientAttribution.attributionTag = context.getAttributionTag();
clientAttribution.next = new AttributionSourceState[0];
return clientAttribution;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index ad3374a7da6a..ac85ab7f6a6e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -169,10 +169,8 @@ public class CameraBinderTest extends AndroidTestCase {
ICameraClient dummyCallbacks = new DummyCameraClient();
- String clientPackageName = getContext().getPackageName();
-
ICamera cameraUser = mUtils.getCameraService()
- .connect(dummyCallbacks, cameraId, clientPackageName,
+ .connect(dummyCallbacks, cameraId,
getContext().getApplicationInfo().targetSdkVersion,
ICameraService.ROTATION_OVERRIDE_NONE,
/*forceSlowJpegMode*/false,
@@ -267,8 +265,6 @@ public class CameraBinderTest extends AndroidTestCase {
ICameraDeviceCallbacks dummyCallbacks = new DummyCameraDeviceCallbacks();
- String clientPackageName = getContext().getPackageName();
- String clientAttributionTag = getContext().getAttributionTag();
AttributionSourceState clientAttribution =
CameraTestUtils.getClientAttribution(mContext);
clientAttribution.deviceId = DEVICE_ID_DEFAULT;
@@ -277,7 +273,6 @@ public class CameraBinderTest extends AndroidTestCase {
ICameraDeviceUser cameraUser =
mUtils.getCameraService().connectDevice(
dummyCallbacks, String.valueOf(cameraId),
- clientPackageName, clientAttributionTag,
0 /*oomScoreOffset*/,
getContext().getApplicationInfo().targetSdkVersion,
ICameraService.ROTATION_OVERRIDE_NONE, clientAttribution,
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 0ab1ee9095e0..35ad924cee74 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -242,9 +242,6 @@ public class CameraDeviceBinderTest extends AndroidTestCase {
ICameraDeviceCallbacks.Stub dummyCallbacks = new DummyCameraDeviceCallbacks();
- String clientPackageName = getContext().getPackageName();
- String clientAttributionTag = getContext().getAttributionTag();
-
mMockCb = spy(dummyCallbacks);
AttributionSourceState clientAttribution = CameraTestUtils.getClientAttribution(mContext);
@@ -252,7 +249,6 @@ public class CameraDeviceBinderTest extends AndroidTestCase {
clientAttribution.uid = ICameraService.USE_CALLING_UID;
mCameraUser = mUtils.getCameraService().connectDevice(mMockCb, mCameraId,
- clientPackageName, clientAttributionTag,
/*oomScoreOffset*/0, getContext().getApplicationInfo().targetSdkVersion,
ICameraService.ROTATION_OVERRIDE_NONE, clientAttribution, DEVICE_POLICY_DEFAULT);
assertNotNull(String.format("Camera %s was null", mCameraId), mCameraUser);
diff --git a/media/tests/mediatestutils/java/com/android/media/mediatestutils/TestUtils.java b/media/tests/mediatestutils/java/com/android/media/mediatestutils/TestUtils.java
index 7065e3a8f68a..46c72730cf5b 100644
--- a/media/tests/mediatestutils/java/com/android/media/mediatestutils/TestUtils.java
+++ b/media/tests/mediatestutils/java/com/android/media/mediatestutils/TestUtils.java
@@ -27,6 +27,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import java.lang.ref.WeakReference;
+import java.util.Collection;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -35,12 +36,13 @@ import java.util.function.Predicate;
/** Utils for audio tests. */
public class TestUtils {
/**
- * Return a future for an intent delivered by a broadcast receiver which matches an
- * action and predicate.
+ * Return a future for an intent delivered by a broadcast receiver which matches an action and
+ * predicate.
+ *
* @param context - Context to register the receiver with
* @param action - String representing action to register receiver for
- * @param pred - Predicate which sets the future if evaluates to true, otherwise, leaves
- * the future unset. If the predicate throws, the future is set exceptionally
+ * @param pred - Predicate which sets the future if evaluates to true, otherwise, leaves the
+ * future unset. If the predicate throws, the future is set exceptionally
* @return - The future representing intent delivery matching predicate.
*/
public static ListenableFuture<Intent> getFutureForIntent(
@@ -76,20 +78,77 @@ public class TestUtils {
}
/**
- * Same as previous, but with no predicate.
+ * Return a future for an intent delivered by a broadcast receiver which matches one of a set of
+ * actions and predicate.
+ *
+ * @param context - Context to register the receiver with
+ * @param actionsCollection - Collection of actions which to listen for, completing on any
+ * @param pred - Predicate which sets the future if evaluates to true, otherwise, leaves the
+ * future unset. If the predicate throws, the future is set exceptionally
+ * @return - The future representing intent delivery matching predicate.
*/
+ public static ListenableFuture<Intent> getFutureForIntent(
+ Context context, Collection<String> actionsCollection, Predicate<Intent> pred) {
+ // These are evaluated async
+ Objects.requireNonNull(actionsCollection);
+ Objects.requireNonNull(pred);
+ if (actionsCollection.isEmpty()) {
+ throw new IllegalArgumentException("actionsCollection must not be empty");
+ }
+ return getFutureForListener(
+ (recv) ->
+ context.registerReceiver(
+ recv,
+ actionsCollection.stream()
+ .reduce(
+ new IntentFilter(),
+ (IntentFilter filter, String x) -> {
+ filter.addAction(x);
+ return filter;
+ },
+ (x, y) -> {
+ throw new IllegalStateException(
+ "No parallel support");
+ }),
+ Context.RECEIVER_EXPORTED),
+ (recv) -> {
+ try {
+ context.unregisterReceiver(recv);
+ } catch (IllegalArgumentException e) {
+ // Thrown when receiver is already unregistered, nothing to do
+ }
+ },
+ (completer) ->
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ if (actionsCollection.contains(intent.getAction())
+ && pred.test(intent)) {
+ completer.set(intent);
+ }
+ } catch (Exception e) {
+ completer.setException(e);
+ }
+ }
+ },
+ "Intent receiver future for actions: " + actionsCollection);
+ }
+
+ /** Same as previous, but with no predicate. */
public static ListenableFuture<Intent> getFutureForIntent(Context context, String action) {
return getFutureForIntent(context, action, i -> true);
}
/**
* Return a future for a callback registered to a listener interface.
+ *
* @param registerFunc - Function which consumes the callback object for registration
- * @param unregisterFunc - Function which consumes the callback object for unregistration
- * This function is called when the future is completed or cancelled
+ * @param unregisterFunc - Function which consumes the callback object for unregistration This
+ * function is called when the future is completed or cancelled
* @param instantiateCallback - Factory function for the callback object, provided a completer
- * object (see {@code CallbackToFutureAdapter.Completer<T>}), which is a logical reference
- * to the future returned by this function
+ * object (see {@code CallbackToFutureAdapter.Completer<T>}), which is a logical reference
+ * to the future returned by this function
* @param debug - Debug string contained in future {@code toString} representation.
*/
public static <T, V> ListenableFuture<T> getFutureForListener(
diff --git a/nfc/Android.bp b/nfc/Android.bp
index 13ac2311bde3..0282e6f5c246 100644
--- a/nfc/Android.bp
+++ b/nfc/Android.bp
@@ -61,9 +61,6 @@ java_sdk_library {
"android.nfc",
"com.android.nfc",
],
- hidden_api_packages: [
- "com.android.nfc",
- ],
impl_library_visibility: [
"//frameworks/base:__subpackages__",
"//cts/hostsidetests/multidevices/nfc:__subpackages__",
diff --git a/nfc/java/android/nfc/AvailableNfcAntenna.java b/nfc/java/android/nfc/AvailableNfcAntenna.java
index 6e6512a04971..e76aeb07f106 100644
--- a/nfc/java/android/nfc/AvailableNfcAntenna.java
+++ b/nfc/java/android/nfc/AvailableNfcAntenna.java
@@ -28,13 +28,13 @@ import android.os.Parcelable;
public final class AvailableNfcAntenna implements Parcelable {
/**
* Location of the antenna on the Y axis in millimeters.
- * 0 is the bottom-left when the user is facing the screen
+ * 0 is the top-left when the user is facing the screen
* and the device orientation is Portrait.
*/
private final int mLocationX;
/**
* Location of the antenna on the Y axis in millimeters.
- * 0 is the bottom-left when the user is facing the screen
+ * 0 is the top-left when the user is facing the screen
* and the device orientation is Portrait.
*/
private final int mLocationY;
@@ -46,7 +46,7 @@ public final class AvailableNfcAntenna implements Parcelable {
/**
* Location of the antenna on the X axis in millimeters.
- * 0 is the bottom-left when the user is facing the screen
+ * 0 is the top-left when the user is facing the screen
* and the device orientation is Portrait.
*/
public int getLocationX() {
@@ -55,7 +55,7 @@ public final class AvailableNfcAntenna implements Parcelable {
/**
* Location of the antenna on the Y axis in millimeters.
- * 0 is the bottom-left when the user is facing the screen
+ * 0 is the top-left when the user is facing the screen
* and the device orientation is Portrait.
*/
public int getLocationY() {
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index fd77820afc81..90ca92f299a4 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -104,6 +104,7 @@ interface INfcAdapter
void notifyPollingLoop(in PollingFrame frame);
void notifyHceDeactivated();
+ void notifyTestHceData(in int technology, in byte[] data);
int sendVendorNciMessage(int mt, int gid, int oid, in byte[] payload);
void registerVendorExtensionCallback(in INfcVendorNciCallback callbacks);
void unregisterVendorExtensionCallback(in INfcVendorNciCallback callbacks);
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 1dfc81e2108e..395f81d73351 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -963,22 +963,9 @@ public final class NfcAdapter {
throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
+ " NFC extras APIs");
}
- try {
- return sService.getNfcDtaInterface(mContext.getPackageName());
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return null;
- }
- try {
- return sService.getNfcDtaInterface(mContext.getPackageName());
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return null;
- }
+ return callServiceReturn(() -> sService.getNfcDtaInterface(mContext.getPackageName()),
+ null);
+
}
/**
@@ -1095,22 +1082,8 @@ public final class NfcAdapter {
@SystemApi
@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
public @AdapterState int getAdapterState() {
- try {
- return sService.getState();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return NfcAdapter.STATE_OFF;
- }
- try {
- return sService.getState();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return NfcAdapter.STATE_OFF;
- }
+ return callServiceReturn(() -> sService.getState(), NfcAdapter.STATE_OFF);
+
}
/**
@@ -1134,22 +1107,8 @@ public final class NfcAdapter {
@FlaggedApi(Flags.FLAG_NFC_STATE_CHANGE)
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
public boolean enable() {
- try {
- return sService.enable(mContext.getPackageName());
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.enable(mContext.getPackageName());
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.enable(mContext.getPackageName()), false);
+
}
/**
@@ -1175,22 +1134,9 @@ public final class NfcAdapter {
@FlaggedApi(Flags.FLAG_NFC_STATE_CHANGE)
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
public boolean disable() {
- try {
- return sService.disable(true, mContext.getPackageName());
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.disable(true, mContext.getPackageName());
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.disable(true, mContext.getPackageName()),
+ false);
+
}
/**
@@ -1200,22 +1146,9 @@ public final class NfcAdapter {
@SystemApi
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
public boolean disable(boolean persist) {
- try {
- return sService.disable(persist, mContext.getPackageName());
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.disable(persist, mContext.getPackageName());
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.disable(persist, mContext.getPackageName()),
+ false);
+
}
/**
@@ -1241,12 +1174,7 @@ public final class NfcAdapter {
*/
@FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
public boolean isObserveModeSupported() {
- try {
- return sService.isObserveModeSupported();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- return false;
- }
+ return callServiceReturn(() -> sService.isObserveModeSupported(), false);
}
/**
@@ -1257,12 +1185,7 @@ public final class NfcAdapter {
@FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
public boolean isObserveModeEnabled() {
- try {
- return sService.isObserveModeEnabled();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- return false;
- }
+ return callServiceReturn(() -> sService.isObserveModeEnabled(), false);
}
/**
@@ -1286,12 +1209,8 @@ public final class NfcAdapter {
throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
+ " observe mode APIs");
}
- try {
- return sService.setObserveMode(enabled, mContext.getPackageName());
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- return false;
- }
+ return callServiceReturn(() -> sService.setObserveMode(enabled, mContext.getPackageName()),
+ false);
}
/**
@@ -2057,22 +1976,8 @@ public final class NfcAdapter {
if (!sHasNfcFeature && !sHasCeFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.setNfcSecure(enable);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.setNfcSecure(enable);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.setNfcSecure(enable), false);
+
}
/**
@@ -2088,22 +1993,8 @@ public final class NfcAdapter {
if (!sHasNfcFeature && !sHasCeFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.deviceSupportsNfcSecure();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.deviceSupportsNfcSecure();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.deviceSupportsNfcSecure(), false);
+
}
/**
@@ -2121,22 +2012,8 @@ public final class NfcAdapter {
if (!sHasNfcFeature && !sHasCeFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.getNfcAntennaInfo();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return null;
- }
- try {
- return sService.getNfcAntennaInfo();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return null;
- }
+ return callServiceReturn(() -> sService.getNfcAntennaInfo(), null);
+
}
/**
@@ -2154,22 +2031,8 @@ public final class NfcAdapter {
if (!sHasNfcFeature && !sHasCeFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.isNfcSecureEnabled();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.isNfcSecureEnabled();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.isNfcSecureEnabled(), false);
+
}
/**
@@ -2185,22 +2048,8 @@ public final class NfcAdapter {
if (!sHasNfcFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.enableReaderOption(enable);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.enableReaderOption(enable);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.enableReaderOption(enable), false);
+
}
/**
@@ -2214,22 +2063,8 @@ public final class NfcAdapter {
if (!sHasNfcFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.isReaderOptionSupported();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.isReaderOptionSupported();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.isReaderOptionSupported(), false);
+
}
/**
@@ -2245,22 +2080,8 @@ public final class NfcAdapter {
if (!sHasNfcFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.isReaderOptionEnabled();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.isReaderOptionEnabled();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.isReaderOptionEnabled(), false);
+
}
/**
@@ -2388,11 +2209,9 @@ public final class NfcAdapter {
synchronized (mLock) {
mTagRemovedListener = iListener;
}
- try {
- return sService.ignore(tag.getServiceHandle(), debounceMs, iListener);
- } catch (RemoteException e) {
- return false;
- }
+ final ITagRemovedCallback.Stub passedListener = iListener;
+ return callServiceReturn(() ->
+ sService.ignore(tag.getServiceHandle(), debounceMs, passedListener), false);
}
/**
@@ -2509,22 +2328,9 @@ public final class NfcAdapter {
throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
+ " NFC extras APIs");
}
- try {
- return sService.getNfcAdapterExtrasInterface(mContext.getPackageName());
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return null;
- }
- try {
- return sService.getNfcAdapterExtrasInterface(mContext.getPackageName());
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return null;
- }
+ return callServiceReturn(() ->
+ sService.getNfcAdapterExtrasInterface(mContext.getPackageName()), null);
+
}
void enforceResumed(Activity activity) {
@@ -2569,22 +2375,8 @@ public final class NfcAdapter {
if (!sHasNfcFeature && !sHasCeFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.setControllerAlwaysOn(value);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.setControllerAlwaysOn(value);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.setControllerAlwaysOn(value), false);
+
}
/**
@@ -2600,22 +2392,8 @@ public final class NfcAdapter {
@SystemApi
@RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
public boolean isControllerAlwaysOn() {
- try {
- return sService.isControllerAlwaysOn();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.isControllerAlwaysOn();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.isControllerAlwaysOn(), false);
+
}
/**
@@ -2634,22 +2412,8 @@ public final class NfcAdapter {
if (!sHasNfcFeature && !sHasCeFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.isControllerAlwaysOnSupported();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.isControllerAlwaysOnSupported();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.isControllerAlwaysOnSupported(), false);
+
}
/**
@@ -2719,21 +2483,9 @@ public final class NfcAdapter {
Log.e(TAG, "TagIntentAppPreference is not supported");
throw new UnsupportedOperationException();
}
- try {
- return sService.setTagIntentAppPreferenceForUser(userId, pkg, allow);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- try {
- return sService.setTagIntentAppPreferenceForUser(userId, pkg, allow);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE;
- }
+ return callServiceReturn(() ->
+ sService.setTagIntentAppPreferenceForUser(userId, pkg, allow),
+ TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE);
}
@@ -2808,22 +2560,8 @@ public final class NfcAdapter {
if (!sHasNfcFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.isTagIntentAppPreferenceSupported();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.isTagIntentAppPreferenceSupported();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.isTagIntentAppPreferenceSupported(), false);
+
}
/**
@@ -2836,11 +2574,30 @@ public final class NfcAdapter {
@TestApi
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
public void notifyPollingLoop(@NonNull PollingFrame pollingFrame) {
+ callService(() -> sService.notifyPollingLoop(pollingFrame));
+ }
+
+
+ /**
+ * Notifies the system of new HCE data for tests.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
+ public void notifyTestHceData(int technology, byte[] data) {
+ callService(() -> sService.notifyTestHceData(technology, data));
+ }
+
+ interface ServiceCall {
+ void call() throws RemoteException;
+ }
+
+ void callService(ServiceCall call) {
try {
if (sService == null) {
attemptDeadServiceRecovery(null);
}
- sService.notifyPollingLoop(pollingFrame);
+ call.call();
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
// Try one more time
@@ -2849,39 +2606,46 @@ public final class NfcAdapter {
return;
}
try {
- sService.notifyPollingLoop(pollingFrame);
+ call.call();
} catch (RemoteException ee) {
Log.e(TAG, "Failed to recover NFC Service.");
}
}
}
-
- /**
- * Notifies the system of a an HCE session being deactivated.
- * *
- * @hide
- */
- @TestApi
- @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public void notifyHceDeactivated() {
+ interface ServiceCallReturn<T> {
+ T call() throws RemoteException;
+ }
+ <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
try {
if (sService == null) {
attemptDeadServiceRecovery(null);
}
- sService.notifyHceDeactivated();
+ return call.call();
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
// Try one more time
if (sService == null) {
Log.e(TAG, "Failed to recover NFC Service.");
- return;
+ return defaultReturn;
}
try {
- sService.notifyHceDeactivated();
+ return call.call();
} catch (RemoteException ee) {
Log.e(TAG, "Failed to recover NFC Service.");
}
}
+ return defaultReturn;
+ }
+
+ /**
+ * Notifies the system of a an HCE session being deactivated.
+ * *
+ * @hide
+ */
+ @TestApi
+ @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
+ public void notifyHceDeactivated() {
+ callService(() -> sService.notifyHceDeactivated());
}
/**
@@ -2897,22 +2661,7 @@ public final class NfcAdapter {
if (!sHasNfcWlcFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.setWlcEnabled(enable);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.setWlcEnabled(enable);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.setWlcEnabled(enable), false);
}
/**
@@ -2927,22 +2676,8 @@ public final class NfcAdapter {
if (!sHasNfcWlcFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.isWlcEnabled();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- return sService.isWlcEnabled();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return false;
- }
+ return callServiceReturn(() -> sService.isWlcEnabled(), false);
+
}
/**
@@ -3021,22 +2756,8 @@ public final class NfcAdapter {
if (!sHasNfcWlcFeature) {
throw new UnsupportedOperationException();
}
- try {
- return sService.getWlcListenerDeviceInfo();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return null;
- }
- try {
- return sService.getWlcListenerDeviceInfo();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return null;
- }
+ return callServiceReturn(() -> sService.getWlcListenerDeviceInfo(), null);
+
}
/**
diff --git a/nfc/java/android/nfc/NfcAntennaInfo.java b/nfc/java/android/nfc/NfcAntennaInfo.java
index b002ca21e8e3..c57b2e029cc5 100644
--- a/nfc/java/android/nfc/NfcAntennaInfo.java
+++ b/nfc/java/android/nfc/NfcAntennaInfo.java
@@ -64,9 +64,9 @@ public final class NfcAntennaInfo implements Parcelable {
/**
* Whether the device is foldable. When the device is foldable,
- * the 0, 0 is considered to be bottom-left when the device is unfolded and
+ * the 0, 0 is considered to be top-left when the device is unfolded and
* the screens are facing the user. For non-foldable devices 0, 0
- * is bottom-left when the user is facing the screen.
+ * is top-left when the user is facing the screen.
*/
public boolean isDeviceFoldable() {
return mDeviceFoldable;
diff --git a/packages/BackupRestoreConfirmation/res/values-el/strings.xml b/packages/BackupRestoreConfirmation/res/values-el/strings.xml
index 02234990606c..7142edf17c69 100644
--- a/packages/BackupRestoreConfirmation/res/values-el/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-el/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="backup_confirm_title" msgid="827563724209303345">"Πλήρης δημιουργία αντιγράφων ασφαλείας"</string>
+ <string name="backup_confirm_title" msgid="827563724209303345">"Πλήρης δημιουργία αντιγράφου ασφαλείας"</string>
<string name="restore_confirm_title" msgid="5469365809567486602">"Πλήρης επαναφορά"</string>
<string name="backup_confirm_text" msgid="1878021282758896593">"Έχει ζητηθεί ένα πλήρες αντίγραφο ασφαλείας όλων των δεδομένων σε έναν συνδεδεμένο επιτραπέζιο υπολογιστή. Θέλετε να επιτραπεί αυτή η ενέργεια;\n\nΑν δεν έχετε ζητήσει οι ίδιοι αυτό το αντίγραφο ασφαλείας, μην επιτρέψετε την ενέργεια."</string>
<string name="allow_backup_button_label" msgid="4217228747769644068">"Δημιουργία αντιγράφων ασφαλείας για τα δεδομένα μου"</string>
diff --git a/packages/CarrierDefaultApp/res/values-fa/strings.xml b/packages/CarrierDefaultApp/res/values-fa/strings.xml
index d9afe873b444..bfc2fec8dafc 100644
--- a/packages/CarrierDefaultApp/res/values-fa/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fa/strings.xml
@@ -5,7 +5,7 @@
<string name="android_system_label" msgid="2797790869522345065">"شرکت مخابراتی دستگاه همراه"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"داده تلفن همراه تمام شده است"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"داده شبکه تلفن همراه شما غیرفعال شده است"</string>
- <string name="portal_notification_detail" msgid="2295729385924660881">"‏برای رفتن به وب‌سایت %s، ضربه بزنید"</string>
+ <string name="portal_notification_detail" msgid="2295729385924660881">"‏برای رفتن به وب‌سایت %s، تک‌ضرب بزنید"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"‏لطفاً با ارائه‌دهنده خدمات %s خود تماس بگیرید"</string>
<string name="no_mobile_data_connection_title" msgid="7449525772416200578">"بدون اتصال داده دستگاه همراه"</string>
<string name="no_mobile_data_connection" msgid="544980465184147010">"‏افزودن طرح داده یا فراگردی ازطریق %s"</string>
diff --git a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
index 54dae628ba88..91da7dcdf977 100644
--- a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
@@ -16,7 +16,7 @@
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuer quand même dans un navigateur"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Optimiseur de performances"</string>
<string name="performance_boost_notification_title" msgid="3126203390685781861">"Options 5G de votre fournisseur de services"</string>
- <string name="performance_boost_notification_detail" msgid="216569851036236346">"Consultez le site Web de %s pour voir les options concernant votre expérience de l\'application"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Consultez le site Web de %s pour voir les options concernant votre expérience de l\'appli"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Plus tard"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gérer"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Achetez un optimiseur de performances."</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index 97abef773a52..5b5896109846 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -17,20 +17,20 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4470785958457506021">"Gestionnaire d\'appareil compagnon"</string>
- <string name="confirmation_title" msgid="2244241995958340998">"Autoriser l\'application &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
+ <string name="confirmation_title" msgid="2244241995958340998">"Autoriser l\'appli &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
<string name="chooser_title_non_profile" msgid="6035023914517087400">"Choisir un appareil qui sera géré par &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
<string name="chooser_title" msgid="2235819929238267637">"Choisir un appareil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) pour le configurer"</string>
- <string name="summary_watch" msgid="7962014927042971830">"Cette application sera autorisée à synchroniser des informations, comme le nom de l\'appelant, et à accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Cette appli sera autorisée à synchroniser des informations, comme le nom de l\'appelant, et à accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à gérer &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_glasses" msgid="3506504967216601277">"appareil"</string>
- <string name="summary_glasses" msgid="2872254734959842579">"Cette application pourra accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Cette appli pourra accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Autorisez &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations à partir de votre téléphone"</string>
- <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à diffuser les applications de votre téléphone?"</string>
- <string name="summary_app_streaming" msgid="295548145144086753">"%1$s aura accès à tout ce qui est visible ou lu sur le téléphone, y compris l\'audio, les photos, les mots de passe et les messages.&lt;br/&gt;&lt;br/&gt;%1$s pourra diffuser des applications jusqu\'à ce que vous retiriez l\'accès à cette autorisation."</string>
+ <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à diffuser les applis de votre téléphone?"</string>
+ <string name="summary_app_streaming" msgid="295548145144086753">"%1$s aura accès à tout ce qui est visible ou lu sur le téléphone, y compris l\'audio, les photos, les mots de passe et les messages.&lt;br/&gt;&lt;br/&gt;%1$s pourra diffuser des applis jusqu\'à ce que vous retiriez l\'accès à cette autorisation."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Services multiappareils"</string>
- <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour diffuser des applications entre vos appareils"</string>
- <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation, au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>, d\'afficher et de diffuser des applications entre vos appareils"</string>
+ <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour diffuser des applis entre vos appareils"</string>
+ <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation, au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>, d\'afficher et de diffuser des applis entre vos appareils"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorisez &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations à partir de votre téléphone"</string>
@@ -38,18 +38,18 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour accéder aux photos, aux fichiers multimédias et aux notifications de votre téléphone"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Autoriser &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; à effectuer cette action?"</string>
- <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Autoriser &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; à diffuser les applications et les fonctionnalités du système de votre téléphone?"</string>
- <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s aura accès à tout ce qui est visible ou lu sur le téléphone, y compris l\'audio, les photos, les renseignements de paiement, les mots de passe et les messages.&lt;br/&gt;&lt;br/&gt;%1$s pourra diffuser des applications jusqu\'à ce que vous retiriez l\'accès à cette autorisation."</string>
- <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation, au nom de votre <xliff:g id="DEVICE_NAME">%2$s</xliff:g>, de diffuser des applications et d\'autres fonctionnalités du système sur des appareils à proximité"</string>
+ <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Autoriser &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; à diffuser les applis et les fonctionnalités du système de votre téléphone?"</string>
+ <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s aura accès à tout ce qui est visible ou lu sur le téléphone, y compris l\'audio, les photos, les renseignements de paiement, les mots de passe et les messages.&lt;br/&gt;&lt;br/&gt;%1$s pourra diffuser des applis jusqu\'à ce que vous retiriez l\'accès à cette autorisation."</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation, au nom de votre <xliff:g id="DEVICE_NAME">%2$s</xliff:g>, de diffuser des applis et d\'autres fonctionnalités du système sur des appareils à proximité"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
- <string name="summary_generic" msgid="1761976003668044801">"Cette application pourra synchroniser des informations, comme le nom de l\'appelant, entre votre téléphone et l\'appareil sélectionné"</string>
+ <string name="summary_generic" msgid="1761976003668044801">"Cette appli pourra synchroniser des informations, comme le nom de l\'appelant, entre votre téléphone et l\'appareil sélectionné"</string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
<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>
<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 applications 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>
+ <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>
<string name="permission_sync_summary" msgid="765497944331294275">"Cela peut inclure l\'accès &lt;strong&gt;au microphone&lt;/strong&gt;, &lt;strong&gt;à l\'appareil photo&lt;/strong&gt;, et &lt;strong&gt;à la position&lt;/strong&gt;, ainsi que d\'autres autorisations sensibles sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Vous pouvez modifier ces autorisations à tout moment dans vos paramètres sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
<string name="vendor_header_button_description" msgid="7994879208461111473">"Plus de renseignements"</string>
<string name="permission_phone" msgid="2661081078692784919">"Téléphone"</string>
@@ -62,7 +62,7 @@
<string name="permission_media_routing_control" msgid="5498639511586715253">"Modifier la sortie multimédia"</string>
<string name="permission_storage" msgid="6831099350839392343">"Photos et fichiers multimédias"</string>
<string name="permission_notifications" msgid="4099418516590632909">"Notifications"</string>
- <string name="permission_app_streaming" msgid="6009695219091526422">"Applications"</string>
+ <string name="permission_app_streaming" msgid="6009695219091526422">"Applis"</string>
<string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Diffusion en continu"</string>
<string name="permission_phone_summary" msgid="8246321093970051702">"Passez et gérez des appels téléphoniques"</string>
<string name="permission_call_logs_summary" msgid="7545243592757693321">"Lisez et écrivez le journal d\'appels téléphoniques"</string>
@@ -72,11 +72,11 @@
<string name="permission_microphone_summary" msgid="4862628553869973259">"Enregistrez des fichiers audio"</string>
<string name="permission_nearby_devices_summary" msgid="1306752848196464817">"Trouvez et déterminez la position relative des appareils à proximité, et connectez-vous à ceux-ci"</string>
<string name="permission_notification_listener_access_summary" msgid="7856071768185367749">"Lisez toutes les notifications, y compris les renseignements tels que les contacts, les messages et les photos"</string>
- <string name="permission_notifications_summary" msgid="2272810466047367030">"• Lisez toutes les notifications, y compris les renseignements tels que les contacts, les messages et les photos&lt;br/&gt;• Envoyez des notifications&lt;br/&gt;&lt;br/&gt;Vous pouvez gérer la capacité de cette application à lire et à envoyer des notifications à tout moment dans Paramètres > Notifications."</string>
- <string name="permission_app_streaming_summary" msgid="606923325679670624">"Diffusez les applications de votre téléphone"</string>
+ <string name="permission_notifications_summary" msgid="2272810466047367030">"• Lisez toutes les notifications, y compris les renseignements tels que les contacts, les messages et les photos&lt;br/&gt;• Envoyez des notifications&lt;br/&gt;&lt;br/&gt;Vous pouvez gérer la capacité de cette appli à lire et à envoyer des notifications à tout moment dans Paramètres > Notifications."</string>
+ <string name="permission_app_streaming_summary" msgid="606923325679670624">"Diffusez les applis de votre téléphone"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Diffusez des applications et d\'autres fonctionnalités du système à partir de votre téléphone"</string>
- <string name="permission_media_routing_control_summary" msgid="2714631092321412250">"Accédez à une liste d\'appareils accessibles et contrôlez ceux qui diffusent du contenu audio ou vidéo à partir d\'autres applications"</string>
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Diffusez des applis et d\'autres fonctionnalités du système à partir de votre téléphone"</string>
+ <string name="permission_media_routing_control_summary" msgid="2714631092321412250">"Accédez à une liste d\'appareils accessibles et contrôlez ceux qui diffusent du contenu audio ou vidéo à partir d\'autres applis"</string>
<string name="device_type" product="default" msgid="8268703872070046263">"téléphone"</string>
<string name="device_type" product="tablet" msgid="5038791954983067774">"tablette"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java
index 66ab81bf02b1..e00533422072 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java
@@ -554,11 +554,18 @@ public class CompanionAssociationActivity extends FragmentActivity implements
mSelectedDevice = requireNonNull(selectedDevice);
Slog.d(TAG, "onDeviceClicked(): " + mSelectedDevice.toShortString());
-
+ // The permission consent dialog should not be displayed if it's a isSkipPrompt(true)
+ // AssociationRequest or when there is no device profile available
+ // for the multiple devices dialog.
+ // See AssociationRequestsProcessor#mayAssociateWithoutPrompt.
+ final String deviceProfile = mRequest.getDeviceProfile();
+ if (deviceProfile == null || mRequest.isSkipPrompt()) {
+ onUserSelectedDevice(mSelectedDevice);
+ return;
+ }
+ // The permission consent dialog should be displayed for the multiple device
+ // dialog if a device profile exists.
updateSingleDeviceUi();
-
- if (mRequest.isSkipPrompt()) return;
-
mSummary.setVisibility(View.VISIBLE);
mButtonAllow.setVisibility(View.VISIBLE);
mButtonNotAllow.setVisibility(View.VISIBLE);
@@ -588,9 +595,6 @@ public class CompanionAssociationActivity extends FragmentActivity implements
if (deviceProfile == null && mRequest.isSingleDevice()) {
summary = getHtmlFromResources(this, summaryResourceId, remoteDeviceName);
mConstraintList.setVisibility(View.GONE);
- } else if (deviceProfile == null) {
- onUserSelectedDevice(mSelectedDevice);
- return;
} else {
summary = getHtmlFromResources(
this, summaryResourceId, getString(R.string.device_type));
diff --git a/packages/CrashRecovery/aconfig/flags.aconfig b/packages/CrashRecovery/aconfig/flags.aconfig
index 225f8c685fe1..52e0cbbda03a 100644
--- a/packages/CrashRecovery/aconfig/flags.aconfig
+++ b/packages/CrashRecovery/aconfig/flags.aconfig
@@ -31,3 +31,11 @@ flag {
description: "Deletes flag and settings resets"
bug: "333847376"
}
+
+flag {
+ name: "refactor_crashrecovery"
+ namespace: "modularization"
+ description: "Refactor required CrashRecovery code"
+ bug: "289203818"
+ is_fixed_read_only: true
+}
diff --git a/packages/CredentialManager/res/values-el/strings.xml b/packages/CredentialManager/res/values-el/strings.xml
index 2f3aa0bce6f2..8436e21f01d3 100644
--- a/packages/CredentialManager/res/values-el/strings.xml
+++ b/packages/CredentialManager/res/values-el/strings.xml
@@ -53,7 +53,7 @@
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Θέλετε να αποθηκεύσετε τον κωδικό πρόσβασης σε κάποια άλλη συσκευή;"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Θέλετε να αποθηκεύσετε τα στοιχεία σύνδεσης σε κάποια άλλη συσκευή;"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Να χρησιμοποιηθεί το <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> για όλες τις συνδέσεις σας;"</string>
- <string name="use_provider_for_all_description" msgid="1998772715863958997">"Αυτός ο διαχειριστής κωδικών πρόσβασης για τον χρήστη <xliff:g id="USERNAME">%1$s</xliff:g> θα αποθηκεύει τους κωδικούς και τα κλειδιά πρόσβασης, για πιο εύκολη σύνδεση"</string>
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Αυτή η διαχείριση κωδικών πρόσβασης για τον χρήστη <xliff:g id="USERNAME">%1$s</xliff:g> θα αποθηκεύει τους κωδικούς και τα κλειδιά πρόσβασης, για πιο εύκολη σύνδεση"</string>
<string name="set_as_default" msgid="4415328591568654603">"Ορισμός ως προεπιλογής"</string>
<string name="settings" msgid="6536394145760913145">"Ρυθμίσεις"</string>
<string name="use_once" msgid="9027366575315399714">"Χρήση μία φορά"</string>
diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml
index 6147ccce8741..6e6c22aacafe 100644
--- a/packages/CredentialManager/res/values-fa/strings.xml
+++ b/packages/CredentialManager/res/values-fa/strings.xml
@@ -86,7 +86,7 @@
<string name="button_label_view_more" msgid="3429098227286495651">"مشاهده موارد بیشتر"</string>
<string name="get_dialog_heading_for_username" msgid="3456868514554204776">"برای <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
<string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"مدیران گذرواژه قفل‌شده"</string>
- <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"برای باز کردن قفل ضربه بزنید"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"برای باز کردن قفل تک‌ضرب بزنید"</string>
<string name="locked_credential_entry_label_subtext_no_sign_in" msgid="8131725029983174901">"اطلاعات ورود به سیستم موجود نیست"</string>
<string name="no_sign_in_info_in" msgid="2641118151920288356">"هیچ اطلاعات ورود به سیستمی در <xliff:g id="SOURCE">%1$s</xliff:g> وجود ندارد"</string>
<string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"مدیریت ورود به سیستم‌ها"</string>
diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml
index d9715eefa955..d68de9fcd27c 100644
--- a/packages/CredentialManager/res/values-fr-rCA/strings.xml
+++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml
@@ -32,9 +32,9 @@
<string name="passwordless_technology_title" msgid="2497513482056606668">"Technologie sans mot de passe"</string>
<string name="passwordless_technology_detail" msgid="6853928846532955882">"Les clés d\'accès vous permettent de vous connecter sans utiliser de mots de passe. Il vous suffit d\'utiliser votre empreinte digitale, la reconnaissance faciale, un NIP ou un schéma de balayage pour vérifier votre identité et créer un mot de passe."</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"Cryptographie à clé publique"</string>
- <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Selon les normes de l\'Alliance FIDO (y compris Google, Apple, Microsoft et plus) et du W3C, les clés d\'accès utilisent des biclés cryptographiques. Contrairement au nom d\'utilisateur et à la chaîne de caractères que nous utilisons pour les mots de passe, une biclé privée-publique est créée pour une application ou un site Web. La clé privée est stockée en toute sécurité sur votre appareil ou votre gestionnaire de mots de passe et confirme votre identité. La clé publique est partagée avec le serveur de l\'application ou du site Web. Avec les clés correspondantes, vous pouvez vous inscrire et vous connecter instantanément."</string>
+ <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Selon les normes de l\'Alliance FIDO (y compris Google, Apple, Microsoft et plus) et du W3C, les clés d\'accès utilisent des biclés cryptographiques. Contrairement au nom d\'utilisateur et à la chaîne de caractères que nous utilisons pour les mots de passe, une biclé privée-publique est créée pour une appli ou un site Web. La clé privée est stockée en toute sécurité sur votre appareil ou votre gestionnaire de mots de passe et confirme votre identité. La clé publique est partagée avec le serveur de l\'appli ou du site Web. Avec les clés correspondantes, vous pouvez vous inscrire et vous connecter instantanément."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Sécurité accrue du compte"</string>
- <string name="improved_account_security_detail" msgid="9123750251551844860">"Chaque clé est exclusivement liée à l\'application ou au site Web pour lequel elle a été créée, de sorte que vous ne pourrez jamais vous connecter par erreur à une application ou à un site Web frauduleux. En outre, comme les serveurs ne conservent que les clés publiques, le piratage informatique est beaucoup plus difficile."</string>
+ <string name="improved_account_security_detail" msgid="9123750251551844860">"Chaque clé est exclusivement liée à l\'appli ou au site Web pour lequel elle a été créée, de sorte que vous ne pourrez jamais vous connecter par erreur à une appli ou à un site Web frauduleux. En outre, comme les serveurs ne conservent que les clés publiques, le piratage informatique est beaucoup plus difficile."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Transition fluide"</string>
<string name="seamless_transition_detail" msgid="4475509237171739843">"À mesure que nous nous dirigeons vers un avenir sans mot de passe, ils resteront toujours utilisés parallèlement aux clés d\'accès."</string>
<string name="choose_provider_title" msgid="8870795677024868108">"Choisir où enregistrer vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-iw/strings.xml b/packages/CredentialManager/res/values-iw/strings.xml
index 46ad865c256b..51f163922203 100644
--- a/packages/CredentialManager/res/values-iw/strings.xml
+++ b/packages/CredentialManager/res/values-iw/strings.xml
@@ -80,7 +80,7 @@
<string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"רוצה לבחור אפשרות עבור <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="get_dialog_title_use_info_on" msgid="8863708099535435146">"להשתמש במידע הזה בשביל <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="get_dialog_use_saved_passkey_for" msgid="4618100798664888512">"כניסה בדרך אחרת"</string>
- <string name="snackbar_action" msgid="37373514216505085">"הצגת האפשרויות"</string>
+ <string name="snackbar_action" msgid="37373514216505085">"עיון באפשרויות"</string>
<string name="get_dialog_button_label_continue" msgid="6446201694794283870">"המשך"</string>
<string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"אפשרויות כניסה לחשבון"</string>
<string name="button_label_view_more" msgid="3429098227286495651">"עוד מידע"</string>
diff --git a/packages/CredentialManager/res/values-pa/strings.xml b/packages/CredentialManager/res/values-pa/strings.xml
index 517fd82e614a..309299cbf88c 100644
--- a/packages/CredentialManager/res/values-pa/strings.xml
+++ b/packages/CredentialManager/res/values-pa/strings.xml
@@ -32,7 +32,7 @@
<string name="passwordless_technology_title" msgid="2497513482056606668">"ਪਾਸਵਰਡ ਰਹਿਤ ਤਕਨਾਲੋਜੀ"</string>
<string name="passwordless_technology_detail" msgid="6853928846532955882">"ਪਾਸਕੀਆਂ ਤੁਹਾਨੂੰ ਪਾਸਵਰਡਾਂ \'ਤੇ ਭਰੋਸਾ ਕੀਤੇ ਬਿਨਾਂ ਸਾਈਨ-ਇਨ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀਆਂ ਹਨ। ਤੁਹਾਨੂੰ ਆਪਣੀ ਪਛਾਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਅਤੇ ਪਾਸਕੀ ਬਣਾਉਣ ਲਈ ਸਿਰਫ਼ ਆਪਣੇ ਫਿੰਗਰਪ੍ਰਿੰਟ, ਚਿਹਰਾ ਪਛਾਣ, ਪਿੰਨ ਜਾਂ ਸਵਾਈਪ ਪੈਟਰਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।"</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"ਜਨਤਕ ਕੁੰਜੀ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫ਼ੀ"</string>
- <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO ਗਠਜੋੜ (ਜਿਸ ਵਿੱਚ Google, Apple, Microsoft ਅਤੇ ਹੋਰ ਸ਼ਾਮਲ ਹਨ) ਅਤੇ W3C ਮਿਆਰਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਪਾਸਕੀਆਂ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫ਼ਿਕ ਕੁੰਜੀਆਂ ਦੇ ਜੋੜੇ ਵਰਤਦੀਆਂ ਹਨ। ਪਾਸਵਰਡ ਲਈ ਵਰਤੀ ਜਾਂਦੀ ਅੱਖਰ-ਚਿੰਨ੍ਹਾਂ ਦੀ ਸਤਰ ਅਤੇ ਵਰਤੋਂਕਾਰ ਨਾਮ ਤੋਂ ਅਲੱਗ, ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਲਈ ਨਿੱਜੀ-ਜਨਤਕ ਕੁੰਜੀ ਜੋੜਾ ਬਣਾਇਆ ਜਾਂਦਾ ਹੈ। ਨਿੱਜੀ ਕੁੰਜੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਜਾਂ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ \'ਤੇ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਸਟੋਰ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੀ ਪਛਾਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰਦੀ ਹੈ। ਜਨਤਕ ਕੁੰਜੀ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਸਰਵਰ ਨਾਲ ਸਾਂਝੀ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਸੰਬੰਧਿਤ ਕੁੰਜੀਆਂ ਨਾਲ, ਤੁਸੀਂ ਤੁਰੰਤ ਰਜਿਸਟਰ ਅਤੇ ਸਾਈਨ-ਇਨ ਕਰ ਸਕਦੇ ਹੋ।"</string>
+ <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO ਗਠਜੋੜ (Google, Apple, Microsoft ਅਤੇ ਹੋਰ) ਅਤੇ W3C ਮਿਆਰਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਪਾਸਕੀਆਂ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫ਼ਿਕ ਕੁੰਜੀਆਂ ਦੇ ਜੋੜੇ ਵਰਤਦੀਆਂ ਹਨ। ਪਾਸਵਰਡ ਲਈ ਵਰਤੀ ਜਾਂਦੀ ਅੱਖਰ-ਚਿੰਨ੍ਹਾਂ ਦੀ ਸਤਰ ਅਤੇ ਵਰਤੋਂਕਾਰ ਨਾਮ ਤੋਂ ਅਲੱਗ, ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਲਈ ਪ੍ਰਾਈਵੇਟ-ਜਨਤਕ ਕੁੰਜੀ ਜੋੜਾ ਬਣਾਇਆ ਜਾਂਦਾ ਹੈ। ਪ੍ਰਾਈਵੇਟ ਕੁੰਜੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਜਾਂ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ \'ਤੇ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਸਟੋਰ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੀ ਪਛਾਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰਦੀ ਹੈ। ਜਨਤਕ ਕੁੰਜੀ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਸਰਵਰ ਨਾਲ ਸਾਂਝੀ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਸੰਬੰਧਿਤ ਕੁੰਜੀਆਂ ਨਾਲ, ਤੁਸੀਂ ਤੁਰੰਤ ਰਜਿਸਟਰ ਅਤੇ ਸਾਈਨ-ਇਨ ਕਰ ਸਕਦੇ ਹੋ।"</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"ਬਿਹਤਰ ਖਾਤਾ ਸੁਰੱਖਿਆ"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"ਹਰੇਕ ਕੁੰਜੀ ਖਾਸ ਤੌਰ \'ਤੇ ਉਸ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਨਾਲ ਲਿੰਕ ਹੁੰਦੀ ਹੈ ਜਿਸ ਲਈ ਉਹ ਬਣਾਈ ਗਈ ਸੀ, ਇਸ ਲਈ ਤੁਸੀਂ ਕਦੇ ਵੀ ਗਲਤੀ ਨਾਲ ਕਿਸੇ ਧੋਖਾਧੜੀ ਵਾਲੀ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ \'ਤੇ ਸਾਈਨ-ਇਨ ਨਹੀਂ ਕਰ ਸਕਦੇ। ਇਸ ਤੋਂ ਇਲਾਵਾ, ਸਿਰਫ਼ ਜਨਤਕ ਕੁੰਜੀਆਂ ਵਾਲੇ ਸਰਵਰਾਂ \'ਤੇ, ਹੈਕਿੰਗ ਕਰਨਾ ਬਹੁਤ ਔਖਾ ਹੁੰਦਾ ਹੈ।"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"ਸਹਿਜ ਪਰਿਵਰਤਨ"</string>
diff --git a/packages/CredentialManager/wear/res/values-af/strings.xml b/packages/CredentialManager/wear/res/values-af/strings.xml
new file mode 100644
index 000000000000..44e46f4bef65
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-af/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Eiebewysbestuurder"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Gebruik toegangsleutel?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Gebruik wagwoord?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Maak toe"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Gaan voort"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Aanmeldopsies"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Aanmeldopsies"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Bestuur aanmeldings"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Kies ’n aanmelding"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Kies toegangsleutel"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Kies wagwoord"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Meld aan op foon"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Geen aanmeldinligting nie"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tik om te ontsluit"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-am/strings.xml b/packages/CredentialManager/wear/res/values-am/strings.xml
new file mode 100644
index 000000000000..4aa4af184752
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-am/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"የመግቢያ ማስረጃ አስተዳዳሪ"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"የይለፍ ቁልፍ ይጠቀማሉ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"የይለፍ ቃል ይጠቀማሉ?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"አሰናብት"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"ቀጥል"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"የመግቢያ አማራጮች"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"የመግቢያ አማራጮች"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"መግቢያዎችን ያስተዳድሩ"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"መግቢያ ይምረጡ"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"የይለፍ ቁልፍ ይምረጡ"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"የይለፍ ቃል ይምረጡ"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"በስልክ ላይ ግባ"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ምንም የመግቢያ መረጃ የለም"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ለመክፈት መታ ያድርጉ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ar/strings.xml b/packages/CredentialManager/wear/res/values-ar/strings.xml
new file mode 100644
index 000000000000..43a651ea4300
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ar/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"هل تريد استخدام مفتاح المرور؟"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"هل تريد استخدام كلمة المرور؟"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"إغلاق"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"متابعة"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"خيارات تسجيل الدخول"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"خيارات تسجيل الدخول"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"إداراة عمليات تسجيل الدخول"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"اختيار معلومات تسجيل الدخول"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"اختيار مفتاح المرور"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"اختيار كلمة المرور"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"تسجيل الدخول على الهاتف"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"لا تتوفّر معلومات تسجيل دخول"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"انقر لفتح القفل"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-as/strings.xml b/packages/CredentialManager/wear/res/values-as/strings.xml
new file mode 100644
index 000000000000..7b6055dd5372
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-as/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"ক্ৰিডেনশ্বিয়েল পৰিচালক"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"পাছকী ব্যৱহাৰ কৰিবনে?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"পাছৱৰ্ড ব্যৱহাৰ কৰিবনে?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"অগ্ৰাহ্য কৰক"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"অব্যাহত ৰাখক"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ছাইন ইন কৰাৰ বিকল্প"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"ছাইন ইন কৰাৰ বিকল্প"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"ছাইন ইন পৰিচালনা কৰক"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"এটা ছাইন ইনৰ উপায় বাছনি কৰক"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"পাছকী বাছনি কৰক"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"পাছৱৰ্ড বাছনি কৰক"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ফ’নত ছাইন ইন কৰক"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ছাইন ইনৰ তথ্য নাই"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"আনলক কৰিবলৈ টিপক"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-az/strings.xml b/packages/CredentialManager/wear/res/values-az/strings.xml
new file mode 100644
index 000000000000..3f2700295495
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-az/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Giriş Məlumatları Meneceri"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Giriş açarı istifadə edilsin?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Parol istifadə edilsin?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Ləğv edin"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Davam edin"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Giriş seçimləri"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Giriş seçimləri"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Girişləri idarə edin"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Giriş seçin"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Giriş açarı seçin"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Parol seçin"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Telefonda daxil olun"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Giriş məlumatı yoxdur"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Kiliddən çıxarmaq üçün toxunun"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-b+sr+Latn/strings.xml b/packages/CredentialManager/wear/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 000000000000..fd5a59a87657
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Menadžer akreditiva"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Želite da koristite pristupni ključ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Želite da koristite lozinku?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Odbaci"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Nastavi"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opcije za prijavljivanje"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opcije za prijavljivanje"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Upravljajte prijavljivanjima"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Odaberite prijavljivanje"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Odaberite pristupni ključ"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Odaberite lozinku"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Prijavite se na telefonu"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Nema podataka za prijavljivanje"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Dodirnite da biste otključali"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-be/strings.xml b/packages/CredentialManager/wear/res/values-be/strings.xml
new file mode 100644
index 000000000000..275924748e0c
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-be/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Выкарыстаць ключ доступу?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Выкарыстаць пароль?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Закрыць"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Працягнуць"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Спосабы ўваходу"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Спосабы ўваходу"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Кіраванне спосабамі ўваходу"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Выберыце спосаб уваходу"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Выберыце ключ доступу"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Выберыце пароль"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Увайсці на тэлефоне"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Няма даных для ўваходу"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Націсніце, каб разблакіраваць"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-bg/strings.xml b/packages/CredentialManager/wear/res/values-bg/strings.xml
new file mode 100644
index 000000000000..0b6b8d5705a2
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-bg/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Мениджър на идентификационни данни"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Искате ли да използвате ключ за достъп?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Искате ли да използвате парола?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Отхвърляне"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Напред"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Опции за влизане в профила"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Опции за влизане в профила"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Управление на данните за вход"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Избиране на данни за вход"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Избиране на ключ за достъп"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Избиране на парола"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Вход в профила на телефона"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Няма данни за вход"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Докоснете, за да отключите"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-bn/strings.xml b/packages/CredentialManager/wear/res/values-bn/strings.xml
new file mode 100644
index 000000000000..a28da2d38a07
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-bn/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"ক্রেডেনশিয়াল ম্যানেজার"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"পাসকী ব্যবহার করতে চান?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"পাসওয়ার্ড ব্যবহার করতে চান?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"বাতিল করুন"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"চালিয়ে যান"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"সাইন-ইন করার বিকল্প"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"সাইন-ইন করার বিকল্প"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"সাইন-ইন সংক্রান্ত ক্রেডেনশিয়াল ম্যানেজ করুন"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"সাইন-ইন করার বিকল্প বেছে নিন"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"পাসকী বেছে নিন"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"পাসওয়ার্ড বেছে নিন"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ফোনে সাইন-ইন করুন"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"সাইন-ইন সংক্রান্ত তথ্য দেওয়া নেই"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"আনলক করতে ট্যাপ করুন"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-bs/strings.xml b/packages/CredentialManager/wear/res/values-bs/strings.xml
new file mode 100644
index 000000000000..da71c4638f1e
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-bs/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Upravitelj akreditiva"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Koristiti pristupni ključ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Koristiti lozinku?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Odbaci"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Nastavi"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Načini prijave"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Načini prijave"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Upravljajte prijavama"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Odaberite prijavu"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Odaberite pristupni ključ"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Odaberite lozinku"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Prijavite se na telefonu"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Nema podataka za prijavu"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Dodirnite da otključate"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ca/strings.xml b/packages/CredentialManager/wear/res/values-ca/strings.xml
new file mode 100644
index 000000000000..6bb5854c98ae
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ca/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Gestor de credencials"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Vols utilitzar la clau d\'accés?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Vols utilitzar la contrasenya?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Ignora"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continua"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opcions d\'inici de sessió"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opcions d\'inici de sessió"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Gestiona els inicis de sessió"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Tria un inici de sessió"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Tria una clau d\'accés"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Tria una contrasenya"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Inicia la sessió al telèfon"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Sense informació d\'inici de sessió"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Toca per desbloquejar"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-cs/strings.xml b/packages/CredentialManager/wear/res/values-cs/strings.xml
new file mode 100644
index 000000000000..ba60a8c6440a
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-cs/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Správce oprávnění"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Použít přístupový klíč?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Použít heslo?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Zavřít"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Pokračovat"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Možnosti přihlášení"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Možnosti přihlášení"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Spravovat přihlášení"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Vyberte přihlášení"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Vyberte přístupový klíč"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Vyberte heslo"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Přihlásit se z telefonu"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Žádné informace o přihlášení"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Klepnutím odemknete"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-da/strings.xml b/packages/CredentialManager/wear/res/values-da/strings.xml
new file mode 100644
index 000000000000..d4450673ffb6
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-da/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Loginadministrator"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Vil du bruge en adgangsnøgle?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Vil du bruge en adgangskode?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Luk"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Fortsæt"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Loginmetoder"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Loginmetoder"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Administrer loginmetoder"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Vælg et login"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Vælg adgangsnøgle"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Vælg adgangskode"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Log ind via telefonen"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Ingen loginoplysninger"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tryk for at låse op"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-de/strings.xml b/packages/CredentialManager/wear/res/values-de/strings.xml
new file mode 100644
index 000000000000..b5107c5f158b
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-de/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Passkey verwenden?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Passwort verwenden?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Schließen"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Weiter"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Anmeldeoptionen"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Anmeldeoptionen"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Anmeldungen verwalten"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Anmeldung auswählen"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Passkey auswählen"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Passwort auswählen"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Auf dem Smartphone anmelden"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Keine Anmeldedaten"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Zum Entsperren tippen"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-el/strings.xml b/packages/CredentialManager/wear/res/values-el/strings.xml
new file mode 100644
index 000000000000..ca241273022f
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-el/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Διαχείριση διαπιστευτηρίων"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Χρήση κλειδιού πρόσβασης;"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Χρήση κωδικού πρόσβασης;"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Παράβλεψη"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Συνέχεια"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Επιλογές σύνδεσης"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Επιλογές σύνδεσης"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Διαχείριση στοιχείων σύνδεσης"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Επιλογή σύνδεσης"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Επιλογή κλειδιού πρόσβασης"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Επιλογή κωδικού πρόσβασης"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Σύνδεση στο τηλέφωνο"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Δεν υπάρχουν πληροφορίες σύνδεσης"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Πατήστε για ξεκλείδωμα"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-en-rAU/strings.xml b/packages/CredentialManager/wear/res/values-en-rAU/strings.xml
new file mode 100644
index 000000000000..75a0a0067e31
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-en-rAU/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Use passkey?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Use password?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Dismiss"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continue"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Sign-in options"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Sign-in options"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Manage sign-ins"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Choose a sign-in"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Choose passkey"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Choose password"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Sign in on phone"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"No sign-in info"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tap to unlock"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-en-rCA/strings.xml b/packages/CredentialManager/wear/res/values-en-rCA/strings.xml
new file mode 100644
index 000000000000..a8a2b7aa7f63
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-en-rCA/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Use passkey?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Use password?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Dismiss"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continue"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Sign-in Options"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Sign-in Options"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Manage sign-ins"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Choose a sign in"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Choose passkey"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Choose password"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Sign in on phone"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"No sign-in info"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tap to unlock"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-en-rGB/strings.xml b/packages/CredentialManager/wear/res/values-en-rGB/strings.xml
new file mode 100644
index 000000000000..75a0a0067e31
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-en-rGB/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Use passkey?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Use password?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Dismiss"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continue"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Sign-in options"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Sign-in options"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Manage sign-ins"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Choose a sign-in"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Choose passkey"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Choose password"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Sign in on phone"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"No sign-in info"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tap to unlock"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-en-rIN/strings.xml b/packages/CredentialManager/wear/res/values-en-rIN/strings.xml
new file mode 100644
index 000000000000..75a0a0067e31
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-en-rIN/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Use passkey?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Use password?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Dismiss"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continue"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Sign-in options"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Sign-in options"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Manage sign-ins"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Choose a sign-in"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Choose passkey"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Choose password"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Sign in on phone"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"No sign-in info"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tap to unlock"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-en-rXC/strings.xml b/packages/CredentialManager/wear/res/values-en-rXC/strings.xml
new file mode 100644
index 000000000000..fbdd5cfff1dc
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-en-rXC/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎Credential Manager‎‏‎‎‏‎"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎Use passkey?‎‏‎‎‏‎"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎Use password?‎‏‎‎‏‎"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‏‎‏‏‎Dismiss‎‏‎‎‏‎"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎Continue‎‏‎‎‏‎"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎Sign-in Options‎‏‎‎‏‎"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎Sign-in Options‎‏‎‎‏‎"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎Manage sign-ins‎‏‎‎‏‎"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎Choose a sign in‎‏‎‎‏‎"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎Choose passkey‎‏‎‎‏‎"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎Choose password‎‏‎‎‏‎"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎Sign in on phone‎‏‎‎‏‎"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‏‎No sign-in info‎‏‎‎‏‎"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎Tap to unlock‎‏‎‎‏‎"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-es-rUS/strings.xml b/packages/CredentialManager/wear/res/values-es-rUS/strings.xml
new file mode 100644
index 000000000000..97bb3e056ec8
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-es-rUS/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"¿Quieres usar una llave de acceso?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"¿Quieres usar una contraseña?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Descartar"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continuar"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opción para acceder"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opción para acceder"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Administrar accesos"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Elige un acceso"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Elige una llave de acceso"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Elige una contraseña"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Acceder desde el teléfono"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"No hay información de acceso"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Presiona para desbloquear"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-es/strings.xml b/packages/CredentialManager/wear/res/values-es/strings.xml
new file mode 100644
index 000000000000..275ac147ce3c
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-es/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Gestor de credenciales"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"¿Usar llave de acceso?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"¿Usar contraseña?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Cerrar"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continuar"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opciones de inicio de sesión"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opciones de inicio de sesión"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Gestionar inicios de sesión"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Elige un inicio de sesión"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Elige una llave de acceso"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Elige una contraseña"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Iniciar sesión en el teléfono"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"No hay información de inicio de sesión"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Toca para desbloquear"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-et/strings.xml b/packages/CredentialManager/wear/res/values-et/strings.xml
new file mode 100644
index 000000000000..c1fdc61e6048
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-et/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Mandaatide haldur"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Kas kasutada pääsuvõtit?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Kas kasutada parooli?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Loobu"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Jätka"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Sisselogimise valikud"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Sisselogimise valikud"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Sisselogimisteabe haldamine"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Valige sisselogimisteave"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Valige pääsuvõti"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Valige parool"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Logi telefonis sisse"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Sisselogimisteave puudub"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Avamiseks puudutage"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-eu/strings.xml b/packages/CredentialManager/wear/res/values-eu/strings.xml
new file mode 100644
index 000000000000..352164b2bb35
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-eu/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Sarbide-gako bat erabili nahi duzu?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Pasahitz bat erabili nahi duzu?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Baztertu"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Egin aurrera"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Saioa hasteko moduak"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Saioa hasteko moduak"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Kudeatu saioa hasteko moduak"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Aukeratu saioa hasteko modu bat"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Aukeratu sarbide-gako bat"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Aukeratu pasahitz bat"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Hasi saioa telefonoan"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Ez dago saioa hasteko informaziorik"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Desblokeatzeko, sakatu hau"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-fa/strings.xml b/packages/CredentialManager/wear/res/values-fa/strings.xml
new file mode 100644
index 000000000000..80537695c95c
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-fa/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"از گذرکلید استفاده می‌کنید؟"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"از گذرواژه استفاده می‌کنید؟"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"رد کردن"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"ادامه"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"گزینه‌های ورود به سیستم"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"گزینه‌های ورود به سیستم"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"مدیریت ورود به سیستم"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"ورود به سیستم را انتخاب کنید"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"گذرکلید را انتخاب کنید"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"گذرواژه را انتخاب کنید"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ورود به سیستم در تلفن"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"اطلاعات ورود به سیستم موجود نیست"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"برای باز کردن قفل، تک‌ضرب بزنید"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-fi/strings.xml b/packages/CredentialManager/wear/res/values-fi/strings.xml
new file mode 100644
index 000000000000..855f025e1b81
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-fi/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Kirjautumistietojen hallinta"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Käytetäänkö avainkoodia?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Käytetäänkö salasanaa?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Hylkää"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Jatka"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Kirjautumisvaihtoehdot"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Kirjautumisvaihtoehdot"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Muuta kirjautumistietoja"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Valitse kirjautumistapa"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Valitse avainkoodi"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Valitse salasana"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Kirjaudu sisään puhelimella"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Ei kirjautumistietoja"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Avaa napauttamalla"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-fr-rCA/strings.xml b/packages/CredentialManager/wear/res/values-fr-rCA/strings.xml
new file mode 100644
index 000000000000..6a04cbb29861
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-fr-rCA/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Gestionnaire d\'authentifiants"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Utiliser la clé d\'accès?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Utiliser le mot de passe?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Fermer"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continuer"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Options de connexion"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Options de connexion"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Gérer les identifiants de connexion"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Choisir un identifiant de connexion"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Choisir la clé d\'accès"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Choisir le mot de passe"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Se connecter sur le téléphone"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Aucun renseignement de connexion"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Toucher pour déverrouiller"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-fr/strings.xml b/packages/CredentialManager/wear/res/values-fr/strings.xml
new file mode 100644
index 000000000000..fbecd31fb95a
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-fr/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Utiliser la clé d\'accès ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Utiliser le mot de passe ?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Ignorer"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continuer"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Options de connexion"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Options de connexion"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Gérer les connexions"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Choisir une connexion"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Choisir une clé d\'accès"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Choisir un mot de passe"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Se connecter sur le téléphone"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Aucune information de connexion"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Appuyer pour déverrouiller"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-gl/strings.xml b/packages/CredentialManager/wear/res/values-gl/strings.xml
new file mode 100644
index 000000000000..376b08f48d80
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-gl/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Queres usar a clave de acceso?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Queres usar o contrasinal?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Pechar"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continuar"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opcións de inicio de sesión"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opcións de inicio de sesión"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Xestionar os métodos de inicio de sesión"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Seleccionar un método de inicio de sesión"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Seleccionar unha clave de acceso"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Seleccionar un contrasinal"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Iniciar sesión no teléfono"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Sen información de inicio de sesión"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Toca para desbloquear"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-gu/strings.xml b/packages/CredentialManager/wear/res/values-gu/strings.xml
new file mode 100644
index 000000000000..ff8d2989253a
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-gu/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"લૉગ ઇન વિગતોના મેનેજર"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"પાસકીનો ઉપયોગ કરીએ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"પાસવર્ડનો ઉપયોગ કરીએ?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"છોડી દો"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"ચાલુ રાખો"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"સાઇન-ઇનના વિકલ્પો"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"સાઇન-ઇનના વિકલ્પો"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"સાઇન-ઇન મેનેજ કરો"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"સાઇન ઇન કરવાની કોઈ રીત પસંદ કરો"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"પાસકી પસંદ કરો"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"પાસવર્ડ પસંદ કરો"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ફોન પર સાઇન ઇન કરો"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"કોઈ સાઇન-ઇન માહિતી નથી"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"અનલૉક કરવા માટે ટૅપ કરો"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-hi/strings.xml b/packages/CredentialManager/wear/res/values-hi/strings.xml
new file mode 100644
index 000000000000..a061453e72a4
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-hi/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"क्या आपको पासकी का इस्तेमाल करना है?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"क्या आपको पासवर्ड का इस्तेमाल करना है?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"खारिज करें"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"जारी रखें"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"साइन इन करने के विकल्प"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"साइन इन करने के विकल्प"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"साइन-इन क्रेडेंशियल मैनेज करें"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"साइन इन करने का कोई तरीका चुनें"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"कोई पासकी चुनें"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"कोई पासवर्ड चुनें"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"फ़ोन पर साइन इन करें"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"साइन-इन के लिए कोई क्रेडेंशियल मौजूद नहीं है"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"अनलॉक करने के लिए टैप करें"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-hr/strings.xml b/packages/CredentialManager/wear/res/values-hr/strings.xml
new file mode 100644
index 000000000000..2adcad5bf0af
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-hr/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Upravitelj vjerodajnicama"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Želite li upotrijebiti pristupni ključ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Želite li upotrijebiti zaporku?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Odbaci"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Nastavi"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opcije prijave"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opcije prijave"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Upravljanje prijavama"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Odaberite prijavu"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Odaberite pristupni ključ"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Odaberite zaporku"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Prijavite se na telefonu"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Nema podataka o prijavi"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Dodirnite za otključavanje"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-hu/strings.xml b/packages/CredentialManager/wear/res/values-hu/strings.xml
new file mode 100644
index 000000000000..f2cb4975ce4e
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-hu/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Tanúsítványkezelő"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Azonosítókulcsot szeretne használni?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Jelszót szeretne használni?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Elvetés"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Tovább"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Bejelentkezési lehetőségek"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Bejelentkezési lehetőségek"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Bejelentkezési adatok kezelése"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Bejelentkezési mód kiválasztása"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Azonosítókulcs kiválasztása"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Jelszó kiválasztása"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Bejelentkezés telefonon"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Nincsenek bejelentkezési adatok"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Koppintson ide a feloldáshoz"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-hy/strings.xml b/packages/CredentialManager/wear/res/values-hy/strings.xml
new file mode 100644
index 000000000000..cea111294f36
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-hy/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Մուտքի տվյալների կառավարիչ"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Օգտագործե՞լ մուտքի բանալին"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Օգտագործե՞լ գաղտնաբառը"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Փակել"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Շարունակել"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Մուտք գործելու եղանակներ"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Մուտք գործելու եղանակներ"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Մուտքի կառավարում"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Ընտրեք մուտք գործելու եղանակը"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Ընտրեք մուտքի բանալին"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Ընտրեք գաղտնաբառը"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Մուտք գործել հեռախոսում"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Մուտքի տվյալներ չկան"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Հպեք ապակողպելու համար"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-in/strings.xml b/packages/CredentialManager/wear/res/values-in/strings.xml
new file mode 100644
index 000000000000..2e527e253976
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-in/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Gunakan kunci sandi?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Gunakan sandi?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Tutup"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Lanjutkan"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opsi Login"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opsi Login"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Kelola login"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Pilih login"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Pilih kunci sandi"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Pilih sandi"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Login di ponsel"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Tidak ada info login"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Ketuk untuk membuka kunci"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-is/strings.xml b/packages/CredentialManager/wear/res/values-is/strings.xml
new file mode 100644
index 000000000000..fcd9ce59ee9d
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-is/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Skilríkjastjórnun"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Nota aðgangslykil?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Nota aðgangsorð?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Hunsa"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Halda áfram"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Innskráningarkostir"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Innskráningarkostir"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Stjórna innskráningu"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Velja innskráningu"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Velja aðgangslykil"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Velja aðgangsorð"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Skráðu þig inn á síma"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Engar innskráningarupplýsingar"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Ýttu til að opna"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-it/strings.xml b/packages/CredentialManager/wear/res/values-it/strings.xml
new file mode 100644
index 000000000000..0b398fda87b9
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-it/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Gestore delle credenziali"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Vuoi utilizzare la passkey?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Vuoi utilizzare la password?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Ignora"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continua"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opzioni di accesso"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opzioni di accesso"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Gestisci gli accessi"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Scegli un accesso"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Scegli passkey"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Scegli password"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Accedi dallo smartphone"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Nessun dato di accesso"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tocca per sbloccare"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-iw/strings.xml b/packages/CredentialManager/wear/res/values-iw/strings.xml
new file mode 100644
index 000000000000..4fb203d43386
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-iw/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"להשתמש במפתח גישה?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"להשתמש בסיסמה?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"סגירה"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"המשך"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"אמצעי כניסה"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"אמצעי כניסה"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"ניהול הכניסות"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"בחירת אמצעי כניסה"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"בחירת מפתח גישה"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"בחירת סיסמה"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"כניסה לחשבון בטלפון"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"אין פרטי כניסה"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"צריך להקיש כדי לבטל את הנעילה"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ja/strings.xml b/packages/CredentialManager/wear/res/values-ja/strings.xml
new file mode 100644
index 000000000000..05a04e32a94d
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ja/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"認証情報マネージャー"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"パスキーを使用しますか?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"パスワードを使用しますか?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"閉じる"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"続行"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ログイン オプション"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"ログイン オプション"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"ログインの管理"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"ログインの選択"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"パスキーの選択"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"パスワードの選択"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"スマートフォンでログイン"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ログイン情報はありません"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"タップしてロック解除"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ka/strings.xml b/packages/CredentialManager/wear/res/values-ka/strings.xml
new file mode 100644
index 000000000000..2164d1ec7f6a
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ka/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"ავტორიზაციის მონაცემების მმართველი"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"გსურთ წვდომის გასაღების გამოყენება?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"გსურთ პაროლის გამოყენება?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"დახურვა"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"გაგრძელება"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"სისტემაში შესვლის ვარიანტები"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"სისტემაში შესვლის ვარიანტები"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"სისტემაში შესვლის მართვა"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"სისტემაში შესვლის არჩევა"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"წვდომის გასაღების არჩევა"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"პაროლის არჩევა"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"სისტემაში შესვლა ტელეფონით"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"სისტემაში შესვლისთვის ინფორმაცია არ არის"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"შეეხეთ განსაბლოკად"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-kk/strings.xml b/packages/CredentialManager/wear/res/values-kk/strings.xml
new file mode 100644
index 000000000000..ca6cd7db8998
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-kk/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Тіркелу деректері менеджері"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Кіру кілтін пайдалану керек пе?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Құпия сөзін пайдалану керек пе?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Жабу"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Жалғастыру"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Аккаунтқа кіру әдістері"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Аккаунтқа кіру әдістері"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Аккаунтқа кіру әрекеттерін басқару"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Аккаунтқа кіру жолын таңдаңыз"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Кіру кілтін таңдаңыз"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Құпия сөз таңдаңыз"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Аккаунтқа телефон арқылы кіру"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Аккаунтқа кіру ақпараты жоқ."</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Құлыпты ашу үшін түртіңіз."</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-km/strings.xml b/packages/CredentialManager/wear/res/values-km/strings.xml
new file mode 100644
index 000000000000..9dcaeb87c891
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-km/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"ប្រើកូដសម្ងាត់ឬ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"ប្រើពាក្យ​សម្ងាត់ឬ?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"ច្រានចោល"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"បន្ត"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ជម្រើសចូលគណនី"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"ជម្រើសចូលគណនី"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"គ្រប់គ្រងការចូល​គណនី"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"ជ្រើសរើសការចូល​គណនី"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"ជ្រើសរើសកូដសម្ងាត់"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"ជ្រើសរើសពាក្យ​សម្ងាត់"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ចូលនៅលើទូរសព្ទ"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"គ្មានព័ត៌មានចូលគណនីទេ"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ចុចដើម្បីដោះសោ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-kn/strings.xml b/packages/CredentialManager/wear/res/values-kn/strings.xml
new file mode 100644
index 000000000000..fc2f65eecf22
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-kn/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"ಕ್ರೆಡೆನ್ಶಿಯಲ್ ಮ್ಯಾನೇಜರ್"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"ಪಾಸ್‌ಕೀ ಅನ್ನು ಬಳಸಬೇಕೆ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ಬಳಸಬೇಕೆ?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"ವಜಾಗೊಳಿಸಿ"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"ಮುಂದುವರಿಸಿ"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ಸೈನ್ ಇನ್ ಆಯ್ಕೆಗಳು"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"ಸೈನ್ ಇನ್ ಆಯ್ಕೆಗಳು"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"ಸೈನ್-ಇನ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"ಸೈನ್-ಇನ್ ಅನ್ನು ಆರಿಸಿ"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"ಪಾಸ್‌ಕೀ ಅನ್ನು ಆರಿಸಿ"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ಆರಿಸಿ"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ಫೋನ್‌ನಲ್ಲಿ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ಯಾವುದೇ ಸೈನ್ ಇನ್ ಮಾಹಿತಿಯಿಲ್ಲ"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ko/strings.xml b/packages/CredentialManager/wear/res/values-ko/strings.xml
new file mode 100644
index 000000000000..a07fb2ab6e21
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ko/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"인증 관리자"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"패스키를 사용하시겠습니까?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"비밀번호를 사용하시겠습니까?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"닫기"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"계속"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"로그인 옵션"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"로그인 옵션"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"로그인 정보 관리"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"로그인 선택"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"패스키 선택"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"비밀번호 선택"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"휴대전화에서 로그인하기"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"로그인 정보 없음"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"탭하여 잠금 해제하기"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ky/strings.xml b/packages/CredentialManager/wear/res/values-ky/strings.xml
new file mode 100644
index 000000000000..418d2f19dea0
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ky/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Киргизүүчү ачкычты колдоносузбу?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Сырсөздү колдоносузбу?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Жабуу"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Улантуу"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Аккаунтка кирүү параметрлери"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Аккаунтка кирүү параметрлери"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Кирүү параметрлерин тескөө"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Кирүүнү тандаңыз"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Киргизүүчү ачкычты тандаңыз"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Сырсөздү тандаңыз"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Аккаунтка телефондон кирүү"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Аккаунтка кирүү маалыматы жок"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Кулпусун ачуу үчүн таптаңыз"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-lo/strings.xml b/packages/CredentialManager/wear/res/values-lo/strings.xml
new file mode 100644
index 000000000000..c48f88fa921e
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-lo/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"ຕົວຈັດການຂໍ້ມູນການເຂົ້າສູ່ລະບົບ"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"ໃຊ້ກະແຈຜ່ານບໍ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"ໃຊ້ລະຫັດຜ່ານບໍ?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"ປິດໄວ້"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"ສືບຕໍ່"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ຕົວເລືອກການເຂົ້າສູ່ລະບົບ"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"ຕົວເລືອກການເຂົ້າສູ່ລະບົບ"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"ຈັດການການເຂົ້າສູ່ລະບົບ"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"ເລືອກການເຂົ້າສູ່ລະບົບ"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"ເລືອກກະແຈຜ່ານ"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"ເລືອກລະຫັດຜ່ານ"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ເຂົ້າສູ່ລະບົບຢູ່ໂທລະສັບ"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ບໍ່ມີຂໍ້ມູນການເຂົ້າສູ່ລະບົບ"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ແຕະເພື່ອປົດລັອກ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-lt/strings.xml b/packages/CredentialManager/wear/res/values-lt/strings.xml
new file mode 100644
index 000000000000..b313e874d341
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-lt/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Prisijungimo duomenų tvarkytuvė"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Naudoti prieigos raktą?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Naudoti slaptažodį?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Atsisakyti"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Tęsti"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Prisijungimo parinktys"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Prisijungimo parinktys"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Prisijungimo informacijos tvarkymas"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Pasirinkti prisijungimą"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Pasirinkite prieigos raktus"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Pasirinkite slaptažodį"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Prisijungti telefone"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Prisijungimo informacijos nėra"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Palieskite, kad atrakintumėte"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-lv/strings.xml b/packages/CredentialManager/wear/res/values-lv/strings.xml
new file mode 100644
index 000000000000..efeedec1b837
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-lv/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Akreditācijas datu pārvaldnieks"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Vai izmantot piekļuves atslēgu?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Vai izmantot paroli?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Nerādīt"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Turpināt"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Pierakstīšanās opcijas"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Pierakstīšanās opcijas"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Pierakstīšanās informācijas pārvaldība"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Izvēlieties pierakstīšanās veidu"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Izvēlieties piekļuves atslēgu"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Izvēlieties paroli"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Pierakstīties tālrunī"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Nav pierakstīšanās informācijas"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Pieskarieties, lai atbloķētu"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-mk/strings.xml b/packages/CredentialManager/wear/res/values-mk/strings.xml
new file mode 100644
index 000000000000..a4d807388700
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-mk/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Управување со акредитиви"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Да се користи криптографски клуч?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Да се користи лозинка?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Отфрли"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Продолжи"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Опции за најавување"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Опции за најавување"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Управувајте со најавувањата"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Изберете најавување"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Изберете криптографски клуч"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Изберете лозинка"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Најавете се на телефонот"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Нема податоци за најавување"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Допрете за да отклучите"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ml/strings.xml b/packages/CredentialManager/wear/res/values-ml/strings.xml
new file mode 100644
index 000000000000..a93514809c57
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ml/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"ക്രെഡൻഷ്യൽ മാനേജർ"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"പാസ്‌കീ ഉപയോഗിക്കുക"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"പാസ്‌വേഡ് ഉപയോഗിക്കണോ?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"തുടരുക"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"സൈൻ ഇൻ ചെയ്യൽ ഓപ്ഷനുകൾ"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"സൈൻ ഇൻ ചെയ്യൽ ഓപ്ഷനുകൾ"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"സൈൻ ഇൻ ചെയ്യലുകൾ മാനേജ് ചെയ്യുക"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"ഒരു സൈൻ-ഇൻ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"പാസ്‌കീ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"പാസ്‌കീ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ഫോണിൽ സൈൻ ഇൻ ചെയ്യുക"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"സൈൻ ഇൻ വിവരങ്ങളൊന്നുമില്ല"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"അൺലോക്ക് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-mn/strings.xml b/packages/CredentialManager/wear/res/values-mn/strings.xml
new file mode 100644
index 000000000000..b5772684102c
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-mn/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Мандат үнэмлэхийн менежер"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Нэвтрэх түлхүүр ашиглах уу?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Нууц үг ашиглах уу?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Хаах"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Үргэлжлүүлэх"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Нэвтрэх сонголт"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Нэвтрэх сонголт"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Нэвтрэх сонголтыг удирдах"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Нэвтрэх сонголт хийх"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Нэвтрэх түлхүүр сонгох"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Нууц үг сонгох"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Утсан дээр нэвтрэх"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Ямар ч нэвтрэх мэдээлэл байхгүй"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Түгжээг тайлахын тулд товшино уу"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-mr/strings.xml b/packages/CredentialManager/wear/res/values-mr/strings.xml
new file mode 100644
index 000000000000..e966d308ec21
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-mr/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"क्रेडेंशियल व्यवस्थापक"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"पासकी वापरायची आहे का?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"पासवर्ड वापरायचा आहे का?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"डिसमिस करा"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"पुढे सुरू ठेवा"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"साइन-इन पर्याय"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"साइन-इन पर्याय"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"साइन-इन व्यवस्थापित करा"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"साइन इन निवडा"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"पासकी निवडा"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"पासवर्ड निवडा"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"फोनवर साइन इन करा"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"साइन-इनची कोणतीही माहिती नाही"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"अनलॉक करण्यासाठी टॅप करा"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ms/strings.xml b/packages/CredentialManager/wear/res/values-ms/strings.xml
new file mode 100644
index 000000000000..772bf194c77c
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ms/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Pengurus Bukti Kelayakan"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Gunakan kunci laluan?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Gunakan kata laluan?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Ketepikan"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Teruskan"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Pilihan Log Masuk"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Pilihan Log Masuk"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Urus log masuk"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Pilih log masuk"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Pilih kunci laluan"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Pilih kata laluan"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Log masuk pada telefon"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Tiada maklumat log masuk"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Ketik untuk membuka kunci"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-my/strings.xml b/packages/CredentialManager/wear/res/values-my/strings.xml
new file mode 100644
index 000000000000..7c38b9ef40a8
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-my/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"လျှို့ဝှက်ကီး သုံးမလား။"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"စကားဝှက် သုံးမလား။"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"ပယ်ရန်"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"ရှေ့ဆက်ရန်"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"လက်မှတ်ထိုးဝင်နည်းများ"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"လက်မှတ်ထိုးဝင်နည်းများ"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"လက်မှတ်ထိုးဝင်မှုများ စီမံခြင်း"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"လက်မှတ်ထိုးဝင်မှု ရွေးခြင်း"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"လျှို့ဝှက်ကီးရွေးခြင်း"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"စကားဝှက်ရွေးခြင်း"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ဖုန်းတွင် လက်မှတ်ထိုးဝင်ရန်"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"လက်မှတ်ထိုးဝင်ရန် အချက်အလက် မရှိပါ"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ဖွင့်ရန် တို့ပါ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-nb/strings.xml b/packages/CredentialManager/wear/res/values-nb/strings.xml
new file mode 100644
index 000000000000..0c45c9cdb30a
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-nb/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Legitimasjonsbehandling"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Vil du bruke passnøkkel?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Vil du bruke passord?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Lukk"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Fortsett"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Påloggingsalternativer"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Påloggingsalternativer"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Administrer pålogginger"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Velg en pålogging"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Velg passnøkkel"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Velg passord"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Logg på med telefonen"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Ingen påloggingsinformasjon"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Trykk for å låse opp"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ne/strings.xml b/packages/CredentialManager/wear/res/values-ne/strings.xml
new file mode 100644
index 000000000000..de92acd419c1
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ne/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"क्रिडेन्सियल म्यानेजर"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"पासकी प्रयोग गर्ने हो?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"पासवर्ड प्रयोग गर्ने हो?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"खारेज गर्नुहोस्"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"जारी राख्नुहोस्"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"साइन इनसम्बन्धी विकल्पहरू"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"साइन इनसम्बन्धी विकल्पहरू"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"साइन इनसम्बन्धी जानकारी व्यवस्थापन गर्नुहोस्"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"साइन इन गर्ने तरिका छनौट गर्नुहोस्"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"पासकी छनौट गर्नुहोस्"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"पासवर्ड छनौट गर्नुहोस्"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"फोनमा साइन इन गर्नुहोस्"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"साइन इनसम्बन्धी जानकारी उपलब्ध छैन"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"अनलक गर्न ट्याप गर्नुहोस्"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-nl/strings.xml b/packages/CredentialManager/wear/res/values-nl/strings.xml
new file mode 100644
index 000000000000..1a15ead6abd2
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-nl/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Manager Inloggegevens"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Toegangssleutel gebruiken?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Wachtwoord gebruiken?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Sluiten"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Doorgaan"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Inlogopties"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Inlogopties"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Logins beheren"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Een login kiezen"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Toegangssleutel kiezen"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Wachtwoord kiezen"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Inloggen op telefoon"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Geen inloggegevens"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tik om te ontgrendelen"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-or/strings.xml b/packages/CredentialManager/wear/res/values-or/strings.xml
new file mode 100644
index 000000000000..00270de6e26f
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-or/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"କ୍ରେଡେନସିଆଲ ମେନେଜର"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"ପାସକୀ ବ୍ୟବହାର କରିବେ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"ପାସୱାର୍ଡ ବ୍ୟବହାର କରିବେ?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"ଖାରଜ କରନ୍ତୁ"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"ଜାରି ରଖନ୍ତୁ"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ସାଇନ-ଇନ ବିକଳ୍ପଗୁଡ଼ିକ"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"ସାଇନ-ଇନ ବିକଳ୍ପଗୁଡ଼ିକ"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"ସାଇନ-ଇନ ପରିଚାଳନା କରନ୍ତୁ"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"ଏକ ସାଇନ ଇନ ବାଛନ୍ତୁ"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"ପାସକୀ ବାଛନ୍ତୁ"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"ପାସୱାର୍ଡ ବାଛନ୍ତୁ"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ଫୋନରେ ସାଇନ ଇନ କରନ୍ତୁ"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"କୌଣସି ସାଇନ-ଇନ ସୂଚନା ନାହିଁ"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ଅନଲକ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-pa/strings.xml b/packages/CredentialManager/wear/res/values-pa/strings.xml
new file mode 100644
index 000000000000..a1ba4fd80a6e
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-pa/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"ਕ੍ਰੀਡੈਂਸ਼ੀਅਲ ਪ੍ਰਬੰਧਕ"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"ਕੀ ਪਾਸਕੀ ਨੂੰ ਵਰਤਣਾ ਹੈ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"ਕੀ ਪਾਸਵਰਡ ਨੂੰ ਵਰਤਣਾ ਹੈ?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"ਖਾਰਜ ਕਰੋ"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"ਜਾਰੀ ਰੱਖੋ"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ਸਾਈਨ-ਇਨ ਵਿਕਲਪ"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"ਸਾਈਨ-ਇਨ ਵਿਕਲਪ"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"ਸਾਈਨ-ਇਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"ਸਾਈਨ-ਇਨ ਕਰਨ ਦਾ ਵਿਕਲਪ ਚੁਣੋ"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"ਪਾਸਕੀ ਚੁਣੋ"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"ਪਾਸਵਰਡ ਚੁਣੋ"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ਫ਼ੋਨ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ਕੋਈ ਸਾਈਨ-ਇਨ ਜਾਣਕਾਰੀ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-pl/strings.xml b/packages/CredentialManager/wear/res/values-pl/strings.xml
new file mode 100644
index 000000000000..345a24a617e1
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-pl/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Użyć klucza dostępu?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Użyć hasła?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Zamknij"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Dalej"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opcje logowania"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opcje logowania"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Zarządzanie danymi logowania"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Wybierz dane logowania"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Wybierz klucz dostępu"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Wybierz hasło"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Zaloguj się na telefonie"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Brak danych logowania"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Dotknij, aby odblokować"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-pt-rPT/strings.xml b/packages/CredentialManager/wear/res/values-pt-rPT/strings.xml
new file mode 100644
index 000000000000..acec24c31a41
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-pt-rPT/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Gestor de credenciais"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Usar a chave de acesso?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Usar a palavra-passe?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Ignorar"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continuar"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opções de início de sessão"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opções de início de sessão"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Faça a gestão dos inícios de sessão"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Escolha um início de sessão"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Escolha a chave de acesso"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Escolha a palavra-passe"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Iniciar sessão no telemóvel"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Sem informações de início de sessão"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tocar para desbloquear"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-pt/strings.xml b/packages/CredentialManager/wear/res/values-pt/strings.xml
new file mode 100644
index 000000000000..c451b256b078
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-pt/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Usar chave de acesso?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Usar senha?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Dispensar"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continuar"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opções de login"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opções de login"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Gerenciar logins"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Escolher opção de login"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Escolher chave de acesso"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Escolher senha"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Fazer login no smartphone"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Nenhuma informação de login"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Toque para desbloquear"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ro/strings.xml b/packages/CredentialManager/wear/res/values-ro/strings.xml
new file mode 100644
index 000000000000..adb45ec28c6a
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ro/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Folosești cheia de acces?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Folosești parola?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Închide"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Continuă"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opțiuni de conectare"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opțiuni de conectare"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Gestionează datele de conectare"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Alege setul de date de conectare"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Alege cheia de acces"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Alege parola"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Conectează-te pe telefon"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Fără informații de conectare"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Atinge pentru a debloca"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ru/strings.xml b/packages/CredentialManager/wear/res/values-ru/strings.xml
new file mode 100644
index 000000000000..692e7a7798b9
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ru/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Менеджер учетных данных"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Использовать ключ доступа?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Использовать пароль?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Закрыть"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Продолжить"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Способы входа"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Способы входа"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Управление входом"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Выберите способ входа"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Выберите ключ доступа"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Выберите пароль"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Войти в аккаунт на телефоне"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Нет данных для входа"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Разблокировать"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-si/strings.xml b/packages/CredentialManager/wear/res/values-si/strings.xml
new file mode 100644
index 000000000000..0849e8eeed34
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-si/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"අක්තපත්‍ර කළමනාකරු"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"මුරයතුර භාවිත කරන්න ද?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"මුරපදය භාවිත කරන්න ද?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"අස් කරන්න"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"ඉදිරියට යන්න"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"පුරනය වීමේ විකල්ප"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"පුරනය වීමේ විකල්ප"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"පුරනය වීම් කළමනාකරණය කරන්න"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"පුරනය වීමක් තෝරා ගන්න"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"මුරයතුර තෝරා ගන්න"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"මුරපදය තෝරා ගන්න"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"දුරකථනයෙන් පුරන්න"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"පුරනය වීමේ තතු නැත"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"අගුළු හැරීමට තට්ටු කරන්න"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-sk/strings.xml b/packages/CredentialManager/wear/res/values-sk/strings.xml
new file mode 100644
index 000000000000..fa40ec651f30
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-sk/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Správca prihlasovacích údajov"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Chcete použiť prístupový kľúč?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Chcete použiť heslo?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Zavrieť"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Pokračovať"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Možnosti prihlásenia"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Možnosti prihlásenia"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Správa prihlasovacích údajov"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Vyberte prihlásenie"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Vyberte prístupový kľúč"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Vyberte heslo"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Prihlásiť sa v telefóne"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Žiadne prihlasovacie údaje"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Odomknite klepnutím"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-sl/strings.xml b/packages/CredentialManager/wear/res/values-sl/strings.xml
new file mode 100644
index 000000000000..b76165edb907
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-sl/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Upravitelj poverilnic"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Želite uporabiti ključ za dostop?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Želite uporabiti geslo?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Opusti"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Naprej"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Možnosti prijave"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Možnosti prijave"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Upravljanje podatkov za prijavo"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Izbira prijave"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Izbira ključa za dostop"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Izbira gesla"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Prijava v telefonu"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Ni nobenih podatkov za prijavo"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Dotaknite se, da odklenete"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-sq/strings.xml b/packages/CredentialManager/wear/res/values-sq/strings.xml
new file mode 100644
index 000000000000..246cd0b6308d
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-sq/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Menaxheri i kredencialeve"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Të përdoret çelësi i kalimit?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Të përdoret fjalëkalimi?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Hiq"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Vazhdo"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opsionet për identifikimin"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Opsionet për identifikimin"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Menaxho identifikimet"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Zgjidh një identifikim"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Zgjidh çelësin e kalimit"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Zgjidh fjalëkalimin"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Identifikohu në telefon"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Nuk ka informacione për identifikimin"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Trokit për të shkyçur"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-sr/strings.xml b/packages/CredentialManager/wear/res/values-sr/strings.xml
new file mode 100644
index 000000000000..97cdcbcd99ca
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-sr/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Менаџер акредитива"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Желите да користите приступни кључ?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Желите да користите лозинку?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Одбаци"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Настави"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Опције за пријављивање"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Опције за пријављивање"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Управљајте пријављивањима"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Одаберите пријављивање"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Одаберите приступни кључ"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Одаберите лозинку"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Пријавите се на телефону"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Нема података за пријављивање"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Додирните да бисте откључали"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-sv/strings.xml b/packages/CredentialManager/wear/res/values-sv/strings.xml
new file mode 100644
index 000000000000..2d0254a60465
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-sv/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Vill du använda nyckeln?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Vill du använda lösenordet?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Stäng"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Fortsätt"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Inloggningsalternativ"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Inloggningsalternativ"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Hantera inloggningar"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Välj en inloggning"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Välj nyckel"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Välj lösenord"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Logga in på telefon"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Inga inloggningsuppgifter"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tryck för att låsa upp"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-sw/strings.xml b/packages/CredentialManager/wear/res/values-sw/strings.xml
new file mode 100644
index 000000000000..509c404c7926
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-sw/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Kidhibiti cha Vitambulisho"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Ungependa kutumia ufunguo wa siri?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Ungependa kutumia nenosiri?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Ondoa"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Endelea"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Chaguo za Kuingia katika Akaunti"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Chaguo za Kuingia katika Akaunti"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Dhibiti michakato ya kuingia katika akaunti"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Chagua mbinu ya kuingia katika akaunti"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Chagua ufunguo wa siri"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Chagua nenosiri"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Ingia katika akaunti kwenye simu"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Hakuna maelezo ya kuingia katika akaunti"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Gusa ili ufungue"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ta/strings.xml b/packages/CredentialManager/wear/res/values-ta/strings.xml
new file mode 100644
index 000000000000..9f88c81b45c0
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ta/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"அனுமதிச் சான்று நிர்வாகி"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"கடவுச்சாவியைப் பயன்படுத்தவா?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"கடவுச்சொல்லைப் பயன்படுத்தவா?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"மூடு"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"தொடர்க"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"உள்நுழைவு விருப்பங்கள்"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"உள்நுழைவு விருப்பங்கள்"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"உள்நுழைவுகளை நிர்வகித்தல்"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"உள்நுழைவைத் தேர்வுசெய்தல்"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"கடவுச்சாவியைத் தேர்வுசெய்தல்"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"கடவுச்சொல்லைத் தேர்வுசெய்தல்"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"மொபைலில் உள்நுழைக"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"உள்நுழைவுத் தகவல் இல்லை"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"அன்லாக் செய்ய தட்டவும்"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-te/strings.xml b/packages/CredentialManager/wear/res/values-te/strings.xml
new file mode 100644
index 000000000000..086b109b1933
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-te/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"సైన్-ఇన్ మేనేజర్"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"పాస్-కీని ఉపయోగిస్తారా?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"పాస్‌వర్డ్‌ను ఉపయోగిస్తారా?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"విస్మరించండి"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"కొనసాగించండి"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"సైన్ ఇన్ ఆప్షన్‌లు"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"సైన్ ఇన్ ఆప్షన్‌లు"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"సైన్‌ ఇన్‌లను మేనేజ్ చేయండి"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"సైన్ ఇన్‌ను ఎంచుకోండి"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"పాస్-కీని ఎంచుకోండి"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"పాస్‌వర్డ్‌ను ఎంచుకోండి"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ఫోన్‌లో సైన్ ఇన్ చేయండి"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"సైన్ ఇన్ సమాచారం ఏదీ లేదు"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"అన్‌లాక్ చేయడానికి ట్యాప్ చేయండి"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-th/strings.xml b/packages/CredentialManager/wear/res/values-th/strings.xml
new file mode 100644
index 000000000000..5d4f7998378e
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-th/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"ใช้พาสคีย์ไหม"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"ใช้รหัสผ่านไหม"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"ปิด"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"ต่อไป"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ตัวเลือกการลงชื่อเข้าใช้"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"ตัวเลือกการลงชื่อเข้าใช้"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"จัดการการลงชื่อเข้าใช้"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"เลือกการลงชื่อเข้าใช้"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"เลือกพาสคีย์"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"เลือกรหัสผ่าน"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ลงชื่อเข้าใช้บนโทรศัพท์"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ไม่มีข้อมูลการลงชื่อเข้าใช้"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"แตะเพื่อปลดล็อก"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-tl/strings.xml b/packages/CredentialManager/wear/res/values-tl/strings.xml
new file mode 100644
index 000000000000..bd3e67238882
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-tl/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Gamitin ang passkey?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Gamitin ang password?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"I-dismiss"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Magpatuloy"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Mga Opsyon sa Pag-sign in"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Mga Opsyon sa Pag-sign in"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Pamahalaan ang mga pag-sign in"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Pumili ng pag-sign in"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Pumili ng passkey"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Pumili ng password"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Mag-sign in sa telepono"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Walang impormasyon sa pag-sign in"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"I-tap para i-unlock"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-tr/strings.xml b/packages/CredentialManager/wear/res/values-tr/strings.xml
new file mode 100644
index 000000000000..a4f512bb31e0
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-tr/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Kimlik Bilgisi Yöneticisi"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Geçiş anahtarı kullanılsın mı?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Şifre kullanılsın mı?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Kapat"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Devam"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Oturum açma seçenekleri"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Oturum açma seçenekleri"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Oturum açma bilgilerini yönetin"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Oturum açma bilgilerini seçin"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Geçiş anahtarı seçin"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Şifre seçin"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Telefonda oturum açın"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Oturum açma bilgisi yok"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Kilidi açmak için dokunun"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-uk/strings.xml b/packages/CredentialManager/wear/res/values-uk/strings.xml
new file mode 100644
index 000000000000..78b4db3f64fd
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-uk/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Менеджер облікових даних"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Використати ключ доступу?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Використати пароль?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Закрити"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Продовжити"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Способи входу"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Способи входу"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Керування даними для входу"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Виберіть спосіб входу"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Виберіть ключ доступу"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Виберіть пароль"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Увійти на телефоні"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Немає даних для входу"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Натисніть, щоб розблокувати"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ur/strings.xml b/packages/CredentialManager/wear/res/values-ur/strings.xml
new file mode 100644
index 000000000000..60bf163a1a5f
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ur/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"اسناد مینیجر"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"پاس کی کا استعمال کریں؟"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"پاس ورڈ کا استعمال کریں؟"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"برخاست کریں"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"جاری رکھیں"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"سائن ان کے اختیارات"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"سائن ان کے اختیارات"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"سائن انز کا نظم کریں"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"سائن ان کا انتخاب کریں"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"پاس کی کا انتخاب کریں"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"پاس ورڈ منتخب کریں"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"فون پر سائن ان کریں"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"سائن ان کی کوئی معلومات نہیں"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"غیر مقفل کرنے کیلئے تھپتھپائیں"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-uz/strings.xml b/packages/CredentialManager/wear/res/values-uz/strings.xml
new file mode 100644
index 000000000000..3b630c792032
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-uz/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Hisob maʼlumotlari boshqaruvi"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Kirish kaliti ishlatilsinmi?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Parol ishlatilsinmi?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Yopish"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Davom etish"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Kirish parametrlari"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Kirish parametrlari"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Kirishni boshqarish"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Kirish axborotini tanlash"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Kalit tanlash"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Parol tanlash"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Telefonda hisobga kirish"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Kirish axboroti topilmadi"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Qulfni ochish uchun bosing"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-vi/strings.xml b/packages/CredentialManager/wear/res/values-vi/strings.xml
new file mode 100644
index 000000000000..476d9bcaf9c8
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-vi/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Trình quản lý thông tin xác thực"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Dùng khoá truy cập?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Dùng mật khẩu?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Đóng"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Tiếp tục"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Phương thức đăng nhập"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Phương thức đăng nhập"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Quản lý thông tin đăng nhập"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Chọn một phương thức đăng nhập"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Chọn khoá truy cập"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Chọn mật khẩu"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Đăng nhập trên điện thoại"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Không có thông tin đăng nhập"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Nhấn để mở khoá"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-zh-rCN/strings.xml b/packages/CredentialManager/wear/res/values-zh-rCN/strings.xml
new file mode 100644
index 000000000000..15f0de608a4b
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-zh-rCN/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"要使用通行密钥吗?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"要使用密码吗?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"关闭"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"继续"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"登录方式"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"登录方式"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"管理登录方式"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"选择登录方式"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"选择通行密钥"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"选择密码"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"在手机上登录"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"无登录信息"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"点按即可解锁"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-zh-rHK/strings.xml b/packages/CredentialManager/wear/res/values-zh-rHK/strings.xml
new file mode 100644
index 000000000000..4e0484918baf
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-zh-rHK/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"憑證管理工具"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"要使用密鑰嗎?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"要使用密碼嗎?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"關閉"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"繼續"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"登入方式"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"登入方式"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"管理登入方式"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"選擇登入憑證"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"選擇密鑰"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"選擇密碼"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"在手機上登入"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"沒有登入資料"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"輕按即可解鎖"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-zh-rTW/strings.xml b/packages/CredentialManager/wear/res/values-zh-rTW/strings.xml
new file mode 100644
index 000000000000..82149e3b4a64
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-zh-rTW/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"要使用密碼金鑰嗎?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"要使用密碼嗎?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"關閉"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"繼續"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"登入選項"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"登入選項"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"管理登入憑證"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"選擇登入憑證"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"選擇密碼金鑰"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"選擇密碼"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"在手機上登入"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"沒有登入資訊"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"輕觸即可解鎖"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-zu/strings.xml b/packages/CredentialManager/wear/res/values-zu/strings.xml
new file mode 100644
index 000000000000..c7fd5a8812ed
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-zu/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="7384524142163511792">"Umphathi wokuqinisekisa"</string>
+ <string name="use_passkey_title" msgid="716598039340757817">"Sebenzisa ukhiye wokudlula?"</string>
+ <string name="use_password_title" msgid="4655101984031246476">"Sebenzisa iphasiwedi?"</string>
+ <string name="dialog_dismiss_button" msgid="989567669882005067">"Cashisa"</string>
+ <string name="dialog_continue_button" msgid="8630290044077052145">"Qhubeka"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Okungakhethwa kukho kokungena ngemvume"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"Okungakhethwa kukho kokungena ngemvume"</string>
+ <string name="provider_list_title" msgid="6803918216129492212">"Phatha ukungena ngemvume"</string>
+ <string name="choose_sign_in_title" msgid="3616025924746872202">"Khetha ukungena ngemvume"</string>
+ <string name="choose_passkey_title" msgid="8459270617632817465">"Khetha ukhiye wokudlula"</string>
+ <string name="choose_password_title" msgid="7610721820858017214">"Khetha iphasiwedi"</string>
+ <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Ngena ngemvume kufoni"</string>
+ <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Alukho ulwazi lokungena ngemvume"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Thepha ukuze uvule"</string>
+</resources>
diff --git a/packages/InputDevices/AndroidManifest.xml b/packages/InputDevices/AndroidManifest.xml
index da8c0d3a4f2e..01b0bc7b3052 100644
--- a/packages/InputDevices/AndroidManifest.xml
+++ b/packages/InputDevices/AndroidManifest.xml
@@ -19,5 +19,23 @@
<meta-data android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS"
android:resource="@xml/keyboard_layouts" />
</receiver>
+
+ <receiver android:name=".KeyGlyphMapProvider"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.hardware.input.action.QUERY_KEYBOARD_GLYPH_MAPS" />
+ </intent-filter>
+ <meta-data android:name="android.hardware.input.metadata.KEYBOARD_GLYPH_MAPS"
+ android:resource="@xml/keyboard_glyph_maps" />
+ </receiver>
+
+ <receiver android:name=".OverlayKeyGlyphMapProvider"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.hardware.input.action.QUERY_KEYBOARD_GLYPH_MAPS" />
+ </intent-filter>
+ <meta-data android:name="android.hardware.input.metadata.KEYBOARD_GLYPH_MAPS"
+ android:resource="@xml/keyboard_glyph_maps_overlay" />
+ </receiver>
</application>
</manifest>
diff --git a/packages/InputDevices/res/values-am/strings.xml b/packages/InputDevices/res/values-am/strings.xml
index fd507613a6f5..a6f5f3a7018f 100644
--- a/packages/InputDevices/res/values-am/strings.xml
+++ b/packages/InputDevices/res/values-am/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ታይላንድኛ (ፓታሾት)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"ሰርቢያኛ (ላቲን)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ሞንቴኔግሮኛ (ላቲን)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ሰርቢያኛ (ሲሪሊክኛ)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ሞንቴኔግሮኛ (ሲሪሊክኛ)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ar/strings.xml b/packages/InputDevices/res/values-ar/strings.xml
index ac730385c6e1..f92d0def3b7e 100644
--- a/packages/InputDevices/res/values-ar/strings.xml
+++ b/packages/InputDevices/res/values-ar/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"‏التايلاندية (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"الصربية (اللاتينية)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"لغة الجبل الأسود (اللاتينية)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"الصربية (السيريلية)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"لغة الجبل الأسود (السيريلية)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-as/strings.xml b/packages/InputDevices/res/values-as/strings.xml
index 1162c723ed6c..8084da395175 100644
--- a/packages/InputDevices/res/values-as/strings.xml
+++ b/packages/InputDevices/res/values-as/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"থাই (পাটাচ’টে)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"ছাৰ্বিয়ান (লেটিন)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"মণ্টেনেগ্ৰিণ (লেটিন)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ছাৰ্বিয়ান (চিৰিলিক)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"মণ্টেনেগ্ৰিণ (চিৰিলিক)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-az/strings.xml b/packages/InputDevices/res/values-az/strings.xml
index 6a6a99d10b36..068a771d9c50 100644
--- a/packages/InputDevices/res/values-az/strings.xml
+++ b/packages/InputDevices/res/values-az/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tay (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serb dili (Latın)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Monteneqro dili (Latın)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serb dili (Kiril)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Monteneqro dili (Kiril)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-b+sr+Latn/strings.xml b/packages/InputDevices/res/values-b+sr+Latn/strings.xml
index 96ac10cb8f64..334b03218f91 100644
--- a/packages/InputDevices/res/values-b+sr+Latn/strings.xml
+++ b/packages/InputDevices/res/values-b+sr+Latn/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"tajski (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"srpski (latinica)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"crnogorski (latinica)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srpski (ćirilica)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"crnogorski (ćirilica)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-be/strings.xml b/packages/InputDevices/res/values-be/strings.xml
index e8341a112d7a..c11266512978 100644
--- a/packages/InputDevices/res/values-be/strings.xml
+++ b/packages/InputDevices/res/values-be/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тайская (Патачотэ)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Сербская (лацініца)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Чарнагорская (лацініца)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербская (кірыліца)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Чарнагорская (кірыліца)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-bg/strings.xml b/packages/InputDevices/res/values-bg/strings.xml
index b6a5b0036651..8a650b283f4f 100644
--- a/packages/InputDevices/res/values-bg/strings.xml
+++ b/packages/InputDevices/res/values-bg/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"тайландски (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"сръбски (латиница)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"черногорски (латиница)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"сръбски (кирилица)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"черногорски (кирилица)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-bn/strings.xml b/packages/InputDevices/res/values-bn/strings.xml
index 353b6dc6310f..02ab5075b991 100644
--- a/packages/InputDevices/res/values-bn/strings.xml
+++ b/packages/InputDevices/res/values-bn/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"থাই (পাট্টাচোটে)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"সার্বিয়ান (ল্যাটিন)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"মন্টেনেগ্রিন (ল্যাটিন)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"সার্বিয়ান (সিরিলিক)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"মন্টেনেগ্রিন (সিরিলিক)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-bs/strings.xml b/packages/InputDevices/res/values-bs/strings.xml
index 0145b0ac14ac..e1aef5d67d89 100644
--- a/packages/InputDevices/res/values-bs/strings.xml
+++ b/packages/InputDevices/res/values-bs/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"tajlandski (pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"srpski (latinica)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"crnogorski (latinica)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srpski (ćirilica)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"crnogorski (ćirilica)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ca/strings.xml b/packages/InputDevices/res/values-ca/strings.xml
index d729c9190409..f9b2e5eb342a 100644
--- a/packages/InputDevices/res/values-ca/strings.xml
+++ b/packages/InputDevices/res/values-ca/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbi (llatí)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrí (llatí)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbi (ciríl·lic)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrí (ciríl·lic)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-cs/strings.xml b/packages/InputDevices/res/values-cs/strings.xml
index 170fa58b50b9..72efbc4cc999 100644
--- a/packages/InputDevices/res/values-cs/strings.xml
+++ b/packages/InputDevices/res/values-cs/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"thajština (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"srbština (latinka)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"černohorština (latinka)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srbština (cyrilice)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"černohorština (cyrilice)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-da/strings.xml b/packages/InputDevices/res/values-da/strings.xml
index 47fcfb19ea2b..6ce0b8b9febe 100644
--- a/packages/InputDevices/res/values-da/strings.xml
+++ b/packages/InputDevices/res/values-da/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbisk (latinsk)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrinsk (latinsk)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisk (kyrillisk)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrinsk (kyrillisk)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-de/strings.xml b/packages/InputDevices/res/values-de/strings.xml
index 1f6b65d76c4b..0dc4e2a0aa49 100644
--- a/packages/InputDevices/res/values-de/strings.xml
+++ b/packages/InputDevices/res/values-de/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thailändisch (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbisch (lat. Alphabet)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrinisch (lat. Alphabet)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisch (kyrillisch)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrinisch (kyrillisch)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-el/strings.xml b/packages/InputDevices/res/values-el/strings.xml
index 2a9dd8c42537..08357db6b06b 100644
--- a/packages/InputDevices/res/values-el/strings.xml
+++ b/packages/InputDevices/res/values-el/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Ταϊλανδικά (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Σερβικά (Λατινικά)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Μαυροβουνιακά (Λατινικά)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Σερβικά (Κυριλλικά)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Μαυροβουνιακά (Κυριλλικά)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-en-rAU/strings.xml b/packages/InputDevices/res/values-en-rAU/strings.xml
index e27fb6416b6d..0e9e6ebb7f38 100644
--- a/packages/InputDevices/res/values-en-rAU/strings.xml
+++ b/packages/InputDevices/res/values-en-rAU/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbian (Latin)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-en-rGB/strings.xml b/packages/InputDevices/res/values-en-rGB/strings.xml
index e27fb6416b6d..0e9e6ebb7f38 100644
--- a/packages/InputDevices/res/values-en-rGB/strings.xml
+++ b/packages/InputDevices/res/values-en-rGB/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbian (Latin)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-en-rIN/strings.xml b/packages/InputDevices/res/values-en-rIN/strings.xml
index e27fb6416b6d..0e9e6ebb7f38 100644
--- a/packages/InputDevices/res/values-en-rIN/strings.xml
+++ b/packages/InputDevices/res/values-en-rIN/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbian (Latin)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-es-rUS/strings.xml b/packages/InputDevices/res/values-es-rUS/strings.xml
index 049edf494b71..321b9a595dfa 100644
--- a/packages/InputDevices/res/values-es-rUS/strings.xml
+++ b/packages/InputDevices/res/values-es-rUS/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tailandés (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbio (latino)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latino)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbio (cirílico)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-es/strings.xml b/packages/InputDevices/res/values-es/strings.xml
index b6e27c537969..98076524b5e8 100644
--- a/packages/InputDevices/res/values-es/strings.xml
+++ b/packages/InputDevices/res/values-es/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tailandés (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbio (latino)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latino)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbio (cirílico)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-et/strings.xml b/packages/InputDevices/res/values-et/strings.xml
index cecf304d1c11..eb7ea9fd2843 100644
--- a/packages/InputDevices/res/values-et/strings.xml
+++ b/packages/InputDevices/res/values-et/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbia (ladina)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegro (ladina)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbia (kirillitsa)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegro (kirillitsa)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-eu/strings.xml b/packages/InputDevices/res/values-eu/strings.xml
index 481b315bf413..53707598b264 100644
--- a/packages/InputDevices/res/values-eu/strings.xml
+++ b/packages/InputDevices/res/values-eu/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thailandiarra (pattachote-a)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbiarra (latindarra)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegroarra (latindarra)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbiarra (zirilikoa)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegroarra (zirilikoa)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-fa/strings.xml b/packages/InputDevices/res/values-fa/strings.xml
index 9614fef9396c..9bbf4e36fa16 100644
--- a/packages/InputDevices/res/values-fa/strings.xml
+++ b/packages/InputDevices/res/values-fa/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"تایلندی (پاتاچوته)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"صربی (لاتین)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"مونته‌نگرویی (لاتین)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"صربی (سیریلیک)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"مونته‌نگرویی (سیریلیک)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-fi/strings.xml b/packages/InputDevices/res/values-fi/strings.xml
index afae51ba623c..3e88c2085373 100644
--- a/packages/InputDevices/res/values-fi/strings.xml
+++ b/packages/InputDevices/res/values-fi/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"thai (pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"serbia (latinalainen)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"montenegro (latinalainen)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbia (kyrillinen)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegro (kyrillinen)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-fr-rCA/strings.xml b/packages/InputDevices/res/values-fr-rCA/strings.xml
index f2d79df6d469..690fbad6ab12 100644
--- a/packages/InputDevices/res/values-fr-rCA/strings.xml
+++ b/packages/InputDevices/res/values-fr-rCA/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thaï (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbe (latin)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Monténégrin (latin)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbe (cyrillique)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Monténégrin (cyrillique)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-fr/strings.xml b/packages/InputDevices/res/values-fr/strings.xml
index 61891c3dad50..70bd250738f7 100644
--- a/packages/InputDevices/res/values-fr/strings.xml
+++ b/packages/InputDevices/res/values-fr/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thaï (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbe (latin)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Monténégrin (latin)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbe (cyrillique)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Monténégrin (cyrillique)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-gu/strings.xml b/packages/InputDevices/res/values-gu/strings.xml
index f04b2d2c1453..3f1b31a8a6c8 100644
--- a/packages/InputDevices/res/values-gu/strings.xml
+++ b/packages/InputDevices/res/values-gu/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"થાઇ (પટ્ટાશોટે)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"સર્બિયન (લેટિન)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"મોંટેનેગ્રીન (લેટિન)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"સર્બિયન (સિરિલિક)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"મોંટેનેગ્રીન (સિરિલિક)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-hi/strings.xml b/packages/InputDevices/res/values-hi/strings.xml
index 1017ef118822..db59ebac7805 100644
--- a/packages/InputDevices/res/values-hi/strings.xml
+++ b/packages/InputDevices/res/values-hi/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"थाई (पटैचोटे)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"सर्बियन (लैटिन)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"मॉन्टेनीग्रिन (लैटिन)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"सर्बियन (सिरिलिक)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"मोंटेनेग्रिन (सिरिलिक)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-hr/strings.xml b/packages/InputDevices/res/values-hr/strings.xml
index bc630bc35108..905dce25b4aa 100644
--- a/packages/InputDevices/res/values-hr/strings.xml
+++ b/packages/InputDevices/res/values-hr/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"tajski (pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"srpski (latinica)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"crnogorski (latinica)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srpski (ćirilica)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"crnogorski (ćirilica)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-hu/strings.xml b/packages/InputDevices/res/values-hu/strings.xml
index 5155543c2318..4c8e7b8de6ba 100644
--- a/packages/InputDevices/res/values-hu/strings.xml
+++ b/packages/InputDevices/res/values-hu/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"thai (pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"szerb (latin betűs)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"montenegrói (latin betűs)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"szerb (cirill betűs)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegrói (cirill betűs)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-hy/strings.xml b/packages/InputDevices/res/values-hy/strings.xml
index 8097438055eb..ae56fc5b1620 100644
--- a/packages/InputDevices/res/values-hy/strings.xml
+++ b/packages/InputDevices/res/values-hy/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"թայերեն (պատաչոտ)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"սերբերեն (լատինատառ)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"չեռնոգորերեն (լատինատառ)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"սերբերեն (կյուրեղատառ)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"չեռնոգորերեն (կյուրեղատառ)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-in/strings.xml b/packages/InputDevices/res/values-in/strings.xml
index 1c52e9c3a569..52bc03943abd 100644
--- a/packages/InputDevices/res/values-in/strings.xml
+++ b/packages/InputDevices/res/values-in/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbia (Latin)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegro (Latin)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbia (Sirilik)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegro (Sirilik)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-is/strings.xml b/packages/InputDevices/res/values-is/strings.xml
index bf428bae38c3..0f516cef370e 100644
--- a/packages/InputDevices/res/values-is/strings.xml
+++ b/packages/InputDevices/res/values-is/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Taílenskt (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbneska (latneskt)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Svartfellska (latneskt)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbneska (kyrillískt)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Svartfellska (kyrillískt)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-it/strings.xml b/packages/InputDevices/res/values-it/strings.xml
index bb3b12cc2d5c..f77b87cc67be 100644
--- a/packages/InputDevices/res/values-it/strings.xml
+++ b/packages/InputDevices/res/values-it/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbo (latino)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latino)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbo (cirillico)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirillico)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-iw/strings.xml b/packages/InputDevices/res/values-iw/strings.xml
index f44235a1fec6..0e400e2d0fa4 100644
--- a/packages/InputDevices/res/values-iw/strings.xml
+++ b/packages/InputDevices/res/values-iw/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"‏תאית (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"סרבית (לטינית)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"מונטנגרית (לטינית)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"סרבית (אותיות קיריליות)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"מונטנגרית (אותיות קיריליות)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ja/strings.xml b/packages/InputDevices/res/values-ja/strings.xml
index 55b9642d612b..b1830ebda199 100644
--- a/packages/InputDevices/res/values-ja/strings.xml
+++ b/packages/InputDevices/res/values-ja/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"タイ語(Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"セルビア語(ラテン文字)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"モンテネグロ語(ラテン)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"セルビア語(キリル)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"モンテネグロ語(キリル)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ka/strings.xml b/packages/InputDevices/res/values-ka/strings.xml
index 8696fb26c0fb..75c72b91df94 100644
--- a/packages/InputDevices/res/values-ka/strings.xml
+++ b/packages/InputDevices/res/values-ka/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ტაილანდური (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"სერბული (ლათინური)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"მონტენეგრული (ლათინური)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"სერბული (კირილიცა)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"მონტენეგრული (კირილიცა)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-kk/strings.xml b/packages/InputDevices/res/values-kk/strings.xml
index 2e7236c25c84..c0a58685bc52 100644
--- a/packages/InputDevices/res/values-kk/strings.xml
+++ b/packages/InputDevices/res/values-kk/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тай (паттачот)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Серб (латын жазуы)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Черногор (латын жазуы)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербия (кириллица)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Черногория (кириллица)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-km/strings.xml b/packages/InputDevices/res/values-km/strings.xml
index 2689258ad8ab..6c3db64fa1e9 100644
--- a/packages/InputDevices/res/values-km/strings.xml
+++ b/packages/InputDevices/res/values-km/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ថៃ (ប៉ាតាឈោត)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"ស៊ែប៊ី (ឡាតាំង)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ម៉ុងតេណេហ្គ្រោ (ឡាតាំង)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"សែប៊ី (ស៊ីរីលីក)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ម៉ុងតេណេហ្គ្រោ (ស៊ីរីលីក)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-kn/strings.xml b/packages/InputDevices/res/values-kn/strings.xml
index 34d90535a775..0f4c5229c4d4 100644
--- a/packages/InputDevices/res/values-kn/strings.xml
+++ b/packages/InputDevices/res/values-kn/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ಥಾಯ್ (ಪಟ್ಟಚೋಟ್)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"ಸೆರ್ಬಿಯನ್ (ಲ್ಯಾಟಿನ್)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ಮೊಂಟೆನೆಗ್ರಿನ್ (ಲ್ಯಾಟಿನ್)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ಸೆರ್ಬಿಯನ್ (ಸಿರಿಲಿಕ್)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ಮೊಂಟೆನೆಗ್ರಿನ್ (ಸಿರಿಲಿಕ್)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ko/strings.xml b/packages/InputDevices/res/values-ko/strings.xml
index ad99961cc813..dcfb3b4ece40 100644
--- a/packages/InputDevices/res/values-ko/strings.xml
+++ b/packages/InputDevices/res/values-ko/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"태국어(Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"세르비아어(로마자)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"몬테네그로어(로마자)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"세르비아어(키릴 자모)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"몬테네그로어(키릴)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ky/strings.xml b/packages/InputDevices/res/values-ky/strings.xml
index 79ff71e04cc2..c0b3d3a1d9b3 100644
--- a/packages/InputDevices/res/values-ky/strings.xml
+++ b/packages/InputDevices/res/values-ky/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тайча (Pattachote баскычтобу)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Сербче (Латын)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Монтенегрочо (Латын)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербче (Кирилл)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Черногориялыкча (Кирилл)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-lo/strings.xml b/packages/InputDevices/res/values-lo/strings.xml
index 2427d1c9b672..c2e5a2beded5 100644
--- a/packages/InputDevices/res/values-lo/strings.xml
+++ b/packages/InputDevices/res/values-lo/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ໄທ (ປັດຕະໂຊຕິ)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"ເຊີບຽນ (ລາຕິນ)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ມອນເທເນກຣິນ (ລາຕິນ)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ເຊີບຽນ (ຊີຣິວລິກ)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ມອນເທເນກຣິນ (ຊີຣິວລິກ)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-lt/strings.xml b/packages/InputDevices/res/values-lt/strings.xml
index 48010bc3a66b..9a98e8eb5b13 100644
--- a/packages/InputDevices/res/values-lt/strings.xml
+++ b/packages/InputDevices/res/values-lt/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tajų („Pattachote“)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbų (lotynų rašmenys)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Juodkalniečių (lotynų rašmenys)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbų (kirilica)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Juodkalniečių (kirilica)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-lv/strings.xml b/packages/InputDevices/res/values-lv/strings.xml
index a2e8f8fd2972..d3422b210757 100644
--- a/packages/InputDevices/res/values-lv/strings.xml
+++ b/packages/InputDevices/res/values-lv/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Taju (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbu (latīņu)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Melnkalniešu (latīņu)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbu (kirilica)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Melnkalniešu (kirilica)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-mk/strings.xml b/packages/InputDevices/res/values-mk/strings.xml
index 13cc8e189188..ccb09392aed3 100644
--- a/packages/InputDevices/res/values-mk/strings.xml
+++ b/packages/InputDevices/res/values-mk/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"тајландски (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"српски (латиница)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"црногорски (латиница)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"српски (кирилица)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"црногорски (кирилица)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ml/strings.xml b/packages/InputDevices/res/values-ml/strings.xml
index fda477bfe38f..5a7b601baa97 100644
--- a/packages/InputDevices/res/values-ml/strings.xml
+++ b/packages/InputDevices/res/values-ml/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"തായ് (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"സെർബിയൻ (ലാറ്റിൻ)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"മോണ്ടിനെഗ്രിൻ (ലാറ്റിൻ)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"സെർബിയൻ (സിറിലിക്)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"മോണ്ടിനെഗ്രിൻ (സിറിലിക്)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-mn/strings.xml b/packages/InputDevices/res/values-mn/strings.xml
index a6d3320ee1fd..0044eb24bc6a 100644
--- a/packages/InputDevices/res/values-mn/strings.xml
+++ b/packages/InputDevices/res/values-mn/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тай (паттачоте)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Серби (латин)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Монтенегро (латин)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Серби (кирилл)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Монтенегро (кирилл)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-mr/strings.xml b/packages/InputDevices/res/values-mr/strings.xml
index faae021e4187..d306dda71553 100644
--- a/packages/InputDevices/res/values-mr/strings.xml
+++ b/packages/InputDevices/res/values-mr/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"थाई (पट्टाचोटे)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"सर्बियन (लॅटिन)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"मॉन्टेनेग्रिन (लॅटिन)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"सर्बियन (सिरिलिक)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"मॉन्टेनेग्रिन (सिरिलिक)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ms/strings.xml b/packages/InputDevices/res/values-ms/strings.xml
index 9f142607ac63..d1b16547f8e6 100644
--- a/packages/InputDevices/res/values-ms/strings.xml
+++ b/packages/InputDevices/res/values-ms/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbia (Latin)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbia (Cyril)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyril)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-my/strings.xml b/packages/InputDevices/res/values-my/strings.xml
index bb2602724ae1..fb553446dbd4 100644
--- a/packages/InputDevices/res/values-my/strings.xml
+++ b/packages/InputDevices/res/values-my/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ထိုင်း (ပတ်တာချုတ်)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"ဆားဘီးယား (လက်တင်)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"မွန်တီနီဂရင်း (လက်တင်)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ဆားဘီးယား (စီရီလစ်)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"မွန်တီနီဂရင်း (စီရီလစ်)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-nb/strings.xml b/packages/InputDevices/res/values-nb/strings.xml
index 402d7eeca7ab..7ac2a822667a 100644
--- a/packages/InputDevices/res/values-nb/strings.xml
+++ b/packages/InputDevices/res/values-nb/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbisk (latinsk)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrisk (latinsk)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisk (kyrillisk)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrisk (kyrillisk)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ne/strings.xml b/packages/InputDevices/res/values-ne/strings.xml
index a60cf36d8fb6..113489d65d96 100644
--- a/packages/InputDevices/res/values-ne/strings.xml
+++ b/packages/InputDevices/res/values-ne/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"थाई (पत्ताचोते)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"सर्बियाली (ल्याटिन)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"मोन्टेनिग्रिन (ल्याटिन)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"सर्बियाली (सिरिलिक)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"मोन्टेनिग्रिन (सिरिलिक)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-nl/strings.xml b/packages/InputDevices/res/values-nl/strings.xml
index bb0c945494d2..0e954e9b9ed3 100644
--- a/packages/InputDevices/res/values-nl/strings.xml
+++ b/packages/InputDevices/res/values-nl/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Servisch (Latijns)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrijns (Latijns)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Servisch (Cyrillisch)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrijns (Cyrillisch)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-or/strings.xml b/packages/InputDevices/res/values-or/strings.xml
index 2bf862b144f7..d9d852008275 100644
--- a/packages/InputDevices/res/values-or/strings.xml
+++ b/packages/InputDevices/res/values-or/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ଥାଇ (ପାଟ୍ଟାଚୋଟେ)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"ସର୍ବିଆନ (ଲାଟିନ)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ମଣ୍ଟେନେଗ୍ରିନ (ଲାଟିନ)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ସର୍ବିଆନ (ସିରିଲିକ)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ମଣ୍ଟେନେଗ୍ରିନ (ସିରିଲିକ)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-pa/strings.xml b/packages/InputDevices/res/values-pa/strings.xml
index c1fee5feb968..85b0d195f05f 100644
--- a/packages/InputDevices/res/values-pa/strings.xml
+++ b/packages/InputDevices/res/values-pa/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ਥਾਈ (ਪੈਟਾਸ਼ੋਟੇ)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"ਸਰਬੀਆਈ (ਲਾਤੀਨੀ)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ਮਾਂਟੇਨੀਗਰਿਨ (ਲਾਤੀਨੀ)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ਸਰਬੀਆਈ (ਸਿਰਿਲਿਕ)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ਮਾਂਟੇਨੀਗਰਿਨ (ਸਿਰਿਲਿਕ)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-pl/strings.xml b/packages/InputDevices/res/values-pl/strings.xml
index d3e4a3a9cb11..7fb90d2454f6 100644
--- a/packages/InputDevices/res/values-pl/strings.xml
+++ b/packages/InputDevices/res/values-pl/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"tajski (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"serbski (alfabet łaciński)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"czarnogórski (alfabet łaciński)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbski (cyrylica)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"czarnogórski (cyrylica)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-pt-rBR/strings.xml b/packages/InputDevices/res/values-pt-rBR/strings.xml
index 94a10c504b1f..2b92c811be64 100644
--- a/packages/InputDevices/res/values-pt-rBR/strings.xml
+++ b/packages/InputDevices/res/values-pt-rBR/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tailandês (pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Sérvio (latim)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latim)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sérvio (cirílico)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-pt-rPT/strings.xml b/packages/InputDevices/res/values-pt-rPT/strings.xml
index 8c227761d9c3..98cf7e2df754 100644
--- a/packages/InputDevices/res/values-pt-rPT/strings.xml
+++ b/packages/InputDevices/res/values-pt-rPT/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tailandês (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Sérvio (latim)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latim)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sérvio (cirílico)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-pt/strings.xml b/packages/InputDevices/res/values-pt/strings.xml
index 94a10c504b1f..2b92c811be64 100644
--- a/packages/InputDevices/res/values-pt/strings.xml
+++ b/packages/InputDevices/res/values-pt/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tailandês (pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Sérvio (latim)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latim)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sérvio (cirílico)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ro/strings.xml b/packages/InputDevices/res/values-ro/strings.xml
index 654f168ce9bf..71d19958263e 100644
--- a/packages/InputDevices/res/values-ro/strings.xml
+++ b/packages/InputDevices/res/values-ro/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thailandeză (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Sârbă (caractere latine)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Muntenegreană (caractere latine)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sârbă (caractere chirilice)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Muntenegreană (Chirilică)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ru/strings.xml b/packages/InputDevices/res/values-ru/strings.xml
index 05b1b25d1c7f..13130fc9ca1f 100644
--- a/packages/InputDevices/res/values-ru/strings.xml
+++ b/packages/InputDevices/res/values-ru/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тайский (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Сербский (латиница)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Черногорский (латиница)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербский (кириллица)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Черногорский (кириллица)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-si/strings.xml b/packages/InputDevices/res/values-si/strings.xml
index 8d36553db34c..80c674d00bca 100644
--- a/packages/InputDevices/res/values-si/strings.xml
+++ b/packages/InputDevices/res/values-si/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"තායි (පට්ටචෝටේ)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"සර්බියානු (ලතින්)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"මොන්ටෙනේග්‍රීන් (ලතින්)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"සර්බියානු (සිරිලික්)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"මොන්ටෙනේග්‍රීන් (සිරිලික්)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-sk/strings.xml b/packages/InputDevices/res/values-sk/strings.xml
index 33e1651b98a8..6ce98cc34bca 100644
--- a/packages/InputDevices/res/values-sk/strings.xml
+++ b/packages/InputDevices/res/values-sk/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"thajčina (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"srbčina (latinka)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"čiernohorčina (latinka)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srbčina (cyrilika)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"čiernohorčina (cyrilika)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-sl/strings.xml b/packages/InputDevices/res/values-sl/strings.xml
index e40cca7fd850..29264231e6f6 100644
--- a/packages/InputDevices/res/values-sl/strings.xml
+++ b/packages/InputDevices/res/values-sl/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"tajščina (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"srbščina (latinica)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"črnogorščina (latinica)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srbščina (cirilica)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"črnogorščina (cirilica)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-sq/strings.xml b/packages/InputDevices/res/values-sq/strings.xml
index 46405ba3ce18..06f76f3d6c4a 100644
--- a/packages/InputDevices/res/values-sq/strings.xml
+++ b/packages/InputDevices/res/values-sq/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tajlandisht (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbisht (latine)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Malazisht (latine)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisht (cirilike)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Malazisht (cirilike)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-sr/strings.xml b/packages/InputDevices/res/values-sr/strings.xml
index 56420409a54e..1172fef2c0a9 100644
--- a/packages/InputDevices/res/values-sr/strings.xml
+++ b/packages/InputDevices/res/values-sr/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"тајски (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"српски (латиница)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"црногорски (латиница)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"српски (ћирилица)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"црногорски (ћирилица)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-sv/strings.xml b/packages/InputDevices/res/values-sv/strings.xml
index 9ba122786974..946854ca00bb 100644
--- a/packages/InputDevices/res/values-sv/strings.xml
+++ b/packages/InputDevices/res/values-sv/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"thailändska (pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"serbiska (latinskt)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"montenegrinska (latinskt)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbiska (kyrilliskt)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegrinska (kyrilliskt)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-sw/strings.xml b/packages/InputDevices/res/values-sw/strings.xml
index 5da85421c2d4..c3578d8b5fbd 100644
--- a/packages/InputDevices/res/values-sw/strings.xml
+++ b/packages/InputDevices/res/values-sw/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Kitai (Kipatachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Kiserbia (Kilatini)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Kimontenegri (Kilatini)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Kiserbia (Kisiriliki)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Kimontenegri (Kisiriliki)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ta/strings.xml b/packages/InputDevices/res/values-ta/strings.xml
index becffd3f0c91..5c3f57e361b7 100644
--- a/packages/InputDevices/res/values-ta/strings.xml
+++ b/packages/InputDevices/res/values-ta/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"தாய் (பட்டாசொட்டே)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"செர்பியன் (லத்தீன்)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"மாண்டினெக்ரன் (லத்தீன்)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"செர்பியன் (சிரிலிக்)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"மாண்டினெக்ரன் (சிரிலிக்)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-te/strings.xml b/packages/InputDevices/res/values-te/strings.xml
index 1d2fcb4e530a..a0674d665ed9 100644
--- a/packages/InputDevices/res/values-te/strings.xml
+++ b/packages/InputDevices/res/values-te/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"థాయ్ (పత్తచోత్)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"సెర్బియన్ (లాటిన్)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"మాంటెనెగ్రిన్ (లాటిన్)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"సెర్బియన్ (సిరిలిక్)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"మాంటెనెగ్రిన్ (సిరిలిక్)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-th/strings.xml b/packages/InputDevices/res/values-th/strings.xml
index 318a3bba8c55..a9465961f06a 100644
--- a/packages/InputDevices/res/values-th/strings.xml
+++ b/packages/InputDevices/res/values-th/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ไทย (ปัตตะโชติ)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"เซอร์เบีย (ละติน)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"มอนเตเนโกร (ละติน)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"เซอร์เบีย (ซีริลลิก)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"มอนเตเนโกร (ซีริลลิก)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-tl/strings.xml b/packages/InputDevices/res/values-tl/strings.xml
index 062dff0dec0f..0a5d3cc6c1d6 100644
--- a/packages/InputDevices/res/values-tl/strings.xml
+++ b/packages/InputDevices/res/values-tl/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbian (Latin)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-tr/strings.xml b/packages/InputDevices/res/values-tr/strings.xml
index c6d38f4a7022..f37a098f0714 100644
--- a/packages/InputDevices/res/values-tr/strings.xml
+++ b/packages/InputDevices/res/values-tr/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tayca (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Sırpça (Latin)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Karadağca (Latin)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sırpça (Kiril)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Karadağca (Kiril)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-uk/strings.xml b/packages/InputDevices/res/values-uk/strings.xml
index 357747b41413..d496dfa3910b 100644
--- a/packages/InputDevices/res/values-uk/strings.xml
+++ b/packages/InputDevices/res/values-uk/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тайська (паттачоте)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Сербська (латиниця)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Чорногорська (латиниця)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербська (кирилиця)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Чорногорська (кирилиця)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ur/strings.xml b/packages/InputDevices/res/values-ur/strings.xml
index 7b4c10499469..7293858ee413 100644
--- a/packages/InputDevices/res/values-ur/strings.xml
+++ b/packages/InputDevices/res/values-ur/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"تھائی (پٹاچوٹے)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"سربیائی (لاطینی)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"مونٹے نیگریائی (لاطینی)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"سربیائی (سیریلک)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"مونٹے نیگریائی (سیریلک)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-uz/strings.xml b/packages/InputDevices/res/values-uz/strings.xml
index 60e740598b4e..f212e2c4108e 100644
--- a/packages/InputDevices/res/values-uz/strings.xml
+++ b/packages/InputDevices/res/values-uz/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tay (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serb (lotin)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Chernogor (lotin)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serb (kirill)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Chernogor (kirill)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-vi/strings.xml b/packages/InputDevices/res/values-vi/strings.xml
index 6fe39d2a84a4..f3d2cc48fb96 100644
--- a/packages/InputDevices/res/values-vi/strings.xml
+++ b/packages/InputDevices/res/values-vi/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tiếng Thái (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Tiếng Serbia (Latinh)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Tiếng Montenegro (Latinh)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Tiếng Serbia (Chữ Kirin)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Tiếng Montenegro (Chữ Kirin)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-zh-rCN/strings.xml b/packages/InputDevices/res/values-zh-rCN/strings.xml
index 6e96e5d46a83..1f74d3436557 100644
--- a/packages/InputDevices/res/values-zh-rCN/strings.xml
+++ b/packages/InputDevices/res/values-zh-rCN/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"泰语 (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"塞尔维亚语(拉丁字母)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"黑山语(拉丁字母)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"塞尔维亚语(西里尔字母)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"黑山语(西里尔字母)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-zh-rHK/strings.xml b/packages/InputDevices/res/values-zh-rHK/strings.xml
index 3d1a895d4641..9c6864a7bec6 100644
--- a/packages/InputDevices/res/values-zh-rHK/strings.xml
+++ b/packages/InputDevices/res/values-zh-rHK/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"泰文 (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"塞爾維亞文 (拉丁)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"蒙特內哥羅文 (拉丁)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"塞爾維亞文 (西里爾字母)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"蒙特內哥羅文 (西里爾字母)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-zh-rTW/strings.xml b/packages/InputDevices/res/values-zh-rTW/strings.xml
index 26be41bce094..f4159c983bb4 100644
--- a/packages/InputDevices/res/values-zh-rTW/strings.xml
+++ b/packages/InputDevices/res/values-zh-rTW/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"泰文 (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"塞爾維亞文 (拉丁字母)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"蒙特內哥羅文 (拉丁字母)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"塞爾維亞文 (西里爾字母)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"蒙特內哥羅文 (西里爾字母)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-zu/strings.xml b/packages/InputDevices/res/values-zu/strings.xml
index f6f6a774526a..ead5a4557901 100644
--- a/packages/InputDevices/res/values-zu/strings.xml
+++ b/packages/InputDevices/res/values-zu/strings.xml
@@ -54,8 +54,6 @@
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Isi-Thai (Pattachote)"</string>
<string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"IsiSerbian (Latin)"</string>
<string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"IsiMontenegrin (Latin)"</string>
- <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
- <skip />
- <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
- <skip />
+ <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
+ <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
</resources>
diff --git a/packages/InputDevices/res/xml/keyboard_glyph_maps.xml b/packages/InputDevices/res/xml/keyboard_glyph_maps.xml
new file mode 100644
index 000000000000..b7a6f3fbf7eb
--- /dev/null
+++ b/packages/InputDevices/res/xml/keyboard_glyph_maps.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 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.
+ -->
+<keyboard-glyph-maps xmlns:android="http://schemas.android.com/apk/res/android">
+<!-- <key-glyph-map-->
+<!-- android:glyphMap="@xml/xyz_glyph_map"-->
+<!-- android:vendorId="0x1234"-->
+<!-- android:productId="0x3456" />-->
+</keyboard-glyph-maps> \ No newline at end of file
diff --git a/packages/InputDevices/res/xml/keyboard_glyph_maps_overlay.xml b/packages/InputDevices/res/xml/keyboard_glyph_maps_overlay.xml
new file mode 100644
index 000000000000..7c036ebde09d
--- /dev/null
+++ b/packages/InputDevices/res/xml/keyboard_glyph_maps_overlay.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 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.
+ -->
+<keyboard-glyph-maps xmlns:android="http://schemas.android.com/apk/res/android">
+<!-- NOTE: This is reserved for glyph maps to be provided using RRO. For providing glyph maps in
+ AOSP use key_glyph_maps.xml instead -->
+</keyboard-glyph-maps> \ No newline at end of file
diff --git a/packages/InputDevices/src/com/android/inputdevices/KeyGlyphMapProvider.java b/packages/InputDevices/src/com/android/inputdevices/KeyGlyphMapProvider.java
new file mode 100644
index 000000000000..6b508dd90a40
--- /dev/null
+++ b/packages/InputDevices/src/com/android/inputdevices/KeyGlyphMapProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 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.inputdevices;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class KeyGlyphMapProvider extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Nothing to do at this time.
+ }
+}
diff --git a/packages/InputDevices/src/com/android/inputdevices/OverlayKeyGlyphMapProvider.java b/packages/InputDevices/src/com/android/inputdevices/OverlayKeyGlyphMapProvider.java
new file mode 100644
index 000000000000..13b5b422c7ce
--- /dev/null
+++ b/packages/InputDevices/src/com/android/inputdevices/OverlayKeyGlyphMapProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 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.inputdevices;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class OverlayKeyGlyphMapProvider extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Nothing to do at this time.
+ }
+}
diff --git a/packages/PackageInstaller/Android.bp b/packages/PackageInstaller/Android.bp
index 79c810ca2611..bd84b58aa0f4 100644
--- a/packages/PackageInstaller/Android.bp
+++ b/packages/PackageInstaller/Android.bp
@@ -46,7 +46,6 @@ android_app {
sdk_version: "system_current",
rename_resources_package: false,
static_libs: [
- "xz-java",
"androidx.leanback_leanback",
"androidx.annotation_annotation",
"androidx.fragment_fragment",
@@ -79,7 +78,6 @@ android_app {
overrides: ["PackageInstaller"],
static_libs: [
- "xz-java",
"androidx.leanback_leanback",
"androidx.fragment_fragment",
"androidx.lifecycle_lifecycle-livedata",
@@ -112,7 +110,6 @@ android_app {
overrides: ["PackageInstaller"],
static_libs: [
- "xz-java",
"androidx.leanback_leanback",
"androidx.annotation_annotation",
"androidx.fragment_fragment",
diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml
index 443747530315..68443a7e1492 100644
--- a/packages/PackageInstaller/AndroidManifest.xml
+++ b/packages/PackageInstaller/AndroidManifest.xml
@@ -147,17 +147,6 @@
android:configChanges="mnc|mnc|touchscreen|navigation|screenLayout|screenSize|smallestScreenSize|orientation|locale|keyboard|keyboardHidden|fontScale|uiMode|layoutDirection|density"
android:exported="false" />
- <!-- Wearable Components -->
- <service android:name=".wear.WearPackageInstallerService"
- android:permission="com.google.android.permission.INSTALL_WEARABLE_PACKAGES"
- android:foregroundServiceType="systemExempted"
- android:exported="true"/>
-
- <provider android:name=".wear.WearPackageIconProvider"
- android:authorities="com.google.android.packageinstaller.wear.provider"
- android:grantUriPermissions="true"
- android:exported="false" />
-
<receiver android:name="androidx.profileinstaller.ProfileInstallReceiver"
tools:node="remove" />
diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
index 60075e6703fb..2e423396fbd8 100644
--- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
@@ -23,55 +23,55 @@
<string name="cancel" msgid="1018267193425558088">"Annuler"</string>
<string name="installing" msgid="4921993079741206516">"Installation en cours…"</string>
<string name="installing_app" msgid="1165095864863849422">"Installation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> en cours…"</string>
- <string name="install_done" msgid="5987363587661783896">"Application installée."</string>
- <string name="install_confirm_question" msgid="7663733664476363311">"Voulez-vous installer cette application?"</string>
- <string name="install_confirm_question_update" msgid="3348888852318388584">"Voulez-vous mettre à jour cette application?"</string>
- <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"&lt;p&gt;Mettre à jour cette application à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette application reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre tablette. Le fonctionnement de l\'application peut en être modifié.&lt;/p&gt;"</string>
- <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"&lt;p&gt;Mettre à jour cette application à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette application reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre téléviseur. Le fonctionnement de l\'application peut en être modifié.&lt;/p&gt;"</string>
- <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"&lt;p&gt;Mettre à jour cette application à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette application reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre téléphone. Le fonctionnement de l\'application peut en être modifié.&lt;/p&gt;"</string>
- <string name="install_failed" msgid="5777824004474125469">"Application non installée."</string>
+ <string name="install_done" msgid="5987363587661783896">"Appli installée."</string>
+ <string name="install_confirm_question" msgid="7663733664476363311">"Voulez-vous installer cette appli?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Voulez-vous mettre à jour cette appli?"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"&lt;p&gt;Mettre à jour cette appli à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette appli reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre tablette. Le fonctionnement de l\'appli peut en être modifié.&lt;/p&gt;"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"&lt;p&gt;Mettre à jour cette appli à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette appli reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre téléviseur. Le fonctionnement de l\'appli peut en être modifié.&lt;/p&gt;"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"&lt;p&gt;Mettre à jour cette appli à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette appli reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre téléphone. Le fonctionnement de l\'appli peut en être modifié.&lt;/p&gt;"</string>
+ <string name="install_failed" msgid="5777824004474125469">"Appli non installée."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"L\'installation du paquet a été bloquée."</string>
- <string name="install_failed_conflict" msgid="3493184212162521426">"L\'application n\'a pas été installée, car le paquet entre en conflit avec un paquet existant."</string>
- <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre tablette."</string>
- <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Cette application n\'est pas compatible avec votre téléviseur."</string>
- <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre téléphone."</string>
- <string name="install_failed_invalid_apk" msgid="8581007676422623930">"L\'application n\'a pas été installée, car elle ne semble pas être valide."</string>
+ <string name="install_failed_conflict" msgid="3493184212162521426">"L\'appli n\'a pas été installée, car le paquet entre en conflit avec un paquet existant."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"L\'appli n\'a pas été installée, car elle n\'est pas compatible avec votre tablette."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Cette appli n\'est pas compatible avec votre téléviseur."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"L\'appli n\'a pas été installée, car elle n\'est pas compatible avec votre téléphone."</string>
+ <string name="install_failed_invalid_apk" msgid="8581007676422623930">"L\'appli n\'a pas été installée, car elle ne semble pas être valide."</string>
<string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur votre tablette."</string>
<string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'a pas pu être installée sur votre téléviseur."</string>
<string name="install_failed_msg" product="default" msgid="6484461562647915707">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur votre téléphone."</string>
<string name="launch" msgid="3952550563999890101">"Ouvrir"</string>
- <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Votre administrateur n\'autorise pas l\'installation d\'applications obtenues à partir de sources inconnues"</string>
- <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Cet utilisateur ne peut pas installer d\'applications inconnues"</string>
- <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Cet utilisateur n\'est pas autorisé à installer des applications"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Votre administrateur n\'autorise pas l\'installation d\'applis obtenues à partir de sources inconnues"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Cet utilisateur ne peut pas installer d\'applis inconnues"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Cet utilisateur n\'est pas autorisé à installer des applis"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
<string name="archive" msgid="4447791830199354721">"Archiver"</string>
<string name="update_anyway" msgid="8792432341346261969">"Mettre à jour malgré tout"</string>
<string name="manage_applications" msgid="5400164782453975580">"Gérer les applis"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Espace insuffisant"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g>. Veuillez libérer de l\'espace, puis réessayer."</string>
- <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Application non trouvée"</string>
- <string name="app_not_found_dlg_text" msgid="5219983779377811611">"L\'application ne figure pas dans la liste des applications installées."</string>
+ <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Appli non trouvée"</string>
+ <string name="app_not_found_dlg_text" msgid="5219983779377811611">"L\'appli ne figure pas dans la liste des applis installées."</string>
<string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Non autorisée"</string>
<string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"L\'utilisateur actuel n\'est pas autorisé à effectuer cette désinstallation."</string>
<string name="generic_error_dlg_title" msgid="5863195085927067752">"Erreur"</string>
- <string name="generic_error_dlg_text" msgid="5287861443265795232">"L\'application n\'a pas pu être désinstallée."</string>
- <string name="uninstall_application_title" msgid="4045420072401428123">"Désinstaller l\'application"</string>
+ <string name="generic_error_dlg_text" msgid="5287861443265795232">"L\'appli n\'a pas pu être désinstallée."</string>
+ <string name="uninstall_application_title" msgid="4045420072401428123">"Désinstaller l\'appli"</string>
<string name="uninstall_update_title" msgid="824411791011583031">"Désinstaller mise à jour"</string>
- <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fait partie de l\'application suivante :"</string>
- <string name="uninstall_application_text" msgid="3816830743706143980">"Voulez-vous désinstaller cette application?"</string>
+ <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fait partie de l\'appli suivante :"</string>
+ <string name="uninstall_application_text" msgid="3816830743706143980">"Voulez-vous désinstaller cette appli?"</string>
<string name="archive_application_text" msgid="8482325710714386348">"Vos données personnelles seront enregistrées"</string>
- <string name="archive_application_text_all_users" msgid="3151229641681672580">"Archiver cette application pour tous les utilisateurs? Vos données personnelles seront enregistrées"</string>
- <string name="archive_application_text_current_user_work_profile" msgid="1450487362134779752">"Archiver cette application sur votre profil professionnel? Vos données personnelles seront enregistrées"</string>
- <string name="archive_application_text_user" msgid="2586558895535581451">"Archiver cette application pour <xliff:g id="USERNAME">%1$s</xliff:g>? Vos données personnelles seront enregistrées"</string>
- <string name="archive_application_text_current_user_private_profile" msgid="1958423158655599132">"Voulez-vous archiver cette application de votre Espace privé? Vos données personnelles seront enregistrées"</string>
- <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Voulez-vous désinstaller cette application pour "<b>"tous"</b>" les utilisateurs? L\'application et ses données seront supprimées pour "<b>"tous"</b>" les utilisateurs de l\'appareil."</string>
- <string name="uninstall_application_text_user" msgid="498072714173920526">"Voulez-vous désinstaller cette application pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
- <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Voulez-vous désinstaller cette application de votre profil professionnel?"</string>
- <string name="uninstall_update_text" msgid="863648314632448705">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées."</string>
- <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées. Cela touchera tous les utilisateurs de cet appareil, y compris ceux qui utilisent un profil professionnel."</string>
- <string name="uninstall_keep_data" msgid="7002379587465487550">"Garder <xliff:g id="SIZE">%1$s</xliff:g> de données d\'application."</string>
- <string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Voulez-vous supprimer cette application?"</string>
- <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Voulez-vous désinstaller cette application? Le clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sera aussi supprimé."</string>
+ <string name="archive_application_text_all_users" msgid="3151229641681672580">"Archiver cette appli pour tous les utilisateurs? Vos données personnelles seront enregistrées"</string>
+ <string name="archive_application_text_current_user_work_profile" msgid="1450487362134779752">"Archiver cette appli sur votre profil professionnel? Vos données personnelles seront enregistrées"</string>
+ <string name="archive_application_text_user" msgid="2586558895535581451">"Archiver cette appli pour <xliff:g id="USERNAME">%1$s</xliff:g>? Vos données personnelles seront enregistrées"</string>
+ <string name="archive_application_text_current_user_private_profile" msgid="1958423158655599132">"Voulez-vous archiver cette appli de votre Espace privé? Vos données personnelles seront enregistrées"</string>
+ <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Voulez-vous désinstaller cette appli pour "<b>"tous"</b>" les utilisateurs? L\'appli et ses données seront supprimées pour "<b>"tous"</b>" les utilisateurs de l\'appareil."</string>
+ <string name="uninstall_application_text_user" msgid="498072714173920526">"Voulez-vous désinstaller cette appli pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Voulez-vous désinstaller cette appli de votre profil professionnel?"</string>
+ <string name="uninstall_update_text" msgid="863648314632448705">"Remplacer cette appli par la version d\'usine? Toutes les données seront supprimées."</string>
+ <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Remplacer cette appli par la version d\'usine? Toutes les données seront supprimées. Cela touchera tous les utilisateurs de cet appareil, y compris ceux qui utilisent un profil professionnel."</string>
+ <string name="uninstall_keep_data" msgid="7002379587465487550">"Garder <xliff:g id="SIZE">%1$s</xliff:g> de données d\'appli."</string>
+ <string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Voulez-vous supprimer cette appli?"</string>
+ <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Voulez-vous désinstaller cette appli? Le clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sera aussi supprimé."</string>
<string name="uninstall_application_text_current_user_private_profile" msgid="867004464945674674">"Voulez-vous désinstaller cette appli de votre espace privé?"</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"Désinstallations en cours…"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Désinstallations échouées"</string>
@@ -83,47 +83,47 @@
<string name="uninstall_failed" msgid="1847750968168364332">"Échec de la désinstallation."</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"La désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> n\'a pas réussi."</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"Suppression du clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
- <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Impossible de désinstaller une application d\'administration de l\'appareil active"</string>
- <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Impossible de désinstaller une application d\'administration de l\'appareil active pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
- <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Cette application est nécessaire pour certains utilisateurs ou profils, et elle a été désinstallée pour d\'autres"</string>
- <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Cette application est nécessaire pour votre profil et ne peut pas être désinstallée."</string>
- <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Imposs. de désinst. l\'application : elle est requise par l\'admin de l\'appareil."</string>
- <string name="manage_device_administrators" msgid="3092696419363842816">"Gérer les applications d\'administration d\'appareils"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Impossible de désinstaller une appli d\'administration de l\'appareil active"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Impossible de désinstaller une appli d\'administration de l\'appareil active pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Cette appli est nécessaire pour certains utilisateurs ou profils, et elle a été désinstallée pour d\'autres"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Cette appli est nécessaire pour votre profil et ne peut pas être désinstallée."</string>
+ <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Imposs. de désinst. l\'appli : elle est requise par l\'admin de l\'appareil."</string>
+ <string name="manage_device_administrators" msgid="3092696419363842816">"Gérer les applis d\'administration d\'appareils"</string>
<string name="manage_users" msgid="1243995386982560813">"Gérer les utilisateurs"</string>
<string name="uninstall_failed_msg" msgid="2176744834786696012">"Impossible de désinstaller <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="Parse_error_dlg_text" msgid="1661404001063076789">"Un problème est survenu lors de l\'analyse du paquet."</string>
- <string name="message_staging" msgid="8032722385658438567">"Pré-production de l\'application en cours…"</string>
+ <string name="message_staging" msgid="8032722385658438567">"Pré-production de l\'appli en cours…"</string>
<string name="app_name_unknown" msgid="6881210203354323926">"Inconnue"</string>
- <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur cette tablette. Vous pouvez modifier cette option dans les paramètres."</string>
- <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléviseur. Vous pouvez modifier cette option dans les paramètres."</string>
- <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur cette montre. Vous pouvez modifier cette option dans les paramètres."</string>
- <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléphone. Vous pouvez modifier cette option dans les paramètres."</string>
- <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Votre téléphone et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
- <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Votre tablette et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
- <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Votre téléviseur et vos données personnelles sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"À des fins de sécurité, l\'installation d\'applis inconnues provenant de cette source n\'est pas autorisée sur cette tablette. Vous pouvez modifier cette option dans les paramètres."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"À des fins de sécurité, l\'installation d\'applis inconnues provenant de cette source n\'est pas autorisée sur ce téléviseur. Vous pouvez modifier cette option dans les paramètres."</string>
+ <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"À des fins de sécurité, l\'installation d\'applis inconnues provenant de cette source n\'est pas autorisée sur cette montre. Vous pouvez modifier cette option dans les paramètres."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"À des fins de sécurité, l\'installation d\'applis inconnues provenant de cette source n\'est pas autorisée sur ce téléphone. Vous pouvez modifier cette option dans les paramètres."</string>
+ <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Votre téléphone et vos données personnelles sont plus vulnérables aux attaques provenant d\'applis inconnues. En installant cette appli, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de l\'utilisation de telles applis."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Votre tablette et vos données personnelles sont plus vulnérables aux attaques provenant d\'applis inconnues. En installant cette appli, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de l\'utilisation de telles applis."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Votre téléviseur et vos données personnelles sont plus vulnérables aux attaques d\'applis inconnues. En installant cette appli, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
<string name="cloned_app_label" msgid="7503612829833756160">"Clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
<string name="archiving_app_label" msgid="1127085259724124725">"Archiver <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>?"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Continuer"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Paramètres"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Installer/désinstaller applis Google Wear"</string>
- <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notification d\'application installée"</string>
+ <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notification d\'appli installée"</string>
<string name="notification_installation_success_message" msgid="6450467996056038442">"Installation réussie"</string>
<string name="notification_installation_success_status" msgid="3172502643504323321">"Installation de « <xliff:g id="APPNAME">%1$s</xliff:g> » réussie"</string>
<string name="unarchive_application_title" msgid="7958278328280721421">"Restaurer <xliff:g id="APPNAME">%1$s</xliff:g> à partir de <xliff:g id="INSTALLERNAME">%2$s</xliff:g>?"</string>
- <string name="unarchive_body_text" msgid="8244155079861708964">"Le téléchargement de cette application commencera en arrière-plan"</string>
+ <string name="unarchive_body_text" msgid="8244155079861708964">"Le téléchargement de cette appli commencera en arrière-plan"</string>
<string name="restore" msgid="8460854736328970444">"Restaurer"</string>
<string name="unarchive_error_offline_title" msgid="4021785324565678605">"Vous êtes hors ligne"</string>
- <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Pour restaurer cette application, vérifiez votre connexion Internet et réessayez."</string>
+ <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Pour restaurer cette appli, vérifiez votre connexion Internet et réessayez."</string>
<string name="unarchive_error_generic_title" msgid="7123457671482449992">"Un problème est survenu"</string>
- <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Un problème est survenu lors de la restauration de cette application"</string>
+ <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Un problème est survenu lors de la restauration de cette appli"</string>
<string name="unarchive_error_storage_title" msgid="5080723357273852630">"Espace de stockage insuffisant"</string>
- <string name="unarchive_error_storage_body" msgid="6879544407568780524">"Pour restaurer cette application, vous devez libérer de l\'espace de stockage sur cet appareil. Espace de stockage requis : <xliff:g id="BYTES">%1$s</xliff:g>"</string>
+ <string name="unarchive_error_storage_body" msgid="6879544407568780524">"Pour restaurer cette appli, vous devez libérer de l\'espace de stockage sur cet appareil. Espace de stockage requis : <xliff:g id="BYTES">%1$s</xliff:g>"</string>
<string name="unarchive_action_required_title" msgid="4971245740162604619">"Action requise"</string>
- <string name="unarchive_action_required_body" msgid="1679431572983989231">"Suivez les étapes suivantes pour restaurer cette application"</string>
+ <string name="unarchive_action_required_body" msgid="1679431572983989231">"Suivez les étapes suivantes pour restaurer cette appli"</string>
<string name="unarchive_error_installer_disabled_title" msgid="4815715617014985605">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> est désactivé"</string>
- <string name="unarchive_error_installer_disabled_body" msgid="4820821285907011729">"Pour restaurer cette application, activez <xliff:g id="INSTALLERNAME">%1$s</xliff:g> dans les paramètres"</string>
+ <string name="unarchive_error_installer_disabled_body" msgid="4820821285907011729">"Pour restaurer cette appli, activez <xliff:g id="INSTALLERNAME">%1$s</xliff:g> dans les paramètres"</string>
<string name="unarchive_error_installer_uninstalled_title" msgid="3748354109176326489">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> est désinstallé"</string>
- <string name="unarchive_error_installer_uninstalled_body" msgid="944733542444183204">"Pour restaurer cette application, vous devrez installer <xliff:g id="INSTALLERNAME">%1$s</xliff:g>"</string>
+ <string name="unarchive_error_installer_uninstalled_body" msgid="944733542444183204">"Pour restaurer cette appli, vous devrez installer <xliff:g id="INSTALLERNAME">%1$s</xliff:g>"</string>
<string name="unarchive_action_required_continue" msgid="5711202111224184257">"Continuer"</string>
<string name="unarchive_clear_storage_button" msgid="1549537154535608744">"Effacer le stockage"</string>
<string name="unarchive_settings_button" msgid="3504171760009177425">"Paramètres"</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index e0398aa49dc9..824dd4a5fdaf 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -330,7 +330,8 @@ public class PackageInstallerActivity extends Activity {
// data we still want to count it as "installed".
mAppInfo = mPm.getApplicationInfo(pkgName,
PackageManager.MATCH_UNINSTALLED_PACKAGES);
- if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+ // If the package is archived, treat it as update case.
+ if (!mAppInfo.isArchived && (mAppInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
mAppInfo = null;
}
} catch (NameNotFoundException e) {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
index a23df64f3582..88770d487a83 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
@@ -95,9 +95,22 @@ class InstallRepository(private val context: Context) {
*/
var stagedSessionId = SessionInfo.INVALID_ID
private set
+
+ /**
+ * UID of the last caller of Pia. This can point to a 3P installer if it uses intents to install
+ * an APK, or receives a
+ * [STATUS_PENDING_USER_ACTION][PackageInstaller.STATUS_PENDING_USER_ACTION] status code.
+ * It may point to Pia, when it receives the STATUS_PENDING_USER_ACTION status code in case of
+ * an update-ownership change.
+ */
private var callingUid = Process.INVALID_UID
+
+ /**
+ * UID of the origin of the installation. This UID is used to fetch the app-label of the
+ * source of the install, and also check whether the source app has the AppOp to install other
+ * apps.
+ */
private var originatingUid = Process.INVALID_UID
- private var originatingUidFromSessionInfo = Process.INVALID_UID
private var callingPackage: String? = null
private var sessionStager: SessionStager? = null
private lateinit var intent: Intent
@@ -136,76 +149,68 @@ class InstallRepository(private val context: Context) {
stagedSessionId = intent.getIntExtra(EXTRA_STAGED_SESSION_ID, SessionInfo.INVALID_ID)
callingPackage = callerInfo.packageName
-
- // Uid of the source package, coming from ActivityManager
callingUid = callerInfo.uid
- if (callingUid == Process.INVALID_UID) {
- Log.e(LOG_TAG, "Could not determine the launching uid.")
+
+ val sourceInfo: ApplicationInfo? = getSourceInfo(callingPackage)
+ if (callingUid == Process.INVALID_UID && sourceInfo == null) {
+ // Caller's identity could not be determined. Abort the install
+ Log.e(LOG_TAG, "Cannot determine caller since UID is invalid and sourceInfo is null")
+ return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
}
- originatingUidFromSessionInfo = callingUid
+ originatingUid = callingUid
val sessionInfo: SessionInfo? =
if (sessionId != SessionInfo.INVALID_ID)
packageInstaller.getSessionInfo(sessionId)
else null
if (sessionInfo != null) {
- callingPackage = sessionInfo.installerPackageName
callingAttributionTag = sessionInfo.installerAttributionTag
if (sessionInfo.originatingUid != Process.INVALID_UID) {
- originatingUidFromSessionInfo = sessionInfo.originatingUid
+ originatingUid = sessionInfo.originatingUid
}
}
- val sourceInfo: ApplicationInfo? = getSourceInfo(callingPackage)
- // Uid of the source package, with a preference to uid from ApplicationInfo
- originatingUid = sourceInfo?.uid ?: callingUid
appOpRequestInfo = AppOpRequestInfo(
getPackageNameForUid(context, originatingUid, callingPackage),
- originatingUid, callingAttributionTag
+ originatingUid,
+ callingAttributionTag
)
- if(localLogv) {
- Log.i(LOG_TAG, "Intent: $intent\n" +
- "sessionId: $sessionId\n" +
- "staged sessionId: $stagedSessionId\n" +
- "calling package: $callingPackage\n" +
- "callingUid: $callingUid\n" +
- "originatingUid: $originatingUid")
- }
-
- if (callingUid == Process.INVALID_UID && sourceInfo == null) {
- // Caller's identity could not be determined. Abort the install
- Log.e(LOG_TAG, "Cannot determine caller since UID is invalid and sourceInfo is null")
- return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
+ if (localLogv) {
+ Log.i(
+ LOG_TAG, "Intent: $intent\n" +
+ "sessionId: $sessionId\n" +
+ "staged sessionId: $stagedSessionId\n" +
+ "calling package: $callingPackage\n" +
+ "callingUid: $callingUid\n" +
+ "originatingUid: $originatingUid\n" +
+ "sourceInfo: $sourceInfo"
+ )
}
if ((sessionId != SessionInfo.INVALID_ID
- && !isCallerSessionOwner(packageInstaller, originatingUid, sessionId))
+ && !isCallerSessionOwner(packageInstaller, callingUid, sessionId))
|| (stagedSessionId != SessionInfo.INVALID_ID
&& !isCallerSessionOwner(packageInstaller, Process.myUid(), stagedSessionId))
) {
- Log.e(LOG_TAG, "UID is not the owner of the session:\n" +
- "CallingUid: $originatingUid | SessionId: $sessionId\n" +
- "My UID: ${Process.myUid()} | StagedSessionId: $stagedSessionId")
+ Log.e(
+ LOG_TAG, "UID is not the owner of the session:\n" +
+ "CallingUid: $callingUid | SessionId: $sessionId\n" +
+ "My UID: ${Process.myUid()} | StagedSessionId: $stagedSessionId"
+ )
return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
}
- isTrustedSource = isInstallRequestFromTrustedSource(sourceInfo, this.intent, originatingUid)
- if (!isInstallPermissionGrantedOrRequested(
- context, callingUid, originatingUid, isTrustedSource
- )
- ) {
- Log.e(LOG_TAG, "UID $originatingUid needs to declare " +
- Manifest.permission.REQUEST_INSTALL_PACKAGES
- )
+ isTrustedSource = isInstallRequestFromTrustedSource(sourceInfo, this.intent, callingUid)
+ if (!isInstallPermissionGrantedOrRequested(context, callingUid, isTrustedSource)) {
return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
}
- val restriction = getDevicePolicyRestrictions()
+ val restriction = getDevicePolicyRestrictions(isTrustedSource)
if (restriction != null) {
val adminSupportDetailsIntent =
devicePolicyManager!!.createAdminSupportIntent(restriction)
- Log.e(LOG_TAG, "$restriction set in place. Cannot install." )
+ Log.e(LOG_TAG, "$restriction set in place. Cannot install.")
return InstallAborted(
ABORT_REASON_POLICY, message = restriction, resultIntent = adminSupportDetailsIntent
)
@@ -230,20 +235,27 @@ class InstallRepository(private val context: Context) {
private fun isInstallRequestFromTrustedSource(
sourceInfo: ApplicationInfo?,
intent: Intent,
- originatingUid: Int,
+ callingUid: Int,
): Boolean {
- val isNotUnknownSource = intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)
- return (sourceInfo != null && sourceInfo.isPrivilegedApp
- && (isNotUnknownSource
- || isPermissionGranted(context, Manifest.permission.INSTALL_PACKAGES, originatingUid)))
+ val isPrivilegedAndKnown = sourceInfo != null && sourceInfo.isPrivilegedApp &&
+ intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)
+ val isInstallPkgPermissionGranted =
+ isPermissionGranted(context, Manifest.permission.INSTALL_PACKAGES, callingUid)
+
+ return isPrivilegedAndKnown || isInstallPkgPermissionGranted
}
- private fun getDevicePolicyRestrictions(): String? {
- val restrictions = arrayOf(
- UserManager.DISALLOW_INSTALL_APPS,
- UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
- UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY
- )
+ private fun getDevicePolicyRestrictions(isTrustedSource: Boolean): String? {
+ val restrictions: Array<String> = if (isTrustedSource) {
+ arrayOf(UserManager.DISALLOW_INSTALL_APPS)
+ } else {
+ arrayOf(
+ UserManager.DISALLOW_INSTALL_APPS,
+ UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
+ UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY
+ )
+ }
+
for (restriction in restrictions) {
if (!userManager!!.hasUserRestrictionForUser(restriction, Process.myUserHandle())) {
continue
@@ -320,7 +332,7 @@ class InstallRepository(private val context: Context) {
Intent.EXTRA_INSTALL_RESULT, PackageManager.INSTALL_FAILED_INVALID_APK
),
activityResultCode = Activity.RESULT_FIRST_USER,
- errorDialogType = if (e is IOException) DLG_PACKAGE_ERROR else DLG_NONE
+ errorDialogType = if (e is IOException) DLG_PACKAGE_ERROR else DLG_NONE
)
return
}
@@ -401,8 +413,9 @@ class InstallRepository(private val context: Context) {
Log.e(LOG_TAG, "Cannot parse package $debugPathName. Assuming defaults.", e)
params.setSize(pfd.statSize)
} catch (e: IOException) {
- Log.e(LOG_TAG, "Cannot calculate installed size $debugPathName. " +
- "Try only apk size.", e
+ Log.e(
+ LOG_TAG, "Cannot calculate installed size $debugPathName. " +
+ "Try only apk size.", e
)
}
} else {
@@ -661,10 +674,9 @@ class InstallRepository(private val context: Context) {
if (isAppUpdating(pkgInfo)) {
val existingUpdateOwnerLabel = getExistingUpdateOwnerLabel(pkgInfo)
- val originatingPackageNameFromSessionInfo =
- getPackageNameForUid(context, originatingUidFromSessionInfo, callingPackage)
- val requestedUpdateOwnerLabel =
- getApplicationLabel(originatingPackageNameFromSessionInfo)
+ val originatingPackageName =
+ getPackageNameForUid(context, originatingUid, callingPackage)
+ val requestedUpdateOwnerLabel = getApplicationLabel(originatingPackageName)
if (!TextUtils.isEmpty(existingUpdateOwnerLabel)
&& userActionReason == PackageInstaller.REASON_REMIND_OWNERSHIP
@@ -768,14 +780,14 @@ class InstallRepository(private val context: Context) {
}
private fun handleUnknownSources(requestInfo: AppOpRequestInfo): InstallStage {
- if (requestInfo.callingPackage == null) {
+ if (requestInfo.originatingPackage == null) {
Log.i(LOG_TAG, "No source found for package " + newPackageInfo?.packageName)
return InstallUserActionRequired(USER_ACTION_REASON_ANONYMOUS_SOURCE)
}
// Shouldn't use static constant directly, see b/65534401.
val appOpStr = AppOpsManager.permissionToOp(Manifest.permission.REQUEST_INSTALL_PACKAGES)
val appOpMode = appOpsManager!!.noteOpNoThrow(
- appOpStr!!, requestInfo.originatingUid, requestInfo.callingPackage,
+ appOpStr!!, requestInfo.originatingUid, requestInfo.originatingPackage,
requestInfo.attributionTag, "Started package installation activity"
)
if (localLogv) {
@@ -786,20 +798,20 @@ class InstallRepository(private val context: Context) {
AppOpsManager.MODE_DEFAULT, AppOpsManager.MODE_ERRORED -> {
if (appOpMode == AppOpsManager.MODE_DEFAULT) {
appOpsManager.setMode(
- appOpStr, requestInfo.originatingUid, requestInfo.callingPackage,
+ appOpStr, requestInfo.originatingUid, requestInfo.originatingPackage,
AppOpsManager.MODE_ERRORED
)
}
try {
val sourceInfo =
- packageManager.getApplicationInfo(requestInfo.callingPackage, 0)
+ packageManager.getApplicationInfo(requestInfo.originatingPackage, 0)
val sourceAppSnippet = getAppSnippet(context, sourceInfo)
InstallUserActionRequired(
USER_ACTION_REASON_UNKNOWN_SOURCE, appSnippet = sourceAppSnippet,
- dialogMessage = requestInfo.callingPackage
+ sourceApp = requestInfo.originatingPackage
)
} catch (e: PackageManager.NameNotFoundException) {
- Log.e(LOG_TAG, "Did not find appInfo for " + requestInfo.callingPackage)
+ Log.e(LOG_TAG, "Did not find appInfo for " + requestInfo.originatingPackage)
InstallAborted(ABORT_REASON_INTERNAL_ERROR)
}
}
@@ -841,8 +853,10 @@ class InstallRepository(private val context: Context) {
setStageBasedOnResult(PackageInstaller.STATUS_SUCCESS, -1, null)
} catch (e: PackageManager.NameNotFoundException) {
setStageBasedOnResult(
- PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
- null)
+ PackageInstaller.STATUS_FAILURE,
+ PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
+ null
+ )
}
return
}
@@ -862,7 +876,8 @@ class InstallRepository(private val context: Context) {
}
} catch (e: OutOfIdsException) {
setStageBasedOnResult(
- PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null)
+ PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null
+ )
return
}
val broadcastIntent = Intent(BROADCAST_ACTION)
@@ -880,7 +895,8 @@ class InstallRepository(private val context: Context) {
Log.e(LOG_TAG, "Session $stagedSessionId could not be opened.", e)
packageInstaller.abandonSession(stagedSessionId)
setStageBasedOnResult(
- PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null)
+ PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null
+ )
}
}
@@ -890,9 +906,11 @@ class InstallRepository(private val context: Context) {
message: String?,
) {
if (localLogv) {
- Log.i(LOG_TAG, "Status code: $statusCode\n" +
- "legacy status: $legacyStatus\n" +
- "message: $message")
+ Log.i(
+ LOG_TAG, "Status code: $statusCode\n" +
+ "legacy status: $legacyStatus\n" +
+ "message: $message"
+ )
}
if (statusCode == PackageInstaller.STATUS_SUCCESS) {
val shouldReturnResult = intent.getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)
@@ -905,11 +923,12 @@ class InstallRepository(private val context: Context) {
_installResult.setValue(InstallSuccess(appSnippet, shouldReturnResult, resultIntent))
} else {
if (statusCode != PackageInstaller.STATUS_FAILURE_ABORTED) {
- _installResult.setValue(InstallFailed(appSnippet, statusCode, legacyStatus, message))
+ _installResult.setValue(
+ InstallFailed(appSnippet, statusCode, legacyStatus, message)
+ )
} else {
_installResult.setValue(InstallAborted(ABORT_REASON_INTERNAL_ERROR))
}
-
}
}
@@ -953,7 +972,7 @@ class InstallRepository(private val context: Context) {
data class CallerInfo(val packageName: String?, val uid: Int)
data class AppOpRequestInfo(
- val callingPackage: String?,
+ val originatingPackage: String?,
val originatingUid: Int,
val attributionTag: String?,
)
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt
index bbb9bca6db51..5dd4d2905f47 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt
@@ -43,7 +43,10 @@ data class InstallUserActionRequired(
val actionReason: Int,
private val appSnippet: PackageUtil.AppSnippet? = null,
val isAppUpdating: Boolean = false,
- val dialogMessage: String? = null,
+ /**
+ * This holds either a package name or the app label of the install source.
+ */
+ val sourceApp: String? = null,
) : InstallStage(STAGE_USER_ACTION_REQUIRED) {
val appIcon: Drawable?
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
index bae6f6876580..828a95fcbb01 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
@@ -128,18 +128,19 @@ object PackageUtil {
/**
* @param context the [Context] object
- * @param callingUid the UID of the caller who's permission is being checked
- * @param originatingUid the UID from where install is being originated. This could be same as
- * callingUid or it will be the UID of the package performing a session based install
- * @param isTrustedSource whether install request is coming from a privileged app or an app that
- * has [Manifest.permission.INSTALL_PACKAGES] permission granted
- * @return `true` if the package is granted the said permission
+ * @param callingUid the UID of the caller of Pia
+ * @param isTrustedSource indicates whether install request is coming from a privileged app
+ * that has passed EXTRA_NOT_UNKNOWN_SOURCE as `true` in the installation intent, or an app that
+ * has the [INSTALL_PACKAGES][Manifest.permission.INSTALL_PACKAGES] permission granted.
+ *
+ * @return `true` if the package is either a system downloads provider, a document manager,
+ * a trusted source, or has declared the
+ * [REQUEST_INSTALL_PACKAGES][Manifest.permission.REQUEST_INSTALL_PACKAGES] in its manifest.
*/
@JvmStatic
fun isInstallPermissionGrantedOrRequested(
context: Context,
callingUid: Int,
- originatingUid: Int,
isTrustedSource: Boolean,
): Boolean {
val isDocumentsManager =
@@ -148,19 +149,18 @@ object PackageUtil {
getSystemDownloadsProviderInfo(context.packageManager, callingUid) != null
if (!isTrustedSource && !isSystemDownloadsProvider && !isDocumentsManager) {
- val targetSdkVersion = getMaxTargetSdkVersionForUid(context, originatingUid)
+ val targetSdkVersion = getMaxTargetSdkVersionForUid(context, callingUid)
if (targetSdkVersion < 0) {
- // Invalid originating uid supplied. Abort install.
- Log.w(LOG_TAG, "Cannot get target sdk version for uid $originatingUid")
+ // Invalid calling uid supplied. Abort install.
+ Log.e(LOG_TAG, "Cannot get target SDK version for uid $callingUid")
return false
} else if (targetSdkVersion >= Build.VERSION_CODES.O
&& !isUidRequestingPermission(
- context.packageManager, originatingUid,
- Manifest.permission.REQUEST_INSTALL_PACKAGES
+ context.packageManager, callingUid, Manifest.permission.REQUEST_INSTALL_PACKAGES
)
) {
Log.e(
- LOG_TAG, "Requesting uid " + originatingUid + " needs to declare permission "
+ LOG_TAG, "Requesting uid " + callingUid + " needs to declare permission "
+ Manifest.permission.REQUEST_INSTALL_PACKAGES
)
return false
@@ -204,13 +204,13 @@ object PackageUtil {
* @return `true` if the caller is the session owner
*/
@JvmStatic
- fun isCallerSessionOwner(pi: PackageInstaller, originatingUid: Int, sessionId: Int): Boolean {
- if (originatingUid == Process.ROOT_UID) {
+ fun isCallerSessionOwner(pi: PackageInstaller, callingUid: Int, sessionId: Int): Boolean {
+ if (callingUid == Process.ROOT_UID) {
return true
}
val sessionInfo = pi.getSessionInfo(sessionId) ?: return false
val installerUid = sessionInfo.getInstallerUid()
- return originatingUid == installerUid
+ return callingUid == installerUid
}
/**
@@ -362,8 +362,8 @@ object PackageUtil {
* @return the packageName corresponding to a UID.
*/
@JvmStatic
- fun getPackageNameForUid(context: Context, sourceUid: Int, callingPackage: String?): String? {
- if (sourceUid == Process.INVALID_UID) {
+ fun getPackageNameForUid(context: Context, uid: Int, preferredPkgName: String?): String? {
+ if (uid == Process.INVALID_UID) {
return null
}
// If the sourceUid belongs to the system downloads provider, we explicitly return the
@@ -371,20 +371,21 @@ object PackageUtil {
// packages, resulting in uncertainty about which package will end up first in the list
// of packages associated with this UID
val pm = context.packageManager
- val systemDownloadProviderInfo = getSystemDownloadsProviderInfo(pm, sourceUid)
+ val systemDownloadProviderInfo = getSystemDownloadsProviderInfo(pm, uid)
if (systemDownloadProviderInfo != null) {
return systemDownloadProviderInfo.packageName
}
- val packagesForUid = pm.getPackagesForUid(sourceUid) ?: return null
+
+ val packagesForUid = pm.getPackagesForUid(uid) ?: return null
if (packagesForUid.size > 1) {
- if (callingPackage != null) {
+ Log.i(LOG_TAG, "Multiple packages found for source uid $uid")
+ if (preferredPkgName != null) {
for (packageName in packagesForUid) {
- if (packageName == callingPackage) {
+ if (packageName == preferredPkgName) {
return packageName
}
}
}
- Log.i(LOG_TAG, "Multiple packages found for source uid $sourceUid")
}
return packagesForUid[0]
}
@@ -439,7 +440,7 @@ object PackageUtil {
*/
data class AppSnippet(var label: CharSequence?, var icon: Drawable?) {
override fun toString(): String {
- return "AppSnippet[label = ${label}, hasIcon = ${icon != null}]"
+ return "AppSnippet[label = $label, hasIcon = ${icon != null}]"
}
}
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
index a95137d57a32..343a213780b3 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
@@ -63,7 +63,7 @@ public class ExternalSourcesBlockedFragment extends DialogFragment {
.setMessage(R.string.untrusted_external_source_warning)
.setPositiveButton(R.string.external_sources_settings,
(dialog, which) -> mInstallActionListener.sendUnknownAppsIntent(
- mDialogData.getDialogMessage()))
+ mDialogData.getSourceApp()))
.setNegativeButton(R.string.cancel,
(dialog, which) -> mInstallActionListener.onNegativeResponse(
mDialogData.getStageCode()))
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
index 99b1eec9cd9e..e186590fa5e2 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
@@ -64,7 +64,7 @@ public class InstallConfirmationFragment extends DialogFragment {
int positiveBtnTextRes;
if (mDialogData.isAppUpdating()) {
- if (mDialogData.getDialogMessage() != null) {
+ if (mDialogData.getSourceApp() != null) {
positiveBtnTextRes = R.string.update_anyway;
} else {
positiveBtnTextRes = R.string.update;
@@ -88,9 +88,10 @@ public class InstallConfirmationFragment extends DialogFragment {
TextView viewToEnable;
if (mDialogData.isAppUpdating()) {
viewToEnable = dialogView.requireViewById(R.id.install_confirm_question_update);
- String dialogMessage = mDialogData.getDialogMessage();
- if (dialogMessage != null) {
- viewToEnable.setText(Html.fromHtml(dialogMessage, Html.FROM_HTML_MODE_LEGACY));
+ String sourcePackageName = mDialogData.getSourceApp();
+ if (sourcePackageName != null) {
+ // Show the update-ownership change message
+ viewToEnable.setText(Html.fromHtml(sourcePackageName, Html.FROM_HTML_MODE_LEGACY));
}
} else {
viewToEnable = dialogView.requireViewById(R.id.install_confirm_question);
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java
deleted file mode 100644
index 53a460dc18ca..000000000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.packageinstaller.wear;
-
-import android.content.Context;
-import android.content.IntentSender;
-import android.content.pm.PackageInstaller;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Task that installs an APK. This must not be called on the main thread.
- * This code is based off the Finsky/Wearsky implementation
- */
-public class InstallTask {
- private static final String TAG = "InstallTask";
-
- private static final int DEFAULT_BUFFER_SIZE = 8192;
-
- private final Context mContext;
- private String mPackageName;
- private ParcelFileDescriptor mParcelFileDescriptor;
- private PackageInstallerImpl.InstallListener mCallback;
- private PackageInstaller.Session mSession;
- private IntentSender mCommitCallback;
-
- private Exception mException = null;
- private int mErrorCode = 0;
- private String mErrorDesc = null;
-
- public InstallTask(Context context, String packageName,
- ParcelFileDescriptor parcelFileDescriptor,
- PackageInstallerImpl.InstallListener callback, PackageInstaller.Session session,
- IntentSender commitCallback) {
- mContext = context;
- mPackageName = packageName;
- mParcelFileDescriptor = parcelFileDescriptor;
- mCallback = callback;
- mSession = session;
- mCommitCallback = commitCallback;
- }
-
- public boolean isError() {
- return mErrorCode != InstallerConstants.STATUS_SUCCESS || !TextUtils.isEmpty(mErrorDesc);
- }
-
- public void execute() {
- if (Looper.myLooper() == Looper.getMainLooper()) {
- throw new IllegalStateException("This method cannot be called from the UI thread.");
- }
-
- OutputStream sessionStream = null;
- try {
- sessionStream = mSession.openWrite(mPackageName, 0, -1);
-
- // 2b: Stream the asset to the installer. Note:
- // Note: writeToOutputStreamFromAsset() always safely closes the input stream
- writeToOutputStreamFromAsset(sessionStream);
- mSession.fsync(sessionStream);
- } catch (Exception e) {
- mException = e;
- mErrorCode = InstallerConstants.ERROR_INSTALL_COPY_STREAM;
- mErrorDesc = "Could not write to stream";
- } finally {
- if (sessionStream != null) {
- // 2c: close output stream
- try {
- sessionStream.close();
- } catch (Exception e) {
- // Ignore otherwise
- if (mException == null) {
- mException = e;
- mErrorCode = InstallerConstants.ERROR_INSTALL_CLOSE_STREAM;
- mErrorDesc = "Could not close session stream";
- }
- }
- }
- }
-
- if (mErrorCode != InstallerConstants.STATUS_SUCCESS) {
- // An error occurred, we're done
- Log.e(TAG, "Exception while installing " + mPackageName + ": " + mErrorCode + ", "
- + mErrorDesc + ", " + mException);
- mSession.close();
- mCallback.installFailed(mErrorCode, "[" + mPackageName + "]" + mErrorDesc);
- } else {
- // 3. Commit the session (this actually installs it.) Session map
- // will be cleaned up in the callback.
- mCallback.installBeginning();
- mSession.commit(mCommitCallback);
- mSession.close();
- }
- }
-
- /**
- * {@code PackageInstaller} works with streams. Get the {@code FileDescriptor}
- * corresponding to the {@code Asset} and then write the contents into an
- * {@code OutputStream} that is passed in.
- * <br>
- * The {@code FileDescriptor} is closed but the {@code OutputStream} is not closed.
- */
- private boolean writeToOutputStreamFromAsset(OutputStream outputStream) {
- if (outputStream == null) {
- mErrorCode = InstallerConstants.ERROR_INSTALL_COPY_STREAM_EXCEPTION;
- mErrorDesc = "Got a null OutputStream.";
- return false;
- }
-
- if (mParcelFileDescriptor == null || mParcelFileDescriptor.getFileDescriptor() == null) {
- mErrorCode = InstallerConstants.ERROR_COULD_NOT_GET_FD;
- mErrorDesc = "Could not get FD";
- return false;
- }
-
- InputStream inputStream = null;
- try {
- byte[] inputBuf = new byte[DEFAULT_BUFFER_SIZE];
- int bytesRead;
- inputStream = new ParcelFileDescriptor.AutoCloseInputStream(mParcelFileDescriptor);
-
- while ((bytesRead = inputStream.read(inputBuf)) > -1) {
- if (bytesRead > 0) {
- outputStream.write(inputBuf, 0, bytesRead);
- }
- }
-
- outputStream.flush();
- } catch (IOException e) {
- mErrorCode = InstallerConstants.ERROR_INSTALL_APK_COPY_FAILURE;
- mErrorDesc = "Reading from Asset FD or writing to temp file failed: " + e;
- return false;
- } finally {
- safeClose(inputStream);
- }
-
- return true;
- }
-
- /**
- * Quietly close a closeable resource (e.g. a stream or file). The input may already
- * be closed and it may even be null.
- */
- public static void safeClose(Closeable resource) {
- if (resource != null) {
- try {
- resource.close();
- } catch (IOException ioe) {
- // Catch and discard the error
- }
- }
- }
-} \ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java
deleted file mode 100644
index 3daf3d831d97..000000000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.packageinstaller.wear;
-
-/**
- * Constants for Installation / Uninstallation requests.
- * Using the same values as Finsky/Wearsky code for consistency in user analytics of failures
- */
-public class InstallerConstants {
- /** Request succeeded */
- public static final int STATUS_SUCCESS = 0;
-
- /**
- * The new PackageInstaller also returns a small set of less granular error codes, which
- * we'll remap to the range -500 and below to keep away from existing installer codes
- * (which run from -1 to -110).
- */
- public final static int ERROR_PACKAGEINSTALLER_BASE = -500;
-
- public static final int ERROR_COULD_NOT_GET_FD = -603;
- /** This node is not targeted by this request. */
-
- /** The install did not complete because could not create PackageInstaller session */
- public final static int ERROR_INSTALL_CREATE_SESSION = -612;
- /** The install did not complete because could not open PackageInstaller session */
- public final static int ERROR_INSTALL_OPEN_SESSION = -613;
- /** The install did not complete because could not open PackageInstaller output stream */
- public final static int ERROR_INSTALL_OPEN_STREAM = -614;
- /** The install did not complete because of an exception while streaming bytes */
- public final static int ERROR_INSTALL_COPY_STREAM_EXCEPTION = -615;
- /** The install did not complete because of an unexpected exception from PackageInstaller */
- public final static int ERROR_INSTALL_SESSION_EXCEPTION = -616;
- /** The install did not complete because of an unexpected userActionRequired callback */
- public final static int ERROR_INSTALL_USER_ACTION_REQUIRED = -617;
- /** The install did not complete because of an unexpected broadcast (missing fields) */
- public final static int ERROR_INSTALL_MALFORMED_BROADCAST = -618;
- /** The install did not complete because of an error while copying from downloaded file */
- public final static int ERROR_INSTALL_APK_COPY_FAILURE = -619;
- /** The install did not complete because of an error while copying to the PackageInstaller
- * output stream */
- public final static int ERROR_INSTALL_COPY_STREAM = -620;
- /** The install did not complete because of an error while closing the PackageInstaller
- * output stream */
- public final static int ERROR_INSTALL_CLOSE_STREAM = -621;
-} \ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java
deleted file mode 100644
index bdc22cf0e276..000000000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.packageinstaller.wear;
-
-import android.content.Context;
-
-/**
- * Factory that creates a Package Installer.
- */
-public class PackageInstallerFactory {
- private static PackageInstallerImpl sPackageInstaller;
-
- /**
- * Return the PackageInstaller shared object. {@code init} should have already been called.
- */
- public synchronized static PackageInstallerImpl getPackageInstaller(Context context) {
- if (sPackageInstaller == null) {
- sPackageInstaller = new PackageInstallerImpl(context);
- }
- return sPackageInstaller;
- }
-} \ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java
deleted file mode 100644
index 1e37f15f714d..000000000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.packageinstaller.wear;
-
-import android.annotation.TargetApi;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.pm.PackageInstaller;
-import android.os.Build;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Implementation of package manager installation using modern PackageInstaller api.
- *
- * Heavily copied from Wearsky/Finsky implementation
- */
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-public class PackageInstallerImpl {
- private static final String TAG = "PackageInstallerImpl";
-
- /** Intent actions used for broadcasts from PackageInstaller back to the local receiver */
- private static final String ACTION_INSTALL_COMMIT =
- "com.android.vending.INTENT_PACKAGE_INSTALL_COMMIT";
-
- private final Context mContext;
- private final PackageInstaller mPackageInstaller;
- private final Map<String, PackageInstaller.SessionInfo> mSessionInfoMap;
- private final Map<String, PackageInstaller.Session> mOpenSessionMap;
-
- public PackageInstallerImpl(Context context) {
- mContext = context.getApplicationContext();
- mPackageInstaller = mContext.getPackageManager().getPackageInstaller();
-
- // Capture a map of known sessions
- // This list will be pruned a bit later (stale sessions will be canceled)
- mSessionInfoMap = new HashMap<String, PackageInstaller.SessionInfo>();
- List<PackageInstaller.SessionInfo> mySessions = mPackageInstaller.getMySessions();
- for (int i = 0; i < mySessions.size(); i++) {
- PackageInstaller.SessionInfo sessionInfo = mySessions.get(i);
- String packageName = sessionInfo.getAppPackageName();
- PackageInstaller.SessionInfo oldInfo = mSessionInfoMap.put(packageName, sessionInfo);
-
- // Checking for old info is strictly for logging purposes
- if (oldInfo != null) {
- Log.w(TAG, "Multiple sessions for " + packageName + " found. Removing " + oldInfo
- .getSessionId() + " & keeping " + mySessions.get(i).getSessionId());
- }
- }
- mOpenSessionMap = new HashMap<String, PackageInstaller.Session>();
- }
-
- /**
- * This callback will be made after an installation attempt succeeds or fails.
- */
- public interface InstallListener {
- /**
- * This callback signals that preflight checks have succeeded and installation
- * is beginning.
- */
- void installBeginning();
-
- /**
- * This callback signals that installation has completed.
- */
- void installSucceeded();
-
- /**
- * This callback signals that installation has failed.
- */
- void installFailed(int errorCode, String errorDesc);
- }
-
- /**
- * This is a placeholder implementation that bundles an entire "session" into a single
- * call. This will be replaced by more granular versions that allow longer session lifetimes,
- * download progress tracking, etc.
- *
- * This must not be called on main thread.
- */
- public void install(final String packageName, ParcelFileDescriptor parcelFileDescriptor,
- final InstallListener callback) {
- // 0. Generic try/catch block because I am not really sure what exceptions (other than
- // IOException) might be thrown by PackageInstaller and I want to handle them
- // at least slightly gracefully.
- try {
- // 1. Create or recover a session, and open it
- // Try recovery first
- PackageInstaller.Session session = null;
- PackageInstaller.SessionInfo sessionInfo = mSessionInfoMap.get(packageName);
- if (sessionInfo != null) {
- // See if it's openable, or already held open
- session = getSession(packageName);
- }
- // If open failed, or there was no session, create a new one and open it.
- // If we cannot create or open here, the failure is terminal.
- if (session == null) {
- try {
- innerCreateSession(packageName);
- } catch (IOException ioe) {
- Log.e(TAG, "Can't create session for " + packageName + ": " + ioe.getMessage());
- callback.installFailed(InstallerConstants.ERROR_INSTALL_CREATE_SESSION,
- "Could not create session");
- mSessionInfoMap.remove(packageName);
- return;
- }
- sessionInfo = mSessionInfoMap.get(packageName);
- try {
- session = mPackageInstaller.openSession(sessionInfo.getSessionId());
- mOpenSessionMap.put(packageName, session);
- } catch (SecurityException se) {
- Log.e(TAG, "Can't open session for " + packageName + ": " + se.getMessage());
- callback.installFailed(InstallerConstants.ERROR_INSTALL_OPEN_SESSION,
- "Can't open session");
- mSessionInfoMap.remove(packageName);
- return;
- }
- }
-
- // 2. Launch task to handle file operations.
- InstallTask task = new InstallTask( mContext, packageName, parcelFileDescriptor,
- callback, session,
- getCommitCallback(packageName, sessionInfo.getSessionId(), callback));
- task.execute();
- if (task.isError()) {
- cancelSession(sessionInfo.getSessionId(), packageName);
- }
- } catch (Exception e) {
- Log.e(TAG, "Unexpected exception while installing: " + packageName + ": "
- + e.getMessage());
- callback.installFailed(InstallerConstants.ERROR_INSTALL_SESSION_EXCEPTION,
- "Unexpected exception while installing " + packageName);
- }
- }
-
- /**
- * Retrieve an existing session. Will open if needed, but does not attempt to create.
- */
- private PackageInstaller.Session getSession(String packageName) {
- // Check for already-open session
- PackageInstaller.Session session = mOpenSessionMap.get(packageName);
- if (session != null) {
- try {
- // Probe the session to ensure that it's still open. This may or may not
- // throw (if non-open), but it may serve as a canary for stale sessions.
- session.getNames();
- return session;
- } catch (IOException ioe) {
- Log.e(TAG, "Stale open session for " + packageName + ": " + ioe.getMessage());
- mOpenSessionMap.remove(packageName);
- } catch (SecurityException se) {
- Log.e(TAG, "Stale open session for " + packageName + ": " + se.getMessage());
- mOpenSessionMap.remove(packageName);
- }
- }
- // Check to see if this is a known session
- PackageInstaller.SessionInfo sessionInfo = mSessionInfoMap.get(packageName);
- if (sessionInfo == null) {
- return null;
- }
- // Try to open it. If we fail here, assume that the SessionInfo was stale.
- try {
- session = mPackageInstaller.openSession(sessionInfo.getSessionId());
- } catch (SecurityException se) {
- Log.w(TAG, "SessionInfo was stale for " + packageName + " - deleting info");
- mSessionInfoMap.remove(packageName);
- return null;
- } catch (IOException ioe) {
- Log.w(TAG, "IOException opening old session for " + ioe.getMessage()
- + " - deleting info");
- mSessionInfoMap.remove(packageName);
- return null;
- }
- mOpenSessionMap.put(packageName, session);
- return session;
- }
-
- /** This version throws an IOException when the session cannot be created */
- private void innerCreateSession(String packageName) throws IOException {
- if (mSessionInfoMap.containsKey(packageName)) {
- Log.w(TAG, "Creating session for " + packageName + " when one already exists");
- return;
- }
- PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
- PackageInstaller.SessionParams.MODE_FULL_INSTALL);
- params.setAppPackageName(packageName);
-
- // IOException may be thrown at this point
- int sessionId = mPackageInstaller.createSession(params);
- PackageInstaller.SessionInfo sessionInfo = mPackageInstaller.getSessionInfo(sessionId);
- mSessionInfoMap.put(packageName, sessionInfo);
- }
-
- /**
- * Cancel a session based on its sessionId. Package name is for logging only.
- */
- private void cancelSession(int sessionId, String packageName) {
- // Close if currently held open
- closeSession(packageName);
- // Remove local record
- mSessionInfoMap.remove(packageName);
- try {
- mPackageInstaller.abandonSession(sessionId);
- } catch (SecurityException se) {
- // The session no longer exists, so we can exit quietly.
- return;
- }
- }
-
- /**
- * Close a session if it happens to be held open.
- */
- private void closeSession(String packageName) {
- PackageInstaller.Session session = mOpenSessionMap.remove(packageName);
- if (session != null) {
- // Unfortunately close() is not idempotent. Try our best to make this safe.
- try {
- session.close();
- } catch (Exception e) {
- Log.w(TAG, "Unexpected error closing session for " + packageName + ": "
- + e.getMessage());
- }
- }
- }
-
- /**
- * Creates a commit callback for the package install that's underway. This will be called
- * some time after calling session.commit() (above).
- */
- private IntentSender getCommitCallback(final String packageName, final int sessionId,
- final InstallListener callback) {
- // Create a single-use broadcast receiver
- BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- mContext.unregisterReceiver(this);
- handleCommitCallback(intent, packageName, sessionId, callback);
- }
- };
- // Create a matching intent-filter and register the receiver
- String action = ACTION_INSTALL_COMMIT + "." + packageName;
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(action);
- mContext.registerReceiver(broadcastReceiver, intentFilter,
- Context.RECEIVER_EXPORTED);
-
- // Create a matching PendingIntent and use it to generate the IntentSender
- Intent broadcastIntent = new Intent(action).setPackage(mContext.getPackageName());
- PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, packageName.hashCode(),
- broadcastIntent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT
- | PendingIntent.FLAG_MUTABLE);
- return pendingIntent.getIntentSender();
- }
-
- /**
- * Examine the extras to determine information about the package update/install, decode
- * the result, and call the appropriate callback.
- *
- * @param intent The intent, which the PackageInstaller will have added Extras to
- * @param packageName The package name we created the receiver for
- * @param sessionId The session Id we created the receiver for
- * @param callback The callback to report success/failure to
- */
- private void handleCommitCallback(Intent intent, String packageName, int sessionId,
- InstallListener callback) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Installation of " + packageName + " finished with extras "
- + intent.getExtras());
- }
- String statusMessage = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);
- int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, Integer.MIN_VALUE);
- if (status == PackageInstaller.STATUS_SUCCESS) {
- cancelSession(sessionId, packageName);
- callback.installSucceeded();
- } else if (status == -1 /*PackageInstaller.STATUS_USER_ACTION_REQUIRED*/) {
- // TODO - use the constant when the correct/final name is in the SDK
- // TODO This is unexpected, so we are treating as failure for now
- cancelSession(sessionId, packageName);
- callback.installFailed(InstallerConstants.ERROR_INSTALL_USER_ACTION_REQUIRED,
- "Unexpected: user action required");
- } else {
- cancelSession(sessionId, packageName);
- int errorCode = getPackageManagerErrorCode(status);
- Log.e(TAG, "Error " + errorCode + " while installing " + packageName + ": "
- + statusMessage);
- callback.installFailed(errorCode, null);
- }
- }
-
- private int getPackageManagerErrorCode(int status) {
- // This is a hack: because PackageInstaller now reports error codes
- // with small positive values, we need to remap them into a space
- // that is more compatible with the existing package manager error codes.
- // See https://sites.google.com/a/google.com/universal-store/documentation
- // /android-client/download-error-codes
- int errorCode;
- if (status == Integer.MIN_VALUE) {
- errorCode = InstallerConstants.ERROR_INSTALL_MALFORMED_BROADCAST;
- } else {
- errorCode = InstallerConstants.ERROR_PACKAGEINSTALLER_BASE - status;
- }
- return errorCode;
- }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java
deleted file mode 100644
index 2c289b2a6f94..000000000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.packageinstaller.wear;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-
-/**
- * Installation Util that contains a list of parameters that are needed for
- * installing/uninstalling.
- */
-public class WearPackageArgs {
- private static final String KEY_PACKAGE_NAME =
- "com.google.android.clockwork.EXTRA_PACKAGE_NAME";
- private static final String KEY_ASSET_URI =
- "com.google.android.clockwork.EXTRA_ASSET_URI";
- private static final String KEY_START_ID =
- "com.google.android.clockwork.EXTRA_START_ID";
- private static final String KEY_PERM_URI =
- "com.google.android.clockwork.EXTRA_PERM_URI";
- private static final String KEY_CHECK_PERMS =
- "com.google.android.clockwork.EXTRA_CHECK_PERMS";
- private static final String KEY_SKIP_IF_SAME_VERSION =
- "com.google.android.clockwork.EXTRA_SKIP_IF_SAME_VERSION";
- private static final String KEY_COMPRESSION_ALG =
- "com.google.android.clockwork.EXTRA_KEY_COMPRESSION_ALG";
- private static final String KEY_COMPANION_SDK_VERSION =
- "com.google.android.clockwork.EXTRA_KEY_COMPANION_SDK_VERSION";
- private static final String KEY_COMPANION_DEVICE_VERSION =
- "com.google.android.clockwork.EXTRA_KEY_COMPANION_DEVICE_VERSION";
- private static final String KEY_SHOULD_CHECK_GMS_DEPENDENCY =
- "com.google.android.clockwork.EXTRA_KEY_SHOULD_CHECK_GMS_DEPENDENCY";
- private static final String KEY_SKIP_IF_LOWER_VERSION =
- "com.google.android.clockwork.EXTRA_SKIP_IF_LOWER_VERSION";
-
- public static String getPackageName(Bundle b) {
- return b.getString(KEY_PACKAGE_NAME);
- }
-
- public static Bundle setPackageName(Bundle b, String packageName) {
- b.putString(KEY_PACKAGE_NAME, packageName);
- return b;
- }
-
- public static Uri getAssetUri(Bundle b) {
- return b.getParcelable(KEY_ASSET_URI);
- }
-
- public static Uri getPermUri(Bundle b) {
- return b.getParcelable(KEY_PERM_URI);
- }
-
- public static boolean checkPerms(Bundle b) {
- return b.getBoolean(KEY_CHECK_PERMS);
- }
-
- public static boolean skipIfSameVersion(Bundle b) {
- return b.getBoolean(KEY_SKIP_IF_SAME_VERSION);
- }
-
- public static int getCompanionSdkVersion(Bundle b) {
- return b.getInt(KEY_COMPANION_SDK_VERSION);
- }
-
- public static int getCompanionDeviceVersion(Bundle b) {
- return b.getInt(KEY_COMPANION_DEVICE_VERSION);
- }
-
- public static String getCompressionAlg(Bundle b) {
- return b.getString(KEY_COMPRESSION_ALG);
- }
-
- public static int getStartId(Bundle b) {
- return b.getInt(KEY_START_ID);
- }
-
- public static boolean skipIfLowerVersion(Bundle b) {
- return b.getBoolean(KEY_SKIP_IF_LOWER_VERSION, false);
- }
-
- public static Bundle setStartId(Bundle b, int startId) {
- b.putInt(KEY_START_ID, startId);
- return b;
- }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java
deleted file mode 100644
index 02b9d298db0e..000000000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.packageinstaller.wear;
-
-import android.annotation.TargetApi;
-import android.app.ActivityManager;
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Build;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.List;
-
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
-public class WearPackageIconProvider extends ContentProvider {
- private static final String TAG = "WearPackageIconProvider";
- public static final String AUTHORITY = "com.google.android.packageinstaller.wear.provider";
-
- private static final String REQUIRED_PERMISSION =
- "com.google.android.permission.INSTALL_WEARABLE_PACKAGES";
-
- /** MIME types. */
- public static final String ICON_TYPE = "vnd.android.cursor.item/cw_package_icon";
-
- @Override
- public boolean onCreate() {
- return true;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- throw new UnsupportedOperationException("Query is not supported.");
- }
-
- @Override
- public String getType(Uri uri) {
- if (uri == null) {
- throw new IllegalArgumentException("URI passed in is null.");
- }
-
- if (AUTHORITY.equals(uri.getEncodedAuthority())) {
- return ICON_TYPE;
- }
- return null;
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- throw new UnsupportedOperationException("Insert is not supported.");
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- if (uri == null) {
- throw new IllegalArgumentException("URI passed in is null.");
- }
-
- enforcePermissions(uri);
-
- if (ICON_TYPE.equals(getType(uri))) {
- final File file = WearPackageUtil.getIconFile(
- this.getContext().getApplicationContext(), getPackageNameFromUri(uri));
- if (file != null) {
- file.delete();
- }
- }
-
- return 0;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- throw new UnsupportedOperationException("Update is not supported.");
- }
-
- @Override
- public ParcelFileDescriptor openFile(
- Uri uri, @SuppressWarnings("unused") String mode) throws FileNotFoundException {
- if (uri == null) {
- throw new IllegalArgumentException("URI passed in is null.");
- }
-
- enforcePermissions(uri);
-
- if (ICON_TYPE.equals(getType(uri))) {
- final File file = WearPackageUtil.getIconFile(
- this.getContext().getApplicationContext(), getPackageNameFromUri(uri));
- if (file != null) {
- return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
- }
- }
- return null;
- }
-
- public static Uri getUriForPackage(final String packageName) {
- return Uri.parse("content://" + AUTHORITY + "/icons/" + packageName + ".icon");
- }
-
- private String getPackageNameFromUri(Uri uri) {
- if (uri == null) {
- return null;
- }
- List<String> pathSegments = uri.getPathSegments();
- String packageName = pathSegments.get(pathSegments.size() - 1);
-
- if (packageName.endsWith(".icon")) {
- packageName = packageName.substring(0, packageName.lastIndexOf("."));
- }
- return packageName;
- }
-
- /**
- * Make sure the calling app is either a system app or the same app or has the right permission.
- * @throws SecurityException if the caller has insufficient permissions.
- */
- @TargetApi(Build.VERSION_CODES.BASE_1_1)
- private void enforcePermissions(Uri uri) {
- // Redo some of the permission check in {@link ContentProvider}. Just add an extra check to
- // allow System process to access this provider.
- Context context = getContext();
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- final int myUid = android.os.Process.myUid();
-
- if (uid == myUid || isSystemApp(context, pid)) {
- return;
- }
-
- if (context.checkPermission(REQUIRED_PERMISSION, pid, uid) == PERMISSION_GRANTED) {
- return;
- }
-
- // last chance, check against any uri grants
- if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
- == PERMISSION_GRANTED) {
- return;
- }
-
- throw new SecurityException("Permission Denial: reading "
- + getClass().getName() + " uri " + uri + " from pid=" + pid
- + ", uid=" + uid);
- }
-
- /**
- * From the pid of the calling process, figure out whether this is a system app or not. We do
- * this by checking the application information corresponding to the pid and then checking if
- * FLAG_SYSTEM is set.
- */
- @TargetApi(Build.VERSION_CODES.CUPCAKE)
- private boolean isSystemApp(Context context, int pid) {
- // Get the Activity Manager Object
- ActivityManager aManager =
- (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
- // Get the list of running Applications
- List<ActivityManager.RunningAppProcessInfo> rapInfoList =
- aManager.getRunningAppProcesses();
- for (ActivityManager.RunningAppProcessInfo rapInfo : rapInfoList) {
- if (rapInfo.pid == pid) {
- try {
- PackageInfo pkgInfo = context.getPackageManager().getPackageInfo(
- rapInfo.pkgList[0], 0);
- if (pkgInfo != null && pkgInfo.applicationInfo != null &&
- (pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- Log.d(TAG, pid + " is a system app.");
- return true;
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Could not find package information.", e);
- return false;
- }
- }
- }
- return false;
- }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
deleted file mode 100644
index ae0f4ece1c17..000000000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.packageinstaller.wear;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.FeatureInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
-import android.content.pm.VersionedPackage;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
-import android.os.Process;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Pair;
-import androidx.annotation.Nullable;
-import com.android.packageinstaller.DeviceUtils;
-import com.android.packageinstaller.PackageUtil;
-import com.android.packageinstaller.R;
-import com.android.packageinstaller.common.EventResultPersister;
-import com.android.packageinstaller.common.UninstallEventReceiver;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Service that will install/uninstall packages. It will check for permissions and features as well.
- *
- * -----------
- *
- * Debugging information:
- *
- * Install Action example:
- * adb shell am startservice -a com.android.packageinstaller.wear.INSTALL_PACKAGE \
- * -d package://com.google.android.gms \
- * --eu com.google.android.clockwork.EXTRA_ASSET_URI content://com.google.android.clockwork.home.provider/host/com.google.android.wearable.app/wearable/com.google.android.gms/apk \
- * --es android.intent.extra.INSTALLER_PACKAGE_NAME com.google.android.gms \
- * --ez com.google.android.clockwork.EXTRA_CHECK_PERMS false \
- * --eu com.google.android.clockwork.EXTRA_PERM_URI content://com.google.android.clockwork.home.provider/host/com.google.android.wearable.app/permissions \
- * com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
- *
- * Uninstall Action example:
- * adb shell am startservice -a com.android.packageinstaller.wear.UNINSTALL_PACKAGE \
- * -d package://com.google.android.gms \
- * com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
- *
- * Retry GMS:
- * adb shell am startservice -a com.android.packageinstaller.wear.RETRY_GMS \
- * com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
- */
-public class WearPackageInstallerService extends Service
- implements EventResultPersister.EventResultObserver {
- private static final String TAG = "WearPkgInstallerService";
-
- private static final String WEAR_APPS_CHANNEL = "wear_app_install_uninstall";
- private static final String BROADCAST_ACTION =
- "com.android.packageinstaller.ACTION_UNINSTALL_COMMIT";
-
- private final int START_INSTALL = 1;
- private final int START_UNINSTALL = 2;
-
- private int mInstallNotificationId = 1;
- private final Map<String, Integer> mNotifIdMap = new ArrayMap<>();
- private final Map<Integer, UninstallParams> mServiceIdToParams = new HashMap<>();
-
- private class UninstallParams {
- public String mPackageName;
- public PowerManager.WakeLock mLock;
-
- UninstallParams(String packageName, PowerManager.WakeLock lock) {
- mPackageName = packageName;
- mLock = lock;
- }
- }
-
- private final class ServiceHandler extends Handler {
- public ServiceHandler(Looper looper) {
- super(looper);
- }
-
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case START_INSTALL:
- installPackage(msg.getData());
- break;
- case START_UNINSTALL:
- uninstallPackage(msg.getData());
- break;
- }
- }
- }
- private ServiceHandler mServiceHandler;
- private NotificationChannel mNotificationChannel;
- private static volatile PowerManager.WakeLock lockStatic = null;
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- HandlerThread thread = new HandlerThread("PackageInstallerThread",
- Process.THREAD_PRIORITY_BACKGROUND);
- thread.start();
-
- mServiceHandler = new ServiceHandler(thread.getLooper());
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if (!DeviceUtils.isWear(this)) {
- Log.w(TAG, "Not running on wearable.");
- finishServiceEarly(startId);
- return START_NOT_STICKY;
- }
-
- if (intent == null) {
- Log.w(TAG, "Got null intent.");
- finishServiceEarly(startId);
- return START_NOT_STICKY;
- }
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Got install/uninstall request " + intent);
- }
-
- Uri packageUri = intent.getData();
- if (packageUri == null) {
- Log.e(TAG, "No package URI in intent");
- finishServiceEarly(startId);
- return START_NOT_STICKY;
- }
-
- final String packageName = WearPackageUtil.getSanitizedPackageName(packageUri);
- if (packageName == null) {
- Log.e(TAG, "Invalid package name in URI (expected package:<pkgName>): " + packageUri);
- finishServiceEarly(startId);
- return START_NOT_STICKY;
- }
-
- PowerManager.WakeLock lock = getLock(this.getApplicationContext());
- if (!lock.isHeld()) {
- lock.acquire();
- }
-
- Bundle intentBundle = intent.getExtras();
- if (intentBundle == null) {
- intentBundle = new Bundle();
- }
- WearPackageArgs.setStartId(intentBundle, startId);
- WearPackageArgs.setPackageName(intentBundle, packageName);
- Message msg;
- String notifTitle;
- if (Intent.ACTION_INSTALL_PACKAGE.equals(intent.getAction())) {
- msg = mServiceHandler.obtainMessage(START_INSTALL);
- notifTitle = getString(R.string.installing);
- } else if (Intent.ACTION_UNINSTALL_PACKAGE.equals(intent.getAction())) {
- msg = mServiceHandler.obtainMessage(START_UNINSTALL);
- notifTitle = getString(R.string.uninstalling);
- } else {
- Log.e(TAG, "Unknown action : " + intent.getAction());
- finishServiceEarly(startId);
- return START_NOT_STICKY;
- }
- Pair<Integer, Notification> notifPair = buildNotification(packageName, notifTitle);
- startForeground(notifPair.first, notifPair.second);
- msg.setData(intentBundle);
- mServiceHandler.sendMessage(msg);
- return START_NOT_STICKY;
- }
-
- private void installPackage(Bundle argsBundle) {
- int startId = WearPackageArgs.getStartId(argsBundle);
- final String packageName = WearPackageArgs.getPackageName(argsBundle);
- final Uri assetUri = WearPackageArgs.getAssetUri(argsBundle);
- final Uri permUri = WearPackageArgs.getPermUri(argsBundle);
- boolean checkPerms = WearPackageArgs.checkPerms(argsBundle);
- boolean skipIfSameVersion = WearPackageArgs.skipIfSameVersion(argsBundle);
- int companionSdkVersion = WearPackageArgs.getCompanionSdkVersion(argsBundle);
- int companionDeviceVersion = WearPackageArgs.getCompanionDeviceVersion(argsBundle);
- String compressionAlg = WearPackageArgs.getCompressionAlg(argsBundle);
- boolean skipIfLowerVersion = WearPackageArgs.skipIfLowerVersion(argsBundle);
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Installing package: " + packageName + ", assetUri: " + assetUri +
- ",permUri: " + permUri + ", startId: " + startId + ", checkPerms: " +
- checkPerms + ", skipIfSameVersion: " + skipIfSameVersion +
- ", compressionAlg: " + compressionAlg + ", companionSdkVersion: " +
- companionSdkVersion + ", companionDeviceVersion: " + companionDeviceVersion +
- ", skipIfLowerVersion: " + skipIfLowerVersion);
- }
- final PackageManager pm = getPackageManager();
- File tempFile = null;
- PowerManager.WakeLock lock = getLock(this.getApplicationContext());
- boolean messageSent = false;
- try {
- PackageInfo existingPkgInfo = null;
- try {
- existingPkgInfo = pm.getPackageInfo(packageName,
- PackageManager.MATCH_ANY_USER | PackageManager.GET_PERMISSIONS);
- if (existingPkgInfo != null) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Replacing package:" + packageName);
- }
- }
- } catch (PackageManager.NameNotFoundException e) {
- // Ignore this exception. We could not find the package, will treat as a new
- // installation.
- }
- // TODO(28021618): This was left as a temp file due to the fact that this code is being
- // deprecated and that we need the bare minimum to continue working moving forward
- // If this code is used as reference, this permission logic might want to be
- // reworked to use a stream instead of a file so that we don't need to write a
- // file at all. Note that there might be some trickiness with opening a stream
- // for multiple users.
- ParcelFileDescriptor parcelFd = getContentResolver()
- .openFileDescriptor(assetUri, "r");
- tempFile = WearPackageUtil.getFileFromFd(WearPackageInstallerService.this,
- parcelFd, packageName, compressionAlg);
- if (tempFile == null) {
- Log.e(TAG, "Could not create a temp file from FD for " + packageName);
- return;
- }
- PackageInfo pkgInfo = PackageUtil.getPackageInfo(this, tempFile,
- PackageManager.GET_PERMISSIONS | PackageManager.GET_CONFIGURATIONS);
- if (pkgInfo == null) {
- Log.e(TAG, "Could not parse apk information for " + packageName);
- return;
- }
-
- if (!pkgInfo.packageName.equals(packageName)) {
- Log.e(TAG, "Wearable Package Name has to match what is provided for " +
- packageName);
- return;
- }
-
- ApplicationInfo appInfo = pkgInfo.applicationInfo;
- appInfo.sourceDir = tempFile.getPath();
- appInfo.publicSourceDir = tempFile.getPath();
- getLabelAndUpdateNotification(packageName,
- getString(R.string.installing_app, appInfo.loadLabel(pm)));
-
- List<String> wearablePerms = Arrays.asList(pkgInfo.requestedPermissions);
-
- // Log if the installed pkg has a higher version number.
- if (existingPkgInfo != null) {
- long longVersionCode = pkgInfo.getLongVersionCode();
- if (existingPkgInfo.getLongVersionCode() == longVersionCode) {
- if (skipIfSameVersion) {
- Log.w(TAG, "Version number (" + longVersionCode +
- ") of new app is equal to existing app for " + packageName +
- "; not installing due to versionCheck");
- return;
- } else {
- Log.w(TAG, "Version number of new app (" + longVersionCode +
- ") is equal to existing app for " + packageName);
- }
- } else if (existingPkgInfo.getLongVersionCode() > longVersionCode) {
- if (skipIfLowerVersion) {
- // Starting in Feldspar, we are not going to allow downgrades of any app.
- Log.w(TAG, "Version number of new app (" + longVersionCode +
- ") is lower than existing app ( "
- + existingPkgInfo.getLongVersionCode() +
- ") for " + packageName + "; not installing due to versionCheck");
- return;
- } else {
- Log.w(TAG, "Version number of new app (" + longVersionCode +
- ") is lower than existing app ( "
- + existingPkgInfo.getLongVersionCode() + ") for " + packageName);
- }
- }
-
- // Following the Android Phone model, we should only check for permissions for any
- // newly defined perms.
- if (existingPkgInfo.requestedPermissions != null) {
- for (int i = 0; i < existingPkgInfo.requestedPermissions.length; ++i) {
- // If the permission is granted, then we will not ask to request it again.
- if ((existingPkgInfo.requestedPermissionsFlags[i] &
- PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, existingPkgInfo.requestedPermissions[i] +
- " is already granted for " + packageName);
- }
- wearablePerms.remove(existingPkgInfo.requestedPermissions[i]);
- }
- }
- }
- }
-
- // Check that the wearable has all the features.
- boolean hasAllFeatures = true;
- for (FeatureInfo feature : pkgInfo.reqFeatures) {
- if (feature.name != null && !pm.hasSystemFeature(feature.name) &&
- (feature.flags & FeatureInfo.FLAG_REQUIRED) != 0) {
- Log.e(TAG, "Wearable does not have required feature: " + feature +
- " for " + packageName);
- hasAllFeatures = false;
- }
- }
-
- if (!hasAllFeatures) {
- return;
- }
-
- // Check permissions on both the new wearable package and also on the already installed
- // wearable package.
- // If the app is targeting API level 23, we will also start a service in ClockworkHome
- // which will ultimately prompt the user to accept/reject permissions.
- if (checkPerms && !checkPermissions(pkgInfo, companionSdkVersion,
- companionDeviceVersion, permUri, wearablePerms, tempFile)) {
- Log.w(TAG, "Wearable does not have enough permissions.");
- return;
- }
-
- // Finally install the package.
- ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(assetUri, "r");
- PackageInstallerFactory.getPackageInstaller(this).install(packageName, fd,
- new PackageInstallListener(this, lock, startId, packageName));
-
- messageSent = true;
- Log.i(TAG, "Sent installation request for " + packageName);
- } catch (FileNotFoundException e) {
- Log.e(TAG, "Could not find the file with URI " + assetUri, e);
- } finally {
- if (!messageSent) {
- // Some error happened. If the message has been sent, we can wait for the observer
- // which will finish the service.
- if (tempFile != null) {
- tempFile.delete();
- }
- finishService(lock, startId);
- }
- }
- }
-
- // TODO: This was left using the old PackageManager API due to the fact that this code is being
- // deprecated and that we need the bare minimum to continue working moving forward
- // If this code is used as reference, this logic should be reworked to use the new
- // PackageInstaller APIs similar to how installPackage was reworked
- private void uninstallPackage(Bundle argsBundle) {
- int startId = WearPackageArgs.getStartId(argsBundle);
- final String packageName = WearPackageArgs.getPackageName(argsBundle);
-
- PowerManager.WakeLock lock = getLock(this.getApplicationContext());
-
- UninstallParams params = new UninstallParams(packageName, lock);
- mServiceIdToParams.put(startId, params);
-
- final PackageManager pm = getPackageManager();
- try {
- PackageInfo pkgInfo = pm.getPackageInfo(packageName, 0);
- getLabelAndUpdateNotification(packageName,
- getString(R.string.uninstalling_app, pkgInfo.applicationInfo.loadLabel(pm)));
-
- int uninstallId = UninstallEventReceiver.addObserver(this,
- EventResultPersister.GENERATE_NEW_ID, this);
-
- Intent broadcastIntent = new Intent(BROADCAST_ACTION);
- broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, uninstallId);
- broadcastIntent.putExtra(EventResultPersister.EXTRA_SERVICE_ID, startId);
- broadcastIntent.setPackage(getPackageName());
-
- PendingIntent pendingIntent = PendingIntent.getBroadcast(this, uninstallId,
- broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT
- | PendingIntent.FLAG_MUTABLE);
-
- // Found package, send uninstall request.
- pm.getPackageInstaller().uninstall(
- new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
- PackageManager.DELETE_ALL_USERS,
- pendingIntent.getIntentSender());
-
- Log.i(TAG, "Sent delete request for " + packageName);
- } catch (IllegalArgumentException | PackageManager.NameNotFoundException e) {
- // Couldn't find the package, no need to call uninstall.
- Log.w(TAG, "Could not find package, not deleting " + packageName, e);
- finishService(lock, startId);
- } catch (EventResultPersister.OutOfIdsException e) {
- Log.e(TAG, "Fails to start uninstall", e);
- finishService(lock, startId);
- }
- }
-
- @Override
- public void onResult(int status, int legacyStatus, @Nullable String message, int serviceId) {
- if (mServiceIdToParams.containsKey(serviceId)) {
- UninstallParams params = mServiceIdToParams.get(serviceId);
- try {
- if (status == PackageInstaller.STATUS_SUCCESS) {
- Log.i(TAG, "Package " + params.mPackageName + " was uninstalled.");
- } else {
- Log.e(TAG, "Package uninstall failed " + params.mPackageName
- + ", returnCode " + legacyStatus);
- }
- } finally {
- finishService(params.mLock, serviceId);
- }
- }
- }
-
- private boolean checkPermissions(PackageInfo pkgInfo, int companionSdkVersion,
- int companionDeviceVersion, Uri permUri, List<String> wearablePermissions,
- File apkFile) {
- // Assumption: We are running on Android O.
- // If the Phone App is targeting M, all permissions may not have been granted to the phone
- // app. If the Wear App is then not targeting M, there may be permissions that are not
- // granted on the Phone app (by the user) right now and we cannot just grant it for the Wear
- // app.
- if (pkgInfo.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
- // Install the app if Wear App is ready for the new perms model.
- return true;
- }
-
- if (!doesWearHaveUngrantedPerms(pkgInfo.packageName, permUri, wearablePermissions)) {
- // All permissions requested by the watch are already granted on the phone, no need
- // to do anything.
- return true;
- }
-
- // Log an error if Wear is targeting < 23 and phone is targeting >= 23.
- if (companionSdkVersion == 0 || companionSdkVersion >= Build.VERSION_CODES.M) {
- Log.e(TAG, "MNC: Wear app's targetSdkVersion should be at least 23, if "
- + "phone app is targeting at least 23, will continue.");
- }
-
- return false;
- }
-
- /**
- * Given a {@string packageName} corresponding to a phone app, query the provider for all the
- * perms that are granted.
- *
- * @return true if the Wear App has any perms that have not been granted yet on the phone side.
- * @return true if there is any error cases.
- */
- private boolean doesWearHaveUngrantedPerms(String packageName, Uri permUri,
- List<String> wearablePermissions) {
- if (permUri == null) {
- Log.e(TAG, "Permission URI is null");
- // Pretend there is an ungranted permission to avoid installing for error cases.
- return true;
- }
- Cursor permCursor = getContentResolver().query(permUri, null, null, null, null);
- if (permCursor == null) {
- Log.e(TAG, "Could not get the cursor for the permissions");
- // Pretend there is an ungranted permission to avoid installing for error cases.
- return true;
- }
-
- Set<String> grantedPerms = new HashSet<>();
- Set<String> ungrantedPerms = new HashSet<>();
- while(permCursor.moveToNext()) {
- // Make sure that the MatrixCursor returned by the ContentProvider has 2 columns and
- // verify their types.
- if (permCursor.getColumnCount() == 2
- && Cursor.FIELD_TYPE_STRING == permCursor.getType(0)
- && Cursor.FIELD_TYPE_INTEGER == permCursor.getType(1)) {
- String perm = permCursor.getString(0);
- Integer granted = permCursor.getInt(1);
- if (granted == 1) {
- grantedPerms.add(perm);
- } else {
- ungrantedPerms.add(perm);
- }
- }
- }
- permCursor.close();
-
- boolean hasUngrantedPerm = false;
- for (String wearablePerm : wearablePermissions) {
- if (!grantedPerms.contains(wearablePerm)) {
- hasUngrantedPerm = true;
- if (!ungrantedPerms.contains(wearablePerm)) {
- // This is an error condition. This means that the wearable has permissions that
- // are not even declared in its host app. This is a developer error.
- Log.e(TAG, "Wearable " + packageName + " has a permission \"" + wearablePerm
- + "\" that is not defined in the host application's manifest.");
- } else {
- Log.w(TAG, "Wearable " + packageName + " has a permission \"" + wearablePerm +
- "\" that is not granted in the host application.");
- }
- }
- }
- return hasUngrantedPerm;
- }
-
- /** Finishes the service after fulfilling obligation to call startForeground. */
- private void finishServiceEarly(int startId) {
- Pair<Integer, Notification> notifPair = buildNotification(
- getApplicationContext().getPackageName(), "");
- startForeground(notifPair.first, notifPair.second);
- finishService(null, startId);
- }
-
- private void finishService(PowerManager.WakeLock lock, int startId) {
- if (lock != null && lock.isHeld()) {
- lock.release();
- }
- stopSelf(startId);
- }
-
- private synchronized PowerManager.WakeLock getLock(Context context) {
- if (lockStatic == null) {
- PowerManager mgr =
- (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- lockStatic = mgr.newWakeLock(
- PowerManager.PARTIAL_WAKE_LOCK, context.getClass().getSimpleName());
- lockStatic.setReferenceCounted(true);
- }
- return lockStatic;
- }
-
- private class PackageInstallListener implements PackageInstallerImpl.InstallListener {
- private Context mContext;
- private PowerManager.WakeLock mWakeLock;
- private int mStartId;
- private String mApplicationPackageName;
- private PackageInstallListener(Context context, PowerManager.WakeLock wakeLock,
- int startId, String applicationPackageName) {
- mContext = context;
- mWakeLock = wakeLock;
- mStartId = startId;
- mApplicationPackageName = applicationPackageName;
- }
-
- @Override
- public void installBeginning() {
- Log.i(TAG, "Package " + mApplicationPackageName + " is being installed.");
- }
-
- @Override
- public void installSucceeded() {
- try {
- Log.i(TAG, "Package " + mApplicationPackageName + " was installed.");
-
- // Delete tempFile from the file system.
- File tempFile = WearPackageUtil.getTemporaryFile(mContext, mApplicationPackageName);
- if (tempFile != null) {
- tempFile.delete();
- }
- } finally {
- finishService(mWakeLock, mStartId);
- }
- }
-
- @Override
- public void installFailed(int errorCode, String errorDesc) {
- Log.e(TAG, "Package install failed " + mApplicationPackageName
- + ", errorCode " + errorCode);
- finishService(mWakeLock, mStartId);
- }
- }
-
- private synchronized Pair<Integer, Notification> buildNotification(final String packageName,
- final String title) {
- int notifId;
- if (mNotifIdMap.containsKey(packageName)) {
- notifId = mNotifIdMap.get(packageName);
- } else {
- notifId = mInstallNotificationId++;
- mNotifIdMap.put(packageName, notifId);
- }
-
- if (mNotificationChannel == null) {
- mNotificationChannel = new NotificationChannel(WEAR_APPS_CHANNEL,
- getString(R.string.wear_app_channel), NotificationManager.IMPORTANCE_MIN);
- NotificationManager notificationManager = getSystemService(NotificationManager.class);
- notificationManager.createNotificationChannel(mNotificationChannel);
- }
- return new Pair<>(notifId, new Notification.Builder(this, WEAR_APPS_CHANNEL)
- .setSmallIcon(R.drawable.ic_file_download)
- .setContentTitle(title)
- .build());
- }
-
- private void getLabelAndUpdateNotification(String packageName, String title) {
- // Update notification since we have a label now.
- NotificationManager notificationManager = getSystemService(NotificationManager.class);
- Pair<Integer, Notification> notifPair = buildNotification(packageName, title);
- notificationManager.notify(notifPair.first, notifPair.second);
- }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java
deleted file mode 100644
index 6a9145db9a06..000000000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.packageinstaller.wear;
-
-import android.content.Context;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.TextUtils;
-import android.util.Log;
-
-import org.tukaani.xz.LZMAInputStream;
-import org.tukaani.xz.XZInputStream;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class WearPackageUtil {
- private static final String TAG = "WearablePkgInstaller";
-
- private static final String COMPRESSION_LZMA = "lzma";
- private static final String COMPRESSION_XZ = "xz";
-
- public static File getTemporaryFile(Context context, String packageName) {
- try {
- File newFileDir = new File(context.getFilesDir(), "tmp");
- newFileDir.mkdirs();
- Os.chmod(newFileDir.getAbsolutePath(), 0771);
- File newFile = new File(newFileDir, packageName + ".apk");
- return newFile;
- } catch (ErrnoException e) {
- Log.e(TAG, "Failed to open.", e);
- return null;
- }
- }
-
- public static File getIconFile(final Context context, final String packageName) {
- try {
- File newFileDir = new File(context.getFilesDir(), "images/icons");
- newFileDir.mkdirs();
- Os.chmod(newFileDir.getAbsolutePath(), 0771);
- return new File(newFileDir, packageName + ".icon");
- } catch (ErrnoException e) {
- Log.e(TAG, "Failed to open.", e);
- return null;
- }
- }
-
- /**
- * In order to make sure that the Wearable Asset Manager has a reasonable apk that can be used
- * by the PackageManager, we will parse it before sending it to the PackageManager.
- * Unfortunately, ParsingPackageUtils needs a file to parse. So, we have to temporarily convert
- * the fd to a File.
- *
- * @param context
- * @param fd FileDescriptor to convert to File
- * @param packageName Name of package, will define the name of the file
- * @param compressionAlg Can be null. For ALT mode the APK will be compressed. We will
- * decompress it here
- */
- public static File getFileFromFd(Context context, ParcelFileDescriptor fd,
- String packageName, String compressionAlg) {
- File newFile = getTemporaryFile(context, packageName);
- if (fd == null || fd.getFileDescriptor() == null) {
- return null;
- }
- InputStream fr = new ParcelFileDescriptor.AutoCloseInputStream(fd);
- try {
- if (TextUtils.equals(compressionAlg, COMPRESSION_XZ)) {
- fr = new XZInputStream(fr);
- } else if (TextUtils.equals(compressionAlg, COMPRESSION_LZMA)) {
- fr = new LZMAInputStream(fr);
- }
- } catch (IOException e) {
- Log.e(TAG, "Compression was set to " + compressionAlg + ", but could not decode ", e);
- return null;
- }
-
- int nRead;
- byte[] data = new byte[1024];
- try {
- final FileOutputStream fo = new FileOutputStream(newFile);
- while ((nRead = fr.read(data, 0, data.length)) != -1) {
- fo.write(data, 0, nRead);
- }
- fo.flush();
- fo.close();
- Os.chmod(newFile.getAbsolutePath(), 0644);
- return newFile;
- } catch (IOException e) {
- Log.e(TAG, "Reading from Asset FD or writing to temp file failed ", e);
- return null;
- } catch (ErrnoException e) {
- Log.e(TAG, "Could not set permissions on file ", e);
- return null;
- } finally {
- try {
- fr.close();
- } catch (IOException e) {
- Log.e(TAG, "Failed to close the file from FD ", e);
- }
- }
- }
-
- /**
- * @return com.google.com from expected formats like
- * Uri: package:com.google.com, package:/com.google.com, package://com.google.com
- */
- public static String getSanitizedPackageName(Uri packageUri) {
- String packageName = packageUri.getEncodedSchemeSpecificPart();
- if (packageName != null) {
- return packageName.replaceAll("^/+", "");
- }
- return packageName;
- }
-}
diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
index 6ffad709b2f3..c2b82afa238a 100644
--- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml
+++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
@@ -33,7 +33,7 @@
<string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string>
<string name="print_preview" msgid="8010217796057763343">"Aperçu avant impression"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Installer un lecteur PDF pour voir l\'aperçu"</string>
- <string name="printing_app_crashed" msgid="854477616686566398">"L\'application à l\'origine de l\'impression a planté"</string>
+ <string name="printing_app_crashed" msgid="854477616686566398">"L\'appli à l\'origine de l\'impression a planté"</string>
<string name="generating_print_job" msgid="3119608742651698916">"Génération tâche impression…"</string>
<string name="save_as_pdf" msgid="5718454119847596853">"Enregistrer au format PDF"</string>
<string name="all_printers" msgid="5018829726861876202">"Toutes les imprimantes…"</string>
diff --git a/packages/SettingsLib/ActionButtonsPreference/Android.bp b/packages/SettingsLib/ActionButtonsPreference/Android.bp
index c36b82d175e2..71ecb4c30543 100644
--- a/packages/SettingsLib/ActionButtonsPreference/Android.bp
+++ b/packages/SettingsLib/ActionButtonsPreference/Android.bp
@@ -19,7 +19,6 @@ android_library {
static_libs: [
"androidx.preference_preference",
- "SettingsLibUtils",
],
sdk_version: "system_current",
diff --git a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
index 3e65d94e3323..5dc11cfc0392 100644
--- a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
+++ b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -31,12 +32,11 @@ import androidx.annotation.StringRes;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
-import com.android.settingslib.utils.BuildCompatUtils;
+import com.android.settingslib.widget.preference.actionbuttons.R;
+
import java.util.ArrayList;
import java.util.List;
-import com.android.settingslib.widget.preference.actionbuttons.R;
-
/**
* This preference provides a four buttons layout with Settings style.
* It looks like below
@@ -56,7 +56,7 @@ import com.android.settingslib.widget.preference.actionbuttons.R;
public class ActionButtonsPreference extends Preference {
private static final String TAG = "ActionButtonPreference";
- private static final boolean mIsAtLeastS = BuildCompatUtils.isAtLeastS();
+ private static final boolean mIsAtLeastS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
private static final int SINGLE_BUTTON_STYLE = 1;
private static final int TWO_BUTTONS_STYLE = 2;
private static final int THREE_BUTTONS_STYLE = 3;
diff --git a/packages/SettingsLib/ActivityEmbedding/Android.bp b/packages/SettingsLib/ActivityEmbedding/Android.bp
index 838a9e505ece..556100212445 100644
--- a/packages/SettingsLib/ActivityEmbedding/Android.bp
+++ b/packages/SettingsLib/ActivityEmbedding/Android.bp
@@ -20,7 +20,6 @@ android_library {
"androidx.annotation_annotation",
"androidx.core_core",
"androidx.window_window",
- "SettingsLibUtils",
],
sdk_version: "system_current",
min_sdk_version: "21",
diff --git a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
index f89be9fba583..67aa8f41e227 100644
--- a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
+++ b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
@@ -20,13 +20,11 @@ import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.os.Build;
import android.util.Log;
-import androidx.core.os.BuildCompat;
import androidx.window.embedding.ActivityEmbeddingController;
-import com.android.settingslib.utils.BuildCompatUtils;
-
/**
* An util class collecting all common methods for the embedding activity features.
*/
@@ -70,7 +68,7 @@ public final class ActivityEmbeddingUtils {
* enabled (unsupported devices).
*/
private static ComponentName getEmbeddingActivityComponent(Context context) {
- if (!BuildCompatUtils.isAtLeastSV2()) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S_V2) {
return null;
}
final Intent intent = new Intent(ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY);
@@ -95,7 +93,7 @@ public final class ActivityEmbeddingUtils {
* Settings app
*/
public static boolean shouldHideNavigateUpButton(Activity activity, boolean isSecondLayerPage) {
- if (!BuildCompat.isAtLeastT()) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
return false;
}
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index d6cbf2a0f581..0cb85d8638b0 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -64,6 +64,7 @@ android_library {
srcs: [
"src/**/*.java",
"src/**/*.kt",
+ "src/**/I*.aidl",
],
}
diff --git a/packages/SettingsLib/AppPreference/res/values-fr-rCA/strings.xml b/packages/SettingsLib/AppPreference/res/values-fr-rCA/strings.xml
index 7be1e97f51e0..4771382de59b 100644
--- a/packages/SettingsLib/AppPreference/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/AppPreference/res/values-fr-rCA/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="install_type_instant" msgid="7217305006127216917">"Application instantanée"</string>
+ <string name="install_type_instant" msgid="7217305006127216917">"Appli instantanée"</string>
</resources>
diff --git a/packages/SettingsLib/BannerMessagePreference/Android.bp b/packages/SettingsLib/BannerMessagePreference/Android.bp
index 07290de8661e..3f671b9e7b10 100644
--- a/packages/SettingsLib/BannerMessagePreference/Android.bp
+++ b/packages/SettingsLib/BannerMessagePreference/Android.bp
@@ -20,7 +20,6 @@ android_library {
static_libs: [
"androidx.preference_preference",
"SettingsLibSettingsTheme",
- "SettingsLibUtils",
],
sdk_version: "system_current",
diff --git a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
index 33775a64aa82..6cd777e878fe 100644
--- a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
+++ b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
@@ -38,7 +38,6 @@ import androidx.annotation.StringRes;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
-import com.android.settingslib.utils.BuildCompatUtils;
import com.android.settingslib.widget.preference.banner.R;
/**
* Banner message is a banner displaying important information (permission request, page error etc),
@@ -84,7 +83,7 @@ public class BannerMessagePreference extends Preference {
}
private static final String TAG = "BannerPreference";
- private static final boolean IS_AT_LEAST_S = BuildCompatUtils.isAtLeastS();
+ private static final boolean IS_AT_LEAST_S = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
private final BannerMessagePreference.ButtonInfo mPositiveButtonInfo =
new BannerMessagePreference.ButtonInfo();
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
index 87ec0b8d46fb..b56b944955d7 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
@@ -20,9 +20,9 @@ android_library {
static_libs: [
"androidx.annotation_annotation",
"androidx.core_core",
+ "androidx.activity_activity",
"com.google.android.material_material",
"SettingsLibSettingsTransition",
- "SettingsLibUtils",
"SettingsLibSettingsTheme",
],
sdk_version: "system_current",
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java
index 8ebbac39d1d0..b252e5f021ae 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java
@@ -16,11 +16,11 @@
package com.android.settingslib.collapsingtoolbar;
+import android.os.Build;
+
import androidx.fragment.app.FragmentActivity;
import androidx.preference.PreferenceFragmentCompat;
-import com.android.settingslib.utils.BuildCompatUtils;
-
import com.google.android.material.appbar.AppBarLayout;
/**
@@ -58,7 +58,7 @@ public abstract class BasePreferencesFragment extends PreferenceFragmentCompat {
if (activity != null) {
activity.setTitle(getTitle());
- if (BuildCompatUtils.isAtLeastS()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
AppBarLayout appBarLayout = (AppBarLayout) activity.findViewById(R.id.app_bar);
if (appBarLayout != null) {
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
index 04c44e6d11be..465905170347 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
@@ -17,6 +17,7 @@
package com.android.settingslib.collapsingtoolbar;
import android.app.ActionBar;
+import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -26,8 +27,6 @@ import android.widget.Toolbar;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
-import com.android.settingslib.utils.BuildCompatUtils;
-
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.color.DynamicColors;
@@ -65,13 +64,14 @@ public class CollapsingToolbarAppCompatActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
+ EdgeToEdgeUtils.enable(this);
super.onCreate(savedInstanceState);
- if (BuildCompatUtils.isAtLeastS()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
DynamicColors.applyToActivityIfAvailable(this);
}
setTheme(com.android.settingslib.widget.theme.R.style.Theme_SubSettingsBase);
- if (mCustomizeLayoutResId > 0 && !BuildCompatUtils.isAtLeastS()) {
+ if (mCustomizeLayoutResId > 0 && Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
super.setContentView(mCustomizeLayoutResId);
return;
}
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
index 143101f76977..3965303d3ba5 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
@@ -18,6 +18,7 @@ package com.android.settingslib.collapsingtoolbar;
import android.app.ActionBar;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -27,8 +28,6 @@ import android.widget.Toolbar;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
-import com.android.settingslib.utils.BuildCompatUtils;
-
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
@@ -58,9 +57,11 @@ public class CollapsingToolbarBaseActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
+ EdgeToEdgeUtils.enable(this);
super.onCreate(savedInstanceState);
// for backward compatibility on R devices or wearable devices due to small device size.
- if (mCustomizeLayoutResId > 0 && (!BuildCompatUtils.isAtLeastS() || isWatch())) {
+ if (mCustomizeLayoutResId > 0 && (Build.VERSION.SDK_INT < Build.VERSION_CODES.S
+ || isWatch())) {
super.setContentView(mCustomizeLayoutResId);
return;
}
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/EdgeToEdgeUtils.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/EdgeToEdgeUtils.java
new file mode 100644
index 000000000000..6e53012e1245
--- /dev/null
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/EdgeToEdgeUtils.java
@@ -0,0 +1,62 @@
+/*
+ * 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.settingslib.collapsingtoolbar;
+
+import android.os.Build;
+
+import androidx.activity.ComponentActivity;
+import androidx.activity.EdgeToEdge;
+import androidx.annotation.NonNull;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
+/**
+ * Util class for edge to edge.
+ */
+public class EdgeToEdgeUtils {
+ private EdgeToEdgeUtils() {
+ }
+
+ /**
+ * Enable Edge to Edge and handle overlaps using insets. It should be called before
+ * setContentView.
+ */
+ static void enable(@NonNull ComponentActivity activity) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
+ return;
+ }
+
+ EdgeToEdge.enable(activity);
+
+ ViewCompat.setOnApplyWindowInsetsListener(activity.findViewById(android.R.id.content),
+ (v, windowInsets) -> {
+ Insets insets = windowInsets.getInsets(
+ WindowInsetsCompat.Type.systemBars()
+ | WindowInsetsCompat.Type.ime()
+ | WindowInsetsCompat.Type.displayCutout());
+ int statusBarHeight = activity.getWindow().getDecorView().getRootWindowInsets()
+ .getInsets(WindowInsetsCompat.Type.statusBars()).top;
+ // Apply the insets paddings to the view.
+ v.setPadding(insets.left, statusBarHeight, insets.right, insets.bottom);
+
+ // Return CONSUMED if you don't want the window insets to keep being
+ // passed down to descendant views.
+ return WindowInsetsCompat.CONSUMED;
+ });
+ }
+}
diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
index bbf0315aa475..4387b6f061c3 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
@@ -16,6 +16,8 @@
package com.android.settingslib.widget;
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES;
+
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -122,6 +124,8 @@ public class IllustrationPreference extends Preference {
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
+ final FrameLayout illustrationFrame = (FrameLayout) holder.findViewById(
+ R.id.illustration_frame);
final ImageView backgroundView =
(ImageView) holder.findViewById(R.id.background_view);
final FrameLayout middleGroundLayout =
@@ -130,15 +134,15 @@ public class IllustrationPreference extends Preference {
(LottieAnimationView) holder.findViewById(R.id.lottie_view);
if (illustrationView != null && !TextUtils.isEmpty(mContentDescription)) {
illustrationView.setContentDescription(mContentDescription);
- illustrationView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ illustrationView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+ final View illustrationContainer = (View) illustrationFrame.getParent();
+ illustrationContainer.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
}
// To solve the problem of non-compliant illustrations, we set the frame height
// to 300dp and set the length of the short side of the screen to
// the width of the frame.
final int screenWidth = getContext().getResources().getDisplayMetrics().widthPixels;
final int screenHeight = getContext().getResources().getDisplayMetrics().heightPixels;
- final FrameLayout illustrationFrame = (FrameLayout) holder.findViewById(
- R.id.illustration_frame);
final LayoutParams lp = (LayoutParams) illustrationFrame.getLayoutParams();
lp.width = screenWidth < screenHeight ? screenWidth : screenHeight;
illustrationFrame.setLayoutParams(lp);
diff --git a/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml b/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml
index c629d96bcf4b..b967405b5c63 100644
--- a/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml
+++ b/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml
@@ -18,38 +18,19 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/entity_header"
- style="@style/EntityHeader"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:orientation="horizontal">
+ style="@style/SettingsLibEntityHeader">
<LinearLayout
android:id="@+id/entity_header_content"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerHorizontal="true"
- android:gravity="center_horizontal"
- android:orientation="vertical">
+ style="@style/SettingsLibEntityHeaderContent">
<ImageView
android:id="@+id/entity_header_icon"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:scaleType="fitCenter"
- android:antialias="true"/>
+ style="@style/SettingsLibEntityHeaderIcon"/>
<TextView
android:id="@+id/entity_header_title"
- style="@style/TextAppearance.EntityHeaderTitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:singleLine="false"
- android:gravity="center"
- android:ellipsize="marquee"
- android:textDirection="locale"
- android:layout_marginTop="8dp"/>
+ style="@style/SettingsLibEntityHeaderTitle"/>
<TextView
android:id="@+id/install_type"
diff --git a/packages/SettingsLib/LayoutPreference/res/values/styles.xml b/packages/SettingsLib/LayoutPreference/res/values/styles.xml
index f958037cfca6..c9d35975a907 100644
--- a/packages/SettingsLib/LayoutPreference/res/values/styles.xml
+++ b/packages/SettingsLib/LayoutPreference/res/values/styles.xml
@@ -22,6 +22,39 @@
<item name="android:paddingEnd">16dp</item>
</style>
+ <style name="SettingsLibEntityHeader" parent="EntityHeader">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:paddingStart">?android:attr/listPreferredItemPaddingStart</item>
+ <item name="android:paddingEnd">?android:attr/listPreferredItemPaddingEnd</item>
+ </style>
+
+ <style name="SettingsLibEntityHeaderContent">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_centerHorizontal">true</item>
+ <item name="android:orientation">vertical</item>
+ <item name="android:gravity">center_horizontal</item>
+ </style>
+
+ <style name="SettingsLibEntityHeaderIcon">
+ <item name="android:layout_width">48dp</item>
+ <item name="android:layout_height">48dp</item>
+ <item name="android:scaleType">fitCenter</item>
+ <item name="android:antialias">true</item>
+ </style>
+
+ <style name="SettingsLibEntityHeaderTitle">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_marginTop">8dp</item>
+ <item name="android:singleLine">false</item>
+ <item name="android:gravity">center</item>
+ <item name="android:ellipsize">marquee</item>
+ <item name="android:textDirection">locale</item>
+ <item name="android:textAppearance">@style/TextAppearance.EntityHeaderTitle</item>
+ </style>
+
<style name="CrossProfileEntityHeaderIcon">
<item name="android:layout_width">48dp</item>
<item name="android:layout_height">48dp</item>
@@ -52,4 +85,4 @@
<item name="android:fontFamily">google-sans-medium</item>
<item name="android:layout_marginTop">8dp</item>
</style>
-</resources> \ No newline at end of file
+</resources>
diff --git a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java
index c52386bef07b..7be448207efe 100644
--- a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java
+++ b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java
@@ -30,7 +30,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import androidx.core.os.BuildCompat;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;
@@ -226,7 +225,8 @@ public abstract class ProfileSelectFragment extends Fragment {
// to be here only for this API level - when then private profile was introduced.
@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
private boolean shouldShowPrivateProfileIfItsOne(UserHandle userHandle) {
- if (!BuildCompat.isAtLeastV() || !android.os.Flags.allowPrivateProfile()) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM
+ || !android.os.Flags.allowPrivateProfile()) {
return false;
}
try {
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml b/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml
index 6052be3b52e2..b6e80c784f10 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml
@@ -22,6 +22,9 @@
<item name="android:textColorPrimary">@color/settingslib_materialColorOnSurface</item>
<item name="android:textColorSecondary">@color/settingslib_text_color_secondary</item>
<item name="android:textColorTertiary">@color/settingslib_materialColorOutline</item>
+ <!-- Set up edge-to-edge configuration for top app bar -->
+ <item name="android:clipToPadding">false</item>
+ <item name="android:clipChildren">false</item>
</style>
<style name="Theme.SettingsBase" parent="Theme.SettingsBase_v35" />
diff --git a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml
index df5644b8aad0..26453609fc43 100644
--- a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml
+++ b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml
@@ -46,20 +46,6 @@
</intent-filter>
</provider>
- <provider android:name="com.android.settingslib.spa.slice.SpaSliceProvider"
- android:authorities="com.android.spa.gallery.slice.provider"
- android:exported="true" >
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.app.slice.category.SLICE" />
- </intent-filter>
- </provider>
-
- <receiver
- android:name="com.android.settingslib.spa.slice.SpaSliceBroadcastReceiver"
- android:exported="false">
- </receiver>
-
<activity
android:name="com.android.settingslib.spa.debug.BlankActivity"
android:exported="true">
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt
index 91bd7916b0ab..ffd28798d82f 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt
@@ -55,7 +55,6 @@ import com.android.settingslib.spa.gallery.ui.CategoryPageProvider
import com.android.settingslib.spa.gallery.ui.CopyablePageProvider
import com.android.settingslib.spa.gallery.scaffold.ScrollablePagerPageProvider
import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
-import com.android.settingslib.spa.slice.SpaSliceBroadcastReceiver
/**
* Enum to define all SPP name here.
@@ -120,9 +119,7 @@ class GallerySpaEnvironment(context: Context) : SpaEnvironment(context) {
override val logger = DebugLogger()
override val browseActivityClass = GalleryMainActivity::class.java
- override val sliceBroadcastReceiverClass = SpaSliceBroadcastReceiver::class.java
// For debugging
override val searchProviderAuthorities = "com.android.spa.gallery.search.provider"
- override val sliceProviderAuthorities = "com.android.spa.gallery.slice.provider"
}
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt
index 96de1a778c97..6d1d34628efa 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt
@@ -27,7 +27,6 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.android.settingslib.spa.framework.common.EntrySearchData
-import com.android.settingslib.spa.framework.common.EntrySliceData
import com.android.settingslib.spa.framework.common.EntryStatusData
import com.android.settingslib.spa.framework.common.SettingsEntry
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
@@ -35,10 +34,8 @@ import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.theme.SettingsTheme
-import com.android.settingslib.spa.framework.util.createIntent
import com.android.settingslib.spa.gallery.R
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
-import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.ASYNC_PREFERENCE_SUMMARY
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.ASYNC_PREFERENCE_TITLE
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.AUTO_UPDATE_PREFERENCE_TITLE
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.DISABLE_PREFERENCE_SUMMARY
@@ -48,15 +45,10 @@ import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Compan
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_KEYWORDS
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_SUMMARY
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_TITLE
-import com.android.settingslib.spa.slice.createBrowsePendingIntent
-import com.android.settingslib.spa.slice.provider.createDemoActionSlice
-import com.android.settingslib.spa.slice.provider.createDemoBrowseSlice
-import com.android.settingslib.spa.slice.provider.createDemoSlice
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.preference.SimplePreferenceMacro
import com.android.settingslib.spa.widget.ui.SettingsIcon
-import kotlinx.coroutines.delay
private const val TAG = "PreferencePage"
@@ -139,26 +131,6 @@ object PreferencePageProvider : SettingsPageProvider {
override val enabled = { model.asyncEnable.value }
}
)
- }
- .setSliceDataFn { sliceUri, _ ->
- val createSliceImpl = { s: String ->
- createDemoBrowseSlice(
- sliceUri = sliceUri,
- title = ASYNC_PREFERENCE_TITLE,
- summary = s,
- )
- }
- return@setSliceDataFn object : EntrySliceData() {
- init {
- postValue(createSliceImpl("(loading)"))
- }
-
- override suspend fun asyncRunner() {
- spaLogger.message(TAG, "Async entry loading")
- delay(2000L)
- postValue(createSliceImpl(ASYNC_PREFERENCE_SUMMARY))
- }
- }
}.build()
)
entryList.add(
@@ -176,28 +148,6 @@ object PreferencePageProvider : SettingsPageProvider {
}
}
)
- }
- .setSliceDataFn { sliceUri, args ->
- val createSliceImpl = { v: Int ->
- createDemoActionSlice(
- sliceUri = sliceUri,
- title = MANUAL_UPDATE_PREFERENCE_TITLE,
- summary = "manual update value $v",
- )
- }
-
- return@setSliceDataFn object : EntrySliceData() {
- private var tick = args?.getString("init")?.toInt() ?: 0
-
- init {
- postValue(createSliceImpl(tick))
- }
-
- override suspend fun asyncAction() {
- tick++
- postValue(createSliceImpl(tick))
- }
- }
}.build()
)
entryList.add(
@@ -216,33 +166,6 @@ object PreferencePageProvider : SettingsPageProvider {
}
}
)
- }
- .setSliceDataFn { sliceUri, args ->
- val createSliceImpl = { v: Int ->
- createDemoBrowseSlice(
- sliceUri = sliceUri,
- title = AUTO_UPDATE_PREFERENCE_TITLE,
- summary = "auto update value $v",
- )
- }
-
- return@setSliceDataFn object : EntrySliceData() {
- private var tick = args?.getString("init")?.toInt() ?: 0
-
- init {
- postValue(createSliceImpl(tick))
- }
-
- override suspend fun asyncRunner() {
- spaLogger.message(TAG, "autoUpdater.active")
- while (true) {
- delay(1000L)
- tick++
- spaLogger.message(TAG, "autoUpdater.value $tick")
- postValue(createSliceImpl(tick))
- }
- }
- }
}.build()
)
@@ -272,22 +195,6 @@ object PreferencePageProvider : SettingsPageProvider {
clickRoute = SettingsPageProviderEnum.PREFERENCE.name
)
}
- .setSliceDataFn { sliceUri, _ ->
- val intent = owner.createIntent()?.createBrowsePendingIntent()
- ?: return@setSliceDataFn null
- return@setSliceDataFn object : EntrySliceData() {
- init {
- postValue(
- createDemoSlice(
- sliceUri = sliceUri,
- title = PAGE_TITLE,
- summary = "Injected Entry",
- intent = intent,
- )
- )
- }
- }
- }
}
override fun getTitle(arguments: Bundle?): String {
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugActivity.kt
index 14af5084d625..296579333115 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugActivity.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugActivity.kt
@@ -16,7 +16,6 @@
package com.android.settingslib.spa.debug
-import android.net.Uri
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@@ -41,8 +40,6 @@ import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.util.SESSION_BROWSE
import com.android.settingslib.spa.framework.util.SESSION_SEARCH
import com.android.settingslib.spa.framework.util.createIntent
-import com.android.settingslib.spa.slice.fromEntry
-import com.android.settingslib.spa.slice.presenter.SliceDemo
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.HomeScaffold
@@ -52,7 +49,6 @@ private const val TAG = "DebugActivity"
private const val ROUTE_ROOT = "root"
private const val ROUTE_All_PAGES = "pages"
private const val ROUTE_All_ENTRIES = "entries"
-private const val ROUTE_All_SLICES = "slices"
private const val ROUTE_PAGE = "page"
private const val ROUTE_ENTRY = "entry"
private const val PARAM_NAME_PAGE_ID = "pid"
@@ -87,7 +83,6 @@ class DebugActivity : ComponentActivity() {
composable(route = ROUTE_ROOT) { RootPage() }
composable(route = ROUTE_All_PAGES) { AllPages() }
composable(route = ROUTE_All_ENTRIES) { AllEntries() }
- composable(route = ROUTE_All_SLICES) { AllSlices() }
composable(
route = "$ROUTE_PAGE/{$PARAM_NAME_PAGE_ID}",
arguments = listOf(
@@ -109,8 +104,6 @@ class DebugActivity : ComponentActivity() {
val entryRepository by spaEnvironment.entryRepository
val allPageWithEntry = remember { entryRepository.getAllPageWithEntry() }
val allEntry = remember { entryRepository.getAllEntries() }
- val allSliceEntry =
- remember { entryRepository.getAllEntries().filter { it.hasSliceSupport } }
HomeScaffold(title = "Settings Debug") {
Preference(object : PreferenceModel {
override val title = "List All Pages (${allPageWithEntry.size})"
@@ -120,10 +113,6 @@ class DebugActivity : ComponentActivity() {
override val title = "List All Entries (${allEntry.size})"
override val onClick = navigator(route = ROUTE_All_ENTRIES)
})
- Preference(object : PreferenceModel {
- override val title = "List All Slices (${allSliceEntry.size})"
- override val onClick = navigator(route = ROUTE_All_SLICES)
- })
}
}
@@ -152,18 +141,6 @@ class DebugActivity : ComponentActivity() {
}
}
- @Composable
- fun AllSlices() {
- val entryRepository by spaEnvironment.entryRepository
- val authority = spaEnvironment.sliceProviderAuthorities
- val allSliceEntry =
- remember { entryRepository.getAllEntries().filter { it.hasSliceSupport } }
- RegularScaffold(title = "All Slices (${allSliceEntry.size})") {
- for (entry in allSliceEntry) {
- SliceDemo(sliceUri = Uri.Builder().fromEntry(entry, authority).build())
- }
- }
- }
@Composable
fun OnePage(arguments: Bundle?) {
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugFormat.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugFormat.kt
index 444a3f0fd634..06d105ba61d8 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugFormat.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugFormat.kt
@@ -70,7 +70,6 @@ fun SettingsEntry.debugContent(entryRepository: SettingsEntryRepository): String
"allowSearch = $isAllowSearch",
"isSearchDynamic = $isSearchDataDynamic",
"isSearchMutable = $hasMutableStatus",
- "hasSlice = $hasSliceSupport",
"------ SEARCH ------",
"search_path = $entryPathWithTitle",
searchData?.debugContent() ?: "no search data",
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt
index 2d956d5eddb2..6e5132bbb53e 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt
@@ -17,12 +17,10 @@
package com.android.settingslib.spa.framework.common
import android.app.Activity
-import android.content.BroadcastReceiver
import android.content.Context
import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
-import com.android.settingslib.spa.slice.SettingsSliceDataRepository
private const val TAG = "SpaEnvironment"
@@ -69,8 +67,6 @@ abstract class SpaEnvironment(context: Context) {
val entryRepository = lazy { SettingsEntryRepository(pageProviderRepository.value) }
- val sliceDataRepository = lazy { SettingsSliceDataRepository(entryRepository.value) }
-
// The application context. Use local context as fallback when applicationContext is not
// available (e.g. in Robolectric test).
val appContext: Context = context.applicationContext ?: context
@@ -81,11 +77,9 @@ abstract class SpaEnvironment(context: Context) {
// Specify class name of browse activity and slice broadcast receiver, which is used to
// generate the necessary intents.
open val browseActivityClass: Class<out Activity>? = null
- open val sliceBroadcastReceiverClass: Class<out BroadcastReceiver>? = null
// Specify provider authorities for debugging purpose.
open val searchProviderAuthorities: String? = null
- open val sliceProviderAuthorities: String? = null
// TODO: add other environment setup here.
companion object {
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchContract.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchContract.kt
index 780933d3c9e2..e5bbb8f027bf 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchContract.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchContract.kt
@@ -50,7 +50,6 @@ enum class ColumnEnum(val id: String) {
INTENT_TARGET_PACKAGE("intentTargetPackage"),
INTENT_TARGET_CLASS("intentTargetClass"),
INTENT_EXTRAS("intentExtras"),
- SLICE_URI("sliceUri"),
ENTRY_DISABLED("entryDisabled"),
}
@@ -71,7 +70,6 @@ enum class QueryEnum(
ColumnEnum.INTENT_TARGET_PACKAGE,
ColumnEnum.INTENT_TARGET_CLASS,
ColumnEnum.INTENT_EXTRAS,
- ColumnEnum.SLICE_URI,
)
),
SEARCH_DYNAMIC_DATA_QUERY(
@@ -85,7 +83,6 @@ enum class QueryEnum(
ColumnEnum.INTENT_TARGET_PACKAGE,
ColumnEnum.INTENT_TARGET_CLASS,
ColumnEnum.INTENT_EXTRAS,
- ColumnEnum.SLICE_URI,
)
),
SEARCH_IMMUTABLE_STATUS_DATA_QUERY(
@@ -115,7 +112,6 @@ enum class QueryEnum(
ColumnEnum.INTENT_TARGET_PACKAGE,
ColumnEnum.INTENT_TARGET_CLASS,
ColumnEnum.INTENT_EXTRAS,
- ColumnEnum.SLICE_URI,
ColumnEnum.ENTRY_DISABLED,
)
),
@@ -130,7 +126,6 @@ enum class QueryEnum(
ColumnEnum.INTENT_TARGET_PACKAGE,
ColumnEnum.INTENT_TARGET_CLASS,
ColumnEnum.INTENT_EXTRAS,
- ColumnEnum.SLICE_URI,
ColumnEnum.ENTRY_DISABLED,
)
),
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchProvider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchProvider.kt
index eacb28c29bc3..65f700cb8b94 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchProvider.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchProvider.kt
@@ -32,8 +32,6 @@ import com.android.settingslib.spa.framework.common.SettingsEntry
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.util.SESSION_SEARCH
import com.android.settingslib.spa.framework.util.createIntent
-import com.android.settingslib.spa.slice.fromEntry
-
private const val TAG = "SpaSearchProvider"
@@ -217,11 +215,6 @@ class SpaSearchProvider : ContentProvider() {
.add(ColumnEnum.INTENT_TARGET_CLASS.id, spaEnvironment.browseActivityClass?.name)
.add(ColumnEnum.INTENT_EXTRAS.id, marshall(intent.extras))
}
- if (entry.hasSliceSupport)
- row.add(
- ColumnEnum.SLICE_URI.id, Uri.Builder()
- .fromEntry(entry, spaEnvironment.sliceProviderAuthorities)
- )
}
private fun fetchStatusData(entry: SettingsEntry, cursor: MatrixCursor) {
@@ -252,11 +245,6 @@ class SpaSearchProvider : ContentProvider() {
.add(ColumnEnum.INTENT_TARGET_CLASS.id, spaEnvironment.browseActivityClass?.name)
.add(ColumnEnum.INTENT_EXTRAS.id, marshall(intent.extras))
}
- if (entry.hasSliceSupport)
- row.add(
- ColumnEnum.SLICE_URI.id, Uri.Builder()
- .fromEntry(entry, spaEnvironment.sliceProviderAuthorities)
- )
// Fetch status data. We can add runtime arguments later if necessary
val statusData = entry.getStatusData() ?: return
row.add(ColumnEnum.ENTRY_DISABLED.id, statusData.isDisabled)
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SettingsSliceDataRepository.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SettingsSliceDataRepository.kt
deleted file mode 100644
index 7a4750dfb134..000000000000
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SettingsSliceDataRepository.kt
+++ /dev/null
@@ -1,57 +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.settingslib.spa.slice
-
-import android.net.Uri
-import android.util.Log
-import com.android.settingslib.spa.framework.common.EntrySliceData
-import com.android.settingslib.spa.framework.common.SettingsEntryRepository
-import com.android.settingslib.spa.framework.util.getEntryId
-
-private const val TAG = "SliceDataRepository"
-
-class SettingsSliceDataRepository(private val entryRepository: SettingsEntryRepository) {
- // The map of slice uri to its EntrySliceData, a.k.a. LiveData<Slice?>
- private val sliceDataMap: MutableMap<String, EntrySliceData> = mutableMapOf()
-
- // Note: mark this function synchronized, so that we can get the same livedata during the
- // whole lifecycle of a Slice.
- @Synchronized
- fun getOrBuildSliceData(sliceUri: Uri): EntrySliceData? {
- val sliceString = sliceUri.getSliceId() ?: return null
- return sliceDataMap[sliceString] ?: buildLiveDataImpl(sliceUri)?.let {
- sliceDataMap[sliceString] = it
- it
- }
- }
-
- fun getActiveSliceData(sliceUri: Uri): EntrySliceData? {
- val sliceString = sliceUri.getSliceId() ?: return null
- val sliceData = sliceDataMap[sliceString] ?: return null
- return if (sliceData.isActive()) sliceData else null
- }
-
- private fun buildLiveDataImpl(sliceUri: Uri): EntrySliceData? {
- Log.d(TAG, "buildLiveData: $sliceUri")
-
- val entryId = sliceUri.getEntryId() ?: return null
- val entry = entryRepository.getEntry(entryId) ?: return null
- if (!entry.hasSliceSupport) return null
- val arguments = sliceUri.getRuntimeArguments()
- return entry.getSliceData(runtimeArguments = arguments, sliceUri = sliceUri)
- }
-}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SliceUtil.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SliceUtil.kt
index f3628903dc6d..ec89c7cd3a6c 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SliceUtil.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SliceUtil.kt
@@ -16,23 +16,10 @@
package com.android.settingslib.spa.slice
-import android.app.Activity
-import android.app.PendingIntent
-import android.content.BroadcastReceiver
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
import android.net.Uri
import android.os.Bundle
-import com.android.settingslib.spa.framework.common.SettingsEntry
-import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.util.KEY_DESTINATION
import com.android.settingslib.spa.framework.util.KEY_HIGHLIGHT_ENTRY
-import com.android.settingslib.spa.framework.util.SESSION_SLICE
-import com.android.settingslib.spa.framework.util.SPA_INTENT_RESERVED_KEYS
-import com.android.settingslib.spa.framework.util.appendSpaParams
-import com.android.settingslib.spa.framework.util.getDestination
-import com.android.settingslib.spa.framework.util.getEntryId
// Defines SliceUri, which contains special query parameters:
// -- KEY_DESTINATION: The route that this slice is navigated to.
@@ -45,25 +32,6 @@ fun SliceUri.getEntryId(): String? {
return getQueryParameter(KEY_HIGHLIGHT_ENTRY)
}
-fun SliceUri.getDestination(): String? {
- return getQueryParameter(KEY_DESTINATION)
-}
-
-fun SliceUri.getRuntimeArguments(): Bundle {
- val params = Bundle()
- for (queryName in queryParameterNames) {
- if (SPA_INTENT_RESERVED_KEYS.contains(queryName)) continue
- params.putString(queryName, getQueryParameter(queryName))
- }
- return params
-}
-
-fun SliceUri.getSliceId(): String? {
- val entryId = getEntryId() ?: return null
- val params = getRuntimeArguments()
- return "${entryId}_$params"
-}
-
fun Uri.Builder.appendSpaParams(
destination: String? = null,
entryId: String? = null,
@@ -79,72 +47,3 @@ fun Uri.Builder.appendSpaParams(
return this
}
-fun Uri.Builder.fromEntry(
- entry: SettingsEntry,
- authority: String?,
- runtimeArguments: Bundle? = null
-): Uri.Builder {
- if (authority == null) return this
- val sp = entry.containerPage()
- return scheme("content").authority(authority).appendSpaParams(
- destination = sp.buildRoute(),
- entryId = entry.id,
- runtimeArguments = runtimeArguments
- )
-}
-
-fun SliceUri.createBroadcastPendingIntent(): PendingIntent? {
- val context = SpaEnvironmentFactory.instance.appContext
- val sliceBroadcastClass =
- SpaEnvironmentFactory.instance.sliceBroadcastReceiverClass ?: return null
- val entryId = getEntryId() ?: return null
- return createBroadcastPendingIntent(context, sliceBroadcastClass, entryId)
-}
-
-fun SliceUri.createBrowsePendingIntent(): PendingIntent? {
- val context = SpaEnvironmentFactory.instance.appContext
- val browseActivityClass = SpaEnvironmentFactory.instance.browseActivityClass ?: return null
- val destination = getDestination() ?: return null
- val entryId = getEntryId()
- return createBrowsePendingIntent(context, browseActivityClass, destination, entryId)
-}
-
-fun Intent.createBrowsePendingIntent(): PendingIntent? {
- val context = SpaEnvironmentFactory.instance.appContext
- val browseActivityClass = SpaEnvironmentFactory.instance.browseActivityClass ?: return null
- val destination = getDestination() ?: return null
- val entryId = getEntryId()
- return createBrowsePendingIntent(context, browseActivityClass, destination, entryId)
-}
-
-private fun createBrowsePendingIntent(
- context: Context,
- browseActivityClass: Class<out Activity>,
- destination: String,
- entryId: String?
-): PendingIntent {
- val intent = Intent().setComponent(ComponentName(context, browseActivityClass))
- .appendSpaParams(destination, entryId, SESSION_SLICE)
- .apply {
- // Set both extra and data (which is a Uri) in Slice Intent:
- // 1) extra is used in SPA navigation framework
- // 2) data is used in Slice framework
- data = Uri.Builder().appendSpaParams(destination, entryId).build()
- flags = Intent.FLAG_ACTIVITY_NEW_TASK
- }
-
- return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
-}
-
-private fun createBroadcastPendingIntent(
- context: Context,
- sliceBroadcastClass: Class<out BroadcastReceiver>,
- entryId: String
-): PendingIntent {
- val intent = Intent().setComponent(ComponentName(context, sliceBroadcastClass))
- .apply { data = Uri.Builder().appendSpaParams(entryId = entryId).build() }
- return PendingIntent.getBroadcast(
- context, 0 /* requestCode */, intent,
- PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_MUTABLE
- )
-}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceBroadcastReceiver.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceBroadcastReceiver.kt
deleted file mode 100644
index 39cb43180f58..000000000000
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceBroadcastReceiver.kt
+++ /dev/null
@@ -1,31 +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.settingslib.spa.slice
-
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
-
-class SpaSliceBroadcastReceiver : BroadcastReceiver() {
- override fun onReceive(context: Context?, intent: Intent?) {
- val sliceRepository by SpaEnvironmentFactory.instance.sliceDataRepository
- val sliceUri = intent?.data ?: return
- val sliceData = sliceRepository.getActiveSliceData(sliceUri) ?: return
- sliceData.doAction()
- }
-}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceProvider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceProvider.kt
deleted file mode 100644
index 3496f02a70e4..000000000000
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceProvider.kt
+++ /dev/null
@@ -1,77 +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.settingslib.spa.slice
-
-import android.net.Uri
-import android.util.Log
-import androidx.lifecycle.Observer
-import androidx.slice.Slice
-import androidx.slice.SliceProvider
-import com.android.settingslib.spa.framework.common.EntrySliceData
-import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withContext
-
-private const val TAG = "SpaSliceProvider"
-
-class SpaSliceProvider : SliceProvider(), Observer<Slice?> {
- private fun getOrPutSliceData(sliceUri: Uri): EntrySliceData? {
- if (!SpaEnvironmentFactory.isReady()) return null
- val sliceRepository by SpaEnvironmentFactory.instance.sliceDataRepository
- return sliceRepository.getOrBuildSliceData(sliceUri)
- }
-
- override fun onBindSlice(sliceUri: Uri): Slice? {
- if (context == null) return null
- Log.d(TAG, "onBindSlice: $sliceUri")
- return getOrPutSliceData(sliceUri)?.value
- }
-
- override fun onSlicePinned(sliceUri: Uri) {
- Log.d(TAG, "onSlicePinned: $sliceUri")
- super.onSlicePinned(sliceUri)
- val sliceLiveData = getOrPutSliceData(sliceUri) ?: return
- runBlocking {
- withContext(Dispatchers.Main) {
- sliceLiveData.observeForever(this@SpaSliceProvider)
- }
- }
- }
-
- override fun onSliceUnpinned(sliceUri: Uri) {
- Log.d(TAG, "onSliceUnpinned: $sliceUri")
- super.onSliceUnpinned(sliceUri)
- val sliceLiveData = getOrPutSliceData(sliceUri) ?: return
- runBlocking {
- withContext(Dispatchers.Main) {
- sliceLiveData.removeObserver(this@SpaSliceProvider)
- }
- }
- }
-
- override fun onChanged(value: Slice?) {
- val uri = value?.uri ?: return
- Log.d(TAG, "onChanged: $uri")
- context?.contentResolver?.notifyChange(uri, null)
- }
-
- override fun onCreateSliceProvider(): Boolean {
- Log.d(TAG, "onCreateSliceProvider")
- return true
- }
-}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/presenter/Demo.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/presenter/Demo.kt
deleted file mode 100644
index 007f47bd3c82..000000000000
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/presenter/Demo.kt
+++ /dev/null
@@ -1,47 +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.settingslib.spa.slice.presenter
-
-import android.net.Uri
-import androidx.compose.material3.HorizontalDivider
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.viewinterop.AndroidView
-import androidx.lifecycle.compose.LocalLifecycleOwner
-import androidx.slice.widget.SliceLiveData
-import androidx.slice.widget.SliceView
-
-@Composable
-fun SliceDemo(sliceUri: Uri) {
- val context = LocalContext.current
- val lifecycleOwner = LocalLifecycleOwner.current
- val sliceData = remember {
- SliceLiveData.fromUri(context, sliceUri)
- }
-
- HorizontalDivider()
- AndroidView(
- factory = { localContext ->
- val view = SliceView(localContext)
- view.setShowTitleItems(true)
- view.isScrollable = false
- view
- },
- update = { view -> sliceData.observe(lifecycleOwner, view) }
- )
-}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/provider/Demo.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/provider/Demo.kt
deleted file mode 100644
index e4a738631474..000000000000
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/provider/Demo.kt
+++ /dev/null
@@ -1,60 +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.settingslib.spa.slice.provider
-
-import android.app.PendingIntent
-import android.content.Context
-import android.net.Uri
-import androidx.core.R
-import androidx.core.graphics.drawable.IconCompat
-import androidx.slice.Slice
-import androidx.slice.SliceManager
-import androidx.slice.builders.ListBuilder
-import androidx.slice.builders.SliceAction
-import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
-import com.android.settingslib.spa.slice.createBroadcastPendingIntent
-import com.android.settingslib.spa.slice.createBrowsePendingIntent
-
-fun createDemoBrowseSlice(sliceUri: Uri, title: String, summary: String): Slice? {
- val intent = sliceUri.createBrowsePendingIntent() ?: return null
- return createDemoSlice(sliceUri, title, summary, intent)
-}
-
-fun createDemoActionSlice(sliceUri: Uri, title: String, summary: String): Slice? {
- val intent = sliceUri.createBroadcastPendingIntent() ?: return null
- return createDemoSlice(sliceUri, title, summary, intent)
-}
-
-fun createDemoSlice(sliceUri: Uri, title: String, summary: String, intent: PendingIntent): Slice? {
- val context = SpaEnvironmentFactory.instance.appContext
- if (!SliceManager.getInstance(context).pinnedSlices.contains(sliceUri)) return null
- return ListBuilder(context, sliceUri, ListBuilder.INFINITY)
- .addRow(ListBuilder.RowBuilder().apply {
- setPrimaryAction(createSliceAction(context, intent))
- setTitle(title)
- setSubtitle(summary)
- }).build()
-}
-
-private fun createSliceAction(context: Context, intent: PendingIntent): SliceAction {
- return SliceAction.create(
- intent,
- IconCompat.createWithResource(context, R.drawable.notification_action_background),
- ListBuilder.ICON_IMAGE,
- "Enter app"
- )
-}
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SettingsSliceDataRepositoryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SettingsSliceDataRepositoryTest.kt
deleted file mode 100644
index 341a4a5134f9..000000000000
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SettingsSliceDataRepositoryTest.kt
+++ /dev/null
@@ -1,97 +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.settingslib.spa.slice
-
-import android.content.Context
-import android.net.Uri
-import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import androidx.lifecycle.Observer
-import androidx.slice.Slice
-import androidx.test.core.app.ApplicationProvider
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
-import com.android.settingslib.spa.framework.common.createSettingsPage
-import com.android.settingslib.spa.framework.util.genEntryId
-import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest
-import com.android.settingslib.spa.tests.testutils.SppHome
-import com.android.settingslib.spa.tests.testutils.SppLayer2
-import com.google.common.truth.Truth.assertThat
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class SettingsSliceDataRepositoryTest {
- @get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule()
-
- private val context: Context = ApplicationProvider.getApplicationContext()
- private val spaEnvironment =
- SpaEnvironmentForTest(context, listOf(SppHome.createSettingsPage()))
- private val sliceDataRepository by spaEnvironment.sliceDataRepository
-
- @Test
- fun getOrBuildSliceDataTest() {
- SpaEnvironmentFactory.reset(spaEnvironment)
-
- // Slice empty
- assertThat(sliceDataRepository.getOrBuildSliceData(Uri.EMPTY)).isNull()
-
- // Slice supported
- val page = SppLayer2.createSettingsPage()
- val entryId = genEntryId("Layer2Entry1", page)
- val sliceUri = Uri.Builder().appendSpaParams(page.buildRoute(), entryId).build()
- assertThat(sliceUri.getDestination()).isEqualTo("SppLayer2")
- assertThat(sliceUri.getSliceId()).isEqualTo("${entryId}_Bundle[{}]")
- val sliceData = sliceDataRepository.getOrBuildSliceData(sliceUri)
- assertThat(sliceData).isNotNull()
- assertThat(sliceDataRepository.getOrBuildSliceData(sliceUri)).isSameInstanceAs(sliceData)
-
- // Slice unsupported
- val entryId2 = genEntryId("Layer2Entry2", page)
- val sliceUri2 = Uri.Builder().appendSpaParams(page.buildRoute(), entryId2).build()
- assertThat(sliceUri2.getDestination()).isEqualTo("SppLayer2")
- assertThat(sliceUri2.getSliceId()).isEqualTo("${entryId2}_Bundle[{}]")
- assertThat(sliceDataRepository.getOrBuildSliceData(sliceUri2)).isNull()
- }
-
- @Test
- fun getActiveSliceDataTest() {
- SpaEnvironmentFactory.reset(spaEnvironment)
-
- val page = SppLayer2.createSettingsPage()
- val entryId = genEntryId("Layer2Entry1", page)
- val sliceUri = Uri.Builder().appendSpaParams(page.buildRoute(), entryId).build()
-
- // build slice data first
- val sliceData = sliceDataRepository.getOrBuildSliceData(sliceUri)
-
- // slice data is inactive
- assertThat(sliceData!!.isActive()).isFalse()
- assertThat(sliceDataRepository.getActiveSliceData(sliceUri)).isNull()
-
- // slice data is active
- val observer = Observer<Slice?> { }
- sliceData.observeForever(observer)
- assertThat(sliceData.isActive()).isTrue()
- assertThat(sliceDataRepository.getActiveSliceData(sliceUri)).isSameInstanceAs(sliceData)
-
- // slice data is inactive again
- sliceData.removeObserver(observer)
- assertThat(sliceData.isActive()).isFalse()
- assertThat(sliceDataRepository.getActiveSliceData(sliceUri)).isNull()
- }
-}
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SliceUtilTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SliceUtilTest.kt
index d1c4e5110f60..b489afdae157 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SliceUtilTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SliceUtilTest.kt
@@ -16,91 +16,27 @@
package com.android.settingslib.spa.slice
-import android.content.Context
-import android.content.Intent
import android.net.Uri
import androidx.core.os.bundleOf
-import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
-import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class SliceUtilTest {
- private val context: Context = ApplicationProvider.getApplicationContext()
- private val spaEnvironment = SpaEnvironmentForTest(context)
-
@Test
fun sliceUriTest() {
assertThat(Uri.EMPTY.getEntryId()).isNull()
- assertThat(Uri.EMPTY.getDestination()).isNull()
- assertThat(Uri.EMPTY.getRuntimeArguments().size()).isEqualTo(0)
- assertThat(Uri.EMPTY.getSliceId()).isNull()
// valid slice uri
val dest = "myRoute"
val entryId = "myEntry"
val sliceUriWithoutParams = Uri.Builder().appendSpaParams(dest, entryId).build()
assertThat(sliceUriWithoutParams.getEntryId()).isEqualTo(entryId)
- assertThat(sliceUriWithoutParams.getDestination()).isEqualTo(dest)
- assertThat(sliceUriWithoutParams.getRuntimeArguments().size()).isEqualTo(0)
- assertThat(sliceUriWithoutParams.getSliceId()).isEqualTo("${entryId}_Bundle[{}]")
val sliceUriWithParams =
Uri.Builder().appendSpaParams(dest, entryId, bundleOf("p1" to "v1")).build()
assertThat(sliceUriWithParams.getEntryId()).isEqualTo(entryId)
- assertThat(sliceUriWithParams.getDestination()).isEqualTo(dest)
- assertThat(sliceUriWithParams.getRuntimeArguments().size()).isEqualTo(1)
- assertThat(sliceUriWithParams.getSliceId()).isEqualTo("${entryId}_Bundle[{p1=v1}]")
- }
-
- @Test
- fun createBroadcastPendingIntentTest() {
- SpaEnvironmentFactory.reset(spaEnvironment)
-
- // Empty Slice Uri
- assertThat(Uri.EMPTY.createBroadcastPendingIntent()).isNull()
-
- // Valid Slice Uri
- val dest = "myRoute"
- val entryId = "myEntry"
- val sliceUriWithoutParams = Uri.Builder().appendSpaParams(dest, entryId).build()
- val pendingIntent = sliceUriWithoutParams.createBroadcastPendingIntent()
- assertThat(pendingIntent).isNotNull()
- assertThat(pendingIntent!!.isBroadcast).isTrue()
- assertThat(pendingIntent.isImmutable).isFalse()
- }
-
- @Test
- fun createBrowsePendingIntentTest() {
- SpaEnvironmentFactory.reset(spaEnvironment)
-
- // Empty Slice Uri
- assertThat(Uri.EMPTY.createBrowsePendingIntent()).isNull()
-
- // Empty Intent
- assertThat(Intent().createBrowsePendingIntent()).isNull()
-
- // Valid Slice Uri
- val dest = "myRoute"
- val entryId = "myEntry"
- val sliceUri = Uri.Builder().appendSpaParams(dest, entryId).build()
- val pendingIntent = sliceUri.createBrowsePendingIntent()
- assertThat(pendingIntent).isNotNull()
- assertThat(pendingIntent!!.isActivity).isTrue()
- assertThat(pendingIntent.isImmutable).isTrue()
-
- // Valid Intent
- val intent = Intent().apply {
- putExtra("spaActivityDestination", dest)
- putExtra("highlightEntry", entryId)
- }
- val pendingIntent2 = intent.createBrowsePendingIntent()
- assertThat(pendingIntent2).isNotNull()
- assertThat(pendingIntent2!!.isActivity).isTrue()
- assertThat(pendingIntent2.isImmutable).isTrue()
}
} \ No newline at end of file
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/SpaEnvironmentForTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/SpaEnvironmentForTest.kt
index 22a5ca328755..4f8fd794b248 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/SpaEnvironmentForTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/SpaEnvironmentForTest.kt
@@ -216,8 +216,6 @@ class SpaEnvironmentForTest(
context: Context,
rootPages: List<SettingsPage> = emptyList(),
override val browseActivityClass: Class<out Activity>? = BlankActivity::class.java,
- override val sliceBroadcastReceiverClass: Class<out BroadcastReceiver>? =
- BlankSliceBroadcastReceiver::class.java,
override val logger: SpaLogger = object : SpaLogger {}
) : SpaEnvironment(context) {
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-fr-rCA/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-fr-rCA/strings.xml
index a271ff52e801..7e73c4816cc2 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-fr-rCA/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_applications" msgid="5800789569715871963">"Aucune application"</string>
+ <string name="no_applications" msgid="5800789569715871963">"Aucune appli"</string>
<string name="menu_show_system" msgid="906304605807554788">"Afficher le système"</string>
<string name="menu_hide_system" msgid="374571689914923020">"Masquer le système"</string>
<string name="app_permission_summary_allowed" msgid="6115213465364138103">"Autorisé"</string>
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt
index c9934adfad22..fb23637a9f4c 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt
@@ -115,7 +115,7 @@ internal class RestrictedSwitchPreferenceModel(
content: @Composable (SwitchPreferenceModel) -> Unit,
) {
val context = LocalContext.current
- val restrictedSwitchPreferenceModel = remember(restrictedMode, model.title) {
+ val restrictedSwitchPreferenceModel = remember(restrictedMode, model) {
RestrictedSwitchPreferenceModel(context, model, restrictedMode)
}
restrictedSwitchPreferenceModel.RestrictionWrapper {
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index b949cd58a862..ac0b9b45aba6 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -15,6 +15,7 @@
*/
package com.android.settingslib.drawer;
+import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -25,7 +26,9 @@ import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
+import android.graphics.drawable.Icon;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -36,6 +39,8 @@ import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import java.util.ArrayList;
@@ -102,6 +107,9 @@ public class TileUtils {
/** The key used to get the package name of the icon resource for the preference. */
static final String EXTRA_PREFERENCE_ICON_PACKAGE = "com.android.settings.icon_package";
+ /** The key used for the raw byte data of the icon for the preference. */
+ static final String EXTRA_PREFERENCE_ICON_RAW = "com.android.settings.icon_raw";
+
/**
* Name of the meta-data item that should be set in the AndroidManifest.xml
* to specify the key that should be used for the preference.
@@ -518,6 +526,24 @@ public class TileUtils {
}
/**
+ * Retrieves an icon stored in the Bundle as a Parcel with key EXTRA_PREFERENCE_ICON_RAW
+ */
+ @TargetApi(Build.VERSION_CODES.TIRAMISU)
+ @Nullable
+ public static Icon getRawIconFromUri(@NonNull Context context, @Nullable Uri uri,
+ @NonNull Map<String, IContentProvider> providerMap) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+ return null;
+ }
+ final Bundle bundle = getBundleFromUri(context, uri, providerMap, null /* bundle */);
+ if (bundle == null) {
+ return null;
+ }
+
+ return bundle.getParcelable(EXTRA_PREFERENCE_ICON_RAW, Icon.class);
+ }
+
+ /**
* Gets text associated with the input key from the content provider.
*
* @param context context
@@ -564,8 +590,9 @@ public class TileUtils {
return getBundleFromUri(context, uri, providerMap, bundle);
}
- private static Bundle getBundleFromUri(Context context, Uri uri,
- Map<String, IContentProvider> providerMap, Bundle bundle) {
+ @Nullable
+ private static Bundle getBundleFromUri(@NonNull Context context, @Nullable Uri uri,
+ @NonNull Map<String, IContentProvider> providerMap, @Nullable Bundle bundle) {
final Pair<String, String> args = getMethodAndKey(uri);
if (args == null) {
return null;
@@ -593,8 +620,9 @@ public class TileUtils {
}
}
- private static IContentProvider getProviderFromUri(Context context, Uri uri,
- Map<String, IContentProvider> providerMap) {
+ @Nullable
+ private static IContentProvider getProviderFromUri(@NonNull Context context, @Nullable Uri uri,
+ @NonNull Map<String, IContentProvider> providerMap) {
if (uri == null) {
return null;
}
@@ -609,7 +637,8 @@ public class TileUtils {
}
/** Returns method and key of the complete uri. */
- private static Pair<String, String> getMethodAndKey(Uri uri) {
+ @Nullable
+ private static Pair<String, String> getMethodAndKey(@Nullable Uri uri) {
if (uri == null) {
return null;
}
diff --git a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/BuildCompatUtils.java b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/BuildCompatUtils.java
deleted file mode 100644
index bf3651b2cdad..000000000000
--- a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/BuildCompatUtils.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.utils;
-
-import android.os.Build;
-
-import androidx.annotation.ChecksSdkIntAtLeast;
-
-/**
- * An util class to check whether the current OS version is higher or equal to sdk version of
- * device.
- */
-public final class BuildCompatUtils {
-
- /**
- * Implementation of BuildCompat.isAtLeastS() suitable for use in Settings
- *
- * @return Whether the current OS version is higher or equal to S.
- */
- @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.S)
- public static boolean isAtLeastS() {
- return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
- }
-
- /**
- * Implementation of BuildCompat.isAtLeastS() suitable for use in Settings
- *
- * @return Whether the current OS version is higher or equal to Sv2.
- */
- @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.S_V2)
- public static boolean isAtLeastSV2() {
- return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S_V2;
- }
-
- /**
- * Implementation of BuildCompat.isAtLeastT() suitable for use in Settings
- *
- * @return Whether the current OS version is higher or equal to T.
- */
- @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.TIRAMISU)
- public static boolean isAtLeastT() {
- return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU;
- }
-
- private BuildCompatUtils() {}
-}
diff --git a/packages/SettingsLib/aconfig/settingslib.aconfig b/packages/SettingsLib/aconfig/settingslib.aconfig
index 8666584e0972..403e219f3467 100644
--- a/packages/SettingsLib/aconfig/settingslib.aconfig
+++ b/packages/SettingsLib/aconfig/settingslib.aconfig
@@ -92,3 +92,23 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "volume_dialog_audio_sharing_fix"
+ namespace: "cross_device_experiences"
+ description: "Gates whether to show separate volume bars during audio sharing"
+ bug: "336716411"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "extreme_power_low_state_vulnerability"
+ namespace: "pixel_energizer"
+ description: "the battery saver can pause all non-essential apps and their corresponding notification when device is in locked state to introduce the security vulnerability"
+ bug: "346513692"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SettingsLib/res/layout/zen_mode_duration_dialog.xml b/packages/SettingsLib/res/layout/zen_mode_duration_dialog.xml
index 6552296bc4e4..bc5ec6911939 100644
--- a/packages/SettingsLib/res/layout/zen_mode_duration_dialog.xml
+++ b/packages/SettingsLib/res/layout/zen_mode_duration_dialog.xml
@@ -28,7 +28,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
- <com.android.settingslib.notification.ZenRadioLayout
+ <com.android.settingslib.notification.modes.ZenRadioLayout
android:id="@+id/zen_duration_conditions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -46,7 +46,7 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"/>
- </com.android.settingslib.notification.ZenRadioLayout>
+ </com.android.settingslib.notification.modes.ZenRadioLayout>
</LinearLayout>
</ScrollView> \ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/zen_mode_turn_on_dialog_container.xml b/packages/SettingsLib/res/layout/zen_mode_turn_on_dialog_container.xml
index bc330c7356b5..5cf365bd90a7 100644
--- a/packages/SettingsLib/res/layout/zen_mode_turn_on_dialog_container.xml
+++ b/packages/SettingsLib/res/layout/zen_mode_turn_on_dialog_container.xml
@@ -28,7 +28,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
- <com.android.settingslib.notification.ZenRadioLayout
+ <com.android.settingslib.notification.modes.ZenRadioLayout
android:id="@+id/zen_conditions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -46,7 +46,7 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"/>
- </com.android.settingslib.notification.ZenRadioLayout>
+ </com.android.settingslib.notification.modes.ZenRadioLayout>
<TextView
android:id="@+id/zen_alarm_warning"
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 2db6f627e29e..193d0bc6e4e3 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Laat laai van GPU-ontfoutlae vir ontfoutapps toe"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktiveer woordryke verkoperloginskrywing"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sluit bykomende toestelspesifieke verkoperloglêers by foutverslae in, wat privaat inligting kan bevat, meer batterykrag kan gebruik, en/of meer berging kan gebruik."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Deaktiveer ná een dag"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Breedsprakige verkoperloginskrywing het geëindig"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Geaktiveer vir een dag"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Aktiveer vir nog een dag"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Deaktiveer ná een dag"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Geaktiveer vir ’n onbepaalde tyd"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Vensteranimasieskaal"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Oorganganimasieskaal"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator-tydsduurskaal"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Maak dat enige program na eksterne berging geskryf kan word, ongeag manifeswaardes"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Dwing aktiwiteite om verstelbaar te wees"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Maak die groottes van alle aktiwiteite verstelbaar vir veelvuldige vensters, ongeag manifeswaardes."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Aktiveer vormvrye vensters"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktiveer steun vir eksperimentele vormvrye vensters."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Aktiveer vryevormvensters (vorige)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Aktiveer steun vir eksperimentele vorige vryevormvensters."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Werkskerm-rugsteunwagwoord"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Volle rekenaarrugsteune word nie tans beskerm nie"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tik om die wagwoord vir volledige rekenaarrugsteune te verander of te verwyder"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 732ec6fad3ab..606a01ce9a2f 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ለስህተት ማረሚያ መተግበሪያዎች የጂፒዩ ንብርብሮችን መስቀልን ፍቀድ"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"የዝርክርክ ቃላት አቅራቢ ምዝግብ ማስታወሻን መያዝ አንቃ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"በሳንካ ሪፖርቶች ውስጥ ተጨማሪ መሣሪያ-ተኮር የአቅራቢ ምዝግብ ማስታወሻዎችን ያካትቱ፣ ይህም የግል መረጃን ሊይዝ፣ ተጨማሪ ባትሪ ሊፈጅ እና/ወይም ተጨማሪ ማከማቻ ሊጠቀም ይችላል።"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"ከአንድ ቀን በኋላ አሰናክል"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"የብዙ ቃላት አቅራቢ መግቢያ አብቅቷል"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"ለአንድ ቀን ነቅቷል"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"ለአንድ ተጨማሪ ቀን አንቃ"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"ከአንድ ቀን በኋላ ይሰናከላል"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"ያለገደብ ነቅቷል"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"የ Window እነማ ልኬት ለውጥ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"የእነማ ልኬት ለውጥ ሽግግር"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"እነማ አድራጊ ቆይታ መለኪያ"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"የዝርዝር ሰነዶች እሴቶች ግምት ውስጥ ሳያስገባ ማንኛውም መተግበሪያ ወደ ውጫዊ ማከማቻው ለመጻፍ ብቁ ያደርጋል"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"እንቅስቃሴዎች ዳግመኛ እንዲመጣጠኑ አስገድድ"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"የዝርዝር ሰነድ እሴቶች ምንም ይሁኑ ምን ለበርካታ መስኮቶች ሁሉንም እንቅስቃሴዎች መጠናቸው የሚቀየሩ እንዲሆኑ ያደርጋቸዋል።"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"የነጻ ቅርጽ መስኮቶችን ያንቁ"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"የሙከራ ነፃ መልክ መስኮቶች ድጋፍን አንቃ"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"ነፃ ቅርጽ መስኮቶች (የቆየ) ያንቁ"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"የሙከራ የቆዩ የነፃ ቅርጽ መስኮቶች ድጋፍን ያንቁ።"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"የዴስክቶፕ መጠባበቂያ ይለፍ ቃል"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ዴስክቶፕ ሙሉ ምትኬዎች በአሁኑ ሰዓት አልተጠበቁም"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"የዴስክቶፕ ሙሉ ምትኬዎች የይለፍ ቃሉን ለመለወጥ ወይም ለማስወገድ ነካ ያድርጉ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 2964930736db..3da23c82c1d3 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -436,8 +436,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"تأهيل أي تطبيق بحيث تتم كتابته على وحدة تخزين خارجية، بغض النظر عن قيم البيان"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"فرض إمكانية تغيير حجم الأنشطة"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"السماح بتغيير حجم جميع الأنشطة لتناسب تعدد النوافذ، بغض النظر عن قيم البيان"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"تفعيل النوافذ الحرة"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"إتاحة استخدام النوافذ الحرة التجريبية"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"تفعيل النوافذ الحرة (القديمة)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"تفعيل عرض النوافذ الحرة التجريبية القديمة"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"كلمة مرور احتياطية للكمبيوتر"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"النُسخ الاحتياطية الكاملة لسطح المكتب غير محمية في الوقت الحالي"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"انقر لتغيير كلمة مرور النسخ الاحتياطية الكاملة لسطح المكتب أو إزالتها."</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index e73462e31ab2..da17f8007efd 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ডিবাগ এপসমূহৰ বাবে জিপিইউ ডিবাগ তৰপ ল\'ড কৰিবলৈ অনুমতি দিয়ক"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"বিক্ৰেতাৰ ভাৰ্ব’ছ লগিং সক্ষম কৰক"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"বাগ ৰিপ’ৰ্টসমূহত অতিৰিক্ত ডিভাইচ নিৰ্দিষ্ট বিক্ৰেতাৰ লগসমূহ অন্তৰ্ভুক্ত কৰক, য’ত ব্যক্তিগত তথ্য থাকিব পাৰে, যি অধিক বেটাৰী আৰু/অথবা ষ্ট’ৰেজ ব্যৱহাৰ কৰিব পাৰে।"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"এদিনৰ পাছত অক্ষম কৰক"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"ভাৰ্ব’ছ বিক্ৰেতাৰ লগ ইন সমাপ্ত হৈছে"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"এদিনৰ বাবে সক্ষম কৰক"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"আৰু এদিনৰ বাবে সক্ষম কৰক"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"এদিনৰ পাছত অক্ষম কৰে"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"অনিৰ্দিষ্ট কালৰ বাবে সক্ষম কৰা আছে"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"ৱিণ্ড\' এনিমেশ্বন স্কেল"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ট্ৰাঞ্জিশ্বন এনিমেশ্বন স্কেল"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"এনিমেটৰ কালদৈৰ্ঘ্য স্কেল"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"মেনিফেষ্টৰ মান যিয়েই নহওক, বাহ্যিক ষ্ট’ৰেজত লিখিবলৈ যিকোনো এপক উপযুক্ত কৰি তোলে"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"বলেৰে কাৰ্যকলাপসমূহৰ আকাৰ সলনি কৰিব পৰা কৰক"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"মেনিফেষ্টৰ মান যিয়েই নহওক, মাল্টি-ৱিণ্ডৰ বাবে আটাইবোৰ কাৰ্যকলাপৰ আকাৰ সলনি কৰিব পৰা কৰক।"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"ফ্ৰিফৰ্ম ৱিণ্ড\'জ সক্ষম কৰক"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"পৰীক্ষামূলক ফ্ৰী-ফৰ্ম ৱিণ্ড’বোৰৰ বাবে সহায়তা সক্ষম কৰক৷"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"ফ্ৰীফৰ্ম ৱিণ্ড’ সক্ষম কৰ (লিগেচী)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"পৰীক্ষামূলক লিগেচী ফ্ৰীফৰ্ম ৱিণ্ড’ৰ সমৰ্থন সক্ষম কৰক।"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ডেস্কটপ বেকআপ পাছৱৰ্ড"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ডেস্কটপৰ পূৰ্ণ বেকআপ এতিয়ালৈকে সংৰক্ষিত অৱস্থাত নাই"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ডেস্কটপ সম্পূৰ্ণ বেকআপৰ বাবে পাছৱৰ্ডটো সলনি কৰিবলৈ বা আঁতৰাবলৈ টিপক"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 2ae6cd3bf15e..5ae1c6e291fa 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Qrafik prosessor qatları sazlanmasının yüklənməsinə icazə verilsin"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Təfsilatlı təchizatçı jurnalı"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Xəta hesabatına təchizatçının cihaz haqqında əlavə qeydləri daxil edilsin. Qeydlərdə şəxsi məlumatlar ola, onlar artıq yer tuta və enerji sərfiyyatını artıra bilər."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Bir gündən sonra deaktiv edin"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Təchizatçının çox sözlülüyə girişi bitib"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Birgünlük aktivləşdirilib"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Daha bir gün üçün aktivləşdirin"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Bir gün sonra deaktiv olur"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Qeyri-müəyyən müddətə aktivləşdirilib"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Pəncərə animasiyası"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Keçid animasiyası"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animasiya müddəti"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Manifest dəyərindən asılı olmayaraq tətbiqlərin xarici daşıyıcılarda saxlanmasına icazə verilsin"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Çoxpəncərəli rejimdə ölçü dəyişdirilməsi"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Manifest dəyərindən asılı olmayaraq çoxpəncərəli rejimdə pəncərə ölçüsünün dəyişdirilməsinə icazə verilsin"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"İxtiyari formada pəncərə yaradılsın"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Eksperimental olaraq ixtiyari formada pəncərə yaradılsın"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"İxtiyari formada pəncərələri (köhnə) aktivləşdirin"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Təcrübi köhnə ixtiyari formada pəncərələr üçün dəstəyi aktivləşdirin."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Masaüstü rezerv parolu"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Masaüstü tam rezervlər hazırda qorunmayıblar."</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Masaüstünün tam rezerv kopyalanması üçün parolu dəyişmək və ya silmək üçün basın"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index e1e93ef8f1ea..2b92c52ff3fd 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Učitava otklanjanje grešaka GPU-a u apl. za otklanjanje grešaka"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Opširne evidencije prodavca"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Uvrštava u izveštaje o greškama dodatne posebne evidencije prodavca za uređaje, koje mogu da sadrže privatne podatke, da troše više baterije i/ili da koriste više memorije."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Onemogući posle jednog dana"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Detaljno evidentiranje prodavca je završeno"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Omogućeno na jedan dan"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Omogući još jedan dan"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Onemogućeno posle jednog dana"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Omogućeno neograničeno"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Razmera animacije prozora"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Razmera animacije prelaza"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatorova razmera trajanja"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Omogućava upisivanje svih aplikacija u spoljnu memoriju, bez obzira na vrednosti manifesta"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Prinudno omogući promenu veličine aktivnosti"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Omogućava promenu veličine svih aktivnosti za režim sa više prozora, bez obzira na vrednosti manifesta."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Omogući prozore proizvoljnog formata"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogućava podršku za eksperimentalne prozore proizvoljnog formata."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Omogući prozore proizvoljnog formata (zastarelo)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Omogućava podršku za zastarele eksperimentalne prozore proizvoljnog formata."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Lozinka rezervne kopije za računar"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Rezervne kopije čitavog sistema trenutno nisu zaštićene"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dodirnite da biste promenili ili uklonili lozinku za pravljenje rezervnih kopija čitavog sistema na računaru"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 00eb95d877c1..e676fdf97555 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Загружаць слаі адладкі GPU для праграм адладкі"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Уключыць падрабязны журнал пастаўшчыка"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Дадаваць у справаздачы пра памылкі дадатковыя журналы пастаўшчыка для пэўнай прылады (могуць утрымлівацца прыватныя даныя, можа павышацца выкарыстанне акумулятара і/ці памяці)."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Адключыць праз адзін дзень"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Вядзенне дэталёвага журнала пастаўшчыка завершана"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Уключана на адзін дзень"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Уключыць яшчэ на адзін дзень"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Будзе адключана праз адзін дзень"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Уключана без абмежавання па часе"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Маштаб анімацыі акна"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Маштаб перадачы анімацыі"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Працягласць анімацыі"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Робіць любую праграму даступнай для запісу ў знешняе сховішча, незалежна ад значэнняў маніфеста"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Зрабіць вокны дзеянняў даступнымі для змены памеру"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Зрабіць усе віды дзейнасці даступнымі для змены памеру ў рэжыме некалькіх вокнаў, незалежна ад значэнняў маніфеста."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Уключыць адвольную форму вокнаў"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Уключыць падтрымку для эксперыментальнай адвольнай формы акна."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Уключыць адвольную форму вокнаў (устарэлая налада)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Уключыць падтрымку для эксперыментальнай адвольнай формы вокнаў (устарэлая налада)."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Пароль для рэз. копіі ПК"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Поўнае рэзервовае капіраванне працоўнага стала зараз не абаронена"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Краніце, каб змяніць або выдаліць пароль для поўнага рэзервовага капіравання працоўнага стала"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index a2db0f96b74a..c64e2ead6952 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Разреш. на зарежд. на слоевете за отстр. на грешки в ГП за съотв. прилож."</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Активиране на подробно регистр. на файлове за доставчиците"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Включване на допълнителни регистрационни файлове за доставчиците на конкретни устройства в сигналите за програмни грешки, които може да съдържат поверителна информация, да изразходват батерията в по-голяма степен и/или да използват повече място в хранилището."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Да се деактивира след един ден"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Подробното регистриране на файлове за доставчиците приключи"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Активирано за един ден"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Да се активира за още един ден"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Ще се деактивира след един ден"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Активирано за неопределено време"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Скала на прозореца на аним."</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Скала на преходната анимация"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Скала за Animator"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Всички приложения ще отговарят на условията да бъдат записвани във външното хранилище независимо от стойностите в манифеста"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Възможност за преоразмеряване на активностите"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Дава възможност за преоразмеряване на всички активности в режима за няколко прозореца независимо от стойностите в манифеста."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Активиране на прозорците в свободна форма"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Активиране на поддръжката за експерименталните прозорци в свободна форма."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Актив. на прозорците в свободна форма (наследени)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Активиране на поддръжката за експерименталните наследени прозорци в свободна форма."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Парола за резервни копия"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Понастоящем пълните резервни копия за настолен компютър не са защитени"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Докоснете, за да промените или премахнете паролата за пълни резервни копия на настолния компютър"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index f8118f4a0f69..531795ab5cc9 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ডিবাগ অ্যাপের জন্য GPU ডিবাগ স্তর লোড হতে দিন"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ভারবোস ভেন্ডর লগ-ইন চালু করুন"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"সমস্যা সংক্রান্ত রিপোর্টগুলিতে অতিরিক্ত ডিভাইস-নির্দিষ্ট ভেন্ডরের লগগুলি অন্তর্ভুক্ত করুন, যার মধ্যে ব্যক্তিগত তথ্য থাকতে পারে, আরও বেশি ব্যাটারি ব্যবহার করতে পারে, এবং/অথবা আরও স্টোরেজ ব্যবহার করতে পারে।"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"এক দিন পরে বন্ধ করুন"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"ভারবোস ভেন্ডর লগিংয়ের সুবিধা বন্ধ হয়ে গেছে"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"এক দিনের জন্য চালু করা হয়েছে"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"আরও এক দিনের জন্য চালু করুন"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"এক দিন পরে বন্ধ হয়ে যায়"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"অনির্দিষ্টকালের জন্য চালু করা হয়েছে"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"উইন্ডো অ্যানিমেশন স্কেল"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ট্র্যানজিশন অ্যানিমেশন স্কেল"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"অ্যানিমেটর সময়কাল স্কেল"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"ম্যানিফেস্ট মানের নির্বিশেষে যেকোনও অ্যাপকে এক্সটারনাল স্টোরেজে ইনস্টল করার উপযুক্ত বানায়"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"আকার পরিবর্তনযোগ্য করার জন্য ক্রিয়াকলাপগুলিকে জোর করুন"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"ম্যানিফেস্ট মানগুলির নির্বিশেষে মাল্টি-উইন্ডোর জন্য সমস্ত ক্রিয়াকলাপগুলির আকার পরিবর্তনযোগ্য করুন৷"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"ফ্রি-ফর্ম উইন্ডো চালু করুন"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"পরীক্ষামূলক ফ্রি-ফর্ম উইন্ডোগুলির জন্য সহায়তা সক্ষম করুন৷"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"ফ্রিফর্ম উইন্ডো (লিগ্যাসি) চালু করুন"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"এক্সপেরিমেন্টাল ফ্রিফর্ম উইন্ডোর জন্য সহায়তা চালু করুন।"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ডেস্কটপ ব্যাকআপ পাসওয়ার্ড"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ডেস্কটপ পূর্ণ ব্যাকআপ বর্তমানে সুরক্ষিত নয়"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ডেস্কটপের সম্পূর্ণ ব্যাকআপের পাসওয়ার্ডটি পরিবর্তন করতে বা মুছে ফেলতে আলতো চাপুন"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 2288f05140e5..93b4ffb2d0da 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Omogućite slojeve za otkl. grešaka na GPU-u za apl. za otkl. grešaka"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Omogući opširni zapisnik"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"U izvještaje o greškama uključite dodatne zapisnike dobavljača specifične za uređaj, koji mogu sadržavati lične informacije, povećati potrošnju baterije i/ili koristiti više prostora za pohranu."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Onemogući nakon jednog dana"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Opširno zapisivanje dobavljača je završeno"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Omogućeno je na jedan dan"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Omogući još jedan dan"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Onemogućava se nakon jednog dana"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Omogućeno je na neograničeno vrijeme"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animacije prozora"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animacije prijelaza"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala trajanja animatora"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Omogućava upisivanje svih aplikacija u vanjsku pohranu, bez obzira na prikazane vrijednosti"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Nametni aktivnostima mijenjanje veličina"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Omogućava mijenjanje veličine svih aktivnosti za prikaz s više prozora, bez obzira na prikazane vrijednosti"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Omogući prozore nepravilnih oblika"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogućava podršku za eksperimentalne prozore nepravilnih oblika."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Omogući prilagodljive prozore (staro)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Omogućite podršku za eksperimentalne stare prilagodljive prozore."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Lozinka sigurnosne kopije za računar"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Potpune sigurnosne kopije za računare trenutno nisu zaštićene"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dodirnite da promijenite ili uklonite lozinku za potpune rezervne kopije s radne površine"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 61a6e82f19c4..0e6b3d8651c2 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permet carregar capes de depuració de GPU en aplicacions de depuració"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activa el registre detallat del proveïdor"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclou altres registres de proveïdor específics del dispositiu als informes d’errors; és possible que continguin informació privada, consumeixin més bateria o utilitzin més espai d\'emmagatzematge"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Desactiva passat un dia"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"El registre del proveïdor detallat ha finalitzat"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"S\'ha activat durant un dia"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Activa durant un dia més"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Es desactiva passat un dia"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"S\'ha activat indefinidament"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala d\'animació de la finestra"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala d\'animació de la transició"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de durada de l\'animació"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Permet que qualsevol aplicació es pugui escriure en un dispositiu d’emmagatzematge extern, independentment dels valors del manifest"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Força l\'ajust de la mida de les activitats"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permet ajustar la mida de totes les activitats per al mode multifinestra, independentment dels valors del manifest"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Activa les finestres amb format lliure"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activa la compatibilitat amb finestres experimentals amb format lliure"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Activa les finestres amb format lliure (heretat)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Activa la compatibilitat amb les finestres de format lliure heretades i experimentals."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Contrasenya per a còpies d\'ordinador"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Les còpies de seguretat completes d\'ordinador no estan protegides"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toca per canviar o suprimir la contrasenya per a les còpies de seguretat completes de l\'ordinador"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 34444308495e..b04c9080ac46 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Povolit načítání vrstev ladění GPU pro ladicí aplikace"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Povolit podrobné protokolování dodavatele"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Zahrnovat do zpráv o chybách dodatečné protokoly dodavatelů specifické pro zařízení, které mohou obsahovat soukromé údaje, více vybíjet baterii nebo využívat více místa v úložišti."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Po jednom dni vypnout"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Podrobné protokolování dodavatele bylo ukončeno"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Zapnuto na jeden den"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Ponechat zapnuté ještě jeden den"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Po jednom dni se vypne"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Zapnuto na neomezenou dobu"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Měřítko animace okna"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Měřítko animace přeměny"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Měřítko délky animace"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Každou aplikaci bude možné zapsat do externího úložiště, bez ohledu na hodnoty manifestu"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Vynutit možnost změny velikosti aktivit"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Umožní změnu velikosti všech aktivit na několik oken (bez ohledu na hodnoty manifestu)"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivovat okna s volným tvarem"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivuje podporu experimentálních oken s volným tvarem"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Aktivovat okna s volným tvarem (starší nastavení)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Aktivuje podporu starších experimentálních oken s volným tvarem."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Heslo pro zálohy v počítači"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Úplné zálohy v počítači nejsou v současné době chráněny"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tuto možnost vyberte, chcete-li změnit nebo odebrat heslo pro úplné zálohy do počítače"</string>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 3c5135bb87e8..3d2d6c7a5681 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -156,13 +156,13 @@
<item msgid="1241278021345116816">"Optimeret til lydkvalitet (990 kbps/909 kbps)"</item>
<item msgid="3523665555859696539">"Afbalancer lyd- og forbindelseskvalitet (660 kbps/606 kbps)"</item>
<item msgid="886408010459747589">"Optimeret til forbindelseskvalitet (330 kbps/303 kbps)"</item>
- <item msgid="3808414041654351577">"Bedste resultat (tilpasset bithastighed)"</item>
+ <item msgid="3808414041654351577">"Bedste resultat (adaptiv bithastighed)"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
<item msgid="804499336721569838">"Optimeret til lydkvalitet"</item>
<item msgid="7451422070435297462">"Afbalancer lyd- og forbindelseskvalitet"</item>
<item msgid="6173114545795428901">"Optimeret til forbindelseskvalitet"</item>
- <item msgid="4349908264188040530">"Bedste resultat (tilpasset bithastighed)"</item>
+ <item msgid="4349908264188040530">"Bedste resultat (adaptiv bithastighed)"</item>
</string-array>
<string-array name="bluetooth_audio_active_device_summaries">
<item msgid="8019740759207729126"></item>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 1bff907a86c7..6e526dbedde9 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Tillad, at fejlretningslag indlæses for grafikprocessor i apps til fejlretning"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivér detaljeret leverandørlogging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Medtag yderligere enhedsspecifikke leverandørlogfiler i fejlrapporter, som muligvis indeholder personlige oplysninger. Dette bruger muligvis mere batteri og/eller lagerplads."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Deaktiver efter én dag"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Detaljeret leverandørlogging er slut"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Aktiveret i én dag"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Aktivér i én dag mere"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Deaktiveres efter én dag"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Aktiveret på ubestemt tid"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Animationsskala for vindue"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Overgangsanimationsskala"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatorvarighedsskala"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Gør det muligt at overføre enhver app til et eksternt lager uafhængigt af manifestværdier"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Gennemtving, at aktiviteter kan tilpasses"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tillad, at alle aktiviteter kan tilpasses flere vinduer uafhængigt af manifestværdier"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivér vinduer i frit format"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivér understøttelse af eksperimentelle vinduer i frit format"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Aktivér vinduer i frit format (forældet)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Aktivér understøttelse af eksperimentelle forældede vinduer i frit format."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Kode til lokal sikkerhedskopi"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Lokale komplette backups er i øjeblikket ikke beskyttet"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tryk for at skifte eller fjerne adgangskoden til fuld lokal sikkerhedskopiering"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 64139a912fc1..504a9daa148a 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Debug-Apps das Laden von GPU-Debug-Ebenen erlauben"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ausführliche Protokollierung aktivieren"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Schließt zusätzliche gerätespezifische Anbieterprotokolle in Fehlerberichten ein, die private Informationen enthalten, den Akkuverbrauch erhöhen und/oder zusätzlichen Speicher benötigen können."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Nach einem Tag deaktivieren"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Ausführliche Vendoren-Protokollierung beendet"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Für einen Tag aktiviert"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Für einen weiteren Tag aktivieren"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Wird nach einem Tag deaktiviert"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Auf unbestimmte Zeit aktiviert"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Fensteranimationsfaktor"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Übergangsanimationsfaktor"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animationsdauerfaktor"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Jede App kann, ungeachtet der Manifestwerte, in den externen Speicher geschrieben werden"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Aktivitätengröße darf immer angepasst werden"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Die Größe aller Aktivitäten darf, ungeachtet der Manifestwerte, für die Mehrfensterdarstellung angepasst werden"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Freiform-Fenster zulassen"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Unterstützung für experimentelle Freiform-Fenster aktivieren"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Freiform-Fenster zulassen (Legacy)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Unterstützung für experimentelle Legacy-Freiform-Fenster aktivieren."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Passwort für Desktop-Sicherung"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Vollständige Desktop-Sicherungen sind momentan nicht passwortgeschützt"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Zum Ändern oder Entfernen des Passworts für vollständige Desktop-Sicherungen tippen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index f8a6944d84d2..cad445fa41f8 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Φόρτωση επιπ. εντοπ. σφ. GPU για εφαρμ. αντιμ. σφ."</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ενεργ. λεπτ. καταγραφής προμ."</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Συμπερίληψη πρόσθετων αρχείων καταγραφής προμηθευτή για συγκεκριμένες συσκευές στις αναφορές σφαλμάτων, τα οποία ενδέχεται να περιέχουν ιδιωτικές πληροφορίες, να χρησιμοποιούν περισσότερη μπαταρία ή/και να χρησιμοποιούν περισσότερο αποθηκευτικό χώρο."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Απενεργοποίηση μετά από μία ημέρα"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Η λεπτομερής καταγραφή προμηθευτή έχει λήξει"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Έχει ενεργοποιηθεί για μία ημέρα"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Ενεργοποίηση για μία ακόμα ημέρα"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Απενεργοποιείται μετά από μία ημέρα"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Έχει ενεργοποιηθεί επ\' αόριστον"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Κλίμακα κίνησης παραθύρου"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Κλίμακα κίνησης μετάβασης"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Κλίμ. διάρ. Animator"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Κάνει κάθε εφαρμογή κατάλληλη για εγγραφή σε εξωτερικό αποθηκευτικό χώρο, ανεξάρτητα από τις τιμές του μανιφέστου"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Αναγκαστική δυνατότητα αλλαγής μεγέθους δραστηριοτήτων"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Να έχουν όλες οι δραστηριότητες δυνατότητα αλλαγής μεγέθους για την προβολή πολλαπλών παραθύρων, ανεξάρτητα από τις τιμές του μανιφέστου."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Ενεργοποίηση παραθύρων ελεύθερης μορφής"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ενεργοποίηση υποστήριξης για πειραματικά παράθυρα ελεύθερης μορφής."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Ενεργ. παραθύρων ελεύθερης μορφής (παλαιού τύπου)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ενεργοποίηση υποστήριξης για πειραματικά παράθυρα ελεύθερης μορφής παλαιού τύπου."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Εφ/κός κωδικός desktop"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Τα πλήρη αντίγραφα ασφαλείας επιφάνειας εργασίας δεν προστατεύονται αυτή τη στιγμή"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Πατήστε για αλλαγή ή κατάργηση του κωδικού πρόσβασης για τα πλήρη αντίγραφα ασφαλείας επιφάνειας εργασίας"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index a6367f1059b4..ad436646c5e1 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery and/or use more storage."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Disable after one day"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Verbose vendor logging has ended"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Enabled for one day"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Enable for one more day"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Disables after one day"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Enabled indefinitely"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizeable"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizeable for multi-window, regardless of manifest values."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Enable freeform windows (legacy)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Enable support for experimental legacy freeform windows."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren\'t currently protected"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 975cc5ee7b88..a77d6c66447d 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -430,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizable"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizable for multi-window, regardless of manifest values."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Enable freeform windows (legacy)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Enable support for experimental legacy freeform windows."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren’t currently protected"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index a6367f1059b4..ad436646c5e1 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery and/or use more storage."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Disable after one day"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Verbose vendor logging has ended"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Enabled for one day"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Enable for one more day"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Disables after one day"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Enabled indefinitely"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizeable"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizeable for multi-window, regardless of manifest values."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Enable freeform windows (legacy)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Enable support for experimental legacy freeform windows."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren\'t currently protected"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index a6367f1059b4..ad436646c5e1 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery and/or use more storage."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Disable after one day"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Verbose vendor logging has ended"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Enabled for one day"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Enable for one more day"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Disables after one day"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Enabled indefinitely"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizeable"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizeable for multi-window, regardless of manifest values."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Enable freeform windows (legacy)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Enable support for experimental legacy freeform windows."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren\'t currently protected"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 7411487899f3..8d6520f992b2 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -430,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎Makes any app eligible to be written to external storage, regardless of manifest values‎‏‎‎‏‎"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‎‎Force activities to be resizable‎‏‎‎‏‎"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‎Make all activities resizable for multi-window, regardless of manifest values.‎‏‎‎‏‎"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‎‏‏‎‏‎Enable freeform windows‎‏‎‎‏‎"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‎Enable support for experimental freeform windows.‎‏‎‎‏‎"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‎Enable freeform windows (legacy)‎‏‎‎‏‎"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎Enable support for experimental legacy freeform windows.‎‏‎‎‏‎"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎Desktop backup password‎‏‎‎‏‎"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‎‎Desktop full backups aren’t currently protected‎‏‎‎‏‎"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‏‎Tap to change or remove the password for desktop full backups‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 3c95fd29ca6f..2cf0fe317cb6 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite cargar capas de depuración de GPU para apps de depuración"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Habilitar registro detallado"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluye otros registros de proveedor específicos del dispositivo en los informes de errores, que podrían contener información privada, consumir más batería o usar más espacio de almacenamiento."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Inhabilitar luego de un día"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Finalizó el registro de verbosidad del proveedor"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Habilitado por un día"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Habilitar por un día más"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Se inhabilita luego de un día"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Habilitado por tiempo indefinido"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animación de ventana"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animación de transición"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duración de animador"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Cualquier app puede escribirse en un almacenamiento externo, sin importar los valores del manifiesto"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Forzar actividades para que cambien de tamaño"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permitir que todas las actividades puedan cambiar de tamaño para el modo multiventana, sin importar los valores del manifiesto."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Habilitar ventanas de forma libre"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Permite la compatibilidad con ventanas de forma libre experimentales."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Habilitar ventanas de formato libre (heredado)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Permitir la compatibilidad con ventanas de formato libre experimentales (heredado)"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Contraseñas"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Tus copias de seguridad de escritorio no están protegidas por contraseña"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Presiona para cambiar o quitar la contraseña de las copias de seguridad completas de tu escritorio."</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 28bfb383eac6..e012a4180eed 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite cargar capas de depuración de GPU en aplicaciones de depuración"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Habilitar registro de proveedor detallado"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluye otros registros de proveedor específicos del dispositivo en informes de errores, lo que puede añadir información privada, usar más batería u ocupar más espacio de almacenamiento."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Inhabilitar después de un día"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"El registro de proveedor detallado ha finalizado"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Habilitado durante un día"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Habilitar durante un día más"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Se inhabilita después de un día"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Habilitado indefinidamente"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animación de ventana"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animación de transición"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duración de animación"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Permite que cualquier aplicación se pueda escribir en un almacenamiento externo independientemente de los valores de manifiesto"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Forzar que las actividades puedan cambiar de tamaño"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permite que todas las actividades puedan cambiar de tamaño en multiventana independientemente de los valores de manifiesto"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Habilitar ventanas de forma libre"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Permite la compatibilidad con ventanas de forma libre experimentales"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Habilitar ventanas de forma libre (antiguo)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Habilita la compatibilidad con ventanas de forma libre antiguas y experimentales."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Contraseña para copias de ordenador"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Las copias de seguridad completas de ordenador no están protegidas"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toca para cambiar o quitar la contraseña de las copias de seguridad completas del escritorio"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 25bc4874a17a..70b436cf0249 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU silumise kihtide laadimise lubamine silumisrakendustele"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Luba paljusõnaline logimine"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Veaaruannetesse kaasatakse täiendavad seadmepõhised teenusepakkuja logid, mis võivad sisaldada privaatset teavet, kasutada rohkem akut ja/või salvestusruumi."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Keela ühe päeva pärast"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Tootja paljusõnaline logimine on lõppenud"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Lubatud üheks päevaks"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Luba veel üheks päevaks"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Keelatakse ühe päeva pärast"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Lubatud määramata ajaks"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Akna animatsioonimastaap"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Ülemineku animatsioonimastaap"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animaatori kestuse mastaap"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Lubab mis tahes rakendusi kirjutada välisesse salvestusruumi manifesti väärtustest olenemata"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Muuda tegevuste suurused muudetavaks"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Muudetakse kõigi tegevuste suurused mitme aknaga vaates muudetavaks (manifesti väärtustest olenemata)."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Luba vabas vormis aknad"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Lubatakse katseliste vabavormis akende tugi."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Luba vabas vormis aknad (pärand)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Lubatakse katseliste pärand vabas vormis akende tugi."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Arvutivarunduse parool"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Täielikud arvutivarundused pole praegu kaitstud"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Puudutage täielike arvutivarunduste parooli muutmiseks või eemaldamiseks"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 92c7d39204a4..1c80af8bb65f 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -288,7 +288,7 @@
<string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM desblokeoa onartu nahi duzu?"</string>
<string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"ABISUA: ezarpen hau aktibatuta dagoen bitartean, gailua babesteko eginbideek ez dute gailu honetan funtzionatuko."</string>
<string name="mock_location_app" msgid="6269380172542248304">"Hautatu asmatutako kokapenen aplikazioa"</string>
- <string name="mock_location_app_not_set" msgid="6972032787262831155">"Ez da ezarri kokapen faltsuen aplikaziorik"</string>
+ <string name="mock_location_app_not_set" msgid="6972032787262831155">"Ez da ezarri asmatutako kokapenen aplikaziorik"</string>
<string name="mock_location_app_set" msgid="4706722469342913843">"Asmatutako kokapenen aplikazioa: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"Sareak"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"Hari gabe bistaratzeko ziurtagiria"</string>
@@ -337,8 +337,8 @@
<string name="select_logpersist_dialog_title" msgid="7745193591195485594">"Hautatu gailuan gordeta utzi nahi dituzun erregistroen bufferrak"</string>
<string name="select_usb_configuration_title" msgid="6339801314922294586">"Hautatu USB konfigurazioa"</string>
<string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"Hautatu USB konfigurazioa"</string>
- <string name="allow_mock_location" msgid="2102650981552527884">"Onartu kokapen faltsuak"</string>
- <string name="allow_mock_location_summary" msgid="179780881081354579">"Onartu kokapen faltsuak"</string>
+ <string name="allow_mock_location" msgid="2102650981552527884">"Baimendu asmatutako kokapenak"</string>
+ <string name="allow_mock_location_summary" msgid="179780881081354579">"Baimendu asmatutako kokapenak"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"Gaitu ikuspegiaren atributuak ikuskatzeko aukera"</string>
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Mantendu datu-konexioa beti aktibo, baita wifi-konexioa aktibo dagoenean ere (sare batetik bestera bizkor aldatu ahal izateko)."</string>
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Erabilgarri badago, erabili konexioa partekatzeko hardwarearen bizkortzea"</string>
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Eman GPUaren arazketa-geruzak kargatzeko baimena arazketa-aplikazioei"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Gaitu saltzaileen erregistro xehatuak"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sartu gailuaren berariazko saltzaileen erregistro gehigarriak akatsen txostenetan; baliteke haiek informazio pribatua izatea, bateria gehiago erabiltzea eta/edo biltegiratzeko toki gehiago hartzea."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Desgaitu egun baten buruan"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Saltzailearen erregistro xehatua amaitu da"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Egun baterako gaituta"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Gaitu beste egun batez"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Egun baten buruan desgaituko da"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Mugarik gabe gaituta"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Leihoen animazio-eskala"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Trantsizioen animazio-eskala"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatzailearen iraupen-eskala"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Aplikazioek kanpoko memorian idatz dezakete, ezarritako balioak kontuan izan gabe"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Behartu jardueren tamaina doitu ahal izatera"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Eman aukera jarduera guztien tamaina doitzeko, leiho batean baino gehiagotan erabili ahal izan daitezen, ezarritako balioak kontuan izan gabe"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Gaitu estilo libreko leihoak"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Onartu estilo libreko leiho esperimentalak"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Gaitu estilo libreko leihoak (aurreko bertsiokoak)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Onartu aurreko bertsioko estilo libreko leiho esperimentalak."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Babeskopien pasahitz lokala"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Une honetan, ordenagailuko babeskopia osoak ez daude babestuta"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ordenagailuko eduki guztiaren babeskopia egiteko erabiltzen den pasahitza aldatzeko edo kentzeko, sakatu hau"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 27e203b91b53..5e4d29a959b2 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -406,20 +406,14 @@
<string name="track_frame_time" msgid="522674651937771106">"‏پرداز زدن HWUI نمایه"</string>
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"‏فعال کردن لایه‌های اشکال‌زدایی GPU"</string>
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"‏مجاز کردن بارگیری لایه‌های اشکال‌زدایی GPU برای برنامه‌های اشکا‌ل‌زدایی"</string>
- <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"فعال کردن گزارش‌گیری مفصل فروشنده"</string>
+ <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"فعال کردن ثبت گزارش مفصل فروشنده"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"شامل گزارشات اشکال تکمیلی ورود به سیستم فروشنده ویژه دستگاه می‌شود که ممکن است دربرگیرنده اطلاعات خصوصی، استفاده بیشتر از باتری، و/یا استفاده بیشتر از فضای ذخیره‌سازی باشد."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"غیرفعال کردن پس‌از یک روز"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"ثبت گزارش مفصل فروشنده پایان یافته است"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"برای یک روز فعال شد"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"فعال کردن برای یک روز دیگر"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"پس‌از یک روز غیرفعال می‌شود"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"به‌طور نامحدود فعال شد"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"مقیاس پویانمایی پنجره"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"مقیاس پویانمایی انتقالی"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"مقیاس طول مدت انیماتور"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"بدون توجه به مقادیر آشکار، هر برنامه‌ای را برای نوشتن در حافظه خارجی واجد شرایط می‌کند"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"اجبار فعالیت‌ها به قابل تغییر اندازه بودن"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"بدون توجه به مقادیر مانیفست، اندازه همه فعالیت‌ها برای حالت چند پنجره‌ای می‌تواند تغییر کند."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"فعال کردن پنجره‌های آزاد"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"فعال کردن پشتیبانی برای پنجره‌های آزاد آزمایشی."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"فعال کردن پنجره‌های با قالب آزاد (قدیمی)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"فعال کردن پشتیبانی از پنجره‌های با قالب آزاد قدیمی آزمایشی."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"گذرواژه پشتیبان‌گیری محلی"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"پشتیبان‌گیری کامل رایانه درحال حاضر محافظت نمی‌شود"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"برای تغییر یا حذف گذرواژه برای نسخه‌های پشتیبان کامل رایانه‌ای تک‌ضرب بزنید"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index a8222b9fee4c..ad0cab36ce17 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Salli GPU:n virheenkorjauskerrosten lataus"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Käytä laajennettua kirjausta"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sisällytä virheraportteihin muita laitekohtaisia myyjälokeja, jotka voivat sisältää yksityisiä tietoja, käyttää enemmän akkua ja/tai käyttää enemmän tallennustilaa"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Poista käytöstä yhden päivän jälkeen"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Tarjoajien laajennettu kirjaus on päättynyt"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Käytössä päivän ajan"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Pidä käytössä vielä yhden päivän ajan"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Poistuu käytöstä yhden päivän jälkeen"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Käytössä toistaiseksi"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Ikkuna"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Siirtymä"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animaattori"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Mahdollistaa sovelluksen tietojen tallentamisen ulkoiseen tallennustilaan luetteloarvoista riippumatta"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Pakota kaikki toiminnot hyväksymään koon muutos"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Pakota kaikki toiminnot hyväksymään koon muuttaminen usean ikkunan tilassa luettelon arvoista riippumatta"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Ota käyttöön vapaamuotoiset ikkunat"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ota kokeellisten vapaamuotoisten ikkunoiden tuki käyttöön"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Ota vapaamuotoiset ikkunat käyttöön (vanha)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ota kokeellinen vapaamuotoisten ikkunoiden tuki käyttöön (vanha)."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Varmuuskop. salasana"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Tietokoneen kaikkien tietojen varmuuskopiointia ei ole tällä hetkellä suojattu"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Vaihda tai poista tietokoneen kaikkien tietojen varmuuskopioinnin salasana koskettamalla."</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index cdc1e44ae3bf..45e70f88839d 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -182,8 +182,8 @@
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Réseau ouvert"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Réseau sécurisé"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Système d\'exploitation Android"</string>
- <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Applications supprimées"</string>
- <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Applications et utilisateurs supprimés"</string>
+ <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Applis supprimées"</string>
+ <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Applis et utilisateurs supprimés"</string>
<string name="data_usage_ota" msgid="7984667793701597001">"Mises à jour du système"</string>
<string name="tether_settings_title_usb" msgid="3728686573430917722">"Partage de connexion par USB"</string>
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Point d\'accès Wi-Fi mobile"</string>
@@ -241,7 +241,7 @@
<string name="category_clone" msgid="1554511758987195974">"Cloner"</string>
<string name="development_settings_title" msgid="140296922921597393">"Options pour les développeurs"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Activer les options pour les développeurs"</string>
- <string name="development_settings_summary" msgid="8718917813868735095">"Définir les options pour le développement de l\'application"</string>
+ <string name="development_settings_summary" msgid="8718917813868735095">"Définir les options pour le développement de l\'appli"</string>
<string name="development_settings_not_available" msgid="355070198089140951">"Les options proposées aux développeurs ne sont pas disponibles pour cet utilisateur."</string>
<string name="vpn_settings_not_available" msgid="2894137119965668920">"Les paramètres de RPV ne sont pas disponibles pour cet utilisateur"</string>
<string name="tethering_settings_not_available" msgid="266821736434699780">"Les paramètres de partage de connexion ne sont pas disponibles pour cet utilisateur"</string>
@@ -288,8 +288,8 @@
<string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Permettre le déverrouillage par le fabricant?"</string>
<string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"AVERTISSEMENT : Les fonctionnalités de protection de l\'appareil ne fonctionneront pas sur cet appareil lorsque ce paramètre est activé."</string>
<string name="mock_location_app" msgid="6269380172542248304">"Sélectionner l\'appli de position fictive"</string>
- <string name="mock_location_app_not_set" msgid="6972032787262831155">"Aucune application de position fictive définie"</string>
- <string name="mock_location_app_set" msgid="4706722469342913843">"Application de position fictive : <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="mock_location_app_not_set" msgid="6972032787262831155">"Aucune appli de position fictive définie"</string>
+ <string name="mock_location_app_set" msgid="4706722469342913843">"Appli de position fictive : <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"Réseautage"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"Certification de l\'affichage sans fil"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Autoriser enreg. données Wi-Fi détaillées"</string>
@@ -343,30 +343,30 @@
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Toujours garder les données cellulaires actives, même lorsque le Wi-Fi est activé (pour la commutation rapide entre les réseaux)."</string>
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Utiliser l\'accélération matérielle du partage de connexion si possible"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"Autoriser le débogage USB?"</string>
- <string name="adb_warning_message" msgid="8145270656419669221">"Le débogage USB est conçu uniquement pour le développement. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applications sur votre appareil sans notification et lire les données de journal."</string>
+ <string name="adb_warning_message" msgid="8145270656419669221">"Le débogage USB est conçu uniquement pour le développement. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applis sur votre appareil sans notification et lire les données de journal."</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"Autoriser le débogage sans fil?"</string>
- <string name="adbwifi_warning_message" msgid="8005936574322702388">"Le débogage sans fil est conçu uniquement aux fin de conception. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applications sur votre appareil sans notification et lire les données de journal."</string>
+ <string name="adbwifi_warning_message" msgid="8005936574322702388">"Le débogage sans fil est conçu uniquement aux fin de conception. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applis sur votre appareil sans notification et lire les données de journal."</string>
<string name="adb_keys_warning_message" msgid="2968555274488101220">"Voulez-vous vraiment désactiver l\'accès au débogage USB de tous les ordinateurs précédemment autorisés?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"Activer les paramètres de développement?"</string>
- <string name="dev_settings_warning_message" msgid="37741686486073668">"Ces paramètres sont en cours de développement. Ils peuvent endommager votre appareil et les applications qui s\'y trouvent, ou provoquer leur dysfonctionnement."</string>
+ <string name="dev_settings_warning_message" msgid="37741686486073668">"Ces paramètres sont en cours de développement. Ils peuvent endommager votre appareil et les applis qui s\'y trouvent, ou provoquer leur dysfonctionnement."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Vérifier les applis par USB"</string>
- <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Vérifier que les applications installées par ADB/ADT ne présentent pas de comportement dangereux."</string>
+ <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Vérifier que les applis installées par ADB/ADT ne présentent pas de comportement dangereux."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Les appareils Bluetooth sans nom (adresses MAC seulement) seront affichés"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Désactive la fonctionnalité de volume absolu par Bluetooth en cas de problème de volume sur les appareils à distance, par exemple si le volume est trop élevé ou s\'il ne peut pas être contrôlé."</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Active la pile de la fonctionnalité Bluetooth Gabeldorsche."</string>
<string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Active la fonctionnalité Connectivité améliorée."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
- <string name="enable_terminal_summary" msgid="2481074834856064500">"Activer l\'application Terminal permettant l\'accès au shell local"</string>
+ <string name="enable_terminal_summary" msgid="2481074834856064500">"Activer l\'appli Terminal permettant l\'accès au shell local"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Vérification HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Configurer vérification HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Débogage"</string>
- <string name="debug_app" msgid="8903350241392391766">"Sélectionner une application à déboguer"</string>
- <string name="debug_app_not_set" msgid="1934083001283807188">"Aucune application à déboguer définie"</string>
- <string name="debug_app_set" msgid="6599535090477753651">"Application à déboguer : <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="select_application" msgid="2543228890535466325">"Sél. application"</string>
+ <string name="debug_app" msgid="8903350241392391766">"Sélectionner une appli à déboguer"</string>
+ <string name="debug_app_not_set" msgid="1934083001283807188">"Aucune appli à déboguer définie"</string>
+ <string name="debug_app_set" msgid="6599535090477753651">"Appli à déboguer : <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="select_application" msgid="2543228890535466325">"Sél. appli"</string>
<string name="no_application" msgid="9038334538870247690">"Aucune"</string>
<string name="wait_for_debugger" msgid="7461199843335409809">"Attendre l\'intervention du débogueur"</string>
- <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Avant de s\'exécuter, l\'application déboguée doit attendre que le débogueur soit attaché."</string>
+ <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Avant de s\'exécuter, l\'appli déboguée doit attendre que le débogueur soit attaché."</string>
<string name="debug_input_category" msgid="7349460906970849771">"Entrée"</string>
<string name="debug_drawing_category" msgid="5066171112313666619">"Dessin"</string>
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Accélération matérielle"</string>
@@ -401,43 +401,37 @@
<string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Rendre la couleur d\'arrière-plan de la barre de navigation transparente par défaut"</string>
<string name="window_blurs" msgid="6831008984828425106">"Autoriser le flou au niveau des fenêtres"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forcer MSAA 4x"</string>
- <string name="force_msaa_summary" msgid="9070437493586769500">"Activer MSAA 4x dans les applications OpenGL ES 2.0"</string>
+ <string name="force_msaa_summary" msgid="9070437493586769500">"Activer MSAA 4x dans les applis OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Déboguer opérations de découpage non rectangulaire"</string>
<string name="track_frame_time" msgid="522674651937771106">"Rendu HWUI du profil"</string>
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Activer couches débogage GPU"</string>
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Autoriser couches débogage GPU pour applis de débogage"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activer le journal détaillé des fournisseurs"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluez les journaux supplémentaires du fournisseur propres à l\'appareil dans les rapports de bogue. Ils peuvent contenir des données personnelles, épuiser la pile plus rapidement et/ou utiliser plus d\'espace de stockage."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Désactiver après une journée"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Le journal détaillé des fournisseurs est terminé"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Activé pour une journée"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Activer pour une journée de plus"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Se désactive après une journée"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Activé indéfiniment"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Échelle animation fenêtres"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Éch. d\'animation des transitions"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Échelle durée animation"</string>
<string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuler affich. secondaires"</string>
- <string name="debug_applications_category" msgid="5394089406638954196">"Applications"</string>
+ <string name="debug_applications_category" msgid="5394089406638954196">"Applis"</string>
<string name="immediately_destroy_activities" msgid="1826287490705167403">"Ne pas conserver activités"</string>
<string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Supprimer immédiatement les activités abandonnées"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"Limite processus arr.-plan"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"Afficher ANR arrière-plan"</string>
- <string name="show_all_anrs_summary" msgid="8562788834431971392">"Afficher le message « L\'application ne répond plus » pour les applications en arrière-plan"</string>
+ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Afficher le message « L\'appli ne répond plus » pour les applis en arrière-plan"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"Affich. avertiss. canal notification"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Afficher avertiss. à l\'écran quand une appli présente une notif. sans canal valide"</string>
<string name="force_allow_on_external" msgid="9187902444231637880">"Forcer l\'autor. d\'applis sur stockage externe"</string>
- <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Rend possible l\'enregistrement de toute application sur un espace de stockage externe, indépendamment des valeurs du fichier manifeste"</string>
+ <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Rend possible l\'enregistrement de toute appli sur un espace de stockage externe, indépendamment des valeurs du fichier manifeste"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Forcer les activités à être redimensionnables"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permet de redimensionner toutes les activités pour le mode multi-fenêtre, indépendamment des valeurs du fichier manifeste."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Activer les fenêtres de forme libre"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activer la compatibilité avec les fenêtres de forme libre expérimentales."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Activer fenêtres de forme libre (patrimoniales)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Activer la prise en charge des fenêtres de forme libre patrimoniales expérimentales."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Mot de passe sauvegarde PC"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Les sauvegardes complètes sur PC ne sont pas protégées actuellement"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Touchez pour modifier ou supprimer le mot de passe utilisé pour les sauvegardes complètes sur ordinateur."</string>
@@ -455,14 +449,14 @@
<item msgid="4548987861791236754">"Couleurs naturelles, comme l\'œil les voit"</item>
<item msgid="1282170165150762976">"Couleurs optimisées pour le contenu numérique"</item>
</string-array>
- <string name="inactive_apps_title" msgid="5372523625297212320">"Applications en veille"</string>
- <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Application inactive. Touchez ici pour l\'activer."</string>
- <string name="inactive_app_active_summary" msgid="8047630990208722344">"Application active. Touchez ici pour la désactiver."</string>
- <string name="standby_bucket_summary" msgid="5128193447550429600">"État de l\'application en veille :<xliff:g id="BUCKET"> %s</xliff:g>"</string>
+ <string name="inactive_apps_title" msgid="5372523625297212320">"Applis en veille"</string>
+ <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Appli inactive. Touchez ici pour l\'activer."</string>
+ <string name="inactive_app_active_summary" msgid="8047630990208722344">"Appli active. Touchez ici pour la désactiver."</string>
+ <string name="standby_bucket_summary" msgid="5128193447550429600">"État de l\'appli en veille :<xliff:g id="BUCKET"> %s</xliff:g>"</string>
<string name="transcode_settings_title" msgid="2581975870429850549">"Paramètres de transcodage des éléments multimédias"</string>
<string name="transcode_user_control" msgid="6176368544817731314">"Remplacer les valeurs par défaut de transcodage"</string>
<string name="transcode_enable_all" msgid="2411165920039166710">"Activer le transcodage"</string>
- <string name="transcode_default" msgid="3784803084573509491">"Présumer que les applications prennent en charge les formats modernes"</string>
+ <string name="transcode_default" msgid="3784803084573509491">"Présumer que les applis prennent en charge les formats modernes"</string>
<string name="transcode_notification" msgid="5560515979793436168">"Afficher les notifications de transcodage"</string>
<string name="transcode_disable_cache" msgid="3160069309377467045">"Désactiver le cache de transcodage"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"Services en cours d\'exécution"</string>
@@ -547,9 +541,9 @@
<string name="retail_demo_reset_title" msgid="1866911701095959800">"Mot de passe obligatoire"</string>
<string name="active_input_method_subtypes" msgid="4232680535471633046">"Modes de saisie actifs"</string>
<string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Utiliser les langues du système"</string>
- <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Échec de l\'ouverture des paramètres de l\'application <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>."</string>
- <string name="ime_security_warning" msgid="6547562217880551450">"Ce mode de saisie est susceptible d\'enregistrer le texte que vous saisissez, y compris vos données personnelles, telles que les mots de passe et les numéros de carte de paiement. Il provient de l\'application <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voulez-vous vraiment l\'activer?"</string>
- <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Remarque : Après un redémarrage, vous ne pouvez pas lancer cette application tant que vous n\'avez pas déverrouillé votre téléphone."</string>
+ <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Échec de l\'ouverture des paramètres de l\'appli <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>."</string>
+ <string name="ime_security_warning" msgid="6547562217880551450">"Ce mode de saisie est susceptible d\'enregistrer le texte que vous saisissez, y compris vos données personnelles, telles que les mots de passe et les numéros de carte de paiement. Il provient de l\'appli <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voulez-vous vraiment l\'activer?"</string>
+ <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Remarque : Après un redémarrage, vous ne pouvez pas lancer cette appli tant que vous n\'avez pas déverrouillé votre téléphone."</string>
<string name="ims_reg_title" msgid="8197592958123671062">"État d\'enregistrement IMS"</string>
<string name="ims_reg_status_registered" msgid="884916398194885457">"Enregistré"</string>
<string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Non enregistré"</string>
@@ -567,7 +561,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes et rappels"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Autoriser la création d\'alarmes et de rappels"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes et rappels"</string>
- <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette application à créer des alarmes et à programmer des actions urgentes. Cela permet à l’application de s\'exécuter en arrière-plan, ce qui peut nécessiter plus de pile.\n\nSi cette autorisation est désactivée, les alarmes existantes et les événements en temps réel programmés par cette application ne fonctionneront pas."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette appli à créer des alarmes et à programmer des actions urgentes. Cela permet à l’appli de s\'exécuter en arrière-plan, ce qui peut nécessiter plus de pile.\n\nSi cette autorisation est désactivée, les alarmes existantes et les événements en temps réel programmés par cette appli ne fonctionneront pas."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"horaire, alarme, rappel, horloge"</string>
<string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne pas déranger"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
@@ -619,20 +613,20 @@
<string name="blob_expires_text" msgid="7882727111491739331">"Expirent le <xliff:g id="DATE">%s</xliff:g>"</string>
<string name="shared_data_delete_failure_text" msgid="3842701391009628947">"Une erreur s\'est produite lors de la suppression des données partagées."</string>
<string name="shared_data_no_accessors_dialog_text" msgid="8903738462570715315">"Il n\'y a aucun bail octroyé pour ces données partagées. Souhaitez-vous les supprimer?"</string>
- <string name="accessor_info_title" msgid="8289823651512477787">"Applications qui partagent des données"</string>
- <string name="accessor_no_description_text" msgid="7510967452505591456">"Aucune description fournie par l\'application."</string>
+ <string name="accessor_info_title" msgid="8289823651512477787">"Applis qui partagent des données"</string>
+ <string name="accessor_no_description_text" msgid="7510967452505591456">"Aucune description fournie par l\'appli."</string>
<string name="accessor_expires_text" msgid="4625619273236786252">"Le bail expire le <xliff:g id="DATE">%s</xliff:g>"</string>
<string name="delete_blob_text" msgid="2819192607255625697">"Supprimer les données partagées"</string>
<string name="delete_blob_confirmation_text" msgid="7807446938920827280">"Voulez-vous vraiment supprimer ces données partagées?"</string>
- <string name="user_add_user_item_summary" msgid="5748424612724703400">"Les utilisateurs disposent de leurs propres applications et de leur propre contenu."</string>
- <string name="user_add_profile_item_summary" msgid="5418602404308968028">"Vous pouvez limiter l\'accès aux applications et au contenu depuis votre compte."</string>
+ <string name="user_add_user_item_summary" msgid="5748424612724703400">"Les utilisateurs disposent de leurs propres applis et de leur propre contenu."</string>
+ <string name="user_add_profile_item_summary" msgid="5418602404308968028">"Vous pouvez limiter l\'accès aux applis et au contenu depuis votre compte."</string>
<string name="user_add_user_item_title" msgid="2394272381086965029">"Utilisateur"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Profil limité"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Ajouter un utilisateur?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Vous pouvez partager cet appareil avec d\'autres personnes en ajoutant des utilisateurs. Chaque utilisateur dispose de son propre espace, où il peut personnaliser, entre autres, ses applications et son fond d\'écran. Chacun peut également modifier les paramètres de l\'appareil, comme les réseaux Wi-Fi, qui touchent tous les utilisateurs.\n\nLorsque vous ajoutez un utilisateur, celui-ci doit configurer son propre espace.\n\nTout utilisateur peut mettre à jour les applications pour les autres utilisateurs. Il se peut que les paramètres et les services d\'accessibilité ne soient pas transférés aux nouveaux utilisateurs."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nTout utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Vous pouvez partager cet appareil avec d\'autres personnes en ajoutant des utilisateurs. Chaque utilisateur dispose de son propre espace, où il peut personnaliser, entre autres, ses applis et son fond d\'écran. Chacun peut également modifier les paramètres de l\'appareil, comme les réseaux Wi-Fi, qui touchent tous les utilisateurs.\n\nLorsque vous ajoutez un utilisateur, celui-ci doit configurer son propre espace.\n\nTout utilisateur peut mettre à jour les applis pour les autres utilisateurs. Il se peut que les paramètres et les services d\'accessibilité ne soient pas transférés aux nouveaux utilisateurs."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nTout utilisateur peut mettre à jour les applis pour tous les autres utilisateurs."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Définir cet utilisateur comme administrateur?"</string>
- <string name="user_grant_admin_message" msgid="1673791931033486709">"Les administrateurs ont des privilèges spéciaux que les autres utilisateurs n\'ont pas. Un administrateur peut gérer tous les utilisateurs, mettre à jour ou réinitialiser cet appareil, modifier les paramètres, voir toutes les applications installées et accorder ou révoquer les privilèges d\'administrateur à d\'autres personnes."</string>
+ <string name="user_grant_admin_message" msgid="1673791931033486709">"Les administrateurs ont des privilèges spéciaux que les autres utilisateurs n\'ont pas. Un administrateur peut gérer tous les utilisateurs, mettre à jour ou réinitialiser cet appareil, modifier les paramètres, voir toutes les applis installées et accorder ou révoquer les privilèges d\'administrateur à d\'autres personnes."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Définir comme administrateur"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Configurer l\'utilisateur?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"Assurez-vous que la personne est disponible et qu\'elle peut utiliser l\'appareil pour configurer son espace."</string>
@@ -644,7 +638,7 @@
<string name="user_new_profile_name" msgid="2405500423304678841">"Nouveau profil"</string>
<string name="user_info_settings_title" msgid="6351390762733279907">"Informations sur l\'utilisateur"</string>
<string name="profile_info_settings_title" msgid="105699672534365099">"Informations de profil"</string>
- <string name="user_need_lock_message" msgid="4311424336209509301">"Avant de créer un profil limité, vous devez définir un écran de verrouillage pour protéger vos applications et vos données personnelles."</string>
+ <string name="user_need_lock_message" msgid="4311424336209509301">"Avant de créer un profil limité, vous devez définir un écran de verrouillage pour protéger vos applis et vos données personnelles."</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"Définir verrouillage écran"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Passer à <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Création d\'un utilisateur en cours…"</string>
@@ -663,9 +657,9 @@
<string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Retirer"</string>
<string name="guest_resetting" msgid="7822120170191509566">"Réinitialisation de la session Invité en cours…"</string>
<string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Réinitialiser la session d\'invité?"</string>
- <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Une nouvelle session d\'invité sera lancée, et toutes les applications et données de la session en cours seront supprimées"</string>
+ <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Une nouvelle session d\'invité sera lancée, et toutes les applis et données de la session en cours seront supprimées"</string>
<string name="guest_exit_dialog_title" msgid="1846494656849381804">"Quitter le mode Invité?"</string>
- <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Les applications et les données de la session d\'invité en cours seront supprimées"</string>
+ <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Les applis et les données de la session d\'invité en cours seront supprimées"</string>
<string name="grant_admin" msgid="4323199171790522574">"Oui, le définir comme administrateur"</string>
<string name="not_grant_admin" msgid="3557849576157702485">"Non, ne pas le définir comme administrateur"</string>
<string name="guest_exit_dialog_button" msgid="1736401897067442044">"Quitter"</string>
@@ -724,14 +718,14 @@
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Par défaut"</string>
<string name="turn_screen_on_title" msgid="2662312432042116026">"Commande d\'activation de l\'écran"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Autoriser l\'activation de l\'écran"</string>
- <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Autorisez une application à activer l\'écran. Lorsque vous accordez cette autorisation, l\'application peut activer l\'écran à tout moment sans que vous lui demandiez."</string>
+ <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Autorisez une appli à activer l\'écran. Lorsque vous accordez cette autorisation, l\'appli peut activer l\'écran à tout moment sans que vous lui demandiez."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou changez la sortie, votre diffusion actuelle s\'arrêtera"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Changer la sortie"</string>
<string name="back_navigation_animation" msgid="8105467568421689484">"Animations pour le retour prédictif"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Activer les animations système pour le retour prédictif."</string>
- <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ce paramètre permet d\'activer les animations du système pour l\'animation des gestes prédictifs. Cela exige de définir le paramètre enableOnBackInvokedCallback à Vrai pour chaque application dans le fichier de configuration."</string>
+ <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ce paramètre permet d\'activer les animations du système pour l\'animation des gestes prédictifs. Cela exige de définir le paramètre enableOnBackInvokedCallback à Vrai pour chaque appli dans le fichier de configuration."</string>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Non précisé"</string>
<string name="neuter" msgid="2075249330106127310">"Neutre"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 300dca1ea255..c60e8ce1f6c5 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Autoriser le chargement de couches de débogage GPU"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activer la journalisation détaillée du fournisseur"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclure les journaux supplémentaires du fournisseur, spécifiques à l\'appareil, dans les rapports de bug. Ils peuvent contenir des informations personnelles, solliciter davantage la batterie et/ou utiliser plus d\'espace de stockage."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Désactiver après un jour"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"La journalisation détaillée du fournisseur est terminée"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Activée pour un jour"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Activer pour un jour de plus"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Désactivation après un jour"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Activée indéfiniment"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Échelle d\'animation des fenêtres"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Échelle d\'animation des transitions"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Échelle de durée d\'animation"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Autoriser l\'enregistrement de toute application sur un espace de stockage externe, indépendamment des valeurs du fichier manifeste"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Forcer le redimensionnement des activités"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Rendre toutes les activités redimensionnables pour le mode multifenêtre, indépendamment des valeurs du fichier manifeste"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Activer les fenêtres de forme libre"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activer la compatibilité avec les fenêtres de forme libre expérimentales"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Activer les anciennes fenêtres de forme libre"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Permet d\'activer la compatibilité avec les anciennes fenêtres de forme libre expérimentales."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Mot de passe de sauvegarde ordi"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Les sauvegardes complètes sur ordi ne sont actuellement pas protégées"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Appuyez pour modifier ou supprimer le mot de passe des sauvegardes complètes sur ordi."</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index d00d6d3a5fd8..4f82af38aab7 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -436,8 +436,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Permite que calquera aplicación compatible se poida escribir nun almacenamento externo, independentemente dos valores do manifesto"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Forzar o axuste do tamaño das actividades"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permite axustar o tamaño de todas as actividades para o modo multiventá, independentemente dos valores do manifesto"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Activar ventás de forma libre"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activa a compatibilidade con ventás de forma libre experimentais"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Activar ventás de forma libre (antigas)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Activa a compatibilidade coas ventás de forma libre experimentais antigas."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Contrasinal para copias"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"As copias de seguranza de ordenador completas non están protexidas"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toca para cambiar ou quitar o contrasinal para as copias de seguranza completas de ordenador"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 0c204f7b9b69..b44f0c72041c 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ડિબગ ઍપ માટે GPU ડિબગ સ્તરો લોડ કરવાની મંજૂરી આપો"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"વર્બોઝ વેન્ડર લૉગિંગ ચાલુ કરો"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ખામીની જાણકારીમાં ડિવાઇસથી જોડાયેલા ચોક્કસ વેન્ડર લૉગ શામેલ કરો, જેમાં ખાનગી માહિતી શામેલ હોઈ શકે છે, તે વધુ બૅટરીનો ઉપયોગ કરી શકે છે અને/અથવા વધુ સ્ટોરેજનો ઉપયોગ કરી શકે છે."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"એક દિવસ પછી બંધ કરો"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"શબ્દબહુલ વિક્રેતા લૉગિંગ સમાપ્ત થયું"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"એક દિવસ માટે ચાલુ કર્યું"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"વધુ એક દિવસ માટે ચાલુ કરો"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"એક દિવસ પછી બંધ કરે છે"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"અનિશ્ચિત સમય માટે ચાલુ કર્યું"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"વિન્ડો ઍનિમેશન સ્કેલ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ટ્રાન્ઝિશન ઍનિમેશન સ્કેલ"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ઍનિમેટર અવધિ સ્કેલ"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"મેનિફેસ્ટ મૂલ્યોને ધ્યાનમાં લીધા સિવાય, કોઈપણ ઍપને બાહ્ય સ્ટોરેજ પર લખાવા માટે લાયક બનાવે છે"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"પ્રવૃત્તિઓને ફરીથી કદ યોગ્ય થવા માટે ફરજ પાડો"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"મૅનિફેસ્ટ મૂલ્યોને ધ્યાનમાં લીધા સિવાય, તમામ પ્રવૃત્તિઓને મલ્ટી-વિન્ડો માટે ફરીથી કદ બદલી શકે તેવી બનાવો."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"ફ્રીફોર્મ વિન્ડો ચાલુ કરો"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"પ્રાયોગિક ફ્રીફોર્મ વિન્ડો માટે સપોર્ટને ચાલુ કરો."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"ફ્રીફોર્મ વિન્ડો ચાલુ કરો (જૂની)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"પ્રાયોગિક જૂની ફ્રીફોર્મ વિન્ડો માટે સપોર્ટ મેળવવાની સુવિધા ચાલુ કરો."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ડેસ્કટૉપ બૅકઅપ પાસવર્ડ"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ડેસ્કટૉપ સંપૂર્ણ બૅકઅપ હાલમાં સુરક્ષિત નથી"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ડેસ્કટૉપ સંપૂર્ણ બેકઅપ્સ માટેનો પાસવર્ડ બદલવા અથવા દૂર કરવા માટે ટૅચ કરો"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 2c938a610c0b..246f66e8dcc3 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"डीबग ऐप के लिए जीपीयू डीबग लेयर लोड करने दें"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"वर्बोस वेंडर लॉगिंग चालू करें"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"गड़बड़ियों की रिपोर्ट में डिवाइस से जुड़े अतिरिक्त वेंडर लॉग शामिल करें. इन लॉग में निजी जानकारी, बैटरी का ज़्यादा इस्तेमाल, और/या डिवाइस का स्टोरेज ज़्यादा इस्तेमाल करने की जानकारी हो सकती है."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"एक दिन बाद बंद करें"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"वर्बोस वेंडर लॉगिंग खत्म हो चुका है"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"एक दिन के लिए चालू किया गया"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"एक और दिन के लिए चालू करें"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"एक दिन के बाद बंद होगा"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"अनिश्चित समय के लिए चालू किया गया"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"विंडो ऐनिमेशन स्‍केल"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ट्रांज़िशन ऐनिमेशन स्‍केल"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ऐनिमेटर ड्यूरेशन स्केल"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"इससे कोई भी ऐप्लिकेशन बाहरी स्टोरेज में रखने लायक बन जाता है, चाहे उसकी मेनिफ़ेस्ट वैल्यू कुछ भी हो"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"विंडो के हिसाब से गतिविधियों का साइज़ बदल दें"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"सभी गतिविधियों को मल्टी-विंडो (एक से ज़्यादा ऐप्लिकेशन, एक साथ) के लिए साइज़ बदलने लायक बनाएं, चाहे उनकी मेनिफ़ेस्ट वैल्यू कुछ भी हो."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"फ़्रीफ़ॉर्म विंडो (एक साथ कई विंडो दिखाना) चालू करें"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"फ़्रीफ़ॉर्म विंडो आज़माने की सुविधा चालू करें."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"फ़्रीफ़ॉर्म विंडो वाला लेगसी मोड चालू करें"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"एक्सपेरिमेंट के तौर पर उपलब्ध फ़्रीफ़ॉर्म विंडो वाला लेगसी मोड चालू करें."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"डेस्‍कटॉप बैकअप पासवर्ड"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"डेस्‍कटॉप का पूरा बैकअप फ़िलहाल सुरक्षित नहीं है"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"डेस्कटॉप के पूरे बैक अप का पासवर्ड बदलने या हटाने के लिए टैप करें"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 260e9c2f7b43..f4bb6ea36e54 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Omogućuje učitavanje slojeva za otklanjanje pogrešaka GPU-a za aplikacije za otklanjanje pogrešaka"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Omogući opširni zapisnik"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Uključite dodatne zapisnike dobavljača pojedinog uređaja u izvješća o programskim pogreškama koja mogu sadržavati privatne podatke, trošiti više baterije i/ili zauzeti više prostora za pohranu."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Onemogući nakon jednog dana"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Opširno bilježenje dobavljača je završilo"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Omogućeno na jedan dan"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Omogući još jedan dan"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Onemogućuje se nakon jednog dana"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Omogućeno na neograničeno vrijeme"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Brzina animacije prozora"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Brzina animacije prijelaza"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Razmjer duljine animatora"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Aplikacije se mogu zapisivati u vanjsku pohranu neovisno o vrijednostima manifesta"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Nametni mogućnost promjene veličine za aktivnosti"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Omogući mijenjanje veličine svih aktivnosti za više prozora, neovisno o vrijednostima manifesta."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Omogući prozore slobodnog oblika"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogućuje podršku za eksperimentalne prozore slobodnog oblika."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Omogući prozore slobodnog oblika (naslijeđeno)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Omogući podršku za eksperimentalne naslijeđene prozore slobodnog oblika."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Zaporka sigurnosne kopije"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Potpune sigurnosne kopije na stolnom računalu trenutačno nisu zaštićene"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dodirnite da biste promijenili ili uklonili zaporku za potpune sigurnosne kopije na računalu"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index b16f4a3dc2e3..db739d56c8a3 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU-hibakeresési rétegek betöltésének engedélyezése"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Részletes szolgáltatói naplózás engedélyezése"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"További eszközspecifikus szolgáltatói naplók felvétele a hibajelentésekbe. Ezek a naplók tartalmazhatnak privát információkat, ezenkívül előfordulhat, hogy jobban merítik az akkumulátort, illetve nagyobb tárhelyet foglalnak el."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Letiltás egy nap után"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"A részletes szolgáltatói naplózás lezárult"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Egy napra engedélyezve"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Engedélyezés még egy napra"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Letilt egy nap után"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Határozatlan időre engedélyezve"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Ablakanimáció tempója"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Áttűnési animáció tempója"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animáció tempója"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Lehetővé teszi bármely alkalmazás külső tárhelyre való írását a jegyzékértékektől függetlenül"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Tevékenységek átméretezésének kényszerítése"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Legyen az összes tevékenység átméretezhető a többablakos megjelenítés érdekében a jegyzékértékektől függetlenül."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Szabad formájú ablakok engedélyezése"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Kísérleti, szabad formájú ablakok támogatásának engedélyezése."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Szabad formájú ablakok engedélyezése (régi)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Kísérleti, régi szabad formájú ablakok támogatásának engedélyezése."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Asztali mentés jelszava"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Az asztali teljes biztonsági mentések jelenleg nem védettek."</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Koppintson ide az asztali teljes mentések jelszavának módosításához vagy eltávolításához"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index bd9e564a27af..717313fbb2bf 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Թույլատրել GPU վրիպազերծման շերտերի բեռնումը վրիպազերծման հավելվածների համար"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Մատակարարի մանրամասն գրանցամատյան"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Վրիպակների հաշվետվություններում ներառել կոնկրետ սարքի վերաբերյալ մատակարարի լրացուցիչ մատյանները։ Դա կարող է պարունակել խիստ անձնական տեղեկություններ, ավելի արագ սպառել մարտկոցի լիցքը և/կամ ավելի շատ տարածք օգտագործել։"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Անջատել մեկ օր հետո"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Մատակարարի մանրամասն մատյանի վարումն ավարտված է"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Միացնել մեկ օրով"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Միացնել ևս մեկ օրով"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Կանջատվի մեկ օր հետո"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Միացված է առանց ժամանակային սահմանափակման"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Պատուհանի շարժապատկեր"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Անցումների շարժապատկեր"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Շարժանկարի տևողության սանդղակ"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Թույլ է տալիս ցանկացած հավելված պահել արտաքին սարքում՝ մանիֆեստի արժեքներից անկախ"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Չափերի փոփոխում բազմապատուհան ռեժիմում"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Բոլոր ակտիվությունների չափերը բազմապատուհան ռեժիմի համար դարձնել փոփոխելի՝ մանիֆեստի արժեքներից անկախ:"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Ակտիվացնել կամայական ձևի պատուհանները"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Միացնել ազատ ձևի փորձնական պատուհանների աջակցումը:"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Միացնել կամայական ձևի պատուհանները (հնացած)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Միացնել կամայական ձևի պատուհանների ստեղծման հնացած փորձնական գործառույթի աջակցումը:"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Աշխատասեղանի պահուստավորման գաղտնաբառ"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Աշխատասեղանի ամբողջական պահուստավորումները այժմ պաշտպանված չեն"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Հպեք՝ աշխատասեղանի ամբողջական պահուստավորման գաղտնաբառը փոխելու կամ հեռացնելու համար"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index b3a1291d0fb0..748d5ed4b239 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Izinkan lapisan debug GPU dimuat di aplikasi debug"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktifkan logging vendor panjang"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sertakan log vendor tambahan khusus perangkat dalam laporan bug, yang mungkin berisi informasi pribadi. Meningkatkan penggunaan baterai dan/atau ruang penyimpanan."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Nonaktifkan setelah satu hari"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Logging panjang untuk vendor telah berakhir"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Diaktifkan selama satu hari"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Aktifkan selama satu hari lagi"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Dinonaktifkan setelah satu hari"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Diaktifkan tanpa batas waktu"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animasi jendela"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animasi transisi"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala durasi animator"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Membuat semua aplikasi dapat ditulis ke penyimpanan eksternal, terlepas dari nilai manifes"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Paksa aktivitas agar ukurannya dapat diubah"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Membuat semua aktivitas dapat diubah ukurannya untuk banyak jendela, terlepas dari nilai manifes."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Aktifkan jendela berformat bebas"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktifkan dukungan untuk jendela eksperimental berformat bebas."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Aktifkan jendela freeform (versi lama)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Aktifkan dukungan untuk jendela freeform eksperimental versi lama."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Sandi cadangan desktop"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Saat ini cadangan desktop penuh tidak dilindungi"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ketuk guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 7712b8aed985..7871cb283bfe 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Leyfa villuleit skjákorts fyrir villuleit forrita"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Nákvæm skráning söluaðila"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Taka með viðbótarannála söluaðila fyrir tiltekin tæki í villutilkynningum, sem gætu innihaldið viðkvæmar upplýsingar, notað meiri rafhlöðuorku og/eða þurft meira geymslupláss."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Slökkva eftir einn dag"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Nákvæmri skráningu söluaðila er lokið"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Kveikt í einn dag"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Kveikja eftir einn dag"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Slokknar eftir einn dag"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Kveikt án tímamarka"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Kvarði gluggahreyfinga"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Lengd hreyfiumbreytinga"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Tímalengd hreyfiáhrifa"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Gerir öll forrit skrifanleg í ytra geymslurými, óháð gildum í upplýsingaskrá"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Þvinga breytanlega stærð virkni"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gera stærð allrar virkni breytanlega svo að hún henti fyrir marga glugga, óháð gildum í upplýsingaskrá."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Virkja glugga með frjálsu sniði"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Virkja stuðning við glugga með frjálsu sniði á tilraunastigi."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Virkja glugga á frjálsu sniði (eldra)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Virkja stuðning við eldri tilraunaglugga á frjálsu sniði."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Aðgangsorð tölvuafritunar"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Heildarafritun á tölvu er ekki varin sem stendur."</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ýttu til að breyta eða fjarlægja aðgangsorðið fyrir heildarafritun á tölvu"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index a661700e009d..26b67b468e80 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Consenti caricamento livelli debug GPU per app di debug"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Attiva log dettagliati fornitori"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Includi log aggiuntivi di fornitori relativi a un dispositivo specifico nelle segnalazioni di bug che potrebbero contenere informazioni private, causare un maggior consumo della batteria e/o utilizzare più spazio di archiviazione"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Disattiva dopo un giorno"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Log dettagliati fornitori terminati"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Impostazione attivata per un giorno"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Attiva per un altro giorno"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Impostazione disattivata dopo un giorno"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Impostazione attivata a tempo indeterminato"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Scala animazione finestra"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Scala animazione transizione"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Scala durata animatore"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Consente l\'installazione di qualsiasi app su memoria esterna, indipendentemente dai valori manifest"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Imponi formato modificabile alle attività"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Rendi il formato di tutte le attività modificabile per la modalità multi-finestra, indipendentemente dai valori manifest"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Attiva finestre a forma libera"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Attiva il supporto delle finestre a forma libera sperimentali"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Attiva finestre a forma libera (legacy)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Attiva il supporto delle finestre a forma libera sperimentali legacy."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Password di backup desktop"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"I backup desktop completi non sono attualmente protetti"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tocca per modificare o rimuovere la password per i backup desktop completi"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index fe674bcab81a..f7c96842f64b 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"‏טעינת שכבות לניפוי באגים ב-GPU לאפליקציות ניפוי באגים"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"הפעלת רישום ספקים מפורט ביומן"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"הוספת רישומי יומן של יצרנים למכשירים ספציפיים בדוחות על באגים. דוחות אלה עשויים להכיל מידע פרטי, להגביר את צריכת הסוללה ולצרוך נפח אחסון גדול יותר."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"השבתה אחרי יום אחד"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"רישום הספקים המפורט ביומן הסתיים"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"בוצעה הפעלה ליום אחד"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"הפעלה ליום אחד נוסף"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"מתבצעת השבתה אחרי יום אחד"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"בוצעה הפעלה ללא הגבלת זמן"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"קנה מידה לאנימציה של חלון"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"קנה מידה לאנימציית מעבר"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"קנה מידה למשך זמן אנימציה"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"מאפשר כתיבה של כל אפליקציה באחסון חיצוני, ללא התחשבות בערכי המניפסט"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"אילוץ יכולת קביעת גודל של הפעילויות"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"מאפשר יכולת קביעת גודל של כל הפעילויות לריבוי חלונות, ללא התחשבות בערכי המניפסט."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"הפעלת האפשרות לשנות את הגודל והמיקום של החלונות"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"הפעלת תמיכה בתכונה הניסיונית של שינוי הגודל והמיקום של החלונות."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"הפעלת שינוי הגודל והמיקום של החלונות (מדור קודם)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"הפעלת תמיכה בתכונה הניסיונית מדור קודם של שינוי הגודל והמיקום של החלונות."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"סיסמת גיבוי שולחן העבודה"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"גיבויים מלאים בשולחן העבודה אינם מוגנים כעת"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"יש להקיש כדי לשנות או להסיר את הסיסמה לגיבויים מלאים בשולחן העבודה"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index f5ee5c4357c6..cafa95d3c66b 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"デバッグアプリに GPU デバッグレイヤの読み込みを許可"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ベンダーの詳細なロギングを有効にする"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"バグレポートには、その他のデバイス固有のベンダーログが含まれます。これには、非公開の情報が含まれることがあります。また、バッテリーやストレージの使用量が増えることもあります。"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"1 日後に無効にする"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"ベンダーの詳細なロギングが終了しました"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"1 日間有効にしました"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"あと 1 日有効にする"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"1 日後に無効にします"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"期限なしで有効にしました"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"ウィンドウ アニメ スケール"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"トランジション アニメ スケール"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 再生時間スケール"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"マニフェストの値に関係なく、すべてのアプリを外部ストレージに書き込めるようになります"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"アクティビティをサイズ変更可能にする"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"マニフェストの値に関係なく、マルチウィンドウですべてのアクティビティのサイズを変更できるようにします。"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"フリーフォーム ウィンドウを有効にする"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"試験運用機能のフリーフォーム ウィンドウのサポートを有効にします。"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"フリーフォーム ウィンドウを有効にする(従来版)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"従来の試験運用版のフリーフォーム ウィンドウのサポートを有効にします。"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"PC バックアップ パスワード"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"デスクトップのフルバックアップは現在保護されていません"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"デスクトップのフルバックアップ用のパスワードを変更または削除する場合にタップします"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 1c5822c466e8..10a660bdc492 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -412,18 +412,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"გასამართი აპებისთვის GPU-ს შეცდომების გამართვის შრეების გაშვების დაშვება"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ჟურნალებში მომწოდებელთა დაწვრილებითი აღრიცხვის ჩართვა"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"გამყიდველის მოწყობილობისთვის სპეციფიკური დამატებითი ჟურნალები შევიდეს სისტემის ხარვეზის ანგარიშებში, რომლებიც შეიძლება შეიცავდეს პირად ინფორმაციას, ხარჯავდეს ბატარეის მეტ მუხტს და/ან იყენებდეს მეტ მეხსიერებას."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"ერთი დღის შემდეგ გათიშვა"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"მომწოდებელთა დეტალური აღრიცხვა დასრულდა"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"ჩართულია ერთი დღით"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"კიდევ ერთი დღით ჩართვა"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"გაითიშება ერთი დღის შემდეგ"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"ჩართულია განუსაზღვრელი დროით"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"ფანჯარა: მასშტაბი"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"გადასვლის მასშტაბი"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ანიმაციების ხანგრძლივობის მასშტაბი"</string>
@@ -440,8 +434,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"აპები ჩაიწერება გარე მეხსიერებაზე აღწერის ფაილების მნიშვნელობების მიუხედავად"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"ზომაცვლადი აქტივობების იძულება"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"მანიფესტის მნიშვნელობების მიუხედავად, მრავალი ფანჯრის რეჟიმისთვის ყველა აქტივობის ზომაცვლადად გადაქცევა."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"თავისუფალი ფორმის მქონე ფანჯრების ჩართვა"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"თავისუფალი ფორმის მქონე ფანჯრების მხარდაჭერის ექსპერიმენტული ფუნქციის ჩართვა."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"თავისუფალი ფორმის ფანჯრების ჩართვა (მოძველებული)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"თავისუფალი ფორმის ექსპერიმენტული მოძველებული ფანჯრების ჩართვა."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"დესკტოპის სარეზერვო ასლის პაროლი"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"დესკტოპის სრული სარეზერვო ასლები ამჟამად დაცული არ არის"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"შეეხეთ დესკტოპის სრული სარეზერვო ასლების პაროლის შესაცვლელად ან წასაშლელად"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index ef9b0050fa65..536b624badef 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU түзету қабаттарының жүктелуіне рұқсат ету"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Жеткізуші туралы толық мәліметті тіркеу"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Қате туралы есепте жеткізушінің құрылғыға қатысты қосымша ақпараты қамтылады. Мұнда жеке ақпарат көрсетілуі, батарея шығыны артуы және/немесе қосымша жад пайдаланылуы мүмкін."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Бір күннен кейін өшіру"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Жеткізушінің сөз мөлшерін тіркеуі аяқталды"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Тағы бір күнге қосылды."</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Тағы бір күнге қосу"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Бір күннен кейін өшіріледі."</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Белгісіз уақытқа қосылды."</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Терезе анимациясының өлшемі"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Ауысу анимациясының өлшемі"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Аниматор ұзақтығы"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Манифест мәндеріне қарамастан, кез келген қолданбаны сыртқы жадқа жазуға рұқсат беру"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Әрекеттердің өлшемін өзгертуге рұқсат ету"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Манифест мәндеріне қарамастан, бірнеше терезе режимінде барлық әрекеттердің өлшемін өзгертуге рұқсат беру"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Еркін пішінді терезелерге рұқсат беру"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Еркін пішінді терезелерді құру эксперименттік функиясын қосу"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Еркін пішінді терезелерге рұқсат беру (бұрынғы)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Эксперименттік бұрынғы еркін пішінді терезелерді қолдауға рұқсат береді."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Компьютердегі сақтық көшірме құпия сөзі"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Компьютердегі толық сақтық көшірмелер қазір қорғалмаған."</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Үстелдік компьютердің толық сақтық көшірмелерінің кілтсөзін өзгерту немесе жою үшін түртіңіз"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 199b1141c54a..baef5d87dadf 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"អនុញ្ញាតឱ្យ​ផ្ទុក​ស្រទាប់​ជួស​ជុល GPU សម្រាប់​កម្មវិធី​ជួសជុល"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"បើកការកត់ត្រាអ្នកផ្គត់ផ្គង់ឥតសំចៃ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"រួមបញ្ចូលកំណត់​ហេតុ​អ្នកផ្គត់ផ្គង់​ពាក់ព័ន្ធ​នឹងឧបករណ៍បន្ថែមទៀតនៅក្នុងរបាយការណ៍​អំពីបញ្ហា ដែលអាច​មានផ្ទុកព័ត៌មាន​ឯកជន ប្រើប្រាស់​ថ្មច្រើនជាង និង/ឬប្រើប្រាស់​ទំហំផ្ទុកច្រើនជាង។"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"បិទក្រោយពេលមួយថ្ងៃ"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"ការចុះកំណត់ហេតុអ្នកផ្គត់ផ្គង់លម្អិតបានចប់"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"បានបើករយៈពេលមួយថ្ងៃ"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"បើករយៈពេលលើសពីមួយថ្ងៃ"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"បិទក្រោយពេលមួយថ្ងៃ"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"បានបើកដោយគ្មានពេលកំណត់"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"មាត្រដ្ឋាន​ចលនា​វិនដូ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"មាត្រដ្ឋាន​ដំណើរ​ផ្លាស់ប្ដូរ​ចលនា"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"មាត្រដ្ឋាន​រយៈពេល​នៃ​កម្មវិធី​ចលនា"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"ធ្វើឲ្យកម្មវិធីទាំងឡាយមានសិទ្ធិសរសេរទៅកាន់ឧបករណ៍ផ្ទុកខាងក្រៅ ដោយមិនគិតពីតម្លៃមេនីហ្វេសថ៍"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"បង្ខំឲ្យសកម្មភាពអាចប្តូរទំហំបាន"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"ធ្វើឲ្យសកម្មភាពទាំងអស់អាចប្តូរទំហំបានសម្រាប់ពហុវិនដូ ដោយមិនគិតពីតម្លៃមេនីហ្វេសថ៍។"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"បើកដំណើរការផ្ទាំងវិនដូទម្រង់សេរី"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"បើកឱ្យអាចប្រើផ្ទាំងវិនដូទម្រង់សេរីពិសោធន៍។"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"បើកវិនដូទម្រង់សេរី (ចាស់)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"បើកជំនួយសម្រាប់វិនដូទម្រង់សេរីចាស់ក្នុងដំណាក់កាលពិសោធន៍។"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ពាក្យ​សម្ងាត់​បម្រុង​ទុក​លើកុំព្យូទ័រ"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"បច្ចុប្បន្ន ការ​បម្រុង​ទុក​ពេញលេញនៅលើកុំព្យូទ័រមិន​ត្រូវ​បាន​ការពារ​ទេ"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ប៉ះដើម្បីប្ដូរ ឬយកពាក្យសម្ងាត់ចេញសម្រាប់ការបម្រុងទុកពេញលេញលើកុំព្យូទ័រ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 6ff80d80279d..a203ea785e12 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ಡೀಬಗ್ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗಾಗಿ GPU ಡೀಬಗ್ ಲೇಯರ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡುವುದನ್ನು ಅನುಮತಿಸಿ"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ವರ್‌ಬೋಸ್ ವೆಂಡರ್ ಲಾಗಿಂಗ್‌ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ಬಗ್ ವರದಿಗಳಲ್ಲಿ ಹೆಚ್ಚುವರಿ ಸಾಧನ ನಿರ್ದಿಷ್ಟ ವೆಂಡರ್ ಲಾಗ್‌ಗಳು ಒಳಗೊಂಡಿದೆ, ಇದು ಖಾಸಗಿ ಮಾಹಿತಿ, ಹೆಚ್ಚಿನ ಬ್ಯಾಟರಿ ಬಳಕೆ ಮತ್ತು/ಅಥವಾ ಹೆಚ್ಚಿನ ಸಂಗ್ರಹಣೆಯ ಬಳಕೆಯನ್ನು ಒಳಗೊಂಡಿರಬಹುದು."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"ಒಂದು ದಿನದ ನಂತರ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"ಶಬ್ದ ಬಾಹುಳ್ಯ ಲಾಗಿಂಗ್ ಕೊನೆಗೊಂಡಿದೆ"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"ಒಂದು ದಿನಕ್ಕೆ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"ಇನ್ನೂ ಒಂದು ದಿನದವರೆಗೆ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"ಒಂದು ದಿನದ ನಂತರ ನಿಷ್ಕ್ರಿಯಗೊಳ್ಳುತ್ತದೆ"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"ಅನಿರ್ದಿಷ್ಟವಾಗಿ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Window ಅನಿಮೇಶನ್ ಸ್ಕೇಲ್‌"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ಪರಿವರ್ತನೆ ಅನಿಮೇಶನ್ ಸ್ಕೇಲ್‌"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ಅನಿಮೇಟರ್ ಅವಧಿಯ ಪ್ರಮಾಣ"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳು ಯಾವುದೇ ಆಗಿದ್ದರೂ, ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆಗೆ ಬರೆಯಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಅರ್ಹಗೊಳಿಸುತ್ತದೆ"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"ಚಟುವಟಿಕೆಗಳನ್ನು ಮರುಗಾತ್ರಗೊಳಿಸುವಂತೆ ಒತ್ತಾಯ ಮಾಡಿ"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳನ್ನು ಪರಿಗಣಿಸದೇ, ಬಹು-ವಿಂಡೊಗೆ ಎಲ್ಲಾ ಚಟುವಟಿಕೆಗಳನ್ನು ಮರುಗಾತ್ರಗೊಳಿಸುವಂತೆ ಮಾಡಿ."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"ಮುಕ್ತಸ್ವರೂಪದ ವಿಂಡೊಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ಪ್ರಾಯೋಗಿಕ ಫ್ರೀಫಾರ್ಮ್ ವಿಂಡೊಗಳಿಗೆ ಬೆಂಬಲವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"ಫ್ರೀಫಾರ್ಮ್ ವಿಂಡೋಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ (ಲೆಗಸಿ)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"ಪ್ರಾಯೋಗಿಕ ಲೆಗಸಿ ಫ್ರೀಫಾರ್ಮ್ ವಿಂಡೋಗಳಿಗೆ ಬೆಂಬಲವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ಡೆಸ್ಕ್‌ಟಾಪ್ ಬ್ಯಾಕಪ್ ಪಾಸ್‌ವರ್ಡ್"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ಡೆಸ್ಕ್‌ಟಾಪ್‌‌ ಪೂರ್ಣ ಬ್ಯಾಕಪ್‌‌ಗಳನ್ನು ಪ್ರಸ್ತುತ ರಕ್ಷಿಸಲಾಗಿಲ್ಲ"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ಡೆಸ್ಕ್‌ಟಾಪ್‌ನ ಪೂರ್ಣ ಬ್ಯಾಕಪ್‌ಗಳಿಗೆ ಪಾಸ್‌ವರ್ಡ್‌ ಬದಲಾಯಿಸಲು ಅಥವಾ ತೆಗೆದುಹಾಕಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index af5f9d4c5230..67f1ecdb8e85 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"디버그 앱에 GPU 디버그 레이어 로드 허용"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"상세 공급업체 로깅 사용 설정"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"버그 신고에 추가적인 기기별 공급업체 로그를 포함합니다. 여기에는 개인정보가 포함될 수 있으며, 배터리 또는 저장공간 사용량이 늘어날 수 있습니다."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"1일 후 사용 중지"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"상세 공급업체 로깅 종료됨"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"1일간 사용 설정됨"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"1일 더 사용 설정"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"1일 후 사용 중지"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"무기한 사용 설정됨"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"창 애니메이션 배율"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"전환 애니메이션 배율"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 길이 배율"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"매니페스트 값과 관계없이 모든 앱이 외부 저장소에 작성되도록 허용"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"활동의 크기가 조정 가능하도록 설정"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"모든 활동을 매니페스트 값에 관계없이 멀티 윈도우용으로 크기 조정 가능하도록 설정"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"자유 형식 창 사용"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"자유 형식 창 지원 사용"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"자유 형식 창 사용(레거시)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"실험적인 레거시 자유 형식 창에 대한 지원을 사용하도록 설정합니다."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"데스크톱 백업 비밀번호"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"데스크톱 전체 백업에 비밀번호가 설정되어 있지 않음"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"데스크톱 전체 백업에 대한 비밀번호를 변경하거나 삭제하려면 탭하세요."</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 1d3f44ade109..73532645873a 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU мүчүлүштүктөрдү оңдоо катмарларын иштетет"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Кызмат көрсөтүүчүнүн журналы"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Кызмат көрсөтүүчүнүн түзмөккө байланыштуу кошумча жазуулары мүчүлүштүк тууралуу кабарларга кошулат. Анда купуя маалымат камтылып, батарея тезирээк отуруп жана/же сактагычтан көбүрөөк орун ээлеши мүмкүн."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Бир күндөн кийин өчүрүү"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Кепти дааналатуучунун журналынын аягына чыкты"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Бир күнгө иштетилди"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Дагы бир күнгө иштетүү"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Бир күндөн кийин өчүрүлөт"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Белгисиз убакытка иштетилди"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Терезелердин анимациясы"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Өткөрүү анимацснн шкаласы"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Анимациянын узактыгы"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Манифест маанилерине карабастан бардык колдонмолорду тышкы сактагычка сактоого уруксат берет"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Бир нече терезе режиминде өлчөмдү өзгөртүү"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Бир нече терезе режиминде өлчөмдү өзгөртүүгө уруксат берет (манифесттин маанилерине карабастан)"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Эркин формадагы терезелерди түзүүнү иштетүү"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Эркин формадагы терезелерди түзүү боюнча сынамык функциясы иштетилет."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Эркин формадагы терезелерди түзүүнү иштетүү (эски)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Эркин формадагы эски терезелерди түзүү боюнча сынамык функциясы иштетилет."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Камдык көчүрмөнүн сырсөзү"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Толук камдык көчүрмөлөр учурда корголгон эмес"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Иш тактасынын камдалган сырсөзүн өзгөртүү же алып салуу үчүн таптап коюңуз"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index d99759b625b6..3680e8d13b1f 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ອະນຸຍາດການໂຫລດຊັ້ນຂໍ້ມູນດີບັກ GPU ສຳລັບແອັບດີບັກ"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ເປີດໃຊ້ການບັນທຶກຜູ້ຂາຍແບບລະອຽດ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ຮວມທັງການລາຍງານຂໍ້ຜິດພາດການເຂົ້າສູ່ລະບົບຂອງຜູ້ຂາຍສະເພາະອຸປະກອນເພີ່ມເຕີມ, ເຊິ່ງອາດມີຂໍ້ມູນສ່ວນຕົວ, ໃຊ້ແບັດເຕີຣີຫຼາຍຂຶ້ນ ແລະ/ຫຼື ໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນເພີ່ມເຕີມ."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"ປິດການນຳໃຊ້ຫຼັງຈາກ 1 ມື້"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"ການບັນທຶກຜູ້ຂາຍແບບລະອຽດສິ້ນສຸດແລ້ວ"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"ເປີດການນຳໃຊ້ອີກ 1 ມື້ແລ້ວ"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"ເປີດການນຳໃຊ້ອີກ 1 ມື້"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"ປິດການນຳໃຊ້ຫຼັງຈາກ 1 ມື້"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"ເປີດການນຳໃຊ້ແບບບໍ່ມີກຳນົດສິ້ນສຸດແລ້ວ"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"ຂະໜາດໜ້າ​ຈໍ​ຂອງອະນິເມຊັນ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ຂະໜາດສະຫຼັບອະນິເມຊັນ"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ໄລຍະເວລາອະນິເມຊັນ"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"ເຮັດໃຫ້ທຸກແອັບມີສິດໄດ້ຮັບການຂຽນໃສ່ພື້ນທີ່ຈັດເກັບຂໍ້ມູນພາຍນອກ, ໂດຍບໍ່ຄຳນຶງເຖິງຄ່າ manifest"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"ບັງ​ຄັງ​ໃຫ້​ການ​ເຄື່ອນ​ໄຫວ​ປ່ຽນ​ຂະ​ໜາດ​ໄດ້"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"ເຮັດໃຫ້ທຸກການ​ເຄື່ອນ​ໄຫວສາມາດປັບຂະໜາດໄດ້ສຳລັບຫຼາຍໜ້າຈໍ, ໂດຍບໍ່ຄຳນຶງເຖິງຄ່າ manifest."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"ເປີດໃຊ້ໜ້າຈໍຮູບແບບອິດສະຫຼະ"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ເປີດໃຊ້ການຮອງຮັບໜ້າຈໍຮູບແບບອິດສະຫຼະແບບທົດລອງ."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"ເປີດການນຳໃຊ້ໜ້າຈໍຮູບແບບອິດສະຫຼະ (ແບບເກົ່າ)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"ເປີດການນຳໃຊ້ການຮອງຮັບໜ້າຈໍຮູບແບບອິດສະຫຼະແບບເກົ່າເວີຊັນທົດລອງ."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ລະຫັດຜ່ານການສຳຮອງຂໍ້ມູນເດັສທັອບ"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ການ​ສຳຮອງ​ຂໍ້ມູນ​ເຕັມຮູບແບບ​ໃນ​ເດັສທັອບ​ຍັງ​ບໍ່​ໄດ້​ຮັບ​ການ​ປ້ອງກັນ​ໃນ​ເວລາ​ນີ້"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ແຕະເພື່ອປ່ຽນ ຫຼື ລຶບລະຫັດຂອງການສຳຮອງຂໍ້ມູນເຕັມຮູບແບບໃນເດັສທັອບ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 204afc72d0e2..4f0d6b082479 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Leisti įkelti graf. proc. der. sluoks. der. progr."</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Įg. daugiaž. pasl. teik. reg."</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Į pranešimus apie riktą įtraukiami papildomi konkretaus įrenginio paslaugų teikėjo žurnalai, kuriuose gali būti privačios informacijos, kurie gali naudoti daugiau akumuliatoriaus energijos ir (arba) daugiau vietos saugykloje."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Išjungti po vienos dienos"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Išsamus paslaugų teikėjo registravimas žurnale baigtas"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Įgalinta vienai dienai"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Įgalinti dar vienai dienai"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Bus išjungta po vienos dienos"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Įgalinta neribotam laikui"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Lango animacijos mast."</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Animuoto perėjimo mast."</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator. trukmės skalė"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Nustatoma, kad visas programas būtų galima įrašyti į išorinę saugyklą, nepaisant aprašo verčių"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Priv. nust., kad veiksm. b. g. atl. kelių d. lang."</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Nustatyti, kad visus veiksmus būtų galima atlikti kelių dydžių languose, nepaisant aprašo verčių."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Įgalinti laisvos formos langus"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Įgalinti eksperimentinių laisvos formos langų palaikymą."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Įgalinti laisvos formos langus (pasenę)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Įgalinti eksperimentinių pasenusių laisvos formos langų palaikymą."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Viet. atsrg. kop. slapt."</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Šiuo metu visos vietinės atsarginės kopijos neapsaugotos"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Jei norite pakeisti ar pašalinti visų stalinio kompiuterio atsarginių kopijų slaptažodį, palieskite"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 71d11d562a62..e571b84ae681 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Atļaut GPU atkļūd. slāņu ielādi atkļūd. lietotnēm"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Iespējot izvērsto reģistrēšanu"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Iekļaut kļūdu pārskatos konkrētas ierīces papildu nodrošinātāju žurnālus (var iekļaut privātu informāciju, patērēt vairāk akumulatora enerģijas un/vai aizņemt vairāk vietas krātuvē)."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Atspējot pēc vienas dienas"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Detalizētā nodrošinātāju reģistrēšana ir beigusies"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Iespējota uz vienu dienu"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Iespējot uz vēl vienu dienu"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Tiek atspējota pēc vienas dienas"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Iespējota uz nenoteiktu laiku"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Loga animācijas mērogs"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Pārejas animācijas mērogs"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animācijas ilguma mērogs"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Ļauj jebkuru lietotni ierakstīt ārējā krātuvē neatkarīgi no manifesta vērtības."</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Pielāgot darbības"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Pielāgot visas darbības vairāku logu režīmam neatkarīgi no vērtībām manifestā."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Iespējot brīvās formas logus"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Iespējot eksperimentālo brīvās formas logu atbalstu."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Iespējot brīvās formas logus (mantots režīms)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Iespējot atbalstu eksperimentālajam, mantotajam brīvās formas logu režīmam."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Datora dublējuma parole"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Darbvirsmas pilnie dublējumi pašlaik nav aizsargāti."</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Pieskarieties, lai mainītu vai noņemtu paroli pilniem datora dublējumiem."</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 537f8b55a330..ab30556856b7 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Дозволи вчитување GPU-слоеви за отстранув. грешки"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Опширна евиденција на продавачи"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Вклучува дополнителна евиденција на продавачи во извештаите за грешки за конкретен уред, којашто може да содржи приватни податоци, повеќе да ја користи батеријата и/или да користи повеќе капацитет."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Оневозможи по еден ден"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Опширната евиденција на продавачи заврши"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Овозможено за еден ден"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Овозможи за уште еден ден"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Се оневозможува по еден ден"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Овозможено на неодредено време"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Брзина на анимации за прозорци"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Брзина на преодни анимации"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Брзина на општи анимации"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Сите апликации ќе бидат подобни за запишување во надворешната меморија, независно од вредностите на манифестот"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Наметни променлива големина на активностите"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Сите активности ќе имаат променлива големина во режимот со повеќе прозорци, независно од вредностите на манифестот."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Овозможи прозорци со слободна форма"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Овозможи поддршка за експериментални прозорци со слободна форма."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Овозможи прозорци со менлива големина (застарено)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Овозможете поддршка за експериментални застарени прозорци со менлива големина."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Лозинка за бекап на компјутер"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Целосниот бекап на компјутерот во моментов не е заштитен"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Допрете за да се промени или отстрани лозинката за целосен бекап на компјутерот"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index c096260cf70a..d19069157b45 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ഡീബഗ് ആപ്പുകൾക്കായി GPU ഡീബഗ് ലെയറുകൾ ലോഡ് ചെയ്യാൻ അനുവദിക്കുക"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"വെർബോസ് വെണ്ടർ ലോഗ് ചെയ്യൽ പ്രവർത്തനക്ഷമമാക്കൂ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ബഗ് റിപ്പോർട്ടുകളിൽ ഉപകരണ-നിർദ്ദിഷ്ട വെണ്ടർ അധിക ലോഗുകൾ ഉൾപ്പെടുത്തുക, അതിൽ സ്വകാര്യ വിവരങ്ങൾ അടങ്ങിയിരിക്കാം, കൂടുതൽ ബാറ്ററി ഉപയോഗിക്കാം കൂടാതെ/അല്ലെങ്കിൽ കൂടുതൽ സ്‌റ്റോറേജ് ഇടം ഉപയോഗിക്കാം."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"ഒരു ദിവസത്തിന് ശേഷം പ്രവർത്തനരഹിതമാക്കുക"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"വെർബോസ് വെണ്ടർ ലോഗിംഗ് അവസാനിച്ചു"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"ഒരു ദിവസത്തേക്ക് പ്രവർത്തനക്ഷമമാക്കി"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"ഒരു ദിവസത്തേക്ക് കൂടി പ്രവർത്തനക്ഷമമാക്കുക"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"ഒരു ദിവസത്തിന് ശേഷം പ്രവർത്തനരഹിതമാക്കും"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"അനിശ്ചിതകാലത്തേക്ക് പ്രവർത്തനക്ഷമമാക്കി"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"വിൻഡോ ആനിമേഷൻ സ്‌കെയിൽ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ട്രാൻസിഷൻ ആനിമേഷൻ സ്‌കെയിൽ"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ആനിമേറ്റർ ദൈർഘ്യ സ്‌കെയിൽ"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"മാനിഫെസ്റ്റ് മൂല്യങ്ങൾ പരിഗണിക്കാതെ, ബാഹ്യ സ്റ്റോറേജിലേക്ക് എഴുതപ്പെടുന്നതിന് ഏതൊരു ആപ്പിനെയും യോഗ്യമാക്കുന്നു"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"വലുപ്പം മാറ്റാൻ പ്രവർത്തനങ്ങളെ നിർബന്ധിക്കുക"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"മാനിഫെസ്റ്റ് മൂല്യങ്ങൾ പരിഗണിക്കാതെ, എല്ലാ ആക്ടിവിറ്റികളെയും മൾട്ടി-വിൻഡോയ്ക്കായി വലുപ്പം മാറ്റുക."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"ഫ്രീഫോം വിൻഡോകൾ പ്രവർത്തനക്ഷമമാക്കുക"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"പരീക്ഷണാത്മക ഫ്രീഫോം വിൻഡോകൾക്കുള്ള പിന്തുണ പ്രവർത്തനക്ഷമമാക്കുക."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"ഫ്രീഫോം വിൻഡോകൾ പ്രവർത്തനക്ഷമമാക്കുക (ലെഗസി)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"പരീക്ഷണാത്മക ലെഗസി ഫ്രീഫോം വിൻഡോകൾക്കുള്ള പിന്തുണ പ്രവർത്തനക്ഷമമാക്കുക."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ഡെ‌സ്‌ക്ടോപ്പ് ബാക്കപ്പ് പാസ്‌വേഡ്"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ഡെസ്‌ക്‌ടോപ്പ് പൂർണ്ണ ബാക്കപ്പുകൾ നിലവിൽ പരിരക്ഷിച്ചിട്ടില്ല"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ഡെസ്‌ക്‌ടോപ്പ് പൂർണ്ണ ബാക്കപ്പുകൾക്കായി പാസ്‌വേഡുകൾ മാറ്റാനോ നീക്കംചെയ്യാനോ ടാപ്പുചെയ്യുക"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index b3bca99253c0..c0a79392e0f3 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Дебаг хийх аппад GPU дебаг хийх давхарга ачаалахыг зөвшөөрөх"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Нийлүүлэгчийн дэлгэрэнгүй логийг идэвхжүүлэх"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Төхөөрөмжийн тодорхойлсон нийлүүлэгчийн нэвтрэх үеийн алдааны нэмэлт мэдээг оруулах бөгөөд энэ нь хувийн мэдээлэл агуулж, батарейг илүү ашиглах болон/эсвэл хадгалах сан илүү ашиглаж болзошгүй."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Нэг хоногийн дараа идэвхгүй болгох"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Нийлүүлэгчийн нуршсан дэлгэрэнгүй байдлын лог дууссан"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Нэг хоногийн турш идэвхжүүлсэн"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Дахин нэг хоногийн турш идэвхжүүлэх"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Нэг хоногийн дараа идэвхгүй болгоно"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Тодорхойгүй хугацаанд идэвхжүүлсэн"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Цонхны анимацийн масштаб"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Шилжилтийн анимацийн масштаб"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Анимацийн хугацааны масштаб"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Манифест утгыг нь үл хамааран дурын апп-г гадаад санах ойд бичих боломжтой болгодог"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Үйл ажиллагааны хэмжээг өөрчилж болохуйц болгох"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Тодорхойлогч файлын утгыг үл хамааран, бүх үйл ажиллагааны хэмжээг олон цонхонд өөрчилж болохуйц болгоно уу."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Чөлөөт хэлбэрийн цонхыг идэвхжүүлэх"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Туршилтын чөлөөт хэлбэрийн цонхны дэмжлэгийг идэвхжүүлнэ үү."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Чөлөөт хэлбэрийн цонхыг идэвхжүүлэх (уламжлалт)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Туршилтын чөлөөт хэлбэрийн уламжлалт цонхны дэмжлэгийг идэвхжүүлнэ үү."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Компьютерын нөөцлөлтийн нууц үг"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Компьютерын бүрэн нөөцлөлт одоогоор хамгаалалтгүй байна"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Компьютерийн бүтэн нөөцлөлтийн нууц үгийг өөрчлөх, устгах бол дарна уу"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index f6467fa740ad..4842a9925170 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"डीबग अ‍ॅप्ससाठी GPU डीबग स्तर लोड करण्याची अनुमती द्या"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"व्हर्बोझ विक्रेता लॉगिंग सुरू करा"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"बग रिपोर्टमध्ये अतिरिक्त डिव्हाइस-विशिष्ट विक्रेता लॉगचा समावेश करा ज्यामध्ये खाजगी माहिती असू शकते, अधिक बॅटरी आणि/किंवा अधिक स्टोरेज वापरले जाईल."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"एका दिवसानंतर बंद करा"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"व्हर्बाेस विक्रेता लॉगिंग संपले आहे"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"एका दिवसासाठी सुरू केले आहे"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"आणखी एका दिवसासाठी सुरू करा"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"एका दिवसानंतर बंद करते"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"अनिश्‍चितपणे सुरू केले आहे"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"विंडो ॲनिमेशन स्केल"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ट्रांझिशन ॲनिमेशन स्केल"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ॲनिमेटर कालावधी स्केल"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"मॅनिफेस्‍ट मूल्ये काहीही असू देत, कोणत्याही अ‍ॅपला बाह्य स्टोरेजवर राइट करण्यासाठी पात्र बनविते"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"ॲक्टिव्हिटीचा आकार बदलण्यायोग्य होण्याची सक्ती करा"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"मॅनिफेस्‍ट मूल्ये काहीही असू देत, एकाहून अधिक विंडोसाठी सर्व अ‍ॅक्टिव्हिटीचा आकार बदलण्यायोग्य करा."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"freeform windows सुरू करा"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"प्रायोगिक freeform windows साठी सपोर्ट सुरू करा."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"फ्रीफॉर्म विंडो सुरू करा (लेगसी)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"प्रायोगिक लेगसी फ्रीफॉर्म विंडोसाठी सपोर्ट सुरू करा."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"डेस्कटॉप बॅकअप पासवर्ड"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"डेस्कटॉप पूर्ण बॅक अप सध्या संरक्षित नाहीत"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"डेस्कटॉपच्या पूर्ण बॅकअपसाठी असलेला पासवर्ड बदलण्यासाठी किंवा काढण्यासाठी टॅप करा"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 3301b5472673..01d640998744 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Benarkan pemuatan lapisan nyahpepijat GPU untuk apl penyahpepijatan"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Dayakan pengelogan vendor berjela"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sertakan log tambahan vendor khusus peranti dalam laporan pepijat, yang mungkin mengandungi maklumat peribadi, menggunakan lebih banyak kuasa bateri dan/atau menggunakan lebih banyak storan."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Lumpuhkan selepas satu hari"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Pengelogan vendor berjela telah tamat"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Didayakan untuk satu hari"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Dayakan untuk satu hari lagi"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Dilumpuhkan selepas satu hari"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Didayakan selama-lamanya"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animasi tetingkap"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animasi peralihan"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala tempoh juruanimasi"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Menjadikan sebarang apl layak ditulis ke storan luaran, tanpa mengambil kira nilai manifes"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Paksa aktiviti supaya boleh diubah saiz"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Bolehkan semua saiz aktiviti diubah untuk berbilang tetingkap, tanpa mengambil kira nilai manifes."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Dayakan tetingkap bentuk bebas"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Dayakan sokongan untuk tetingkap bentuk bebas percubaan."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Dayakan tetingkap bentuk bebas (lama)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Dayakan sokongan untuk tetingkap bentuk bebas lama yang bersifat percubaan."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Kata laluan sandaran desktop"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Sandaran penuh desktop tidak dilindungi pada masa ini"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ketik untuk menukar atau mengalih keluar kata laluan untuk sandaran penuh desktop"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 79f1bc3ddd82..92b630dc3422 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"အမှားရှာအက်ပ်များအတွက် GPU အမှားရှာအလွှာများ ဖွင့်ခွင့်ပြုသည်"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"အကျယ်ရှင်းလင်းချက်ပံ့ပိုးသူ မှတ်တမ်းဖွင့်ရန်"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ချွတ်ယွင်းမှု အစီရင်ခံချက်တွင် စက်ပစ္စည်းအလိုက် ထုတ်လုပ်သူမှတ်တမ်းများကို ထည့်သွင်းခြင်းဖြင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များ ပါဝင်ခြင်း၊ ဘက်ထရီပိုသုံးခြင်း နှင့်/သို့မဟုတ် သိုလှောင်ခန်းပိုသုံးခြင်းတို့ ဖြစ်စေနိုင်သည်။"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"တစ်ရက်ကြာပြီးနောက် ပိတ်ရန်"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"အကျယ်ချဲ့ရှင်းပြသည့် ထုတ်လုပ်သူမှတ်တမ်း ပြီးသွားပါပြီ"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"တစ်ရက်စာ ဖွင့်ထားသည်"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"နောက်ထပ်တစ်ရက် ဖွင့်ရန်"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"တစ်ရက်ကြာပြီးနောက် ပိတ်မည်"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"အကန့်အသတ်မရှိ ဖွင့်ထားသည်"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"လှုပ်ရှားသက်ဝင်ပုံစကေး"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"သက်ဝင်အသွင်ပြောင်းခြင်း"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"လှုပ်ရှားမှုကြာချိန်စကေး"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"သတ်မှတ်တန်ဖိုးများ မည်သို့ပင်ရှိစေ ပြင်ပသိုလှောင်ခန်းများသို့ မည်သည့်အက်ပ်ကိုမဆို ဝင်ရောက်ခွင့်ပြုသည်"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"လုပ်ဆောင်ချက်များ အရွယ်ပြောင်းနိုင်ခြင်း"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"သတ်မှတ်တန်ဖိုး မည်သို့ပင်ရှိစေ ဝင်းဒိုးများ၏ လုပ်ဆောင်မှုအားလုံးကို အရွယ်အစားပြင်သည်။"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"ပုံစံမျိုးစုံ ဝင်းဒိုးများ ဖွင့်ရန်"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ပုံစံမျိုးစုံဝင်းဒိုးများ စမ်းသပ်ခြင်းအတွက် ပံ့ပိုးမှုကို ဖွင့်သည်"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"အလွတ်ပုံစံ ဝင်းဒိုးများ ဖွင့်ပါ (အဟောင်း)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"အလွတ်ပုံစံဝင်းဒိုးအဟောင်းများ စမ်းသပ်ရန် ပံ့ပိုးမှုရယူပါ။"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ဒက်စ်တော့ အရန်စကားဝှက်"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ဒက်စ်တော့ တစ်ခုလုံး အရန်သိမ်းဆည်းခြင်းကို လက်ရှိတွင် ကာကွယ်မထားပါ"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ဒက်စ်တော့ အပြည့်အဝ အရန်သိမ်းခြင်းအတွက် စကားဝှက်ကို ပြောင်းရန် သို့မဟုတ် ဖယ်ရှားရန် တို့ပါ။"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 23031c37dbf3..75b04ad04bf1 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Tillat GPU-feilsøkingslag for feilsøkingsapper"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Detaljert leverandørlogging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inkluder flere enhetsspesifikke leverandørlogger i feilrapporter, som kan inneholde privat informasjon, bruke mer batteri og/eller bruke mer lagringsplass."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Deaktiver etter én dag"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Detaljert leverandørloggføring er avsluttet"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Aktivert i én dag"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Aktiver i én dag til"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Deaktiveres etter én dag"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Aktivert på ubestemt tid"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Animasjonsskala for vindu"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Animasjonsskala for overgang"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Varighetsskala for animasjoner"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Dette gjør at alle apper kan lagres på eksterne lagringsmedier – uavhengig av manifestverdier"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Alle aktiviteter kan endre størrelse"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gjør at alle aktiviteter kan endre størrelse for flervindusmodus, uavhengig av manifestverdier."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Slå på vinduer i fritt format"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Slå på støtte for vinduer i eksperimentelt fritt format."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Slå på vinduer i fritt format (eldre versjon)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Slå på støtte for eldre versjon av vinduer i eksperimentelt fritt format."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Passord for sikkerhetskopiering på datamaskin"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Fullstendig sikkerhetskopiering på datamaskin er ikke beskyttet"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Trykk for å endre eller fjerne passordet for fullstendige sikkerhetskopier på datamaskinen"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 38e137d28767..b25285486985 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"डिबग एपका लागि GPU का डिबग लेयर लोड गर्नुहोस्"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"भर्बोज भेन्डर लगिङ अन गर्नुहोस्"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"बग रिपोर्टहरूमा डिभाइस विशेषका विक्रेताका अतिरिक्त लगहरू समावेश गर्नुहोस्। यी लगमा निजी जानकारी समावेश हुन सक्छन्, यिनले ब्याट्रीको खपत बढाउन र/वा थप भण्डारण प्रयोग गर्न सक्छन्।"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"एक दिनपछि अफ गर्नुहोस्"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Verbose भेन्डर लगिङ अन्त्य भएको छ"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"एक दिनका लागि अन गरियो"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"थप एक दिनका लागि अन गर्नुहोस्"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"एक दिनपछि अफ हुन्छ"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"अनिश्चितकालीन रूपमा अन गरियो"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"विन्डो एनिमेसन स्केल"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"संक्रमण एनिमेसन स्केल"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"एनिमेसनको अवधि मापन"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"तोकिएको नियमको ख्याल नगरी एपलाई बाह्य भण्डारणमा चल्ने बनाउनुहोस्"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"बलपूर्वक एपहरूको आकार मिलाउन मिल्ने बनाउनुहोस्"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"तोकिएको नियमको ख्याल नगरी एपलाई एकभन्दा बढी विन्डोमा रिसाइज गर्न सकिने बनाउनुहोस्।"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"फ्रिफर्म विन्डोहरू अन गर्नुहोस्"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"प्रयोगात्मक फ्रिफर्म विन्डोहरू चल्ने बनाउनुहोस्"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"फ्रिफर्म विन्डोहरू अन गर्नुहोस् (लिगेसी)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"प्रयोगात्मक लिगेसी फ्रिफर्म विन्डोहरू चल्ने बनाउनुहोस्"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"डेस्कटप ब्याकअप पासवर्ड"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"हाल डेस्कटपका सबै ब्याकअप पासवर्ड सुरक्षित छैनन्"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"डेस्कटप पूर्ण ब्याकअपको लागि पासवर्ड बदल्न वा हटाउन ट्याप गर्नुहोस्"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 9e0088f1b1d0..8577f4853b23 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Sta laden van GPU-foutopsporingslagen toe voor foutopsporingsapps"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Uitgebreide leverancierslogboeken aanzetten"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Neem aanvullende apparaatspecifieke leverancierslogboeken op in bugrapporten. Deze kunnen privégegevens bevatten, meer batterijlading gebruiken en/of meer opslagruimte gebruiken"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Uitzetten na één dag"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Uitgebreide leverancierslogboekregistratie is beëindigd"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Aangezet voor één dag"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Aanzetten voor nog één dag"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Wordt uitgezet na één dag"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Aangezet voor onbepaalde tijd"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Venster­animatieschaal"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Overgangs­animatieschaal"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Duur van animatieschaal"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Hiermee komt elke app in aanmerking voor schrijven naar externe opslag, ongeacht de manifestwaarden"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Formaat activiteiten geforceerd aanpasbaar maken"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Maak het formaat van alle activiteiten aanpasbaar, ongeacht de manifestwaarden"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Vensters met vrije vorm aanzetten"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Zet ondersteuning voor vensters met experimentele vrije vorm aan"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Vensters met vrije vorm aanzetten (verouderd)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Zet ondersteuning voor verouderde vensters met experimentele vrije vorm aan."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Wachtwoord desktopback-up"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Volledige back-ups naar desktops zijn momenteel niet beveiligd"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tik om het wachtwoord voor volledige back-ups naar desktops te wijzigen of te verwijderen"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 8d4e5cc8cf8f..9fdb99b64bb7 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ଡିବଗ୍‌ ଆପ୍‌ଗୁଡ଼ିକ ପାଇଁ GPU ଡିବଗ୍‌ ଲେୟର୍‌ ଲୋଡ୍ କରିବାର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ଭର୍ବୋସ ଭେଣ୍ଡର୍ ଲଗିଂ ସକ୍ଷମ କରନ୍ତୁ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ବଗ୍ ରିପୋର୍ଟଗୁଡ଼ିକରେ ଅତିରିକ୍ତ ଡିଭାଇସ୍-ନିର୍ଦ୍ଦିଷ୍ଟ ଲଗଗୁଡ଼ିକ ସାମିଲ କରନ୍ତୁ, ଯେଉଁଥିରେ ବ୍ୟକ୍ତିଗତ ସୂଚନା ଥାଇପାରେ, ଯାହା ଅଧିକ ବ୍ୟାଟେରୀ ଏବଂ/କିମ୍ବା ଅଧିକ ଷ୍ଟୋରେଜ୍ ବ୍ୟବହାର କରିପାରେ।"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"ଗୋଟିଏ ଦିନ ପରେ ଅକ୍ଷମ କରନ୍ତୁ"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"ଭର୍ବୋସ ଭେଣ୍ଡର ଲଗିଂ ସମାପ୍ତ ହୋଇଯାଇଛି"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"ଗୋଟିଏ ଦିନ ପାଇଁ ସକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"ଆଉ ଗୋଟିଏ ଦିନ ପାଇଁ ସକ୍ଷମ କରନ୍ତୁ"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"ଗୋଟିଏ ଦିନ ପରେ ଅକ୍ଷମ ହେବ"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"ଅନିର୍ଦ୍ଦିଷ୍ଟ ସମୟ ପାଇଁ ସକ୍ଷମ କରାଯାଇଛି"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"ୱିଣ୍ଡୋ ଆନିମେସନ୍‌ ସ୍କେଲ୍‌"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ଟ୍ରାଞ୍ଜିସନ୍‌ ଆନିମେସନ୍‌ ସ୍କେଲ୍‌"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ଆନିମେଟର୍‌ ଅବଧି ସ୍କେଲ୍‌"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"ଯେକୌଣସି ଆପ୍‌କୁ ଏକ୍ସଟର୍ନଲ୍ ଷ୍ଟୋରେଜ୍‌ରେ ଲେଖାଯୋଗ୍ୟ କରନ୍ତୁ, ମେନିଫେଷ୍ଟ ମୂଲ୍ୟ ଯାହା ହୋଇଥାଉ ନା କାହିଁକି"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"ୱିଣ୍ଡୋ ହିସାବରେ କାର୍ଯ୍ୟକଳାପର ଆକାର ବଦଳାନ୍ତୁ"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"ମାନିଫେଷ୍ଟ ମୂଲ୍ୟ ଯାହା ହୋଇଥାଉ ନା କାହିଁକି, ଏକାଧିକ-ୱିଣ୍ଡୋ ପାଇଁ ସମସ୍ତ କାର୍ଯ୍ୟକଳାପକୁ ରିସାଇଜ କରନ୍ତୁ।"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"ଫ୍ରିଫର୍ମ ୱିଣ୍ଡୋକୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ପରୀକ୍ଷାମୂଳକ ଫ୍ରିଫର୍ମ ୱିଣ୍ଡୋଗୁଡ଼ିକ ପାଇଁ ସପୋର୍ଟକୁ ସକ୍ଷମ କରନ୍ତୁ।"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"ଫ୍ରିଫର୍ମ ୱିଣ୍ଡୋ ସକ୍ଷମ କରନ୍ତୁ (ଲିଗାସି)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"ପରୀକ୍ଷାମୂଳକ ଲିଗାସି ଫ୍ରିଫର୍ମ ୱିଣ୍ଡୋ ପାଇଁ ସପୋର୍ଟ ସକ୍ଷମ କରନ୍ତୁ।"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ଡେସ୍କଟପ ବେକଅପ ପାସୱାର୍ଡ"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ଡେସ୍କଟପ୍‌ର ସମ୍ପୂର୍ଣ୍ଣ ବ୍ୟାକଅପ୍‌ଗୁଡ଼ିକ ବର୍ତ୍ତମାନ ସୁରକ୍ଷିତ ନୁହେଁ"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ଡେସ୍କଟପ୍‌ର ସମ୍ପୂର୍ଣ୍ଣ ବ୍ୟାକ୍‌ଅପ୍‌ ପାଇଁ ପାସ୍‌ୱର୍ଡ ବଦଳାଇବା କିମ୍ୱା କାଢ଼ିଦେବା ନିମନ୍ତେ ଟାପ୍‌ କରନ୍ତୁ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 4091f9bc4ee5..64981a7a1dec 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -407,19 +407,13 @@
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"GPU ਡੀਬੱਗ ਤਹਿਆਂ ਚਾਲੂ ਕਰੋ"</string>
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ਡੀਬੱਗ ਐਪਾਂ ਲਈ GPU ਡੀਬੱਗ ਤਹਿਆਂ ਨੂੰ ਲੋਡ ਹੋਣ ਦਿਓ"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ਵਰਬੋਸ ਵਿਕਰੇਤਾ ਲੌਗਿੰਗ ਚਾਲੂ ਕਰੋ"</string>
- <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ਬੱਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਵਧੀਕ ਡੀਵਾਈਸ ਨਾਲ ਸੰਬੰਧਿਤ ਵਿਕਰੇਤਾ ਲੌਗ ਸ਼ਾਮਲ ਕਰੋ, ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਨਿੱਜੀ ਜਾਣਕਾਰੀ, ਬੈਟਰੀ ਦੀ ਵਧੇਰੇ ਵਰਤੋਂ, ਅਤੇ/ਜਾਂ ਵਧੇਰੀ ਸਟੋਰੇਜ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ।"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ਬੱਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਵਧੀਕ ਡੀਵਾਈਸ ਮੁਤਾਬਕ ਵਿਕਰੇਤਾ ਲੌਗ ਸ਼ਾਮਲ ਕਰੋ, ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਪ੍ਰਾਈਵੇਟ ਜਾਣਕਾਰੀ, ਬੈਟਰੀ ਦੀ ਵਧੇਰੇ ਵਰਤੋਂ ਅਤੇ/ਜਾਂ ਜ਼ਿਆਦਾ ਸਟੋਰੇਜ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ।"</string>
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"ਇੱਕ ਦਿਨ ਬਾਅਦ ਬੰਦ ਕਰੋ"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"ਵਰਬੋਸ ਵਿਕਰੇਤਾ ਲੌਗਿੰਗ ਸਮਾਪਤ ਹੋ ਗਈ ਹੈ"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"ਇੱਕ ਦਿਨ ਲਈ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"ਇੱਕ ਹੋਰ ਦਿਨ ਲਈ ਚਾਲੂ ਕਰੋ"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"ਇੱਕ ਦਿਨ ਬਾਅਦ ਬੰਦ ਹੋ ਜਾਵੇਗਾ"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"ਅਣਮਿੱਥੇ ਸਮੇਂ ਲਈ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"ਵਿੰਡੋ ਐਨੀਮੇਸ਼ਨ ਸਕੇਲ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ਟ੍ਰਾਂਜ਼ਿਸ਼ਨ ਐਨੀਮੇਸ਼ਨ ਸਕੇਲ"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ਐਨੀਮੇਟਰ ਮਿਆਦ ਸਕੇਲ"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"ਮੈਨੀਫੈਸਟ ਮੁੱਲਾਂ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ, ਕਿਸੇ ਵੀ ਐਪ ਨੂੰ ਬਾਹਰੀ ਸਟੋਰੇਜ \'ਤੇ ਲਿਖਣ ਦੇ ਯੋਗ ਬਣਾਉਂਦੀ ਹੈ"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"ਸਰਗਰਮੀਆਂ ਨੂੰ ਜ਼ਬਰਦਸਤੀ ਆਕਾਰ ਬਦਲਣਯੋਗ ਬਣਾਓ"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"ਮੈਨੀਫ਼ੈਸਟ ਮੁੱਲਾਂ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ, ਮਲਟੀ-ਵਿੰਡੋ ਲਈ ਸਾਰੀਆਂ ਸਰਗਰਮੀਆਂ ਨੂੰ ਆਕਾਰ ਬਦਲਣਯੋਗ ਬਣਾਓ।"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਜ਼ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ਪ੍ਰਯੋਗਮਈ ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਜ਼ ਲਈ ਸਮਰਥਨ ਨੂੰ ਚਾਲੂ ਕਰੋ।"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਆਂ ਚਾਲੂ ਕਰੋ (ਵਿਰਾਸਤੀ)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"ਪ੍ਰਯੋਗਮਈ ਵਿਰਾਸਤੀ ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਆਂ ਲਈ ਸਹਾਇਤਾ ਚਾਲੂ ਕਰੋ।"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ਡੈਸਕਟਾਪ ਬੈਕਅੱਪ ਪਾਸਵਰਡ"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ਡੈਸਕਟਾਪ ਦੇ ਪੂਰੇ ਬੈਕਅੱਪ ਇਸ ਵੇਲੇ ਸੁਰੱਖਿਅਤ ਨਹੀਂ ਹਨ"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ਡੈਸਕਟਾਪ ਦੇ ਮੁਕੰਮਲ ਬੈਕਅੱਪਾਂ ਲਈ ਪਾਸਵਰਡ ਨੂੰ ਬਦਲਣ ਜਾਂ ਹਟਾਉਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index ef096876e802..a1ca4a6b8fcd 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Zezwalaj na ładowanie warstw debugowania GPU"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Włącz szczegółowe rejestrowanie dostawcy"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Dołączaj do raportów o błędach dodatkowe dane dostawcy dotyczące konkretnego urządzenia, które mogą zawierać dane prywatne oraz wykorzystywać więcej baterii lub pamięci"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Wyłącz po 1 dniu"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Szczegółowe rejestrowanie dostawcy zostało zakończone"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Włączone na 1 dzień"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Włącz na jeszcze 1 dzień"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Wyłączy się po 1 dniu"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Włączone bez ograniczeń czasowych"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animacji okna"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animacji przejścia"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala długości animacji"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Pozwala na zapis aplikacji w pamięci zewnętrznej niezależnie od wartości w pliku manifestu"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Wymuś zmianę rozmiaru okien aktywności"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Zezwalaj na zmianę rozmiaru wszystkich okien aktywności w trybie wielu okien niezależnie od ustawień w pliku manifestu"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Włącz dowolny rozmiar okien"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Włącz obsługę eksperymentalnej funkcji dowolnego rozmiaru okien"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Włącz dowolny rozmiar okien (starsza wersja)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Włącz obsługę eksperymentalnej funkcji dowolnego rozmiaru okien w starszej wersji"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Hasło kopii zapasowej"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Pełne kopie zapasowe na komputerze nie są obecnie chronione"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dotknij, by zmienić lub usunąć hasło pełnych kopii zapasowych na komputerze."</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index e441f058f3e1..13f9c40f329b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permitir carregamento de camadas de depuração de GPU p/ apps de depuração"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ativar registro detalhado de fornecedor"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluir mais registros de fornecedores específicos do dispositivo em relatórios de bugs. Isso pode aumentar o uso da bateria e/ou do armazenamento, e os relatórios podem conter informações particulares."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Desativar depois de 1 dia"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"O registro detalhado de fornecedor foi encerrado"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Ativado por 1 dia"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Ativar por mais 1 dia"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"É desativado depois de 1 dia"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Ativado indefinidamente"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animação da janela"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animação de transição"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duração do Animator"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Qualificar apps para gravação em armazenamento externo, independentemente dos valores do manifesto"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Forçar atividades a serem redimensionáveis"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Ativar janelas de forma livre"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ativar a compatibilidade com janelas experimentais de forma livre"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Ativar janelas de forma livre (legado)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ativar a compatibilidade com janelas experimentais legadas de forma livre."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Senha de backup local"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Os backups completos não estão protegidos no momento"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toque para alterar ou remover a senha de backups completos do desktop"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 7aed3f4ad709..260e58e0b365 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite carregamento de camadas de depuração de GPU para apps de depuração"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ativ. registo do fornecedor"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclua registos adicionais de fornecedores específicos de dispositivos em relatórios de erros, que podem conter informações privadas, utilizar mais bateria e/ou utilizar mais armazenamento."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Desativar após um dia"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"O registo verboso de fornecedor terminou"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Ativado durante um dia"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Ativar durante mais um dia"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"É desativado após um dia"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Ativado indefinidamente"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animação de transição"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animação de transição"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duração de animação"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Torna qualquer aplicação elegível para ser gravada no armazenamento externo, independentemente dos valores do manifesto"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Forçar as atividades a serem redimensionáveis"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Ativar janelas de forma livre"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ativar a compatibilidade com janelas de forma livre experimentais."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Ativar janelas de forma livre (antigo)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ativar compatibilidade com janelas de forma livre antigas experimentais."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Palavra-passe cópia do computador"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"As cópias de segurança completas no ambiente de trabalho não estão atualmente protegidas"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tocar para alterar ou remover a palavra-passe para cópias de segurança completas no ambiente de trabalho"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index e441f058f3e1..13f9c40f329b 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permitir carregamento de camadas de depuração de GPU p/ apps de depuração"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ativar registro detalhado de fornecedor"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluir mais registros de fornecedores específicos do dispositivo em relatórios de bugs. Isso pode aumentar o uso da bateria e/ou do armazenamento, e os relatórios podem conter informações particulares."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Desativar depois de 1 dia"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"O registro detalhado de fornecedor foi encerrado"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Ativado por 1 dia"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Ativar por mais 1 dia"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"É desativado depois de 1 dia"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Ativado indefinidamente"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animação da janela"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animação de transição"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duração do Animator"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Qualificar apps para gravação em armazenamento externo, independentemente dos valores do manifesto"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Forçar atividades a serem redimensionáveis"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Ativar janelas de forma livre"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ativar a compatibilidade com janelas experimentais de forma livre"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Ativar janelas de forma livre (legado)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ativar a compatibilidade com janelas experimentais legadas de forma livre."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Senha de backup local"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Os backups completos não estão protegidos no momento"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toque para alterar ou remover a senha de backups completos do desktop"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 9a79bdf5be2d..5f8f367e109b 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite încărcarea nivelurilor de depanare GPU pentru aplicațiile de depanare"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activează înregistrarea detaliată a furnizorilor"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include alte jurnale ale furnizorilor de dispozitive în rapoartele de eroare, care pot conține informații private, folosește mai multă baterie și/sau mai mult spațiu de stocare."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Dezactivează după o zi"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Înregistrarea detaliată a furnizorilor s-a încheiat"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Activată timp de o zi"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Activează timp de încă o zi"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Se dezactivează după o zi"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Activată pe termen nedefinit"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Scară animație fereastră"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Scară tranziție animații"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Scară durată Animator"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Permite scrierea oricărei aplicații eligibile în stocarea externă, indiferent de valorile manifestului"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Forțează redimensionarea activităților"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permite redimensionarea tuturor activităților pentru modul cu ferestre multiple, indiferent de valorile manifestului."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Activează ferestrele cu formă liberă"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activează compatibilitatea pentru ferestrele experimentale cu formă liberă."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Activează ferestrele cu formă liberă (vechi)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Activează compatibilitatea pentru ferestrele experimentale vechi cu formă liberă."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Parolă backup computer"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"În prezent, backupurile complete pe computer nu sunt protejate"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Atinge ca să modifici sau să elimini parola pentru backupurile complete pe desktop"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index b768cd969c64..f492b65612c5 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Включить загрузку слоев отладки графического процессора"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Подробный журнал поставщика"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Включать в информацию об ошибках дополнительные записи поставщика об устройстве, которые могут содержать личные данные и занимать больше места. Также это может увеличить расход заряда батареи."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Отключить через день"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Ведение подробного журнала поставщика завершено"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Включено на один день"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Включить ещё на один день"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Отключится через один день"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Включено без ограничения по времени"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Анимация окон"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Анимация переходов"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Длительность анимации"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Разрешить сохранение приложений на внешних накопителях (независимо от значений в манифесте)"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Изменение размера в многооконном режиме"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Разрешить изменение размера окон в многооконном режиме (независимо от значений в манифесте)"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Разрешить создание окон произвольной формы"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Включить экспериментальную функцию создания окон произвольной формы"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Разрешить окна произвольной формы (устаревшее)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Включить устаревшую экспериментальную функцию для создания окон произвольной формы"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Пароль для резервного копирования"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Полные локальные резервные копии в настоящее время не защищены"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Нажмите, чтобы изменить или удалить пароль для резервного копирования"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index e6095e80a13b..42cde8b7cc2c 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"නිදොසීමේ යෙදුම්වලට GPU නිදොසීමේ ස්තර පූරණයට ඉඩ දෙ."</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"verbose vendor පිරීම සබල කරන්න"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"පුද්ගලික තොරතුරු අන්තර්ගත විය හැකි, වැඩි බැටරි බලයක් භාවිත කිරීමට සහ/හෝ වැඩි ගබඩා ඉඩක් භාවිත කිරීමට හැකි අමතර උපාංග නිශ්චිත විකුණුම්කරු ලොග, දෝෂ වාර්තාවල අඩංගු වේ."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"එක දිනකට පසු අබල කරන්න"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"වචන බහුලකමේ විකුණුම්කරු ලොග් කිරීම නිමා වී ඇත"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"එක් දිනක් සඳහා සබල කර ඇත"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"තවත් එක් දිනක් සඳහා සබල කරන්න"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"දිනකට පසු අබල කරයි"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"දින නියමයක් නොමැතිව සබල කර ඇත"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"කවුළු සජීවිකරණ පරිමාණය"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"සංක්‍රමණ සජීවන පරිමාණය"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"සජීවක කාල පරාස පරිමාණය"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"මැනිෆෙස්ට් අගයන් නොසලකා, ඕනෑම යෙදුමක් බාහිර ගබඩාවට ලිවීමට සුදුසුකම් ලබා දෙයි"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"ක්‍රියාකාරකම් ප්‍රතිප්‍රමාණ කළ හැකි බවට බල කරන්න"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"මැනිෆෙස්ට් අගයන් නොසලකා, සියලු ක්‍රියාකාරකම් බහු-කවුළුව සඳහා ප්‍රතිප්‍රමාණ කළ හැකි බවට පත් කරන්න."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"අනියම් හැඩැති කවුළු සබල කරන්න"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"පරීක්ෂණාත්මක අනියම් හැඩැති කවුළු සඳහා සහාය සබල කරන්න."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"නිදහස් ආකෘති කවුළු සබල කරන්න (ලෙගසිය)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"පරීක්ෂණාත්මක ලෙගසි නිදහස් ආකෘති කවුළු සඳහා සහාය සබල කරන්න."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ඩෙස්ක්ටොප් උපස්ථ මුරපදය"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ඩෙස්ක්ටොප් සම්පූර්ණ උපස්ථ දැනට ආරක්ෂා කර නොමැත"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ඩෙස්ක්ටොප් සම්පූර්ණ උපස්ථ සඳහා මුරපදය වෙනස් කිරීමට හෝ ඉවත් කිරීමට තට්ටු කරන්න"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index bc09bdf24ad4..6bf0cdba4d7a 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -261,7 +261,7 @@
<string name="adb_paired_devices_title" msgid="5268997341526217362">"Spárované zariadenia"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Aktuálne pripojené"</string>
<string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Podrobnosti o zariadení"</string>
- <string name="adb_device_forget" msgid="193072400783068417">"Odstrániť"</string>
+ <string name="adb_device_forget" msgid="193072400783068417">"Zabudnúť"</string>
<string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Digitálny odtlačok zariadenia: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Pripojenie zlyhalo"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Skontrolujte, či je zariadenie <xliff:g id="DEVICE_NAME">%1$s</xliff:g> pripojené k správnej sieti"</string>
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Povoliť načítanie vrstiev ladenia grafického procesora na ladenie aplikácií"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivovať podrobný zápis dodávateľov do denníka"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Zahŕňať do hlásení chýb ďalšie denníky dodávateľa pre konkrétne zariadenie, ktoré môžu obsahovať osobné údaje, zvýšiť spotrebu batérie alebo zabrať viac ukladacieho priestoru"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Deaktivovať po jednom dni"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Podrobné zapisovanie do denníka dodávateľa bolo ukončené"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Aktivované na jeden deň"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Aktivovať ešte na deň"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Deaktivuje sa po jednom dni"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Aktivované na neurčito"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Mierka animácie okna"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Mierka animácie premeny"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Mierka dĺžky animácie"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Umožniť zapísať akúkoľvek aplikáciu do externého úložiska bez ohľadu na hodnoty v manifeste"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Vynútiť možnosť zmeny veľkosti aktivít"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Umožniť zmeniť veľkosť všetkých aktivít na niekoľko okien (bez ohľadu na hodnoty manifestu)"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Povoliť okná s voľným tvarom"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Povoliť podporu pre experimentálne okná s voľným tvarom"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Povolenie meniteľných okien (starých)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Povoľte podporu pre experimentálne staré meniteľné okná."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Heslo pre zálohy v počítači"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Úplné zálohy v počítači nie sú momentálne chránené"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Klepnutím zmeníte alebo odstránite heslo pre úplné zálohy do počítača"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 7ce5d465a3d1..869958f5ccc4 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Aplikacijam za odpravljanje napak dovoli nalaganje slojev za odpravljanje napak GPE."</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Omogoči podrobno beleženje za ponudnika"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Vključi dodatne dnevnike ponudnika, odvisne od posamezne naprave, v poročila o napakah. Takšno poročilo lahko vsebuje zasebne podatke, porabi več energije baterije in/ali več shrambe."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Onemogoči čez en dan"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Podrobno beleženje za ponudnika je končano"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Omogočeno za en dan"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Omogoči za še en dan"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Onemogočeno bo čez en dan"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Omogočeno brez časovne omejitve"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Merilo animacije okna"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Merilo animacije prehoda"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Merilo trajanja animacije"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Poskrbi, da je ne glede na vrednosti v manifestu mogoče vsako aplikacijo zapisati v zunanjo shrambo."</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Vsili spremembo velikosti za aktivnosti"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Poskrbi, da je ne glede na vrednosti v manifestu mogoče vsem aktivnostim spremeniti velikost za način z več okni."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Omogoči okna svobodne oblike"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogoči podporo za poskusna okna svobodne oblike."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Omogoči okna svobodne oblike (starejše)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Omogoči podporo za poskusna okna svobodne oblike starejše različice."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Geslo za varnostno kopijo namizja"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Popolne varnostne kopije namizja trenutno niso zaščitene."</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dotaknite se, če želite spremeniti ali odstraniti geslo za popolno varnostno kopiranje namizja"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 313fbc2a2c0d..0c1bf6cb4021 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Lejo ngarkimin e shtresave të korrigjimit të GPU-së për aplikacionet e korrigjimit"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivizo evidencat e tregtuesit me shumë fjalë"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Përfshi evidenca shtesë të treguesve specifike për pajisjen në raportet e defekteve, që mund të përfshijnë informacion privat, mund të përdorin më shumë bateri dhe/ose të përdorin më shumë hapësirë ruajtëse."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Çaktivizo pas një dite"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Evidencat e detajuara të shitësit janë mbyllur"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Aktivizuar për një ditë"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Aktivizo për një ditë më shumë"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Çaktivizohet pas një dite"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Aktivizuar për një kohë të papërcaktuar"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Animacioni i dritares"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Animacioni kalimtar"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Kohëzgjatja e animatorit"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Bën që çdo aplikacion të jetë i përshtatshëm për t\'u shkruar në hapësirën ruajtëse të jashtme, pavarësisht nga vlerat e manifestit"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Detyro madhësinë e ndryshueshme për aktivitetet"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Bëj që të gjitha aktivitetet të kenë madhësi të ndryshueshme për përdorimin me shumë dritare, pavarësisht vlerave të manifestit."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivizo dritaret me formë të lirë"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivizo mbështetjen për dritaret eksperimentale me formë të lirë."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Aktivizo dritaret me formë të lirë (të vjetra)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Aktivizo mbështetjen për dritaret eksperimentale me formë të lirë të versionit të vjetër."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Fjalëkalimi i rezervimit të desktopit"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Rezervimet e plota të desktopit nuk janë të mbrojtura aktualisht"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Trokit për të ndryshuar ose hequr fjalëkalimin për rezervime të plota të desktopit"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 217da2c56417..2b004cbac886 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Учитава отклањање грешака GPU-a у апл. за отклањање грешака"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Опширне евиденције продавца"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Уврштава у извештаје о грешкама додатне посебне евиденције продавца за уређаје, које могу да садрже приватне податке, да троше више батерије и/или да користе више меморије."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Онемогући после једног дана"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Детаљно евидентирање продавца је завршено"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Омогућено на један дан"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Омогући још један дан"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Онемогућено после једног дана"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Омогућено неограничено"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Размера анимације прозора"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Размера анимације прелаза"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Аниматорова размера трајања"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Омогућава уписивање свих апликација у спољну меморију, без обзира на вредности манифеста"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Принудно омогући промену величине активности"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Омогућава промену величине свих активности за режим са више прозора, без обзира на вредности манифеста."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Омогући прозоре произвољног формата"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Омогућава подршку за експерименталне прозоре произвољног формата."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Омогући прозоре произвољног формата (застарело)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Омогућава подршку за застареле експерименталне прозоре произвољног формата."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Лозинка резервне копије за рачунар"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Резервне копије читавог система тренутно нису заштићене"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Додирните да бисте променили или уклонили лозинку за прављење резервних копија читавог система на рачунару"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 38faa8cde5ba..06ed90e08cf0 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Tillåt att felsökningsappar läser in GPU-felsökningslager"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivera utförlig loggning för leverantörer"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Ta med ytterligare enhetsspecifika leverantörsloggar i felrapporter. Dessa kan innehålla privata uppgifter samt använda mer batteri och/eller mer lagringsutrymme."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Inaktivera efter en dag"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Utförlig leverantörsloggning har avslutats"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Aktiverat i en dag"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Aktivera i en dag till"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Inaktiveras efter en dag"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Aktiverat tills vidare"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala – fönsteranimering"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala – övergångsanimering"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Längdskala för Animator"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Allar appar kan skrivas till extern lagring, oavsett manifestvärden"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Framtvinga storleksanpassning för aktiviteter"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gör det möjligt att ändra storleken på alla aktiviteter i flerfönsterläge, oavsett manifestvärden."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivera frihandsfönster"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivera stöd för experimentella frihandsfönster."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Aktivera frihandsfönster (äldre)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Aktivera stöd för äldre experimentella frihandsfönster."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Lösenord för säkerhetskopia av datorn"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"De fullständiga säkerhetskopiorna av datorn är för närvarande inte skyddade"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tryck om du vill ändra eller ta bort lösenordet för fullständig säkerhetskopiering av datorn"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 744a79e8f4f4..08aa7840a9fc 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Ruhusu upakiaji wa safu za utatuzi wa GPU za programu za utatuzi"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Washa uwekaji kumbukumbu za muuzaji kwa kutumia sauti"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Jumuisha kumbukumbu zaidi za muuzaji ambazo ni mahususi kwa kifaa kwenye ripoti za hitilafu, ambazo huenda zikawa na maelezo ya faragha, zikatumia chaji nyingi ya betri na/au zikatumia nafasi kubwa ya hifadhi."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Zima baada ya siku moja"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Mchakato wa kuweka kumbukumbu ya kina ya muuzaji umekamilika"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Umewasha kwa siku moja"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Washa kwa siku moja zaidi"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Utazima baada ya siku moja"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Umewasha kwa muda usiojulikana"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Uhuishaji kwenye dirisha"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Mageuzi ya kipimo cha uhuishaji"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Mizani ya muda wa uhuishaji"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Huruhusu programu yoyote iwekwe kwenye hifadhi ya nje, bila kujali thamani za faili ya maelezo"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Lazimisha shughuli ziweze kubadilishwa ukubwa"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Fanya shughuli zote ziweze kubadilishwa ukubwa kwenye madirisha mengi, bila kuzingatia thamani za faili ya maelezo."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Washa madirisha yenye muundo huru"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ruhusu uwezo wa kutumia madirisha ya majaribio yenye muundo huru."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Washa madirisha yenye muundo huru (yaliyopitwa na wakati)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ruhusu matumizi ya madirisha ya majaribio yenye muundo huru yaliyopitwa na wakati."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Nenosiri la hifadhi rudufu ya eneo kazi"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Hifadhi rudufu kamili za eneo kazi hazijalindwa kwa sasa"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Gusa ili ubadilishe au uondoe nenosiri la hifadhi rudufu kamili za eneo kazi"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 113a139176bb..5972756108f4 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"பிழைத்திருத்த ஆப்ஸிற்கு, GPU பிழைத்திருத்த லேயர்களை ஏற்றுவதற்கு அனுமதி"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"வெர்போஸ் வெண்டார் பதிவை இயக்கு"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"பிழை அறிக்கைகளில் சாதனம் சார்ந்த கூடுதல் வெண்டார் பதிவுகளைச் சேர்க்கவும். அவற்றில் தனிப்பட்ட தகவல்கள், அதிக பேட்டரி உபயோகம் மற்றும்/அல்லது அதிக சேமிப்பிட உபயோகம் குறித்த தகவல்கள் இருக்கக்கூடும்."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"ஒரு நாளுக்குப் பிறகு முடக்கு"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"விற்பனையாளரின் அதிவிவரப் பதிவு முடிந்துவிட்டது"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"ஒரு நாளுக்கு இயக்கப்பட்டுள்ளது"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"இன்னும் ஒரு நாள் இயக்கு"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"ஒரு நாளுக்குப் பிறகு முடக்கப்படும்"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"காலவரம்பின்றி இயக்கப்பட்டுள்ளது"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"சாளர அனிமேஷன் வேகம்"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"அனிமேஷன் மாற்றத்தின் வேகம்"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"அனிமேட்டர் கால அளவு"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"மேனிஃபெஸ்ட் மதிப்புகளைப் பொருட்படுத்தாமல், எல்லா ஆப்ஸையும் வெளிப்புறச் சேமிப்பிடத்தில் எழுத அனுமதிக்கும்"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"செயல்பாடுகளை அளவுமாறக்கூடியதாக அமை"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"மேனிஃபெஸ்ட் மதிப்புகளைப் பொருட்படுத்தாமல், பல சாளரத்திற்கு எல்லா செயல்பாடுகளையும் அளவுமாறக்கூடியதாக அமை."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"குறிப்பிட்ட வடிவமில்லாத சாளரங்களை இயக்கு"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"சாளரங்களை அளவுமாற்ற மற்றும் எங்கும் நகர்த்த அனுமதிக்கும் பரிசோதனைக்குரிய அம்சத்திற்கான ஆதரவை இயக்கு."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"குறிப்பிட்ட வடிவமில்லாத சாளரத்தை இயக்குதல் (லெகஸி)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"பரிசோதனைக்குரிய, குறிப்பிட்ட வடிவமில்லாத பழைய சாளரங்களுக்கான ஆதரவை இயக்குதல்."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"டெஸ்க்டாப் காப்புப்பிரதி கடவுச்சொல்"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"டெஸ்க்டாப்பின் முழு காப்புப்பிரதிகள் தற்போது பாதுகாக்கப்படவில்லை"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"டெஸ்க்டாப்பின் முழுக் காப்புப் பிரதிகளுக்கான கடவுச்சொல்லை மாற்ற அல்லது அகற்ற, தட்டவும்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 83f2faaab9c8..1df1823ea01b 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"డీబగ్ యాప్‌ల కోసం GPU డీబగ్ లేయర్‌లను లోడ్ చేయడాన్ని అనుమతించండి"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"వివరణాత్మక వెండార్‌ లాగింగ్‌ను ఎనేబుల్ చేయండి"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"బగ్ రిపోర్ట్‌లలో అదనపు పరికర-నిర్దిష్ట వెండార్ లాగ్‌లను చేర్చండి, అవి ప్రైవేట్ సమాచారాన్ని కలిగి ఉండవచ్చు, మరింత బ్యాటరీని, మరియు/లేదా మరింత స్టోరేజ్‌ను ఉపయోగించవచ్చు."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"ఒక రోజు తర్వాత డిజేబుల్ చేయండి"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"వెర్బోస్ వెండర్ లాగింగ్ ముగిసింది"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"ఒక రోజు పాటు ఎనేబుల్ చేసి ఉంది"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"ఇంకొక రోజు ఎనేబుల్ చేసి ఉంచండి"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"ఒక రోజు తర్వాత డిజేబుల్ అవుతుంది"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"నిరవధికంగా ఎనేబుల్ చేయబడింది"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"విండో యానిమేషన్ స్కేల్"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ట్రాన్సిషన్ యానిమేషన్ స్కేల్"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"యానిమేటర్ వ్యవధి స్కేల్"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"ఏ యాప్‌ను అయినా మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా బాహ్య స్టోరేజ్‌లో సేవ్ చేయడానికి అనుమతిస్తుంది"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"యాక్టివిటీ విండోల సైజ్‌ మార్చ‌గ‌లిగేలా నిర్బంధించు"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా అన్ని యాక్టివిటీస్‌ను పలు రకాల విండోల్లో సరిపోయేటట్లు సైజ్‌ మార్చగలిగేలా చేస్తుంది."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"స్వతంత్ర రూప విండోలను ఎనేబుల్ చేయండి"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ప్రయోగాత్మక స్వతంత్ర రూప విండోల కోసం సపోర్ట్‌ను ఎనేబుల్ చేస్తుంది."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"ఫ్రీఫార్మ్ విండోలను ఎనేబుల్ చేయండి (లెగసీ)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"ప్రయోగాత్మక లెగసీ ఫ్రీఫార్మ్ విండోలకు సంబంధించిన సపోర్ట్‌ను ఎనేబుల్ చేయండి."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"డెస్క్‌టాప్ బ్యాకప్ పాస్‌వర్డ్"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"డెస్క్‌టాప్ పూర్తి బ్యాకప్‌లు ప్రస్తుతం రక్షించబడలేదు"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"డెస్క్‌టాప్ పూర్తి బ్యాకప్‌ల కోసం పాస్‌వర్డ్‌ను మార్చడానికి లేదా తీసివేయడానికి నొక్కండి"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index ef315924465d..c26f02d8636b 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"อนุญาตให้โหลดเลเยอร์การแก้ไขข้อบกพร่อง GPU สำหรับแอปแก้ไขข้อบกพร่อง"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"เปิดการบันทึกเวนเดอร์แบบละเอียด"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"รวมบันทึกเวนเดอร์เพิ่มเติมเฉพาะอุปกรณ์ไว้ในรายงานข้อบกพร่อง ซึ่งอาจมีข้อมูลส่วนตัว ใช้แบตเตอรี่มากขึ้น และ/หรือใช้พื้นที่เก็บข้อมูลมากขึ้น"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"ปิดใช้หลังจากผ่านไป 1 วัน"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"การบันทึกข้อมูลเวนเดอร์แบบละเอียดสิ้นสุดแล้ว"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"เปิดใช้อีก 1 วันแล้ว"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"เปิดใช้อีก 1 วัน"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"ปิดใช้หลังจากผ่านไป 1 วัน"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"เปิดใช้แบบไม่มีกำหนดสิ้นสุดแล้ว"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"อัตราการเคลื่อนไหวของหน้าต่าง"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"อัตราการเคลื่อนไหวของการเปลี่ยนภาพ"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"อัตราความเร็วตามตัวสร้างภาพเคลื่อนไหว"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"ทำให้เขียนแอปในที่จัดเก็บข้อมูลภายนอกได้ โดยไม่คำนึงถึงค่าในไฟล์ Manifest"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"บังคับให้กิจกรรมปรับขนาดได้"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"ทำให้กิจกรรมทั้งหมดปรับขนาดได้สำหรับหน้าต่างหลายบาน โดยไม่คำนึงถึงค่าในไฟล์ Manifest"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"เปิดใช้หน้าต่างรูปแบบอิสระ"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"เปิดการสนับสนุนหน้าต่างรูปแบบอิสระแบบทดลอง"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"เปิดใช้หน้าต่างรูปแบบอิสระ (แบบเดิม)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"เปิดใช้การรองรับหน้าต่างรูปแบบอิสระแบบเดิมเวอร์ชันทดลอง"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"รหัสผ่านการสำรองข้อมูลในเดสก์ท็อป"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"การสำรองข้อมูลเต็มรูปแบบในเดสก์ท็อปไม่ได้รับการป้องกันในขณะนี้"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"แตะเพื่อเปลี่ยนแปลงหรือลบรหัสผ่านสำหรับการสำรองข้อมูลเต็มรูปแบบในเดสก์ท็อป"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 90acd6fa0647..1c038f6a8742 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Payagang i-load ang GPU debug layer sa debug app"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"I-enable ang verbose vendor logging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Magsama sa mga ulat ng bug ng mga karagdagang log ng vendor na partikular sa device, na posibleng may pribadong impormasyon, gumamit ng mas maraming baterya, at/o gumamit ng mas malaking storage."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"I-disable pagkalipas ng isang araw"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Tapos na ang verbose vendor logging"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Naka-enable para sa isang araw"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"I-enable para sa isa pang araw"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Magdi-disable pagkalipas ng isang araw"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Naka-enable nang walang katapusan"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Scale ng window animation"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Scale ng transition animation"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Scale ng tagal ng animator"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Ginagawang kwalipikado ang anumang app na mailagay sa external na storage, anuman ang mga value ng manifest"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Sapilitang gawing resizable ang mga aktibidad"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gawing nare-resize ang lahat ng aktibidad para sa multi-window, anuman ang mga value ng manifest."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"I-enable ang mga freeform window"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"I-enable ang suporta para sa mga pang-eksperimentong freeform window."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"I-enable ang mga freeform window (legacy)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"I-enable ang suporta para sa mga pang-eksperimentong legacy na freeform window."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Password ng pag-backup ng desktop"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Kasalukuyang hindi pinoprotektahan ang mga buong pag-backup ng desktop"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"I-tap upang baguhin o alisin ang password para sa mga kumpletong pag-back up sa desktop"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index a30c3ee5c24d..79ace3f79986 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Hata ayıklama uygulamaları için GPU hata ayıklama katmanlarının yüklenmesine izin ver"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ayrıntılı satıcı günlüğünü etkinleştir"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Hata raporlarına cihaza özgü ek satıcı günlükleri ekle. Bu günlükler gizli bilgiler içerebilir, daha fazla pil ve/veya daha fazla depolama alanı kullanabilir."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"1 gün sonra devre dışı bırak"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Ayrıntılı satıcı günlüğü sona erdi"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"1 günlüğüne etkinleştirildi"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"1 gün daha etkinleştir"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"1 gün sonra devre dışı bırakılır"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Süresiz olarak etkinleştirildi"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Pencere animasyonu ölçeği"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Geçiş animasyonu ölçeği"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatör süre ölçeği"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Manifest değerlerinden bağımsız olarak uygulamaları harici depolamaya yazmak için uygun hale getirir"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Etkinlikleri yeniden boyutlandırılabilmeye zorla"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Manifest değerlerinden bağımsız olarak, tüm etkinlikleri birden fazla pencerede yeniden boyutlandırılabilir yap."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Serbest biçimli pencereleri etkinleştir"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Deneysel serbest biçimli pencere desteğini etkinleştir."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Serbest biçimli pencereleri (eski) etkinleştir"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Deneysel eski serbest biçimli pencere desteğini etkinleştir."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Masaüstü yedekleme şifresi"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Masaüstü tam yedeklemeleri şu an korunmuyor"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Masaüstü tam yedeklemelerinin şifresini değiştirmek veya kaldırmak için dokunun"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index c94e745bfcd4..de416d2f7db8 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Дозволити завантажувати шари налагодження ГП для додатків налагодження"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Увімкнути докладний журнал постачальника"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Включати у звіти про помилки додаткові записи постачальника про пристрій, які можуть містити особисті дані, призводити до надмірного споживання заряду акумулятора та/або використовувати більший обсяг пам\'яті."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Вимкнути через один день"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Ведення детального журналу постачальника завершено"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Увімкнено на один день"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Увімкнути ще на один день"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Вимикається через один день"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Увімкнено на необмежений час"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Анімація вікон"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Анімація переходів"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Тривалість анімації"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Можна записувати додатки в зовнішню пам’ять, незалежно від значень у маніфесті"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Примусово масштабувати активність"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Масштабувати активність на кілька вікон, незалежно від значень у файлі маніфесту."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Увімкнути вікна довільного формату"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Увімкнути експериментальні вікна довільного формату."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Увімкнути старий формат вікон змінного розміру"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Увімкнути підтримку експериментального старого формату вікон змінного розміру."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Пароль рез. копії на ПК"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Повні резервні копії на комп’ютері наразі не захищені"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Торкніться, щоб змінити або видалити пароль для повного резервного копіювання на комп’ютер"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 3d2c89c26fa3..309283266417 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"‏ڈیبگ ایپس کیلئے GPU ڈیبگ پرتوں کو لوڈ کرنے دیں"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"وربوس وینڈر لاگنگ فعال کریں"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"اضافی آلہ کے مخصوص وینڈر لاگز کو بگ رپورٹس میں شامل کریں، جن میں نجی معلومات، بیٹری کا زیادہ استعمال اور/یا اسٹوریج کا زیادہ استعمال شامل ہوسکتے ہیں۔"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"ایک دن کے بعد غیر فعال کریں"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"وربوس وینڈر لاگنگ بند ہو گیا ہے"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"ایک دن کے لئے فعال ہو گیا"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"ایک اور دن کے لئے فعال کریں"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"ایک دن کے بعد غیر فعال ہو جائے گا"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"غیر معینہ مدت کے لئے فعال کر دیا گیا"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"ونڈو اینیمیشن اسکیل"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ٹرانزیشن اینیمیشن اسکیل"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"اینیمیٹر دورانیے کا اسکیل"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"‏manifest اقدار سے قطع نظر، کسی بھی ایپ کو بیرونی اسٹوریج پر لکھے جانے کا اہل بناتا ہے"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"سرگرمیوں کو ری سائز ایبل بنائیں"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"مینی فیسٹ اقدار سے قطع نظر، ملٹی ونڈو کیلئے تمام سرگرمیوں کو ری سائز ایبل بنائیں۔"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"‏freeform ونڈوز فعال کریں"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"تجرباتی فری فارم ونڈوز کیلئے سپورٹ فعال کریں۔"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"‏فریفارم ونڈوز کو فعال کریں (legacy)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"‏تجرباتی legacy فری فارم ونڈوز کیلئے سپورٹ فعال کریں۔"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ڈیسک ٹاپ کا بیک اپ پاس ورڈ"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ڈیسک ٹاپ کے مکمل بیک اپس فی الحال محفوظ کیے ہوئے نہیں ہیں"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ڈیسک ٹاپ کے مکمل بیک اپس کیلئے پاس ورڈ کو تبدیل کرنے یا ہٹانے کیلئے تھپتھپائیں"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 93ffac82a583..7502412b2d92 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Grafik protsessorni tuzatish qatlamlarini yuklashni yoqish"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Taʼminotchining batafsil jurnali"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Xatoliklar hisobotiga shaxsiy maʼlumotlari bor va koʻp joy olishi mumkin boʻlgan qurilma haqida taʼminotchining qoʻshimcha yozuvlari kiradi. Bunda batareya quvvati tezroq sarflanishi mumkin."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Bir kundan keyin faolsizlantirish"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Taʼminotchi tafsilotlarini qayd qilish tugadi"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Bir kunga yoqilgan"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Yana bir kunga yoqish"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Bir kundan keyin faolsizlantiriladi"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Oʻchirilmaguncha yoqilgan"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Oynalar animatsiyasi"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"O‘tish animatsiyasi"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatsiya tezligi"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Manifest qiymatidan qat’i nazar istalgan ilovani tashqi xotiraga saqlash imkonini beradi"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Harakatlarni moslashuvchan o‘lchamga keltirish"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Manifest qiymatidan qat’i nazar barcha harakatlarni ko‘p oynali rejimga moslashtirish."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Erkin shakldagi oynalarni yoqish"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Erkin shakldagi oynalar yaratish uchun mo‘ljallangan tajribaviy funksiyani yoqish."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Erkin shakldagi oynalarni (eskirgan) yoqish"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Eskirgan erkin shakldagi oynalar yaratish uchun moʻljallangan tajribaviy funksiyani yoqish."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Zaxira nusxa uchun parol"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Kompyuterdagi zaxira nusxalar hozirgi vaqtda himoyalanmagan"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ish stoli to‘liq zaxira nusxalari parolini o‘zgartirish yoki o‘chirish uchun bu yerni bosing"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 414ad37bf072..02f0aa1c7227 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Cho phép tải lớp gỡ lỗi GPU cho ứng dụng gỡ lỗi"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Bật tùy chọn ghi nhật ký chi tiết của nhà cung cấp"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Đưa thêm nhật ký của nhà cung cấp dành riêng cho thiết bị vào các báo cáo lỗi. Nhật ký này có thể chứa thông tin cá nhân, dùng nhiều pin hơn và/hoặc chiếm nhiều dung lượng lưu trữ hơn."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Tắt sau một ngày"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Quá trình ghi nhật ký chi tiết của nhà cung cấp đã kết thúc"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Đã bật trong một ngày"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Bật thêm một ngày nữa"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Tắt sau một ngày"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Đã bật vô thời hạn"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Tỷ lệ hình động của cửa sổ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Tỷ lệ hình động chuyển tiếp"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Tỷ lệ thời lượng của trình tạo hình động"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Cho phép ghi mọi ứng dụng đủ điều kiện vào bộ nhớ ngoài, bất kể giá trị tệp kê khai là gì"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Buộc các hoạt động có thể thay đổi kích thước"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Cho phép thay đổi kích thước của tất cả các hoạt động cho nhiều cửa sổ, bất kể giá trị tệp kê khai là gì."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Bật cửa sổ dạng tự do"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Bật tính năng hỗ trợ cửa sổ dạng tự do thử nghiệm."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Bật cửa sổ có thể đổi kích thước (cũ)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Bật tính năng hỗ trợ cửa sổ có thể đổi kích thước thử nghiệm (cũ)."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Mật khẩu cho bản sao lưu qua máy tính"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Các bản sao lưu đầy đủ qua máy tính hiện không được bảo vệ"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Nhấn để thay đổi hoặc xóa mật khẩu dành cho các bản sao lưu đầy đủ vào máy tính"</string>
@@ -575,7 +569,7 @@
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Không bao giờ"</string>
<string name="zen_interruption_level_priority" msgid="5392140786447823299">"Chỉ cho các mục ưu tiên"</string>
<string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <string name="zen_alarm_warning_indef" msgid="4146527909616457163">"Bạn sẽ không nghe thấy báo thức tiếp theo lúc <xliff:g id="WHEN">%1$s</xliff:g> của mình trừ khi bạn tắt chức năng này trước"</string>
+ <string name="zen_alarm_warning_indef" msgid="4146527909616457163">"Bạn sẽ không nghe thấy báo thức tiếp theo lúc <xliff:g id="WHEN">%1$s</xliff:g> của mình trừ phi bạn tắt chức năng này trước"</string>
<string name="zen_alarm_warning" msgid="245729928048586280">"Bạn sẽ không nghe thấy báo thức tiếp theo lúc <xliff:g id="WHEN">%1$s</xliff:g> của mình"</string>
<string name="alarm_template" msgid="3346777418136233330">"lúc <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template_far" msgid="6382760514842998629">"vào <xliff:g id="WHEN">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index c0a8f2d51c31..a551121e0922 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"允许为调试应用加载 GPU 调试层"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"启用详细供应商日志记录"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"在 bug 报告中包含其他设备特定的供应商日志,这些日志可能会含有隐私信息、消耗更多电量和/或使用更多存储空间。"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"一天后停用"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"详细供应商日志记录已结束"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"已启用一天"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"再启用一天"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"一天后停用"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"已无限期启用"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"窗口动画缩放"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"过渡动画缩放"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 时长缩放"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"允许将任何应用写入外部存储设备(无论清单值是什么)"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"强制将 activity 设为可调整大小"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"将所有 activity 设为可配合多窗口环境调整大小(无论清单值是什么)。"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"启用可自由调整的窗口"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"启用可自由调整的窗口这一实验性功能。"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"启用可自由调整的窗口(旧版)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"实现对实验性旧版可自由调整的窗口的支持。"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"桌面备份密码"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"桌面完整备份当前未设置密码保护"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"点按即可更改或移除用于保护桌面完整备份的密码"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 74f2678b1cce..6f8c537dafeb 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"允許為偵錯應用程式載入 GPU 偵錯圖層"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"啟用詳細供應商記錄"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"在錯誤報告中加入其他裝置專屬供應商記錄,其中可能包含私人資料,並會耗用更多電量及/或儲存空間。"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"在一天後停用"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"詳細供應商記錄已結束"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"已啟用一天"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"啟用多一天"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"在一天後停用"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"已無限期啟用"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"視窗動畫比例"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"轉場動畫比例"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 片長比例"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"在任何資訊清單值下,允許將所有符合資格的應用程式寫入到外部儲存完間"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"強制將活動設為可調整尺寸"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"在任何資訊清單值下,允許系統配合多重視窗環境調整所有活動的尺寸。"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"啟用自由形態視窗"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"啟用實驗版自由形態視窗的支援功能。"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"啟用自由形態視窗 (舊的)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"啟用舊的實驗版自由形態視窗的支援功能。"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"桌面電腦備份密碼"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"桌面電腦的完整備份目前未受保護"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"輕按即可變更或移除桌面電腦完整備份的密碼"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 5b068e35daa1..2806b0262356 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"允許載入 GPU 偵錯圖層為應用程式偵錯"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"啟用詳細供應商記錄功能"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"在錯誤報告中附上其他的裝置專屬供應商記錄。如果你這麼做,可能會增加電池用量及/或占用較多儲存空間,報告中可能也會包含私人資訊。"</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"一天後停用"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"已停用詳細供應商記錄功能"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"已啟用一天"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"再啟用一天"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"一天後停用"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"已無限期啟用"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"視窗動畫比例"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"轉場動畫比例"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"動畫影片長度比例"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"允許將任何應用程式寫入外部儲存空間 (無論資訊清單值為何)"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"將活動強制設為可調整大小"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"將所有活動設為可配合多重視窗環境調整大小 (無論資訊清單值為何)。"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"啟用自由形式視窗"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"啟用實驗版自由形式視窗的支援功能。"</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"啟用自由形式視窗 (舊版)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"啟用實驗性舊版自由形式視窗支援功能。"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"電腦備份密碼"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"尚未設定密碼保護電腦的完整備份"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"輕觸即可變更或移除電腦完整備份的密碼"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index da152cefaf49..570c4243f944 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -408,18 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Vumela izendlalelo zokususa amaphutha ze-GPU ngezinhlelo zokusebenza zokususa amaphutha"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Nika amandla ilogu yomthengisi we-verbose"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Faka phakathi amalogu athize womthengisi wedivayisi angeziwe, angase afake phakathi ulwazi oluyimfihlo, kusebenzisa ibhethri eningi, futhi/noma kusebenzisa isitoreji esiningi."</string>
- <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
- <skip />
- <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
- <skip />
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Khubaza ngemva kosuku olulodwa"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Ukungena komthengisi weverbose kuphelile"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Nika amandla usuku olulodwa"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Nika amandla usuku olulodwa olwengeziwe"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Khubaza ngemva kosuku olulodwa"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Kunikwe amandla isikhathi esinganqunyiwe"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Iwindi yesilinganisi sesithombe esinyakazayo"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Isilinganiso sesithombe soku"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Isilinganiso sobude besikhathi somenzi womfanekiso onyakazayo"</string>
@@ -436,8 +430,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Yenza noma uluphi uhlelo lokusebenza lifaneleke ukuthi libhalwe kusitoreji sangaphandle, ngaphandle kwamavelu we-manifest"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Imisebenzi yamandla izonikezwa usayizi omusha"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Yenza yonke imisebenzi ibe nosayizi abasha kumawindi amaningi, ngokunganaki amavelu e-manifest."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Nika amandla amawindi e-freeform"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Nika amandla usekelo lwe-windows yokuhlola kwe-freeform."</string>
+ <string name="enable_freeform_support" msgid="8409932201445109106">"Vumela amawindi efreeform (ifa)"</string>
+ <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Nika amandla amawindi efreeform efa elisahlolwa."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Iphasiwedi yokusekela ngokulondoloza ye-Desktop"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Ukusekela ngokulondoloza okugcwele kwe-Desktop akuvikelekile okwamanje."</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Thepha ukushintsha noma ukususa iphasiwedi yokwenziwa kwezipele ngokugcwele kwideskithophu"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 734b92c7ac6e..6ca9279de8c6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -38,8 +38,6 @@ import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
-import com.android.settingslib.utils.BuildCompatUtils;
-
/**
* Helper class for managing settings preferences that can be disabled
* by device admins via user restrictions.
@@ -120,9 +118,10 @@ public class RestrictedPreferenceHelper {
if (mDisabledSummary) {
final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
if (summaryView != null) {
- final CharSequence disabledText = BuildCompatUtils.isAtLeastT()
- ? getDisabledByAdminUpdatableString()
- : mContext.getString(R.string.disabled_by_admin_summary_text);
+ final CharSequence disabledText =
+ (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
+ ? getDisabledByAdminUpdatableString()
+ : mContext.getString(R.string.disabled_by_admin_summary_text);
if (mDisabledByAdmin) {
summaryView.setText(disabledText);
} else if (mDisabledByEcm) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index 45754eb8f16d..fffbb547c662 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -25,6 +25,7 @@ import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.res.TypedArray;
+import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import android.util.AttributeSet;
@@ -40,8 +41,6 @@ import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreferenceCompat;
-import com.android.settingslib.utils.BuildCompatUtils;
-
/**
* Version of SwitchPreferenceCompat that can be disabled by a device admin
* using a user restriction.
@@ -164,7 +163,7 @@ public class RestrictedSwitchPreference extends SwitchPreferenceCompat {
private static String getUpdatableEnterpriseString(
Context context, String updatableStringId, int resId) {
- if (!BuildCompatUtils.isAtLeastT()) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
return context.getString(resId);
}
return context.getSystemService(DevicePolicyManager.class).getResources().getString(
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index c2506d353d14..b02b0c454644 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -66,7 +66,6 @@ import com.android.launcher3.util.UserIconInfo;
import com.android.settingslib.drawable.UserIconDrawable;
import com.android.settingslib.fuelgauge.BatteryStatus;
import com.android.settingslib.fuelgauge.BatteryUtils;
-import com.android.settingslib.utils.BuildCompatUtils;
import java.util.List;
@@ -147,7 +146,7 @@ public class Utils {
String name = info != null ? info.name : null;
if (info.isManagedProfile()) {
// We use predefined values for managed profiles
- return BuildCompatUtils.isAtLeastT()
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
? getUpdatableManagedUserTitle(context)
: context.getString(R.string.managed_user_title);
} else if (info.isGuest()) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManagerExt.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManagerExt.kt
new file mode 100644
index 000000000000..2eaa804152e4
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManagerExt.kt
@@ -0,0 +1,39 @@
+/*
+ * 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.settingslib.bluetooth
+
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.launch
+
+/** [Flow] for [BluetoothCallback] device profile connection state change events */
+val BluetoothEventManager.onProfileConnectionStateChanged: Flow<ProfileConnectionState>
+ get() = callbackFlow {
+ val callback =
+ object : BluetoothCallback {
+ override fun onProfileConnectionStateChanged(
+ cachedDevice: CachedBluetoothDevice,
+ @BluetoothCallback.ConnectionState state: Int,
+ bluetoothProfile: Int
+ ) {
+ launch { send(ProfileConnectionState(cachedDevice, state, bluetoothProfile)) }
+ }
+ }
+ registerCallback(callback)
+ awaitClose { unregisterCallback(callback) }
+ }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 721e7b93fd32..53441c08776f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -24,6 +24,7 @@ import android.media.AudioManager;
import android.net.Uri;
import android.provider.DeviceConfig;
import android.provider.MediaStore;
+import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -808,7 +809,8 @@ public class BluetoothUtils {
* <p>If CachedBluetoothDevice#getGroupId is invalid, fetch group id from
* LeAudioProfile#getGroupId.
*/
- public static int getGroupId(@NonNull CachedBluetoothDevice cachedDevice) {
+ public static int getGroupId(@Nullable CachedBluetoothDevice cachedDevice) {
+ if (cachedDevice == null) return BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
int groupId = cachedDevice.getGroupId();
String anonymizedAddress = cachedDevice.getDevice().getAnonymizedAddress();
if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
@@ -824,4 +826,44 @@ public class BluetoothUtils {
Log.d(TAG, "getGroupId return invalid id for device: " + anonymizedAddress);
return BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
}
+
+ /** Get primary device Uri in broadcast. */
+ @NonNull
+ public static String getPrimaryGroupIdUriForBroadcast() {
+ return "bluetooth_le_broadcast_fallback_active_group_id";
+ }
+
+ /** Get primary device group id in broadcast. */
+ @WorkerThread
+ public static int getPrimaryGroupIdForBroadcast(@NonNull Context context) {
+ return Settings.Secure.getInt(
+ context.getContentResolver(),
+ getPrimaryGroupIdUriForBroadcast(),
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
+ }
+
+ /** Get secondary {@link CachedBluetoothDevice} in broadcast. */
+ @Nullable
+ @WorkerThread
+ public static CachedBluetoothDevice getSecondaryDeviceForBroadcast(
+ @NonNull Context context, @Nullable LocalBluetoothManager localBtManager) {
+ if (localBtManager == null) return null;
+ int primaryGroupId = getPrimaryGroupIdForBroadcast(context);
+ if (primaryGroupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) return null;
+ LocalBluetoothLeBroadcastAssistant assistant =
+ localBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile();
+ CachedBluetoothDeviceManager deviceManager = localBtManager.getCachedDeviceManager();
+ List<BluetoothDevice> devices = assistant.getAllConnectedDevices();
+ for (BluetoothDevice device : devices) {
+ CachedBluetoothDevice cachedDevice = deviceManager.findDevice(device);
+ if (hasConnectedBroadcastSource(cachedDevice, localBtManager)) {
+ int groupId = getGroupId(cachedDevice);
+ if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
+ && groupId != primaryGroupId) {
+ return cachedDevice;
+ }
+ }
+ }
+ return null;
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
index 9faebe2036d6..148e164e4806 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
@@ -389,6 +389,14 @@ public class LocalBluetoothLeBroadcastAssistant implements LocalBluetoothProfile
return mService.getDevicesMatchingConnectionStates(states);
}
+ /** Gets all connected devices on assistant profile. */
+ public List<BluetoothDevice> getAllConnectedDevices() {
+ if (mService == null) {
+ return new ArrayList<BluetoothDevice>(0);
+ }
+ return mService.getConnectedDevices();
+ }
+
public boolean isEnabled(BluetoothDevice device) {
if (mService == null || device == null) {
return false;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistantCallbackExt.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistantCallbackExt.kt
new file mode 100644
index 000000000000..91a99aed6db5
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistantCallbackExt.kt
@@ -0,0 +1,85 @@
+/*
+ * 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.settingslib.bluetooth
+
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothLeBroadcastAssistant
+import android.bluetooth.BluetoothLeBroadcastMetadata
+import android.bluetooth.BluetoothLeBroadcastReceiveState
+import com.android.internal.util.ConcurrentUtils
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.launch
+
+/** [Flow] for [BluetoothLeBroadcastAssistant.Callback] source connected/removed events */
+val LocalBluetoothLeBroadcastAssistant.onSourceConnectedOrRemoved: Flow<Unit>
+ get() = callbackFlow {
+ val callback =
+ object : BluetoothLeBroadcastAssistant.Callback {
+ override fun onReceiveStateChanged(
+ sink: BluetoothDevice,
+ sourceId: Int,
+ state: BluetoothLeBroadcastReceiveState
+ ) {
+ if (BluetoothUtils.isConnected(state)) {
+ launch { send(Unit) }
+ }
+ }
+
+ override fun onSourceRemoved(sink: BluetoothDevice, sourceId: Int, reason: Int) {
+ launch { send(Unit) }
+ }
+
+ override fun onSearchStarted(reason: Int) {}
+
+ override fun onSearchStartFailed(reason: Int) {}
+
+ override fun onSearchStopped(reason: Int) {}
+
+ override fun onSearchStopFailed(reason: Int) {}
+
+ override fun onSourceFound(source: BluetoothLeBroadcastMetadata) {}
+
+ override fun onSourceAdded(sink: BluetoothDevice, sourceId: Int, reason: Int) {}
+
+ override fun onSourceAddFailed(
+ sink: BluetoothDevice,
+ source: BluetoothLeBroadcastMetadata,
+ reason: Int
+ ) {}
+
+ override fun onSourceModified(sink: BluetoothDevice, sourceId: Int, reason: Int) {}
+
+ override fun onSourceModifyFailed(
+ sink: BluetoothDevice,
+ sourceId: Int,
+ reason: Int
+ ) {}
+
+ override fun onSourceRemoveFailed(
+ sink: BluetoothDevice,
+ sourceId: Int,
+ reason: Int
+ ) {}
+ }
+ registerServiceCallBack(
+ ConcurrentUtils.DIRECT_EXECUTOR,
+ callback,
+ )
+ awaitClose { unregisterServiceCallBack(callback) }
+ }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/ProfileConnectionState.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/ProfileConnectionState.kt
new file mode 100644
index 000000000000..45aaa66e7f95
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/ProfileConnectionState.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.settingslib.bluetooth
+
+data class ProfileConnectionState(
+ val cachedDevice: CachedBluetoothDevice,
+ @BluetoothCallback.ConnectionState val state: Int,
+ val bluetoothProfile: Int,
+) \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreference.java
new file mode 100644
index 000000000000..1cbb8b4faaa8
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreference.java
@@ -0,0 +1,326 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Objects;
+
+/**
+ * A data class representing an action/switch preference. The preference could be one of the four
+ * following forms: 1. Texted row with action to jump to another page 2. Texted row without action
+ * 3. Texted row with action and switch 4. Texted row with switch
+ */
+public class ActionSwitchPreference extends DeviceSettingPreference implements Parcelable {
+ private final String mTitle;
+ private final String mSummary;
+ private final Bitmap mIcon;
+ private final Intent mIntent;
+ private final boolean mHasSwitch;
+ private final boolean mChecked;
+ private final boolean mIsAllowedChangingState;
+ private final Bundle mExtras;
+
+ ActionSwitchPreference(
+ String title,
+ @Nullable String summary,
+ @Nullable Bitmap icon,
+ @Nullable Intent intent,
+ boolean hasSwitch,
+ boolean checked,
+ boolean allowChangingState,
+ @NonNull Bundle extras) {
+ super(DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH);
+ validate(title);
+ mTitle = title;
+ mSummary = summary;
+ mIcon = icon;
+ mIntent = intent;
+ mHasSwitch = hasSwitch;
+ mChecked = checked;
+ mIsAllowedChangingState = allowChangingState;
+ mExtras = extras;
+ }
+
+ private static void validate(String title) {
+ if (Objects.isNull(title)) {
+ throw new IllegalArgumentException("Title must be set");
+ }
+ }
+
+ /**
+ * Reads an {@link ActionSwitchPreference} instance from {@link Parcel}
+ * @param in The parcel to read from
+ * @return The instance read
+ */
+ @NonNull
+ public static ActionSwitchPreference readFromParcel(@NonNull Parcel in) {
+ String title = in.readString();
+ String summary = in.readString();
+ Bitmap icon = in.readParcelable(Bitmap.class.getClassLoader());
+ Intent intent = in.readParcelable(Intent.class.getClassLoader());
+ boolean hasSwitch = in.readBoolean();
+ boolean checked = in.readBoolean();
+ boolean allowChangingState = in.readBoolean();
+ Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+ return new ActionSwitchPreference(
+ title, summary, icon, intent, hasSwitch, checked, allowChangingState, extras);
+ }
+
+ public static final Creator<ActionSwitchPreference> CREATOR =
+ new Creator<>() {
+ @Override
+ @NonNull
+ public ActionSwitchPreference createFromParcel(@NonNull Parcel in) {
+ in.readInt();
+ return readFromParcel(in);
+ }
+
+ @Override
+ @NonNull
+ public ActionSwitchPreference[] newArray(int size) {
+ return new ActionSwitchPreference[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeString(mTitle);
+ dest.writeString(mSummary);
+ dest.writeParcelable(mIcon, flags);
+ dest.writeParcelable(mIntent, flags);
+ dest.writeBoolean(mHasSwitch);
+ dest.writeBoolean(mChecked);
+ dest.writeBoolean(mIsAllowedChangingState);
+ dest.writeBundle(mExtras);
+ }
+
+ /** Builder class for {@link ActionSwitchPreference}. */
+ public static final class Builder {
+ private String mTitle;
+ private String mSummary;
+ private Bitmap mIcon;
+ private Intent mIntent;
+ private boolean mHasSwitch;
+ private boolean mChecked;
+ private boolean mIsAllowedChangingState;
+ private Bundle mExtras = Bundle.EMPTY;
+
+ /**
+ * Sets the title of the preference.
+ *
+ * @param title The title of the preference.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setTitle(@NonNull String title) {
+ mTitle = title;
+ return this;
+ }
+
+ /**
+ * Sets the summary of the preference, optional.
+ *
+ * @param summary The preference summary.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setSummary(@Nullable String summary) {
+ mSummary = summary;
+ return this;
+ }
+
+ /**
+ * Sets the icon to be displayed on the left of the preference, optional.
+ *
+ * @param icon The icon.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setIcon(@Nullable Bitmap icon) {
+ mIcon = icon;
+ return this;
+ }
+
+ /**
+ * Sets the Intent to launch when the preference is clicked, optional.
+ *
+ * @param intent The Intent.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setIntent(@Nullable Intent intent) {
+ mIntent = intent;
+ return this;
+ }
+
+ /**
+ * Sets whether the preference will contain a switch.
+ *
+ * @param hasSwitch Whether the preference contains a switch.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setHasSwitch(boolean hasSwitch) {
+ mHasSwitch = hasSwitch;
+ return this;
+ }
+
+ /**
+ * Sets the state of the preference.
+ *
+ * @param checked Whether the switch is checked.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setChecked(boolean checked) {
+ mChecked = checked;
+ return this;
+ }
+
+ /**
+ * Sets whether state can be changed by user.
+ *
+ * @param allowChangingState Whether user is allowed to change state.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setAllowedChangingState(boolean allowChangingState) {
+ mIsAllowedChangingState = allowChangingState;
+ return this;
+ }
+
+ /**
+ * Sets the extras bundle.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Builds the {@link ActionSwitchPreference} object.
+ *
+ * @return Returns the built {@link ActionSwitchPreference} object.
+ */
+ @NonNull
+ public ActionSwitchPreference build() {
+ return new ActionSwitchPreference(
+ mTitle,
+ mSummary,
+ mIcon,
+ mIntent,
+ mHasSwitch,
+ mChecked,
+ mIsAllowedChangingState,
+ mExtras);
+ }
+ }
+
+ /**
+ * Gets the title of the preference.
+ *
+ * @return Returns the title of the preference.
+ */
+ @NonNull
+ public String getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Gets the summary of the preference.
+ *
+ * @return Returns the summary of the preference.
+ */
+ @Nullable
+ public String getSummary() {
+ return mSummary;
+ }
+
+ /**
+ * Gets the icon of the preference.
+ *
+ * @return Returns the icon of the preference.
+ */
+ @Nullable
+ public Bitmap getIcon() {
+ return mIcon;
+ }
+
+ /**
+ * Gets the Intent to launch when the preference is clicked.
+ *
+ * @return Returns the intent to launch.
+ */
+ @Nullable
+ public Intent getIntent() {
+ return mIntent;
+ }
+
+ /**
+ * Whether the preference contains a switch.
+ *
+ * @return Whether the preference contains a switch.
+ */
+ public boolean hasSwitch() {
+ return mHasSwitch;
+ }
+
+ /**
+ * Whether the switch is checked.
+ *
+ * @return Whether the switch is checked.
+ */
+ public boolean getChecked() {
+ return mChecked;
+ }
+
+ /**
+ * Gets whether the state can be changed by user.
+ *
+ * @return Whether the state can be changed by user.
+ */
+ public boolean isAllowedChangingState() {
+ return mIsAllowedChangingState;
+ }
+
+ /**
+ * Gets the extras bundle.
+ *
+ * @return The extra bundle.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceState.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceState.java
new file mode 100644
index 000000000000..91c1a59fa6f2
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceState.java
@@ -0,0 +1,136 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+/** A data class representing the state of an action/switch preference. */
+public class ActionSwitchPreferenceState extends DeviceSettingPreferenceState
+ implements Parcelable {
+ private final boolean mChecked;
+ private final Bundle mExtras;
+
+ ActionSwitchPreferenceState(boolean checked, @NonNull Bundle extras) {
+ super(DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH);
+ mChecked = checked;
+ mExtras = extras;
+ }
+
+ /**
+ * Reads an {@link ActionSwitchPreferenceState} instance from {@link Parcel}
+ * @param in The parcel to read from
+ * @return The instance read
+ */
+ @NonNull
+ public static ActionSwitchPreferenceState readFromParcel(@NonNull Parcel in) {
+ boolean checked = in.readBoolean();
+ Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+ return new ActionSwitchPreferenceState(checked, extras);
+ }
+
+ public static final Creator<ActionSwitchPreferenceState> CREATOR =
+ new Creator<>() {
+ @Override
+ @NonNull
+ public ActionSwitchPreferenceState createFromParcel(@NonNull Parcel in) {
+ in.readInt();
+ return readFromParcel(in);
+ }
+
+ @Override
+ @NonNull
+ public ActionSwitchPreferenceState[] newArray(int size) {
+ return new ActionSwitchPreferenceState[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeBoolean(mChecked);
+ dest.writeBundle(mExtras);
+ }
+
+ /** Builder class for {@link ActionSwitchPreferenceState}. */
+ public static final class Builder {
+ private boolean mChecked;
+ private Bundle mExtras = Bundle.EMPTY;
+
+ public Builder() {}
+
+ /**
+ * Sets the state of the preference.
+ *
+ * @param checked Whether the switch is checked.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setChecked(boolean checked) {
+ mChecked = checked;
+ return this;
+ }
+
+ /**
+ * Sets the extras bundle.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Builds the object.
+ *
+ * @return Returns the built object.
+ */
+ @NonNull
+ public ActionSwitchPreferenceState build() {
+ return new ActionSwitchPreferenceState(mChecked, mExtras);
+ }
+ }
+
+ /**
+ * Whether the switch is checked.
+ *
+ * @return Whether the switch is checked.
+ */
+ public boolean getChecked() {
+ return mChecked;
+ }
+
+ /**
+ * Gets the extras bundle.
+ *
+ * @return The extra bundle.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.aidl
new file mode 100644
index 000000000000..acbaf2df1d2c
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+parcelable DeviceInfo; \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.java
new file mode 100644
index 000000000000..52e520ea8835
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.java
@@ -0,0 +1,137 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+import java.util.Objects;
+
+/** A data class representing a bluetooth device. */
+public class DeviceInfo implements Parcelable {
+ private final String mBluetoothAddress;
+ private final Bundle mExtras;
+
+ DeviceInfo(String bluetoothAddress, Bundle extras) {
+ validate(bluetoothAddress);
+ mBluetoothAddress = bluetoothAddress;
+ mExtras = extras;
+ }
+
+ private static void validate(String bluetoothAddress) {
+ if (Objects.isNull(bluetoothAddress)) {
+ throw new IllegalArgumentException("Bluetooth address must be set");
+ }
+ }
+
+ /** Read a {@link DeviceInfo} instance from {@link Parcel} */
+ @NonNull
+ public static DeviceInfo readFromParcel(@NonNull Parcel in) {
+ String bluetoothAddress = in.readString();
+ Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+ return new DeviceInfo(bluetoothAddress, extras);
+ }
+
+ public static final Creator<DeviceInfo> CREATOR =
+ new Creator<>() {
+ @Override
+ @NonNull
+ public DeviceInfo createFromParcel(@NonNull Parcel in) {
+ return readFromParcel(in);
+ }
+
+ @Override
+ @NonNull
+ public DeviceInfo[] newArray(int size) {
+ return new DeviceInfo[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mBluetoothAddress);
+ dest.writeBundle(mExtras);
+ }
+
+ /** Builder class for {@link DeviceInfo}. */
+ public static final class Builder {
+ private String mBluetoothAddress;
+ private Bundle mExtras = Bundle.EMPTY;
+
+ /**
+ * Sets the bluetooth address of the device, from {@link
+ * android.bluetooth.BluetoothDevice#getAddress()}.
+ *
+ * @param bluetoothAddress The bluetooth address.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setBluetoothAddress(@NonNull String bluetoothAddress) {
+ mBluetoothAddress = bluetoothAddress;
+ return this;
+ }
+
+ /**
+ * Sets the extras bundle.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Builds the {@link DeviceInfo} object.
+ *
+ * @return Returns the built {@link DeviceInfo} object.
+ */
+ @NonNull
+ public DeviceInfo build() {
+ return new DeviceInfo(mBluetoothAddress, mExtras);
+ }
+ }
+
+ /**
+ * Gets the bluetooth address of the device.
+ *
+ * @return The bluetooth address from {@link android.bluetooth.BluetoothDevice#getAddress()}.
+ */
+ @NonNull
+ public String getBluetoothAddress() {
+ return mBluetoothAddress;
+ }
+
+ /**
+ * Gets the extras bundle.
+ *
+ * @return The extra bundle.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.aidl
new file mode 100644
index 000000000000..043cae3a576a
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+parcelable DeviceSetting; \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.java
new file mode 100644
index 000000000000..dc219a9dfcf4
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.java
@@ -0,0 +1,160 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+import java.util.Objects;
+
+/** A data class representing a device setting item in bluetooth device details page. */
+public final class DeviceSetting implements Parcelable {
+ @DeviceSettingId private final int mSettingId;
+ private final DeviceSettingPreference mPreference;
+ private final Bundle mExtras;
+
+ DeviceSetting(
+ int settingId, @NonNull DeviceSettingPreference preference, @NonNull Bundle extras) {
+ validate(preference);
+ mSettingId = settingId;
+ mPreference = preference;
+ mExtras = extras;
+ }
+
+ private static void validate(DeviceSettingPreference preference) {
+ if (Objects.isNull(preference)) {
+ throw new IllegalArgumentException("Preference must be set");
+ }
+ }
+
+ /** Read a {@link DeviceSetting} instance from {@link Parcel} */
+ @NonNull
+ public static DeviceSetting readFromParcel(@NonNull Parcel in) {
+ int settingId = in.readInt();
+ Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+ DeviceSettingPreference settingPreference = DeviceSettingPreference.readFromParcel(in);
+ return new DeviceSetting(settingId, settingPreference, extras);
+ }
+
+ public static final Creator<DeviceSetting> CREATOR =
+ new Creator<>() {
+ @Override
+ @NonNull
+ public DeviceSetting createFromParcel(@NonNull Parcel in) {
+ return readFromParcel(in);
+ }
+
+ @Override
+ @NonNull
+ public DeviceSetting[] newArray(int size) {
+ return new DeviceSetting[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mSettingId);
+ dest.writeBundle(mExtras);
+ mPreference.writeToParcel(dest, flags);
+ }
+
+ /** Builder class for {@link DeviceSetting}. */
+ public static final class Builder {
+ private int mSettingId;
+ private DeviceSettingPreference mPreference;
+ private Bundle mExtras = Bundle.EMPTY;
+
+ public Builder() {}
+
+ /**
+ * Sets the setting ID, as defined by IntDef {@link DeviceSettingId}.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setSettingId(@DeviceSettingId int settingId) {
+ mSettingId = settingId;
+ return this;
+ }
+
+ /**
+ * Sets the setting preference.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setPreference(@NonNull DeviceSettingPreference settingPreference) {
+ mPreference = settingPreference;
+ return this;
+ }
+
+ /**
+ * Sets the extras bundle.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /** Build the object. */
+ @NonNull
+ public DeviceSetting build() {
+ return new DeviceSetting(mSettingId, mPreference, mExtras);
+ }
+ }
+
+ /**
+ * Gets the setting ID as defined by IntDef {@link DeviceSettingId}.
+ *
+ * @return Returns the setting ID.
+ */
+ @DeviceSettingId
+ public int getSettingId() {
+ return mSettingId;
+ }
+
+ /**
+ * Gets the setting preference.
+ *
+ * @return Returns the setting preference.
+ */
+ @NonNull
+ public DeviceSettingPreference getPreference() {
+ return mPreference;
+ }
+
+ /**
+ * Gets the extras Bundle.
+ *
+ * @return Returns a Bundle object.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingId.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingId.java
new file mode 100644
index 000000000000..20a0339b9182
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingId.java
@@ -0,0 +1,113 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.SOURCE)
+@IntDef(
+ value = {
+ DeviceSettingId.DEVICE_SETTING_ID_UNKNOWN,
+ DeviceSettingId.DEVICE_SETTING_ID_HEADER,
+ DeviceSettingId.DEVICE_SETTING_ID_ADVANCED_HEADER,
+ DeviceSettingId.DEVICE_SETTING_ID_LE_AUDIO_HEADER,
+ DeviceSettingId.DEVICE_SETTING_ID_HEARING_AID_PAIR_OTHER_BUTTON,
+ DeviceSettingId.DEVICE_SETTING_ID_HEARING_AID_SPACE_LAYOUT,
+ DeviceSettingId.DEVICE_SETTING_ID_ACTION_BUTTONS,
+ DeviceSettingId.DEVICE_SETTING_ID_DEVICE_STYLUS,
+ DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_EXTRA_CONTROL,
+ DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_DEVICE_SLICE_CATEGORY,
+ DeviceSettingId.DEVICE_SETTING_ID_DEVICE_COMPANION_APPS,
+ DeviceSettingId.DEVICE_SETTING_ID_HEARING_DEVICE_GROUP,
+ DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_AUDIO_DEVICE_TYPE_GROUP,
+ DeviceSettingId.DEVICE_SETTING_ID_SPATIAL_AUDIO_GROUP,
+ DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_PROFILES,
+ DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_EXTRA_OPTIONS,
+ DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_RELATED_TOOLS,
+ DeviceSettingId.DEVICE_SETTING_ID_DATA_SYNC_GROUP,
+ DeviceSettingId.DEVICE_SETTING_ID_KEYBOARD_SETTINGS,
+ DeviceSettingId.DEVICE_SETTING_ID_DEVICE_DETAILS_FOOTER,
+ DeviceSettingId.DEVICE_SETTING_ID_ANC,
+ },
+ open = true)
+public @interface DeviceSettingId {
+ /** Device setting ID is unknown. */
+ int DEVICE_SETTING_ID_UNKNOWN = 0;
+
+ /** Device setting ID for header. */
+ int DEVICE_SETTING_ID_HEADER = 1;
+
+ /** Device setting ID for advanced header. */
+ int DEVICE_SETTING_ID_ADVANCED_HEADER = 2;
+
+ /** Device setting ID for LeAudio header. */
+ int DEVICE_SETTING_ID_LE_AUDIO_HEADER = 3;
+
+ /** Device setting ID for hearing aid “pair other” button. */
+ int DEVICE_SETTING_ID_HEARING_AID_PAIR_OTHER_BUTTON = 4;
+
+ /** Device setting ID for hearing aid space layout. */
+ int DEVICE_SETTING_ID_HEARING_AID_SPACE_LAYOUT = 5;
+
+ /** Device setting ID for action buttons(Forget, Connect/Disconnect). */
+ int DEVICE_SETTING_ID_ACTION_BUTTONS = 6;
+
+ /** Device setting ID for stylus device. */
+ int DEVICE_SETTING_ID_DEVICE_STYLUS = 7;
+
+ /** Device setting ID for bluetooth extra control. */
+ int DEVICE_SETTING_ID_BLUETOOTH_EXTRA_CONTROL = 8;
+
+ /** Device setting ID for bluetooth device slice category. */
+ int DEVICE_SETTING_ID_BLUETOOTH_DEVICE_SLICE_CATEGORY = 9;
+
+ /** Device setting ID for device companion apps. */
+ int DEVICE_SETTING_ID_DEVICE_COMPANION_APPS = 10;
+
+ /** Device setting ID for hearing device group. */
+ int DEVICE_SETTING_ID_HEARING_DEVICE_GROUP = 11;
+
+ /** Device setting ID for bluetooth audio device type group. */
+ int DEVICE_SETTING_ID_BLUETOOTH_AUDIO_DEVICE_TYPE_GROUP = 12;
+
+ /** Device setting ID for spatial audio group. */
+ int DEVICE_SETTING_ID_SPATIAL_AUDIO_GROUP = 13;
+
+ /** Device setting ID for bluetooth profiles. */
+ int DEVICE_SETTING_ID_BLUETOOTH_PROFILES = 14;
+
+ /** Device setting ID for bluetooth extra options. */
+ int DEVICE_SETTING_ID_BLUETOOTH_EXTRA_OPTIONS = 15;
+
+ /** Device setting ID for bluetooth related tools. */
+ int DEVICE_SETTING_ID_BLUETOOTH_RELATED_TOOLS = 16;
+
+ /** Device setting ID for data sync group. */
+ int DEVICE_SETTING_ID_DATA_SYNC_GROUP = 17;
+
+ /** Device setting ID for keyboard settings. */
+ int DEVICE_SETTING_ID_KEYBOARD_SETTINGS = 18;
+
+ /** Device setting ID for device details footer. */
+ int DEVICE_SETTING_ID_DEVICE_DETAILS_FOOTER = 19;
+
+ /** Device setting ID for ANC. */
+ int DEVICE_SETTING_ID_ANC = 1001;
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItem.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItem.kt
new file mode 100644
index 000000000000..9ee33b0dbffe
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItem.kt
@@ -0,0 +1,72 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings
+
+import android.os.Bundle
+import android.os.Parcel
+import android.os.Parcelable
+
+/**
+ * A data class representing a device settings item in bluetooth device details config.
+ *
+ * @property settingId The setting ID of the item, as defined by IntDef [DeviceSettingId].
+ * @property packageName The package name for service binding.
+ * @property className The class name for service binding.
+ * @property intentAction The intent action for service binding.
+ * @property extras Extra bundle
+ */
+data class DeviceSettingItem(
+ @DeviceSettingId val settingId: Int,
+ val packageName: String,
+ val className: String,
+ val intentAction: String,
+ val extras: Bundle = Bundle.EMPTY,
+) : Parcelable {
+
+ override fun describeContents(): Int = 0
+
+ override fun writeToParcel(parcel: Parcel, flags: Int) {
+ parcel.run {
+ writeInt(settingId)
+ writeString(packageName)
+ writeString(className)
+ writeString(intentAction)
+ writeBundle(extras)
+ }
+ }
+
+ companion object {
+ @JvmField
+ val CREATOR: Parcelable.Creator<DeviceSettingItem> =
+ object : Parcelable.Creator<DeviceSettingItem> {
+ override fun createFromParcel(parcel: Parcel) =
+ parcel.run {
+ DeviceSettingItem(
+ settingId = readInt(),
+ packageName = readString() ?: "",
+ className = readString() ?: "",
+ intentAction = readString() ?: "",
+ extras = readBundle((Bundle::class.java.classLoader)) ?: Bundle.EMPTY,
+ )
+ }
+
+ override fun newArray(size: Int): Array<DeviceSettingItem?> {
+ return arrayOfNulls(size)
+ }
+ }
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreference.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreference.java
new file mode 100644
index 000000000000..790939a18a0c
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreference.java
@@ -0,0 +1,62 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Parcel;
+
+import androidx.annotation.NonNull;
+
+/** An abstract class representing a device setting preference. */
+public abstract class DeviceSettingPreference {
+ @DeviceSettingType private final int mSettingType;
+
+ public static final DeviceSettingPreference UNKNOWN =
+ new DeviceSettingPreference(DeviceSettingType.DEVICE_SETTING_TYPE_UNKNOWN) {};
+
+ protected DeviceSettingPreference(@DeviceSettingType int settingType) {
+ mSettingType = settingType;
+ }
+
+ /** Read a {@link DeviceSettingPreference} instance from {@link Parcel} */
+ @NonNull
+ public static DeviceSettingPreference readFromParcel(@NonNull Parcel in) {
+ int type = in.readInt();
+ switch (type) {
+ case DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH:
+ return ActionSwitchPreference.readFromParcel(in);
+ case DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE:
+ return MultiTogglePreference.readFromParcel(in);
+ default:
+ return UNKNOWN;
+ }
+ }
+
+ /** Writes the instance to {@link Parcel}. */
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mSettingType);
+ }
+
+ /**
+ * Gets the setting type, as defined by IntDef {@link DeviceSettingType}.
+ *
+ * @return the setting type.
+ */
+ @DeviceSettingType
+ public int getSettingType() {
+ return mSettingType;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreferenceState.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreferenceState.java
new file mode 100644
index 000000000000..a982af709f69
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreferenceState.java
@@ -0,0 +1,62 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Parcel;
+
+import androidx.annotation.NonNull;
+
+/** An abstract class representing a device setting preference state. */
+public abstract class DeviceSettingPreferenceState {
+ @DeviceSettingType private final int mSettingType;
+
+ public static final DeviceSettingPreferenceState UNKNOWN =
+ new DeviceSettingPreferenceState(DeviceSettingType.DEVICE_SETTING_TYPE_UNKNOWN) {};
+
+ protected DeviceSettingPreferenceState(@DeviceSettingType int settingType) {
+ mSettingType = settingType;
+ }
+
+ /** Reads a {@link DeviceSettingPreferenceState} from {@link Parcel}. */
+ @NonNull
+ public static DeviceSettingPreferenceState readFromParcel(@NonNull Parcel in) {
+ int type = in.readInt();
+ switch (type) {
+ case DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH:
+ return ActionSwitchPreferenceState.readFromParcel(in);
+ case DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE:
+ return MultiTogglePreferenceState.readFromParcel(in);
+ default:
+ return UNKNOWN;
+ }
+ }
+
+ /** Writes the object to parcel. */
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mSettingType);
+ }
+
+ /**
+ * Gets the setting type, as defined by IntDef {@link DeviceSettingType}.
+ *
+ * @return The setting type.
+ */
+ @DeviceSettingType
+ public int getSettingType() {
+ return mSettingType;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.aidl
new file mode 100644
index 000000000000..61429a63128f
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+parcelable DeviceSettingState; \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.java
new file mode 100644
index 000000000000..63fd4eb425c0
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.java
@@ -0,0 +1,165 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+import java.util.Objects;
+
+/** A data class representing a device setting state. */
+public class DeviceSettingState implements Parcelable {
+ @DeviceSettingId private final int mSettingId;
+ private final DeviceSettingPreferenceState mPreferenceState;
+ private final Bundle mExtras;
+
+ DeviceSettingState(
+ @DeviceSettingId int settingId,
+ @NonNull DeviceSettingPreferenceState preferenceState,
+ @NonNull Bundle extras) {
+ validate(preferenceState);
+ mSettingId = settingId;
+ mPreferenceState = preferenceState;
+ mExtras = extras;
+ }
+
+ private static void validate(DeviceSettingPreferenceState preferenceState) {
+ if (Objects.isNull(preferenceState)) {
+ throw new IllegalArgumentException("PreferenceState must be set");
+ }
+ }
+
+ /** Reads a {@link DeviceSettingState} from {@link Parcel}. */
+ @NonNull
+ public static DeviceSettingState readFromParcel(@NonNull Parcel in) {
+ int settingId = in.readInt();
+ Bundle extra = in.readBundle(Bundle.class.getClassLoader());
+ DeviceSettingPreferenceState preferenceState =
+ DeviceSettingPreferenceState.readFromParcel(in);
+ return new DeviceSettingState(settingId, preferenceState, extra);
+ }
+
+ public static final Creator<DeviceSettingState> CREATOR =
+ new Creator<>() {
+ @Override
+ @NonNull
+ public DeviceSettingState createFromParcel(@NonNull Parcel in) {
+ return readFromParcel(in);
+ }
+
+ @Override
+ @NonNull
+ public DeviceSettingState[] newArray(int size) {
+ return new DeviceSettingState[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Writes the instance to {@link Parcel}. */
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mSettingId);
+ dest.writeBundle(mExtras);
+ mPreferenceState.writeToParcel(dest, flags);
+ }
+
+ /** Builder class for {@link DeviceSettingState}. */
+ public static final class Builder {
+ private int mSettingId;
+ private DeviceSettingPreferenceState mSettingPreferenceState;
+ private Bundle mExtras = Bundle.EMPTY;
+
+ public Builder() {}
+
+ /**
+ * Sets the setting ID, as defined by IntDef {@link DeviceSettingId}.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setSettingId(@DeviceSettingId int settingId) {
+ mSettingId = settingId;
+ return this;
+ }
+
+ /**
+ * Sets the setting preference state.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setPreferenceState(
+ @NonNull DeviceSettingPreferenceState settingPreferenceState) {
+ mSettingPreferenceState = settingPreferenceState;
+ return this;
+ }
+
+ /**
+ * Sets the extras bundle.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /** Build the object. */
+ @NonNull
+ public DeviceSettingState build() {
+ return new DeviceSettingState(mSettingId, mSettingPreferenceState, mExtras);
+ }
+ }
+
+ /**
+ * Gets the setting ID, as defined by IntDef {@link DeviceSettingId}.
+ *
+ * @return the setting ID.
+ */
+ @DeviceSettingId
+ public int getSettingId() {
+ return mSettingId;
+ }
+
+ /**
+ * Gets the preference state of the setting.
+ *
+ * @return the setting preference state.
+ */
+ @NonNull
+ public DeviceSettingPreferenceState getPreferenceState() {
+ return mPreferenceState;
+ }
+
+ /**
+ * Gets the extras Bundle.
+ *
+ * @return Returns a Bundle object.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingType.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingType.java
new file mode 100644
index 000000000000..ee4d90fe4171
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingType.java
@@ -0,0 +1,41 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.SOURCE)
+@IntDef(
+ value = {
+ DeviceSettingType.DEVICE_SETTING_TYPE_UNKNOWN,
+ DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH,
+ DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE,
+ },
+ open = true)
+public @interface DeviceSettingType {
+ /** Device setting type is unknown. */
+ int DEVICE_SETTING_TYPE_UNKNOWN = 0;
+
+ /** Device setting type is action/switch preference. */
+ int DEVICE_SETTING_TYPE_ACTION_SWITCH = 1;
+
+ /** Device setting type is multi-toggle preference. */
+ int DEVICE_SETTING_TYPE_MULTI_TOGGLE = 2;
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.aidl
new file mode 100644
index 000000000000..3201d13cd92e
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+parcelable DeviceSettingsConfig; \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.kt
new file mode 100644
index 000000000000..c8a2e9ca3af1
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.kt
@@ -0,0 +1,74 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings
+
+import android.os.Bundle
+import android.os.Parcel
+import android.os.Parcelable
+
+/**
+ * A data class representing a bluetooth device details config.
+ *
+ * @property mainContentItems The setting items to be shown in main page.
+ * @property moreSettingsItems The setting items to be shown in more settings page.
+ * @property moreSettingsFooter The footer in more settings page.
+ * @property extras Extra bundle
+ */
+data class DeviceSettingsConfig(
+ val mainContentItems: List<DeviceSettingItem>,
+ val moreSettingsItems: List<DeviceSettingItem>,
+ val moreSettingsFooter: String,
+ val extras: Bundle = Bundle.EMPTY,
+) : Parcelable {
+
+ override fun describeContents(): Int = 0
+
+ override fun writeToParcel(parcel: Parcel, flags: Int) {
+ parcel.run {
+ writeTypedList(mainContentItems)
+ writeTypedList(moreSettingsItems)
+ writeString(moreSettingsFooter)
+ writeBundle(extras)
+ }
+ }
+
+ companion object {
+ @JvmField
+ val CREATOR: Parcelable.Creator<DeviceSettingsConfig> =
+ object : Parcelable.Creator<DeviceSettingsConfig> {
+ override fun createFromParcel(parcel: Parcel): DeviceSettingsConfig =
+ parcel.run {
+ DeviceSettingsConfig(
+ mainContentItems =
+ arrayListOf<DeviceSettingItem>().also {
+ readTypedList(it, DeviceSettingItem.CREATOR)
+ },
+ moreSettingsItems =
+ arrayListOf<DeviceSettingItem>().also {
+ readTypedList(it, DeviceSettingItem.CREATOR)
+ },
+ moreSettingsFooter = readString()!!,
+ extras = readBundle((Bundle::class.java.classLoader))!!,
+ )
+ }
+
+ override fun newArray(size: Int): Array<DeviceSettingsConfig?> {
+ return arrayOfNulls(size)
+ }
+ }
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsListener.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsListener.aidl
new file mode 100644
index 000000000000..385a780b01f3
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsListener.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import com.android.settingslib.bluetooth.devicesettings.DeviceSetting;
+
+interface IDeviceSettingsListener {
+ oneway void onDeviceSettingsChanged(in List<DeviceSetting> settings) = 0;
+} \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsProviderService.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsProviderService.aidl
new file mode 100644
index 000000000000..d5efac9d0336
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsProviderService.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import com.android.settingslib.bluetooth.devicesettings.DeviceInfo;
+import com.android.settingslib.bluetooth.devicesettings.DeviceSettingState;
+import com.android.settingslib.bluetooth.devicesettings.IDeviceSettingsListener;
+
+oneway interface IDeviceSettingsProviderService {
+ void registerDeviceSettingsListener(in DeviceInfo device, in IDeviceSettingsListener callback);
+ void unregisterDeviceSettingsListener(in DeviceInfo device, in IDeviceSettingsListener callback);
+ void updateDeviceSettings(in DeviceInfo device, in DeviceSettingState params);
+} \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreference.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreference.java
new file mode 100644
index 000000000000..01bb6f013d16
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreference.java
@@ -0,0 +1,232 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/** A data class representing a multi-toggle preference. */
+public class MultiTogglePreference extends DeviceSettingPreference implements Parcelable {
+ private final String mTitle;
+ private final ImmutableList<ToggleInfo> mToggleInfos;
+ private final int mState;
+ private final boolean mIsAllowedChangingState;
+ private final Bundle mExtras;
+
+ MultiTogglePreference(
+ @NonNull String title,
+ List<ToggleInfo> toggleInfos,
+ int state,
+ boolean allowChangingState,
+ Bundle extras) {
+ super(DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE);
+ validate(title, state);
+ mTitle = title;
+ mToggleInfos = ImmutableList.copyOf(toggleInfos);
+ mState = state;
+ mIsAllowedChangingState = allowChangingState;
+ mExtras = extras;
+ }
+
+ private static void validate(String title, int state) {
+ if (Objects.isNull(title)) {
+ throw new IllegalArgumentException("Title must be set");
+ }
+ if (state < 0) {
+ throw new IllegalArgumentException("State must be a non-negative integer");
+ }
+ }
+
+ /** Read a {@link MultiTogglePreference} from {@link Parcel}. */
+ @NonNull
+ public static MultiTogglePreference readFromParcel(@NonNull Parcel in) {
+ String title = in.readString();
+ List<ToggleInfo> toggleInfos = new ArrayList<>();
+ in.readTypedList(toggleInfos, ToggleInfo.CREATOR);
+ int state = in.readInt();
+ boolean allowChangingState = in.readBoolean();
+ Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+ return new MultiTogglePreference(title, toggleInfos, state, allowChangingState, extras);
+ }
+
+ public static final Creator<MultiTogglePreference> CREATOR =
+ new Creator<>() {
+ @Override
+ @NonNull
+ public MultiTogglePreference createFromParcel(@NonNull Parcel in) {
+ in.readInt();
+ return readFromParcel(in);
+ }
+
+ @Override
+ @NonNull
+ public MultiTogglePreference[] newArray(int size) {
+ return new MultiTogglePreference[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeString(mTitle);
+ dest.writeTypedList(mToggleInfos, flags);
+ dest.writeInt(mState);
+ dest.writeBoolean(mIsAllowedChangingState);
+ dest.writeBundle(mExtras);
+ }
+
+ /** Builder class for {@link MultiTogglePreference}. */
+ public static final class Builder {
+ private String mTitle;
+ private ImmutableList.Builder<ToggleInfo> mToggleInfos = new ImmutableList.Builder<>();
+ private int mState;
+ private boolean mAllowChangingState;
+ private Bundle mExtras = Bundle.EMPTY;
+
+ /**
+ * Sets the title of the preference.
+ *
+ * @param title The title of the preference.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setTitle(@NonNull String title) {
+ mTitle = title;
+ return this;
+ }
+
+ /**
+ * Adds a toggle in the preference.
+ *
+ * @param toggleInfo The toggle to add.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder addToggleInfo(@NonNull ToggleInfo toggleInfo) {
+ mToggleInfos.add(toggleInfo);
+ return this;
+ }
+
+ /**
+ * Sets the state of the preference.
+ *
+ * @param state The index of the enabled toggle.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setState(int state) {
+ mState = state;
+ return this;
+ }
+
+ /**
+ * Sets whether state can be changed by user.
+ *
+ * @param allowChangingState Whether user is allowed to change state.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setAllowChangingState(boolean allowChangingState) {
+ mAllowChangingState = allowChangingState;
+ return this;
+ }
+
+ /**
+ * Sets the extras bundle.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Builds the {@link ToggleInfo} object.
+ *
+ * @return Returns the built {@link ToggleInfo} object.
+ */
+ @NonNull
+ public MultiTogglePreference build() {
+ return new MultiTogglePreference(
+ mTitle, mToggleInfos.build(), mState, mAllowChangingState, mExtras);
+ }
+ }
+
+ /**
+ * Gets the title of the preference.
+ *
+ * @return The title.
+ */
+ @NonNull
+ public String getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Gets the state of the {@link MultiTogglePreference}.
+ *
+ * @return Returns the index of the enabled toggle.
+ */
+ public int getState() {
+ return mState;
+ }
+
+ /**
+ * Gets the toggle list in the preference.
+ *
+ * @return the toggle list.
+ */
+ @NonNull
+ public List<ToggleInfo> getToggleInfos() {
+ return mToggleInfos;
+ }
+
+ /**
+ * Gets whether the state can be changed by user.
+ *
+ * @return Whether the state can be changed by user.
+ */
+ public boolean isAllowedChangingState() {
+ return mIsAllowedChangingState;
+ }
+
+ /**
+ * Gets the extras Bundle.
+ *
+ * @return Returns a Bundle object.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceState.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceState.java
new file mode 100644
index 000000000000..239df0b55b22
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceState.java
@@ -0,0 +1,126 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+/** A data class representing a multi-toggle preference state. */
+public class MultiTogglePreferenceState extends DeviceSettingPreferenceState implements Parcelable {
+ private final int mState;
+ private final Bundle mExtras;
+
+ MultiTogglePreferenceState(int state, @NonNull Bundle extras) {
+ super(DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE);
+ mState = state;
+ mExtras = extras;
+ }
+
+ /** Reads a {@link MultiTogglePreferenceState} from {@link Parcel}. */
+ @NonNull
+ public static MultiTogglePreferenceState readFromParcel(@NonNull Parcel in) {
+ int state = in.readInt();
+ Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+ return new MultiTogglePreferenceState(state, extras);
+ }
+
+ public static final Creator<MultiTogglePreferenceState> CREATOR =
+ new Creator<>() {
+ @Override
+ @NonNull
+ public MultiTogglePreferenceState createFromParcel(@NonNull Parcel in) {
+ in.readInt();
+ return readFromParcel(in);
+ }
+
+ @Override
+ @NonNull
+ public MultiTogglePreferenceState[] newArray(int size) {
+ return new MultiTogglePreferenceState[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(mState);
+ dest.writeBundle(mExtras);
+ }
+
+ /** Builder class for {@link MultiTogglePreferenceState}. */
+ public static final class Builder {
+ private int mState;
+ private Bundle mExtras = Bundle.EMPTY;
+
+ public Builder() {}
+
+ /**
+ * Sets the state of {@link MultiTogglePreference}.
+ *
+ * @return Returns the index of enabled toggle.
+ */
+ @NonNull
+ public Builder setState(int state) {
+ mState = state;
+ return this;
+ }
+
+ /**
+ * Sets the extras bundle.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /** Builds the object. */
+ @NonNull
+ public MultiTogglePreferenceState build() {
+ return new MultiTogglePreferenceState(mState, mExtras);
+ }
+ }
+
+ /**
+ * Gets the state of the {@link MultiTogglePreference}.
+ *
+ * @return Returns the index of the enabled toggle.
+ */
+ public int getState() {
+ return mState;
+ }
+
+ /**
+ * Gets the extras Bundle.
+ *
+ * @return Returns a Bundle object.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfo.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfo.java
new file mode 100644
index 000000000000..7dcf3aa7239e
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfo.java
@@ -0,0 +1,167 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+import java.util.Objects;
+
+/** A data class representing a toggle in {@link MultiTogglePreference}. */
+public class ToggleInfo implements Parcelable {
+ private final String mLabel;
+ private final Bitmap mIcon;
+ private final Bundle mExtras;
+
+ ToggleInfo(@NonNull String label, @NonNull Bitmap icon, @NonNull Bundle extras) {
+ validate(label, icon);
+ mLabel = label;
+ mIcon = icon;
+ mExtras = extras;
+ }
+
+ private static void validate(String label, Bitmap icon) {
+ if (Objects.isNull(label)) {
+ throw new IllegalArgumentException("Label must be set");
+ }
+ if (Objects.isNull(icon)) {
+ throw new IllegalArgumentException("Icon must be set");
+ }
+ }
+
+ /** Read a {@link ToggleInfo} instance from {@link Parcel}. */
+ @NonNull
+ public static ToggleInfo readFromParcel(@NonNull Parcel in) {
+ String label = in.readString();
+ Bitmap icon = in.readParcelable(Bitmap.class.getClassLoader());
+ Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+ return new ToggleInfo(label, icon, extras);
+ }
+
+ public static final Creator<ToggleInfo> CREATOR =
+ new Creator<>() {
+ @Override
+ @NonNull
+ public ToggleInfo createFromParcel(@NonNull Parcel in) {
+ return readFromParcel(in);
+ }
+
+ @Override
+ @NonNull
+ public ToggleInfo[] newArray(int size) {
+ return new ToggleInfo[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mLabel);
+ dest.writeParcelable(mIcon, flags);
+ dest.writeBundle(mExtras);
+ }
+
+ /** Builder class for {@link ToggleInfo}. */
+ public static final class Builder {
+ private Bitmap mIcon;
+ private String mLabel;
+ private Bundle mExtras = Bundle.EMPTY;
+
+ /**
+ * Sets the label of the toggle.
+ *
+ * @param label The label of the toggle.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setLabel(@NonNull String label) {
+ mLabel = label;
+ return this;
+ }
+
+ /**
+ * Sets the icon of the toggle.
+ *
+ * @param icon The icon of the toggle.
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setIcon(@NonNull Bitmap icon) {
+ mIcon = icon;
+ return this;
+ }
+
+ /**
+ * Sets the extras bundle.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Builds the {@link ToggleInfo} object.
+ *
+ * @return Returns the built {@link ToggleInfo} object.
+ */
+ @NonNull
+ public ToggleInfo build() {
+ return new ToggleInfo(mLabel, mIcon, mExtras);
+ }
+ }
+
+ /**
+ * Gets the label of the toggle.
+ *
+ * @return the label to be shown under the toggle
+ */
+ @NonNull
+ public String getLabel() {
+ return mLabel;
+ }
+
+ /**
+ * Gets the icon of the toggle.
+ *
+ * @return the icon in toggle
+ */
+ @NonNull
+ public Bitmap getIcon() {
+ return mIcon;
+ }
+
+ /**
+ * Gets the extras Bundle.
+ *
+ * @return Returns a Bundle object.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
index ea65adecd763..84afb9f7a7e2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
@@ -25,7 +25,6 @@ import android.util.Log;
import androidx.annotation.EmptySuper;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
-import androidx.core.os.BuildCompat;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
@@ -141,7 +140,7 @@ public abstract class AbstractPreferenceController {
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
protected void replaceEnterpriseStringTitle(PreferenceScreen screen,
String preferenceKey, String overrideKey, int resource) {
- if (!BuildCompat.isAtLeastT() || mDevicePolicyManager == null) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || mDevicePolicyManager == null) {
return;
}
@@ -159,7 +158,7 @@ public abstract class AbstractPreferenceController {
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
protected void replaceEnterpriseStringSummary(
PreferenceScreen screen, String preferenceKey, String overrideKey, int resource) {
- if (!BuildCompat.isAtLeastT() || mDevicePolicyManager == null) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || mDevicePolicyManager == null) {
return;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
index f07daa3add8b..243403e018b6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
@@ -48,8 +48,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
-import com.android.settingslib.utils.BuildCompatUtils;
-
/**
* Converts the user avatar icon to a circularly clipped one with an optional badge and frame
*/
@@ -88,7 +86,7 @@ public class UserIconDrawable extends Drawable implements Drawable.Callback {
* @return drawable containing just the badge
*/
public static Drawable getManagedUserDrawable(Context context) {
- if (BuildCompatUtils.isAtLeastT()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return getUpdatableManagedUserDrawable(context);
} else {
return getDrawableForDisplayDensity(
@@ -227,7 +225,7 @@ public class UserIconDrawable extends Drawable implements Drawable.Callback {
}
private static Drawable getManagementBadge(Context context) {
- if (BuildCompatUtils.isAtLeastT()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return getUpdatableManagementBadge(context);
} else {
return getDrawableForDisplayDensity(
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index 8bdbee38ab85..9be3159716b8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -16,11 +16,15 @@
package com.android.settingslib.fuelgauge;
+import static android.provider.Settings.Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED;
+import static android.provider.Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED;
+
import static com.android.settingslib.fuelgauge.BatterySaverLogging.ACTION_SAVER_STATE_MANUAL_UPDATE;
import static com.android.settingslib.fuelgauge.BatterySaverLogging.EXTRA_POWER_SAVE_MODE_MANUAL_ENABLED;
import static com.android.settingslib.fuelgauge.BatterySaverLogging.EXTRA_POWER_SAVE_MODE_MANUAL_ENABLED_REASON;
import static com.android.settingslib.fuelgauge.BatterySaverLogging.SaverManualEnabledReason;
+import android.app.KeyguardManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -33,6 +37,10 @@ import android.util.KeyValueListParser;
import android.util.Log;
import android.util.Slog;
+import androidx.core.util.Function;
+
+import com.android.settingslib.flags.Flags;
+
/**
* Utilities related to battery saver.
*/
@@ -125,6 +133,19 @@ public class BatterySaverUtils {
Log.d(TAG, "Battery saver turning " + (enable ? "ON" : "OFF") + ", reason: " + reason);
}
final ContentResolver cr = context.getContentResolver();
+ final PowerManager powerManager = context.getSystemService(PowerManager.class);
+
+ if (Flags.extremePowerLowStateVulnerability()) {
+ var keyguardManager = context.getSystemService(KeyguardManager.class);
+ if (enable
+ && needFirstTimeWarning
+ && keyguardManager != null
+ && keyguardManager.isDeviceLocked()) {
+ var result = powerManager.setPowerSaveModeEnabled(true);
+ Log.d(TAG, "Device is locked, setPowerSaveModeEnabled by default. " + result);
+ return result;
+ }
+ }
final Bundle confirmationExtras = new Bundle(1);
confirmationExtras.putBoolean(EXTRA_CONFIRM_TEXT_ONLY, false);
@@ -136,7 +157,7 @@ public class BatterySaverUtils {
setBatterySaverConfirmationAcknowledged(context);
}
- if (context.getSystemService(PowerManager.class).setPowerSaveModeEnabled(enable)) {
+ if (powerManager.setPowerSaveModeEnabled(enable)) {
if (enable) {
final int count =
Secure.getInt(cr, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, 0) + 1;
@@ -173,10 +194,7 @@ public class BatterySaverUtils {
* @see #EXTRA_POWER_SAVE_MODE_TRIGGER_LEVEL
*/
public static boolean maybeShowBatterySaverConfirmation(Context context, Bundle extras) {
- if (Secure.getInt(context.getContentResolver(),
- Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 0) != 0
- && Secure.getInt(context.getContentResolver(),
- Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 0) != 0) {
+ if (isBatterySaverConfirmationHasBeenShowedBefore(context)) {
// Already shown.
return false;
}
@@ -184,6 +202,17 @@ public class BatterySaverUtils {
return true;
}
+ /**
+ * Returns {@code true} if the battery saver confirmation warning has been acknowledged by the
+ * user in the past before.
+ */
+ public static boolean isBatterySaverConfirmationHasBeenShowedBefore(Context context) {
+ Function<String, Integer> secureGetInt =
+ key -> Secure.getInt(context.getContentResolver(), key, /* def= */ 0);
+ return secureGetInt.apply(LOW_POWER_WARNING_ACKNOWLEDGED) != 0
+ && secureGetInt.apply(EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED) != 0;
+ }
+
private static void recordBatterySaverEnabledReason(Context context, boolean enable,
@SaverManualEnabledReason int reason) {
final Bundle enabledReasonExtras = new Bundle(2);
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
index 6571dd7ba398..eced7b3a116b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
@@ -29,6 +29,7 @@ import android.media.session.MediaController;
import android.os.UserHandle;
import android.text.TextUtils;
+import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -41,7 +42,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
-import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@@ -65,7 +65,9 @@ public final class RouterInfoMediaManager extends InfoMediaManager {
refreshDevices();
};
- private final AtomicReference<MediaRouter2.ScanToken> mScanToken = new AtomicReference<>();
+ @GuardedBy("this")
+ @Nullable
+ private MediaRouter2.ScanToken mScanToken;
// TODO (b/321969740): Plumb target UserHandle between UMO and RouterInfoMediaManager.
/* package */ RouterInfoMediaManager(
@@ -101,8 +103,13 @@ public final class RouterInfoMediaManager extends InfoMediaManager {
@Override
protected void startScanOnRouter() {
if (Flags.enableScreenOffScanning()) {
- MediaRouter2.ScanRequest request = new MediaRouter2.ScanRequest.Builder().build();
- mScanToken.compareAndSet(null, mRouter.requestScan(request));
+ synchronized (this) {
+ if (mScanToken == null) {
+ MediaRouter2.ScanRequest request =
+ new MediaRouter2.ScanRequest.Builder().build();
+ mScanToken = mRouter.requestScan(request);
+ }
+ }
} else {
mRouter.startScan();
}
@@ -120,9 +127,11 @@ public final class RouterInfoMediaManager extends InfoMediaManager {
@Override
protected void stopScanOnRouter() {
if (Flags.enableScreenOffScanning()) {
- MediaRouter2.ScanToken token = mScanToken.getAndSet(null);
- if (token != null) {
- mRouter.cancelScanRequest(token);
+ synchronized (this) {
+ if (mScanToken != null) {
+ mRouter.cancelScanRequest(mScanToken);
+ mScanToken = null;
+ }
}
} else {
mRouter.stopScan();
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExt.kt b/packages/SettingsLib/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExt.kt
new file mode 100644
index 000000000000..02d684d7d0ce
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExt.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.settingslib.media.data.repository
+
+import android.media.AudioManager
+import android.media.IVolumeController
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.buffer
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.launch
+
+/** Returns [AudioManager.setVolumeController] events as a [Flow] */
+fun AudioManager.volumeControllerEvents(): Flow<VolumeControllerEvent> =
+ callbackFlow {
+ volumeController =
+ object : IVolumeController.Stub() {
+ override fun displaySafeVolumeWarning(flags: Int) {
+ launch { send(VolumeControllerEvent.DisplaySafeVolumeWarning(flags)) }
+ }
+
+ override fun volumeChanged(streamType: Int, flags: Int) {
+ launch { send(VolumeControllerEvent.VolumeChanged(streamType, flags)) }
+ }
+
+ override fun masterMuteChanged(flags: Int) {
+ launch { send(VolumeControllerEvent.MasterMuteChanged(flags)) }
+ }
+
+ override fun setLayoutDirection(layoutDirection: Int) {
+ launch { send(VolumeControllerEvent.SetLayoutDirection(layoutDirection)) }
+ }
+
+ override fun dismiss() {
+ launch { send(VolumeControllerEvent.Dismiss) }
+ }
+
+ override fun setA11yMode(mode: Int) {
+ launch { send(VolumeControllerEvent.SetA11yMode(mode)) }
+ }
+
+ override fun displayCsdWarning(
+ csdWarning: Int,
+ displayDurationMs: Int,
+ ) {
+ launch {
+ send(
+ VolumeControllerEvent.DisplayCsdWarning(
+ csdWarning,
+ displayDurationMs,
+ )
+ )
+ }
+ }
+ }
+ awaitClose { volumeController = null }
+ }
+ .buffer()
+
+/** Models events received via [IVolumeController] */
+sealed interface VolumeControllerEvent {
+
+ /** @see [IVolumeController.displaySafeVolumeWarning] */
+ data class DisplaySafeVolumeWarning(val flags: Int) : VolumeControllerEvent
+
+ /** @see [IVolumeController.volumeChanged] */
+ data class VolumeChanged(val streamType: Int, val flags: Int) : VolumeControllerEvent
+
+ /** @see [IVolumeController.masterMuteChanged] */
+ data class MasterMuteChanged(val flags: Int) : VolumeControllerEvent
+
+ /** @see [IVolumeController.setLayoutDirection] */
+ data class SetLayoutDirection(val layoutDirection: Int) : VolumeControllerEvent
+
+ /** @see [IVolumeController.setA11yMode] */
+ data class SetA11yMode(val mode: Int) : VolumeControllerEvent
+
+ /** @see [IVolumeController.displayCsdWarning] */
+ data class DisplayCsdWarning(
+ val csdWarning: Int,
+ val displayDurationMs: Int,
+ ) : VolumeControllerEvent
+
+ /** @see [IVolumeController.dismiss] */
+ data object Dismiss : VolumeControllerEvent
+} \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
index 8868837e4cff..4028b73a2c71 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
@@ -105,12 +105,6 @@ public class DataServiceUtils {
public static final String COLUMN_CARD_STATE = "cardState";
/**
- * The name of the extended APDU supported state column, see
- * {@link UiccSlotInfo#getIsExtendedApduSupported()}.
- */
- public static final String COLUMN_IS_EXTENDED_APDU_SUPPORTED = "isExtendedApduSupported";
-
- /**
* The name of the removable state column, see {@link UiccSlotInfo#isRemovable()}.
*/
public static final String COLUMN_IS_REMOVABLE = "isRemovable";
@@ -150,74 +144,17 @@ public class DataServiceUtils {
public static final String COLUMN_SIM_SLOT_INDEX = "simSlotIndex";
/**
- * The name of the carrier ID column, see {@link SubscriptionInfo#getCarrierId()}.
- */
- public static final String COLUMN_CARRIER_ID = "carrierId";
-
- /**
- * The name of the display name column, see {@link SubscriptionInfo#getDisplayName()}.
- */
- public static final String COLUMN_DISPLAY_NAME = "displayName";
-
- /**
- * The name of the carrier name column, see {@link SubscriptionInfo#getCarrierName()}.
- */
- public static final String COLUMN_CARRIER_NAME = "carrierName";
-
- /**
- * The name of the data roaming state column, see
- * {@link SubscriptionInfo#getDataRoaming()}.
- */
- public static final String COLUMN_DATA_ROAMING = "dataRoaming";
-
- /**
- * The name of the mcc column, see {@link SubscriptionInfo#getMccString()}.
- */
- public static final String COLUMN_MCC = "mcc";
-
- /**
- * The name of the mnc column, see {@link SubscriptionInfo#getMncString()}.
- */
- public static final String COLUMN_MNC = "mnc";
-
- /**
- * The name of the country ISO column, see {@link SubscriptionInfo#getCountryIso()}.
- */
- public static final String COLUMN_COUNTRY_ISO = "countryIso";
-
- /**
* The name of the embedded state column, see {@link SubscriptionInfo#isEmbedded()}.
*/
public static final String COLUMN_IS_EMBEDDED = "isEmbedded";
/**
- * The name of the card ID column, see {@link SubscriptionInfo#getCardId()}.
- */
- public static final String COLUMN_CARD_ID = "cardId";
-
- /**
- * The name of the port index column, see {@link SubscriptionInfo#getPortIndex()}.
- */
- public static final String COLUMN_PORT_INDEX = "portIndex";
-
- /**
* The name of the opportunistic state column, see
* {@link SubscriptionInfo#isOpportunistic()}.
*/
public static final String COLUMN_IS_OPPORTUNISTIC = "isOpportunistic";
/**
- * The name of the groupUUID column, see {@link SubscriptionInfo#getGroupUuid()}.
- */
- public static final String COLUMN_GROUP_UUID = "groupUUID";
-
- /**
- * The name of the subscription type column, see
- * {@link SubscriptionInfo#getSubscriptionType()}}.
- */
- public static final String COLUMN_SUBSCRIPTION_TYPE = "subscriptionType";
-
- /**
* The name of the uniqueName column,
* {@see SubscriptionUtil#getUniqueSubscriptionDisplayName(SubscriptionInfo, Context)}.
*/
@@ -231,19 +168,6 @@ public class DataServiceUtils {
public static final String COLUMN_IS_SUBSCRIPTION_VISIBLE = "isSubscriptionVisible";
/**
- * The name of the formatted phone number column,
- * {@see SubscriptionUtil#getFormattedPhoneNumber(Context, SubscriptionInfo)}.
- */
- public static final String COLUMN_FORMATTED_PHONE_NUMBER = "getFormattedPhoneNumber";
-
- /**
- * The name of the first removable subscription state column,
- * {@see SubscriptionUtil#getFirstRemovableSubscription(Context)}.
- */
- public static final String COLUMN_IS_FIRST_REMOVABLE_SUBSCRIPTION =
- "isFirstRemovableSubscription";
-
- /**
* The name of the default subscription selection column,
* {@see SubscriptionUtil#getSubscriptionOrDefault(Context, int)}.
*/
@@ -257,24 +181,12 @@ public class DataServiceUtils {
public static final String COLUMN_IS_VALID_SUBSCRIPTION = "isValidSubscription";
/**
- * The name of the usable subscription column,
- * {@link SubscriptionManager#isUsableSubscriptionId(int)}.
- */
- public static final String COLUMN_IS_USABLE_SUBSCRIPTION = "isUsableSubscription";
-
- /**
* The name of the active subscription column,
* {@link SubscriptionManager#isActiveSubscriptionId(int)}.
*/
public static final String COLUMN_IS_ACTIVE_SUBSCRIPTION_ID = "isActiveSubscription";
/**
- * The name of the available subscription column,
- * {@see SubscriptionUtil#getAvailableSubscription(Context, ProxySubscriptionManager, int)}.
- */
- public static final String COLUMN_IS_AVAILABLE_SUBSCRIPTION = "isAvailableSubscription";
-
- /**
* The name of the active data subscription state column, see
* {@link SubscriptionManager#getActiveDataSubscriptionId()}.
*/
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoDao.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoDao.java
index e6b1cfb440fa..060eab6681c6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoDao.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoDao.java
@@ -40,15 +40,6 @@ public interface SubscriptionInfoDao {
+ DataServiceUtils.SubscriptionInfoData.COLUMN_ID + " = :subId")
SubscriptionInfoEntity querySubInfoById(String subId);
- @Query("SELECT * FROM " + DataServiceUtils.SubscriptionInfoData.TABLE_NAME + " WHERE "
- + DataServiceUtils.SubscriptionInfoData.COLUMN_IS_ACTIVE_SUBSCRIPTION_ID
- + " = :isActiveSubscription" + " AND "
- + DataServiceUtils.SubscriptionInfoData.COLUMN_IS_SUBSCRIPTION_VISIBLE
- + " = :isSubscriptionVisible" + " ORDER BY "
- + DataServiceUtils.SubscriptionInfoData.COLUMN_SIM_SLOT_INDEX)
- LiveData<List<SubscriptionInfoEntity>> queryActiveSubInfos(
- boolean isActiveSubscription, boolean isSubscriptionVisible);
-
@Query("SELECT COUNT(*) FROM " + DataServiceUtils.SubscriptionInfoData.TABLE_NAME)
int count();
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoEntity.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoEntity.java
index 361a24612b3a..88e6a57bf45b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoEntity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoEntity.java
@@ -19,7 +19,6 @@ package com.android.settingslib.mobile.dataservice;
import android.text.TextUtils;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@@ -28,39 +27,19 @@ import java.util.Objects;
@Entity(tableName = DataServiceUtils.SubscriptionInfoData.TABLE_NAME)
public class SubscriptionInfoEntity {
- public SubscriptionInfoEntity(@NonNull String subId, int simSlotIndex, int carrierId,
- String displayName, String carrierName, int dataRoaming, String mcc, String mnc,
- String countryIso, boolean isEmbedded, int cardId, int portIndex,
- boolean isOpportunistic, @Nullable String groupUUID, int subscriptionType,
- String uniqueName, boolean isSubscriptionVisible, @Nullable String formattedPhoneNumber,
- boolean isFirstRemovableSubscription, boolean isDefaultSubscriptionSelection,
- boolean isValidSubscription, boolean isUsableSubscription,
- boolean isActiveSubscriptionId, boolean isAvailableSubscription,
- boolean isActiveDataSubscriptionId) {
+ public SubscriptionInfoEntity(@NonNull String subId, int simSlotIndex, boolean isEmbedded,
+ boolean isOpportunistic, String uniqueName, boolean isSubscriptionVisible,
+ boolean isDefaultSubscriptionSelection, boolean isValidSubscription,
+ boolean isActiveSubscriptionId, boolean isActiveDataSubscriptionId) {
this.subId = subId;
this.simSlotIndex = simSlotIndex;
- this.carrierId = carrierId;
- this.displayName = displayName;
- this.carrierName = carrierName;
- this.dataRoaming = dataRoaming;
- this.mcc = mcc;
- this.mnc = mnc;
- this.countryIso = countryIso;
this.isEmbedded = isEmbedded;
- this.cardId = cardId;
- this.portIndex = portIndex;
this.isOpportunistic = isOpportunistic;
- this.groupUUID = groupUUID;
- this.subscriptionType = subscriptionType;
this.uniqueName = uniqueName;
this.isSubscriptionVisible = isSubscriptionVisible;
- this.formattedPhoneNumber = formattedPhoneNumber;
- this.isFirstRemovableSubscription = isFirstRemovableSubscription;
this.isDefaultSubscriptionSelection = isDefaultSubscriptionSelection;
this.isValidSubscription = isValidSubscription;
- this.isUsableSubscription = isUsableSubscription;
this.isActiveSubscriptionId = isActiveSubscriptionId;
- this.isAvailableSubscription = isAvailableSubscription;
this.isActiveDataSubscriptionId = isActiveDataSubscriptionId;
}
@@ -72,59 +51,18 @@ public class SubscriptionInfoEntity {
@ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_SIM_SLOT_INDEX)
public int simSlotIndex;
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_CARRIER_ID)
- public int carrierId;
-
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_DISPLAY_NAME)
- public String displayName;
-
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_CARRIER_NAME)
- public String carrierName;
-
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_DATA_ROAMING)
- public int dataRoaming;
-
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_MCC)
- public String mcc;
-
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_MNC)
- public String mnc;
-
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_COUNTRY_ISO)
- public String countryIso;
-
@ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_IS_EMBEDDED)
public boolean isEmbedded;
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_CARD_ID)
- public int cardId;
-
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_PORT_INDEX)
- public int portIndex;
-
@ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_IS_OPPORTUNISTIC)
public boolean isOpportunistic;
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_GROUP_UUID)
- @Nullable
- public String groupUUID;
-
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_SUBSCRIPTION_TYPE)
- public int subscriptionType;
-
@ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_UNIQUE_NAME)
public String uniqueName;
@ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_IS_SUBSCRIPTION_VISIBLE)
public boolean isSubscriptionVisible;
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_FORMATTED_PHONE_NUMBER)
- @Nullable
- public String formattedPhoneNumber;
-
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_IS_FIRST_REMOVABLE_SUBSCRIPTION)
- public boolean isFirstRemovableSubscription;
-
@ColumnInfo(name =
DataServiceUtils.SubscriptionInfoData.COLUMN_IS_DEFAULT_SUBSCRIPTION_SELECTION)
public boolean isDefaultSubscriptionSelection;
@@ -132,15 +70,9 @@ public class SubscriptionInfoEntity {
@ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_IS_VALID_SUBSCRIPTION)
public boolean isValidSubscription;
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_IS_USABLE_SUBSCRIPTION)
- public boolean isUsableSubscription;
-
@ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_IS_ACTIVE_SUBSCRIPTION_ID)
public boolean isActiveSubscriptionId;
- @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_IS_AVAILABLE_SUBSCRIPTION)
- public boolean isAvailableSubscription;
-
@ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_IS_ACTIVE_DATA_SUBSCRIPTION)
public boolean isActiveDataSubscriptionId;
@@ -165,28 +97,13 @@ public class SubscriptionInfoEntity {
return Objects.hash(
subId,
simSlotIndex,
- carrierId,
- displayName,
- carrierName,
- dataRoaming,
- mcc,
- mnc,
- countryIso,
isEmbedded,
- cardId,
- portIndex,
isOpportunistic,
- groupUUID,
- subscriptionType,
uniqueName,
isSubscriptionVisible,
- formattedPhoneNumber,
- isFirstRemovableSubscription,
isDefaultSubscriptionSelection,
isValidSubscription,
- isUsableSubscription,
isActiveSubscriptionId,
- isAvailableSubscription,
isActiveDataSubscriptionId);
}
@@ -202,28 +119,13 @@ public class SubscriptionInfoEntity {
SubscriptionInfoEntity info = (SubscriptionInfoEntity) obj;
return TextUtils.equals(subId, info.subId)
&& simSlotIndex == info.simSlotIndex
- && carrierId == info.carrierId
- && TextUtils.equals(displayName, info.displayName)
- && TextUtils.equals(carrierName, info.carrierName)
- && dataRoaming == info.dataRoaming
- && TextUtils.equals(mcc, info.mcc)
- && TextUtils.equals(mnc, info.mnc)
- && TextUtils.equals(countryIso, info.countryIso)
&& isEmbedded == info.isEmbedded
- && cardId == info.cardId
- && portIndex == info.portIndex
&& isOpportunistic == info.isOpportunistic
- && TextUtils.equals(groupUUID, info.groupUUID)
- && subscriptionType == info.subscriptionType
&& TextUtils.equals(uniqueName, info.uniqueName)
&& isSubscriptionVisible == info.isSubscriptionVisible
- && TextUtils.equals(formattedPhoneNumber, info.formattedPhoneNumber)
- && isFirstRemovableSubscription == info.isFirstRemovableSubscription
&& isDefaultSubscriptionSelection == info.isDefaultSubscriptionSelection
&& isValidSubscription == info.isValidSubscription
- && isUsableSubscription == info.isUsableSubscription
&& isActiveSubscriptionId == info.isActiveSubscriptionId
- && isAvailableSubscription == info.isAvailableSubscription
&& isActiveDataSubscriptionId == info.isActiveDataSubscriptionId;
}
@@ -233,50 +135,20 @@ public class SubscriptionInfoEntity {
.append(subId)
.append(", simSlotIndex = ")
.append(simSlotIndex)
- .append(", carrierId = ")
- .append(carrierId)
- .append(", displayName = ")
- .append(displayName)
- .append(", carrierName = ")
- .append(carrierName)
- .append(", dataRoaming = ")
- .append(dataRoaming)
- .append(", mcc = ")
- .append(mcc)
- .append(", mnc = ")
- .append(mnc)
- .append(", countryIso = ")
- .append(countryIso)
.append(", isEmbedded = ")
.append(isEmbedded)
- .append(", cardId = ")
- .append(cardId)
- .append(", portIndex = ")
- .append(portIndex)
.append(", isOpportunistic = ")
.append(isOpportunistic)
- .append(", groupUUID = ")
- .append(groupUUID)
- .append(", subscriptionType = ")
- .append(subscriptionType)
.append(", uniqueName = ")
.append(uniqueName)
.append(", isSubscriptionVisible = ")
.append(isSubscriptionVisible)
- .append(", formattedPhoneNumber = ")
- .append(formattedPhoneNumber)
- .append(", isFirstRemovableSubscription = ")
- .append(isFirstRemovableSubscription)
.append(", isDefaultSubscriptionSelection = ")
.append(isDefaultSubscriptionSelection)
.append(", isValidSubscription = ")
.append(isValidSubscription)
- .append(", isUsableSubscription = ")
- .append(isUsableSubscription)
.append(", isActiveSubscriptionId = ")
.append(isActiveSubscriptionId)
- .append(", isAvailableSubscription = ")
- .append(isAvailableSubscription)
.append(", isActiveDataSubscriptionId = ")
.append(isActiveDataSubscriptionId)
.append(")}");
diff --git a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/FakeZenModeRepository.kt b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt
index 775e2fc47b47..7886e85cbad8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/FakeZenModeRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt
@@ -14,10 +14,13 @@
* limitations under the License.
*/
-package com.android.settingslib.statusbar.notification.data.repository
+package com.android.settingslib.notification.data.repository
import android.app.NotificationManager
import android.provider.Settings
+import com.android.settingslib.notification.modes.TestModeBuilder
+import com.android.settingslib.notification.modes.ZenMode
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -32,6 +35,11 @@ class FakeZenModeRepository : ZenModeRepository {
override val globalZenMode: StateFlow<Int>
get() = mutableZenMode.asStateFlow()
+ private val mutableModesFlow: MutableStateFlow<List<ZenMode>> =
+ MutableStateFlow(listOf(TestModeBuilder.EXAMPLE))
+ override val modes: Flow<List<ZenMode>>
+ get() = mutableModesFlow.asStateFlow()
+
init {
updateNotificationPolicy()
}
@@ -43,6 +51,20 @@ class FakeZenModeRepository : ZenModeRepository {
fun updateZenMode(zenMode: Int) {
mutableZenMode.value = zenMode
}
+
+ fun addMode(id: String, active: Boolean = false) {
+ mutableModesFlow.value += newMode(id, active)
+ }
+
+ fun removeMode(id: String) {
+ mutableModesFlow.value = mutableModesFlow.value.filter { it.id != id }
+ }
+
+ fun deactivateMode(id: String) {
+ val oldMode = mutableModesFlow.value.find { it.id == id } ?: return
+ removeMode(id)
+ mutableModesFlow.value += TestModeBuilder(oldMode).setActive(false).build()
+ }
}
fun FakeZenModeRepository.updateNotificationPolicy(
@@ -61,5 +83,8 @@ fun FakeZenModeRepository.updateNotificationPolicy(
suppressedVisualEffects,
state,
priorityConversationSenders,
- )
- )
+ ))
+
+private fun newMode(id: String, active: Boolean = false): ZenMode {
+ return TestModeBuilder().setId(id).setName("Mode $id").setActive(active).build()
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/ZenModeRepository.kt b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/ZenModeRepository.kt
index 4d25237757ea..b2fcb5f6da41 100644
--- a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/ZenModeRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/ZenModeRepository.kt
@@ -14,21 +14,32 @@
* limitations under the License.
*/
-package com.android.settingslib.statusbar.notification.data.repository
+package com.android.settingslib.notification.data.repository
+import android.annotation.SuppressLint
import android.app.NotificationManager
+import android.app.NotificationManager.EXTRA_NOTIFICATION_POLICY
import android.content.BroadcastReceiver
+import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
+import android.database.ContentObserver
+import android.os.Handler
+import android.provider.Settings
import com.android.settingslib.flags.Flags
+import com.android.settingslib.notification.modes.ZenMode
+import com.android.settingslib.notification.modes.ZenModesBackend
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
@@ -43,21 +54,30 @@ interface ZenModeRepository {
/** @see NotificationManager.getZenMode */
val globalZenMode: StateFlow<Int?>
+
+ /** A list of all existing priority modes. */
+ val modes: Flow<List<ZenMode>>
}
+@SuppressLint("SharedFlowCreation")
class ZenModeRepositoryImpl(
private val context: Context,
private val notificationManager: NotificationManager,
+ private val backend: ZenModesBackend,
+ private val contentResolver: ContentResolver,
val scope: CoroutineScope,
val backgroundCoroutineContext: CoroutineContext,
+ // This is nullable just to simplify testing, since SettingsLib doesn't have a good way
+ // to create a fake handler.
+ val backgroundHandler: Handler?,
) : ZenModeRepository {
- private val notificationBroadcasts =
+ private val notificationBroadcasts by lazy {
callbackFlow {
val receiver =
object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
- intent?.action?.let { action -> launch { send(action) } }
+ intent?.let { launch { send(it) } }
}
}
@@ -69,42 +89,93 @@ class ZenModeRepositoryImpl(
if (Flags.volumePanelBroadcastFix() && android.app.Flags.modesApi())
addAction(
NotificationManager.ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED)
- })
+ },
+ /* broadcastPermission = */ null,
+ /* scheduler = */ if (Flags.volumePanelBroadcastFix()) {
+ backgroundHandler
+ } else {
+ null
+ },
+ )
awaitClose { context.unregisterReceiver(receiver) }
}
- .apply {
+ .let {
if (Flags.volumePanelBroadcastFix()) {
- flowOn(backgroundCoroutineContext)
- stateIn(scope, SharingStarted.WhileSubscribed(), null)
+ // Share the flow to avoid having multiple broadcasts.
+ it.flowOn(backgroundCoroutineContext)
+ .shareIn(started = SharingStarted.WhileSubscribed(), scope = scope)
} else {
- shareIn(
- started = SharingStarted.WhileSubscribed(),
- scope = scope,
- )
+ it.shareIn(started = SharingStarted.WhileSubscribed(), scope = scope)
}
}
+ }
- override val consolidatedNotificationPolicy: StateFlow<NotificationManager.Policy?> =
+ override val consolidatedNotificationPolicy: StateFlow<NotificationManager.Policy?> by lazy {
if (Flags.volumePanelBroadcastFix() && android.app.Flags.modesApi())
flowFromBroadcast(NotificationManager.ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED) {
- notificationManager.consolidatedNotificationPolicy
+ // If available, get the value from extras to avoid a potential binder call.
+ it?.extras?.getParcelable(EXTRA_NOTIFICATION_POLICY)
+ ?: notificationManager.consolidatedNotificationPolicy
}
else
flowFromBroadcast(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED) {
notificationManager.consolidatedNotificationPolicy
}
+ }
- override val globalZenMode: StateFlow<Int?> =
+ override val globalZenMode: StateFlow<Int?> by lazy {
flowFromBroadcast(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED) {
notificationManager.zenMode
}
+ }
- private fun <T> flowFromBroadcast(intentAction: String, mapper: () -> T) =
+ private fun <T> flowFromBroadcast(intentAction: String, mapper: (Intent?) -> T) =
notificationBroadcasts
- .filter { intentAction == it }
- .map { mapper() }
- .onStart { emit(mapper()) }
+ .filter { intentAction == it.action }
+ .map { mapper(it) }
+ .onStart { emit(mapper(null)) }
.flowOn(backgroundCoroutineContext)
.stateIn(scope, SharingStarted.WhileSubscribed(), null)
+
+ private val zenConfigChanged by lazy {
+ if (android.app.Flags.modesUi()) {
+ callbackFlow {
+ // emit an initial value
+ trySend(Unit)
+
+ val observer =
+ object : ContentObserver(backgroundHandler) {
+ override fun onChange(selfChange: Boolean) {
+ trySend(Unit)
+ }
+ }
+
+ contentResolver.registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.ZEN_MODE),
+ /* notifyForDescendants= */ false,
+ observer)
+ contentResolver.registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.ZEN_MODE_CONFIG_ETAG),
+ /* notifyForDescendants= */ false,
+ observer)
+
+ awaitClose { contentResolver.unregisterContentObserver(observer) }
+ }
+ .flowOn(backgroundCoroutineContext)
+ } else {
+ flowOf(Unit)
+ }
+ }
+
+ override val modes: Flow<List<ZenMode>> by lazy {
+ if (android.app.Flags.modesUi()) {
+ zenConfigChanged
+ .map { backend.modes }
+ .distinctUntilChanged()
+ .flowOn(backgroundCoroutineContext)
+ } else {
+ flowOf(emptyList())
+ }
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt b/packages/SettingsLib/src/com/android/settingslib/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt
index 953c90d35d78..0c2ce4ffa765 100644
--- a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package com.android.settingslib.statusbar.notification.domain.interactor
+package com.android.settingslib.notification.domain.interactor
import android.app.NotificationManager
import android.media.AudioManager
import android.provider.Settings
import android.service.notification.ZenModeConfig
-import com.android.settingslib.statusbar.notification.data.repository.ZenModeRepository
+import com.android.settingslib.notification.data.repository.ZenModeRepository
import com.android.settingslib.volume.shared.model.AudioStream
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableZenModeDialog.java
index dfa5ed12b7dd..054c84952fae 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableZenModeDialog.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settingslib.notification;
+package com.android.settingslib.notification.modes;
import android.app.ActivityManager;
import android.app.AlarmManager;
@@ -96,7 +96,7 @@ public class EnableZenModeDialog {
protected LinearLayout mZenRadioGroupContent;
private RadioGroup mZenRadioGroup;
- private int MAX_MANUAL_DND_OPTIONS = 3;
+ private static final int MAX_MANUAL_DND_OPTIONS = 3;
@VisibleForTesting
protected LayoutInflater mLayoutInflater;
@@ -119,9 +119,9 @@ public class EnableZenModeDialog {
}
public AlertDialog createDialog() {
- mNotificationManager = (NotificationManager) mContext.
- getSystemService(Context.NOTIFICATION_SERVICE);
- mForeverId = Condition.newId(mContext).appendPath("forever").build();
+ mNotificationManager = (NotificationManager) mContext
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ mForeverId = Condition.newId(mContext).appendPath("forever").build();
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
mUserId = mContext.getUserId();
mAttached = false;
@@ -171,8 +171,8 @@ public class EnableZenModeDialog {
}
private void hideAllConditions() {
- final int N = mZenRadioGroupContent.getChildCount();
- for (int i = 0; i < N; i++) {
+ final int n = mZenRadioGroupContent.getChildCount();
+ for (int i = 0; i < n; i++) {
mZenRadioGroupContent.getChildAt(i).setVisibility(View.GONE);
}
@@ -221,8 +221,10 @@ public class EnableZenModeDialog {
}
tag.condition = condition;
final Uri conditionId = getConditionId(tag.condition);
- if (DEBUG) Log.d(TAG, "bind i=" + mZenRadioGroupContent.indexOfChild(row) + " first="
- + first + " condition=" + conditionId);
+ if (DEBUG) {
+ Log.d(TAG, "bind i=" + mZenRadioGroupContent.indexOfChild(row) + " first="
+ + first + " condition=" + conditionId);
+ }
tag.rb.setEnabled(enabled);
tag.rb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
@@ -447,14 +449,14 @@ public class EnableZenModeDialog {
private void onClickTimeButton(View row, ConditionTag tag, boolean up, int rowId) {
mMetricsLogger.logOnClickTimeButton(up);
Condition newCondition = null;
- final int N = MINUTE_BUCKETS.length;
+ final int n = MINUTE_BUCKETS.length;
if (mBucketIndex == -1) {
// not on a known index, search for the next or prev bucket by time
final Uri conditionId = getConditionId(tag.condition);
final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
final long now = System.currentTimeMillis();
- for (int i = 0; i < N; i++) {
- int j = up ? i : N - 1 - i;
+ for (int i = 0; i < n; i++) {
+ int j = up ? i : n - 1 - i;
final int bucketMinutes = MINUTE_BUCKETS[j];
final long bucketTime = now + bucketMinutes * MINUTES_MS;
if (up && bucketTime > time || !up && bucketTime < time) {
@@ -472,7 +474,7 @@ public class EnableZenModeDialog {
}
} else {
// on a known index, simply increment or decrement
- mBucketIndex = Math.max(0, Math.min(N - 1, mBucketIndex + (up ? 1 : -1)));
+ mBucketIndex = Math.max(0, Math.min(n - 1, mBucketIndex + (up ? 1 : -1)));
newCondition = ZenModeConfig.toTimeCondition(mContext,
MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java
new file mode 100644
index 000000000000..7b994d59d963
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java
@@ -0,0 +1,176 @@
+/*
+ * 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.settingslib.notification.modes;
+
+import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.net.Uri;
+import android.service.notification.Condition;
+import android.service.notification.ZenDeviceEffects;
+import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenPolicy;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.Nullable;
+
+import java.util.Random;
+
+public class TestModeBuilder {
+
+ private String mId;
+ private AutomaticZenRule mRule;
+ private ZenModeConfig.ZenRule mConfigZenRule;
+
+ public static final ZenMode EXAMPLE = new TestModeBuilder().build();
+
+ public TestModeBuilder() {
+ // Reasonable defaults
+ int id = new Random().nextInt(1000);
+ mId = "rule_" + id;
+ mRule = new AutomaticZenRule.Builder("Test Rule #" + id, Uri.parse("rule://" + id))
+ .setPackage("some_package")
+ .setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY)
+ .setZenPolicy(new ZenPolicy.Builder().disallowAllSounds().build())
+ .build();
+ mConfigZenRule = new ZenModeConfig.ZenRule();
+ mConfigZenRule.enabled = true;
+ mConfigZenRule.pkg = "some_package";
+ }
+
+ public TestModeBuilder(ZenMode previous) {
+ mId = previous.getId();
+ mRule = previous.getRule();
+
+ mConfigZenRule = new ZenModeConfig.ZenRule();
+ mConfigZenRule.enabled = previous.getRule().isEnabled();
+ mConfigZenRule.pkg = previous.getRule().getPackageName();
+ setActive(previous.isActive());
+ }
+
+ public TestModeBuilder setId(String id) {
+ mId = id;
+ return this;
+ }
+
+ public TestModeBuilder setAzr(AutomaticZenRule rule) {
+ mRule = rule;
+ mConfigZenRule.pkg = rule.getPackageName();
+ mConfigZenRule.conditionId = rule.getConditionId();
+ mConfigZenRule.enabled = rule.isEnabled();
+ return this;
+ }
+
+ public TestModeBuilder setConfigZenRule(ZenModeConfig.ZenRule configZenRule) {
+ mConfigZenRule = configZenRule;
+ return this;
+ }
+
+ public TestModeBuilder setName(String name) {
+ mRule.setName(name);
+ mConfigZenRule.name = name;
+ return this;
+ }
+
+ public TestModeBuilder setPackage(String pkg) {
+ mRule.setPackageName(pkg);
+ mConfigZenRule.pkg = pkg;
+ return this;
+ }
+
+ public TestModeBuilder setOwner(ComponentName owner) {
+ mRule.setOwner(owner);
+ mConfigZenRule.component = owner;
+ return this;
+ }
+
+ public TestModeBuilder setConfigurationActivity(ComponentName configActivity) {
+ mRule.setConfigurationActivity(configActivity);
+ mConfigZenRule.configurationActivity = configActivity;
+ return this;
+ }
+
+ public TestModeBuilder setConditionId(Uri conditionId) {
+ mRule.setConditionId(conditionId);
+ mConfigZenRule.conditionId = conditionId;
+ return this;
+ }
+
+ public TestModeBuilder setType(@AutomaticZenRule.Type int type) {
+ mRule.setType(type);
+ mConfigZenRule.type = type;
+ return this;
+ }
+
+ public TestModeBuilder setInterruptionFilter(
+ @NotificationManager.InterruptionFilter int interruptionFilter) {
+ mRule.setInterruptionFilter(interruptionFilter);
+ mConfigZenRule.zenMode = NotificationManager.zenModeFromInterruptionFilter(
+ interruptionFilter, NotificationManager.INTERRUPTION_FILTER_PRIORITY);
+ return this;
+ }
+
+ public TestModeBuilder setZenPolicy(@Nullable ZenPolicy policy) {
+ mRule.setZenPolicy(policy);
+ mConfigZenRule.zenPolicy = policy;
+ return this;
+ }
+
+ public TestModeBuilder setDeviceEffects(@Nullable ZenDeviceEffects deviceEffects) {
+ mRule.setDeviceEffects(deviceEffects);
+ mConfigZenRule.zenDeviceEffects = deviceEffects;
+ return this;
+ }
+
+ public TestModeBuilder setEnabled(boolean enabled) {
+ mRule.setEnabled(enabled);
+ mConfigZenRule.enabled = enabled;
+ return this;
+ }
+
+ public TestModeBuilder setManualInvocationAllowed(boolean allowed) {
+ mRule.setManualInvocationAllowed(allowed);
+ mConfigZenRule.allowManualInvocation = allowed;
+ return this;
+ }
+
+ public TestModeBuilder setTriggerDescription(@Nullable String triggerDescription) {
+ mRule.setTriggerDescription(triggerDescription);
+ mConfigZenRule.triggerDescription = triggerDescription;
+ return this;
+ }
+
+ public TestModeBuilder setIconResId(@DrawableRes int iconResId) {
+ mRule.setIconResId(iconResId);
+ return this;
+ }
+
+ public TestModeBuilder setActive(boolean active) {
+ if (active) {
+ mConfigZenRule.enabled = true;
+ mConfigZenRule.condition = new Condition(mRule.getConditionId(), "...",
+ Condition.STATE_TRUE);
+ } else {
+ mConfigZenRule.condition = null;
+ }
+ return this;
+ }
+
+ public ZenMode build() {
+ return new ZenMode(mId, mRule, mConfigZenRule);
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenDurationDialog.java
index abbdaa73c18e..98c3edba8223 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenDurationDialog.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settingslib.notification;
+package com.android.settingslib.notification.modes;
import android.app.ActivityManager;
import android.app.Dialog;
@@ -46,22 +46,31 @@ import java.util.Arrays;
public class ZenDurationDialog {
private static final int[] MINUTE_BUCKETS = ZenModeConfig.MINUTE_BUCKETS;
- @VisibleForTesting protected static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
- @VisibleForTesting protected static final int MAX_BUCKET_MINUTES =
+ @VisibleForTesting
+ protected static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
+ @VisibleForTesting
+ protected static final int MAX_BUCKET_MINUTES =
MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1];
private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60);
- @VisibleForTesting protected int mBucketIndex = -1;
+ @VisibleForTesting
+ protected int mBucketIndex = -1;
- @VisibleForTesting protected static final int FOREVER_CONDITION_INDEX = 0;
- @VisibleForTesting protected static final int COUNTDOWN_CONDITION_INDEX = 1;
- @VisibleForTesting protected static final int ALWAYS_ASK_CONDITION_INDEX = 2;
+ @VisibleForTesting
+ protected static final int FOREVER_CONDITION_INDEX = 0;
+ @VisibleForTesting
+ protected static final int COUNTDOWN_CONDITION_INDEX = 1;
+ @VisibleForTesting
+ protected static final int ALWAYS_ASK_CONDITION_INDEX = 2;
- @VisibleForTesting protected Context mContext;
- @VisibleForTesting protected LinearLayout mZenRadioGroupContent;
+ @VisibleForTesting
+ protected Context mContext;
+ @VisibleForTesting
+ protected LinearLayout mZenRadioGroupContent;
private RadioGroup mZenRadioGroup;
- private int MAX_MANUAL_DND_OPTIONS = 3;
+ private static final int MAX_MANUAL_DND_OPTIONS = 3;
- @VisibleForTesting protected LayoutInflater mLayoutInflater;
+ @VisibleForTesting
+ protected LayoutInflater mLayoutInflater;
public ZenDurationDialog(Context context) {
mContext = context;
@@ -104,22 +113,22 @@ public class ZenDurationDialog {
case FOREVER_CONDITION_INDEX:
newZenDuration = Settings.Secure.ZEN_DURATION_FOREVER;
MetricsLogger.action(mContext,
- MetricsProto.MetricsEvent.
- NOTIFICATION_ZEN_MODE_DURATION_FOREVER);
+ MetricsProto.MetricsEvent
+ .NOTIFICATION_ZEN_MODE_DURATION_FOREVER);
break;
case COUNTDOWN_CONDITION_INDEX:
ConditionTag tag = getConditionTagAt(checkedRadioButtonId);
newZenDuration = tag.countdownZenDuration;
MetricsLogger.action(mContext,
- MetricsProto.MetricsEvent.
- NOTIFICATION_ZEN_MODE_DURATION_TIME,
+ MetricsProto.MetricsEvent
+ .NOTIFICATION_ZEN_MODE_DURATION_TIME,
newZenDuration);
break;
case ALWAYS_ASK_CONDITION_INDEX:
newZenDuration = Settings.Secure.ZEN_DURATION_PROMPT;
MetricsLogger.action(mContext,
- MetricsProto.MetricsEvent.
- NOTIFICATION_ZEN_MODE_DURATION_PROMPT);
+ MetricsProto.MetricsEvent
+ .NOTIFICATION_ZEN_MODE_DURATION_PROMPT);
break;
}
@@ -299,12 +308,12 @@ public class ZenDurationDialog {
@VisibleForTesting
protected void onClickTimeButton(View row, ConditionTag tag, boolean up, int rowId) {
int newDndTimeDuration = -1;
- final int N = MINUTE_BUCKETS.length;
+ final int n = MINUTE_BUCKETS.length;
if (mBucketIndex == -1) {
// not on a known index, search for the next or prev bucket by time
final long time = tag.countdownZenDuration;
- for (int i = 0; i < N; i++) {
- int j = up ? i : N - 1 - i;
+ for (int i = 0; i < n; i++) {
+ int j = up ? i : n - 1 - i;
final int bucketMinutes = MINUTE_BUCKETS[j];
if (up && bucketMinutes > time || !up && bucketMinutes < time) {
mBucketIndex = j;
@@ -318,7 +327,7 @@ public class ZenDurationDialog {
}
} else {
// on a known index, simply increment or decrement
- mBucketIndex = Math.max(0, Math.min(N - 1, mBucketIndex + (up ? 1 : -1)));
+ mBucketIndex = Math.max(0, Math.min(n - 1, mBucketIndex + (up ? 1 : -1)));
newDndTimeDuration = MINUTE_BUCKETS[mBucketIndex];
}
tag.countdownZenDuration = newDndTimeDuration;
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java
index 3f19830c9114..960df63b24bf 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java
@@ -20,6 +20,7 @@ import static com.google.common.util.concurrent.Futures.immediateFuture;
import static java.util.Objects.requireNonNull;
+import android.annotation.DrawableRes;
import android.annotation.Nullable;
import android.app.AutomaticZenRule;
import android.content.Context;
@@ -120,7 +121,14 @@ public class ZenIconLoader {
}
private static Drawable getFallbackIcon(Context context, int ruleType) {
- int iconResIdFromType = switch (ruleType) {
+ int iconResIdFromType = getIconResourceIdFromType(ruleType);
+ return requireNonNull(context.getDrawable(iconResIdFromType));
+ }
+
+ /** Return the default icon resource associated to a {@link AutomaticZenRule.Type} */
+ @DrawableRes
+ public static int getIconResourceIdFromType(@AutomaticZenRule.Type int ruleType) {
+ return switch (ruleType) {
case AutomaticZenRule.TYPE_UNKNOWN ->
com.android.internal.R.drawable.ic_zen_mode_type_unknown;
case AutomaticZenRule.TYPE_OTHER ->
@@ -141,7 +149,6 @@ public class ZenIconLoader {
com.android.internal.R.drawable.ic_zen_mode_type_managed;
default -> com.android.internal.R.drawable.ic_zen_mode_type_unknown;
};
- return requireNonNull(context.getDrawable(iconResIdFromType));
}
private static Drawable getMonochromeIconIfPresent(Drawable icon) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
index 33d39f000663..03a2b7526f62 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
@@ -23,6 +23,7 @@ import static android.service.notification.SystemZenRules.getTriggerDescriptionF
import static android.service.notification.ZenModeConfig.tryParseEventConditionId;
import static android.service.notification.ZenModeConfig.tryParseScheduleConditionId;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
@@ -33,12 +34,15 @@ import android.app.NotificationManager;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.service.notification.SystemZenRules;
import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
import android.util.Log;
+import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -56,11 +60,12 @@ import java.util.Objects;
* <p>It also adapts other rule features that we don't want to expose in the UI, such as
* interruption filters other than {@code PRIORITY}, rules without specific icons, etc.
*/
-public class ZenMode {
+public class ZenMode implements Parcelable {
private static final String TAG = "ZenMode";
static final String MANUAL_DND_MODE_ID = "manual_dnd";
+ static final String TEMP_NEW_MODE_ID = "temp_new_mode";
// Must match com.android.server.notification.ZenModeHelper#applyCustomPolicy.
private static final ZenPolicy POLICY_INTERRUPTION_FILTER_ALARMS =
@@ -125,6 +130,25 @@ public class ZenMode {
isActive ? Status.ENABLED_AND_ACTIVE : Status.ENABLED, true);
}
+ /**
+ * Returns a new {@link ZenMode} instance that can represent a custom_manual mode that is in the
+ * process of being created (and not yet saved).
+ *
+ * @param name mode name
+ * @param iconResId resource id of the chosen icon, {code 0} if none.
+ */
+ public static ZenMode newCustomManual(String name, @DrawableRes int iconResId) {
+ AutomaticZenRule rule = new AutomaticZenRule.Builder(name,
+ ZenModeConfig.toCustomManualConditionId())
+ .setPackage(ZenModeConfig.getCustomManualConditionProvider().getPackageName())
+ .setType(AutomaticZenRule.TYPE_OTHER)
+ .setOwner(ZenModeConfig.getCustomManualConditionProvider())
+ .setIconResId(iconResId)
+ .setManualInvocationAllowed(true)
+ .build();
+ return new ZenMode(TEMP_NEW_MODE_ID, rule, Status.ENABLED, false);
+ }
+
private ZenMode(String id, @NonNull AutomaticZenRule rule, Status status, boolean isManualDnd) {
mId = id;
mRule = rule;
@@ -262,11 +286,7 @@ public class ZenMode {
mRule, oldCondition, conditionId));
}
- public boolean canEditName() {
- return !isManualDnd();
- }
-
- public boolean canEditIcon() {
+ public boolean canEditNameAndIcon() {
return !isManualDnd();
}
@@ -304,4 +324,34 @@ public class ZenMode {
public String toString() {
return mId + " (" + mStatus + ") -> " + mRule;
}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mId);
+ dest.writeParcelable(mRule, 0);
+ dest.writeString(mStatus.name());
+ dest.writeBoolean(mIsManualDnd);
+ }
+
+ public static final Creator<ZenMode> CREATOR = new Creator<ZenMode>() {
+ @Override
+ public ZenMode createFromParcel(Parcel in) {
+ return new ZenMode(
+ in.readString(),
+ checkNotNull(in.readParcelable(AutomaticZenRule.class.getClassLoader(),
+ AutomaticZenRule.class)),
+ Status.valueOf(in.readString()),
+ in.readBoolean());
+ }
+
+ @Override
+ public ZenMode[] newArray(int size) {
+ return new ZenMode[size];
+ }
+ };
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ZenModeDialogMetricsLogger.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModeDialogMetricsLogger.java
index 088a37d995ed..17695e396bef 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/ZenModeDialogMetricsLogger.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModeDialogMetricsLogger.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settingslib.notification;
+package com.android.settingslib.notification.modes;
import android.content.Context;
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java
index 5529da009329..d36e2fe8cfc3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java
@@ -27,6 +27,8 @@ import android.service.notification.Condition;
import android.service.notification.ZenModeConfig;
import android.util.Log;
+import androidx.annotation.DrawableRes;
+
import com.android.settingslib.R;
import java.time.Duration;
@@ -184,18 +186,13 @@ public class ZenModesBackend {
* Creates a new custom mode with the provided {@code name}. The mode will be "manual" (i.e.
* not have a schedule), this can be later updated by the user in the mode settings page.
*
+ * @param name mode name
+ * @param iconResId resource id of the chosen icon, {code 0} if none.
* @return the created mode. Only {@code null} if creation failed due to an internal error
*/
@Nullable
- public ZenMode addCustomMode(String name) {
- AutomaticZenRule rule = new AutomaticZenRule.Builder(name,
- ZenModeConfig.toCustomManualConditionId())
- .setPackage(ZenModeConfig.getCustomManualConditionProvider().getPackageName())
- .setType(AutomaticZenRule.TYPE_OTHER)
- .setOwner(ZenModeConfig.getCustomManualConditionProvider())
- .setManualInvocationAllowed(true)
- .build();
-
+ public ZenMode addCustomManualMode(String name, @DrawableRes int iconResId) {
+ AutomaticZenRule rule = ZenMode.newCustomManual(name, iconResId).getRule();
String ruleId = mNotificationManager.addAutomaticZenRule(rule);
return getMode(ruleId);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ZenRadioLayout.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenRadioLayout.java
index 1140028b1ca4..ed659f922484 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/ZenRadioLayout.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenRadioLayout.java
@@ -1,18 +1,20 @@
/*
* 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
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package com.android.settingslib.notification;
+package com.android.settingslib.notification.modes;
import android.content.Context;
import android.util.AttributeSet;
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt
index 9dbf23eba7a5..eb33a7a10524 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt
@@ -16,33 +16,84 @@
package com.android.settingslib.volume.data.repository
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothCsipSetCoordinator
+import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothLeBroadcast
import android.bluetooth.BluetoothLeBroadcastMetadata
+import android.bluetooth.BluetoothProfile
+import android.bluetooth.BluetoothVolumeControl
+import android.content.ContentResolver
+import android.content.Context
+import android.database.ContentObserver
+import android.provider.Settings
+import androidx.annotation.IntRange
import com.android.internal.util.ConcurrentUtils
+import com.android.settingslib.bluetooth.BluetoothUtils
import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.settingslib.bluetooth.onProfileConnectionStateChanged
+import com.android.settingslib.bluetooth.onSourceConnectedOrRemoved
import com.android.settingslib.flags.Flags
+import com.android.settingslib.volume.data.repository.AudioSharingRepository.Companion.AUDIO_SHARING_VOLUME_MAX
+import com.android.settingslib.volume.data.repository.AudioSharingRepository.Companion.AUDIO_SHARING_VOLUME_MIN
import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.runningFold
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+typealias GroupIdToVolumes = Map<Int, Int>
/** Provides audio sharing functionality. */
interface AudioSharingRepository {
/** Whether the device is in audio sharing. */
val inAudioSharing: Flow<Boolean>
+
+ /** The secondary headset groupId in audio sharing. */
+ val secondaryGroupId: StateFlow<Int>
+
+ /** The headset groupId to volume map during audio sharing. */
+ val volumeMap: StateFlow<GroupIdToVolumes>
+
+ /** Set the volume of secondary headset during audio sharing. */
+ suspend fun setSecondaryVolume(
+ @IntRange(from = AUDIO_SHARING_VOLUME_MIN.toLong(), to = AUDIO_SHARING_VOLUME_MAX.toLong())
+ volume: Int
+ )
+
+ companion object {
+ const val AUDIO_SHARING_VOLUME_MIN = 0
+ const val AUDIO_SHARING_VOLUME_MAX = 255
+ }
}
+@OptIn(ExperimentalCoroutinesApi::class)
class AudioSharingRepositoryImpl(
- private val localBluetoothManager: LocalBluetoothManager?,
- backgroundCoroutineContext: CoroutineContext,
+ private val context: Context,
+ private val contentResolver: ContentResolver,
+ private val btManager: LocalBluetoothManager?,
+ private val coroutineScope: CoroutineScope,
+ private val backgroundCoroutineContext: CoroutineContext,
) : AudioSharingRepository {
override val inAudioSharing: Flow<Boolean> =
if (Flags.enableLeAudioSharing()) {
- localBluetoothManager?.profileManager?.leAudioBroadcastProfile?.let { leBroadcast ->
+ btManager?.profileManager?.leAudioBroadcastProfile?.let { leBroadcast ->
callbackFlow {
val listener =
object : BluetoothLeBroadcast.Callback {
@@ -92,9 +143,117 @@ class AudioSharingRepositoryImpl(
flowOf(false)
}
+ private val primaryChange: Flow<Unit> = callbackFlow {
+ val callback =
+ object : ContentObserver(null) {
+ override fun onChange(selfChange: Boolean) {
+ launch { send(Unit) }
+ }
+ }
+ contentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(BluetoothUtils.getPrimaryGroupIdUriForBroadcast()),
+ false,
+ callback)
+ awaitClose { contentResolver.unregisterContentObserver(callback) }
+ }
+
+ override val secondaryGroupId: StateFlow<Int> =
+ if (Flags.volumeDialogAudioSharingFix()) {
+ merge(
+ btManager
+ ?.profileManager
+ ?.leAudioBroadcastAssistantProfile
+ ?.onSourceConnectedOrRemoved
+ ?.map { getSecondaryGroupId() } ?: emptyFlow(),
+ btManager
+ ?.eventManager
+ ?.onProfileConnectionStateChanged
+ ?.filter { profileConnection ->
+ profileConnection.state == BluetoothAdapter.STATE_DISCONNECTED &&
+ profileConnection.bluetoothProfile ==
+ BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT
+ }
+ ?.map { getSecondaryGroupId() } ?: emptyFlow(),
+ primaryChange.map { getSecondaryGroupId() })
+ .onStart { emit(getSecondaryGroupId()) }
+ .distinctUntilChanged()
+ .flowOn(backgroundCoroutineContext)
+ } else {
+ emptyFlow()
+ }
+ .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), getSecondaryGroupId())
+
+ override val volumeMap: StateFlow<GroupIdToVolumes> =
+ if (Flags.volumeDialogAudioSharingFix()) {
+ btManager?.profileManager?.volumeControlProfile?.let { volumeControl ->
+ inAudioSharing.flatMapLatest { isSharing ->
+ if (isSharing) {
+ callbackFlow {
+ val callback =
+ object : BluetoothVolumeControl.Callback {
+ override fun onDeviceVolumeChanged(
+ device: BluetoothDevice,
+ @IntRange(
+ from = AUDIO_SHARING_VOLUME_MIN.toLong(),
+ to = AUDIO_SHARING_VOLUME_MAX.toLong())
+ volume: Int
+ ) {
+ launch { send(Pair(device, volume)) }
+ }
+ }
+ // Once registered, we will receive the initial volume of all
+ // connected BT devices on VolumeControlProfile via callbacks
+ volumeControl.registerCallback(
+ ConcurrentUtils.DIRECT_EXECUTOR, callback)
+ awaitClose { volumeControl.unregisterCallback(callback) }
+ }
+ .runningFold(emptyMap<Int, Int>()) { acc, value ->
+ val groupId =
+ BluetoothUtils.getGroupId(
+ btManager.cachedDeviceManager?.findDevice(value.first))
+ if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
+ acc + Pair(groupId, value.second)
+ } else {
+ acc
+ }
+ }
+ .distinctUntilChanged()
+ .flowOn(backgroundCoroutineContext)
+ } else {
+ emptyFlow()
+ }
+ }
+ } ?: emptyFlow()
+ } else {
+ emptyFlow()
+ }
+ .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), emptyMap())
+
+ override suspend fun setSecondaryVolume(
+ @IntRange(from = AUDIO_SHARING_VOLUME_MIN.toLong(), to = AUDIO_SHARING_VOLUME_MAX.toLong())
+ volume: Int
+ ) {
+ withContext(backgroundCoroutineContext) {
+ if (Flags.volumeDialogAudioSharingFix()) {
+ btManager?.profileManager?.volumeControlProfile?.let {
+ // Find secondary headset and set volume.
+ val cachedDevice =
+ BluetoothUtils.getSecondaryDeviceForBroadcast(context, btManager)
+ if (cachedDevice != null) {
+ it.setDeviceVolume(cachedDevice.device, volume, /* isGroupOp= */ true)
+ }
+ }
+ }
+ }
+ }
+
private fun isBroadcasting(): Boolean {
return Flags.enableLeAudioSharing() &&
- (localBluetoothManager?.profileManager?.leAudioBroadcastProfile?.isEnabled(null)
- ?: false)
+ (btManager?.profileManager?.leAudioBroadcastProfile?.isEnabled(null) ?: false)
+ }
+
+ private fun getSecondaryGroupId(): Int {
+ return BluetoothUtils.getGroupId(
+ BluetoothUtils.getSecondaryDeviceForBroadcast(context, btManager))
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt b/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt
index 202ff400782f..08863b56cbe0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt
@@ -17,7 +17,7 @@
package com.android.settingslib.volume.domain.interactor
import android.media.AudioManager
-import com.android.settingslib.statusbar.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
import com.android.settingslib.volume.data.repository.AudioRepository
import com.android.settingslib.volume.shared.model.AudioStream
import com.android.settingslib.volume.shared.model.AudioStreamModel
@@ -61,6 +61,10 @@ class AudioVolumeInteractor(
}
suspend fun setMuted(audioStream: AudioStream, isMuted: Boolean) {
+ val streamModel = getAudioStream(audioStream).first()
+ if (!streamModel.isAffectedByMute) {
+ return
+ }
if (audioStream.value == AudioManager.STREAM_RING) {
val mode =
if (isMuted) AudioManager.RINGER_MODE_VIBRATE else AudioManager.RINGER_MODE_NORMAL
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExtTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExtTest.kt
new file mode 100644
index 000000000000..83b612df8dc9
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExtTest.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.settingslib.media.data.repository
+
+import android.media.AudioManager
+import android.media.IVolumeController
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AudioManagerVolumeControllerExtTest {
+
+ private val testScope = TestScope()
+
+ @Captor private lateinit var volumeControllerCaptor: ArgumentCaptor<IVolumeController>
+ @Mock private lateinit var audioManager: AudioManager
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ }
+
+ @Test
+ fun displaySafeVolumeWarning_emitsEvent() =
+ testEvent(VolumeControllerEvent.DisplaySafeVolumeWarning(1)) { displaySafeVolumeWarning(1) }
+
+ @Test
+ fun volumeChanged_emitsEvent() =
+ testEvent(VolumeControllerEvent.VolumeChanged(1, 2)) { volumeChanged(1, 2) }
+
+ @Test
+ fun masterMuteChanged_emitsEvent() =
+ testEvent(VolumeControllerEvent.MasterMuteChanged(1)) { masterMuteChanged(1) }
+
+ @Test
+ fun setLayoutDirection_emitsEvent() =
+ testEvent(VolumeControllerEvent.SetLayoutDirection(1)) { setLayoutDirection(1) }
+
+ @Test
+ fun setA11yMode_emitsEvent() =
+ testEvent(VolumeControllerEvent.SetA11yMode(1)) { setA11yMode(1) }
+
+ @Test
+ fun displayCsdWarning_emitsEvent() =
+ testEvent(VolumeControllerEvent.DisplayCsdWarning(1, 2)) { displayCsdWarning(1, 2) }
+
+ @Test fun dismiss_emitsEvent() = testEvent(VolumeControllerEvent.Dismiss) { dismiss() }
+
+ private fun testEvent(
+ expectedEvent: VolumeControllerEvent,
+ emit: IVolumeController.() -> Unit,
+ ) =
+ testScope.runTest {
+ var event: VolumeControllerEvent? = null
+ audioManager.volumeControllerEvents().onEach { event = it }.launchIn(backgroundScope)
+ runCurrent()
+ verify(audioManager).volumeController = volumeControllerCaptor.capture()
+
+ volumeControllerCaptor.value.emit()
+ runCurrent()
+
+ assertThat(event).isEqualTo(expectedEvent)
+ }
+}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt
index 1c80ef4fe4d4..000664dd1552 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt
@@ -16,15 +16,33 @@
package com.android.settingslib.volume.data.repository
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothLeBroadcast
+import android.bluetooth.BluetoothLeBroadcastAssistant
+import android.bluetooth.BluetoothLeBroadcastReceiveState
+import android.bluetooth.BluetoothProfile
+import android.bluetooth.BluetoothVolumeControl
+import android.content.ContentResolver
+import android.content.Context
+import android.database.ContentObserver
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
+import android.provider.Settings
+import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.settingslib.bluetooth.BluetoothCallback
+import com.android.settingslib.bluetooth.BluetoothEventManager
+import com.android.settingslib.bluetooth.BluetoothUtils
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant
import com.android.settingslib.bluetooth.LocalBluetoothManager
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager
+import com.android.settingslib.bluetooth.VolumeControlProfile
import com.android.settingslib.flags.Flags
import com.google.common.truth.Truth
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -39,6 +57,9 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.never
@@ -52,27 +73,76 @@ import org.mockito.junit.MockitoRule
@RunWith(AndroidJUnit4::class)
class AudioSharingRepositoryTest {
@get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
+
@get:Rule val setFlagsRule: SetFlagsRule = SetFlagsRule()
- @Mock private lateinit var localBluetoothManager: LocalBluetoothManager
- @Mock private lateinit var localBluetoothProfileManager: LocalBluetoothProfileManager
- @Mock private lateinit var localBluetoothLeBroadcast: LocalBluetoothLeBroadcast
+ @Mock private lateinit var btManager: LocalBluetoothManager
+
+ @Mock private lateinit var profileManager: LocalBluetoothProfileManager
+
+ @Mock private lateinit var broadcast: LocalBluetoothLeBroadcast
+
+ @Mock private lateinit var assistant: LocalBluetoothLeBroadcastAssistant
+
+ @Mock private lateinit var volumeControl: VolumeControlProfile
+
+ @Mock private lateinit var eventManager: BluetoothEventManager
+
+ @Mock private lateinit var deviceManager: CachedBluetoothDeviceManager
+
+ @Mock private lateinit var device1: BluetoothDevice
+
+ @Mock private lateinit var device2: BluetoothDevice
+
+ @Mock private lateinit var cachedDevice1: CachedBluetoothDevice
+
+ @Mock private lateinit var cachedDevice2: CachedBluetoothDevice
+
+ @Mock private lateinit var receiveState: BluetoothLeBroadcastReceiveState
+
+ @Mock private lateinit var contentResolver: ContentResolver
@Captor
- private lateinit var leBroadcastCallbackCaptor: ArgumentCaptor<BluetoothLeBroadcast.Callback>
- private val testScope = TestScope()
+ private lateinit var broadcastCallbackCaptor: ArgumentCaptor<BluetoothLeBroadcast.Callback>
+
+ @Captor
+ private lateinit var assistantCallbackCaptor:
+ ArgumentCaptor<BluetoothLeBroadcastAssistant.Callback>
+
+ @Captor private lateinit var btCallbackCaptor: ArgumentCaptor<BluetoothCallback>
+
+ @Captor private lateinit var contentObserverCaptor: ArgumentCaptor<ContentObserver>
+ @Captor
+ private lateinit var volumeCallbackCaptor: ArgumentCaptor<BluetoothVolumeControl.Callback>
+
+ private val testScope = TestScope()
+ private val context: Context = ApplicationProvider.getApplicationContext()
private lateinit var underTest: AudioSharingRepository
@Before
fun setup() {
- `when`(localBluetoothManager.profileManager).thenReturn(localBluetoothProfileManager)
- `when`(localBluetoothProfileManager.leAudioBroadcastProfile)
- .thenReturn(localBluetoothLeBroadcast)
- `when`(localBluetoothLeBroadcast.isEnabled(null)).thenReturn(true)
+ `when`(btManager.profileManager).thenReturn(profileManager)
+ `when`(profileManager.leAudioBroadcastProfile).thenReturn(broadcast)
+ `when`(profileManager.leAudioBroadcastAssistantProfile).thenReturn(assistant)
+ `when`(profileManager.volumeControlProfile).thenReturn(volumeControl)
+ `when`(btManager.eventManager).thenReturn(eventManager)
+ `when`(btManager.cachedDeviceManager).thenReturn(deviceManager)
+ `when`(broadcast.isEnabled(null)).thenReturn(true)
+ `when`(cachedDevice1.groupId).thenReturn(TEST_GROUP_ID1)
+ `when`(cachedDevice1.device).thenReturn(device1)
+ `when`(deviceManager.findDevice(device1)).thenReturn(cachedDevice1)
+ `when`(cachedDevice2.groupId).thenReturn(TEST_GROUP_ID2)
+ `when`(cachedDevice2.device).thenReturn(device2)
+ `when`(deviceManager.findDevice(device2)).thenReturn(cachedDevice2)
+ `when`(receiveState.bisSyncState).thenReturn(arrayListOf(TEST_RECEIVE_STATE_CONTENT))
+ `when`(assistant.getAllSources(any())).thenReturn(listOf(receiveState))
underTest =
AudioSharingRepositoryImpl(
- localBluetoothManager,
+ context,
+ contentResolver,
+ btManager,
+ testScope.backgroundScope,
testScope.testScheduler,
)
}
@@ -84,9 +154,9 @@ class AudioSharingRepositoryTest {
val states = mutableListOf<Boolean?>()
underTest.inAudioSharing.onEach { states.add(it) }.launchIn(backgroundScope)
runCurrent()
- triggerAudioSharingStateChange(false)
+ triggerAudioSharingStateChange(TriggerType.BROADCAST_STOP, broadcastStopped)
runCurrent()
- triggerAudioSharingStateChange(true)
+ triggerAudioSharingStateChange(TriggerType.BROADCAST_START, broadcastStarted)
runCurrent()
Truth.assertThat(states).containsExactly(true, false, true)
@@ -102,19 +172,229 @@ class AudioSharingRepositoryTest {
runCurrent()
Truth.assertThat(states).containsExactly(false)
- verify(localBluetoothLeBroadcast, never()).registerServiceCallBack(any(), any())
- verify(localBluetoothLeBroadcast, never()).isEnabled(any())
+ verify(broadcast, never()).registerServiceCallBack(any(), any())
+ verify(broadcast, never()).isEnabled(any())
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_VOLUME_DIALOG_AUDIO_SHARING_FIX)
+ fun secondaryGroupIdChange_emitValues() {
+ testScope.runTest {
+ val groupIds = mutableListOf<Int?>()
+ underTest.secondaryGroupId.onEach { groupIds.add(it) }.launchIn(backgroundScope)
+ runCurrent()
+ triggerSourceAdded()
+ runCurrent()
+ triggerContentObserverChange()
+ runCurrent()
+ triggerSourceRemoved()
+ runCurrent()
+ triggerSourceAdded()
+ runCurrent()
+ triggerProfileConnectionChange(
+ BluetoothAdapter.STATE_CONNECTING, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)
+ runCurrent()
+ triggerProfileConnectionChange(
+ BluetoothAdapter.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO)
+ runCurrent()
+ triggerProfileConnectionChange(
+ BluetoothAdapter.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)
+ runCurrent()
+
+ Truth.assertThat(groupIds)
+ .containsExactly(
+ TEST_GROUP_ID_INVALID,
+ TEST_GROUP_ID2,
+ TEST_GROUP_ID1,
+ TEST_GROUP_ID_INVALID,
+ TEST_GROUP_ID2,
+ TEST_GROUP_ID_INVALID)
}
}
- private fun triggerAudioSharingStateChange(inAudioSharing: Boolean) {
- verify(localBluetoothLeBroadcast)
- .registerServiceCallBack(any(), leBroadcastCallbackCaptor.capture())
- `when`(localBluetoothLeBroadcast.isEnabled(null)).thenReturn(inAudioSharing)
- if (inAudioSharing) {
- leBroadcastCallbackCaptor.value.onBroadcastStarted(0, 0)
- } else {
- leBroadcastCallbackCaptor.value.onBroadcastStopped(0, 0)
+ @Test
+ @DisableFlags(Flags.FLAG_VOLUME_DIALOG_AUDIO_SHARING_FIX)
+ fun secondaryGroupIdChange_audioSharingFlagOff_returnFalse() {
+ testScope.runTest {
+ val groupIds = mutableListOf<Int?>()
+ underTest.secondaryGroupId.onEach { groupIds.add(it) }.launchIn(backgroundScope)
+ runCurrent()
+
+ Truth.assertThat(groupIds).containsExactly(TEST_GROUP_ID_INVALID)
+ verify(assistant, never()).registerServiceCallBack(any(), any())
+ verify(eventManager, never()).registerCallback(any())
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_VOLUME_DIALOG_AUDIO_SHARING_FIX)
+ fun volumeMapChange_emitValues() {
+ testScope.runTest {
+ val volumeMaps = mutableListOf<GroupIdToVolumes?>()
+ underTest.volumeMap.onEach { volumeMaps.add(it) }.launchIn(backgroundScope)
+ runCurrent()
+ triggerVolumeMapChange(Pair(device1, TEST_VOLUME1))
+ runCurrent()
+ triggerVolumeMapChange(Pair(device1, TEST_VOLUME2))
+ runCurrent()
+ triggerAudioSharingStateChange(TriggerType.BROADCAST_STOP, broadcastStopped)
+ runCurrent()
+ verify(volumeControl).unregisterCallback(any())
+ runCurrent()
+
+ Truth.assertThat(volumeMaps)
+ .containsExactly(
+ emptyMap<Int, Int>(),
+ mapOf(TEST_GROUP_ID1 to TEST_VOLUME1),
+ mapOf(TEST_GROUP_ID1 to TEST_VOLUME2))
+ }
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_VOLUME_DIALOG_AUDIO_SHARING_FIX)
+ fun volumeMapChange_audioSharingFlagOff_returnFalse() {
+ testScope.runTest {
+ val volumeMaps = mutableListOf<GroupIdToVolumes?>()
+ underTest.volumeMap.onEach { volumeMaps.add(it) }.launchIn(backgroundScope)
+ runCurrent()
+
+ Truth.assertThat(volumeMaps).isEmpty()
+ verify(broadcast, never()).registerServiceCallBack(any(), any())
+ verify(volumeControl, never()).registerCallback(any(), any())
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_VOLUME_DIALOG_AUDIO_SHARING_FIX)
+ fun setSecondaryVolume_setValue() {
+ testScope.runTest {
+ Settings.Secure.putInt(
+ context.contentResolver,
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+ TEST_GROUP_ID2)
+ `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2))
+ underTest.setSecondaryVolume(TEST_VOLUME1)
+
+ runCurrent()
+ verify(volumeControl).setDeviceVolume(device1, TEST_VOLUME1, true)
+ }
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_VOLUME_DIALOG_AUDIO_SHARING_FIX)
+ fun setSecondaryVolume_audioSharingFlagOff_doNothing() {
+ testScope.runTest {
+ Settings.Secure.putInt(
+ context.contentResolver,
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+ TEST_GROUP_ID2)
+ `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2))
+ underTest.setSecondaryVolume(TEST_VOLUME1)
+
+ runCurrent()
+ verify(volumeControl, never()).setDeviceVolume(any(), anyInt(), anyBoolean())
+ }
+ }
+
+ private fun triggerAudioSharingStateChange(
+ type: TriggerType,
+ broadcastAction: BluetoothLeBroadcast.Callback.() -> Unit
+ ) {
+ verify(broadcast).registerServiceCallBack(any(), broadcastCallbackCaptor.capture())
+ when (type) {
+ TriggerType.BROADCAST_START -> {
+ `when`(broadcast.isEnabled(null)).thenReturn(true)
+ broadcastCallbackCaptor.value.broadcastAction()
+ }
+ TriggerType.BROADCAST_STOP -> {
+ `when`(broadcast.isEnabled(null)).thenReturn(false)
+ broadcastCallbackCaptor.value.broadcastAction()
+ }
+ }
+ }
+
+ private fun triggerSourceAdded() {
+ verify(assistant).registerServiceCallBack(any(), assistantCallbackCaptor.capture())
+ Settings.Secure.putInt(
+ context.contentResolver,
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+ TEST_GROUP_ID1)
+ `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2))
+ assistantCallbackCaptor.value.sourceAdded(device1, receiveState)
+ }
+
+ private fun triggerSourceRemoved() {
+ verify(assistant).registerServiceCallBack(any(), assistantCallbackCaptor.capture())
+ `when`(assistant.allConnectedDevices).thenReturn(listOf(device1))
+ Settings.Secure.putInt(
+ context.contentResolver,
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+ TEST_GROUP_ID1)
+ assistantCallbackCaptor.value.sourceRemoved(device2)
+ }
+
+ private fun triggerProfileConnectionChange(state: Int, profile: Int) {
+ verify(eventManager).registerCallback(btCallbackCaptor.capture())
+ `when`(assistant.allConnectedDevices).thenReturn(listOf(device1))
+ Settings.Secure.putInt(
+ context.contentResolver,
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+ TEST_GROUP_ID1)
+ btCallbackCaptor.value.onProfileConnectionStateChanged(cachedDevice2, state, profile)
+ }
+
+ private fun triggerContentObserverChange() {
+ verify(contentResolver)
+ .registerContentObserver(
+ eq(Settings.Secure.getUriFor(BluetoothUtils.getPrimaryGroupIdUriForBroadcast())),
+ eq(false),
+ contentObserverCaptor.capture())
+ `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2))
+ Settings.Secure.putInt(
+ context.contentResolver,
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+ TEST_GROUP_ID2)
+ contentObserverCaptor.value.primaryChanged()
+ }
+
+ private fun triggerVolumeMapChange(change: Pair<BluetoothDevice, Int>) {
+ verify(volumeControl).registerCallback(any(), volumeCallbackCaptor.capture())
+ volumeCallbackCaptor.value.onDeviceVolumeChanged(change.first, change.second)
+ }
+
+ private enum class TriggerType {
+ BROADCAST_START,
+ BROADCAST_STOP
+ }
+
+ private companion object {
+ const val TEST_GROUP_ID_INVALID = -1
+ const val TEST_GROUP_ID1 = 1
+ const val TEST_GROUP_ID2 = 2
+ const val TEST_SOURCE_ID = 1
+ const val TEST_BROADCAST_ID = 1
+ const val TEST_REASON = 1
+ const val TEST_RECEIVE_STATE_CONTENT = 1L
+ const val TEST_VOLUME1 = 10
+ const val TEST_VOLUME2 = 20
+
+ val broadcastStarted: BluetoothLeBroadcast.Callback.() -> Unit = {
+ onBroadcastStarted(TEST_REASON, TEST_BROADCAST_ID)
+ }
+ val broadcastStopped: BluetoothLeBroadcast.Callback.() -> Unit = {
+ onBroadcastStopped(TEST_REASON, TEST_BROADCAST_ID)
}
+ val sourceAdded:
+ BluetoothLeBroadcastAssistant.Callback.(
+ sink: BluetoothDevice, state: BluetoothLeBroadcastReceiveState) -> Unit =
+ { sink, state ->
+ onReceiveStateChanged(sink, TEST_SOURCE_ID, state)
+ }
+ val sourceRemoved: BluetoothLeBroadcastAssistant.Callback.(sink: BluetoothDevice) -> Unit =
+ { sink ->
+ onSourceRemoved(sink, TEST_SOURCE_ID, TEST_REASON)
+ }
+ val primaryChanged: ContentObserver.() -> Unit = { onChange(false) }
}
}
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index 397fab129e39..75c40bfa8b60 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -52,6 +52,7 @@ android_robolectric_test {
"androidx.fragment_fragment",
"androidx.test.core",
"androidx.core_core",
+ "kotlinx_coroutines_test",
"flag-junit",
"settingslib_media_flags_lib",
"settingslib_illustrationpreference_flags_lib",
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
index a638df524740..28bf34882365 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
@@ -22,11 +22,13 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.content.Context;
@@ -36,10 +38,13 @@ import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.Uri;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Settings;
import android.util.Pair;
import com.android.settingslib.widget.AdaptiveIcon;
+import com.google.common.collect.ImmutableList;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -562,4 +567,77 @@ public class BluetoothUtilsTest {
assertThat(BluetoothUtils.isAvailableHearingDevice(mCachedBluetoothDevice)).isEqualTo(true);
}
+
+ @Test
+ public void getGroupId_getCsipProfileId() {
+ when(mCachedBluetoothDevice.getGroupId()).thenReturn(1);
+
+ assertThat(BluetoothUtils.getGroupId(mCachedBluetoothDevice)).isEqualTo(1);
+ }
+
+ @Test
+ public void getGroupId_getLeAudioProfileId() {
+ when(mCachedBluetoothDevice.getGroupId())
+ .thenReturn(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
+ when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+ LeAudioProfile leAudio = mock(LeAudioProfile.class);
+ when(leAudio.getGroupId(mBluetoothDevice)).thenReturn(1);
+ when(mCachedBluetoothDevice.getProfiles()).thenReturn(ImmutableList.of(leAudio));
+
+ assertThat(BluetoothUtils.getGroupId(mCachedBluetoothDevice)).isEqualTo(1);
+ }
+
+ @Test
+ public void getSecondaryDeviceForBroadcast_errorState_returnNull() {
+ assertThat(BluetoothUtils.getSecondaryDeviceForBroadcast(mContext, mLocalBluetoothManager))
+ .isNull();
+ }
+
+ @Test
+ public void getSecondaryDeviceForBroadcast_noSecondary_returnNull() {
+ Settings.Secure.putInt(
+ mContext.getContentResolver(),
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+ 1);
+ CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class);
+ when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager);
+ when(deviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
+ when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+ when(mCachedBluetoothDevice.getGroupId()).thenReturn(1);
+ BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
+ when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(ImmutableList.of(state));
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mBluetoothDevice));
+
+ assertThat(BluetoothUtils.getSecondaryDeviceForBroadcast(mContext, mLocalBluetoothManager))
+ .isNull();
+ }
+
+ @Test
+ public void getSecondaryDeviceForBroadcast_returnCorrectDevice() {
+ Settings.Secure.putInt(
+ mContext.getContentResolver(),
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+ 1);
+ CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class);
+ when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager);
+ CachedBluetoothDevice cachedBluetoothDevice = mock(CachedBluetoothDevice.class);
+ BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
+ when(cachedBluetoothDevice.getDevice()).thenReturn(bluetoothDevice);
+ when(cachedBluetoothDevice.getGroupId()).thenReturn(1);
+ when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+ when(mCachedBluetoothDevice.getGroupId()).thenReturn(2);
+ when(deviceManager.findDevice(bluetoothDevice)).thenReturn(cachedBluetoothDevice);
+ when(deviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
+ BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
+ List<Long> bisSyncState = new ArrayList<>();
+ bisSyncState.add(1L);
+ when(state.getBisSyncState()).thenReturn(bisSyncState);
+ when(mAssistant.getAllSources(any(BluetoothDevice.class)))
+ .thenReturn(ImmutableList.of(state));
+ when(mAssistant.getAllConnectedDevices())
+ .thenReturn(ImmutableList.of(mBluetoothDevice, bluetoothDevice));
+
+ assertThat(BluetoothUtils.getSecondaryDeviceForBroadcast(mContext, mLocalBluetoothManager))
+ .isEqualTo(mCachedBluetoothDevice);
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceStateTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceStateTest.java
new file mode 100644
index 000000000000..e8e1556b8fe7
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceStateTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class ActionSwitchPreferenceStateTest {
+
+ @Test
+ public void getMethods() {
+ ActionSwitchPreferenceState state1 =
+ new ActionSwitchPreferenceState.Builder()
+ .setChecked(true)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ ActionSwitchPreferenceState state2 =
+ new ActionSwitchPreferenceState.Builder()
+ .setChecked(false)
+ .setExtras(buildBundle("key2", "value2"))
+ .build();
+
+ assertThat(state1.getChecked()).isTrue();
+ assertThat(state2.getChecked()).isFalse();
+ assertThat(state1.getExtras().getString("key1")).isEqualTo("value1");
+ assertThat(state2.getExtras().getString("key2")).isEqualTo("value2");
+ }
+
+ @Test
+ public void parcelOperation_notChecked() {
+ ActionSwitchPreferenceState state =
+ new ActionSwitchPreferenceState.Builder()
+ .setChecked(false)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ ActionSwitchPreferenceState fromParcel = writeAndRead(state);
+
+ assertThat(fromParcel.getChecked()).isEqualTo(state.getChecked());
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(state.getExtras().getString("key1"));
+ }
+
+ @Test
+ public void parcelOperation_checked() {
+ ActionSwitchPreferenceState state =
+ new ActionSwitchPreferenceState.Builder()
+ .setChecked(true)
+ .setExtras(buildBundle("key2", "value2"))
+ .build();
+
+ ActionSwitchPreferenceState fromParcel = writeAndRead(state);
+
+ assertThat(fromParcel.getChecked()).isEqualTo(state.getChecked());
+ assertThat(fromParcel.getExtras().getString("key2"))
+ .isEqualTo(state.getExtras().getString("key2"));
+ }
+
+ private Bundle buildBundle(String key, String value) {
+ Bundle bundle = new Bundle();
+ bundle.putString(key, value);
+ return bundle;
+ }
+
+ private ActionSwitchPreferenceState writeAndRead(ActionSwitchPreferenceState state) {
+ Parcel parcel = Parcel.obtain();
+ state.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ ActionSwitchPreferenceState fromParcel =
+ ActionSwitchPreferenceState.CREATOR.createFromParcel(parcel);
+ return fromParcel;
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceTest.java
new file mode 100644
index 000000000000..354d0f658544
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceTest.java
@@ -0,0 +1,163 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class ActionSwitchPreferenceTest {
+
+ @Test
+ public void build_withoutTitle_fail() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> {
+ ActionSwitchPreference unused =
+ new ActionSwitchPreference.Builder().setSummary("summary").build();
+ });
+ }
+
+ @Test
+ public void build_withTitle_successfully() {
+ ActionSwitchPreference unused =
+ new ActionSwitchPreference.Builder().setTitle("title").build();
+ }
+
+ @Test
+ public void build_withAllFields_successfully() {
+ ActionSwitchPreference unused =
+ new ActionSwitchPreference.Builder()
+ .setTitle("title")
+ .setSummary("summary")
+ .setIntent(new Intent("intent_action"))
+ .setIcon(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888))
+ .setHasSwitch(true)
+ .setChecked(true)
+ .setAllowedChangingState(true)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ }
+
+ @Test
+ public void getMethods() {
+ Intent intent = new Intent("intent_action");
+ Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ ActionSwitchPreference preference = builder().setIcon(icon).setIntent(intent).build();
+
+ assertThat(preference.getTitle()).isEqualTo("title");
+ assertThat(preference.getSummary()).isEqualTo("summary");
+ assertThat(preference.getIcon()).isSameInstanceAs(icon);
+ assertThat(preference.getIntent()).isSameInstanceAs(intent);
+ assertThat(preference.hasSwitch()).isTrue();
+ assertThat(preference.getChecked()).isTrue();
+ assertThat(preference.isAllowedChangingState()).isTrue();
+ assertThat(preference.getExtras().getString("key1")).isEqualTo("value1");
+ }
+
+ @Test
+ public void parcelOperation() {
+ Intent intent = new Intent("intent_action");
+ Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ ActionSwitchPreference preference = builder().setIcon(icon).setIntent(intent).build();
+
+ ActionSwitchPreference fromParcel = writeAndRead(preference);
+
+ assertThat(fromParcel.getTitle()).isEqualTo(preference.getTitle());
+ assertThat(fromParcel.getSummary()).isEqualTo(preference.getSummary());
+ assertThat(fromParcel.getIcon().sameAs(preference.getIcon())).isTrue();
+ assertThat(fromParcel.getIntent().getAction()).isSameInstanceAs("intent_action");
+ assertThat(fromParcel.hasSwitch()).isEqualTo(preference.hasSwitch());
+ assertThat(fromParcel.getChecked()).isEqualTo(preference.getChecked());
+ assertThat(fromParcel.isAllowedChangingState())
+ .isEqualTo(preference.isAllowedChangingState());
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(preference.getExtras().getString("key1"));
+ }
+
+ @Test
+ public void parcelOperation_noIntent() {
+ Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ ActionSwitchPreference preference = builder().setIcon(icon).setIntent(null).build();
+
+ ActionSwitchPreference fromParcel = writeAndRead(preference);
+
+ assertThat(fromParcel.getTitle()).isEqualTo(preference.getTitle());
+ assertThat(fromParcel.getSummary()).isEqualTo(preference.getSummary());
+ assertThat(fromParcel.getIcon().sameAs(preference.getIcon())).isTrue();
+ assertThat(preference.getIntent()).isNull();
+ assertThat(fromParcel.hasSwitch()).isEqualTo(preference.hasSwitch());
+ assertThat(fromParcel.getChecked()).isEqualTo(preference.getChecked());
+ assertThat(fromParcel.isAllowedChangingState())
+ .isEqualTo(preference.isAllowedChangingState());
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(preference.getExtras().getString("key1"));
+ }
+
+ @Test
+ public void parcelOperation_noIcon() {
+ Intent intent = new Intent("intent_action");
+ ActionSwitchPreference preference = builder().setIcon(null).setIntent(intent).build();
+
+ ActionSwitchPreference fromParcel = writeAndRead(preference);
+
+ assertThat(fromParcel.getTitle()).isEqualTo(preference.getTitle());
+ assertThat(fromParcel.getSummary()).isEqualTo(preference.getSummary());
+ assertThat(fromParcel.getIcon()).isNull();
+ assertThat(fromParcel.getIntent().getAction()).isSameInstanceAs("intent_action");
+ assertThat(fromParcel.hasSwitch()).isEqualTo(preference.hasSwitch());
+ assertThat(fromParcel.getChecked()).isEqualTo(preference.getChecked());
+ assertThat(fromParcel.isAllowedChangingState())
+ .isEqualTo(preference.isAllowedChangingState());
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(preference.getExtras().getString("key1"));
+ }
+
+ private Bundle buildBundle(String key, String value) {
+ Bundle bundle = new Bundle();
+ bundle.putString(key, value);
+ return bundle;
+ }
+
+ private ActionSwitchPreference writeAndRead(ActionSwitchPreference preference) {
+ Parcel parcel = Parcel.obtain();
+ preference.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ ActionSwitchPreference fromParcel = ActionSwitchPreference.CREATOR.createFromParcel(parcel);
+ return fromParcel;
+ }
+
+ private ActionSwitchPreference.Builder builder() {
+ return new ActionSwitchPreference.Builder()
+ .setTitle("title")
+ .setSummary("summary")
+ .setHasSwitch(true)
+ .setChecked(true)
+ .setAllowedChangingState(true)
+ .setExtras(buildBundle("key1", "value1"));
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfoTest.java
new file mode 100644
index 000000000000..fd5b07508b52
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfoTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class DeviceInfoTest {
+ @Test
+ public void build_withoutBluetoothAddress_fail() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> {
+ DeviceInfo unused =
+ new DeviceInfo.Builder()
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ });
+ }
+
+ @Test
+ public void build_withoutExtra_successfully() {
+ DeviceInfo unused = new DeviceInfo.Builder().setBluetoothAddress("12:34:56:78").build();
+ }
+
+ @Test
+ public void build_withAllFields_successfully() {
+ DeviceInfo unused =
+ new DeviceInfo.Builder()
+ .setBluetoothAddress("12:34:56:78")
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ }
+
+ @Test
+ public void getMethods() {
+ DeviceInfo info =
+ new DeviceInfo.Builder()
+ .setBluetoothAddress("12:34:56:78")
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ assertThat(info.getBluetoothAddress()).isEqualTo("12:34:56:78");
+ assertThat(info.getExtras().getString("key1")).isEqualTo("value1");
+ }
+
+ @Test
+ public void parcelOperation() {
+ DeviceInfo info =
+ new DeviceInfo.Builder()
+ .setBluetoothAddress("12:34:56:78")
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ DeviceInfo fromParcel = writeAndRead(info);
+
+ assertThat(fromParcel.getBluetoothAddress()).isEqualTo(info.getBluetoothAddress());
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(info.getExtras().getString("key1"));
+ }
+
+ private Bundle buildBundle(String key, String value) {
+ Bundle bundle = new Bundle();
+ bundle.putString(key, value);
+ return bundle;
+ }
+
+ private DeviceInfo writeAndRead(DeviceInfo state) {
+ Parcel parcel = Parcel.obtain();
+ state.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ DeviceInfo fromParcel = DeviceInfo.CREATOR.createFromParcel(parcel);
+ return fromParcel;
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItemTest.kt b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItemTest.kt
new file mode 100644
index 000000000000..56e9b6c27925
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItemTest.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings
+
+import android.os.Bundle
+import android.os.Parcel
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class DeviceSettingItemTest {
+
+ @Test
+ fun parcelOperation() {
+ val item =
+ DeviceSettingItem(
+ settingId = 1,
+ packageName = "package_name",
+ className = "class_name",
+ intentAction = "intent_action",
+ extras = Bundle().apply { putString("key1", "value1") },
+ )
+
+ val fromParcel = writeAndRead(item)
+
+ assertThat(fromParcel.settingId).isEqualTo(item.settingId)
+ assertThat(fromParcel.packageName).isEqualTo(item.packageName)
+ assertThat(fromParcel.className).isEqualTo(item.className)
+ assertThat(fromParcel.intentAction).isEqualTo(item.intentAction)
+ assertThat(fromParcel.extras.getString("key1")).isEqualTo(item.extras.getString("key1"))
+ }
+
+ private fun writeAndRead(item: DeviceSettingItem): DeviceSettingItem {
+ val parcel = Parcel.obtain()
+ item.writeToParcel(parcel, 0)
+ parcel.setDataPosition(0)
+ return DeviceSettingItem.CREATOR.createFromParcel(parcel)
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingStateTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingStateTest.java
new file mode 100644
index 000000000000..12b7a0f0167c
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingStateTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class DeviceSettingStateTest {
+ private static final ActionSwitchPreferenceState ACTION_SWITCH_PREFERENCE_STATE =
+ new ActionSwitchPreferenceState.Builder().setChecked(true).build();
+ private static final MultiTogglePreferenceState MULTI_TOGGLE_PREFERENCE_STATE =
+ new MultiTogglePreferenceState.Builder().setState(123).build();
+
+ @Test
+ public void build_withoutPreferenceState_fail() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> {
+ DeviceSettingState unused =
+ new DeviceSettingState.Builder()
+ .setSettingId(123)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ });
+ }
+
+ @Test
+ public void build_withoutExtra_successfully() {
+ DeviceSettingState unused =
+ new DeviceSettingState.Builder()
+ .setSettingId(123)
+ .setPreferenceState(ACTION_SWITCH_PREFERENCE_STATE)
+ .build();
+ }
+
+ @Test
+ public void build_withAllFields_successfully() {
+ DeviceSettingState unused =
+ new DeviceSettingState.Builder()
+ .setSettingId(123)
+ .setPreferenceState(ACTION_SWITCH_PREFERENCE_STATE)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ }
+
+ @Test
+ public void getMethods_actionSwitchPreferenceState() {
+ DeviceSettingState state =
+ new DeviceSettingState.Builder()
+ .setSettingId(123)
+ .setPreferenceState(ACTION_SWITCH_PREFERENCE_STATE)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ assertThat(state.getSettingId()).isEqualTo(123);
+ assertThat(state.getPreferenceState()).isInstanceOf(ActionSwitchPreferenceState.class);
+ assertThat(state.getExtras().getString("key1")).isEqualTo("value1");
+ }
+
+ @Test
+ public void getMethods_multiTogglePreference() {
+ DeviceSettingState state =
+ new DeviceSettingState.Builder()
+ .setSettingId(123)
+ .setPreferenceState(MULTI_TOGGLE_PREFERENCE_STATE)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ assertThat(state.getSettingId()).isEqualTo(123);
+ assertThat(state.getPreferenceState()).isInstanceOf(MultiTogglePreferenceState.class);
+ assertThat(state.getExtras().getString("key1")).isEqualTo("value1");
+ }
+
+ @Test
+ public void parcelOperation_actionSwitchPreferenceState() {
+ DeviceSettingState state =
+ new DeviceSettingState.Builder()
+ .setSettingId(123)
+ .setPreferenceState(ACTION_SWITCH_PREFERENCE_STATE)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ DeviceSettingState fromParcel = writeAndRead(state);
+
+ assertThat(fromParcel.getSettingId()).isEqualTo(state.getSettingId());
+ assertThat(fromParcel.getPreferenceState()).isInstanceOf(ActionSwitchPreferenceState.class);
+ assertThat(fromParcel.getPreferenceState().getSettingType())
+ .isEqualTo(DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH);
+ assertThat(((ActionSwitchPreferenceState) fromParcel.getPreferenceState()).getChecked())
+ .isTrue();
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(state.getExtras().getString("key1"));
+ }
+
+ @Test
+ public void parcelOperation_multiTogglePreferenceState() {
+ DeviceSettingState state =
+ new DeviceSettingState.Builder()
+ .setSettingId(123)
+ .setPreferenceState(MULTI_TOGGLE_PREFERENCE_STATE)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ DeviceSettingState fromParcel = writeAndRead(state);
+
+ assertThat(fromParcel.getSettingId()).isEqualTo(state.getSettingId());
+ assertThat(fromParcel.getPreferenceState()).isInstanceOf(MultiTogglePreferenceState.class);
+ assertThat(fromParcel.getPreferenceState().getSettingType())
+ .isEqualTo(DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE);
+ assertThat(((MultiTogglePreferenceState) fromParcel.getPreferenceState()).getState())
+ .isEqualTo(123);
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(state.getExtras().getString("key1"));
+ }
+
+ @Test
+ public void parcelOperation_unknownPreferenceState() {
+ DeviceSettingState state =
+ new DeviceSettingState.Builder()
+ .setSettingId(123)
+ .setPreferenceState(new DeviceSettingPreferenceState(123) {})
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ DeviceSettingState fromParcel = writeAndRead(state);
+
+ assertThat(fromParcel.getSettingId()).isEqualTo(state.getSettingId());
+ assertThat(fromParcel.getPreferenceState())
+ .isSameInstanceAs(DeviceSettingPreferenceState.UNKNOWN);
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(state.getExtras().getString("key1"));
+ }
+
+ private Bundle buildBundle(String key, String value) {
+ Bundle bundle = new Bundle();
+ bundle.putString(key, value);
+ return bundle;
+ }
+
+ private DeviceSettingState writeAndRead(DeviceSettingState state) {
+ Parcel parcel = Parcel.obtain();
+ state.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ DeviceSettingState fromParcel = DeviceSettingState.CREATOR.createFromParcel(parcel);
+ return fromParcel;
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingTest.java
new file mode 100644
index 000000000000..98dc54b2e33d
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class DeviceSettingTest {
+ private static final ActionSwitchPreference ACTION_SWITCH_PREFERENCE =
+ new ActionSwitchPreference.Builder().setTitle("action_switch_preference").build();
+ private static final MultiTogglePreference MULTI_TOGGLE_PREFERENCE =
+ new MultiTogglePreference.Builder().setTitle("multi_toggle_preference").build();
+
+ @Test
+ public void build_withoutPreference_fail() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> {
+ DeviceSetting unused =
+ new DeviceSetting.Builder()
+ .setSettingId(123)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ });
+ }
+
+ @Test
+ public void build_withoutExtra_successfully() {
+ DeviceSetting unused =
+ new DeviceSetting.Builder()
+ .setSettingId(123)
+ .setPreference(ACTION_SWITCH_PREFERENCE)
+ .build();
+ }
+
+ @Test
+ public void build_withAllFields_successfully() {
+ DeviceSetting unused =
+ new DeviceSetting.Builder()
+ .setSettingId(123)
+ .setPreference(ACTION_SWITCH_PREFERENCE)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ }
+
+ @Test
+ public void getMethods_actionSwitchPreference() {
+ DeviceSetting setting =
+ new DeviceSetting.Builder()
+ .setSettingId(123)
+ .setPreference(ACTION_SWITCH_PREFERENCE)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ assertThat(setting.getSettingId()).isEqualTo(123);
+ assertThat(setting.getPreference()).isInstanceOf(ActionSwitchPreference.class);
+ assertThat(setting.getExtras().getString("key1")).isEqualTo("value1");
+ }
+
+ @Test
+ public void getMethods_multiTogglePreference() {
+ DeviceSetting setting =
+ new DeviceSetting.Builder()
+ .setSettingId(123)
+ .setPreference(MULTI_TOGGLE_PREFERENCE)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ assertThat(setting.getSettingId()).isEqualTo(123);
+ assertThat(setting.getPreference()).isInstanceOf(MultiTogglePreference.class);
+ assertThat(setting.getExtras().getString("key1")).isEqualTo("value1");
+ }
+
+ @Test
+ public void parcelOperation_actionSwitchPreference() {
+ DeviceSetting setting =
+ new DeviceSetting.Builder()
+ .setSettingId(123)
+ .setPreference(ACTION_SWITCH_PREFERENCE)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ DeviceSetting fromParcel = writeAndRead(setting);
+
+ assertThat(fromParcel.getSettingId()).isEqualTo(setting.getSettingId());
+ assertThat(fromParcel.getPreference()).isInstanceOf(ActionSwitchPreference.class);
+ assertThat(fromParcel.getPreference().getSettingType())
+ .isEqualTo(DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH);
+ assertThat(((ActionSwitchPreference) fromParcel.getPreference()).getTitle())
+ .isEqualTo("action_switch_preference");
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(setting.getExtras().getString("key1"));
+ }
+
+ @Test
+ public void parcelOperation_multiTogglePreference() {
+ DeviceSetting setting =
+ new DeviceSetting.Builder()
+ .setSettingId(123)
+ .setPreference(MULTI_TOGGLE_PREFERENCE)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ DeviceSetting fromParcel = writeAndRead(setting);
+
+ assertThat(fromParcel.getSettingId()).isEqualTo(setting.getSettingId());
+ assertThat(fromParcel.getPreference()).isInstanceOf(MultiTogglePreference.class);
+ assertThat(fromParcel.getPreference().getSettingType())
+ .isEqualTo(DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE);
+ assertThat(((MultiTogglePreference) fromParcel.getPreference()).getTitle())
+ .isEqualTo("multi_toggle_preference");
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(setting.getExtras().getString("key1"));
+ }
+
+ @Test
+ public void parcelOperation_unknownPreference() {
+ DeviceSetting setting =
+ new DeviceSetting.Builder()
+ .setSettingId(123)
+ .setPreference(new DeviceSettingPreference(123) {})
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ DeviceSetting fromParcel = writeAndRead(setting);
+
+ assertThat(fromParcel.getSettingId()).isEqualTo(setting.getSettingId());
+ assertThat(fromParcel.getPreference()).isSameInstanceAs(DeviceSettingPreference.UNKNOWN);
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(setting.getExtras().getString("key1"));
+ }
+
+ private Bundle buildBundle(String key, String value) {
+ Bundle bundle = new Bundle();
+ bundle.putString(key, value);
+ return bundle;
+ }
+
+ private DeviceSetting writeAndRead(DeviceSetting state) {
+ Parcel parcel = Parcel.obtain();
+ state.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ DeviceSetting fromParcel = DeviceSetting.CREATOR.createFromParcel(parcel);
+ return fromParcel;
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfigTest.kt b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfigTest.kt
new file mode 100644
index 000000000000..2b29a6ef5e5a
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfigTest.kt
@@ -0,0 +1,84 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings
+
+import android.os.Bundle
+import android.os.Parcel
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class DeviceSettingsConfigTest {
+
+ @Test
+ fun parcelOperation() {
+ val config =
+ DeviceSettingsConfig(
+ mainContentItems =
+ listOf(
+ DeviceSettingItem(
+ 1,
+ "package_name_1",
+ "class_name_1",
+ "intent_action_1",
+ Bundle()
+ )
+ ),
+ moreSettingsItems =
+ listOf(
+ DeviceSettingItem(
+ 2,
+ "package_name_2",
+ "class_name_2",
+ "intent_action_2",
+ Bundle()
+ )
+ ),
+ moreSettingsFooter = "footer",
+ extras = Bundle().apply { putString("key1", "value1") },
+ )
+
+ val fromParcel = writeAndRead(config)
+
+ assertThat(fromParcel.mainContentItems.stream().map { it.settingId }.toList())
+ .containsExactly(1)
+ assertThat(fromParcel.mainContentItems.stream().map { it.packageName }.toList())
+ .containsExactly("package_name_1")
+ assertThat(fromParcel.mainContentItems.stream().map { it.className }.toList())
+ .containsExactly("class_name_1")
+ assertThat(fromParcel.mainContentItems.stream().map { it.intentAction }.toList())
+ .containsExactly("intent_action_1")
+ assertThat(fromParcel.moreSettingsItems.stream().map { it.settingId }.toList())
+ .containsExactly(2)
+ assertThat(fromParcel.moreSettingsItems.stream().map { it.packageName }.toList())
+ .containsExactly("package_name_2")
+ assertThat(fromParcel.moreSettingsItems.stream().map { it.className }.toList())
+ .containsExactly("class_name_2")
+ assertThat(fromParcel.moreSettingsItems.stream().map { it.intentAction }.toList())
+ .containsExactly("intent_action_2")
+ assertThat(fromParcel.moreSettingsFooter).isEqualTo(config.moreSettingsFooter)
+ }
+
+ private fun writeAndRead(item: DeviceSettingsConfig): DeviceSettingsConfig {
+ val parcel = Parcel.obtain()
+ item.writeToParcel(parcel, 0)
+ parcel.setDataPosition(0)
+ return DeviceSettingsConfig.CREATOR.createFromParcel(parcel)
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceStateTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceStateTest.java
new file mode 100644
index 000000000000..2645fc5f16ff
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceStateTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class MultiTogglePreferenceStateTest {
+
+ @Test
+ public void getMethods() {
+ MultiTogglePreferenceState state1 =
+ new MultiTogglePreferenceState.Builder()
+ .setState(1)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ MultiTogglePreferenceState state2 =
+ new MultiTogglePreferenceState.Builder()
+ .setState(2)
+ .setExtras(buildBundle("key2", "value2"))
+ .build();
+
+ assertThat(state1.getState()).isEqualTo(1);
+ assertThat(state2.getState()).isEqualTo(2);
+ assertThat(state1.getExtras().getString("key1")).isEqualTo("value1");
+ assertThat(state2.getExtras().getString("key2")).isEqualTo("value2");
+ }
+
+ @Test
+ public void parcelOperation() {
+ MultiTogglePreferenceState state =
+ new MultiTogglePreferenceState.Builder()
+ .setState(123)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ MultiTogglePreferenceState fromParcel = writeAndRead(state);
+
+ assertThat(fromParcel.getState()).isEqualTo(state.getState());
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(state.getExtras().getString("key1"));
+ }
+
+ private Bundle buildBundle(String key, String value) {
+ Bundle bundle = new Bundle();
+ bundle.putString(key, value);
+ return bundle;
+ }
+
+ private MultiTogglePreferenceState writeAndRead(MultiTogglePreferenceState state) {
+ Parcel parcel = Parcel.obtain();
+ state.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ MultiTogglePreferenceState fromParcel =
+ MultiTogglePreferenceState.CREATOR.createFromParcel(parcel);
+ return fromParcel;
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceTest.java
new file mode 100644
index 000000000000..62fcb5ec3011
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class MultiTogglePreferenceTest {
+ private static final Bitmap ICON = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ private static final ToggleInfo TOGGLE_INFO_1 =
+ new ToggleInfo.Builder().setLabel("label1").setIcon(ICON).build();
+ private static final ToggleInfo TOGGLE_INFO_2 =
+ new ToggleInfo.Builder().setLabel("label2").setIcon(ICON).build();
+
+ @Test
+ public void build_withoutTitle_fail() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> {
+ MultiTogglePreference unused =
+ new MultiTogglePreference.Builder()
+ .addToggleInfo(TOGGLE_INFO_1)
+ .setState(0)
+ .setAllowChangingState(true)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ });
+ }
+
+ @Test
+ public void build_withNegativeState_fail() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> {
+ MultiTogglePreference unused =
+ new MultiTogglePreference.Builder()
+ .setTitle("title")
+ .addToggleInfo(TOGGLE_INFO_1)
+ .setState(-1)
+ .setAllowChangingState(true)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ });
+ }
+
+ @Test
+ public void build_withoutExtra_successfully() {
+ MultiTogglePreference unused =
+ new MultiTogglePreference.Builder()
+ .setTitle("title")
+ .addToggleInfo(TOGGLE_INFO_1)
+ .addToggleInfo(TOGGLE_INFO_2)
+ .setState(123)
+ .setAllowChangingState(true)
+ .build();
+ }
+
+ @Test
+ public void build_withAllFields_successfully() {
+ MultiTogglePreference unused =
+ new MultiTogglePreference.Builder()
+ .setTitle("title")
+ .addToggleInfo(TOGGLE_INFO_1)
+ .addToggleInfo(TOGGLE_INFO_2)
+ .setState(123)
+ .setAllowChangingState(true)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ }
+
+ @Test
+ public void getMethods() {
+ MultiTogglePreference preference =
+ new MultiTogglePreference.Builder()
+ .setTitle("title")
+ .addToggleInfo(TOGGLE_INFO_1)
+ .addToggleInfo(TOGGLE_INFO_2)
+ .setState(123)
+ .setAllowChangingState(true)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ assertThat(preference.getTitle()).isEqualTo("title");
+ assertThat(preference.getToggleInfos().stream().map(ToggleInfo::getLabel).toList())
+ .containsExactly("label1", "label2");
+ assertThat(preference.getState()).isEqualTo(123);
+ assertThat(preference.isAllowedChangingState()).isTrue();
+ assertThat(preference.getExtras().getString("key1")).isEqualTo("value1");
+ }
+
+ @Test
+ public void parcelOperation() {
+ MultiTogglePreference preference =
+ new MultiTogglePreference.Builder()
+ .setTitle("title")
+ .addToggleInfo(TOGGLE_INFO_1)
+ .addToggleInfo(TOGGLE_INFO_2)
+ .setState(123)
+ .setAllowChangingState(true)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ MultiTogglePreference fromParcel = writeAndRead(preference);
+
+ assertThat(fromParcel.getTitle()).isEqualTo(preference.getTitle());
+ assertThat(fromParcel.getToggleInfos().stream().map(ToggleInfo::getLabel).toList())
+ .containsExactly("label1", "label2");
+ assertThat(fromParcel.getState()).isEqualTo(preference.getState());
+ assertThat(fromParcel.isAllowedChangingState())
+ .isEqualTo(preference.isAllowedChangingState());
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(preference.getExtras().getString("key1"));
+ }
+
+ private Bundle buildBundle(String key, String value) {
+ Bundle bundle = new Bundle();
+ bundle.putString(key, value);
+ return bundle;
+ }
+
+ private MultiTogglePreference writeAndRead(MultiTogglePreference preference) {
+ Parcel parcel = Parcel.obtain();
+ preference.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ MultiTogglePreference fromParcel = MultiTogglePreference.CREATOR.createFromParcel(parcel);
+ return fromParcel;
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfoTest.java
new file mode 100644
index 000000000000..439749a53d32
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfoTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class ToggleInfoTest {
+
+ @Test
+ public void build_withoutIcon_fail() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> {
+ ToggleInfo unused =
+ new ToggleInfo.Builder()
+ .setLabel("label")
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ });
+ }
+
+ @Test
+ public void build_withoutLabel_fail() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> {
+ ToggleInfo unused =
+ new ToggleInfo.Builder()
+ .setIcon(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888))
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ });
+ }
+
+ @Test
+ public void build_withoutExtra_successfully() {
+ ToggleInfo unused =
+ new ToggleInfo.Builder()
+ .setLabel("label")
+ .setIcon(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888))
+ .build();
+ }
+
+ @Test
+ public void build_withAllFields_successfully() {
+ ToggleInfo unused =
+ new ToggleInfo.Builder()
+ .setLabel("label")
+ .setIcon(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888))
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+ }
+
+ @Test
+ public void getMethods() {
+ Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ ToggleInfo info =
+ new ToggleInfo.Builder()
+ .setLabel("label")
+ .setIcon(icon)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ assertThat(info.getLabel()).isEqualTo("label");
+ assertThat(info.getIcon()).isSameInstanceAs(icon);
+ assertThat(info.getExtras().getString("key1")).isEqualTo("value1");
+ }
+
+ @Test
+ public void parcelOperation() {
+ Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ ToggleInfo info =
+ new ToggleInfo.Builder()
+ .setLabel("label")
+ .setIcon(icon)
+ .setExtras(buildBundle("key1", "value1"))
+ .build();
+
+ ToggleInfo fromParcel = writeAndRead(info);
+
+ assertThat(fromParcel.getLabel()).isEqualTo(info.getLabel());
+ assertThat(fromParcel.getIcon().sameAs(info.getIcon())).isTrue();
+ assertThat(fromParcel.getExtras().getString("key1"))
+ .isEqualTo(info.getExtras().getString("key1"));
+ }
+
+ private Bundle buildBundle(String key, String value) {
+ Bundle bundle = new Bundle();
+ bundle.putString(key, value);
+ return bundle;
+ }
+
+ private ToggleInfo writeAndRead(ToggleInfo state) {
+ Parcel parcel = Parcel.obtain();
+ state.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ ToggleInfo fromParcel = ToggleInfo.CREATOR.createFromParcel(parcel);
+ return fromParcel;
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
index 80301c02dd6a..b143b22c511b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
@@ -28,23 +28,31 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.KeyguardManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
+import com.android.settingslib.flags.Flags;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
@@ -54,26 +62,22 @@ public class BatterySaverUtilsTest {
private static final int BATTERY_SAVER_THRESHOLD_1 = 15;
private static final int BATTERY_SAVER_THRESHOLD_2 = 20;
- @Mock
- private Context mMockContext;
-
- @Mock
- private ContentResolver mMockResolver;
+ @Rule(order = 0) public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ @Rule(order = 1) public final MockitoRule mMockitoRule = MockitoJUnit.rule();
- @Mock
- private PowerManager mMockPowerManager;
+ @Mock private Context mMockContext;
+ @Mock private ContentResolver mMockResolver;
+ @Mock private PowerManager mMockPowerManager;
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
when(mMockContext.getContentResolver()).thenReturn(mMockResolver);
when(mMockContext.getSystemService(eq(PowerManager.class))).thenReturn(mMockPowerManager);
when(mMockPowerManager.setPowerSaveModeEnabled(anyBoolean())).thenReturn(true);
}
@Test
- public void testSetPowerSaveMode_enableWithWarning_firstCall_needConfirmationWarning() {
+ public void setPowerSaveMode_enableWithWarning_firstCall_needConfirmationWarning() {
Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
@@ -96,7 +100,7 @@ public class BatterySaverUtilsTest {
}
@Test
- public void testSetPowerSaveMode_enableWithWarning_secondCall_expectUpdateIntent() {
+ public void setPowerSaveMode_enableWithWarning_secondCall_expectUpdateIntent() {
// Already acked.
Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
Secure.putInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1);
@@ -119,7 +123,7 @@ public class BatterySaverUtilsTest {
}
@Test
- public void testSetPowerSaveMode_enableWithWarning_thirdCall_expectUpdateIntent() {
+ public void setPowerSaveMode_enableWithWarning_thirdCall_expectUpdateIntent() {
// Already acked.
Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
Secure.putInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1);
@@ -142,7 +146,7 @@ public class BatterySaverUtilsTest {
}
@Test
- public void testSetPowerSaveMode_enableWithWarning_5thCall_needAutoSuggestionWarning() {
+ public void setPowerSaveMode_enableWithWarning_5thCall_needAutoSuggestionWarning() {
// Already acked.
Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
Secure.putInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1);
@@ -166,7 +170,7 @@ public class BatterySaverUtilsTest {
}
@Test
- public void testSetPowerSaveMode_enableWithoutWarning_expectUpdateIntent() {
+ public void setPowerSaveMode_enableWithoutWarning_expectUpdateIntent() {
Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
@@ -187,17 +191,17 @@ public class BatterySaverUtilsTest {
}
@Test
- public void testSetPowerSaveMode_disableWithoutWarning_expectUpdateIntent() {
+ public void setPowerSaveMode_disableWithoutWarning_expectUpdateIntent() {
verifyDisablePowerSaveMode(/* needFirstTimeWarning= */ false);
}
@Test
- public void testSetPowerSaveMode_disableWithWarning_expectUpdateIntent() {
+ public void setPowerSaveMode_disableWithWarning_expectUpdateIntent() {
verifyDisablePowerSaveMode(/* needFirstTimeWarning= */ true);
}
@Test
- public void testEnsureAutoBatterysaver_setNewPositiveValue_doNotOverwrite() {
+ public void ensureAutoBatterysaver_setNewPositiveValue_doNotOverwrite() {
Global.putInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
BatterySaverUtils.ensureAutoBatterySaver(mMockContext, BATTERY_SAVER_THRESHOLD_1);
@@ -212,7 +216,7 @@ public class BatterySaverUtilsTest {
}
@Test
- public void testSetAutoBatterySaverTriggerLevel_setSuppressSuggestion() {
+ public void setAutoBatterySaverTriggerLevel_setSuppressSuggestion() {
Global.putString(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, "null");
Secure.putString(mMockResolver, Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, "null");
@@ -230,7 +234,7 @@ public class BatterySaverUtilsTest {
}
@Test
- public void testGetBatterySaverScheduleKey_returnExpectedKey() {
+ public void getBatterySaverScheduleKey_returnExpectedKey() {
Global.putInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
Global.putInt(mMockResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
@@ -253,8 +257,25 @@ public class BatterySaverUtilsTest {
KEY_NO_SCHEDULE);
}
+ @EnableFlags(Flags.FLAG_EXTREME_POWER_LOW_STATE_VULNERABILITY)
+ @Test
+ public void setPowerSaveMode_1stTimeAndDeviceLocked_enableBatterySaver() {
+ var keyguardManager = mock(KeyguardManager.class);
+ when(mMockContext.getSystemService(KeyguardManager.class)).thenReturn(keyguardManager);
+ when(keyguardManager.isDeviceLocked()).thenReturn(true);
+ when(mMockPowerManager.setPowerSaveModeEnabled(true)).thenReturn(true);
+
+ var enableResult = BatterySaverUtils.setPowerSaveMode(
+ mMockContext,
+ /* enable= */ true,
+ /* needFirstTimeWarning= */ true,
+ /* reason= */ 0);
+
+ assertThat(enableResult).isTrue();
+ }
+
@Test
- public void testSetBatterySaverScheduleMode_setSchedule() {
+ public void setBatterySaverScheduleMode_setSchedule() {
BatterySaverUtils.setBatterySaverScheduleMode(mMockContext, KEY_NO_SCHEDULE, -1);
assertThat(Global.getInt(mMockResolver, Global.AUTOMATIC_POWER_SAVE_MODE, -1))
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
index c9b35a0ae833..e1447dc8410c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
@@ -861,6 +861,23 @@ public class InfoMediaManagerTest {
}
@Test
+ public void addMediaDevice_withAddresslessBluetoothDevice_shouldIgnoreDeviceAndNotCrash() {
+ MediaRoute2Info bluetoothRoute =
+ new MediaRoute2Info.Builder(TEST_BLUETOOTH_ROUTE).setAddress(null).build();
+
+ final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
+ mock(CachedBluetoothDeviceManager.class);
+ when(mLocalBluetoothManager.getCachedDeviceManager())
+ .thenReturn(cachedBluetoothDeviceManager);
+ when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class))).thenReturn(null);
+
+ mInfoMediaManager.mMediaDevices.clear();
+ mInfoMediaManager.addMediaDevice(bluetoothRoute, TEST_SYSTEM_ROUTING_SESSION);
+
+ assertThat(mInfoMediaManager.mMediaDevices.size()).isEqualTo(0);
+ }
+
+ @Test
public void onRoutesUpdated_setsFirstSelectedRouteAsCurrentConnectedDevice() {
final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
mock(CachedBluetoothDeviceManager.class);
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/statusbar/notification/data/repository/ZenModeRepositoryTest.kt b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/data/repository/ZenModeRepositoryTest.kt
index 688bebb79384..67c73b1c8f5a 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/statusbar/notification/data/repository/ZenModeRepositoryTest.kt
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/data/repository/ZenModeRepositoryTest.kt
@@ -14,18 +14,24 @@
* limitations under the License.
*/
-package com.android.settingslib.statusbar.notification.data.repository
+package com.android.settingslib.notification.data.repository
import android.app.NotificationManager
import android.content.BroadcastReceiver
+import android.content.ContentResolver
import android.content.Context
import android.content.Intent
+import android.database.ContentObserver
+import android.os.Parcelable
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
import android.provider.Settings.Global
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.flags.Flags
+import com.android.settingslib.notification.modes.TestModeBuilder
+import com.android.settingslib.notification.modes.ZenMode
+import com.android.settingslib.notification.modes.ZenModesBackend
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.launchIn
@@ -34,27 +40,39 @@ import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.eq
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
+import org.robolectric.RobolectricTestRunner
@OptIn(ExperimentalCoroutinesApi::class)
-@RunWith(AndroidJUnit4::class)
+@RunWith(RobolectricTestRunner::class)
@SmallTest
class ZenModeRepositoryTest {
+ @get:Rule val setFlagsRule = SetFlagsRule()
@Mock private lateinit var context: Context
@Mock private lateinit var notificationManager: NotificationManager
+ @Mock private lateinit var zenModesBackend: ZenModesBackend
+
+ @Mock private lateinit var contentResolver: ContentResolver
+
@Captor private lateinit var receiverCaptor: ArgumentCaptor<BroadcastReceiver>
+ @Captor private lateinit var zenModeObserverCaptor: ArgumentCaptor<ContentObserver>
+
+ @Captor private lateinit var zenConfigObserverCaptor: ArgumentCaptor<ContentObserver>
+
private lateinit var underTest: ZenModeRepository
private val testScope: TestScope = TestScope()
@@ -67,12 +85,15 @@ class ZenModeRepositoryTest {
ZenModeRepositoryImpl(
context,
notificationManager,
+ zenModesBackend,
+ contentResolver,
testScope.backgroundScope,
testScope.testScheduler,
+ backgroundHandler = null,
)
}
- @DisableFlags(android.app.Flags.FLAG_MODES_API, Flags.FLAG_VOLUME_PANEL_BROADCAST_FIX)
+ @DisableFlags(Flags.FLAG_VOLUME_PANEL_BROADCAST_FIX)
@Test
fun consolidatedPolicyChanges_repositoryEmits_flagsOff() {
testScope.runTest {
@@ -87,9 +108,7 @@ class ZenModeRepositoryTest {
triggerIntent(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED)
runCurrent()
- assertThat(values)
- .containsExactlyElementsIn(listOf(null, testPolicy1, testPolicy2))
- .inOrder()
+ assertThat(values).containsExactly(null, testPolicy1, testPolicy2).inOrder()
}
}
@@ -108,9 +127,27 @@ class ZenModeRepositoryTest {
triggerIntent(NotificationManager.ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED)
runCurrent()
- assertThat(values)
- .containsExactlyElementsIn(listOf(null, testPolicy1, testPolicy2))
- .inOrder()
+ assertThat(values).containsExactly(null, testPolicy1, testPolicy2).inOrder()
+ }
+ }
+
+ @EnableFlags(android.app.Flags.FLAG_MODES_API, Flags.FLAG_VOLUME_PANEL_BROADCAST_FIX)
+ @Test
+ fun consolidatedPolicyChanges_repositoryEmitsFromExtras() {
+ testScope.runTest {
+ val values = mutableListOf<NotificationManager.Policy?>()
+ `when`(notificationManager.consolidatedNotificationPolicy).thenReturn(testPolicy1)
+ underTest.consolidatedNotificationPolicy
+ .onEach { values.add(it) }
+ .launchIn(backgroundScope)
+ runCurrent()
+
+ triggerIntent(
+ NotificationManager.ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED,
+ extras = mapOf(NotificationManager.EXTRA_NOTIFICATION_POLICY to testPolicy2))
+ runCurrent()
+
+ assertThat(values).containsExactly(null, testPolicy1, testPolicy2).inOrder()
}
}
@@ -127,15 +164,68 @@ class ZenModeRepositoryTest {
runCurrent()
assertThat(values)
- .containsExactlyElementsIn(
- listOf(null, Global.ZEN_MODE_OFF, Global.ZEN_MODE_ALARMS))
+ .containsExactly(null, Global.ZEN_MODE_OFF, Global.ZEN_MODE_ALARMS)
.inOrder()
}
}
- private fun triggerIntent(action: String) {
- verify(context).registerReceiver(receiverCaptor.capture(), any())
- receiverCaptor.value.onReceive(context, Intent(action))
+ @EnableFlags(android.app.Flags.FLAG_MODES_UI)
+ @Test
+ fun modesListEmitsOnSettingsChange() {
+ testScope.runTest {
+ val values = mutableListOf<List<ZenMode>>()
+ val modes1 = listOf(TestModeBuilder().setId("One").build())
+ `when`(zenModesBackend.modes).thenReturn(modes1)
+ underTest.modes.onEach { values.add(it) }.launchIn(backgroundScope)
+ runCurrent()
+
+ // zen mode change triggers update
+ val modes2 = listOf(TestModeBuilder().setId("Two").build())
+ `when`(zenModesBackend.modes).thenReturn(modes2)
+ triggerZenModeSettingUpdate()
+ runCurrent()
+
+ // zen config change also triggers update
+ val modes3 = listOf(TestModeBuilder().setId("Three").build())
+ `when`(zenModesBackend.modes).thenReturn(modes3)
+ triggerZenConfigSettingUpdate()
+ runCurrent()
+
+ // setting update with no list change doesn't trigger update
+ triggerZenModeSettingUpdate()
+ runCurrent()
+
+ assertThat(values).containsExactly(modes1, modes2, modes3).inOrder()
+ }
+ }
+
+ private fun triggerIntent(action: String, extras: Map<String, Parcelable>? = null) {
+ verify(context).registerReceiver(receiverCaptor.capture(), any(), any(), any())
+ val intent = Intent(action)
+ if (extras?.isNotEmpty() == true) {
+ extras.forEach { (key, value) -> intent.putExtra(key, value) }
+ }
+ receiverCaptor.value.onReceive(context, intent)
+ }
+
+ private fun triggerZenModeSettingUpdate() {
+ verify(contentResolver)
+ .registerContentObserver(
+ eq(Global.getUriFor(Global.ZEN_MODE)),
+ eq(false),
+ zenModeObserverCaptor.capture(),
+ )
+ zenModeObserverCaptor.value.onChange(false)
+ }
+
+ private fun triggerZenConfigSettingUpdate() {
+ verify(contentResolver)
+ .registerContentObserver(
+ eq(Global.getUriFor(Global.ZEN_MODE_CONFIG_ETAG)),
+ eq(false),
+ zenConfigObserverCaptor.capture(),
+ )
+ zenConfigObserverCaptor.value.onChange(false)
}
private companion object {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/EnableZenModeDialogTest.java
index 6b81c1a6f794..e397f97e0277 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/EnableZenModeDialogTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settingslib.notification;
+package com.android.settingslib.notification.modes;
import static com.google.common.truth.Truth.assertThat;
@@ -77,7 +77,7 @@ public class EnableZenModeDialogTest {
mController = spy(new EnableZenModeDialog(mContext));
mController.mContext = mContext;
mController.mLayoutInflater = mLayoutInflater;
- mController.mForeverId = Condition.newId(mContext).appendPath("forever").build();
+ mController.mForeverId = Condition.newId(mContext).appendPath("forever").build();
when(mContext.getString(com.android.internal.R.string.zen_mode_forever))
.thenReturn("testSummary");
when(mContext.getString(com.android.internal.R.string.selected))
@@ -96,9 +96,9 @@ public class EnableZenModeDialogTest {
doNothing().when(mController).bindNextAlarm(any());
// as a result of doing nothing above, must bind manually:
- Uri alarm = Condition.newId(mContext).appendPath("alarm").build();
+ Uri alarm = Condition.newId(mContext).appendPath("alarm").build();
mAlarmCondition = new Condition(alarm, "alarm", "", "", 0, 0, 0);
- Uri countdown = Condition.newId(mContext).appendPath("countdown").build();
+ Uri countdown = Condition.newId(mContext).appendPath("countdown").build();
mCountdownCondition = new Condition(countdown, "countdown", "", "", 0, 0, 0);
mController.bind(mCountdownCondition,
mController.mZenRadioGroupContent.getChildAt(
@@ -215,4 +215,4 @@ public class EnableZenModeDialogTest {
assertThat(countdown.line1.getStateDescription()).isNull();
assertThat(alwaysAsk.line1.getStateDescription().toString()).isEqualTo("selected");
}
-} \ No newline at end of file
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenDurationDialogTest.java
index fc45e89a6dd5..19845a04ea18 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenDurationDialogTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settingslib.notification;
+package com.android.settingslib.notification.modes;
import static com.google.common.truth.Truth.assertThat;
@@ -230,4 +230,4 @@ public class ZenDurationDialogTest {
assertThat(countdown.line1.getStateDescription()).isNull();
assertThat(alwaysAsk.line1.getStateDescription().toString()).isEqualTo("selected");
}
-} \ No newline at end of file
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
index 32cdb98ddb4c..e705f97202a3 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
@@ -21,13 +21,17 @@ import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import android.app.AutomaticZenRule;
import android.net.Uri;
+import android.os.Parcel;
import android.service.notification.Condition;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
+import com.android.internal.R;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -52,12 +56,14 @@ public class ZenModeTest {
assertThat(zenMode.getId()).isEqualTo("id");
assertThat(zenMode.getRule()).isEqualTo(ZEN_RULE);
assertThat(zenMode.isManualDnd()).isFalse();
+ assertThat(zenMode.canEditNameAndIcon()).isTrue();
assertThat(zenMode.canBeDeleted()).isTrue();
assertThat(zenMode.isActive()).isTrue();
ZenMode manualMode = ZenMode.manualDndMode(ZEN_RULE, false);
assertThat(manualMode.getId()).isEqualTo(ZenMode.MANUAL_DND_MODE_ID);
assertThat(manualMode.isManualDnd()).isTrue();
+ assertThat(manualMode.canEditNameAndIcon()).isFalse();
assertThat(manualMode.canBeDeleted()).isFalse();
assertThat(manualMode.isActive()).isFalse();
}
@@ -161,6 +167,30 @@ public class ZenModeTest {
assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(ZEN_POLICY);
}
+ @Test
+ public void writeToParcel_equals() {
+ assertUnparceledIsEqualToOriginal("example",
+ new ZenMode("id", ZEN_RULE, zenConfigRuleFor(ZEN_RULE, false)));
+
+ assertUnparceledIsEqualToOriginal("dnd", ZenMode.manualDndMode(ZEN_RULE, true));
+
+ assertUnparceledIsEqualToOriginal("custom_manual",
+ ZenMode.newCustomManual("New mode", R.drawable.ic_zen_mode_type_immersive));
+ }
+
+ private static void assertUnparceledIsEqualToOriginal(String type, ZenMode original) {
+ Parcel parcel = Parcel.obtain();
+ try {
+ original.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ ZenMode unparceled = ZenMode.CREATOR.createFromParcel(parcel);
+
+ assertWithMessage("Comparing " + type).that(unparceled).isEqualTo(original);
+ } finally {
+ parcel.recycle();
+ }
+ }
+
private static ZenModeConfig.ZenRule zenConfigRuleFor(AutomaticZenRule azr, boolean isActive) {
ZenModeConfig.ZenRule zenRule = new ZenModeConfig.ZenRule();
zenRule.pkg = azr.getPackageName();
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 097840ead0d3..5ddf005d9468 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -45,7 +45,7 @@
<integer name="def_location_mode">3</integer>
<!-- 0 == off, 1 == on-->
<integer name="def_paired_device_location_mode">1</integer>
- <bool name="assisted_gps_enabled">true</bool>
+ <bool name="assisted_gps_enabled">false</bool>
<bool name="def_netstats_enabled">true</bool>
<bool name="def_usb_mass_storage_enabled">true</bool>
<bool name="def_wifi_on">false</bool>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index d4a4703d5caf..5f236516785d 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -228,6 +228,7 @@ public class SecureSettings {
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
+ Settings.Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED,
Settings.Secure.ACCESSIBILITY_PINCH_TO_ZOOM_ANYWHERE_ENABLED,
Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED,
Settings.Secure.ODI_CAPTIONS_VOLUME_UI_ENABLED,
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index 00fb7a1feab1..2cdd0aee3d85 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -80,6 +80,7 @@ public class SystemSettings {
Settings.System.SIP_RECEIVE_CALLS,
Settings.System.POINTER_SPEED,
Settings.System.POINTER_FILL_STYLE,
+ Settings.System.POINTER_STROKE_STYLE,
Settings.System.POINTER_SCALE,
Settings.System.VIBRATE_ON,
Settings.System.VIBRATE_WHEN_RINGING,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 6df1c45bd2ac..c8da8afc25c3 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -439,6 +439,7 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.ON_DEVICE_INFERENCE_UNBIND_TIMEOUT_MS, ANY_LONG_VALIDATOR);
VALIDATORS.put(Secure.ON_DEVICE_INTELLIGENCE_UNBIND_TIMEOUT_MS, ANY_LONG_VALIDATOR);
VALIDATORS.put(Secure.ON_DEVICE_INTELLIGENCE_IDLE_TIMEOUT_MS, NONE_NEGATIVE_LONG_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.MANDATORY_BIOMETRICS, new InclusiveIntegerRangeValidator(0, 1));
}
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index 4235bc4157bf..7b927d793c37 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -30,6 +30,8 @@ import static android.view.PointerIcon.DEFAULT_POINTER_SCALE;
import static android.view.PointerIcon.LARGE_POINTER_SCALE;
import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_BEGIN;
import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_END;
+import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_BEGIN;
+import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_END;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
@@ -213,6 +215,9 @@ public class SystemSettingsValidators {
VALIDATORS.put(System.POINTER_FILL_STYLE,
new InclusiveIntegerRangeValidator(POINTER_ICON_VECTOR_STYLE_FILL_BEGIN,
POINTER_ICON_VECTOR_STYLE_FILL_END));
+ VALIDATORS.put(System.POINTER_STROKE_STYLE,
+ new InclusiveIntegerRangeValidator(POINTER_ICON_VECTOR_STYLE_STROKE_BEGIN,
+ POINTER_ICON_VECTOR_STYLE_STROKE_END));
VALIDATORS.put(System.POINTER_SCALE,
new InclusiveFloatRangeValidator(DEFAULT_POINTER_SCALE, LARGE_POINTER_SCALE));
VALIDATORS.put(System.TOUCHPAD_POINTER_SPEED, new InclusiveIntegerRangeValidator(-7, 7));
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index e77cf2fa6543..8b0772bb644d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -42,6 +42,7 @@ import android.provider.Settings.Config.SyncDisabledMode;
import android.provider.UpdatableDeviceConfigServiceReadiness;
import android.util.Slog;
+import com.android.internal.pm.pkg.component.AconfigFlags;
import com.android.internal.util.FastPrintWriter;
import java.io.File;
@@ -189,22 +190,13 @@ public final class DeviceConfigService extends Binder {
public static HashMap<String, String> getAllFlags(IContentProvider provider) {
HashMap<String, String> allFlags = new HashMap<String, String>();
- try {
- Bundle args = new Bundle();
- args.putInt(Settings.CALL_METHOD_USER_KEY,
- ActivityManager.getService().getCurrentUser().id);
- Bundle b = provider.call(new AttributionSource(Process.myUid(),
- resolveCallingPackage(), null), Settings.AUTHORITY,
- Settings.CALL_METHOD_LIST_CONFIG, null, args);
- if (b != null) {
- Map<String, String> flagsToValues =
- (HashMap) b.getSerializable(Settings.NameValueTable.VALUE);
- allFlags.putAll(flagsToValues);
+ for (DeviceConfig.Properties properties : DeviceConfig.getAllProperties()) {
+ List<String> keys = new ArrayList<>(properties.getKeyset());
+ for (String flagName : properties.getKeyset()) {
+ String fullName = properties.getNamespace() + "/" + flagName;
+ allFlags.put(fullName, properties.getString(flagName, null));
}
- } catch (RemoteException e) {
- throw new RuntimeException("Failed in IPC", e);
}
-
return allFlags;
}
@@ -425,7 +417,13 @@ public final class DeviceConfigService extends Binder {
DeviceConfig.setProperty(namespace, key, value, makeDefault);
break;
case OVERRIDE:
- DeviceConfig.setLocalOverride(namespace, key, value);
+ AconfigFlags.Permission permission =
+ (new AconfigFlags()).getFlagPermission(key);
+ if (permission == AconfigFlags.Permission.READ_ONLY) {
+ pout.println("cannot override read-only flag " + key);
+ } else {
+ DeviceConfig.setLocalOverride(namespace, key, value);
+ }
break;
case CLEAR_OVERRIDE:
DeviceConfig.clearLocalOverride(namespace, key);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 384cb7ee9c49..cd37ad171fac 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2916,6 +2916,9 @@ class SettingsProtoDumpUtil {
Settings.System.POINTER_FILL_STYLE,
SystemSettingsProto.Pointer.POINTER_FILL_STYLE);
dumpSetting(s, p,
+ Settings.System.POINTER_STROKE_STYLE,
+ SystemSettingsProto.Pointer.POINTER_STROKE_STYLE);
+ dumpSetting(s, p,
Settings.System.POINTER_SCALE,
SystemSettingsProto.Pointer.POINTER_SCALE);
p.end(pointerToken);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 54f0d7a4d853..e8ef620d6c0c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -44,6 +44,7 @@ import static com.android.providers.settings.SettingsState.isSystemSettingsKey;
import static com.android.providers.settings.SettingsState.makeKey;
import android.Manifest;
+import android.aconfigd.AconfigdFlagInfo;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -1371,10 +1372,27 @@ public class SettingsProvider extends ContentProvider {
}
}
+ Map<String, AconfigdFlagInfo> aconfigFlagInfos =
+ settingsState.getAconfigDefaultFlags();
+
for (int i = 0; i < nameCount; i++) {
String name = names.get(i);
Setting setting = settingsState.getSettingLocked(name);
- if (prefix == null || setting.getName().startsWith(prefix)) {
+ if (prefix == null || name.startsWith(prefix)) {
+ if (Flags.ignoreXmlForReadOnlyFlags()) {
+ int slashIndex = name.indexOf("/");
+ boolean validSlashIndex = slashIndex != -1
+ && slashIndex != 0
+ && slashIndex != name.length();
+ if (validSlashIndex) {
+ String flagName = name.substring(slashIndex + 1);
+ AconfigdFlagInfo flagInfo = aconfigFlagInfos.get(flagName);
+ if (flagInfo != null && !flagInfo.getIsReadWrite()) {
+ continue;
+ }
+ }
+ }
+
flagsToValues.put(setting.getName(), setting.getValue());
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 861c405b1542..452edd924a26 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -740,8 +740,6 @@ final class SettingsState {
// The settings provider must hold its lock when calling here.
@GuardedBy("mLock")
public void removeSettingsForPackageLocked(String packageName) {
- boolean removedSomething = false;
-
final int settingCount = mSettings.size();
for (int i = settingCount - 1; i >= 0; i--) {
String name = mSettings.keyAt(i);
@@ -752,14 +750,9 @@ final class SettingsState {
}
Setting setting = mSettings.valueAt(i);
if (packageName.equals(setting.packageName)) {
- mSettings.removeAt(i);
- removedSomething = true;
+ deleteSettingLocked(setting.name);
}
}
-
- if (removedSomething) {
- scheduleWriteIfNeededLocked();
- }
}
// The settings provider must hold its lock when calling here.
@@ -781,6 +774,13 @@ final class SettingsState {
}
}
+ @NonNull
+ public Map<String, AconfigdFlagInfo> getAconfigDefaultFlags() {
+ synchronized (mLock) {
+ return mAconfigDefaultFlags;
+ }
+ }
+
// The settings provider must hold its lock when calling here.
public Setting getSettingLocked(String name) {
if (TextUtils.isEmpty(name)) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig b/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
index d20fbf591a25..4f5955b1c6ca 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
+++ b/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
@@ -41,3 +41,14 @@ flag {
description: "If this flag is detected as true on boot, writes a logfile to track storage migration correctness."
bug: "328444881"
}
+
+flag {
+ name: "ignore_xml_for_read_only_flags"
+ namespace: "core_experiments_team_internal"
+ description: "When enabled, ignore any flag in the SettingsProvider XML for RO flags."
+ bug: "345007098"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java
index 8dd51b2b8d11..8de0c35ffa12 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java
@@ -22,8 +22,6 @@ import static junit.framework.Assert.assertNull;
import android.content.ContentResolver;
import android.os.Bundle;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
@@ -73,24 +71,9 @@ public class DeviceConfigServiceTest {
}
/**
- * Test that setting overrides are properly disabled when the flag is off.
- */
- @Test
- @RequiresFlagsDisabled("com.android.providers.settings.support_overrides")
- public void testOverrideDisabled() throws IOException {
- final String newValue = "value2";
-
- executeShellCommand("device_config put " + sNamespace + " " + sKey + " " + sValue);
- executeShellCommand("device_config override " + sNamespace + " " + sKey + " " + newValue);
- String result = readShellCommandOutput("device_config get " + sNamespace + " " + sKey);
- assertEquals(sValue + "\n", result);
- }
-
- /**
* Test that overrides are readable and can be cleared.
*/
@Test
- @RequiresFlagsEnabled("com.android.providers.settings.support_overrides")
public void testOverride() throws IOException {
final String newValue = "value2";
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
index 4b4ced3c0753..48ce49dbfb3a 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
@@ -988,7 +988,40 @@ public class SettingsStateTest {
}
@Test
- public void testGetFlagOverrideToSync() {
+ public void testMemoryUsagePerPackage_StatsUpdatedOnAppDataCleared() {
+ SettingsState settingsState =
+ new SettingsState(
+ InstrumentationRegistry.getContext(), mLock, mSettingsFile, 1,
+ SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED, Looper.getMainLooper());
+ final String testKey1 = SETTING_NAME;
+ final String testKey2 = SETTING_NAME + "_2";
+ final String testValue1 = Strings.repeat("A", 9000);
+ final String testValue2 = Strings.repeat("A", 9001);
+ final String packageName = "p";
+ // Inserting the first setting should be okay
+ settingsState.insertSettingLocked(testKey1, testValue1, null, true, packageName);
+ int expectedMemUsageForPackage = (testKey1.length() + testValue1.length()
+ + testValue1.length() /* size for default */) * Character.BYTES;
+ assertEquals(expectedMemUsageForPackage, settingsState.getMemoryUsage(packageName));
+ // Inserting the second setting should fail
+ try {
+ settingsState.insertSettingLocked(testKey2, testValue2, null, true, packageName);
+ fail("Should throw because it exceeded max memory usage per package");
+ } catch (IllegalStateException ex) {
+ assertTrue(ex.getMessage().startsWith("You are adding too many system settings."));
+ }
+ // Now clear app data and check that the memory usage is cleared
+ settingsState.removeSettingsForPackageLocked(packageName);
+ assertEquals(0, settingsState.getMemoryUsage(packageName));
+ // Try inserting the second setting again and it should go through
+ settingsState.insertSettingLocked(testKey2, testValue2, null, true, packageName);
+ expectedMemUsageForPackage = (testKey2.length() + testValue2.length()
+ + testValue2.length() /* size for default */) * Character.BYTES;
+ assertEquals(expectedMemUsageForPackage, settingsState.getMemoryUsage(packageName));
+ }
+
+ @Test
+ public void testGetFlagOverrideToSync() {
int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0);
Object lock = new Object();
SettingsState settingsState =
diff --git a/packages/Shell/res/values-fr-rCA/strings.xml b/packages/Shell/res/values-fr-rCA/strings.xml
index 54ae9542c032..760905049c88 100644
--- a/packages/Shell/res/values-fr-rCA/strings.xml
+++ b/packages/Shell/res/values-fr-rCA/strings.xml
@@ -28,7 +28,7 @@
<string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Sélectionnez pour partager le rapport de bogue sans saisie d\'écran ou attendez que la saisie soit prête"</string>
<string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Touchez pour partager le rapport de bogue sans saisie d\'écran ou attendez que la saisie soit prête"</string>
<string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Touchez pour partager le rapport de bogue sans saisie d\'écran ou attendez que la saisie soit prête"</string>
- <string name="bugreport_confirm" msgid="5917407234515812495">"Les rapports de bogue contiennent des données des fichiers journaux du système, y compris des données que vous considérez comme sensibles (comme des renseignements sur l\'utilisation des applications et des données de localisation). Ne partagez les rapports de bogue qu\'avec les applications et les personnes en qui vous avez confiance."</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"Les rapports de bogue contiennent des données des fichiers journaux du système, y compris des données que vous considérez comme sensibles (comme des renseignements sur l\'utilisation des applis et des données de localisation). Ne partagez les rapports de bogue qu\'avec les applis et les personnes en qui vous avez confiance."</string>
<string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ne plus afficher"</string>
<string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports de bogues"</string>
<string name="bugreport_unreadable_text" msgid="586517851044535486">"Impossible de lire le fichier du rapport de bogue"</string>
diff --git a/packages/Shell/res/values-nb/strings.xml b/packages/Shell/res/values-nb/strings.xml
index 876bd9d7548f..db83f295ed87 100644
--- a/packages/Shell/res/values-nb/strings.xml
+++ b/packages/Shell/res/values-nb/strings.xml
@@ -35,7 +35,7 @@
<string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Kunne ikke legge til informasjon fra feilrapporten i ZIP-filen"</string>
<string name="bugreport_unnamed" msgid="2800582406842092709">"uten navn"</string>
<string name="bugreport_info_action" msgid="2158204228510576227">"Detaljer"</string>
- <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skjermdump"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skjermbilde"</string>
<string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Skjermdumpen er tatt."</string>
<string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Skjermdumpen kunne ikke tas."</string>
<string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detaljer om feilrapport <xliff:g id="ID">#%d</xliff:g>"</string>
diff --git a/packages/SimAppDialog/res/values-fr-rCA/strings.xml b/packages/SimAppDialog/res/values-fr-rCA/strings.xml
index b6075855a3bb..0ce7a2a5db1c 100644
--- a/packages/SimAppDialog/res/values-fr-rCA/strings.xml
+++ b/packages/SimAppDialog/res/values-fr-rCA/strings.xml
@@ -17,10 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8898068901680117589">"Boîte de dialogue de l\'application SIM"</string>
+ <string name="app_name" msgid="8898068901680117589">"Boîte de dialogue de l\'appli SIM"</string>
<string name="install_carrier_app_title" msgid="334729104862562585">"Activer le service cellulaire"</string>
- <string name="install_carrier_app_description" msgid="4014303558674923797">"Pour que le nouveau module SIM fonctionne correctement, vous devez installer l\'application <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="install_carrier_app_description" msgid="4014303558674923797">"Pour que le nouveau module SIM fonctionne correctement, vous devez installer l\'appli <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="install_carrier_app_description_default" msgid="7356830245205847840">"Pour que le nouveau module SIM fonctionne, vous devez installer l\'appli du fournisseur de services"</string>
<string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Pas maintenant"</string>
- <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Télécharger l\'application"</string>
+ <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Télécharger l\'appli"</string>
</resources>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index bd7c9a0e1e55..187187326ad5 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -23,7 +23,10 @@ package {
// See: http://go/android-license-faq
license {
name: "frameworks_base_packages_SystemUI_license",
- visibility: [":__subpackages__"],
+ visibility: [
+ ":__subpackages__",
+ "//development/samples/SceneTransitionLayoutDemo:__subpackages__",
+ ],
license_kinds: [
"SPDX-license-identifier-Apache-2.0",
],
@@ -193,7 +196,7 @@ filegroup {
"tests/src/**/systemui/media/dialog/MediaOutputDialogTest.java",
"tests/src/**/systemui/media/controls/domain/resume/MediaResumeListenerTest.kt",
"tests/src/**/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt",
- "tests/src/**/systemui/navigationbar/NavigationBarButtonTest.java",
+ "tests/src/**/systemui/navigationbar/views/NavigationBarButtonTest.java",
"tests/src/**/systemui/people/PeopleProviderTest.java",
"tests/src/**/systemui/people/PeopleSpaceUtilsTest.java",
"tests/src/**/systemui/people/widget/PeopleSpaceWidgetManagerTest.java",
@@ -449,7 +452,7 @@ filegroup {
"tests/src/**/systemui/doze/DozeScreenStateTest.java",
"tests/src/**/systemui/keyguard/WorkLockActivityControllerTest.java",
"tests/src/**/systemui/media/dialog/MediaOutputControllerTest.java",
- "tests/src/**/systemui/navigationbar/NavigationBarTest.java",
+ "tests/src/**/systemui/navigationbar/views/NavigationBarTest.java",
"tests/src/**/systemui/power/PowerNotificationWarningsTest.java",
"tests/src/**/systemui/power/PowerUITest.java",
"tests/src/**/systemui/qs/QSFooterViewControllerTest.java",
@@ -552,6 +555,7 @@ android_library {
"androidx.exifinterface_exifinterface",
"androidx.room_room-runtime",
"androidx.room_room-ktx",
+ "androidx.datastore_datastore-preferences",
"com.google.android.material_material",
"device_state_flags_lib",
"kotlinx_coroutines_android",
@@ -577,7 +581,6 @@ android_library {
"androidx.activity_activity-compose",
"androidx.compose.animation_animation-graphics",
"androidx.lifecycle_lifecycle-viewmodel-compose",
- "device_policy_aconfig_flags_lib",
],
libs: [
"keepanno-annotations",
@@ -665,6 +668,7 @@ android_library {
],
asset_dirs: [
"tests/goldens",
+ "schemas",
],
static_libs: [
"SystemUI-res",
@@ -704,7 +708,9 @@ android_library {
"androidx-constraintlayout_constraintlayout",
"androidx.exifinterface_exifinterface",
"androidx.room_room-runtime",
+ "androidx.room_room-testing",
"androidx.room_room-ktx",
+ "androidx.datastore_datastore-preferences",
"device_state_flags_lib",
"kotlinx-coroutines-android",
"kotlinx-coroutines-core",
@@ -784,7 +790,11 @@ android_library {
"android.test.mock",
"keepanno-annotations",
],
- kotlincflags: ["-Xjvm-default=all"],
+ kotlincflags: [
+ "-Xjvm-default=all",
+ // TODO(b/352363800): Why do we need this?
+ "-J-Xmx8192M",
+ ],
aaptflags: [
"--extra-packages",
"com.android.systemui",
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml
index 9a0ebef6c639..00cc44217aed 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml
@@ -23,7 +23,7 @@
<string name="accessibility_menu_description" msgid="4458354794093858297">"আপনার ডিভাইস নিয়ন্ত্রণ করতে, \'অ্যাক্সেসিবিলিটি মেনু\' একটি বড় অন-স্ক্রিন মেনু দেখায়। আপনি ফোন লক, ভলিউম ও উজ্জ্বলতা নিয়ন্ত্রণ, স্ক্রিনশট নেওয়া এবং আরও অনেক কিছু করতে পারবেন।"</string>
<string name="accessibility_menu_summary" msgid="340071398148208130">"বড় করে দেখানো মেনুর মাধ্যমে ডিভাইস নিয়ন্ত্রণ করুন"</string>
<string name="accessibility_menu_settings_name" msgid="1716888058785672611">"অ্যাক্সেসিবিলিটি মেনুর সেটিংস"</string>
- <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"বোতাম বড় করা"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"বড় বোতাম"</string>
<string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"অ্যাক্সেসিবিলিটি মেনু বোতামের সাইজ বাড়ান"</string>
<string name="pref_help_title" msgid="6871558837025010641">"সহায়তা"</string>
<string name="brightness_percentage_label" msgid="7391554573977867369">"উজ্জ্বলতা <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml
index 87a95037178e..e60eac0459c5 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml
@@ -21,7 +21,7 @@
<string name="previous_button_content_description" msgid="840869171117765966">"Aller à l\'écran précédent"</string>
<string name="next_button_content_description" msgid="6810058269847364406">"Aller à l\'écran suivant"</string>
<string name="accessibility_menu_description" msgid="4458354794093858297">"Le menu Accessibilité propose un grand espace à l\'écran à l\'aide duquel vous pouvez contrôler votre appareil. Utilisez-le pour verrouiller votre appareil, régler le volume et la luminosité, prendre des captures d\'écran et plus."</string>
- <string name="accessibility_menu_summary" msgid="340071398148208130">"contrôler l\'appareil à l\'aide d\'un menu de grande taille"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Contrôle l\'appareil à l\'aide d\'un menu de grande taille"</string>
<string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Paramètres du menu Accessibilité"</string>
<string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Boutons de grande taille"</string>
<string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Augmenter la taille des boutons du menu Accessibilité"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml
index 3d59c0b62ac4..c9e8858b38a8 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml
@@ -22,7 +22,7 @@
<string name="next_button_content_description" msgid="6810058269847364406">"अगली स्क्रीन पर जाएं"</string>
<string name="accessibility_menu_description" msgid="4458354794093858297">"सुलभता मेन्यू, डिवाइस की स्क्रीन पर दिखने वाला एक बड़ा मेन्यू होता है. इस मेन्यू में जाकर, डिवाइस को लॉक करने, स्क्रीनशॉट लेने, स्क्रीन की रोशनी और आवाज़ को कंट्रोल करने जैसे कई काम किए जा सकते हैं."</string>
<string name="accessibility_menu_summary" msgid="340071398148208130">"बड़े मेन्यू की मदद से डिवाइस को कंट्रोल करें"</string>
- <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"सुलभता मेन्यू सेटिंग"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"सुलभता मेन्यू की सेटिंग"</string>
<string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"बड़े बटन"</string>
<string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"सुलभता मेन्यू के बटनाें का साइज़ बढ़ाएं"</string>
<string name="pref_help_title" msgid="6871558837025010641">"सहायता"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml
index 36fcfdcd9eb3..c5388a8d6c74 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml
@@ -22,9 +22,9 @@
<string name="next_button_content_description" msgid="6810058269847364406">"Idi na sljedeći zaslon"</string>
<string name="accessibility_menu_description" msgid="4458354794093858297">"Izbornik pristupačnosti veliki je zaslonski izbornik koji vam omogućuje upravljanje uređajem. Putem njega možete zaključati uređaj, upravljati glasnoćom i svjetlinom, izrađivati snimke zaslona i drugo."</string>
<string name="accessibility_menu_summary" msgid="340071398148208130">"Upravljajte uređajem pomoću velikog izbornika"</string>
- <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Postavke izbornika pristupačnosti"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Postavke izbornika za pristupačnost"</string>
<string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Veliki gumbi"</string>
- <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Povećanje veličine gumba izbornika Pristupačnosti"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Povećaj veličinu gumba izbornika za pristupačnost"</string>
<string name="pref_help_title" msgid="6871558837025010641">"Pomoć"</string>
<string name="brightness_percentage_label" msgid="7391554573977867369">"Svjetlina <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
<string name="music_volume_percentage_label" msgid="398635599662604706">"Glasnoća glazbe <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml
index 09830520dd74..e95d0edbf320 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml
@@ -12,7 +12,7 @@
<string name="lockscreen_label" msgid="648347953557887087">"Låseskjerm"</string>
<string name="quick_settings_label" msgid="2999117381487601865">"Hurtiginnstillinger"</string>
<string name="notifications_label" msgid="6829741046963013567">"Varsler"</string>
- <string name="screenshot_label" msgid="863978141223970162">"Skjermdump"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Skjermbilde"</string>
<string name="screenshot_utterance" msgid="1430760563401895074">"Ta skjermbilde"</string>
<string name="volume_up_label" msgid="8592766918780362870">"Volum opp"</string>
<string name="volume_down_label" msgid="8574981863656447346">"Volum ned"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml
index 7535c2b0f538..1e28bff6ca7e 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml
@@ -24,7 +24,7 @@
<string name="accessibility_menu_summary" msgid="340071398148208130">"Bedien het apparaat via een groot menu"</string>
<string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Instellingen toegankelijkheidsmenu"</string>
<string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Grote knoppen"</string>
- <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Vergroot knoppen in het toegankelijkheidsmenu"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Maak knoppen in toegankelijkheidsmenu groter"</string>
<string name="pref_help_title" msgid="6871558837025010641">"Hulp"</string>
<string name="brightness_percentage_label" msgid="7391554573977867369">"Helderheid <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
<string name="music_volume_percentage_label" msgid="398635599662604706">"Muziekvolume <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
index 62f63a8739d4..3c92f83b19aa 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
@@ -22,9 +22,9 @@
<string name="next_button_content_description" msgid="6810058269847364406">"Prejsť na ďalšiu obrazovku"</string>
<string name="accessibility_menu_description" msgid="4458354794093858297">"Ponuka dostupnosti spustí na obrazovke telefónu veľkú ponuku, pomocou ktorej môžete ovládať svoje zariadenie. Môžete ho uzamknúť, ovládať hlasitosť a jas, vytvárať snímky obrazovky a mnoho ďalšieho."</string>
<string name="accessibility_menu_summary" msgid="340071398148208130">"Ovládanie zariadenia pomocou veľkej ponuky"</string>
- <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Nastavenia ponuky dostupnosti"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Nastavenia ponuky Dostupnosť"</string>
<string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Veľké tlačidlá"</string>
- <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Zväčšiť tlačidlá ponuky dostupnosti"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Zväčšiť tlačidlá ponuky Dostupnosť"</string>
<string name="pref_help_title" msgid="6871558837025010641">"Pomocník"</string>
<string name="brightness_percentage_label" msgid="7391554573977867369">"Jas: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
<string name="music_volume_percentage_label" msgid="398635599662604706">"Hlasitosť hudby: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index f5153e1aa8b3..71f5511af4f5 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -146,6 +146,16 @@ flag {
}
flag {
+ name: "notification_transparent_header_fix"
+ namespace: "systemui"
+ description: "fix the transparent group header issue for async header inflation."
+ bug: "340161724"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "pss_app_selector_abrupt_exit_fix"
namespace: "systemui"
description: "Fixes the app selector abruptly disappearing without an animation, when the"
@@ -524,6 +534,16 @@ flag {
}
flag {
+ name: "use_volume_controller"
+ namespace: "systemui"
+ description: "Adds Volume Controller signals to the AudioRepository to update volume"
+ bug: "349348461"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "screenshot_action_dismiss_system_windows"
namespace: "systemui"
description: "Dismiss existing system windows when starting action from screenshot UI"
@@ -571,10 +591,13 @@ flag {
}
flag {
- name: "screenshot_shelf_ui2"
+ name: "screenshot_save_image_exporter"
namespace: "systemui"
- description: "Use new shelf UI flow for screenshots"
- bug: "329659738"
+ description: "Save all screenshots using ImageExporter"
+ bug: "352308052"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
flag {
@@ -804,13 +827,6 @@ flag {
}
flag {
- name: "media_controls_refactor"
- namespace: "systemui"
- description: "Refactors media code to follow the recommended architecture"
- bug: "326408371"
-}
-
-flag {
name: "qs_tile_focus_state"
namespace: "systemui"
description: "enables new focus outline for qs tiles when focused on with physical keyboard"
@@ -1032,10 +1048,13 @@ flag {
}
flag {
- name: "glanceable_hub_gesture_handle"
+ name: "glanceable_hub_back_gesture"
namespace: "systemui"
- description: "Shows a vertical bar at the right edge to indicate the user can swipe to open the glanceable hub"
- bug: "339667383"
+ description: "Enables back gesture on the glanceable hub"
+ bug: "346331399"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
flag {
@@ -1045,14 +1064,6 @@ flag {
bug: "343505271"
}
-
-flag {
- name: "new_touchpad_gestures_tutorial"
- namespace: "systemui"
- description: "Enables new interactive tutorial for learning touchpad gestures"
- bug: "309928033"
-}
-
flag {
name: "register_wallpaper_notifier_background"
namespace: "systemui"
@@ -1131,4 +1142,48 @@ flag {
metadata {
purpose: PURPOSE_BUGFIX
}
+}
+
+flag {
+ namespace: "systemui"
+ name: "fetch_bookmarks_xml_keyboard_shortcuts"
+ description: "Fetches application launch keyboard shortcuts from system server rather than building a hardcoded list."
+ bug: "312452252"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ namespace: "systemui"
+ name: "qs_register_setting_observer_on_bg_thread"
+ description: "Registers Quick Settings content providers on background thread"
+ bug: "351766769"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "sounddose_customization"
+ namespace: "systemui"
+ description: "Enables custom actions for sounddose notifications"
+ bug: "345227709"
+}
+
+flag {
+ namespace: "systemui"
+ name: "register_content_observers_async"
+ description: "Use new Async API to register content observers"
+ bug: "316922634"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "msdl_feedback"
+ namespace: "systemui"
+ description: "Enables MSDL feedback in SysUI surfaces."
+ bug: "352600066"
} \ No newline at end of file
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
index b8f9ca82f072..f655ac1d207b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
@@ -83,6 +83,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.PlatformButton
import com.android.compose.animation.Easings
import com.android.compose.animation.scene.ElementKey
+import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.SceneTransitionLayout
@@ -516,13 +517,22 @@ private fun FoldAware(
val currentSceneKey =
if (isSplitAroundTheFold) SceneKeys.SplitSceneKey else SceneKeys.ContiguousSceneKey
- SceneTransitionLayout(
- currentScene = currentSceneKey,
- onChangeScene = {},
- transitions = SceneTransitions,
- modifier = modifier,
- enableInterruptions = false,
- ) {
+ val state = remember {
+ MutableSceneTransitionLayoutState(
+ currentSceneKey,
+ SceneTransitions,
+ enableInterruptions = false,
+ )
+ }
+
+ // Update state whenever currentSceneKey has changed.
+ LaunchedEffect(state, currentSceneKey) {
+ if (currentSceneKey != state.transitionState.currentScene) {
+ state.setTargetScene(currentSceneKey, coroutineScope = this)
+ }
+ }
+
+ SceneTransitionLayout(state, modifier = modifier) {
scene(SceneKeys.ContiguousSceneKey) {
FoldableScene(
aboveFold = aboveFold,
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 e02e5f8af644..92f03d792554 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
@@ -9,21 +9,14 @@ import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.drawBehind
@@ -34,7 +27,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import com.android.compose.animation.scene.CommunalSwipeDetector
+import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.ElementMatcher
@@ -48,11 +41,11 @@ import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.observableTransitionState
import com.android.compose.animation.scene.transitions
import com.android.compose.theme.LocalAndroidColorScheme
-import com.android.systemui.Flags
+import com.android.systemui.Flags.glanceableHubBackGesture
import com.android.systemui.communal.shared.model.CommunalBackgroundType
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalTransitionKeys
-import com.android.systemui.communal.ui.compose.Dimensions.SlideOffsetY
+import com.android.systemui.communal.ui.compose.Dimensions.Companion.SlideOffsetY
import com.android.systemui.communal.ui.compose.extensions.allowGestures
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.util.CommunalColors
@@ -156,11 +149,9 @@ fun CommunalContainer(
val currentSceneKey: SceneKey by
viewModel.currentScene.collectAsStateWithLifecycle(CommunalScenes.Blank)
val touchesAllowed by viewModel.touchesAllowed.collectAsStateWithLifecycle()
- val showGestureIndicator by
- viewModel.showGestureIndicator.collectAsStateWithLifecycle(initialValue = false)
val backgroundType by
viewModel.communalBackground.collectAsStateWithLifecycle(
- initialValue = CommunalBackgroundType.DEFAULT
+ initialValue = CommunalBackgroundType.ANIMATED
)
val state: MutableSceneTransitionLayoutState = remember {
MutableSceneTransitionLayoutState(
@@ -200,25 +191,20 @@ fun CommunalContainer(
)
) {
// This scene shows nothing only allowing for transitions to the communal scene.
- // TODO(b/339667383): remove this temporary swipe gesture handle
- Row(modifier = Modifier.fillMaxSize(), horizontalArrangement = Arrangement.End) {
- if (showGestureIndicator && Flags.glanceableHubGestureHandle()) {
- Box(
- modifier =
- Modifier.height(220.dp)
- .width(4.dp)
- .align(Alignment.CenterVertically)
- .background(color = Color.White, RoundedCornerShape(4.dp))
- )
- Spacer(modifier = Modifier.width(12.dp))
- }
- }
+ Box(modifier = Modifier.fillMaxSize())
}
- scene(
- CommunalScenes.Communal,
- userActions = mapOf(Swipe(SwipeDirection.Right) to CommunalScenes.Blank)
- ) {
+ val userActions =
+ if (glanceableHubBackGesture()) {
+ mapOf(
+ Swipe(SwipeDirection.Right) to CommunalScenes.Blank,
+ Back to CommunalScenes.Blank,
+ )
+ } else {
+ mapOf(Swipe(SwipeDirection.Right) to CommunalScenes.Blank)
+ }
+
+ scene(CommunalScenes.Communal, userActions = userActions) {
CommunalScene(
backgroundType = backgroundType,
colors = colors,
@@ -243,7 +229,7 @@ private fun SceneScope.CommunalScene(
) {
Box(modifier = Modifier.element(Communal.Elements.Scrim).fillMaxSize()) {
when (backgroundType) {
- CommunalBackgroundType.DEFAULT -> DefaultBackground(colors = colors)
+ CommunalBackgroundType.STATIC -> DefaultBackground(colors = colors)
CommunalBackgroundType.STATIC_GRADIENT -> StaticLinearGradient()
CommunalBackgroundType.ANIMATED -> AnimatedLinearGradient()
CommunalBackgroundType.NONE -> BackgroundTopScrim()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index be51c1a76fad..768e6533ac7d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -16,6 +16,8 @@
package com.android.systemui.communal.ui.compose
+import android.content.Context
+import android.content.res.Configuration
import android.graphics.drawable.Icon
import android.os.Bundle
import android.util.SizeF
@@ -40,6 +42,7 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
@@ -64,6 +67,7 @@ import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
+import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
@@ -94,6 +98,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
+import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
@@ -113,18 +118,21 @@ import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.layout.positionInWindow
+import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.CustomAccessibilityAction
+import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.customActions
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
@@ -170,7 +178,11 @@ fun CommunalHub(
var removeButtonCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
var toolbarSize: IntSize? by remember { mutableStateOf(null) }
var gridCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
- val gridState = rememberLazyGridState()
+
+ val gridState =
+ rememberLazyGridState(viewModel.savedFirstScrollIndex, viewModel.savedFirstScrollOffset)
+ viewModel.clearPersistedScrollPosition()
+
val contentListState = rememberContentListState(widgetConfigurator, communalContent, viewModel)
val reorderingWidgets by viewModel.reorderingWidgets.collectAsStateWithLifecycle()
val selectedKey = viewModel.selectedKey.collectAsStateWithLifecycle()
@@ -186,6 +198,8 @@ fun CommunalHub(
val contentPadding = gridContentPadding(viewModel.isEditMode, toolbarSize)
val contentOffset = beforeContentPadding(contentPadding).toOffset()
+ ObserveScrollEffect(gridState, viewModel)
+
if (!viewModel.isEditMode) {
ScrollOnUpdatedLiveContentEffect(communalContent, gridState)
}
@@ -378,6 +392,10 @@ fun CommunalHub(
}
}
+val hubDimensions: Dimensions
+ @Composable
+ get() = Dimensions(LocalContext.current, LocalConfiguration.current, LocalDensity.current)
+
@Composable
private fun DisclaimerBottomSheetContent(onButtonClicked: () -> Unit) {
val colors = LocalAndroidColorScheme.current
@@ -419,6 +437,20 @@ private fun DisclaimerBottomSheetContent(onButtonClicked: () -> Unit) {
}
}
+@Composable
+private fun ObserveScrollEffect(
+ gridState: LazyGridState,
+ communalViewModel: BaseCommunalViewModel
+) {
+
+ LaunchedEffect(gridState) {
+ snapshotFlow {
+ Pair(gridState.firstVisibleItemIndex, gridState.firstVisibleItemScrollOffset)
+ }
+ .collect { communalViewModel.onScrollPositionUpdated(it.first, it.second) }
+ }
+}
+
/**
* Observes communal content and scrolls to any added or updated live content, e.g. a new media
* session is started, or a paused timer is resumed.
@@ -485,7 +517,6 @@ private fun BoxScope.CommunalHubLazyGrid(
gridState = gridState,
contentListState = contentListState,
contentOffset = contentOffset,
- updateDragPositionForRemove = updateDragPositionForRemove
)
// A full size box in background that listens to widget drops from the picker.
@@ -493,7 +524,7 @@ private fun BoxScope.CommunalHubLazyGrid(
// for android drag events.
Box(Modifier.fillMaxSize().dragAndDropTarget(dragAndDropTargetState)) {}
} else {
- gridModifier = gridModifier.height(Dimensions.GridHeight)
+ gridModifier = gridModifier.height(hubDimensions.GridHeight)
}
LazyHorizontalGrid(
@@ -571,7 +602,7 @@ private fun EmptyStateCta(
) {
val colors = LocalAndroidColorScheme.current
Card(
- modifier = Modifier.height(Dimensions.GridHeight).padding(contentPadding),
+ modifier = Modifier.height(hubDimensions.GridHeight).padding(contentPadding),
colors = CardDefaults.cardColors(containerColor = Color.Transparent),
border = BorderStroke(3.dp, colors.secondary),
shape = RoundedCornerShape(size = 80.dp)
@@ -657,14 +688,15 @@ private fun Toolbar(
)
.onSizeChanged { setToolbarSize(it) },
) {
+ val addWidgetText = stringResource(R.string.hub_mode_add_widget_button_text)
ToolbarButton(
isPrimary = !removeEnabled,
modifier = Modifier.align(Alignment.CenterStart),
onClick = onOpenWidgetPicker,
) {
- Icon(Icons.Default.Add, stringResource(R.string.hub_mode_add_widget_button_text))
+ Icon(Icons.Default.Add, null)
Text(
- text = stringResource(R.string.hub_mode_add_widget_button_text),
+ text = addWidgetText,
)
}
@@ -696,7 +728,7 @@ private fun Toolbar(
),
verticalAlignment = Alignment.CenterVertically
) {
- Icon(Icons.Default.Close, stringResource(R.string.button_to_remove_widget))
+ Icon(Icons.Default.Close, contentDescription = null)
Text(
text = stringResource(R.string.button_to_remove_widget),
)
@@ -709,10 +741,7 @@ private fun Toolbar(
modifier = Modifier.align(Alignment.CenterEnd),
onClick = onEditDone,
) {
- Icon(
- Icons.Default.Check,
- stringResource(id = R.string.hub_mode_editing_exit_button_text)
- )
+ Icon(Icons.Default.Check, contentDescription = null)
Text(
text = stringResource(R.string.hub_mode_editing_exit_button_text),
)
@@ -871,7 +900,7 @@ private fun CtaTileInViewModeContent(
Icon(
imageVector = Icons.Outlined.Widgets,
contentDescription = stringResource(R.string.cta_label_to_open_widget_picker),
- modifier = Modifier.size(Dimensions.IconSize),
+ modifier = Modifier.size(Dimensions.IconSize).clearAndSetSemantics {},
)
Spacer(modifier = Modifier.size(6.dp))
Text(
@@ -943,9 +972,25 @@ private fun WidgetContent(
val selectedKey by viewModel.selectedKey.collectAsStateWithLifecycle()
val selectedIndex =
selectedKey?.let { key -> contentListState.list.indexOfFirst { it.key == key } }
+
+ val isSelected = selectedKey == model.key
+
+ val selectableModifier =
+ if (viewModel.isEditMode) {
+ Modifier.selectable(
+ selected = isSelected,
+ onClick = { viewModel.setSelectedKey(model.key) },
+ interactionSource = remember { MutableInteractionSource() },
+ indication = null,
+ )
+ } else {
+ Modifier
+ }
+
Box(
modifier =
modifier
+ .then(selectableModifier)
.thenIf(!viewModel.isEditMode && model.inQuietMode) {
Modifier.pointerInput(Unit) {
// consume tap to prevent the child view from triggering interactions with
@@ -958,7 +1003,6 @@ private fun WidgetContent(
.thenIf(viewModel.isEditMode) {
Modifier.semantics {
contentDescription = accessibilityLabel
- onClick(label = clickActionLabel, action = null)
val deleteAction =
CustomAccessibilityAction(removeWidgetActionLabel) {
contentListState.onRemove(index)
@@ -975,7 +1019,7 @@ private fun WidgetContent(
true
}
- val actions = mutableListOf(deleteAction, selectWidgetAction)
+ val actions = mutableListOf(selectWidgetAction, deleteAction)
if (selectedIndex != null && selectedIndex != index) {
actions.add(
@@ -1242,7 +1286,7 @@ private fun gridContentPadding(isEditMode: Boolean, toolbarSize: IntSize?): Padd
return PaddingValues(
start = Dimensions.ItemSpacing,
end = Dimensions.ItemSpacing,
- top = Dimensions.GridTopSpacing,
+ top = hubDimensions.GridTopSpacing,
)
}
val context = LocalContext.current
@@ -1251,7 +1295,8 @@ private fun gridContentPadding(isEditMode: Boolean, toolbarSize: IntSize?): Padd
val screenHeight = with(density) { windowMetrics.bounds.height().toDp() }
val toolbarHeight = with(density) { Dimensions.ToolbarPaddingTop + toolbarSize.height.toDp() }
val verticalPadding =
- ((screenHeight - toolbarHeight - Dimensions.GridHeight + Dimensions.GridTopSpacing) / 2)
+ ((screenHeight - toolbarHeight - hubDimensions.GridHeight + hubDimensions.GridTopSpacing) /
+ 2)
.coerceAtLeast(Dimensions.Spacing)
return PaddingValues(
start = Dimensions.ToolbarPaddingHorizontal,
@@ -1307,29 +1352,44 @@ data class ContentPaddingInPx(val start: Float, val top: Float) {
fun toOffset(): Offset = Offset(start, top)
}
-object Dimensions {
- val CardHeightFull = 530.dp
- val GridTopSpacing = 114.dp
+class Dimensions(val context: Context, val config: Configuration, val density: Density) {
+ val GridTopSpacing: Dp
+ get() {
+ if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ return 114.dp
+ } else {
+ val windowMetrics =
+ WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
+ val screenHeight = with(density) { windowMetrics.bounds.height().toDp() }
+
+ return (screenHeight - CardHeightFull) / 2
+ }
+ }
+
val GridHeight = CardHeightFull + GridTopSpacing
- val ItemSpacing = 50.dp
- val CardHeightHalf = (CardHeightFull - ItemSpacing) / 2
- val CardHeightThird = (CardHeightFull - (2 * ItemSpacing)) / 3
- val CardWidth = 360.dp
- val CardOutlineWidth = 3.dp
- val Spacing = ItemSpacing / 2
-
- // The sizing/padding of the toolbar in glanceable hub edit mode
- val ToolbarPaddingTop = 27.dp
- val ToolbarPaddingHorizontal = ItemSpacing
- val ToolbarButtonPaddingHorizontal = 24.dp
- val ToolbarButtonPaddingVertical = 16.dp
- val ButtonPadding =
- PaddingValues(
- vertical = ToolbarButtonPaddingVertical,
- horizontal = ToolbarButtonPaddingHorizontal,
- )
- val IconSize = 40.dp
- val SlideOffsetY = 30.dp
+
+ companion object {
+ val CardHeightFull = 530.dp
+ val ItemSpacing = 50.dp
+ val CardHeightHalf = (CardHeightFull - ItemSpacing) / 2
+ val CardHeightThird = (CardHeightFull - (2 * ItemSpacing)) / 3
+ val CardWidth = 360.dp
+ val CardOutlineWidth = 3.dp
+ val Spacing = ItemSpacing / 2
+
+ // The sizing/padding of the toolbar in glanceable hub edit mode
+ val ToolbarPaddingTop = 27.dp
+ val ToolbarPaddingHorizontal = ItemSpacing
+ val ToolbarButtonPaddingHorizontal = 24.dp
+ val ToolbarButtonPaddingVertical = 16.dp
+ val ButtonPadding =
+ PaddingValues(
+ vertical = ToolbarButtonPaddingVertical,
+ horizontal = ToolbarButtonPaddingHorizontal,
+ )
+ val IconSize = 40.dp
+ val SlideOffsetY = 30.dp
+ }
}
private object Colors {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
index 9e6f22a69dbc..0c293948dd3c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
@@ -18,17 +18,13 @@ package com.android.systemui.communal.ui.compose
import android.content.ClipDescription
import android.view.DragEvent
-import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.draganddrop.dragAndDropTarget
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollBy
-import androidx.compose.foundation.lazy.grid.LazyGridItemInfo
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
@@ -45,8 +41,7 @@ import com.android.systemui.communal.ui.compose.extensions.firstItemAtOffset
import com.android.systemui.communal.util.WidgetPickerIntentUtils
import com.android.systemui.communal.util.WidgetPickerIntentUtils.getWidgetExtraFromIntent
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.isActive
+import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
/**
@@ -59,32 +54,22 @@ internal fun rememberDragAndDropTargetState(
gridState: LazyGridState,
contentOffset: Offset,
contentListState: ContentListState,
- updateDragPositionForRemove: (offset: Offset) -> Boolean,
): DragAndDropTargetState {
val scope = rememberCoroutineScope()
- val autoScrollSpeed = remember { mutableFloatStateOf(0f) }
- // Threshold of distance from edges that should start auto-scroll - chosen to be a narrow value
- // that allows differentiating intention of scrolling from intention of dragging over the first
- // visible item.
val autoScrollThreshold = with(LocalDensity.current) { 60.dp.toPx() }
val state =
- remember(gridState, contentListState) {
+ remember(gridState, contentOffset, contentListState, autoScrollThreshold, scope) {
DragAndDropTargetState(
state = gridState,
contentOffset = contentOffset,
contentListState = contentListState,
- scope = scope,
- autoScrollSpeed = autoScrollSpeed,
autoScrollThreshold = autoScrollThreshold,
- updateDragPositionForRemove = updateDragPositionForRemove,
+ scope = scope,
)
}
- LaunchedEffect(autoScrollSpeed.floatValue) {
- if (autoScrollSpeed.floatValue != 0f) {
- while (isActive) {
- gridState.scrollBy(autoScrollSpeed.floatValue)
- delay(10)
- }
+ LaunchedEffect(state) {
+ for (diff in state.scrollChannel) {
+ gridState.scrollBy(diff)
}
}
return state
@@ -96,7 +81,6 @@ internal fun rememberDragAndDropTargetState(
* @see androidx.compose.foundation.draganddrop.dragAndDropTarget
* @see DragEvent
*/
-@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun Modifier.dragAndDropTarget(
dragDropTargetState: DragAndDropTargetState,
@@ -122,6 +106,10 @@ internal fun Modifier.dragAndDropTarget(
return state.onDrop(event)
}
+ override fun onExited(event: DragAndDropEvent) {
+ state.onExited()
+ }
+
override fun onEnded(event: DragAndDropEvent) {
state.onEnded()
}
@@ -149,19 +137,17 @@ internal class DragAndDropTargetState(
private val state: LazyGridState,
private val contentOffset: Offset,
private val contentListState: ContentListState,
- private val scope: CoroutineScope,
- private val autoScrollSpeed: MutableState<Float>,
private val autoScrollThreshold: Float,
- private val updateDragPositionForRemove: (offset: Offset) -> Boolean,
+ private val scope: CoroutineScope,
) {
/**
* The placeholder item that is treated as if it is being dragged across the grid. It is added
* to grid once drag and drop event is started and removed when event ends.
*/
private var placeHolder = CommunalContentModel.WidgetPlaceholder()
-
private var placeHolderIndex: Int? = null
- private var isOnRemoveButton = false
+
+ internal val scrollChannel = Channel<Float>()
fun onStarted() {
// assume item will be added to the end.
@@ -170,39 +156,39 @@ internal class DragAndDropTargetState(
}
fun onMoved(event: DragAndDropEvent) {
- val dragEvent = event.toAndroidDragEvent()
- isOnRemoveButton = updateDragPositionForRemove(Offset(dragEvent.x, dragEvent.y))
- if (!isOnRemoveButton) {
- findTargetItem(dragEvent)?.apply {
- var scrollIndex: Int? = null
- var scrollOffset: Int? = null
- if (placeHolderIndex == state.firstVisibleItemIndex) {
- // Save info about the first item before the move, to neutralize the automatic
- // keeping first item first.
- scrollIndex = placeHolderIndex
- scrollOffset = state.firstVisibleItemScrollOffset
- }
+ val dragOffset = event.toOffset()
- autoScrollIfNearEdges(dragEvent)
+ val targetItem =
+ state.layoutInfo.visibleItemsInfo
+ .asSequence()
+ .filter { item -> contentListState.isItemEditable(item.index) }
+ .firstItemAtOffset(dragOffset - contentOffset)
- if (contentListState.isItemEditable(this.index)) {
- movePlaceholderTo(this.index)
- placeHolderIndex = this.index
- }
+ if (targetItem != null) {
+ var scrollIndex: Int? = null
+ var scrollOffset: Int? = null
+ if (placeHolderIndex == state.firstVisibleItemIndex) {
+ // Save info about the first item before the move, to neutralize the automatic
+ // keeping first item first.
+ scrollIndex = placeHolderIndex
+ scrollOffset = state.firstVisibleItemScrollOffset
+ }
- if (scrollIndex != null && scrollOffset != null) {
- // this is needed to neutralize automatic keeping the first item first.
- scope.launch { state.scrollToItem(scrollIndex, scrollOffset) }
- }
+ if (contentListState.isItemEditable(targetItem.index)) {
+ movePlaceholderTo(targetItem.index)
+ placeHolderIndex = targetItem.index
}
+
+ if (scrollIndex != null && scrollOffset != null) {
+ // this is needed to neutralize automatic keeping the first item first.
+ scope.launch { state.scrollToItem(scrollIndex, scrollOffset) }
+ }
+ } else {
+ computeAutoscroll(dragOffset).takeIf { it != 0f }?.let { scrollChannel.trySend(it) }
}
}
fun onDrop(event: DragAndDropEvent): Boolean {
- autoScrollSpeed.value = 0f
- if (isOnRemoveButton) {
- return false
- }
return placeHolderIndex?.let { dropIndex ->
val widgetExtra = event.maybeWidgetExtra() ?: return false
val (componentName, user) = widgetExtra
@@ -221,39 +207,35 @@ internal class DragAndDropTargetState(
}
fun onEnded() {
- autoScrollSpeed.value = 0f
placeHolderIndex = null
contentListState.list.remove(placeHolder)
- isOnRemoveButton = updateDragPositionForRemove(Offset.Zero)
}
- private fun autoScrollIfNearEdges(dragEvent: DragEvent) {
+ fun onExited() {
+ onEnded()
+ }
+
+ private fun computeAutoscroll(dragOffset: Offset): Float {
val orientation = state.layoutInfo.orientation
val distanceFromStart =
if (orientation == Orientation.Horizontal) {
- dragEvent.x
+ dragOffset.x
} else {
- dragEvent.y
+ dragOffset.y
}
val distanceFromEnd =
if (orientation == Orientation.Horizontal) {
- state.layoutInfo.viewportSize.width - dragEvent.x
+ state.layoutInfo.viewportEndOffset - dragOffset.x
} else {
- state.layoutInfo.viewportSize.height - dragEvent.y
+ state.layoutInfo.viewportEndOffset - dragOffset.y
}
- autoScrollSpeed.value =
- when {
- distanceFromEnd < autoScrollThreshold -> autoScrollThreshold - distanceFromEnd
- distanceFromStart < autoScrollThreshold ->
- -(autoScrollThreshold - distanceFromStart)
- else -> 0f
- }
- }
- private fun findTargetItem(dragEvent: DragEvent): LazyGridItemInfo? =
- state.layoutInfo.visibleItemsInfo.firstItemAtOffset(
- Offset(dragEvent.x, dragEvent.y) - contentOffset
- )
+ return when {
+ distanceFromEnd < autoScrollThreshold -> autoScrollThreshold - distanceFromEnd
+ distanceFromStart < autoScrollThreshold -> distanceFromStart - autoScrollThreshold
+ else -> 0f
+ }
+ }
private fun movePlaceholderTo(index: Int) {
val currentIndex = contentListState.list.indexOf(placeHolder)
@@ -271,4 +253,6 @@ internal class DragAndDropTargetState(
val clipData = this.toAndroidDragEvent().clipData.takeIf { it.itemCount != 0 }
return clipData?.getItemAt(0)?.intent?.let { intent -> getWidgetExtraFromIntent(intent) }
}
+
+ private fun DragAndDropEvent.toOffset() = this.toAndroidDragEvent().run { Offset(x, y) }
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalPopupSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalPopupSection.kt
index 1ea73e144962..620892adc286 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalPopupSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalPopupSection.kt
@@ -23,6 +23,8 @@ import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
+import androidx.compose.foundation.focusable
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@@ -39,11 +41,16 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
@@ -54,6 +61,7 @@ import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.ui.viewmodel.PopupType
import com.android.systemui.res.R
import javax.inject.Inject
+import kotlinx.coroutines.delay
class CommunalPopupSection
@Inject
@@ -91,6 +99,17 @@ constructor(
onClick: () -> Unit,
onDismissRequest: () -> Unit,
) {
+ val interactionSource = remember { MutableInteractionSource() }
+ val focusRequester = remember { FocusRequester() }
+
+ val context = LocalContext.current
+
+ LaunchedEffect(Unit) {
+ // Adding a delay to ensure the animation completes before requesting focus
+ delay(250)
+ focusRequester.requestFocus()
+ }
+
Popup(
alignment = Alignment.TopCenter,
offset = IntOffset(0, 40),
@@ -100,6 +119,8 @@ constructor(
Button(
modifier =
Modifier.height(56.dp)
+ .focusRequester(focusRequester)
+ .focusable(interactionSource = interactionSource)
.graphicsLayer { transformOrigin = TransformOrigin(0f, 0f) }
.animateEnterExit(
enter =
@@ -142,8 +163,7 @@ constructor(
) {
Icon(
imageVector = Icons.Outlined.Widgets,
- contentDescription =
- stringResource(R.string.button_to_configure_widgets_text),
+ contentDescription = null,
tint = colors.onSecondary,
modifier = Modifier.size(20.dp)
)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt
index 418df5c7778d..0b9669410b8e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt
@@ -89,7 +89,7 @@ fun AlertDialogContent(
// Content.
val contentColor = LocalAndroidColorScheme.current.onSurfaceVariant
- Box(Modifier.defaultMinSize(minHeight = 48.dp)) {
+ Box {
CompositionLocalProvider(LocalContentColor provides contentColor) {
ProvideTextStyle(
MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.Center)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt
index 887e3494b49e..25e91bed5808 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.ui.composable
+import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
@@ -48,6 +49,16 @@ class LockscreenContent(
fun SceneScope.Content(
modifier: Modifier = Modifier,
) {
+ val isContentVisible: Boolean by viewModel.isContentVisible.collectAsStateWithLifecycle()
+ if (!isContentVisible) {
+ // If the content isn't supposed to be visible, show a large empty box as it's needed
+ // for scene transition animations (can't just skip rendering everything or shared
+ // elements won't have correct final/initial bounds from animating in and out of the
+ // lockscreen scene).
+ Box(modifier)
+ return
+ }
+
val coroutineScope = rememberCoroutineScope()
val blueprintId by viewModel.blueprintId(coroutineScope).collectAsStateWithLifecycle()
val view = LocalView.current
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
index 0a4c6fd21922..7400711e36df 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
@@ -67,8 +67,7 @@ constructor(
@Composable
override fun SceneScope.Content(modifier: Modifier) {
val isUdfpsVisible = viewModel.isUdfpsVisible
- val shouldUseSplitNotificationShade by
- viewModel.shouldUseSplitNotificationShade.collectAsStateWithLifecycle()
+ val isShadeLayoutWide by viewModel.isShadeLayoutWide.collectAsStateWithLifecycle()
val unfoldTranslations by viewModel.unfoldTranslations.collectAsStateWithLifecycle()
LockscreenLongPress(
@@ -100,7 +99,7 @@ constructor(
}
)
}
- if (shouldUseSplitNotificationShade) {
+ if (isShadeLayoutWide) {
with(notificationSection) {
Notifications(
burnInParams = null,
@@ -112,7 +111,7 @@ constructor(
}
}
}
- if (!shouldUseSplitNotificationShade) {
+ if (!isShadeLayoutWide) {
with(notificationSection) {
Notifications(
burnInParams = null,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
index 065f2a2172b1..72cf83269760 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
@@ -69,8 +69,7 @@ constructor(
@Composable
override fun SceneScope.Content(modifier: Modifier) {
val isUdfpsVisible = viewModel.isUdfpsVisible
- val shouldUseSplitNotificationShade by
- viewModel.shouldUseSplitNotificationShade.collectAsStateWithLifecycle()
+ val isShadeLayoutWide by viewModel.isShadeLayoutWide.collectAsStateWithLifecycle()
val unfoldTranslations by viewModel.unfoldTranslations.collectAsStateWithLifecycle()
LockscreenLongPress(
@@ -102,7 +101,7 @@ constructor(
},
)
}
- if (shouldUseSplitNotificationShade) {
+ if (isShadeLayoutWide) {
with(notificationSection) {
Notifications(
burnInParams = null,
@@ -114,7 +113,7 @@ constructor(
}
}
}
- if (!shouldUseSplitNotificationShade) {
+ if (!isShadeLayoutWide) {
with(notificationSection) {
Notifications(
burnInParams = null,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt
index 7f80dfa703bc..859c0366a52f 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt
@@ -90,10 +90,16 @@ constructor(
*/
@Composable
fun SceneScope.Notifications(burnInParams: BurnInParameters?, modifier: Modifier = Modifier) {
- val shouldUseSplitNotificationShade by
- lockscreenContentViewModel.shouldUseSplitNotificationShade.collectAsStateWithLifecycle()
val areNotificationsVisible by
- lockscreenContentViewModel.areNotificationsVisible.collectAsStateWithLifecycle()
+ lockscreenContentViewModel
+ .areNotificationsVisible(sceneKey)
+ .collectAsStateWithLifecycle(initialValue = false)
+ if (!areNotificationsVisible) {
+ return
+ }
+
+ val isShadeLayoutWide by
+ lockscreenContentViewModel.isShadeLayoutWide.collectAsStateWithLifecycle()
val splitShadeTopMargin: Dp =
if (Flags.centralizedStatusBarHeightFix()) {
LargeScreenHeaderHelper.getLargeScreenHeaderHeight(LocalContext.current).dp
@@ -101,19 +107,13 @@ constructor(
dimensionResource(id = R.dimen.large_screen_shade_header_height)
}
- if (!areNotificationsVisible) {
- return
- }
-
ConstrainedNotificationStack(
stackScrollView = stackScrollView.get(),
viewModel = viewModel,
modifier =
modifier
.fillMaxWidth()
- .thenIf(shouldUseSplitNotificationShade) {
- Modifier.padding(top = splitShadeTopMargin)
- }
+ .thenIf(isShadeLayoutWide) { Modifier.padding(top = splitShadeTopMargin) }
.let {
if (burnInParams == null) {
it
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt
index 166aa70c1d4a..f9e22525237b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt
@@ -28,7 +28,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
-import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
import com.android.compose.modifiers.height
import com.android.keyguard.dagger.KeyguardStatusBarViewComponent
@@ -83,29 +82,20 @@ constructor(
componentFactory.build(view, provider).keyguardStatusBarViewController
}
- MovableElement(
- key = StatusBarElementKey,
- modifier = modifier,
- ) {
- content {
- AndroidView(
- factory = {
- notificationPanelView.get().findViewById<View>(R.id.keyguard_header)?.let {
- (it.parent as ViewGroup).removeView(it)
- }
+ AndroidView(
+ factory = {
+ notificationPanelView.get().findViewById<View>(R.id.keyguard_header)?.let {
+ (it.parent as ViewGroup).removeView(it)
+ }
- viewController.init()
- view
- },
- modifier =
- Modifier.fillMaxWidth().padding(horizontal = 16.dp).height {
- Utils.getStatusBarHeaderHeightKeyguard(context)
- },
- update = { viewController.setDisplayCutout(viewDisplayCutout) }
- )
- }
- }
+ viewController.init()
+ view
+ },
+ modifier =
+ Modifier.fillMaxWidth().padding(horizontal = 16.dp).height {
+ Utils.getStatusBarHeaderHeightKeyguard(context)
+ },
+ update = { viewController.setDisplayCutout(viewDisplayCutout) }
+ )
}
}
-
-private val StatusBarElementKey = ElementKey("StatusBar")
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
index 067315381773..0cd4b6816a61 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
@@ -26,6 +26,7 @@ import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
@@ -33,6 +34,7 @@ import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.SceneTransitionLayout
import com.android.compose.modifiers.thenIf
@@ -78,13 +80,22 @@ constructor(
WeatherClockScenes.splitShadeLargeClockScene
}
- SceneTransitionLayout(
- modifier = modifier,
- currentScene = currentScene,
- onChangeScene = {},
- transitions = ClockTransition.defaultClockTransitions,
- enableInterruptions = false,
- ) {
+ val state = remember {
+ MutableSceneTransitionLayoutState(
+ currentScene,
+ ClockTransition.defaultClockTransitions,
+ enableInterruptions = false,
+ )
+ }
+
+ // Update state whenever currentSceneKey has changed.
+ LaunchedEffect(state, currentScene) {
+ if (currentScene != state.transitionState.currentScene) {
+ state.setTargetScene(currentScene, coroutineScope = this)
+ }
+ }
+
+ SceneTransitionLayout(state, modifier) {
scene(splitShadeLargeClockScene) {
LargeClockWithSmartSpace(
shouldOffSetClockToOneHalf = !hasCustomPositionUpdatedAnimation
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
index 581f3a5cacff..d629eec1c45a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
@@ -16,8 +16,10 @@
package com.android.systemui.media.controls.ui.composable
+import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
+import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
@@ -26,7 +28,6 @@ import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.viewinterop.AndroidView
-import androidx.core.view.contains
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
@@ -36,7 +37,8 @@ import com.android.systemui.util.animation.MeasurementInput
private object MediaCarousel {
object Elements {
- internal val Content = ElementKey("MediaCarouselContent")
+ internal val Content =
+ ElementKey(debugName = "MediaCarouselContent", scenePicker = MediaScenePicker)
}
}
@@ -61,40 +63,43 @@ fun SceneScope.MediaCarousel(
mediaHost.measurementInput = MeasurementInput(layoutWidth, layoutHeight)
carouselController.setSceneContainerSize(layoutWidth, layoutHeight)
- AndroidView(
- modifier =
- modifier
- .element(MediaCarousel.Elements.Content)
- .height(mediaHeight)
- .fillMaxWidth()
- .layout { measurable, constraints ->
- val placeable = measurable.measure(constraints)
+ MovableElement(
+ key = MediaCarousel.Elements.Content,
+ modifier = modifier.height(mediaHeight).fillMaxWidth()
+ ) {
+ content {
+ AndroidView(
+ modifier =
+ Modifier.fillMaxSize().layout { measurable, constraints ->
+ val placeable = measurable.measure(constraints)
- // Notify controller to size the carousel for the current space
- mediaHost.measurementInput = MeasurementInput(placeable.width, placeable.height)
- carouselController.setSceneContainerSize(placeable.width, placeable.height)
+ // Notify controller to size the carousel for the current space
+ mediaHost.measurementInput =
+ MeasurementInput(placeable.width, placeable.height)
+ carouselController.setSceneContainerSize(placeable.width, placeable.height)
- layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) }
+ layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) }
+ },
+ factory = { context ->
+ FrameLayout(context).apply {
+ layoutParams =
+ FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ )
+ }
},
- factory = { context ->
- FrameLayout(context).apply {
- val mediaFrame = carouselController.mediaFrame
- (mediaFrame.parent as? ViewGroup)?.removeView(mediaFrame)
- addView(mediaFrame)
- layoutParams =
- FrameLayout.LayoutParams(
- FrameLayout.LayoutParams.MATCH_PARENT,
- FrameLayout.LayoutParams.MATCH_PARENT,
- )
- }
- },
- update = {
- if (it.contains(carouselController.mediaFrame)) {
- return@AndroidView
- }
- val mediaFrame = carouselController.mediaFrame
- (mediaFrame.parent as? ViewGroup)?.removeView(mediaFrame)
- it.addView(mediaFrame)
- },
- )
+ update = { it.setView(carouselController.mediaFrame) },
+ onRelease = { it.removeAllViews() }
+ )
+ }
+ }
+}
+
+private fun ViewGroup.setView(view: View) {
+ if (view.parent == this) {
+ return
+ }
+ (view.parent as? ViewGroup)?.removeView(view)
+ addView(view)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaScenePicker.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaScenePicker.kt
new file mode 100644
index 000000000000..039813390f1e
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaScenePicker.kt
@@ -0,0 +1,72 @@
+/*
+ * 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.composable
+
+import com.android.compose.animation.scene.ElementKey
+import com.android.compose.animation.scene.ElementScenePicker
+import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.TransitionState
+import com.android.systemui.scene.shared.model.Scenes
+
+/** [ElementScenePicker] implementation for the media carousel object. */
+object MediaScenePicker : ElementScenePicker {
+
+ private val shadeLockscreenFraction = 0.65f
+ private val scenes =
+ setOf(
+ Scenes.Lockscreen,
+ Scenes.Shade,
+ Scenes.QuickSettings,
+ Scenes.QuickSettingsShade,
+ Scenes.Communal
+ )
+
+ override fun sceneDuringTransition(
+ element: ElementKey,
+ transition: TransitionState.Transition,
+ fromSceneZIndex: Float,
+ toSceneZIndex: Float
+ ): SceneKey? {
+ return when {
+ // TODO: 352052894 - update with the actual scene picking
+ transition.isTransitioning(from = Scenes.Lockscreen, to = Scenes.Shade) -> {
+ if (transition.progress < shadeLockscreenFraction) {
+ Scenes.Lockscreen
+ } else {
+ Scenes.Shade
+ }
+ }
+
+ // TODO: 345467290 - update with the actual scene picking
+ transition.isTransitioning(from = Scenes.Shade, to = Scenes.Lockscreen) -> {
+ if (transition.progress < 1f - shadeLockscreenFraction) {
+ Scenes.Shade
+ } else {
+ Scenes.Lockscreen
+ }
+ }
+
+ // TODO: 345467290 - update with the actual scene picking
+ transition.isTransitioningBetween(Scenes.QuickSettings, Scenes.Shade) -> {
+ Scenes.QuickSettings
+ }
+
+ // TODO: 340216785 - update with the actual scene picking
+ else -> pickSingleSceneIn(scenes, transition, element)
+ }
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt
index 9f829cccfb32..22c17f2d326c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt
@@ -24,7 +24,9 @@ import androidx.compose.ui.node.LayoutModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.invalidateMeasurement
import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.dp
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
/**
@@ -32,14 +34,16 @@ import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScr
* by the legacy Notification stack scroll view in [NotificationScrollView.intrinsicStackHeight].
*
* @param view Notification stack scroll view
- * @param padding extra padding in pixels to be added to the received content height.
+ * @param totalVerticalPadding extra padding to be added to the received stack content height.
*/
-fun Modifier.notificationStackHeight(view: NotificationScrollView, padding: Int = 0) =
- this then StackLayoutElement(view, padding)
+fun Modifier.notificationStackHeight(
+ view: NotificationScrollView,
+ totalVerticalPadding: Dp = 0.dp,
+) = this then StackLayoutElement(view, totalVerticalPadding)
private data class StackLayoutElement(
val view: NotificationScrollView,
- val padding: Int,
+ val padding: Dp,
) : ModifierNodeElement<StackLayoutNode>() {
override fun create(): StackLayoutNode = StackLayoutNode(view, padding)
@@ -53,7 +57,7 @@ private data class StackLayoutElement(
}
}
-private class StackLayoutNode(val view: NotificationScrollView, var padding: Int) :
+private class StackLayoutNode(val view: NotificationScrollView, var padding: Dp) :
LayoutModifierNode, Modifier.Node() {
private val stackHeightChangedListener = Runnable { invalidateMeasureIfAttached() }
@@ -72,7 +76,7 @@ private class StackLayoutNode(val view: NotificationScrollView, var padding: Int
measurable: Measurable,
constraints: Constraints
): MeasureResult {
- val contentHeight = padding + view.intrinsicStackHeight
+ val contentHeight = padding.roundToPx() + view.intrinsicStackHeight
val placeable =
measurable.measure(
constraints.copy(minHeight = contentHeight, maxHeight = contentHeight)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
index 2eea2f0565c0..776e166f937c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
@@ -19,13 +19,19 @@ package com.android.systemui.notifications.ui.composable
import android.util.Log
import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.tween
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.animateScrollBy
+import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.gestures.scrollBy
+import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.absoluteOffset
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@@ -41,9 +47,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -52,6 +60,7 @@ import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.boundsInWindow
@@ -59,10 +68,12 @@ import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.layout.positionInWindow
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.lerp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -71,6 +82,7 @@ import com.android.compose.animation.scene.LowestZIndexScenePicker
import com.android.compose.animation.scene.NestedScrollBehavior
import com.android.compose.animation.scene.SceneScope
import com.android.compose.modifiers.thenIf
+import com.android.internal.policy.SystemBarUtils
import com.android.systemui.common.ui.compose.windowinsets.LocalRawScreenHeight
import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadius
import com.android.systemui.res.R
@@ -137,6 +149,88 @@ fun SceneScope.HeadsUpNotificationSpace(
)
}
+/**
+ * A version of [HeadsUpNotificationSpace] that can be swiped up off the top edge of the screen by
+ * the user. When swiped up, the heads up notification is snoozed.
+ */
+@Composable
+fun SceneScope.SnoozeableHeadsUpNotificationSpace(
+ stackScrollView: NotificationScrollView,
+ viewModel: NotificationsPlaceholderViewModel,
+) {
+ val context = LocalContext.current
+ val density = LocalDensity.current
+ val statusBarHeight = SystemBarUtils.getStatusBarHeight(context)
+ val headsUpPadding =
+ with(density) { dimensionResource(id = R.dimen.heads_up_status_bar_padding).roundToPx() }
+
+ val isHeadsUp by viewModel.isHeadsUpOrAnimatingAway.collectAsStateWithLifecycle(false)
+
+ var scrollOffset by remember { mutableFloatStateOf(0f) }
+ val minScrollOffset = -(statusBarHeight + headsUpPadding.toFloat())
+ val maxScrollOffset = 0f
+
+ val scrollableState = rememberScrollableState { delta ->
+ consumeDeltaWithinRange(
+ current = scrollOffset,
+ setCurrent = { scrollOffset = it },
+ min = minScrollOffset,
+ max = maxScrollOffset,
+ delta
+ )
+ }
+
+ val nestedScrollConnection =
+ object : NestedScrollConnection {
+ override suspend fun onPreFling(available: Velocity): Velocity {
+ if (
+ velocityOrPositionalThresholdReached(scrollOffset, minScrollOffset, available.y)
+ ) {
+ scrollableState.animateScrollBy(minScrollOffset, tween())
+ } else {
+ scrollableState.animateScrollBy(-minScrollOffset, tween())
+ }
+ return available
+ }
+ }
+
+ LaunchedEffect(isHeadsUp) { scrollOffset = 0f }
+
+ LaunchedEffect(scrollableState.isScrollInProgress) {
+ if (!scrollableState.isScrollInProgress && scrollOffset <= minScrollOffset) {
+ viewModel.setHeadsUpAnimatingAway(false)
+ viewModel.snoozeHun()
+ }
+ }
+
+ HeadsUpNotificationSpace(
+ stackScrollView = stackScrollView,
+ viewModel = viewModel,
+ modifier =
+ Modifier.absoluteOffset {
+ IntOffset(
+ x = 0,
+ y =
+ calculateHeadsUpPlaceholderYOffset(
+ scrollOffset.roundToInt(),
+ minScrollOffset.roundToInt(),
+ stackScrollView.topHeadsUpHeight
+ )
+ )
+ }
+ .thenIf(isHeadsUp) {
+ Modifier.verticalNestedScrollToScene(
+ bottomBehavior = NestedScrollBehavior.EdgeAlways
+ )
+ .nestedScroll(nestedScrollConnection)
+ .scrollable(
+ orientation = Orientation.Vertical,
+ state = scrollableState,
+ )
+ }
+ )
+}
+
/** Adds the space where notification stack should appear in the scene. */
@Composable
fun SceneScope.ConstrainedNotificationStack(
@@ -196,11 +290,9 @@ fun SceneScope.NotificationScrollingStack(
viewModel.isCurrentGestureOverscroll.collectAsStateWithLifecycle(false)
val expansionFraction by viewModel.expandFraction.collectAsStateWithLifecycle(0f)
- val navBarHeightPx =
- with(density) {
- WindowInsets.systemBars.asPaddingValues().calculateBottomPadding().toPx().toInt()
- }
- val bottomPaddingPx = if (shouldReserveSpaceForNavBar) navBarHeightPx else 0
+ val topPadding = dimensionResource(id = R.dimen.notification_side_paddings)
+ val navBarHeight = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
+ val bottomPadding = if (shouldReserveSpaceForNavBar) navBarHeight else 0.dp
val screenHeight = LocalRawScreenHeight.current
@@ -246,7 +338,7 @@ fun SceneScope.NotificationScrollingStack(
// expanded, reset scrim offset.
LaunchedEffect(stackHeight, scrimOffset) {
snapshotFlow { stackHeight.intValue < minVisibleScrimHeight() && scrimOffset.value < 0f }
- .collect { shouldCollapse -> if (shouldCollapse) scrimOffset.snapTo(0f) }
+ .collect { shouldCollapse -> if (shouldCollapse) scrimOffset.animateTo(0f, tween()) }
}
// if we receive scroll delta from NSSL, offset the scrim and placeholder accordingly.
@@ -369,8 +461,12 @@ fun SceneScope.NotificationScrollingStack(
Modifier.nestedScroll(scrimNestedScrollConnection)
}
.verticalScroll(scrollState)
+ .padding(top = topPadding)
.fillMaxWidth()
- .notificationStackHeight(view = stackScrollView, padding = bottomPaddingPx)
+ .notificationStackHeight(
+ view = stackScrollView,
+ totalVerticalPadding = topPadding + bottomPadding,
+ )
.onSizeChanged { size -> stackHeight.intValue = size.height },
)
}
@@ -480,6 +576,47 @@ private fun calculateCornerRadius(
}
}
+private fun calculateHeadsUpPlaceholderYOffset(
+ scrollOffset: Int,
+ minScrollOffset: Int,
+ topHeadsUpHeight: Int,
+): Int {
+ return -minScrollOffset +
+ (scrollOffset * (-minScrollOffset + topHeadsUpHeight) / -minScrollOffset)
+}
+
+private fun velocityOrPositionalThresholdReached(
+ scrollOffset: Float,
+ minScrollOffset: Float,
+ availableVelocityY: Float,
+): Boolean {
+ return availableVelocityY < HUN_SNOOZE_VELOCITY_THRESHOLD ||
+ (availableVelocityY <= 0f &&
+ scrollOffset < minScrollOffset * HUN_SNOOZE_POSITIONAL_THRESHOLD_FRACTION)
+}
+
+/**
+ * Takes a range, current value, and delta, and updates the current value by the delta, coercing the
+ * result within the given range. Returns how much of the delta was consumed.
+ */
+private fun consumeDeltaWithinRange(
+ current: Float,
+ setCurrent: (Float) -> Unit,
+ min: Float,
+ max: Float,
+ delta: Float
+): Float {
+ return if (delta < 0 && current > min) {
+ val remainder = (current + delta - min).coerceAtMost(0f)
+ setCurrent((current + delta).coerceAtLeast(min))
+ delta - remainder
+ } else if (delta > 0 && current < max) {
+ val remainder = (current + delta).coerceAtLeast(0f)
+ setCurrent((current + delta).coerceAtMost(max))
+ delta - remainder
+ } else 0f
+}
+
private inline fun debugLog(
viewModel: NotificationsPlaceholderViewModel,
msg: () -> Any,
@@ -514,3 +651,5 @@ private const val TAG = "FlexiNotifs"
private val DEBUG_STACK_COLOR = Color(1f, 0f, 0f, 0.2f)
private val DEBUG_HUN_COLOR = Color(0f, 0f, 1f, 0.2f)
private val DEBUG_BOX_COLOR = Color(0f, 1f, 0f, 0.2f)
+private const val HUN_SNOOZE_POSITIONAL_THRESHOLD_FRACTION = 0.25f
+private const val HUN_SNOOZE_VELOCITY_THRESHOLD = -70f
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
index c066ae526cbe..422c9f618fa1 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
@@ -16,14 +16,14 @@
package com.android.systemui.qs.ui.composable
-import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
+import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
@@ -46,6 +46,9 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.ui.composable.LockscreenContent
import com.android.systemui.qs.panels.ui.compose.EditMode
import com.android.systemui.qs.panels.ui.compose.TileGrid
+import com.android.systemui.qs.ui.composable.QuickSettingsShade.Transitions.QuickSettingsLayoutEnter
+import com.android.systemui.qs.ui.composable.QuickSettingsShade.Transitions.QuickSettingsLayoutExit
+import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel
import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneViewModel
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.composable.ComposableScene
@@ -95,7 +98,7 @@ constructor(
)
ShadeBody(
- viewModel = viewModel,
+ viewModel = viewModel.quickSettingsContainerViewModel,
)
}
}
@@ -104,39 +107,30 @@ constructor(
@Composable
private fun ShadeBody(
- viewModel: QuickSettingsShadeSceneViewModel,
+ viewModel: QuickSettingsContainerViewModel,
) {
val isEditing by viewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle()
- Box {
- // The main Quick Settings grid layout.
- AnimatedVisibility(
- visible = !isEditing,
- enter = QuickSettingsShade.Transitions.QuickSettingsLayoutEnter,
- exit = QuickSettingsShade.Transitions.QuickSettingsLayoutExit,
- ) {
- QuickSettingsLayout(
- viewModel = viewModel,
- )
- }
-
- // The Quick Settings Editor layout.
- AnimatedVisibility(
- visible = isEditing,
- enter = QuickSettingsShade.Transitions.QuickSettingsEditorEnter,
- exit = QuickSettingsShade.Transitions.QuickSettingsEditorExit,
- ) {
+ AnimatedContent(
+ targetState = isEditing,
+ transitionSpec = { QuickSettingsLayoutEnter togetherWith QuickSettingsLayoutExit }
+ ) { editing ->
+ if (editing) {
EditMode(
viewModel = viewModel.editModeViewModel,
modifier = Modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding)
)
+ } else {
+ QuickSettingsLayout(
+ viewModel = viewModel,
+ )
}
}
}
@Composable
private fun QuickSettingsLayout(
- viewModel: QuickSettingsShadeSceneViewModel,
+ viewModel: QuickSettingsContainerViewModel,
modifier: Modifier = Modifier,
) {
Column(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
index 4e334c274657..a44041a6ebf7 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -17,26 +17,19 @@
package com.android.systemui.scene.ui.composable
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.absoluteOffset
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.res.dimensionResource
-import androidx.compose.ui.unit.IntOffset
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.animateSceneDpAsState
import com.android.compose.animation.scene.animateSceneFloatAsState
-import com.android.internal.policy.SystemBarUtils
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace
+import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotificationSpace
import com.android.systemui.qs.ui.composable.QuickSettings
import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaLandscapeTopOffset
import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaOffset.Default
-import com.android.systemui.res.R
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.viewmodel.GoneSceneViewModel
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
@@ -72,28 +65,9 @@ constructor(
)
animateSceneDpAsState(value = Default, key = MediaLandscapeTopOffset, canOverflow = false)
Spacer(modifier.fillMaxSize())
- HeadsUpNotificationStack(
+ SnoozeableHeadsUpNotificationSpace(
stackScrollView = notificationStackScrolLView.get(),
viewModel = notificationsPlaceholderViewModel
)
}
}
-
-@Composable
-private fun SceneScope.HeadsUpNotificationStack(
- stackScrollView: NotificationScrollView,
- viewModel: NotificationsPlaceholderViewModel,
-) {
- val context = LocalContext.current
- val density = LocalDensity.current
- val statusBarHeight = SystemBarUtils.getStatusBarHeight(context)
- val headsUpPadding =
- with(density) { dimensionResource(id = R.dimen.heads_up_status_bar_padding).roundToPx() }
-
- HeadsUpNotificationSpace(
- stackScrollView = stackScrollView,
- viewModel = viewModel,
- modifier =
- Modifier.absoluteOffset { IntOffset(x = 0, y = statusBarHeight + headsUpPadding) }
- )
-}
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 a94ebc8f86d2..865622326fcd 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
@@ -193,7 +193,7 @@ object OverlayShade {
}
object Colors {
- val ScrimBackground = Color(0, 0, 0, alpha = 255 / 3)
+ val ScrimBackground = Color(0f, 0f, 0f, alpha = 0.2f)
val PanelBackground: Color
@Composable @ReadOnlyComposable get() = MaterialTheme.colorScheme.surfaceContainer
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index 4a6599a04fab..805351ea8bbe 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -34,9 +34,11 @@ import androidx.compose.foundation.layout.displayCutoutPadding
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
@@ -51,6 +53,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.platform.LocalDensity
@@ -60,6 +63,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.LowestZIndexScenePicker
+import com.android.compose.animation.scene.NestedScrollBehavior
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.TransitionState
import com.android.compose.animation.scene.UserAction
@@ -255,6 +259,8 @@ private fun SceneScope.SingleShade(
val mediaOffset by
animateSceneDpAsState(value = InQQS, key = MediaLandscapeTopOffset, canOverflow = false)
+ val navBarHeight = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
+
Box(
modifier =
modifier.thenIf(shouldPunchHoleBehindScrim) {
@@ -358,11 +364,22 @@ private fun SceneScope.SingleShade(
notificationsPlaceable.placeRelative(x = 0, y = maxNotifScrimTop.value.roundToInt())
}
}
- NotificationStackCutoffGuideline(
- stackScrollView = notificationStackScrollView,
- viewModel = notificationsPlaceholderViewModel,
- modifier = Modifier.align(Alignment.BottomCenter).navigationBarsPadding()
- )
+ Box(
+ modifier =
+ Modifier.align(Alignment.BottomCenter)
+ .height(navBarHeight)
+ .pointerInteropFilter { true }
+ .verticalNestedScrollToScene(
+ topBehavior = NestedScrollBehavior.EdgeAlways,
+ isExternalOverscrollGesture = { false }
+ )
+ ) {
+ NotificationStackCutoffGuideline(
+ stackScrollView = notificationStackScrollView,
+ viewModel = notificationsPlaceholderViewModel,
+ modifier = Modifier.align(Alignment.TopCenter)
+ )
+ }
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/ui/composable/StatusBar.kt b/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/ui/composable/StatusBar.kt
deleted file mode 100644
index f514ab4a710b..000000000000
--- a/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/ui/composable/StatusBar.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- *
- */
-
-package com.android.systemui.statusbar.ui.composable
-
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.defaultMinSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
-
-@Composable
-fun StatusBar(
- modifier: Modifier = Modifier,
-) {
- // TODO(b/272780101): implement.
- Row(
- modifier = modifier.fillMaxWidth().defaultMinSize(minHeight = 48.dp).padding(4.dp),
- horizontalArrangement = Arrangement.Center,
- verticalAlignment = Alignment.CenterVertically,
- ) {
- Text("Status bar")
- }
-}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
index fbf91b702fb9..a23bb67215b5 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
@@ -48,6 +48,7 @@ import com.android.compose.PlatformSlider
import com.android.compose.PlatformSliderColors
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.ui.compose.Icon
+import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderState
@Composable
@@ -62,7 +63,7 @@ fun VolumeSlider(
val value by valueState(state)
PlatformSlider(
modifier =
- modifier.clearAndSetSemantics {
+ modifier.sysuiResTag(state.label).clearAndSetSemantics {
if (state.isEnabled) {
contentDescription = state.label
state.a11yClickDescription?.let {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
index ab14911ab425..9da2a1b06f30 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
@@ -25,20 +25,25 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.paneTitle
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.res.R
import com.android.systemui.volume.panel.ui.layout.ComponentsLayout
import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelState
import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel
+/** Same as android.platform.systemui_tapl.ui.VolumePanel#VolumePanelTestTag */
+private const val VolumePanelTestTag = "VolumePanel"
private val padding = 24.dp
@Composable
+@OptIn(ExperimentalComposeUiApi::class)
fun VolumePanelRoot(
viewModel: VolumePanelViewModel,
modifier: Modifier = Modifier,
@@ -52,6 +57,7 @@ fun VolumePanelRoot(
Components(
componentsState,
modifier
+ .sysuiResTag(VolumePanelTestTag)
.semantics { paneTitle = accessibilityTitle }
.padding(
start = padding,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index e8fdfc8da3bc..20b1303ae6bd 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -184,31 +184,33 @@ internal class DraggableHandlerImpl(
): Swipes {
val fromSource =
startedPosition?.let { position ->
- layoutImpl.swipeSourceDetector.source(
- fromScene.targetSize,
- position.round(),
- layoutImpl.density,
- orientation,
- )
+ layoutImpl.swipeSourceDetector
+ .source(
+ fromScene.targetSize,
+ position.round(),
+ layoutImpl.density,
+ orientation,
+ )
+ ?.resolve(layoutImpl.layoutDirection)
}
val upOrLeft =
- Swipe(
+ Swipe.Resolved(
direction =
when (orientation) {
- Orientation.Horizontal -> SwipeDirection.Left
- Orientation.Vertical -> SwipeDirection.Up
+ Orientation.Horizontal -> SwipeDirection.Resolved.Left
+ Orientation.Vertical -> SwipeDirection.Resolved.Up
},
pointerCount = pointersDown,
fromSource = fromSource,
)
val downOrRight =
- Swipe(
+ Swipe.Resolved(
direction =
when (orientation) {
- Orientation.Horizontal -> SwipeDirection.Right
- Orientation.Vertical -> SwipeDirection.Down
+ Orientation.Horizontal -> SwipeDirection.Resolved.Right
+ Orientation.Vertical -> SwipeDirection.Resolved.Down
},
pointerCount = pointersDown,
fromSource = fromSource,
@@ -833,10 +835,10 @@ private object DefaultSwipeDistance : UserActionDistance {
/** The [Swipe] associated to a given fromScene, startedPosition and pointersDown. */
private class Swipes(
- val upOrLeft: Swipe?,
- val downOrRight: Swipe?,
- val upOrLeftNoSource: Swipe?,
- val downOrRightNoSource: Swipe?,
+ val upOrLeft: Swipe.Resolved?,
+ val downOrRight: Swipe.Resolved?,
+ val upOrLeftNoSource: Swipe.Resolved?,
+ val downOrRightNoSource: Swipe.Resolved?,
) {
/** The [UserActionResult] associated to up and down swipes. */
var upOrLeftResult: UserActionResult? = null
@@ -844,7 +846,7 @@ private class Swipes(
fun computeSwipesResults(fromScene: Scene): Pair<UserActionResult?, UserActionResult?> {
val userActions = fromScene.userActions
- fun result(swipe: Swipe?): UserActionResult? {
+ fun result(swipe: Swipe.Resolved?): UserActionResult? {
return userActions[swipe ?: return null]
}
@@ -913,6 +915,7 @@ internal class NestedScrollHandlerImpl(
private val topOrLeftBehavior: NestedScrollBehavior,
private val bottomOrRightBehavior: NestedScrollBehavior,
private val isExternalOverscrollGesture: () -> Boolean,
+ private val pointersInfoOwner: PointersInfoOwner,
) {
private val layoutState = layoutImpl.state
private val draggableHandler = layoutImpl.draggableHandler(orientation)
@@ -924,25 +927,12 @@ internal class NestedScrollHandlerImpl(
// moving on to the next scene.
var canChangeScene = false
- val actionUpOrLeft =
- Swipe(
- direction =
- when (orientation) {
- Orientation.Horizontal -> SwipeDirection.Left
- Orientation.Vertical -> SwipeDirection.Up
- },
- pointerCount = 1,
- )
-
- val actionDownOrRight =
- Swipe(
- direction =
- when (orientation) {
- Orientation.Horizontal -> SwipeDirection.Right
- Orientation.Vertical -> SwipeDirection.Down
- },
- pointerCount = 1,
- )
+ var _lastPointersInfo: PointersInfo? = null
+ fun pointersInfo(): PointersInfo {
+ return checkNotNull(_lastPointersInfo) {
+ "PointersInfo should be initialized before the transition begins."
+ }
+ }
fun hasNextScene(amount: Float): Boolean {
val transitionState = layoutState.transitionState
@@ -950,8 +940,32 @@ internal class NestedScrollHandlerImpl(
val fromScene = layoutImpl.scene(scene)
val nextScene =
when {
- amount < 0f -> fromScene.userActions[actionUpOrLeft]
- amount > 0f -> fromScene.userActions[actionDownOrRight]
+ amount < 0f -> {
+ val actionUpOrLeft =
+ Swipe.Resolved(
+ direction =
+ when (orientation) {
+ Orientation.Horizontal -> SwipeDirection.Resolved.Left
+ Orientation.Vertical -> SwipeDirection.Resolved.Up
+ },
+ pointerCount = pointersInfo().pointersDown,
+ fromSource = null,
+ )
+ fromScene.userActions[actionUpOrLeft]
+ }
+ amount > 0f -> {
+ val actionDownOrRight =
+ Swipe.Resolved(
+ direction =
+ when (orientation) {
+ Orientation.Horizontal -> SwipeDirection.Resolved.Right
+ Orientation.Vertical -> SwipeDirection.Resolved.Down
+ },
+ pointerCount = pointersInfo().pointersDown,
+ fromSource = null,
+ )
+ fromScene.userActions[actionDownOrRight]
+ }
else -> null
}
if (nextScene != null) return true
@@ -985,6 +999,8 @@ internal class NestedScrollHandlerImpl(
return@PriorityNestedScrollConnection false
}
+ _lastPointersInfo = pointersInfoOwner.pointersInfo()
+
// If the current swipe transition is *not* closed to 0f or 1f, then we want the
// scroll events to intercept the current transition to continue the scene
// transition.
@@ -1002,6 +1018,8 @@ internal class NestedScrollHandlerImpl(
val isZeroOffset =
if (isExternalOverscrollGesture()) false else offsetBeforeStart == 0f
+ _lastPointersInfo = pointersInfoOwner.pointersInfo()
+
val canStart =
when (behavior) {
NestedScrollBehavior.DuringTransitionBetweenScenes -> {
@@ -1039,6 +1057,8 @@ internal class NestedScrollHandlerImpl(
// We could start an overscroll animation
canChangeScene = false
+ _lastPointersInfo = pointersInfoOwner.pointersInfo()
+
val canStart = behavior.canStartOnPostFling && hasNextScene(velocityAvailable)
if (canStart) {
isIntercepting = false
@@ -1049,10 +1069,11 @@ internal class NestedScrollHandlerImpl(
canContinueScroll = { true },
canScrollOnFling = false,
onStart = { offsetAvailable ->
+ val pointersInfo = pointersInfo()
dragController =
draggableHandler.onDragStarted(
- pointersDown = 1,
- startedPosition = null,
+ pointersDown = pointersInfo.pointersDown,
+ startedPosition = pointersInfo.startedPosition,
overSlop = if (isIntercepting) 0f else offsetAvailable,
)
},
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/EdgeDetector.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/EdgeDetector.kt
index b0dc3a144533..97c0cef30388 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/EdgeDetector.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/EdgeDetector.kt
@@ -21,14 +21,28 @@ import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
/** The edge of a [SceneTransitionLayout]. */
-enum class Edge : SwipeSource {
- Left,
- Right,
- Top,
- Bottom,
+enum class Edge(private val resolveEdge: (LayoutDirection) -> Resolved) : SwipeSource {
+ Top(resolveEdge = { Resolved.Top }),
+ Bottom(resolveEdge = { Resolved.Bottom }),
+ Left(resolveEdge = { Resolved.Left }),
+ Right(resolveEdge = { Resolved.Right }),
+ Start(resolveEdge = { if (it == LayoutDirection.Ltr) Resolved.Left else Resolved.Right }),
+ End(resolveEdge = { if (it == LayoutDirection.Ltr) Resolved.Right else Resolved.Left });
+
+ override fun resolve(layoutDirection: LayoutDirection): Resolved {
+ return resolveEdge(layoutDirection)
+ }
+
+ enum class Resolved : SwipeSource.Resolved {
+ Left,
+ Right,
+ Top,
+ Bottom,
+ }
}
val DefaultEdgeDetector = FixedSizeEdgeDetector(40.dp)
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
index 572b1d7ab670..615d393f8bee 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
@@ -29,18 +29,21 @@ import androidx.compose.ui.input.pointer.PointerId
import androidx.compose.ui.input.pointer.PointerInputChange
import androidx.compose.ui.input.pointer.PointerInputScope
import androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode
-import androidx.compose.ui.input.pointer.changedToDownIgnoreConsumed
+import androidx.compose.ui.input.pointer.changedToDown
import androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.input.pointer.positionChangeIgnoreConsumed
import androidx.compose.ui.input.pointer.util.VelocityTracker
import androidx.compose.ui.input.pointer.util.addPointerInputChange
import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
+import androidx.compose.ui.node.DelegatableNode
import androidx.compose.ui.node.DelegatingNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.ObserverModifierNode
import androidx.compose.ui.node.PointerInputModifierNode
+import androidx.compose.ui.node.TraversableNode
import androidx.compose.ui.node.currentValueOf
+import androidx.compose.ui.node.findNearestAncestor
import androidx.compose.ui.node.observeReads
import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.unit.IntSize
@@ -48,11 +51,12 @@ import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.util.fastAll
import androidx.compose.ui.util.fastAny
import androidx.compose.ui.util.fastFirstOrNull
-import androidx.compose.ui.util.fastForEach
+import androidx.compose.ui.util.fastSumBy
import kotlin.coroutines.cancellation.CancellationException
import kotlin.math.sign
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
/**
* Make an element draggable in the given [orientation].
@@ -112,6 +116,18 @@ private data class MultiPointerDraggableElement(
}
}
+private val TRAVERSE_KEY = Any()
+
+/** Find the nearest [PointersInfoOwner] ancestor or throw. */
+internal fun DelegatableNode.requireAncestorPointersInfoOwner(): PointersInfoOwner {
+ val ancestorNode =
+ checkNotNull(findNearestAncestor(TRAVERSE_KEY)) {
+ "This should never happen! Couldn't find a MultiPointerDraggableNode. " +
+ "Are we inside an SceneTransitionLayout?"
+ }
+ return ancestorNode as PointersInfoOwner
+}
+
internal class MultiPointerDraggableNode(
orientation: Orientation,
enabled: () -> Boolean,
@@ -120,15 +136,19 @@ internal class MultiPointerDraggableNode(
(startedPosition: Offset, overSlop: Float, pointersDown: Int) -> DragController,
var swipeDetector: SwipeDetector = DefaultSwipeDetector,
) :
- PointerInputModifierNode,
DelegatingNode(),
+ PointerInputModifierNode,
CompositionLocalConsumerModifierNode,
+ TraversableNode,
+ PointersInfoOwner,
ObserverModifierNode {
private val pointerInputHandler: suspend PointerInputScope.() -> Unit = { pointerInput() }
private val delegate = delegate(SuspendingPointerInputModifierNode(pointerInputHandler))
private val velocityTracker = VelocityTracker()
private var previousEnabled: Boolean = false
+ override val traverseKey: Any = TRAVERSE_KEY
+
var enabled: () -> Boolean = enabled
set(value) {
// Reset the pointer input whenever enabled changed.
@@ -185,49 +205,86 @@ internal class MultiPointerDraggableNode(
bounds: IntSize
) = delegate.onPointerEvent(pointerEvent, pass, bounds)
+ private var startedPosition: Offset? = null
+ private var pointersDown: Int = 0
+
+ override fun pointersInfo(): PointersInfo {
+ return PointersInfo(
+ startedPosition = startedPosition,
+ // Note: We could have 0 pointers during fling or for other reasons.
+ pointersDown = pointersDown.coerceAtLeast(1),
+ )
+ }
+
private suspend fun PointerInputScope.pointerInput() {
if (!enabled()) {
return
}
coroutineScope {
- awaitPointerEventScope {
- while (isActive) {
- try {
- detectDragGestures(
- orientation = orientation,
- startDragImmediately = startDragImmediately,
- onDragStart = { startedPosition, overSlop, pointersDown ->
- velocityTracker.resetTracking()
- onDragStarted(startedPosition, overSlop, pointersDown)
- },
- onDrag = { controller, change, amount ->
- velocityTracker.addPointerInputChange(change)
- controller.onDrag(amount)
- },
- onDragEnd = { controller ->
- val viewConfiguration = currentValueOf(LocalViewConfiguration)
- val maxVelocity =
- viewConfiguration.maximumFlingVelocity.let { Velocity(it, it) }
- val velocity = velocityTracker.calculateVelocity(maxVelocity)
- controller.onStop(
- velocity =
- when (orientation) {
- Orientation.Horizontal -> velocity.x
- Orientation.Vertical -> velocity.y
- },
- canChangeScene = true,
- )
- },
- onDragCancel = { controller ->
- controller.onStop(velocity = 0f, canChangeScene = true)
- },
- swipeDetector = swipeDetector
- )
- } catch (exception: CancellationException) {
- // If the coroutine scope is active, we can just restart the drag cycle.
- if (!isActive) {
- throw exception
+ launch {
+ // Intercepts pointer inputs and exposes [PointersInfo], via
+ // [requireAncestorPointersInfoOwner], to our descendants.
+ awaitPointerEventScope {
+ while (isActive) {
+ // During the Initial pass, we receive the event after our ancestors.
+ val pointers = awaitPointerEvent(PointerEventPass.Initial).changes
+
+ pointersDown = pointers.countDown()
+ if (pointersDown == 0) {
+ // There are no more pointers down
+ startedPosition = null
+ } else if (startedPosition == null) {
+ startedPosition = pointers.first().position
+ }
+ }
+ }
+ }
+
+ // The order is important here: we want to make sure that the previous PointerEventScope
+ // is initialized first. This ensures that the following PointerEventScope doesn't
+ // receive more events than the first one.
+ launch {
+ awaitPointerEventScope {
+ while (isActive) {
+ try {
+ detectDragGestures(
+ orientation = orientation,
+ startDragImmediately = startDragImmediately,
+ onDragStart = { startedPosition, overSlop, pointersDown ->
+ velocityTracker.resetTracking()
+ onDragStarted(startedPosition, overSlop, pointersDown)
+ },
+ onDrag = { controller, change, amount ->
+ velocityTracker.addPointerInputChange(change)
+ controller.onDrag(amount)
+ },
+ onDragEnd = { controller ->
+ val viewConfiguration = currentValueOf(LocalViewConfiguration)
+ val maxVelocity =
+ viewConfiguration.maximumFlingVelocity.let {
+ Velocity(it, it)
+ }
+ val velocity = velocityTracker.calculateVelocity(maxVelocity)
+ controller.onStop(
+ velocity =
+ when (orientation) {
+ Orientation.Horizontal -> velocity.x
+ Orientation.Vertical -> velocity.y
+ },
+ canChangeScene = true,
+ )
+ },
+ onDragCancel = { controller ->
+ controller.onStop(velocity = 0f, canChangeScene = true)
+ },
+ swipeDetector = swipeDetector
+ )
+ } catch (exception: CancellationException) {
+ // If the coroutine scope is active, we can just restart the drag cycle.
+ if (!isActive) {
+ throw exception
+ }
}
}
}
@@ -314,15 +371,16 @@ internal class MultiPointerDraggableNode(
}
if (drag != null) {
- // Count the number of pressed pointers.
- val pressed = mutableSetOf<PointerId>()
- currentEvent.changes.fastForEach { change ->
- if (change.pressed) {
- pressed.add(change.id)
- }
- }
-
- val controller = onDragStart(drag.position, overSlop, pressed.size)
+ val controller =
+ onDragStart(
+ // The startedPosition is the starting position when a gesture begins (when the
+ // first pointer touches the screen), not the point where we begin dragging.
+ // For example, this could be different if one of our children intercepts the
+ // gesture first and then we do.
+ requireNotNull(startedPosition),
+ overSlop,
+ pointersDown,
+ )
val successful: Boolean
try {
@@ -362,15 +420,15 @@ internal class MultiPointerDraggableNode(
pass: () -> PointerEventPass,
): PointerEvent {
fun canBeConsumed(changes: List<PointerInputChange>): Boolean {
- // All pointers must be:
- return changes.fastAll {
- // A) recently pressed: even if the event has already been consumed, we can still
- // use the recently added finger event to determine whether to initiate dragging the
- // scene.
- it.changedToDownIgnoreConsumed() ||
- // B) unconsumed AND in a new position (on the current axis)
- it.positionChange().toFloat() != 0f
- }
+ // At least one pointer down AND
+ return changes.fastAny { it.pressed } &&
+ // All pointers must be either:
+ changes.fastAll {
+ // A) unconsumed AND recently pressed
+ it.changedToDown() ||
+ // B) unconsumed AND in a new position (on the current axis)
+ it.positionChange().toFloat() != 0f
+ }
}
var event: PointerEvent
@@ -459,4 +517,15 @@ internal class MultiPointerDraggableNode(
}
}
}
+
+ private fun List<PointerInputChange>.countDown() = fastSumBy { if (it.pressed) 1 else 0 }
}
+
+internal fun interface PointersInfoOwner {
+ fun pointersInfo(): PointersInfo
+}
+
+internal data class PointersInfo(
+ val startedPosition: Offset?,
+ val pointersDown: Int,
+)
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt
index 1fa6b3f7d6c0..ddff2f709082 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt
@@ -128,6 +128,7 @@ private class NestedScrollToSceneNode(
bottomOrRightBehavior: NestedScrollBehavior,
isExternalOverscrollGesture: () -> Boolean,
) : DelegatingNode() {
+ lateinit var pointersInfoOwner: PointersInfoOwner
private var priorityNestedScrollConnection: PriorityNestedScrollConnection =
scenePriorityNestedScrollConnection(
layoutImpl = layoutImpl,
@@ -135,6 +136,7 @@ private class NestedScrollToSceneNode(
topOrLeftBehavior = topOrLeftBehavior,
bottomOrRightBehavior = bottomOrRightBehavior,
isExternalOverscrollGesture = isExternalOverscrollGesture,
+ pointersInfoOwner = { pointersInfoOwner.pointersInfo() }
)
private var nestedScrollNode: DelegatableNode =
@@ -144,6 +146,7 @@ private class NestedScrollToSceneNode(
)
override fun onAttach() {
+ pointersInfoOwner = requireAncestorPointersInfoOwner()
delegate(nestedScrollNode)
}
@@ -171,6 +174,7 @@ private class NestedScrollToSceneNode(
topOrLeftBehavior = topOrLeftBehavior,
bottomOrRightBehavior = bottomOrRightBehavior,
isExternalOverscrollGesture = isExternalOverscrollGesture,
+ pointersInfoOwner = pointersInfoOwner,
)
nestedScrollNode =
nestedScrollModifierNode(
@@ -187,6 +191,7 @@ private fun scenePriorityNestedScrollConnection(
topOrLeftBehavior: NestedScrollBehavior,
bottomOrRightBehavior: NestedScrollBehavior,
isExternalOverscrollGesture: () -> Boolean,
+ pointersInfoOwner: PointersInfoOwner,
) =
NestedScrollHandlerImpl(
layoutImpl = layoutImpl,
@@ -194,5 +199,6 @@ private fun scenePriorityNestedScrollConnection(
topOrLeftBehavior = topOrLeftBehavior,
bottomOrRightBehavior = bottomOrRightBehavior,
isExternalOverscrollGesture = isExternalOverscrollGesture,
+ pointersInfoOwner = pointersInfoOwner,
)
.connection
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
new file mode 100644
index 000000000000..734241e2faf6
--- /dev/null
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
@@ -0,0 +1,127 @@
+/*
+ * 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.compose.animation.scene
+
+import androidx.activity.BackEventCompat
+import androidx.activity.compose.PredictiveBackHandler
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.AnimationVector1D
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import kotlin.coroutines.cancellation.CancellationException
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.CoroutineStart
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
+
+@Composable
+internal fun PredictiveBackHandler(
+ state: BaseSceneTransitionLayoutState,
+ coroutineScope: CoroutineScope,
+ targetSceneForBack: SceneKey? = null,
+) {
+ PredictiveBackHandler(
+ enabled = targetSceneForBack != null,
+ ) { progress: Flow<BackEventCompat> ->
+ val fromScene = state.transitionState.currentScene
+ if (targetSceneForBack == null || targetSceneForBack == fromScene) {
+ // Note: We have to collect progress otherwise PredictiveBackHandler will throw.
+ progress.first()
+ return@PredictiveBackHandler
+ }
+
+ val transition =
+ PredictiveBackTransition(state, coroutineScope, fromScene, toScene = targetSceneForBack)
+ state.startTransition(transition)
+ try {
+ progress.collect { backEvent -> transition.dragProgress = backEvent.progress }
+
+ // Back gesture successful.
+ transition.animateTo(targetSceneForBack)
+ } catch (e: CancellationException) {
+ // Back gesture cancelled.
+ transition.animateTo(fromScene)
+ }
+ }
+}
+
+private class PredictiveBackTransition(
+ val state: BaseSceneTransitionLayoutState,
+ val coroutineScope: CoroutineScope,
+ fromScene: SceneKey,
+ toScene: SceneKey,
+) : TransitionState.Transition(fromScene, toScene) {
+ override var currentScene by mutableStateOf(fromScene)
+ private set
+
+ /** The animated progress once the gesture was committed or cancelled. */
+ private var progressAnimatable by mutableStateOf<Animatable<Float, AnimationVector1D>?>(null)
+ var dragProgress: Float by mutableFloatStateOf(0f)
+
+ override val progress: Float
+ get() = progressAnimatable?.value ?: dragProgress
+
+ override val progressVelocity: Float
+ get() = progressAnimatable?.velocity ?: 0f
+
+ override val isInitiatedByUserInput: Boolean
+ get() = true
+
+ override val isUserInputOngoing: Boolean
+ get() = progressAnimatable == null
+
+ private var animationJob: Job? = null
+
+ override fun finish(): Job = animateTo(currentScene)
+
+ fun animateTo(scene: SceneKey): Job {
+ check(scene == fromScene || scene == toScene)
+ animationJob?.let {
+ return it
+ }
+
+ if (scene != currentScene && state.transitionState == this && state.canChangeScene(scene)) {
+ currentScene = scene
+ }
+
+ val targetProgress =
+ when (currentScene) {
+ fromScene -> 0f
+ toScene -> 1f
+ else -> error("scene $currentScene should be either $fromScene or $toScene")
+ }
+
+ val animatable = Animatable(dragProgress).also { progressAnimatable = it }
+
+ // Important: We start atomically to make sure that we start the coroutine even if it is
+ // cancelled right after it is launched, so that finishTransition() is correctly called.
+ return coroutineScope
+ .launch(start = CoroutineStart.ATOMIC) {
+ try {
+ animatable.animateTo(targetProgress)
+ } finally {
+ state.finishTransition(this@PredictiveBackTransition, scene)
+ }
+ }
+ .also { animationJob = it }
+ }
+}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PunchHole.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PunchHole.kt
deleted file mode 100644
index b346a70e61f9..000000000000
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PunchHole.kt
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.compose.animation.scene
-
-import androidx.compose.runtime.Stable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.geometry.Size
-import androidx.compose.ui.graphics.BlendMode
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.CompositingStrategy
-import androidx.compose.ui.graphics.Outline
-import androidx.compose.ui.graphics.RectangleShape
-import androidx.compose.ui.graphics.Shape
-import androidx.compose.ui.graphics.drawOutline
-import androidx.compose.ui.graphics.drawscope.ContentDrawScope
-import androidx.compose.ui.graphics.drawscope.DrawScope
-import androidx.compose.ui.graphics.drawscope.translate
-import androidx.compose.ui.layout.LayoutCoordinates
-import androidx.compose.ui.layout.Measurable
-import androidx.compose.ui.layout.MeasureResult
-import androidx.compose.ui.layout.MeasureScope
-import androidx.compose.ui.node.DelegatingNode
-import androidx.compose.ui.node.DrawModifierNode
-import androidx.compose.ui.node.GlobalPositionAwareModifierNode
-import androidx.compose.ui.node.LayoutModifierNode
-import androidx.compose.ui.node.ModifierNodeElement
-import androidx.compose.ui.unit.Constraints
-import androidx.compose.ui.unit.LayoutDirection
-import androidx.compose.ui.unit.toSize
-
-/**
- * Punch a hole in this node with the given [size], [offset] and [shape].
- *
- * Punching a hole in an element will "remove" any pixel drawn by that element in the hole area.
- * This can be used to make content drawn below an opaque element visible. For example, if we have
- * [this lockscreen scene](http://shortn/_VYySFnJDhN) drawn below
- * [this shade scene](http://shortn/_fpxGUk0Rg7) and punch a hole in the latter using the big clock
- * time bounds and a RoundedCornerShape(10dp), [this](http://shortn/_qt80IvORFj) would be the
- * result.
- */
-@Stable
-fun Modifier.punchHole(
- size: () -> Size,
- offset: () -> Offset,
- shape: Shape = RectangleShape,
-): Modifier = this.then(PunchHoleElement(size, offset, shape))
-
-/**
- * Punch a hole in this node using the bounds of [coords] and the given [shape].
- *
- * You can use [androidx.compose.ui.layout.onGloballyPositioned] to get the last coordinates of a
- * node.
- */
-@Stable
-fun Modifier.punchHole(
- coords: () -> LayoutCoordinates?,
- shape: Shape = RectangleShape,
-): Modifier = this.then(PunchHoleWithBoundsElement(coords, shape))
-
-private data class PunchHoleElement(
- private val size: () -> Size,
- private val offset: () -> Offset,
- private val shape: Shape,
-) : ModifierNodeElement<PunchHoleNode>() {
- override fun create(): PunchHoleNode = PunchHoleNode(size, offset, { shape })
-
- override fun update(node: PunchHoleNode) {
- node.size = size
- node.offset = offset
- node.shape = { shape }
- }
-}
-
-private class PunchHoleNode(
- var size: () -> Size,
- var offset: () -> Offset,
- var shape: () -> Shape,
-) : Modifier.Node(), DrawModifierNode, LayoutModifierNode {
- private var lastSize: Size = Size.Unspecified
- private var lastLayoutDirection: LayoutDirection = LayoutDirection.Ltr
- private var lastOutline: Outline? = null
-
- override fun MeasureScope.measure(
- measurable: Measurable,
- constraints: Constraints
- ): MeasureResult {
- return measurable.measure(constraints).run {
- layout(width, height) {
- placeWithLayer(0, 0) { compositingStrategy = CompositingStrategy.Offscreen }
- }
- }
- }
-
- override fun ContentDrawScope.draw() {
- drawContent()
-
- val holeSize = size()
- if (holeSize != Size.Zero) {
- val offset = offset()
- translate(offset.x, offset.y) { drawHole(holeSize) }
- }
- }
-
- private fun DrawScope.drawHole(size: Size) {
- if (shape == RectangleShape) {
- drawRect(Color.Black, size = size, blendMode = BlendMode.DstOut)
- return
- }
-
- val outline =
- if (size == lastSize && layoutDirection == lastLayoutDirection) {
- lastOutline!!
- } else {
- val newOutline = shape().createOutline(size, layoutDirection, this)
- lastSize = size
- lastLayoutDirection = layoutDirection
- lastOutline = newOutline
- newOutline
- }
-
- drawOutline(
- outline,
- Color.Black,
- blendMode = BlendMode.DstOut,
- )
- }
-}
-
-private data class PunchHoleWithBoundsElement(
- private val coords: () -> LayoutCoordinates?,
- private val shape: Shape,
-) : ModifierNodeElement<PunchHoleWithBoundsNode>() {
- override fun create(): PunchHoleWithBoundsNode = PunchHoleWithBoundsNode(coords, shape)
-
- override fun update(node: PunchHoleWithBoundsNode) {
- node.holeCoords = coords
- node.shape = shape
- }
-}
-
-private class PunchHoleWithBoundsNode(
- var holeCoords: () -> LayoutCoordinates?,
- var shape: Shape,
-) : DelegatingNode(), DrawModifierNode, GlobalPositionAwareModifierNode {
- private val delegate = delegate(PunchHoleNode(::holeSize, ::holeOffset, ::shape))
- private var lastCoords: LayoutCoordinates? = null
-
- override fun onGloballyPositioned(coordinates: LayoutCoordinates) {
- this.lastCoords = coordinates
- }
-
- override fun ContentDrawScope.draw() = with(delegate) { draw() }
-
- private fun holeSize(): Size {
- return holeCoords()?.size?.toSize() ?: Size.Zero
- }
-
- private fun holeOffset(): Offset {
- val holeCoords = holeCoords() ?: return Offset.Zero
- val lastCoords = lastCoords ?: error("draw() was called before onGloballyPositioned()")
- return lastCoords.localPositionOf(holeCoords, relativeToSource = Offset.Zero)
- }
-}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt
index 936f4ba0efef..a49f1af97183 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt
@@ -37,7 +37,7 @@ internal class Scene(
val key: SceneKey,
layoutImpl: SceneTransitionLayoutImpl,
content: @Composable SceneScope.() -> Unit,
- actions: Map<UserAction, UserActionResult>,
+ actions: Map<UserAction.Resolved, UserActionResult>,
zIndex: Float,
) {
internal val scope = SceneScopeImpl(layoutImpl, this)
@@ -54,8 +54,8 @@ internal class Scene(
}
private fun checkValid(
- userActions: Map<UserAction, UserActionResult>
- ): Map<UserAction, UserActionResult> {
+ userActions: Map<UserAction.Resolved, UserActionResult>
+ ): Map<UserAction.Resolved, UserActionResult> {
userActions.forEach { (action, result) ->
if (key == result.toScene) {
error(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index 7c8fce8f297d..0c467b181cd8 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -28,10 +28,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.LayoutDirection
+import com.android.compose.animation.scene.UserAction.Resolved
/**
* [SceneTransitionLayout] is a container that automatically animates its content whenever its state
@@ -48,7 +51,6 @@ import androidx.compose.ui.unit.IntSize
* @param transitionInterceptionThreshold used during a scene transition. For the scene to be
* intercepted, the progress value must be above the threshold, and below (1 - threshold).
* @param scenes the configuration of the different scenes of this layout.
- * @see updateSceneTransitionLayoutState
*/
@Composable
fun SceneTransitionLayout(
@@ -70,56 +72,6 @@ fun SceneTransitionLayout(
)
}
-/**
- * [SceneTransitionLayout] is a container that automatically animates its content whenever
- * [currentScene] changes, using the transitions defined in [transitions].
- *
- * Note: You should use [androidx.compose.animation.AnimatedContent] instead of
- * [SceneTransitionLayout] if it fits your need. Use [SceneTransitionLayout] over AnimatedContent if
- * you need support for swipe gestures, shared elements or transitions defined declaratively outside
- * UI code.
- *
- * @param currentScene the current scene
- * @param onChangeScene a mutator that should set [currentScene] to the given scene when called.
- * This is called when the user commits a transition to a new scene because of a [UserAction], for
- * instance by triggering back navigation or by swiping to a new scene.
- * @param transitions the definition of the transitions used to animate a change of scene.
- * @param swipeSourceDetector the source detector used to detect which source a swipe is started
- * from, if any.
- * @param transitionInterceptionThreshold used during a scene transition. For the scene to be
- * intercepted, the progress value must be above the threshold, and below (1 - threshold).
- * @param scenes the configuration of the different scenes of this layout.
- */
-@Composable
-fun SceneTransitionLayout(
- currentScene: SceneKey,
- onChangeScene: (SceneKey) -> Unit,
- transitions: SceneTransitions,
- modifier: Modifier = Modifier,
- swipeSourceDetector: SwipeSourceDetector = DefaultEdgeDetector,
- swipeDetector: SwipeDetector = DefaultSwipeDetector,
- @FloatRange(from = 0.0, to = 0.5) transitionInterceptionThreshold: Float = 0f,
- enableInterruptions: Boolean = DEFAULT_INTERRUPTIONS_ENABLED,
- scenes: SceneTransitionLayoutScope.() -> Unit,
-) {
- val state =
- updateSceneTransitionLayoutState(
- currentScene,
- onChangeScene,
- transitions,
- enableInterruptions = enableInterruptions,
- )
-
- SceneTransitionLayout(
- state,
- modifier,
- swipeSourceDetector,
- swipeDetector,
- transitionInterceptionThreshold,
- scenes,
- )
-}
-
interface SceneTransitionLayoutScope {
/**
* Add a scene to this layout, identified by [key].
@@ -395,34 +347,71 @@ interface ElementBoxScope {
@Stable @ElementDsl interface MovableElementContentScope : BaseSceneScope, ElementBoxScope
/** An action performed by the user. */
-sealed interface UserAction {
+sealed class UserAction {
infix fun to(scene: SceneKey): Pair<UserAction, UserActionResult> {
return this to UserActionResult(toScene = scene)
}
+
+ /** Resolve this into a [Resolved] user action given [layoutDirection]. */
+ internal abstract fun resolve(layoutDirection: LayoutDirection): Resolved
+
+ /** A resolved [UserAction] that does not depend on the layout direction. */
+ internal sealed class Resolved
}
/** The user navigated back, either using a gesture or by triggering a KEYCODE_BACK event. */
-data object Back : UserAction
+data object Back : UserAction() {
+ override fun resolve(layoutDirection: LayoutDirection): Resolved = Resolved
+
+ internal object Resolved : UserAction.Resolved()
+}
/** The user swiped on the container. */
data class Swipe(
val direction: SwipeDirection,
val pointerCount: Int = 1,
val fromSource: SwipeSource? = null,
-) : UserAction {
+) : UserAction() {
companion object {
val Left = Swipe(SwipeDirection.Left)
val Up = Swipe(SwipeDirection.Up)
val Right = Swipe(SwipeDirection.Right)
val Down = Swipe(SwipeDirection.Down)
+ val Start = Swipe(SwipeDirection.Start)
+ val End = Swipe(SwipeDirection.End)
}
+
+ override fun resolve(layoutDirection: LayoutDirection): UserAction.Resolved {
+ return Resolved(
+ direction = direction.resolve(layoutDirection),
+ pointerCount = pointerCount,
+ fromSource = fromSource?.resolve(layoutDirection),
+ )
+ }
+
+ /** A resolved [Swipe] that does not depend on the layout direction. */
+ internal data class Resolved(
+ val direction: SwipeDirection.Resolved,
+ val pointerCount: Int,
+ val fromSource: SwipeSource.Resolved?,
+ ) : UserAction.Resolved()
}
-enum class SwipeDirection(val orientation: Orientation) {
- Up(Orientation.Vertical),
- Down(Orientation.Vertical),
- Left(Orientation.Horizontal),
- Right(Orientation.Horizontal),
+enum class SwipeDirection(internal val resolve: (LayoutDirection) -> Resolved) {
+ Up(resolve = { Resolved.Up }),
+ Down(resolve = { Resolved.Down }),
+ Left(resolve = { Resolved.Left }),
+ Right(resolve = { Resolved.Right }),
+ Start(resolve = { if (it == LayoutDirection.Ltr) Resolved.Left else Resolved.Right }),
+ End(resolve = { if (it == LayoutDirection.Ltr) Resolved.Right else Resolved.Left });
+
+ /** A resolved [SwipeDirection] that does not depend on the layout direction. */
+ internal enum class Resolved(val orientation: Orientation) {
+ Up(Orientation.Vertical),
+ Down(Orientation.Vertical),
+ Left(Orientation.Horizontal),
+ Right(Orientation.Horizontal),
+ }
}
/**
@@ -437,6 +426,16 @@ interface SwipeSource {
override fun equals(other: Any?): Boolean
override fun hashCode(): Int
+
+ /** Resolve this into a [Resolved] swipe source given [layoutDirection]. */
+ fun resolve(layoutDirection: LayoutDirection): Resolved
+
+ /** A resolved [SwipeSource] that does not depend on the layout direction. */
+ interface Resolved {
+ override fun equals(other: Any?): Boolean
+
+ override fun hashCode(): Int
+ }
}
interface SwipeSourceDetector {
@@ -511,11 +510,13 @@ internal fun SceneTransitionLayoutForTesting(
scenes: SceneTransitionLayoutScope.() -> Unit,
) {
val density = LocalDensity.current
+ val layoutDirection = LocalLayoutDirection.current
val coroutineScope = rememberCoroutineScope()
val layoutImpl = remember {
SceneTransitionLayoutImpl(
state = state as BaseSceneTransitionLayoutState,
density = density,
+ layoutDirection = layoutDirection,
swipeSourceDetector = swipeSourceDetector,
transitionInterceptionThreshold = transitionInterceptionThreshold,
builder = scenes,
@@ -526,7 +527,7 @@ internal fun SceneTransitionLayoutForTesting(
// TODO(b/317014852): Move this into the SideEffect {} again once STLImpl.scenes is not a
// SnapshotStateMap anymore.
- layoutImpl.updateScenes(scenes)
+ layoutImpl.updateScenes(scenes, layoutDirection)
SideEffect {
if (state != layoutImpl.state) {
@@ -537,6 +538,7 @@ internal fun SceneTransitionLayoutForTesting(
}
layoutImpl.density = density
+ layoutImpl.layoutDirection = layoutDirection
layoutImpl.swipeSourceDetector = swipeSourceDetector
layoutImpl.transitionInterceptionThreshold = transitionInterceptionThreshold
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index 7ea8cbdd7a97..3e48c429ba7d 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -16,7 +16,6 @@
package com.android.compose.animation.scene
-import androidx.activity.compose.BackHandler
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
@@ -34,6 +33,7 @@ import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastForEachReversed
import com.android.compose.ui.util.lerp
@@ -46,6 +46,7 @@ internal typealias MovableElementContent = @Composable (@Composable () -> Unit)
internal class SceneTransitionLayoutImpl(
internal val state: BaseSceneTransitionLayoutState,
internal var density: Density,
+ internal var layoutDirection: LayoutDirection,
internal var swipeSourceDetector: SwipeSourceDetector,
internal var transitionInterceptionThreshold: Float,
builder: SceneTransitionLayoutScope.() -> Unit,
@@ -115,7 +116,7 @@ internal class SceneTransitionLayoutImpl(
private set
init {
- updateScenes(builder)
+ updateScenes(builder, layoutDirection)
// DraggableHandlerImpl must wait for the scenes to be initialized, in order to access the
// current scene (required for SwipeTransition).
@@ -148,7 +149,10 @@ internal class SceneTransitionLayoutImpl(
return scenes[key] ?: error("Scene $key is not configured")
}
- internal fun updateScenes(builder: SceneTransitionLayoutScope.() -> Unit) {
+ internal fun updateScenes(
+ builder: SceneTransitionLayoutScope.() -> Unit,
+ layoutDirection: LayoutDirection,
+ ) {
// Keep a reference of the current scenes. After processing [builder], the scenes that were
// not configured will be removed.
val scenesToRemove = scenes.keys.toMutableSet()
@@ -164,11 +168,13 @@ internal class SceneTransitionLayoutImpl(
) {
scenesToRemove.remove(key)
+ val resolvedUserActions =
+ userActions.mapKeys { it.key.resolve(layoutDirection) }
val scene = scenes[key]
if (scene != null) {
// Update an existing scene.
scene.content = content
- scene.userActions = userActions
+ scene.userActions = resolvedUserActions
scene.zIndex = zIndex
} else {
// New scene.
@@ -177,7 +183,7 @@ internal class SceneTransitionLayoutImpl(
key,
this@SceneTransitionLayoutImpl,
content,
- userActions,
+ resolvedUserActions,
zIndex,
)
}
@@ -213,16 +219,9 @@ internal class SceneTransitionLayoutImpl(
@Composable
private fun BackHandler() {
- val targetSceneForBackOrNull =
- scene(state.transitionState.currentScene).userActions[Back]?.toScene
- BackHandler(enabled = targetSceneForBackOrNull != null) {
- targetSceneForBackOrNull?.let { targetSceneForBack ->
- // TODO(b/290184746): Handle predictive back and use result.distance if specified.
- if (state.canChangeScene(targetSceneForBack)) {
- with(state) { coroutineScope.onChangeScene(targetSceneForBack) }
- }
- }
- }
+ val targetSceneForBack =
+ scene(state.transitionState.currentScene).userActions[Back.Resolved]?.toScene
+ PredictiveBackHandler(state, coroutineScope, targetSceneForBack)
}
private fun scenesToCompose(): List<Scene> {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
index 5b4fbf036083..56c8752eb53c 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
@@ -22,13 +22,9 @@ import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationVector1D
import androidx.compose.animation.core.spring
import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.util.fastAll
import androidx.compose.ui.util.fastFilter
@@ -38,14 +34,12 @@ import com.android.compose.animation.scene.transition.link.StateLink
import kotlin.math.absoluteValue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
-import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
/**
* The state of a [SceneTransitionLayout].
*
* @see MutableSceneTransitionLayoutState
- * @see updateSceneTransitionLayoutState
*/
@Stable
sealed interface SceneTransitionLayoutState {
@@ -152,55 +146,6 @@ fun MutableSceneTransitionLayoutState(
)
}
-/**
- * Sets up a [SceneTransitionLayoutState] and keeps it synced with [currentScene], [onChangeScene]
- * and [transitions]. New transitions will automatically be started whenever [currentScene] is
- * changed.
- *
- * @param currentScene the current scene
- * @param onChangeScene a mutator that should set [currentScene] to the given scene when called.
- * This is called when the user commits a transition to a new scene because of a [UserAction], for
- * instance by triggering back navigation or by swiping to a new scene.
- * @param transitions the definition of the transitions used to animate a change of scene.
- * @param canChangeScene whether we can transition to the given scene. This is called when the user
- * commits a transition to a new scene because of a [UserAction]. If [canChangeScene] returns
- * `true`, then [onChangeScene] will be called right afterwards with the same [SceneKey]. If it
- * returns `false`, the user action will be cancelled and we will animate back to the current
- * scene.
- * @param stateLinks the [StateLink] connecting this [SceneTransitionLayoutState] to other
- * [SceneTransitionLayoutState]s.
- */
-@Composable
-fun updateSceneTransitionLayoutState(
- currentScene: SceneKey,
- onChangeScene: (SceneKey) -> Unit,
- transitions: SceneTransitions = SceneTransitions.Empty,
- canChangeScene: (SceneKey) -> Boolean = { true },
- stateLinks: List<StateLink> = emptyList(),
- enableInterruptions: Boolean = DEFAULT_INTERRUPTIONS_ENABLED,
-): SceneTransitionLayoutState {
- return remember {
- HoistedSceneTransitionLayoutState(
- currentScene,
- transitions,
- onChangeScene,
- canChangeScene,
- stateLinks,
- enableInterruptions,
- )
- }
- .apply {
- update(
- currentScene,
- onChangeScene,
- canChangeScene,
- transitions,
- stateLinks,
- enableInterruptions,
- )
- }
-}
-
@Stable
sealed interface TransitionState {
/**
@@ -729,58 +674,6 @@ internal abstract class BaseSceneTransitionLayoutState(
}
}
-/**
- * A [SceneTransitionLayout] whose current scene/source of truth is hoisted (its current value comes
- * from outside).
- */
-internal class HoistedSceneTransitionLayoutState(
- initialScene: SceneKey,
- override var transitions: SceneTransitions,
- private var changeScene: (SceneKey) -> Unit,
- private var canChangeScene: (SceneKey) -> Boolean,
- stateLinks: List<StateLink> = emptyList(),
- enableInterruptions: Boolean = DEFAULT_INTERRUPTIONS_ENABLED,
-) : BaseSceneTransitionLayoutState(initialScene, stateLinks, enableInterruptions) {
- private val targetSceneChannel = Channel<SceneKey>(Channel.CONFLATED)
-
- override fun canChangeScene(scene: SceneKey): Boolean = canChangeScene.invoke(scene)
-
- override fun CoroutineScope.onChangeScene(scene: SceneKey) = changeScene.invoke(scene)
-
- @Composable
- fun update(
- currentScene: SceneKey,
- onChangeScene: (SceneKey) -> Unit,
- canChangeScene: (SceneKey) -> Boolean,
- transitions: SceneTransitions,
- stateLinks: List<StateLink>,
- enableInterruptions: Boolean,
- ) {
- SideEffect {
- this.changeScene = onChangeScene
- this.canChangeScene = canChangeScene
- this.transitions = transitions
- this.stateLinks = stateLinks
- this.enableInterruptions = enableInterruptions
-
- targetSceneChannel.trySend(currentScene)
- }
-
- LaunchedEffect(targetSceneChannel) {
- for (newKey in targetSceneChannel) {
- // Inspired by AnimateAsState.kt: let's poll the last value to avoid being one frame
- // late.
- val newKey = targetSceneChannel.tryReceive().getOrNull() ?: newKey
- animateToScene(
- layoutState = this@HoistedSceneTransitionLayoutState,
- target = newKey,
- transitionKey = null,
- )
- }
- }
- }
-}
-
/** A [MutableSceneTransitionLayoutState] that holds the value for the current scene. */
internal class MutableSceneTransitionLayoutStateImpl(
initialScene: SceneKey,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
index 171e2430c004..aeb62628a8f4 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
@@ -98,7 +98,9 @@ private class SwipeToSceneNode(
/** Whether swipe should be enabled in the given [orientation]. */
private fun Scene.shouldEnableSwipes(orientation: Orientation): Boolean {
- return userActions.keys.any { it is Swipe && it.direction.orientation == orientation }
+ return userActions.keys.any {
+ it is Swipe.Resolved && it.direction.orientation == orientation
+ }
}
private fun startDragImmediately(startedPosition: Offset): Boolean {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt
index aa8dc38fdd8f..7daefd0d5d77 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt
@@ -44,26 +44,26 @@ internal class EdgeTranslate(
return value
}
- return when (edge) {
- Edge.Top ->
+ return when (edge.resolve(layoutImpl.layoutDirection)) {
+ Edge.Resolved.Top ->
if (startsOutsideLayoutBounds) {
Offset(value.x, -elementSize.height.toFloat())
} else {
Offset(value.x, 0f)
}
- Edge.Left ->
+ Edge.Resolved.Left ->
if (startsOutsideLayoutBounds) {
Offset(-elementSize.width.toFloat(), value.y)
} else {
Offset(0f, value.y)
}
- Edge.Bottom ->
+ Edge.Resolved.Bottom ->
if (startsOutsideLayoutBounds) {
Offset(value.x, sceneSize.height.toFloat())
} else {
Offset(value.x, (sceneSize.height - elementSize.height).toFloat())
}
- Edge.Right ->
+ Edge.Resolved.Right ->
if (startsOutsideLayoutBounds) {
Offset(sceneSize.width.toFloat(), value.y)
} else {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/CommunalSwipeDetector.kt b/packages/SystemUI/compose/scene/src/com/android/systemui/communal/ui/compose/CommunalSwipeDetector.kt
index 7be34cabfaf8..3fda9b85a5c2 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/CommunalSwipeDetector.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/systemui/communal/ui/compose/CommunalSwipeDetector.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.compose.animation.scene
+package com.android.systemui.communal.ui.compose
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.input.pointer.PointerInputChange
@@ -22,10 +22,12 @@ import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
+import com.android.compose.animation.scene.Edge
+import com.android.compose.animation.scene.SwipeDetector
+import com.android.compose.animation.scene.SwipeSource
+import com.android.compose.animation.scene.SwipeSourceDetector
import kotlin.math.abs
-private const val TRAVEL_RATIO_THRESHOLD = .5f
-
/**
* {@link CommunalSwipeDetector} provides an implementation of {@link SwipeDetector} and {@link
* SwipeSourceDetector} to enable fullscreen swipe handling to transition to and from the glanceable
@@ -33,6 +35,10 @@ private const val TRAVEL_RATIO_THRESHOLD = .5f
*/
class CommunalSwipeDetector(private var lastDirection: SwipeSource? = null) :
SwipeSourceDetector, SwipeDetector {
+ companion object {
+ private const val TRAVEL_RATIO_THRESHOLD = .5f
+ }
+
override fun source(
layoutSize: IntSize,
position: IntOffset,
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
index 65b388f66a0d..7a5a84e2c3f1 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
@@ -25,6 +25,7 @@ import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.Velocity
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.compose.animation.scene.NestedScrollBehavior.DuringTransitionBetweenScenes
@@ -61,8 +62,24 @@ class DraggableHandlerTest {
canChangeScene = { canChangeScene(it) },
)
- val mutableUserActionsA = mutableMapOf(Swipe.Up to SceneB, Swipe.Down to SceneC)
- val mutableUserActionsB = mutableMapOf(Swipe.Up to SceneC, Swipe.Down to SceneA)
+ var layoutDirection = LayoutDirection.Rtl
+ set(value) {
+ field = value
+ layoutImpl.updateScenes(scenesBuilder, layoutDirection)
+ }
+
+ var mutableUserActionsA = mapOf(Swipe.Up to SceneB, Swipe.Down to SceneC)
+ set(value) {
+ field = value
+ layoutImpl.updateScenes(scenesBuilder, layoutDirection)
+ }
+
+ var mutableUserActionsB = mapOf(Swipe.Up to SceneC, Swipe.Down to SceneA)
+ set(value) {
+ field = value
+ layoutImpl.updateScenes(scenesBuilder, layoutDirection)
+ }
+
private val scenesBuilder: SceneTransitionLayoutScope.() -> Unit = {
scene(
key = SceneA,
@@ -94,6 +111,7 @@ class DraggableHandlerTest {
SceneTransitionLayoutImpl(
state = layoutState,
density = Density(1f),
+ layoutDirection = LayoutDirection.Ltr,
swipeSourceDetector = DefaultEdgeDetector,
transitionInterceptionThreshold = transitionInterceptionThreshold,
builder = scenesBuilder,
@@ -113,7 +131,10 @@ class DraggableHandlerTest {
orientation = draggableHandler.orientation,
topOrLeftBehavior = nestedScrollBehavior,
bottomOrRightBehavior = nestedScrollBehavior,
- isExternalOverscrollGesture = { isExternalOverscrollGesture }
+ isExternalOverscrollGesture = { isExternalOverscrollGesture },
+ pointersInfoOwner = {
+ PointersInfo(startedPosition = Offset.Zero, pointersDown = 1)
+ }
)
.connection
@@ -463,10 +484,8 @@ class DraggableHandlerTest {
dragController1.onDragStopped(velocity = -velocityThreshold)
assertTransition(currentScene = SceneB, fromScene = SceneA, toScene = SceneB)
- mutableUserActionsA.remove(Swipe.Up)
- mutableUserActionsA.remove(Swipe.Down)
- mutableUserActionsB.remove(Swipe.Up)
- mutableUserActionsB.remove(Swipe.Down)
+ mutableUserActionsA = emptyMap()
+ mutableUserActionsB = emptyMap()
// start accelaratedScroll and scroll over to B -> null
val dragController2 = onDragStartedImmediately()
@@ -492,7 +511,7 @@ class DraggableHandlerTest {
val dragController1 = onDragStarted(overSlop = up(fractionOfScreen = 0.1f))
assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.1f)
- mutableUserActionsA[Swipe.Up] = UserActionResult(SceneC)
+ mutableUserActionsA += Swipe.Up to UserActionResult(SceneC)
dragController1.onDragDelta(pixels = up(fractionOfScreen = 0.1f))
// target stays B even though UserActions changed
assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.2f)
@@ -509,7 +528,7 @@ class DraggableHandlerTest {
val dragController1 = onDragStarted(overSlop = up(fractionOfScreen = 0.1f))
assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.1f)
- mutableUserActionsA[Swipe.Up] = UserActionResult(SceneC)
+ mutableUserActionsA += Swipe.Up to UserActionResult(SceneC)
dragController1.onDragDelta(pixels = up(fractionOfScreen = 0.1f))
dragController1.onDragStopped(velocity = down(fractionOfScreen = 0.1f))
@@ -1146,8 +1165,7 @@ class DraggableHandlerTest {
overscroll(SceneA, Orientation.Vertical) { fade(TestElements.Foo) }
}
- mutableUserActionsA.clear()
- mutableUserActionsA[Swipe.Up] = UserActionResult(SceneB)
+ mutableUserActionsA = mapOf(Swipe.Up to UserActionResult(SceneB))
val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f)
val dragController = onDragStarted(startedPosition = middle, overSlop = down(1f))
@@ -1175,8 +1193,7 @@ class DraggableHandlerTest {
overscroll(SceneA, Orientation.Vertical) { fade(TestElements.Foo) }
}
- mutableUserActionsA.clear()
- mutableUserActionsA[Swipe.Down] = UserActionResult(SceneC)
+ mutableUserActionsA = mapOf(Swipe.Down to UserActionResult(SceneC))
val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f)
val dragController = onDragStarted(startedPosition = middle, overSlop = up(1f))
@@ -1217,7 +1234,8 @@ class DraggableHandlerTest {
@Test
fun requireFullDistanceSwipe() = runGestureTest {
- mutableUserActionsA[Swipe.Up] = UserActionResult(SceneB, requiresFullDistanceSwipe = true)
+ mutableUserActionsA +=
+ Swipe.Up to UserActionResult(SceneB, requiresFullDistanceSwipe = true)
val controller = onDragStarted(overSlop = up(fractionOfScreen = 0.9f))
assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.9f)
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
index 2de6faaccca2..7988e0e4e416 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
@@ -203,26 +203,28 @@ class ElementTest {
val elementSize = 50.dp
val elementOffset = 20.dp
- lateinit var changeScene: (SceneKey) -> Unit
-
- rule.testTransition(
- from = SceneA,
- to = SceneB,
- transitionLayout = { currentScene, onChangeScene ->
- changeScene = onChangeScene
-
- SceneTransitionLayout(
- currentScene,
- onChangeScene,
+ val state =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutState(
+ SceneA,
transitions {
from(SceneA, to = SceneB) { spec = tween }
from(SceneB, to = SceneC) { spec = tween }
},
- // Disable interruptions so that the current transition is directly removed when
- // starting a new one.
+ // Disable interruptions so that the current transition is directly removed
+ // when starting a new one.
enableInterruptions = false,
- ) {
+ )
+ }
+
+ lateinit var coroutineScope: CoroutineScope
+ rule.testTransition(
+ state = state,
+ to = SceneB,
+ transitionLayout = { state ->
+ coroutineScope = rememberCoroutineScope()
+ SceneTransitionLayout(state) {
scene(SceneA) {
Box(Modifier.size(layoutSize)) {
// Transformed element
@@ -243,7 +245,7 @@ class ElementTest {
onElement(TestElements.Bar).assertExists()
// Start transition from SceneB to SceneC
- changeScene(SceneC)
+ rule.runOnUiThread { state.setTargetScene(SceneC, coroutineScope) }
}
at(3 * frameDuration) { onElement(TestElements.Bar).assertIsNotDisplayed() }
@@ -340,18 +342,16 @@ class ElementTest {
@Test
fun elementIsReusedBetweenScenes() {
- var currentScene by mutableStateOf(SceneA)
+ val state = rule.runOnUiThread { MutableSceneTransitionLayoutState(SceneA) }
var sceneCState by mutableStateOf(0)
val key = TestElements.Foo
var nullableLayoutImpl: SceneTransitionLayoutImpl? = null
+ lateinit var coroutineScope: CoroutineScope
rule.setContent {
+ coroutineScope = rememberCoroutineScope()
SceneTransitionLayoutForTesting(
- state =
- updateSceneTransitionLayoutState(
- currentScene = currentScene,
- onChangeScene = { currentScene = it }
- ),
+ state = state,
onLayoutImpl = { nullableLayoutImpl = it },
) {
scene(SceneA) { /* Nothing */ }
@@ -375,7 +375,7 @@ class ElementTest {
assertThat(layoutImpl.elements).isEmpty()
// Scene B: element is in the map.
- currentScene = SceneB
+ rule.runOnUiThread { state.setTargetScene(SceneB, coroutineScope) }
rule.waitForIdle()
assertThat(layoutImpl.elements.keys).containsExactly(key)
@@ -383,7 +383,7 @@ class ElementTest {
assertThat(element.sceneStates.keys).containsExactly(SceneB)
// Scene C, state 0: the same element is reused.
- currentScene = SceneC
+ rule.runOnUiThread { state.setTargetScene(SceneC, coroutineScope) }
sceneCState = 0
rule.waitForIdle()
@@ -472,12 +472,13 @@ class ElementTest {
@Test
fun elementModifierSupportsUpdates() {
+ val state = rule.runOnUiThread { MutableSceneTransitionLayoutState(SceneA) }
var key by mutableStateOf(TestElements.Foo)
var nullableLayoutImpl: SceneTransitionLayoutImpl? = null
rule.setContent {
SceneTransitionLayoutForTesting(
- state = updateSceneTransitionLayoutState(currentScene = SceneA, onChangeScene = {}),
+ state = state,
onLayoutImpl = { nullableLayoutImpl = it },
) {
scene(SceneA) { Box(Modifier.element(key)) }
@@ -521,11 +522,12 @@ class ElementTest {
rule.waitUntil(timeoutMillis = 10_000) { animationFinished }
}
+ val state = rule.runOnUiThread { MutableSceneTransitionLayoutState(SceneA) }
rule.setContent {
scrollScope = rememberCoroutineScope()
SceneTransitionLayoutForTesting(
- state = updateSceneTransitionLayoutState(currentScene = SceneA, onChangeScene = {}),
+ state = state,
onLayoutImpl = { nullableLayoutImpl = it },
) {
scene(SceneA) {
@@ -839,6 +841,80 @@ class ElementTest {
}
@Test
+ fun elementTransitionDuringNestedScrollWith2Pointers() {
+ // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
+ // detected as a drag event.
+ var touchSlop = 0f
+ val translateY = 10.dp
+ val layoutWidth = 200.dp
+ val layoutHeight = 400.dp
+
+ val state =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutState(
+ initialScene = SceneA,
+ transitions =
+ transitions {
+ from(SceneA, to = SceneB) {
+ translate(TestElements.Foo, y = translateY)
+ }
+ },
+ )
+ as MutableSceneTransitionLayoutStateImpl
+ }
+
+ rule.setContent {
+ touchSlop = LocalViewConfiguration.current.touchSlop
+ SceneTransitionLayout(
+ state = state,
+ modifier = Modifier.size(layoutWidth, layoutHeight)
+ ) {
+ scene(
+ SceneA,
+ userActions = mapOf(Swipe(SwipeDirection.Down, pointerCount = 2) to SceneB)
+ ) {
+ Box(
+ Modifier
+ // Unconsumed scroll gesture will be intercepted by STL
+ .verticalNestedScrollToScene()
+ // A scrollable that does not consume the scroll gesture
+ .scrollable(
+ rememberScrollableState(consumeScrollDelta = { 0f }),
+ Orientation.Vertical
+ )
+ .fillMaxSize()
+ ) {
+ Spacer(Modifier.element(TestElements.Foo).fillMaxSize())
+ }
+ }
+ scene(SceneB) { Spacer(Modifier.fillMaxSize()) }
+ }
+ }
+
+ assertThat(state.transitionState).isIdle()
+ val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
+ fooElement.assertTopPositionInRootIsEqualTo(0.dp)
+
+ // Swipe down with 2 pointers by half of verticalSwipeDistance.
+ rule.onRoot().performTouchInput {
+ val middleTop = Offset((layoutWidth / 2).toPx(), 0f)
+ repeat(2) { i -> down(pointerId = i, middleTop) }
+ repeat(2) { i ->
+ // Scroll 50%
+ moveBy(
+ pointerId = i,
+ delta = Offset(0f, touchSlop + layoutHeight.toPx() * 0.5f),
+ delayMillis = 1_000,
+ )
+ }
+ }
+
+ val transition = assertThat(state.transitionState).isTransition()
+ assertThat(transition).hasProgress(0.5f)
+ fooElement.assertTopPositionInRootIsEqualTo(translateY * 0.5f)
+ }
+
+ @Test
fun elementTransitionWithDistanceDuringOverscroll() {
val layoutWidth = 200.dp
val layoutHeight = 400.dp
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
index 1a0740b54892..ecafb170535d 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
@@ -121,6 +121,82 @@ class MultiPointerDraggableTest {
}
@Test
+ fun shouldNotStartDragEventsWith0PointersDown() {
+ val size = 200f
+ val middle = Offset(size / 2f, size / 2f)
+
+ var started = false
+ var dragged = false
+ var stopped = false
+ var consumedByDescendant = false
+
+ var touchSlop = 0f
+ rule.setContent {
+ touchSlop = LocalViewConfiguration.current.touchSlop
+ Box(
+ Modifier.size(with(LocalDensity.current) { Size(size, size).toDpSize() })
+ .multiPointerDraggable(
+ orientation = Orientation.Vertical,
+ enabled = { true },
+ // We want to start a drag gesture immediately
+ startDragImmediately = { true },
+ onDragStarted = { _, _, _ ->
+ started = true
+ object : DragController {
+ override fun onDrag(delta: Float) {
+ dragged = true
+ }
+
+ override fun onStop(velocity: Float, canChangeScene: Boolean) {
+ stopped = true
+ }
+ }
+ },
+ )
+ .pointerInput(Unit) {
+ coroutineScope {
+ awaitPointerEventScope {
+ while (isActive) {
+ val change = awaitPointerEvent().changes.first()
+ if (consumedByDescendant) {
+ change.consume()
+ }
+ }
+ }
+ }
+ }
+ )
+ }
+
+ // The first part of the gesture is consumed by our descendant
+ consumedByDescendant = true
+ rule.onRoot().performTouchInput {
+ down(middle)
+ moveBy(Offset(0f, touchSlop))
+ }
+
+ // The events were consumed by our descendant, we should not start a drag gesture.
+ assertThat(started).isFalse()
+ assertThat(dragged).isFalse()
+ assertThat(stopped).isFalse()
+
+ // The next events could be consumed by us
+ consumedByDescendant = false
+ rule.onRoot().performTouchInput {
+ // The pointer is moved to a new position without reporting it
+ updatePointerBy(0, Offset(0f, touchSlop))
+
+ // The pointer report an "up" (0 pointers down) with a new position
+ up()
+ }
+
+ // The "up" event should not be used to start a drag gesture
+ assertThat(started).isFalse()
+ assertThat(dragged).isFalse()
+ assertThat(stopped).isFalse()
+ }
+
+ @Test
fun handleDisappearingScrollableDuringAGesture() {
val size = 200f
val middle = Offset(size / 2f, size / 2f)
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ObservableTransitionStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ObservableTransitionStateTest.kt
index 55431354b693..f717301dba38 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ObservableTransitionStateTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ObservableTransitionStateTest.kt
@@ -40,7 +40,13 @@ class ObservableTransitionStateTest {
@Test
fun testObservableTransitionState() = runTest {
- lateinit var state: SceneTransitionLayoutState
+ val state =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutState(
+ SceneA,
+ EmptyTestTransitions,
+ )
+ }
// Collect the current observable state into [observableState].
// TODO(b/290184746): Use collectValues {} once it is extracted into a library that can be
@@ -63,16 +69,9 @@ class ObservableTransitionStateTest {
}
rule.testTransition(
- from = SceneA,
+ state = state,
to = SceneB,
- transitionLayout = { currentScene, onChangeScene ->
- state =
- updateSceneTransitionLayoutState(
- currentScene,
- onChangeScene,
- EmptyTestTransitions
- )
-
+ transitionLayout = {
SceneTransitionLayout(state = state) {
scene(SceneA) {}
scene(SceneB) {}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt
new file mode 100644
index 000000000000..6522eb33bd49
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt
@@ -0,0 +1,159 @@
+/*
+ * 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.compose.animation.scene
+
+import androidx.activity.BackEventCompat
+import androidx.activity.ComponentActivity
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compose.animation.scene.TestScenes.SceneA
+import com.android.compose.animation.scene.TestScenes.SceneB
+import com.android.compose.animation.scene.TestScenes.SceneC
+import com.android.compose.animation.scene.subjects.assertThat
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class PredictiveBackHandlerTest {
+ // We use createAndroidComposeRule() here and not createComposeRule() because we need an
+ // activity for testBack().
+ @get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
+
+ @Test
+ fun testBack() {
+ val layoutState = rule.runOnUiThread { MutableSceneTransitionLayoutState(SceneA) }
+ rule.setContent {
+ SceneTransitionLayout(layoutState) {
+ scene(SceneA, mapOf(Back to SceneB)) { Box(Modifier.fillMaxSize()) }
+ scene(SceneB) { Box(Modifier.fillMaxSize()) }
+ }
+ }
+
+ assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
+
+ rule.runOnUiThread { rule.activity.onBackPressedDispatcher.onBackPressed() }
+ rule.waitForIdle()
+ assertThat(layoutState.transitionState).hasCurrentScene(SceneB)
+ }
+
+ @Test
+ fun testPredictiveBack() {
+ val layoutState = rule.runOnUiThread { MutableSceneTransitionLayoutState(SceneA) }
+ rule.setContent {
+ SceneTransitionLayout(layoutState) {
+ scene(SceneA, mapOf(Back to SceneB)) { Box(Modifier.fillMaxSize()) }
+ scene(SceneB) { Box(Modifier.fillMaxSize()) }
+ }
+ }
+
+ assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
+
+ // Start back.
+ val dispatcher = rule.activity.onBackPressedDispatcher
+ rule.runOnUiThread {
+ dispatcher.dispatchOnBackStarted(backEvent())
+ dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f))
+ }
+
+ val transition = assertThat(layoutState.transitionState).isTransition()
+ assertThat(transition).hasFromScene(SceneA)
+ assertThat(transition).hasToScene(SceneB)
+ assertThat(transition).hasProgress(0.4f)
+
+ // Cancel it.
+ rule.runOnUiThread { dispatcher.dispatchOnBackCancelled() }
+ rule.waitForIdle()
+ assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
+ assertThat(layoutState.transitionState).isIdle()
+
+ // Start again and commit it.
+ rule.runOnUiThread {
+ dispatcher.dispatchOnBackStarted(backEvent())
+ dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f))
+ dispatcher.onBackPressed()
+ }
+ rule.waitForIdle()
+ assertThat(layoutState.transitionState).hasCurrentScene(SceneB)
+ assertThat(layoutState.transitionState).isIdle()
+ }
+
+ @Test
+ fun interruptedPredictiveBackDoesNotCallCanChangeScene() {
+ var canChangeSceneCalled = false
+ val layoutState =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutState(
+ SceneA,
+ canChangeScene = {
+ canChangeSceneCalled = true
+ true
+ },
+ )
+ }
+
+ lateinit var coroutineScope: CoroutineScope
+ rule.setContent {
+ coroutineScope = rememberCoroutineScope()
+ SceneTransitionLayout(layoutState) {
+ scene(SceneA, mapOf(Back to SceneB)) { Box(Modifier.fillMaxSize()) }
+ scene(SceneB) { Box(Modifier.fillMaxSize()) }
+ scene(SceneC) { Box(Modifier.fillMaxSize()) }
+ }
+ }
+
+ assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
+
+ // Start back.
+ val dispatcher = rule.activity.onBackPressedDispatcher
+ rule.runOnUiThread { dispatcher.dispatchOnBackStarted(backEvent()) }
+
+ val predictiveTransition = assertThat(layoutState.transitionState).isTransition()
+ assertThat(predictiveTransition).hasFromScene(SceneA)
+ assertThat(predictiveTransition).hasToScene(SceneB)
+
+ // Start a new transition to C.
+ rule.runOnUiThread { layoutState.setTargetScene(SceneC, coroutineScope) }
+ val newTransition = assertThat(layoutState.transitionState).isTransition()
+ assertThat(newTransition).hasFromScene(SceneA)
+ assertThat(newTransition).hasToScene(SceneC)
+
+ // Commit the back gesture. It shouldn't call canChangeScene given that the back transition
+ // was interrupted.
+ rule.runOnUiThread { dispatcher.onBackPressed() }
+ rule.waitForIdle()
+ assertThat(layoutState.transitionState).hasCurrentScene(SceneC)
+ assertThat(layoutState.transitionState).isIdle()
+ assertThat(predictiveTransition).hasCurrentScene(SceneA)
+ assertThat(canChangeSceneCalled).isFalse()
+ }
+
+ private fun backEvent(progress: Float = 0f): BackEventCompat {
+ return BackEventCompat(
+ touchX = 0f,
+ touchY = 0f,
+ progress = progress,
+ swipeEdge = BackEventCompat.EDGE_LEFT,
+ )
+ }
+}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
index de6f1cc518f4..41bf630e9ae4 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
@@ -314,7 +314,6 @@ class SceneTransitionLayoutStateTest {
}
},
)
- as MutableSceneTransitionLayoutStateImpl
// Default transition from A to B.
assertThat(state.setTargetScene(SceneB, coroutineScope = this)).isNotNull()
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
index a8dd572c4d50..1ec10793363e 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
@@ -16,7 +16,6 @@
package com.android.compose.animation.scene
-import androidx.activity.ComponentActivity
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
@@ -30,6 +29,8 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -40,7 +41,7 @@ import androidx.compose.ui.test.assertHeightIsEqualTo
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertPositionInRootIsEqualTo
import androidx.compose.ui.test.assertWidthIsEqualTo
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onChild
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
@@ -57,6 +58,7 @@ import com.android.compose.test.assertSizeIsEqualTo
import com.android.compose.test.subjects.DpOffsetSubject
import com.android.compose.test.subjects.assertThat
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
import org.junit.Assert.assertThrows
import org.junit.Rule
import org.junit.Test
@@ -68,23 +70,27 @@ class SceneTransitionLayoutTest {
private val LayoutSize = 300.dp
}
- private var currentScene by mutableStateOf(SceneA)
- private lateinit var layoutState: SceneTransitionLayoutState
+ private lateinit var coroutineScope: CoroutineScope
+ private lateinit var layoutState: MutableSceneTransitionLayoutState
+ private var currentScene: SceneKey
+ get() = layoutState.transitionState.currentScene
+ set(value) {
+ rule.runOnUiThread { layoutState.setTargetScene(value, coroutineScope) }
+ }
- // We use createAndroidComposeRule() here and not createComposeRule() because we need an
- // activity for testBack().
- @get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
+ @get:Rule val rule = createComposeRule()
/** The content under test. */
@Composable
private fun TestContent(enableInterruptions: Boolean = true) {
- layoutState =
- updateSceneTransitionLayoutState(
- currentScene,
- { currentScene = it },
+ coroutineScope = rememberCoroutineScope()
+ layoutState = remember {
+ MutableSceneTransitionLayoutState(
+ SceneA,
EmptyTestTransitions,
enableInterruptions = enableInterruptions,
)
+ }
SceneTransitionLayout(
state = layoutState,
@@ -163,17 +169,6 @@ class SceneTransitionLayoutTest {
}
@Test
- fun testBack() {
- rule.setContent { TestContent() }
-
- assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
-
- rule.activity.onBackPressed()
- rule.waitForIdle()
- assertThat(layoutState.transitionState).hasCurrentScene(SceneB)
- }
-
- @Test
fun testTransitionState() {
rule.setContent { TestContent() }
assertThat(layoutState.transitionState).isIdle()
@@ -182,23 +177,15 @@ class SceneTransitionLayoutTest {
// We will advance the clock manually.
rule.mainClock.autoAdvance = false
- // Change the current scene. Until composition is triggered, this won't change the layout
- // state.
+ // Change the current scene.
currentScene = SceneB
- assertThat(layoutState.transitionState).isIdle()
- assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
-
- // On the next frame, we will recompose because currentScene changed, which will start the
- // transition (i.e. it will change the transitionState to be a Transition) in a
- // LaunchedEffect.
- rule.mainClock.advanceTimeByFrame()
val transition = assertThat(layoutState.transitionState).isTransition()
assertThat(transition).hasFromScene(SceneA)
assertThat(transition).hasToScene(SceneB)
assertThat(transition).hasProgress(0f)
// Then, on the next frame, the animator we started gets its initial value and clock
- // starting time. We are now at progress = 0f.
+ // starting time. We are still at progress = 0f.
rule.mainClock.advanceTimeByFrame()
assertThat(transition).hasProgress(0f)
@@ -239,12 +226,9 @@ class SceneTransitionLayoutTest {
// Pause animations to test the state mid-transition.
rule.mainClock.autoAdvance = false
- // Go to scene B and let the animation start. See [testLayoutState()] and
- // [androidx.compose.ui.test.MainTestClock] to understand why we need to advance the clock
- // by 2 frames to be at the start of the animation.
+ // Go to scene B and let the animation start.
currentScene = SceneB
rule.mainClock.advanceTimeByFrame()
- rule.mainClock.advanceTimeByFrame()
// Advance to the middle of the animation.
rule.mainClock.advanceTimeBy(TestTransitionDuration / 2)
@@ -275,7 +259,6 @@ class SceneTransitionLayoutTest {
// Animate to scene C, let the animation start then go to the middle of the transition.
currentScene = SceneC
rule.mainClock.advanceTimeByFrame()
- rule.mainClock.advanceTimeByFrame()
rule.mainClock.advanceTimeBy(TestTransitionDuration / 2)
// In Scene C, foo is at the bottom start of the layout and has a size of 150.dp. The
@@ -373,24 +356,24 @@ class SceneTransitionLayoutTest {
fun multipleTransitionsWillComposeMultipleScenes() {
val duration = 10 * 16L
- var currentScene: SceneKey by mutableStateOf(SceneA)
- lateinit var state: SceneTransitionLayoutState
- rule.setContent {
- state =
- updateSceneTransitionLayoutState(
- currentScene = currentScene,
- onChangeScene = { currentScene = it },
- transitions =
- transitions {
- from(SceneA, to = SceneB) {
- spec = tween(duration.toInt(), easing = LinearEasing)
- }
- from(SceneB, to = SceneC) {
- spec = tween(duration.toInt(), easing = LinearEasing)
- }
+ val state =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutState(
+ SceneA,
+ transitions {
+ from(SceneA, to = SceneB) {
+ spec = tween(duration.toInt(), easing = LinearEasing)
+ }
+ from(SceneB, to = SceneC) {
+ spec = tween(duration.toInt(), easing = LinearEasing)
}
+ }
)
+ }
+ lateinit var coroutineScope: CoroutineScope
+ rule.setContent {
+ coroutineScope = rememberCoroutineScope()
SceneTransitionLayout(state) {
scene(SceneA) { Box(Modifier.testTag("aRoot").fillMaxSize()) }
scene(SceneB) { Box(Modifier.testTag("bRoot").fillMaxSize()) }
@@ -408,12 +391,11 @@ class SceneTransitionLayoutTest {
rule.mainClock.autoAdvance = false
// Start A => B and go to the middle of the transition.
- currentScene = SceneB
+ rule.runOnUiThread { state.setTargetScene(SceneB, coroutineScope) }
- // We need to tick 2 frames after changing [currentScene] before the animation actually
+ // We need to tick 1 frames after changing [currentScene] before the animation actually
// starts.
rule.mainClock.advanceTimeByFrame()
- rule.mainClock.advanceTimeByFrame()
rule.mainClock.advanceTimeBy(duration / 2)
rule.waitForIdle()
@@ -426,8 +408,7 @@ class SceneTransitionLayoutTest {
rule.onNodeWithTag("cRoot").assertDoesNotExist()
// Start B => C.
- currentScene = SceneC
- rule.mainClock.advanceTimeByFrame()
+ rule.runOnUiThread { state.setTargetScene(SceneC, coroutineScope) }
rule.mainClock.advanceTimeByFrame()
rule.waitForIdle()
@@ -481,12 +462,7 @@ class SceneTransitionLayoutTest {
assertThrows(IllegalStateException::class.java) {
rule.setContent {
SceneTransitionLayout(
- state =
- updateSceneTransitionLayoutState(
- currentScene = currentScene,
- onChangeScene = { currentScene = it },
- transitions = EmptyTestTransitions
- ),
+ state = remember { MutableSceneTransitionLayoutState(SceneA) },
modifier = Modifier.size(LayoutSize),
) {
// from SceneA to SceneA
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
index 25ea2eef85e9..0766e00bfccc 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
@@ -23,11 +23,13 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.assertPositionInRootIsEqualTo
@@ -37,10 +39,12 @@ import androidx.compose.ui.test.performTouchInput
import androidx.compose.ui.test.swipeWithVelocity
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.compose.animation.scene.TestScenes.SceneA
import com.android.compose.animation.scene.TestScenes.SceneB
+import com.android.compose.animation.scene.TestScenes.SceneC
import com.android.compose.animation.scene.subjects.assertThat
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
@@ -634,4 +638,152 @@ class SwipeToSceneTest {
// Foo should be translated by (20dp, 30dp).
rule.onNode(isElement(TestElements.Foo)).assertPositionInRootIsEqualTo(20.dp, 30.dp)
}
+
+ @Test
+ fun startEnd_ltrLayout() {
+ val state =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutState(
+ initialScene = SceneA,
+ transitions =
+ transitions {
+ from(SceneA, to = SceneB) {
+ // We go to B by swiping to the start (left in LTR), so we make
+ // scene B appear from the end (right) edge.
+ translate(SceneB.rootElementKey, Edge.End)
+ }
+
+ from(SceneA, to = SceneC) {
+ // We go to C by swiping to the end (right in LTR), so we make
+ // scene C appear from the start (left) edge.
+ translate(SceneC.rootElementKey, Edge.Start)
+ }
+ },
+ )
+ }
+
+ val layoutSize = 200.dp
+ var touchSlop = 0f
+ rule.setContent {
+ touchSlop = LocalViewConfiguration.current.touchSlop
+ SceneTransitionLayout(state, Modifier.size(layoutSize)) {
+ scene(SceneA, userActions = mapOf(Swipe.Start to SceneB, Swipe.End to SceneC)) {
+ Box(Modifier.fillMaxSize())
+ }
+ scene(SceneB) { Box(Modifier.element(SceneB.rootElementKey).fillMaxSize()) }
+ scene(SceneC) { Box(Modifier.element(SceneC.rootElementKey).fillMaxSize()) }
+ }
+ }
+
+ // Swipe to the left (start).
+ rule.onRoot().performTouchInput {
+ val middle = (layoutSize / 2).toPx()
+ down(Offset(middle, middle))
+ moveBy(Offset(-touchSlop, 0f), delayMillis = 1_000)
+ }
+
+ // Scene B should come from the right (end) edge.
+ var transition = assertThat(state.transitionState).isTransition()
+ assertThat(transition).hasFromScene(SceneA)
+ assertThat(transition).hasToScene(SceneB)
+ rule
+ .onNode(isElement(SceneB.rootElementKey))
+ .assertPositionInRootIsEqualTo(layoutSize, 0.dp)
+
+ // Release to go back to A.
+ rule.onRoot().performTouchInput { up() }
+ rule.waitForIdle()
+ assertThat(state.transitionState).isIdle()
+ assertThat(state.transitionState).hasCurrentScene(SceneA)
+
+ // Swipe to the right (end).
+ rule.onRoot().performTouchInput {
+ val middle = (layoutSize / 2).toPx()
+ down(Offset(middle, middle))
+ moveBy(Offset(touchSlop, 0f), delayMillis = 1_000)
+ }
+
+ // Scene C should come from the left (start) edge.
+ transition = assertThat(state.transitionState).isTransition()
+ assertThat(transition).hasFromScene(SceneA)
+ assertThat(transition).hasToScene(SceneC)
+ rule
+ .onNode(isElement(SceneC.rootElementKey))
+ .assertPositionInRootIsEqualTo(-layoutSize, 0.dp)
+ }
+
+ @Test
+ fun startEnd_rtlLayout() {
+ val state =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutState(
+ initialScene = SceneA,
+ transitions =
+ transitions {
+ from(SceneA, to = SceneB) {
+ // We go to B by swiping to the start (right in RTL), so we make
+ // scene B appear from the end (left) edge.
+ translate(SceneB.rootElementKey, Edge.End)
+ }
+
+ from(SceneA, to = SceneC) {
+ // We go to C by swiping to the end (left in RTL), so we make
+ // scene C appear from the start (right) edge.
+ translate(SceneC.rootElementKey, Edge.Start)
+ }
+ },
+ )
+ }
+
+ val layoutSize = 200.dp
+ var touchSlop = 0f
+ rule.setContent {
+ touchSlop = LocalViewConfiguration.current.touchSlop
+ CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
+ SceneTransitionLayout(state, Modifier.size(layoutSize)) {
+ scene(SceneA, userActions = mapOf(Swipe.Start to SceneB, Swipe.End to SceneC)) {
+ Box(Modifier.fillMaxSize())
+ }
+ scene(SceneB) { Box(Modifier.element(SceneB.rootElementKey).fillMaxSize()) }
+ scene(SceneC) { Box(Modifier.element(SceneC.rootElementKey).fillMaxSize()) }
+ }
+ }
+ }
+
+ // Swipe to the left (end).
+ rule.onRoot().performTouchInput {
+ val middle = (layoutSize / 2).toPx()
+ down(Offset(middle, middle))
+ moveBy(Offset(-touchSlop, 0f), delayMillis = 1_000)
+ }
+
+ // Scene C should come from the right (start) edge.
+ var transition = assertThat(state.transitionState).isTransition()
+ assertThat(transition).hasFromScene(SceneA)
+ assertThat(transition).hasToScene(SceneC)
+ rule
+ .onNode(isElement(SceneC.rootElementKey))
+ .assertPositionInRootIsEqualTo(layoutSize, 0.dp)
+
+ // Release to go back to A.
+ rule.onRoot().performTouchInput { up() }
+ rule.waitForIdle()
+ assertThat(state.transitionState).isIdle()
+ assertThat(state.transitionState).hasCurrentScene(SceneA)
+
+ // Swipe to the right (start).
+ rule.onRoot().performTouchInput {
+ val middle = (layoutSize / 2).toPx()
+ down(Offset(middle, middle))
+ moveBy(Offset(touchSlop, 0f), delayMillis = 1_000)
+ }
+
+ // Scene C should come from the left (end) edge.
+ transition = assertThat(state.transitionState).isTransition()
+ assertThat(transition).hasFromScene(SceneA)
+ assertThat(transition).hasToScene(SceneB)
+ rule
+ .onNode(isElement(SceneB.rootElementKey))
+ .assertPositionInRootIsEqualTo(-layoutSize, 0.dp)
+ }
}
diff --git a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestSceneScope.kt b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestSceneScope.kt
index de46f7209c84..fbd557f3cbb3 100644
--- a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestSceneScope.kt
+++ b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestSceneScope.kt
@@ -27,12 +27,6 @@ fun TestSceneScope(
content: @Composable SceneScope.() -> Unit,
) {
val currentScene = remember { SceneKey("current") }
- SceneTransitionLayout(
- currentScene,
- onChangeScene = { /* do nothing */},
- transitions = remember { transitions {} },
- modifier,
- ) {
- scene(currentScene, content = content)
- }
+ val state = remember { MutableSceneTransitionLayoutState(currentScene) }
+ SceneTransitionLayout(state, modifier) { scene(currentScene, content = content) }
}
diff --git a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
index 6724851dbec5..a37d78ef8a71 100644
--- a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
+++ b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
@@ -19,13 +19,14 @@ package com.android.compose.animation.scene
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.SemanticsNode
import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import androidx.compose.ui.test.junit4.ComposeContentTestRule
+import kotlinx.coroutines.CoroutineScope
import platform.test.motion.MotionTestRule
import platform.test.motion.RecordedMotion
import platform.test.motion.compose.ComposeRecordingSpec
@@ -95,20 +96,24 @@ fun ComposeContentTestRule.testTransition(
builder: TransitionTestBuilder.() -> Unit,
) {
testTransition(
- from = fromScene,
+ state =
+ runOnUiThread {
+ MutableSceneTransitionLayoutState(
+ fromScene,
+ transitions { from(fromScene, to = toScene, builder = transition) }
+ )
+ },
to = toScene,
- transitionLayout = { currentScene, onChangeScene ->
+ transitionLayout = { state ->
SceneTransitionLayout(
- currentScene,
- onChangeScene,
- transitions { from(fromScene, to = toScene, builder = transition) },
+ state,
layoutModifier,
) {
scene(fromScene, content = fromSceneContent)
scene(toScene, content = toSceneContent)
}
},
- builder,
+ builder = builder,
)
}
@@ -172,21 +177,19 @@ fun MotionTestRule<ComposeToolkit>.recordTransition(
)
}
-/**
- * Test the transition between two scenes of [transitionLayout][SceneTransitionLayout] at different
- * points in time.
- */
+/** Test the transition from [state] to [to]. */
fun ComposeContentTestRule.testTransition(
- from: SceneKey,
+ state: MutableSceneTransitionLayoutState,
to: SceneKey,
- transitionLayout:
- @Composable
- (
- currentScene: SceneKey,
- onChangeScene: (SceneKey) -> Unit,
- ) -> Unit,
+ transitionLayout: @Composable (state: MutableSceneTransitionLayoutState) -> Unit,
builder: TransitionTestBuilder.() -> Unit,
) {
+ val currentScene = state.transitionState.currentScene
+ check(currentScene != to) {
+ "The 'to' scene (${to.debugName}) should be different from the state current scene " +
+ "(${currentScene.debugName})"
+ }
+
val test = transitionTest(builder)
val assertionScope =
object : TransitionTestAssertionScope {
@@ -198,8 +201,11 @@ fun ComposeContentTestRule.testTransition(
}
}
- var currentScene by mutableStateOf(from)
- setContent { transitionLayout(currentScene, { currentScene = it }) }
+ lateinit var coroutineScope: CoroutineScope
+ setContent {
+ coroutineScope = rememberCoroutineScope()
+ transitionLayout(state)
+ }
// Wait for the UI to be idle then test the before state.
waitForIdle()
@@ -209,14 +215,8 @@ fun ComposeContentTestRule.testTransition(
mainClock.autoAdvance = false
// Change the current scene.
- currentScene = to
-
- // Advance by a frame to trigger recomposition, which will start the transition (i.e. it will
- // change the transitionState to be a Transition) in a LaunchedEffect.
- mainClock.advanceTimeByFrame()
-
- // Advance by another frame so that the animator we started gets its initial value and clock
- // starting time. We are now at progress = 0f.
+ runOnUiThread { state.setTargetScene(to, coroutineScope) }
+ waitForIdle()
mainClock.advanceTimeByFrame()
waitForIdle()
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
index 51c008ab686a..9b725eb9eb5a 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
@@ -17,7 +17,6 @@ import android.app.ActivityManager
import android.app.UserSwitchObserver
import android.content.Context
import android.database.ContentObserver
-import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.UserHandle
import android.provider.Settings
@@ -33,6 +32,7 @@ import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.plugins.clocks.ClockId
import com.android.systemui.plugins.clocks.ClockMessageBuffers
import com.android.systemui.plugins.clocks.ClockMetadata
+import com.android.systemui.plugins.clocks.ClockPickerConfig
import com.android.systemui.plugins.clocks.ClockProvider
import com.android.systemui.plugins.clocks.ClockProviderPlugin
import com.android.systemui.plugins.clocks.ClockSettings
@@ -341,6 +341,7 @@ open class ClockRegistry(
}
private var isClockChanged = AtomicBoolean(false)
+
private fun triggerOnCurrentClockChanged() {
val shouldSchedule = isClockChanged.compareAndSet(false, true)
if (!shouldSchedule) {
@@ -355,6 +356,7 @@ open class ClockRegistry(
}
private var isClockListChanged = AtomicBoolean(false)
+
private fun triggerOnAvailableClocksChanged() {
val shouldSchedule = isClockListChanged.compareAndSet(false, true)
if (!shouldSchedule) {
@@ -458,6 +460,7 @@ open class ClockRegistry(
}
private var isQueued = AtomicBoolean(false)
+
fun verifyLoadedProviders() {
val shouldSchedule = isQueued.compareAndSet(false, true)
if (!shouldSchedule) {
@@ -565,8 +568,8 @@ open class ClockRegistry(
return availableClocks.map { (_, clock) -> clock.metadata }
}
- fun getClockThumbnail(clockId: ClockId): Drawable? =
- availableClocks[clockId]?.provider?.getClockThumbnail(clockId)
+ fun getClockPickerConfig(clockId: ClockId): ClockPickerConfig? =
+ availableClocks[clockId]?.provider?.getClockPickerConfig(clockId)
fun createExampleClock(clockId: ClockId): ClockController? = createClock(clockId)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
index 20f87a059656..4802e3447eb2 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
@@ -15,13 +15,13 @@ package com.android.systemui.shared.clocks
import android.content.Context
import android.content.res.Resources
-import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import com.android.systemui.customization.R
import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.plugins.clocks.ClockId
import com.android.systemui.plugins.clocks.ClockMessageBuffers
import com.android.systemui.plugins.clocks.ClockMetadata
+import com.android.systemui.plugins.clocks.ClockPickerConfig
import com.android.systemui.plugins.clocks.ClockProvider
import com.android.systemui.plugins.clocks.ClockSettings
@@ -60,12 +60,17 @@ class DefaultClockProvider(
)
}
- override fun getClockThumbnail(id: ClockId): Drawable? {
+ override fun getClockPickerConfig(id: ClockId): ClockPickerConfig {
if (id != DEFAULT_CLOCK_ID) {
throw IllegalArgumentException("$id is unsupported by $TAG")
}
- // TODO: Update placeholder to actual resource
- return resources.getDrawable(R.drawable.clock_default_thumbnail, null)
+ return ClockPickerConfig(
+ DEFAULT_CLOCK_ID,
+ resources.getString(R.string.clock_default_name),
+ resources.getString(R.string.clock_default_description),
+ // TODO(b/352049256): Update placeholder to actual resource
+ resources.getDrawable(R.drawable.clock_default_thumbnail, null),
+ )
}
}
diff --git a/packages/SystemUI/lint-baseline.xml b/packages/SystemUI/lint-baseline.xml
index 2fd7f1b53fba..b4c839f08607 100644
--- a/packages/SystemUI/lint-baseline.xml
+++ b/packages/SystemUI/lint-baseline.xml
@@ -128,7 +128,7 @@
errorLine1=" mUserTracker.addCallback(mUserChangedCallback, mContext.getMainExecutor());"
errorLine2=" ~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
line="807"
column="65"/>
</issue>
@@ -1646,7 +1646,7 @@
errorLine1=" mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);"
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
line="177"
column="48"/>
</issue>
@@ -2086,7 +2086,7 @@
errorLine1=" WindowManager wm = getContext().getSystemService(WindowManager.class);"
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="729"
column="45"/>
</issue>
@@ -2097,7 +2097,7 @@
errorLine1=" WindowManager wm = getContext().getSystemService(WindowManager.class);"
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="830"
column="41"/>
</issue>
@@ -4049,7 +4049,7 @@
errorLine1=" pw.println(String.format(&quot; mCurrentView: id=%s (%dx%d) %s %f&quot;,"
errorLine2=" ^">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="1128"
column="20"/>
</issue>
@@ -4060,7 +4060,7 @@
errorLine1=" pw.println(String.format(&quot; disabled=0x%08x vertical=%s darkIntensity=%.2f&quot;,"
errorLine2=" ^">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="1134"
column="20"/>
</issue>
@@ -4668,7 +4668,7 @@
errorLine1=" 500).show();"
errorLine2=" ~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
line="1894"
column="21"/>
</issue>
@@ -8386,7 +8386,7 @@
errorLine1=" mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP);"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
line="1500"
column="60"/>
</issue>
@@ -9168,39 +9168,6 @@
<issue
id="UnclosedTrace"
- message="The `beginSection()` call is not always closed with a matching `endSection()` because the code in between may return early"
- errorLine1=" Trace.beginSection(&quot;KeyguardViewMediator#handleKeyguardDone&quot;);"
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java"
- line="2654"
- column="15"/>
- </issue>
-
- <issue
- id="UnclosedTrace"
- message="The `beginSection()` call is not always closed with a matching `endSection()` because the code in between may return early"
- errorLine1=" Trace.beginSection(&quot;KeyguardViewMediator#handleShow&quot;);"
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java"
- line="2780"
- column="15"/>
- </issue>
-
- <issue
- id="UnclosedTrace"
- message="The `beginSection()` call is not always closed with a matching `endSection()` because the code in between may return early"
- errorLine1=" Trace.beginSection(&quot;KeyguardViewMediator#handleStartKeyguardExitAnimation&quot;);"
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java"
- line="3011"
- column="15"/>
- </issue>
-
- <issue
- id="UnclosedTrace"
message="The `traceBegin()` call is not always closed with a matching `traceEnd()` because the code in between may return early"
errorLine1=" Trace.traceBegin(Trace.TRACE_TAG_APP, &quot;MediaControlPanel#bindPlayer&lt;&quot; + key + &quot;>&quot;);"
errorLine2=" ~~~~~~~~~~">
@@ -23055,7 +23022,7 @@
errorLine1=" mBarTransitions.setBackgroundFrame(new Rect(0, frameHeight - height, w, h));"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="1001"
column="48"/>
</issue>
@@ -25002,7 +24969,7 @@
errorLine1=" mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());"
errorLine2=" ~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
line="373"
column="70"/>
</issue>
@@ -25222,7 +25189,7 @@
errorLine1=" Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);"
errorLine2=" ~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java"
line="329"
column="74"/>
</issue>
@@ -25233,7 +25200,7 @@
errorLine1=" Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);"
errorLine2=" ~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java"
line="357"
column="74"/>
</issue>
@@ -25827,7 +25794,7 @@
errorLine1=" new AsyncTask&lt;Icon, Void, Drawable>() {"
errorLine2=" ^">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
line="207"
column="9"/>
</issue>
@@ -29303,7 +29270,7 @@
errorLine1=" public boolean onTouchEvent(MotionEvent ev) {"
errorLine2=" ~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
line="267"
column="20"/>
</issue>
@@ -29578,7 +29545,7 @@
errorLine1=" mView.setOnTouchListener(this::onNavigationTouch);"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
line="782"
column="9"/>
</issue>
@@ -29589,7 +29556,7 @@
errorLine1=" public boolean onTouchEvent(MotionEvent event) {"
errorLine2=" ~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="383"
column="20"/>
</issue>
@@ -29600,7 +29567,7 @@
errorLine1=" public boolean onTouchEvent(MotionEvent event) {"
errorLine2=" ~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java"
line="207"
column="20"/>
</issue>
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.java
deleted file mode 100644
index 07d889066438..000000000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.java
+++ /dev/null
@@ -1,187 +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.ambient.touch;
-
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.DreamManager;
-import android.platform.test.annotations.DisableFlags;
-import android.platform.test.annotations.EnableFlags;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-
-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.shade.ShadeViewController;
-import com.android.systemui.shared.system.InputChannelCompat;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Optional;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ShadeTouchHandlerTest extends SysuiTestCase {
- @Mock
- CentralSurfaces mCentralSurfaces;
-
- @Mock
- ShadeViewController mShadeViewController;
-
- @Mock
- DreamManager mDreamManager;
-
- @Mock
- TouchHandler.TouchSession mTouchSession;
-
- ShadeTouchHandler mTouchHandler;
-
- @Captor
- ArgumentCaptor<GestureDetector.OnGestureListener> mGestureListenerCaptor;
- @Captor
- ArgumentCaptor<InputChannelCompat.InputEventListener> mInputListenerCaptor;
-
- private static final int TOUCH_HEIGHT = 20;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
-
- mTouchHandler = new ShadeTouchHandler(Optional.of(mCentralSurfaces), mShadeViewController,
- mDreamManager, TOUCH_HEIGHT);
- }
-
- // Verifies that a swipe down in the gesture region is captured by the shade touch handler.
- @Test
- public void testSwipeDown_captured() {
- final boolean captured = swipe(Direction.DOWN);
-
- assertThat(captured).isTrue();
- }
-
- // Verifies that a swipe in the upward direction is not captured.
- @Test
- public void testSwipeUp_notCaptured() {
- final boolean captured = swipe(Direction.UP);
-
- // Motion events not captured as the swipe is going in the wrong direction.
- assertThat(captured).isFalse();
- }
-
- // Verifies that a swipe down forwards captured touches to central surfaces for handling.
- @Test
- @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
- public void testSwipeDown_communalEnabled_sentToCentralSurfaces() {
- swipe(Direction.DOWN);
-
- // Both motion events are sent for central surfaces to process.
- verify(mCentralSurfaces, times(2)).handleExternalShadeWindowTouch(any());
- }
-
- // Verifies that a swipe down forwards captured touches to the shade view for handling.
- @Test
- @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
- public void testSwipeDown_communalDisabled_sentToShadeView() {
- swipe(Direction.DOWN);
-
- // Both motion events are sent for the shade view to process.
- verify(mShadeViewController, times(2)).handleExternalTouch(any());
- }
-
- // Verifies that a swipe down while dreaming forwards captured touches to the shade view for
- // handling.
- @Test
- public void testSwipeDown_dreaming_sentToShadeView() {
- when(mDreamManager.isDreaming()).thenReturn(true);
-
- swipe(Direction.DOWN);
-
- // Both motion events are sent for the shade view to process.
- verify(mShadeViewController, times(2)).handleExternalTouch(any());
- }
-
- // Verifies that a swipe up is not forwarded to central surfaces.
- @Test
- @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
- public void testSwipeUp_communalEnabled_touchesNotSent() {
- swipe(Direction.UP);
-
- // Motion events are not sent for central surfaces to process as the swipe is going in the
- // wrong direction.
- verify(mCentralSurfaces, never()).handleExternalShadeWindowTouch(any());
- }
-
- // Verifies that a swipe up is not forwarded to the shade view.
- @Test
- @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
- public void testSwipeUp_communalDisabled_touchesNotSent() {
- swipe(Direction.UP);
-
- // Motion events are not sent for the shade view to process as the swipe is going in the
- // wrong direction.
- verify(mShadeViewController, never()).handleExternalTouch(any());
- }
-
- /**
- * Simulates a swipe in the given direction and returns true if the touch was intercepted by the
- * touch handler's gesture listener.
- * <p>
- * Swipe down starts from a Y coordinate of 0 and goes downward. Swipe up starts from the edge
- * of the gesture region, {@link #TOUCH_HEIGHT}, and goes upward to 0.
- */
- private boolean swipe(Direction direction) {
- Mockito.clearInvocations(mTouchSession);
- mTouchHandler.onSessionStart(mTouchSession);
-
- verify(mTouchSession).registerGestureListener(mGestureListenerCaptor.capture());
- verify(mTouchSession).registerInputListener(mInputListenerCaptor.capture());
-
- final float startY = direction == Direction.UP ? TOUCH_HEIGHT : 0;
- final float endY = direction == Direction.UP ? 0 : TOUCH_HEIGHT;
-
- // Send touches to the input and gesture listener.
- final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, startY, 0);
- final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, endY, 0);
- mInputListenerCaptor.getValue().onInputEvent(event1);
- mInputListenerCaptor.getValue().onInputEvent(event2);
- final boolean captured = mGestureListenerCaptor.getValue().onScroll(event1, event2, 0,
- startY - endY);
-
- return captured;
- }
-
- private enum Direction {
- DOWN, UP,
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.kt
new file mode 100644
index 000000000000..5cf4f16aed62
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.kt
@@ -0,0 +1,180 @@
+/*
+ * 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.ambient.touch
+
+import android.app.DreamManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.view.GestureDetector
+import android.view.MotionEvent
+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.ambient.touch.TouchHandler.TouchSession
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
+import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.shade.ShadeViewController
+import com.android.systemui.shared.system.InputChannelCompat
+import com.android.systemui.statusbar.phone.CentralSurfaces
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth
+import java.util.Optional
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ShadeTouchHandlerTest : SysuiTestCase() {
+ private var kosmos = testKosmos()
+
+ private var mCentralSurfaces = mock<CentralSurfaces>()
+ private var mShadeViewController = mock<ShadeViewController>()
+ private var mDreamManager = mock<DreamManager>()
+ private var mTouchSession = mock<TouchSession>()
+
+ private lateinit var mTouchHandler: ShadeTouchHandler
+
+ private var mGestureListenerCaptor = argumentCaptor<GestureDetector.OnGestureListener>()
+ private var mInputListenerCaptor = argumentCaptor<InputChannelCompat.InputEventListener>()
+
+ @Before
+ fun setup() {
+ mTouchHandler =
+ ShadeTouchHandler(
+ Optional.of(mCentralSurfaces),
+ mShadeViewController,
+ mDreamManager,
+ kosmos.communalSettingsInteractor,
+ TOUCH_HEIGHT
+ )
+ }
+
+ // Verifies that a swipe down in the gesture region is captured by the shade touch handler.
+ @Test
+ fun testSwipeDown_captured() {
+ val captured = swipe(Direction.DOWN)
+ Truth.assertThat(captured).isTrue()
+ }
+
+ // Verifies that a swipe in the upward direction is not captured.
+ @Test
+ fun testSwipeUp_notCaptured() {
+ val captured = swipe(Direction.UP)
+
+ // Motion events not captured as the swipe is going in the wrong direction.
+ Truth.assertThat(captured).isFalse()
+ }
+
+ // Verifies that a swipe down forwards captured touches to central surfaces for handling.
+ @Test
+ @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
+ fun testSwipeDown_communalEnabled_sentToCentralSurfaces() {
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
+
+ swipe(Direction.DOWN)
+
+ // Both motion events are sent for central surfaces to process.
+ verify(mCentralSurfaces, times(2)).handleExternalShadeWindowTouch(any())
+ }
+
+ // Verifies that a swipe down forwards captured touches to the shade view for handling.
+ @Test
+ @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
+ fun testSwipeDown_communalDisabled_sentToShadeView() {
+ swipe(Direction.DOWN)
+
+ // Both motion events are sent for the shade view to process.
+ verify(mShadeViewController, times(2)).handleExternalTouch(any())
+ }
+
+ // Verifies that a swipe down while dreaming forwards captured touches to the shade view for
+ // handling.
+ @Test
+ fun testSwipeDown_dreaming_sentToShadeView() {
+ whenever(mDreamManager.isDreaming).thenReturn(true)
+ swipe(Direction.DOWN)
+
+ // Both motion events are sent for the shade view to process.
+ verify(mShadeViewController, times(2)).handleExternalTouch(any())
+ }
+
+ // Verifies that a swipe up is not forwarded to central surfaces.
+ @Test
+ @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
+ fun testSwipeUp_communalEnabled_touchesNotSent() {
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
+
+ swipe(Direction.UP)
+
+ // Motion events are not sent for central surfaces to process as the swipe is going in the
+ // wrong direction.
+ verify(mCentralSurfaces, never()).handleExternalShadeWindowTouch(any())
+ }
+
+ // Verifies that a swipe up is not forwarded to the shade view.
+ @Test
+ @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
+ fun testSwipeUp_communalDisabled_touchesNotSent() {
+ swipe(Direction.UP)
+
+ // Motion events are not sent for the shade view to process as the swipe is going in the
+ // wrong direction.
+ verify(mShadeViewController, never()).handleExternalTouch(any())
+ }
+
+ /**
+ * Simulates a swipe in the given direction and returns true if the touch was intercepted by the
+ * touch handler's gesture listener.
+ *
+ * Swipe down starts from a Y coordinate of 0 and goes downward. Swipe up starts from the edge
+ * of the gesture region, [.TOUCH_HEIGHT], and goes upward to 0.
+ */
+ private fun swipe(direction: Direction): Boolean {
+ clearInvocations(mTouchSession)
+ mTouchHandler.onSessionStart(mTouchSession)
+ verify(mTouchSession).registerGestureListener(mGestureListenerCaptor.capture())
+ verify(mTouchSession).registerInputListener(mInputListenerCaptor.capture())
+ val startY = (if (direction == Direction.UP) TOUCH_HEIGHT else 0).toFloat()
+ val endY = (if (direction == Direction.UP) 0 else TOUCH_HEIGHT).toFloat()
+
+ // Send touches to the input and gesture listener.
+ val event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0f, startY, 0)
+ val event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0f, endY, 0)
+ mInputListenerCaptor.lastValue.onInputEvent(event1)
+ mInputListenerCaptor.lastValue.onInputEvent(event2)
+ return mGestureListenerCaptor.lastValue.onScroll(event1, event2, 0f, startY - endY)
+ }
+
+ private enum class Direction {
+ DOWN,
+ UP
+ }
+
+ companion object {
+ private const val TOUCH_HEIGHT = 20
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
index f9f7df820217..4f5d0e58ce01 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
@@ -29,6 +29,7 @@ import com.android.systemui.authentication.domain.interactor.authenticationInter
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel.Pattern
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel.Pin
+import com.android.systemui.biometrics.FaceHelpMessageDebouncer
import com.android.systemui.biometrics.data.repository.FaceSensorInfo
import com.android.systemui.biometrics.data.repository.fakeFacePropertyRepository
import com.android.systemui.biometrics.data.repository.fakeFingerprintPropertyRepository
@@ -36,7 +37,7 @@ import com.android.systemui.biometrics.shared.model.SensorStrength
import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
import com.android.systemui.bouncer.shared.flag.fakeComposeBouncerFlags
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
import com.android.systemui.deviceentry.shared.model.ErrorFaceAuthenticationStatus
import com.android.systemui.deviceentry.shared.model.FailedFaceAuthenticationStatus
import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus
@@ -75,15 +76,20 @@ class BouncerMessageViewModelTest : SysuiTestCase() {
private val authenticationInteractor by lazy { kosmos.authenticationInteractor }
private val bouncerInteractor by lazy { kosmos.bouncerInteractor }
private lateinit var underTest: BouncerMessageViewModel
+ private val ignoreHelpMessageId = 1
@Before
fun setUp() {
kosmos.fakeUserRepository.setUserInfos(listOf(PRIMARY_USER))
kosmos.fakeComposeBouncerFlags.composeBouncerEnabled = true
+ overrideResource(
+ R.array.config_face_acquire_device_entry_ignorelist,
+ intArrayOf(ignoreHelpMessageId)
+ )
underTest = kosmos.bouncerMessageViewModel
overrideResource(R.string.kg_trust_agent_disabled, "Trust agent is unavailable")
kosmos.fakeSystemPropertiesHelper.set(
- DeviceEntryInteractor.SYS_BOOT_REASON_PROP,
+ DeviceUnlockedInteractor.SYS_BOOT_REASON_PROP,
"not mainline reboot"
)
}
@@ -379,7 +385,15 @@ class BouncerMessageViewModelTest : SysuiTestCase() {
runCurrent()
kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(
- HelpFaceAuthenticationStatus(1, "some helpful message")
+ HelpFaceAuthenticationStatus(0, "some helpful message", 0)
+ )
+ runCurrent()
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(
+ HelpFaceAuthenticationStatus(
+ 0,
+ "some helpful message",
+ FaceHelpMessageDebouncer.DEFAULT_WINDOW_MS
+ )
)
runCurrent()
assertThat(bouncerMessage?.text).isEqualTo("Enter PIN")
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalBackupRestoreStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalBackupRestoreStartableTest.kt
index 722eb2b9b622..60aea92ab3bd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalBackupRestoreStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalBackupRestoreStartableTest.kt
@@ -20,6 +20,9 @@ import android.appwidget.AppWidgetManager
import android.content.Context
import android.content.Intent
import android.content.mockedContext
+import android.os.Handler
+import android.os.fakeExecutorHandler
+import android.provider.Settings.Secure.USER_SETUP_COMPLETE
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -27,11 +30,13 @@ import com.android.systemui.broadcast.FakeBroadcastDispatcher
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.widgets.CommunalWidgetModule
+import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.kotlinArgumentCaptor
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.settings.SecureSettings
+import com.android.systemui.util.settings.fakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -41,6 +46,8 @@ import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -50,10 +57,13 @@ class CommunalBackupRestoreStartableTest : SysuiTestCase() {
@Mock private lateinit var communalInteractor: CommunalInteractor
- private val mapCaptor = kotlinArgumentCaptor<Map<Int, Int>>()
+ private val mapCaptor = argumentCaptor<Map<Int, Int>>()
private lateinit var context: Context
private lateinit var broadcastDispatcher: FakeBroadcastDispatcher
+ private lateinit var secureSettings: SecureSettings
+ private lateinit var handler: Handler
+ private lateinit var fakeExecutor: FakeExecutor
private lateinit var underTest: CommunalBackupRestoreStartable
@Before
@@ -62,18 +72,28 @@ class CommunalBackupRestoreStartableTest : SysuiTestCase() {
context = kosmos.mockedContext
broadcastDispatcher = kosmos.broadcastDispatcher
+ secureSettings = kosmos.fakeSettings
+ handler = kosmos.fakeExecutorHandler
+ fakeExecutor = kosmos.fakeExecutor
+
+ secureSettings.putInt(USER_SETUP_COMPLETE, 0)
underTest =
CommunalBackupRestoreStartable(
broadcastDispatcher,
communalInteractor,
logcatLogBuffer("CommunalBackupRestoreStartable"),
+ secureSettings,
+ handler,
)
}
@Test
- fun testRestoreWidgetsUponHostRestored() =
+ fun restoreWidgets_userSetUpComplete_performRestore() =
testScope.runTest {
+ // User set up complete
+ secureSettings.putInt(USER_SETUP_COMPLETE, 1)
+
underTest.start()
// Verify restore widgets not called
@@ -94,7 +114,7 @@ class CommunalBackupRestoreStartableTest : SysuiTestCase() {
// Verify restore widgets called
verify(communalInteractor).restoreWidgets(mapCaptor.capture())
- val oldToNewWidgetIdMap = mapCaptor.value
+ val oldToNewWidgetIdMap = mapCaptor.firstValue
assertThat(oldToNewWidgetIdMap)
.containsExactlyEntriesIn(
mapOf(
@@ -106,10 +126,54 @@ class CommunalBackupRestoreStartableTest : SysuiTestCase() {
}
@Test
- fun testDoNotRestoreWidgetsIfNotForCommunalWidgetHost() =
+ fun restoreWidgets_userSetUpNotComplete_restoreWhenUserSetupComplete() =
testScope.runTest {
underTest.start()
+ // Verify restore widgets not called
+ verify(communalInteractor, never()).restoreWidgets(any())
+
+ // Trigger app widget host restored
+ val intent =
+ Intent().apply {
+ action = AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED
+ putExtra(
+ AppWidgetManager.EXTRA_HOST_ID,
+ CommunalWidgetModule.APP_WIDGET_HOST_ID
+ )
+ putExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS, intArrayOf(1, 2, 3))
+ putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(7, 8, 9))
+ }
+ broadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent)
+
+ // Verify restore widgets not called because user setup not complete
+ verify(communalInteractor, never()).restoreWidgets(any())
+
+ // User setup complete
+ secureSettings.putInt(USER_SETUP_COMPLETE, 1)
+ fakeExecutor.runAllReady()
+
+ // Verify restore widgets called
+ verify(communalInteractor).restoreWidgets(mapCaptor.capture())
+ val oldToNewWidgetIdMap = mapCaptor.firstValue
+ assertThat(oldToNewWidgetIdMap)
+ .containsExactlyEntriesIn(
+ mapOf(
+ Pair(1, 7),
+ Pair(2, 8),
+ Pair(3, 9),
+ )
+ )
+ }
+
+ @Test
+ fun restoreWidgets_broadcastNotForCommunalWidgetHost_doNotPerformRestore() =
+ testScope.runTest {
+ // User set up complete
+ secureSettings.putInt(USER_SETUP_COMPLETE, 1)
+
+ underTest.start()
+
// Trigger app widget host restored, but for another host
val hostId = CommunalWidgetModule.APP_WIDGET_HOST_ID + 1
val intent =
@@ -126,8 +190,11 @@ class CommunalBackupRestoreStartableTest : SysuiTestCase() {
}
@Test
- fun testAbortRestoreWidgetsIfOldToNewIdsMappingInvalid() =
+ fun restoreWidgets_oldToNewIdsMappingInvalid_abortRestore() =
testScope.runTest {
+ // User set up complete
+ secureSettings.putInt(USER_SETUP_COMPLETE, 1)
+
underTest.start()
// Trigger app widget host restored, but new ids list is one too many for old ids
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
index dcc9c7aacdf0..76920e406bff 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
@@ -22,6 +22,9 @@ 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.communal.domain.interactor.communalSettingsInteractor
+import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
+import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.keyguardRepository
@@ -61,9 +64,12 @@ class CommunalDreamStartableTest : SysuiTestCase() {
@Before
fun setUp() {
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
+
underTest =
CommunalDreamStartable(
powerInteractor = kosmos.powerInteractor,
+ communalSettingsInteractor = kosmos.communalSettingsInteractor,
keyguardInteractor = kosmos.keyguardInteractor,
keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
dreamManager = dreamManager,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalOngoingContentStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalOngoingContentStartableTest.kt
new file mode 100644
index 000000000000..9113617095e2
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalOngoingContentStartableTest.kt
@@ -0,0 +1,89 @@
+/*
+ * 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.communal
+
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.data.repository.fakeCommunalMediaRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSmartspaceRepository
+import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
+import com.android.systemui.communal.domain.interactor.setCommunalEnabled
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@EnableFlags(FLAG_COMMUNAL_HUB)
+@RunWith(AndroidJUnit4::class)
+class CommunalOngoingContentStartableTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
+ private val mediaRepository = kosmos.fakeCommunalMediaRepository
+ private val smartspaceRepository = kosmos.fakeCommunalSmartspaceRepository
+
+ private lateinit var underTest: CommunalOngoingContentStartable
+
+ @Before
+ fun setUp() {
+ kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true)
+ underTest =
+ CommunalOngoingContentStartable(
+ bgScope = kosmos.applicationCoroutineScope,
+ communalInteractor = kosmos.communalInteractor,
+ communalMediaRepository = mediaRepository,
+ communalSettingsInteractor = kosmos.communalSettingsInteractor,
+ communalSmartspaceRepository = smartspaceRepository,
+ )
+ }
+
+ @Test
+ fun testListenForOngoingContentWhenCommunalIsEnabled() =
+ testScope.runTest {
+ underTest.start()
+ runCurrent()
+
+ assertThat(mediaRepository.isListening()).isFalse()
+ assertThat(smartspaceRepository.isListening()).isFalse()
+
+ kosmos.setCommunalEnabled(true)
+ runCurrent()
+
+ assertThat(mediaRepository.isListening()).isTrue()
+ assertThat(smartspaceRepository.isListening()).isTrue()
+
+ kosmos.setCommunalEnabled(false)
+ runCurrent()
+
+ assertThat(mediaRepository.isListening()).isFalse()
+ assertThat(smartspaceRepository.isListening()).isFalse()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
index cf145471e55f..4ad020f94c89 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
@@ -16,17 +16,23 @@
package com.android.systemui.communal
+import android.platform.test.annotations.EnableFlags
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
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.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.dock.dockManager
import com.android.systemui.dock.fakeDockManager
+import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.flags.featureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
@@ -57,6 +63,7 @@ import org.mockito.kotlin.whenever
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableFlags(FLAG_COMMUNAL_HUB)
class CommunalSceneStartableTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -66,16 +73,19 @@ class CommunalSceneStartableTest : SysuiTestCase() {
fun setUp() {
with(kosmos) {
fakeSettings.putInt(Settings.System.SCREEN_OFF_TIMEOUT, SCREEN_TIMEOUT)
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
underTest =
CommunalSceneStartable(
dockManager = dockManager,
communalInteractor = communalInteractor,
+ communalSettingsInteractor = communalSettingsInteractor,
communalSceneInteractor = communalSceneInteractor,
keyguardTransitionInteractor = keyguardTransitionInteractor,
keyguardInteractor = keyguardInteractor,
systemSettings = fakeSettings,
notificationShadeWindowController = notificationShadeWindowController,
+ featureFlagsClassic = kosmos.fakeFeatureFlagsClassic,
applicationScope = applicationCoroutineScope,
bgScope = applicationCoroutineScope,
mainDispatcher = testDispatcher,
@@ -93,7 +103,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- fun keyguardGoesAway_forceBlankScene() =
+ fun keyguardGoesAway_whenLaunchingWidget_doNotForceBlankScene() =
with(kosmos) {
testScope.runTest {
val scene by collectLastValue(communalSceneInteractor.currentScene)
@@ -101,6 +111,27 @@ class CommunalSceneStartableTest : SysuiTestCase() {
communalSceneInteractor.changeScene(CommunalScenes.Communal)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
+ communalSceneInteractor.setIsLaunchingWidget(true)
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.PRIMARY_BOUNCER,
+ to = KeyguardState.GONE,
+ testScope = this
+ )
+
+ assertThat(scene).isEqualTo(CommunalScenes.Communal)
+ }
+ }
+
+ @Test
+ fun keyguardGoesAway_whenNotLaunchingWidget_forceBlankScene() =
+ with(kosmos) {
+ testScope.runTest {
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
+
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
+ assertThat(scene).isEqualTo(CommunalScenes.Communal)
+
+ communalSceneInteractor.setIsLaunchingWidget(false)
fakeKeyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.PRIMARY_BOUNCER,
to = KeyguardState.GONE,
@@ -451,6 +482,24 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
}
+ @Test
+ fun transitionFromDozingToGlanceableHub_forcesCommunal() =
+ with(kosmos) {
+ testScope.runTest {
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
+ communalSceneInteractor.changeScene(CommunalScenes.Blank)
+ assertThat(scene).isEqualTo(CommunalScenes.Blank)
+
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.DOZING,
+ to = KeyguardState.GLANCEABLE_HUB,
+ testScope = this
+ )
+
+ assertThat(scene).isEqualTo(CommunalScenes.Communal)
+ }
+ }
+
private fun TestScope.updateDocked(docked: Boolean) =
with(kosmos) {
runCurrent()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationTest.kt
new file mode 100644
index 000000000000..ad2c42fd1f09
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationTest.kt
@@ -0,0 +1,157 @@
+/*
+ * 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.communal.data.db
+
+import android.content.ComponentName
+import android.os.UserHandle
+import android.os.UserManager
+import androidx.sqlite.db.SupportSQLiteDatabase
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.data.db.DefaultWidgetPopulation.SkipReason.RESTORED_FROM_BACKUP
+import com.android.systemui.communal.widgets.CommunalWidgetHost
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.log.logcatLogBuffer
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+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.verify
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
+class DefaultWidgetPopulationTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
+ private val communalWidgetHost =
+ mock<CommunalWidgetHost> {
+ var nextId = 0
+ on { allocateIdAndBindWidget(any(), anyOrNull()) }.thenAnswer { nextId++ }
+ }
+ private val communalWidgetDao = mock<CommunalWidgetDao>()
+ private val database = mock<SupportSQLiteDatabase>()
+ private val mainUser = UserHandle(0)
+ private val userManager =
+ mock<UserManager> {
+ on { mainUser }.thenReturn(mainUser)
+ on { getUserSerialNumber(0) }.thenReturn(0)
+ }
+
+ private val defaultWidgets =
+ arrayOf(
+ "com.android.test_package_1/fake_widget_1",
+ "com.android.test_package_2/fake_widget_2",
+ "com.android.test_package_3/fake_widget_3",
+ )
+
+ private lateinit var underTest: DefaultWidgetPopulation
+
+ @Before
+ fun setUp() {
+ underTest =
+ DefaultWidgetPopulation(
+ bgScope = kosmos.applicationCoroutineScope,
+ communalWidgetHost = communalWidgetHost,
+ communalWidgetDaoProvider = { communalWidgetDao },
+ defaultWidgets = defaultWidgets,
+ logBuffer = logcatLogBuffer("DefaultWidgetPopulationTest"),
+ userManager = userManager,
+ )
+ }
+
+ @Test
+ fun testPopulateDefaultWidgetsWhenDatabaseCreated() =
+ testScope.runTest {
+ // Database created
+ underTest.onCreate(database)
+ runCurrent()
+
+ // Verify default widgets bound
+ verify(communalWidgetHost)
+ .allocateIdAndBindWidget(
+ provider = eq(ComponentName.unflattenFromString(defaultWidgets[0])!!),
+ user = eq(mainUser),
+ )
+ verify(communalWidgetHost)
+ .allocateIdAndBindWidget(
+ provider = eq(ComponentName.unflattenFromString(defaultWidgets[1])!!),
+ user = eq(mainUser),
+ )
+ verify(communalWidgetHost)
+ .allocateIdAndBindWidget(
+ provider = eq(ComponentName.unflattenFromString(defaultWidgets[2])!!),
+ user = eq(mainUser),
+ )
+
+ // Verify default widgets added in database
+ verify(communalWidgetDao)
+ .addWidget(
+ widgetId = 0,
+ componentName = defaultWidgets[0],
+ priority = 3,
+ userSerialNumber = 0,
+ )
+ verify(communalWidgetDao)
+ .addWidget(
+ widgetId = 1,
+ componentName = defaultWidgets[1],
+ priority = 2,
+ userSerialNumber = 0,
+ )
+ verify(communalWidgetDao)
+ .addWidget(
+ widgetId = 2,
+ componentName = defaultWidgets[2],
+ priority = 1,
+ userSerialNumber = 0,
+ )
+ }
+
+ @Test
+ fun testSkipDefaultWidgetsPopulation() =
+ testScope.runTest {
+ // Skip default widgets population
+ underTest.skipDefaultWidgetsPopulation(RESTORED_FROM_BACKUP)
+
+ // Database created
+ underTest.onCreate(database)
+ runCurrent()
+
+ // Verify no widget bounded or added to the database
+ verify(communalWidgetHost, never()).allocateIdAndBindWidget(any(), any())
+ verify(communalWidgetDao, never())
+ .addWidget(
+ widgetId = anyInt(),
+ componentName = any(),
+ priority = anyInt(),
+ userSerialNumber = anyInt(),
+ )
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalMediaRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalMediaRepositoryImplTest.kt
index 407bf4cac633..dd280223f203 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalMediaRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalMediaRepositoryImplTest.kt
@@ -20,46 +20,41 @@ 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.log.table.TableLogBuffer
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.shared.model.MediaData
-import com.android.systemui.util.mockito.KotlinArgumentCaptor
+import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.mock
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
@android.platform.test.annotations.EnabledOnRavenwood
class CommunalMediaRepositoryImplTest : SysuiTestCase() {
- @Mock private lateinit var mediaDataManager: MediaDataManager
- @Mock private lateinit var mediaData: MediaData
- @Mock private lateinit var tableLogBuffer: TableLogBuffer
+ private val mediaDataManager = mock<MediaDataManager>()
+ private val mediaData = mock<MediaData>()
+ private val tableLogBuffer = mock<TableLogBuffer>()
private lateinit var underTest: CommunalMediaRepositoryImpl
- private val mediaDataListenerCaptor: KotlinArgumentCaptor<MediaDataManager.Listener> by lazy {
- KotlinArgumentCaptor(MediaDataManager.Listener::class.java)
- }
+ private val mediaDataListenerCaptor = argumentCaptor<MediaDataManager.Listener>()
- private val testDispatcher = StandardTestDispatcher()
- private val testScope = TestScope(testDispatcher)
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
@Before
fun setUp() {
- MockitoAnnotations.initMocks(this)
-
underTest =
CommunalMediaRepositoryImpl(
mediaDataManager,
@@ -78,6 +73,8 @@ class CommunalMediaRepositoryImplTest : SysuiTestCase() {
@Test
fun mediaModel_updatesWhenMediaDataLoaded() =
testScope.runTest {
+ underTest.startListening()
+
// Listener is added
verify(mediaDataManager).addListener(mediaDataListenerCaptor.capture())
@@ -89,7 +86,7 @@ class CommunalMediaRepositoryImplTest : SysuiTestCase() {
// Change to media available and notify the listener.
whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true)
whenever(mediaData.createdTimestampMillis).thenReturn(1234L)
- mediaDataListenerCaptor.value.onMediaDataLoaded("key", null, mediaData)
+ mediaDataListenerCaptor.firstValue.onMediaDataLoaded("key", null, mediaData)
runCurrent()
// Media active now returns true.
@@ -100,12 +97,14 @@ class CommunalMediaRepositoryImplTest : SysuiTestCase() {
@Test
fun mediaModel_updatesWhenMediaDataRemoved() =
testScope.runTest {
+ underTest.startListening()
+
// Listener is added
verify(mediaDataManager).addListener(mediaDataListenerCaptor.capture())
// Change to media available and notify the listener.
whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true)
- mediaDataListenerCaptor.value.onMediaDataLoaded("key", null, mediaData)
+ mediaDataListenerCaptor.firstValue.onMediaDataLoaded("key", null, mediaData)
runCurrent()
// Media active now returns true.
@@ -114,7 +113,7 @@ class CommunalMediaRepositoryImplTest : SysuiTestCase() {
// Change to media unavailable and notify the listener.
whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(false)
- mediaDataListenerCaptor.value.onMediaDataRemoved("key", false)
+ mediaDataListenerCaptor.firstValue.onMediaDataRemoved("key", false)
runCurrent()
// Media active now returns false.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
index da40f640d5fa..06b710eb86eb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
@@ -68,6 +68,38 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
@EnableFlags(FLAG_COMMUNAL_HUB)
@Test
+ fun getFlagEnabled_bothEnabled() {
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
+
+ assertThat(underTest.getFlagEnabled()).isTrue()
+ }
+
+ @DisableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun getFlagEnabled_bothDisabled() {
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, false)
+
+ assertThat(underTest.getFlagEnabled()).isFalse()
+ }
+
+ @DisableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun getFlagEnabled_onlyClassicFlagEnabled() {
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
+
+ assertThat(underTest.getFlagEnabled()).isFalse()
+ }
+
+ @EnableFlags(FLAG_COMMUNAL_HUB)
+ @Test
+ fun getFlagEnabled_onlyTrunkFlagEnabled() {
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, false)
+
+ assertThat(underTest.getFlagEnabled()).isFalse()
+ }
+
+ @EnableFlags(FLAG_COMMUNAL_HUB)
+ @Test
fun secondaryUserIsInvalid() =
testScope.runTest {
val enabledState by collectLastValue(underTest.getEnabledState(SECONDARY_USER))
@@ -185,7 +217,7 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() {
fun backgroundType_defaultValue() =
testScope.runTest {
val backgroundType by collectLastValue(underTest.getBackground(PRIMARY_USER))
- assertThat(backgroundType).isEqualTo(CommunalBackgroundType.DEFAULT)
+ assertThat(backgroundType).isEqualTo(CommunalBackgroundType.ANIMATED)
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryImplTest.kt
new file mode 100644
index 000000000000..c1816ed3e5bf
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryImplTest.kt
@@ -0,0 +1,319 @@
+/*
+ * 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.communal.data.repository
+
+import android.app.smartspace.SmartspaceTarget
+import android.app.smartspace.flags.Flags.FLAG_REMOTE_VIEWS
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.smartspace.CommunalSmartspaceController
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
+import com.android.systemui.testKosmos
+import com.android.systemui.util.time.fakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
+class CommunalSmartspaceRepositoryImplTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
+ private val listenerCaptor = argumentCaptor<SmartspaceTargetListener>()
+
+ private val smartspaceController = mock<CommunalSmartspaceController>()
+ private val fakeExecutor = kosmos.fakeExecutor
+ private val systemClock = kosmos.fakeSystemClock
+
+ private lateinit var underTest: CommunalSmartspaceRepositoryImpl
+
+ @Before
+ fun setUp() {
+ underTest =
+ CommunalSmartspaceRepositoryImpl(
+ smartspaceController,
+ fakeExecutor,
+ systemClock,
+ )
+ }
+
+ @DisableFlags(FLAG_REMOTE_VIEWS)
+ @Test
+ fun startListening_remoteViewsFlagDisabled_doNotListenForSmartspaceUpdates() =
+ testScope.runTest {
+ underTest.startListening()
+ fakeExecutor.runAllReady()
+
+ verify(smartspaceController, never()).addListener(any())
+ }
+
+ @EnableFlags(FLAG_REMOTE_VIEWS)
+ @Test
+ fun startListening_remoteViewsFlagEnabled_listenForSmartspaceUpdates() =
+ testScope.runTest {
+ underTest.startListening()
+ fakeExecutor.runAllReady()
+
+ // Verify listener added
+ val listener = captureSmartspaceTargetListener()
+
+ underTest.stopListening()
+ fakeExecutor.runAllReady()
+
+ // Verify listener removed
+ verify(smartspaceController).removeListener(listener)
+ }
+
+ @EnableFlags(FLAG_REMOTE_VIEWS)
+ @Test
+ fun communalTimers_onlyShowTimersWithRemoteViews() =
+ testScope.runTest {
+ underTest.startListening()
+
+ val communalTimers by collectLastValue(underTest.timers)
+ runCurrent()
+ fakeExecutor.runAllReady()
+
+ with(captureSmartspaceTargetListener()) {
+ onSmartspaceTargetsUpdated(
+ listOf(
+ // Invalid. Not a timer
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("weather")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_WEATHER)
+ },
+ // Invalid. RemoteViews absent
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("timer-0-started")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_TIMER)
+ on { remoteViews }.doReturn(null)
+ on { creationTimeMillis }.doReturn(1000)
+ },
+ // Valid
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("timer-1-started")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_TIMER)
+ on { remoteViews }.doReturn(mock())
+ on { creationTimeMillis }.doReturn(2000)
+ },
+ )
+ )
+ }
+ runCurrent()
+
+ // Verify that only the valid target is listed
+ assertThat(communalTimers).hasSize(1)
+ assertThat(communalTimers?.first()?.smartspaceTargetId).isEqualTo("timer-1-started")
+ }
+
+ @EnableFlags(FLAG_REMOTE_VIEWS)
+ @Test
+ fun communalTimers_cacheCreationTime() =
+ testScope.runTest {
+ underTest.startListening()
+
+ val communalTimers by collectLastValue(underTest.timers)
+ runCurrent()
+ fakeExecutor.runAllReady()
+
+ val listener = captureSmartspaceTargetListener()
+ listener.onSmartspaceTargetsUpdated(
+ listOf(
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("timer-0-started")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_TIMER)
+ on { remoteViews }.doReturn(mock())
+ on { creationTimeMillis }.doReturn(1000)
+ },
+ )
+ )
+ runCurrent()
+
+ // Verify that the creation time is the current time, not the creation time passed in
+ // the target, because this value can be inaccurate (due to b/318535930).
+ val currentTime = systemClock.currentTimeMillis()
+ assertThat(communalTimers?.get(0)?.createdTimestampMillis).isEqualTo(currentTime)
+ assertThat(communalTimers?.get(0)?.createdTimestampMillis).isNotEqualTo(1000)
+
+ // A second timer is added.
+ listener.onSmartspaceTargetsUpdated(
+ listOf(
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("timer-0-started")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_TIMER)
+ on { remoteViews }.doReturn(mock())
+ on { creationTimeMillis }.doReturn(2000)
+ },
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("timer-1-started")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_TIMER)
+ on { remoteViews }.doReturn(mock())
+ on { creationTimeMillis }.doReturn(3000)
+ },
+ )
+ )
+ runCurrent()
+
+ // Verify that the created timestamp for the first time is consistent
+ assertThat(communalTimers?.get(0)?.createdTimestampMillis).isEqualTo(currentTime)
+
+ // Verify that the second timer has a new creation time
+ assertThat(communalTimers?.get(1)?.createdTimestampMillis)
+ .isEqualTo(systemClock.currentTimeMillis())
+ }
+
+ @EnableFlags(FLAG_REMOTE_VIEWS)
+ @Test
+ fun communalTimers_creationTimeRemovedFromCacheWhenTimerRemoved() =
+ testScope.runTest {
+ underTest.startListening()
+
+ val communalTimers by collectLastValue(underTest.timers)
+ runCurrent()
+ fakeExecutor.runAllReady()
+
+ // Start timer 0
+ val listener = captureSmartspaceTargetListener()
+ listener.onSmartspaceTargetsUpdated(
+ listOf(
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("timer-0-started")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_TIMER)
+ on { remoteViews }.doReturn(mock())
+ on { creationTimeMillis }.doReturn(1000)
+ },
+ )
+ )
+ runCurrent()
+
+ // Verify timer 0 creation time
+ val expectedCreationTimeForTimer0 = systemClock.currentTimeMillis()
+ assertThat(communalTimers?.first()?.createdTimestampMillis)
+ .isEqualTo(expectedCreationTimeForTimer0)
+
+ // Advance some time
+ systemClock.advanceTime(1000)
+
+ // Start timer 1
+ listener.onSmartspaceTargetsUpdated(
+ listOf(
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("timer-0-started")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_TIMER)
+ on { remoteViews }.doReturn(mock())
+ on { creationTimeMillis }.doReturn(1000)
+ },
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("timer-1-started")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_TIMER)
+ on { remoteViews }.doReturn(mock())
+ on { creationTimeMillis }.doReturn(2000)
+ },
+ )
+ )
+ runCurrent()
+
+ // Verify timer 1 creation time is new
+ val expectedCreationTimeForTimer1 = expectedCreationTimeForTimer0 + 1000
+ assertThat(communalTimers?.get(1)?.createdTimestampMillis)
+ .isEqualTo(expectedCreationTimeForTimer1)
+
+ // Removed timer 0
+ listener.onSmartspaceTargetsUpdated(
+ listOf(
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("timer-1-started")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_TIMER)
+ on { remoteViews }.doReturn(mock())
+ on { creationTimeMillis }.doReturn(2000)
+ },
+ )
+ )
+ runCurrent()
+
+ // Verify timer 0 removed, and timer 1 creation time is correct
+ assertThat(communalTimers).hasSize(1)
+ assertThat(communalTimers?.first()?.createdTimestampMillis)
+ .isEqualTo(expectedCreationTimeForTimer1)
+
+ // Advance some time
+ systemClock.advanceTime(1000)
+
+ // Start timer 0 again. Technically this is a new timer, but timers can reused stable
+ // ids.
+ listener.onSmartspaceTargetsUpdated(
+ listOf(
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("timer-1-started")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_TIMER)
+ on { remoteViews }.doReturn(mock())
+ on { creationTimeMillis }.doReturn(2000)
+ },
+ mock<SmartspaceTarget> {
+ on { smartspaceTargetId }.doReturn("timer-0-started")
+ on { featureType }.doReturn(SmartspaceTarget.FEATURE_TIMER)
+ on { remoteViews }.doReturn(mock())
+ on { creationTimeMillis }.doReturn(3000)
+ },
+ )
+ )
+ runCurrent()
+
+ // Verify new timer added, and timer 1 creation time is still correct
+ assertThat(communalTimers).hasSize(2)
+ assertThat(communalTimers?.get(0)?.createdTimestampMillis)
+ .isEqualTo(expectedCreationTimeForTimer1)
+
+ // Verify creation time for the new timer is new, meaning that cache for timer 0 was
+ // removed when it was removed
+ assertThat(communalTimers?.get(1)?.createdTimestampMillis)
+ .isEqualTo(expectedCreationTimeForTimer1 + 1000)
+ }
+
+ @Test
+ fun stableId() {
+ assertThat(CommunalSmartspaceRepositoryImpl.stableId("timer-0-12345-started"))
+ .isEqualTo("timer-0")
+ assertThat(CommunalSmartspaceRepositoryImpl.stableId("timer-1-67890-paused"))
+ .isEqualTo("timer-1")
+ assertThat(CommunalSmartspaceRepositoryImpl.stableId("i_am_an_unexpected_id"))
+ .isEqualTo("i_am_an_unexpected_id")
+ }
+
+ private fun captureSmartspaceTargetListener(): SmartspaceTargetListener {
+ verify(smartspaceController).addListener(listenerCaptor.capture())
+ return listenerCaptor.firstValue
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
index 6ce6cdb32a12..c707ebf0a2c4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
@@ -24,6 +24,7 @@ import android.content.ComponentName
import android.content.applicationContext
import android.graphics.Bitmap
import android.os.UserHandle
+import android.os.userManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -33,6 +34,7 @@ import com.android.systemui.communal.data.backup.CommunalBackupUtils
import com.android.systemui.communal.data.db.CommunalItemRank
import com.android.systemui.communal.data.db.CommunalWidgetDao
import com.android.systemui.communal.data.db.CommunalWidgetItem
+import com.android.systemui.communal.data.db.defaultWidgetPopulation
import com.android.systemui.communal.nano.CommunalHubState
import com.android.systemui.communal.proto.toByteArray
import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
@@ -47,10 +49,6 @@ import com.android.systemui.log.LogBuffer
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.res.R
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.android.systemui.util.mockito.withArgCaptor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
@@ -59,11 +57,16 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.eq
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -77,6 +80,9 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
@Mock private lateinit var communalWidgetDao: CommunalWidgetDao
@Mock private lateinit var backupManager: BackupManager
+ private val communalHubStateCaptor = argumentCaptor<CommunalHubState>()
+ private val componentNameCaptor = argumentCaptor<ComponentName>()
+
private lateinit var backupUtils: CommunalBackupUtils
private lateinit var logBuffer: LogBuffer
private lateinit var fakeWidgets: MutableStateFlow<Map<CommunalItemRank, CommunalWidgetItem>>
@@ -85,6 +91,10 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val packageChangeRepository = kosmos.fakePackageChangeRepository
+ private val userManager = kosmos.userManager
+
+ private val mainUser = UserHandle(0)
+ private val workProfile = UserHandle(10)
private val fakeAllowlist =
listOf(
@@ -109,6 +119,9 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
whenever(communalWidgetDao.getWidgets()).thenReturn(fakeWidgets)
whenever(communalWidgetHost.appWidgetProviders).thenReturn(fakeProviders)
+ whenever(userManager.mainUser).thenReturn(mainUser)
+
+ restoreUser(mainUser)
underTest =
CommunalWidgetRepositoryImpl(
@@ -121,6 +134,8 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
backupManager,
backupUtils,
packageChangeRepository,
+ userManager,
+ kosmos.defaultWidgetPopulation,
)
}
@@ -128,7 +143,7 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
fun communalWidgets_queryWidgetsFromDb() =
testScope.runTest {
val communalItemRankEntry = CommunalItemRank(uid = 1L, rank = 1)
- val communalWidgetItemEntry = CommunalWidgetItem(uid = 1L, 1, "pk_name/cls_name", 1L)
+ val communalWidgetItemEntry = CommunalWidgetItem(uid = 1L, 1, "pk_name/cls_name", 1L, 0)
fakeWidgets.value = mapOf(communalItemRankEntry to communalWidgetItemEntry)
fakeProviders.value = mapOf(1 to providerInfoA)
@@ -154,13 +169,13 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
fakeWidgets.value =
mapOf(
CommunalItemRank(uid = 1L, rank = 1) to
- CommunalWidgetItem(uid = 1L, 1, "pk_1/cls_1", 1L),
+ CommunalWidgetItem(uid = 1L, 1, "pk_1/cls_1", 1L, 0),
CommunalItemRank(uid = 2L, rank = 2) to
- CommunalWidgetItem(uid = 2L, 2, "pk_2/cls_2", 2L),
+ CommunalWidgetItem(uid = 2L, 2, "pk_2/cls_2", 2L, 0),
CommunalItemRank(uid = 3L, rank = 3) to
- CommunalWidgetItem(uid = 3L, 3, "pk_3/cls_3", 3L),
+ CommunalWidgetItem(uid = 3L, 3, "pk_3/cls_3", 3L, 0),
CommunalItemRank(uid = 4L, rank = 4) to
- CommunalWidgetItem(uid = 4L, 4, "pk_4/cls_4", 4L),
+ CommunalWidgetItem(uid = 4L, 4, "pk_4/cls_4", 4L, 0),
)
fakeProviders.value =
mapOf(
@@ -192,9 +207,9 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
fakeWidgets.value =
mapOf(
CommunalItemRank(uid = 1L, rank = 1) to
- CommunalWidgetItem(uid = 1L, 1, "pk_1/cls_1", 1L),
+ CommunalWidgetItem(uid = 1L, 1, "pk_1/cls_1", 1L, 0),
CommunalItemRank(uid = 2L, rank = 2) to
- CommunalWidgetItem(uid = 2L, 2, "pk_2/cls_2", 2L),
+ CommunalWidgetItem(uid = 2L, 2, "pk_2/cls_2", 2L, 0),
)
fakeProviders.value =
mapOf(
@@ -249,7 +264,6 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
val provider = ComponentName("pkg_name", "cls_name")
val id = 1
val priority = 1
- val user = UserHandle(0)
whenever(communalWidgetHost.getAppWidgetInfo(id))
.thenReturn(PROVIDER_INFO_REQUIRES_CONFIGURATION)
whenever(
@@ -259,11 +273,12 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
)
)
.thenReturn(id)
- underTest.addWidget(provider, user, priority, kosmos.widgetConfiguratorSuccess)
+ underTest.addWidget(provider, mainUser, priority, kosmos.widgetConfiguratorSuccess)
runCurrent()
- verify(communalWidgetHost).allocateIdAndBindWidget(provider, user)
- verify(communalWidgetDao).addWidget(id, provider, priority)
+ verify(communalWidgetHost).allocateIdAndBindWidget(provider, mainUser)
+ verify(communalWidgetDao)
+ .addWidget(id, provider, priority, testUserSerialNumber(mainUser))
// Verify backup requested
verify(backupManager).dataChanged()
@@ -275,7 +290,6 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
val provider = ComponentName("pkg_name", "cls_name")
val id = 1
val priority = 1
- val user = UserHandle(0)
whenever(communalWidgetHost.getAppWidgetInfo(id))
.thenReturn(PROVIDER_INFO_REQUIRES_CONFIGURATION)
whenever(
@@ -285,11 +299,12 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
)
)
.thenReturn(id)
- underTest.addWidget(provider, user, priority, kosmos.widgetConfiguratorFail)
+ underTest.addWidget(provider, mainUser, priority, kosmos.widgetConfiguratorFail)
runCurrent()
- verify(communalWidgetHost).allocateIdAndBindWidget(provider, user)
- verify(communalWidgetDao, never()).addWidget(id, provider, priority)
+ verify(communalWidgetHost).allocateIdAndBindWidget(provider, mainUser)
+ verify(communalWidgetDao, never())
+ .addWidget(anyInt(), any<ComponentName>(), anyInt(), anyInt())
verify(appWidgetHost).deleteAppWidgetId(id)
// Verify backup not requested
@@ -302,7 +317,6 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
val provider = ComponentName("pkg_name", "cls_name")
val id = 1
val priority = 1
- val user = UserHandle(0)
whenever(communalWidgetHost.getAppWidgetInfo(id))
.thenReturn(PROVIDER_INFO_REQUIRES_CONFIGURATION)
whenever(
@@ -312,13 +326,14 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
)
)
.thenReturn(id)
- underTest.addWidget(provider, user, priority) {
+ underTest.addWidget(provider, mainUser, priority) {
throw IllegalStateException("some error")
}
runCurrent()
- verify(communalWidgetHost).allocateIdAndBindWidget(provider, user)
- verify(communalWidgetDao, never()).addWidget(id, provider, priority)
+ verify(communalWidgetHost).allocateIdAndBindWidget(provider, mainUser)
+ verify(communalWidgetDao, never())
+ .addWidget(anyInt(), any<ComponentName>(), anyInt(), anyInt())
verify(appWidgetHost).deleteAppWidgetId(id)
// Verify backup not requested
@@ -331,7 +346,6 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
val provider = ComponentName("pkg_name", "cls_name")
val id = 1
val priority = 1
- val user = UserHandle(0)
whenever(communalWidgetHost.getAppWidgetInfo(id))
.thenReturn(PROVIDER_INFO_CONFIGURATION_OPTIONAL)
whenever(
@@ -341,11 +355,12 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
)
)
.thenReturn(id)
- underTest.addWidget(provider, user, priority, kosmos.widgetConfiguratorFail)
+ underTest.addWidget(provider, mainUser, priority, kosmos.widgetConfiguratorFail)
runCurrent()
- verify(communalWidgetHost).allocateIdAndBindWidget(provider, user)
- verify(communalWidgetDao).addWidget(id, provider, priority)
+ verify(communalWidgetHost).allocateIdAndBindWidget(provider, mainUser)
+ verify(communalWidgetDao)
+ .addWidget(id, provider, priority, testUserSerialNumber(mainUser))
// Verify backup requested
verify(backupManager).dataChanged()
@@ -444,11 +459,8 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
runCurrent()
// Verify state restored, and widget 2 skipped
- val restoredState =
- withArgCaptor<CommunalHubState> {
- verify(communalWidgetDao).restoreCommunalHubState(capture())
- }
- val restoredWidgets = restoredState.widgets.toList()
+ verify(communalWidgetDao).restoreCommunalHubState(communalHubStateCaptor.capture())
+ val restoredWidgets = communalHubStateCaptor.firstValue.widgets.toList()
assertThat(restoredWidgets).hasSize(1)
val restoredWidget = restoredWidgets.first()
@@ -474,11 +486,8 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
runCurrent()
// Verify widget 1 and 2 are restored, and are now 11 and 12.
- val restoredState =
- withArgCaptor<CommunalHubState> {
- verify(communalWidgetDao).restoreCommunalHubState(capture())
- }
- val restoredWidgets = restoredState.widgets.toList()
+ verify(communalWidgetDao).restoreCommunalHubState(communalHubStateCaptor.capture())
+ val restoredWidgets = communalHubStateCaptor.firstValue.widgets.toList()
assertThat(restoredWidgets).hasSize(2)
val restoredWidget1 = restoredWidgets[0]
@@ -512,11 +521,8 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
runCurrent()
// Verify widget 1 and 2 are restored, and are now 1 and 12.
- val restoredState =
- withArgCaptor<CommunalHubState> {
- verify(communalWidgetDao).restoreCommunalHubState(capture())
- }
- val restoredWidgets = restoredState.widgets.toList()
+ verify(communalWidgetDao).restoreCommunalHubState(communalHubStateCaptor.capture())
+ val restoredWidgets = communalHubStateCaptor.firstValue.widgets.toList()
assertThat(restoredWidgets).hasSize(2)
val restoredWidget1 = restoredWidgets[0]
@@ -533,14 +539,134 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
}
@Test
+ fun restoreWidgets_undefinedUser_restoredAsMain() =
+ testScope.runTest {
+ // Write two widgets to file, both of which have user serial number undefined.
+ val fakeState =
+ CommunalHubState().apply {
+ widgets =
+ listOf(
+ CommunalHubState.CommunalWidgetItem().apply {
+ widgetId = 1
+ componentName = "pk_name/fake_widget_1"
+ rank = 1
+ userSerialNumber =
+ CommunalWidgetItem.USER_SERIAL_NUMBER_UNDEFINED
+ },
+ CommunalHubState.CommunalWidgetItem().apply {
+ widgetId = 2
+ componentName = "pk_name/fake_widget_2"
+ rank = 2
+ userSerialNumber =
+ CommunalWidgetItem.USER_SERIAL_NUMBER_UNDEFINED
+ },
+ )
+ .toTypedArray()
+ }
+ backupUtils.writeBytesToDisk(fakeState.toByteArray())
+
+ // Set up app widget host with widget ids.
+ setAppWidgetIds(listOf(11, 12))
+
+ // Restore widgets.
+ underTest.restoreWidgets(mapOf(Pair(1, 11), Pair(2, 12)))
+ runCurrent()
+
+ // Verify widget 1 and 2 are restored with the main user.
+ verify(communalWidgetDao).restoreCommunalHubState(communalHubStateCaptor.capture())
+ val restoredWidgets = communalHubStateCaptor.firstValue.widgets.toList()
+ assertThat(restoredWidgets).hasSize(2)
+
+ val restoredWidget1 = restoredWidgets[0]
+ assertThat(restoredWidget1.widgetId).isEqualTo(11)
+ assertThat(restoredWidget1.userSerialNumber).isEqualTo(testUserSerialNumber(mainUser))
+
+ val restoredWidget2 = restoredWidgets[1]
+ assertThat(restoredWidget2.widgetId).isEqualTo(12)
+ assertThat(restoredWidget2.userSerialNumber).isEqualTo(testUserSerialNumber(mainUser))
+ }
+
+ @Test
+ fun restoreWidgets_workProfileNotRestored_widgetSkipped() =
+ testScope.runTest {
+ // Write fake state to file
+ backupUtils.writeBytesToDisk(fakeStateWithWorkProfile.toByteArray())
+
+ // Set up app widget host with widget ids.
+ // (b/349852237) It's possible that the platform restores widgets even though their user
+ // is not restored.
+ setAppWidgetIds(listOf(11, 12))
+
+ // Restore widgets.
+ underTest.restoreWidgets(mapOf(Pair(1, 11), Pair(2, 12)))
+ runCurrent()
+
+ // Verify only widget 1 is restored. Widget 2 is skipped because it belongs to a work
+ // profile, which is not restored.
+ verify(communalWidgetDao).restoreCommunalHubState(communalHubStateCaptor.capture())
+ val restoredWidgets = communalHubStateCaptor.firstValue.widgets.toList()
+ assertThat(restoredWidgets).hasSize(1)
+
+ val restoredWidget = restoredWidgets[0]
+ assertThat(restoredWidget.widgetId).isEqualTo(11)
+ assertThat(restoredWidget.userSerialNumber).isEqualTo(testUserSerialNumber(mainUser))
+ }
+
+ @Test
+ fun restoreWidgets_workProfileRestored_manuallyBindWidget() =
+ testScope.runTest {
+ // Write fake state to file
+ backupUtils.writeBytesToDisk(fakeStateWithWorkProfile.toByteArray())
+
+ // Set up app widget host with widget ids.
+ // (b/349852237) It's possible that the platform restores widgets even though their user
+ // is not restored.
+ setAppWidgetIds(listOf(11, 12))
+
+ // Restore work profile.
+ restoreUser(workProfile)
+
+ val newWidgetId = 13
+ whenever(communalWidgetHost.allocateIdAndBindWidget(any(), any()))
+ .thenReturn(newWidgetId)
+
+ // Restore widgets.
+ underTest.restoreWidgets(mapOf(Pair(1, 11), Pair(2, 12)))
+ runCurrent()
+
+ // Verify widget 1 is restored.
+ verify(communalWidgetDao).restoreCommunalHubState(communalHubStateCaptor.capture())
+ val restoredWidgets = communalHubStateCaptor.firstValue.widgets.toList()
+ assertThat(restoredWidgets).hasSize(1)
+
+ val restoredWidget = restoredWidgets[0]
+ assertThat(restoredWidget.widgetId).isEqualTo(11)
+ assertThat(restoredWidget.userSerialNumber).isEqualTo(testUserSerialNumber(mainUser))
+
+ // Verify widget 2 (now 12) is removed from platform
+ verify(appWidgetHost).deleteAppWidgetId(12)
+
+ // Verify work profile widget is manually bound
+ verify(communalWidgetDao)
+ .addWidget(
+ eq(newWidgetId),
+ componentNameCaptor.capture(),
+ eq(2),
+ eq(testUserSerialNumber(workProfile))
+ )
+ assertThat(componentNameCaptor.firstValue)
+ .isEqualTo(ComponentName("pk_name", "fake_widget_2"))
+ }
+
+ @Test
fun pendingWidgets() =
testScope.runTest {
fakeWidgets.value =
mapOf(
CommunalItemRank(uid = 1L, rank = 1) to
- CommunalWidgetItem(uid = 1L, 1, "pk_1/cls_1", 1L),
+ CommunalWidgetItem(uid = 1L, 1, "pk_1/cls_1", 1L, 0),
CommunalItemRank(uid = 2L, rank = 2) to
- CommunalWidgetItem(uid = 2L, 2, "pk_2/cls_2", 2L),
+ CommunalWidgetItem(uid = 2L, 2, "pk_2/cls_2", 2L, 0),
)
// Widget 1 is installed
@@ -554,7 +680,7 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
sessionId = 1,
packageName = "pk_2",
icon = fakeIcon,
- user = UserHandle.CURRENT,
+ user = mainUser,
)
)
)
@@ -572,7 +698,7 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
priority = 2,
packageName = "pk_2",
icon = fakeIcon,
- user = UserHandle.CURRENT,
+ user = mainUser,
),
)
}
@@ -583,7 +709,7 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
fakeWidgets.value =
mapOf(
CommunalItemRank(uid = 1L, rank = 1) to
- CommunalWidgetItem(uid = 1L, 1, "pk_1/cls_1", 1L),
+ CommunalWidgetItem(uid = 1L, 1, "pk_1/cls_1", 1L, 0),
)
// Widget 1 is pending install
@@ -594,7 +720,7 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
sessionId = 1,
packageName = "pk_1",
icon = fakeIcon,
- user = UserHandle.CURRENT,
+ user = mainUser,
)
)
)
@@ -607,7 +733,7 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
priority = 1,
packageName = "pk_1",
icon = fakeIcon,
- user = UserHandle.CURRENT,
+ user = mainUser,
),
)
@@ -633,6 +759,20 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
whenever(appWidgetHost.appWidgetIds).thenReturn(ids.toIntArray())
}
+ // Commonly the user id and user serial number are the same, but for testing purposes use a
+ // simple algorithm to map a user id to a different user serial number to make sure the correct
+ // value is used.
+ private fun testUserSerialNumber(user: UserHandle): Int {
+ return user.identifier + 100
+ }
+
+ private fun restoreUser(user: UserHandle) {
+ whenever(backupManager.getUserForAncestralSerialNumber(user.identifier.toLong()))
+ .thenReturn(user)
+ whenever(userManager.getUserSerialNumber(user.identifier))
+ .thenReturn(testUserSerialNumber(user))
+ }
+
private companion object {
val PROVIDER_INFO_REQUIRES_CONFIGURATION =
AppWidgetProviderInfo().apply { configure = ComponentName("test.pkg", "test.cmp") }
@@ -650,11 +790,32 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
widgetId = 1
componentName = "pk_name/fake_widget_1"
rank = 1
+ userSerialNumber = 0
+ },
+ CommunalHubState.CommunalWidgetItem().apply {
+ widgetId = 2
+ componentName = "pk_name/fake_widget_2"
+ rank = 2
+ userSerialNumber = 0
+ },
+ )
+ .toTypedArray()
+ }
+ val fakeStateWithWorkProfile =
+ CommunalHubState().apply {
+ widgets =
+ listOf(
+ CommunalHubState.CommunalWidgetItem().apply {
+ widgetId = 1
+ componentName = "pk_name/fake_widget_1"
+ rank = 1
+ userSerialNumber = 0
},
CommunalHubState.CommunalWidgetItem().apply {
widgetId = 2
componentName = "pk_name/fake_widget_2"
rank = 2
+ userSerialNumber = 10
},
)
.toTypedArray()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index 7b26db50814e..5cdbe9ce5856 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
@@ -19,7 +19,6 @@ package com.android.systemui.communal.domain.interactor
import android.app.admin.DevicePolicyManager
import android.app.admin.devicePolicyManager
-import android.app.smartspace.SmartspaceTarget
import android.appwidget.AppWidgetProviderInfo
import android.content.Intent
import android.content.pm.UserInfo
@@ -36,14 +35,17 @@ import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.broadcastDispatcher
+import com.android.systemui.communal.data.model.CommunalSmartspaceTimer
import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
import com.android.systemui.communal.data.repository.FakeCommunalPrefsRepository
import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
+import com.android.systemui.communal.data.repository.FakeCommunalSmartspaceRepository
import com.android.systemui.communal.data.repository.FakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository
import com.android.systemui.communal.data.repository.fakeCommunalMediaRepository
import com.android.systemui.communal.data.repository.fakeCommunalPrefsRepository
import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSmartspaceRepository
import com.android.systemui.communal.data.repository.fakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
import com.android.systemui.communal.domain.model.CommunalContentModel
@@ -69,8 +71,6 @@ import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.fakeUserTracker
-import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
-import com.android.systemui.smartspace.data.repository.fakeSmartspaceRepository
import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.user.data.repository.fakeUserRepository
@@ -114,7 +114,7 @@ class CommunalInteractorTest : SysuiTestCase() {
private lateinit var communalRepository: FakeCommunalSceneRepository
private lateinit var mediaRepository: FakeCommunalMediaRepository
private lateinit var widgetRepository: FakeCommunalWidgetRepository
- private lateinit var smartspaceRepository: FakeSmartspaceRepository
+ private lateinit var smartspaceRepository: FakeCommunalSmartspaceRepository
private lateinit var userRepository: FakeUserRepository
private lateinit var keyguardRepository: FakeKeyguardRepository
private lateinit var communalPrefsRepository: FakeCommunalPrefsRepository
@@ -135,7 +135,7 @@ class CommunalInteractorTest : SysuiTestCase() {
communalRepository = kosmos.fakeCommunalSceneRepository
mediaRepository = kosmos.fakeCommunalMediaRepository
widgetRepository = kosmos.fakeCommunalWidgetRepository
- smartspaceRepository = kosmos.fakeSmartspaceRepository
+ smartspaceRepository = kosmos.fakeCommunalSmartspaceRepository
userRepository = kosmos.fakeUserRepository
keyguardRepository = kosmos.fakeKeyguardRepository
editWidgetsActivityStarter = kosmos.editWidgetsActivityStarter
@@ -265,44 +265,6 @@ class CommunalInteractorTest : SysuiTestCase() {
}
@Test
- fun smartspace_onlyShowTimersWithRemoteViews() =
- testScope.runTest {
- // Keyguard showing, and tutorial completed.
- keyguardRepository.setKeyguardShowing(true)
- keyguardRepository.setKeyguardOccluded(false)
- tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
-
- // Not a timer
- val target1 = mock(SmartspaceTarget::class.java)
- whenever(target1.smartspaceTargetId).thenReturn("target1")
- whenever(target1.featureType).thenReturn(SmartspaceTarget.FEATURE_WEATHER)
- whenever(target1.remoteViews).thenReturn(mock(RemoteViews::class.java))
- whenever(target1.creationTimeMillis).thenReturn(0L)
-
- // Does not have RemoteViews
- val target2 = mock(SmartspaceTarget::class.java)
- whenever(target2.smartspaceTargetId).thenReturn("target2")
- whenever(target2.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER)
- whenever(target2.remoteViews).thenReturn(null)
- whenever(target2.creationTimeMillis).thenReturn(0L)
-
- // Timer and has RemoteViews
- val target3 = mock(SmartspaceTarget::class.java)
- whenever(target3.smartspaceTargetId).thenReturn("target3")
- whenever(target3.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER)
- whenever(target3.remoteViews).thenReturn(mock(RemoteViews::class.java))
- whenever(target3.creationTimeMillis).thenReturn(0L)
-
- val targets = listOf(target1, target2, target3)
- smartspaceRepository.setCommunalSmartspaceTargets(targets)
-
- val smartspaceContent by collectLastValue(underTest.getOngoingContent(true))
- assertThat(smartspaceContent?.size).isEqualTo(1)
- assertThat(smartspaceContent?.get(0)?.key)
- .isEqualTo(CommunalContentModel.KEY.smartspace("target3"))
- }
-
- @Test
fun smartspaceDynamicSizing_oneCard_fullSize() =
testSmartspaceDynamicSizing(
totalTargets = 1,
@@ -387,12 +349,12 @@ class CommunalInteractorTest : SysuiTestCase() {
keyguardRepository.setKeyguardOccluded(false)
tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
- val targets = mutableListOf<SmartspaceTarget>()
+ val targets = mutableListOf<CommunalSmartspaceTimer>()
for (index in 0 until totalTargets) {
targets.add(smartspaceTimer(index.toString()))
}
- smartspaceRepository.setCommunalSmartspaceTargets(targets)
+ smartspaceRepository.setTimers(targets)
val smartspaceContent by collectLastValue(underTest.getOngoingContent(true))
assertThat(smartspaceContent?.size).isEqualTo(totalTargets)
@@ -441,18 +403,18 @@ class CommunalInteractorTest : SysuiTestCase() {
// Timer1 started
val timer1 = smartspaceTimer("timer1", timestamp = 1L)
- smartspaceRepository.setCommunalSmartspaceTargets(listOf(timer1))
+ smartspaceRepository.setTimers(listOf(timer1))
// Umo started
mediaRepository.mediaActive(timestamp = 2L)
// Timer2 started
val timer2 = smartspaceTimer("timer2", timestamp = 3L)
- smartspaceRepository.setCommunalSmartspaceTargets(listOf(timer1, timer2))
+ smartspaceRepository.setTimers(listOf(timer1, timer2))
// Timer3 started
val timer3 = smartspaceTimer("timer3", timestamp = 4L)
- smartspaceRepository.setCommunalSmartspaceTargets(listOf(timer1, timer2, timer3))
+ smartspaceRepository.setTimers(listOf(timer1, timer2, timer3))
val ongoingContent by collectLastValue(underTest.getOngoingContent(true))
assertThat(ongoingContent?.size).isEqualTo(4)
@@ -1089,13 +1051,12 @@ class CommunalInteractorTest : SysuiTestCase() {
assertThat(showCommunalFromOccluded).isTrue()
}
- private fun smartspaceTimer(id: String, timestamp: Long = 0L): SmartspaceTarget {
- val timer = mock(SmartspaceTarget::class.java)
- whenever(timer.smartspaceTargetId).thenReturn(id)
- whenever(timer.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER)
- whenever(timer.remoteViews).thenReturn(mock(RemoteViews::class.java))
- whenever(timer.creationTimeMillis).thenReturn(timestamp)
- return timer
+ private fun smartspaceTimer(id: String, timestamp: Long = 0L): CommunalSmartspaceTimer {
+ return CommunalSmartspaceTimer(
+ smartspaceTargetId = id,
+ createdTimestampMillis = timestamp,
+ remoteViews = mock(RemoteViews::class.java)
+ )
}
private fun setKeyguardFeaturesDisabled(user: UserInfo, disabledFlags: Int) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt
new file mode 100644
index 000000000000..e4916b1a7e46
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt
@@ -0,0 +1,126 @@
+/*
+ * 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.communal.domain.interactor
+
+import android.app.admin.DevicePolicyManager
+import android.app.admin.devicePolicyManager
+import android.content.Intent
+import android.content.pm.UserInfo
+import android.os.UserManager
+import android.os.userManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.broadcastDispatcher
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.settings.fakeUserTracker
+import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.FakeUserRepository
+import com.android.systemui.user.data.repository.fakeUserRepository
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.kotlin.anyOrNull
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CommunalSettingsInteractorTest : SysuiTestCase() {
+
+ private lateinit var userManager: UserManager
+ private lateinit var userRepository: FakeUserRepository
+ private lateinit var userTracker: FakeUserTracker
+
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
+ private lateinit var underTest: CommunalSettingsInteractor
+
+ @Before
+ fun setUp() {
+ userManager = kosmos.userManager
+ userRepository = kosmos.fakeUserRepository
+ userTracker = kosmos.fakeUserTracker
+
+ val userInfos = listOf(MAIN_USER_INFO, USER_INFO_WORK)
+ userRepository.setUserInfos(userInfos)
+ userTracker.set(
+ userInfos = userInfos,
+ selectedUserIndex = 0,
+ )
+
+ underTest = kosmos.communalSettingsInteractor
+ }
+
+ @Test
+ fun filterUsers_dontFilteredUsersWhenAllAreAllowed() =
+ testScope.runTest {
+ // If no users have any keyguard features disabled...
+ val disallowedUser by
+ collectLastValue(underTest.workProfileUserDisallowedByDevicePolicy)
+ // ...then the disallowed user should be null
+ assertNull(disallowedUser)
+ }
+
+ @Test
+ fun filterUsers_filterWorkProfileUserWhenDisallowed() =
+ testScope.runTest {
+ // If the work profile user has keyguard widgets disabled...
+ setKeyguardFeaturesDisabled(
+ USER_INFO_WORK,
+ DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL
+ )
+ // ...then the disallowed user match the work profile
+ val disallowedUser by
+ collectLastValue(underTest.workProfileUserDisallowedByDevicePolicy)
+ assertNotNull(disallowedUser)
+ assertEquals(USER_INFO_WORK.id, disallowedUser!!.id)
+ }
+
+ private fun setKeyguardFeaturesDisabled(user: UserInfo, disabledFlags: Int) {
+ whenever(
+ kosmos.devicePolicyManager.getKeyguardDisabledFeatures(
+ anyOrNull(),
+ ArgumentMatchers.eq(user.id)
+ )
+ )
+ .thenReturn(disabledFlags)
+ kosmos.broadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
+ )
+ }
+
+ private companion object {
+ val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN)
+ val USER_INFO_WORK =
+ UserInfo(
+ 10,
+ "work",
+ /* iconPath= */ "",
+ /* flags= */ 0,
+ UserManager.USER_TYPE_PROFILE_MANAGED,
+ )
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/smartspace/SmartspaceInteractionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/smartspace/SmartspaceInteractionHandlerTest.kt
index 0cd3fb28e299..d51d3567dd8d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/smartspace/SmartspaceInteractionHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/smartspace/SmartspaceInteractionHandlerTest.kt
@@ -26,14 +26,23 @@ import androidx.core.util.component2
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.domain.interactor.communalSceneInteractor
+import com.android.systemui.communal.widgets.CommunalTransitionAnimatorController
import com.android.systemui.communal.widgets.SmartspaceAppWidgetHostView
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.isNull
import org.mockito.kotlin.mock
-import org.mockito.kotlin.notNull
import org.mockito.kotlin.refEq
import org.mockito.kotlin.verify
@@ -41,6 +50,7 @@ import org.mockito.kotlin.verify
@RunWith(AndroidJUnit4::class)
class SmartspaceInteractionHandlerTest : SysuiTestCase() {
private val activityStarter = mock<ActivityStarter>()
+ private val kosmos = testKosmos()
private val testIntent =
PendingIntent.getActivity(
@@ -51,29 +61,43 @@ class SmartspaceInteractionHandlerTest : SysuiTestCase() {
)
private val testResponse = RemoteResponse.fromPendingIntent(testIntent)
- private val underTest: SmartspaceInteractionHandler by lazy {
- SmartspaceInteractionHandler(activityStarter)
+ private lateinit var underTest: SmartspaceInteractionHandler
+
+ @Before
+ fun setUp() {
+ with(kosmos) {
+ underTest = SmartspaceInteractionHandler(activityStarter, communalSceneInteractor)
+ }
}
@Test
fun launchAnimatorIsUsedForSmartspaceView() {
- val parent = FrameLayout(context)
- val view = SmartspaceAppWidgetHostView(context)
- parent.addView(view)
- val (fillInIntent, activityOptions) = testResponse.getLaunchOptions(view)
+ with(kosmos) {
+ testScope.runTest {
+ val launching by collectLastValue(communalSceneInteractor.isLaunchingWidget)
+ assertFalse(launching!!)
- underTest.onInteraction(view, testIntent, testResponse)
+ val parent = FrameLayout(context)
+ val view = SmartspaceAppWidgetHostView(context)
+ parent.addView(view)
+ val (fillInIntent, activityOptions) = testResponse.getLaunchOptions(view)
- // Verify that we pass in a non-null animation controller
- verify(activityStarter)
- .startPendingIntentWithoutDismissing(
- /* intent = */ eq(testIntent),
- /* dismissShade = */ eq(false),
- /* intentSentUiThreadCallback = */ isNull(),
- /* animationController = */ notNull(),
- /* fillInIntent = */ refEq(fillInIntent),
- /* extraOptions = */ refEq(activityOptions.toBundle()),
- )
+ underTest.onInteraction(view, testIntent, testResponse)
+
+ // Verify that we set the state correctly
+ assertTrue(launching!!)
+ // Verify that we pass in a non-null Communal animation controller
+ verify(activityStarter)
+ .startPendingIntentWithoutDismissing(
+ /* intent = */ eq(testIntent),
+ /* dismissShade = */ eq(false),
+ /* intentSentUiThreadCallback = */ isNull(),
+ /* animationController = */ any<CommunalTransitionAnimatorController>(),
+ /* fillInIntent = */ refEq(fillInIntent),
+ /* extraOptions = */ refEq(activityOptions.toBundle()),
+ )
+ }
+ }
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
index 0190ccba3caa..b138fb3b779a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
@@ -16,7 +16,6 @@
package com.android.systemui.communal.view.viewmodel
-import android.app.smartspace.SmartspaceTarget
import android.appwidget.AppWidgetProviderInfo
import android.content.ActivityNotFoundException
import android.content.Intent
@@ -32,12 +31,16 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.data.model.CommunalSmartspaceTimer
import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
+import com.android.systemui.communal.data.repository.FakeCommunalSmartspaceRepository
import com.android.systemui.communal.data.repository.FakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository
import com.android.systemui.communal.data.repository.fakeCommunalMediaRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSmartspaceRepository
import com.android.systemui.communal.data.repository.fakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.communalPrefsInteractor
@@ -57,8 +60,6 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.settings.fakeUserTracker
-import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
-import com.android.systemui.smartspace.data.repository.fakeSmartspaceRepository
import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.util.mockito.any
@@ -76,6 +77,8 @@ import org.mockito.Mockito
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.spy
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -91,9 +94,10 @@ class CommunalEditModeViewModelTest : SysuiTestCase() {
private lateinit var tutorialRepository: FakeCommunalTutorialRepository
private lateinit var widgetRepository: FakeCommunalWidgetRepository
- private lateinit var smartspaceRepository: FakeSmartspaceRepository
+ private lateinit var smartspaceRepository: FakeCommunalSmartspaceRepository
private lateinit var mediaRepository: FakeCommunalMediaRepository
private lateinit var communalSceneInteractor: CommunalSceneInteractor
+ private lateinit var communalInteractor: CommunalInteractor
private val testableResources = context.orCreateTestableResources
@@ -105,9 +109,10 @@ class CommunalEditModeViewModelTest : SysuiTestCase() {
tutorialRepository = kosmos.fakeCommunalTutorialRepository
widgetRepository = kosmos.fakeCommunalWidgetRepository
- smartspaceRepository = kosmos.fakeSmartspaceRepository
+ smartspaceRepository = kosmos.fakeCommunalSmartspaceRepository
mediaRepository = kosmos.fakeCommunalMediaRepository
communalSceneInteractor = kosmos.communalSceneInteractor
+ communalInteractor = spy(kosmos.communalInteractor)
kosmos.fakeUserRepository.setUserInfos(listOf(MAIN_USER_INFO))
kosmos.fakeUserTracker.set(
userInfos = listOf(MAIN_USER_INFO),
@@ -119,7 +124,7 @@ class CommunalEditModeViewModelTest : SysuiTestCase() {
underTest =
CommunalEditModeViewModel(
communalSceneInteractor,
- kosmos.communalInteractor,
+ communalInteractor,
kosmos.communalSettingsInteractor,
kosmos.keyguardTransitionInteractor,
mediaHost,
@@ -152,11 +157,15 @@ class CommunalEditModeViewModelTest : SysuiTestCase() {
widgetRepository.setCommunalWidgets(widgets)
// Smartspace available.
- val target = Mockito.mock(SmartspaceTarget::class.java)
- whenever(target.smartspaceTargetId).thenReturn("target")
- whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER)
- whenever(target.remoteViews).thenReturn(Mockito.mock(RemoteViews::class.java))
- smartspaceRepository.setCommunalSmartspaceTargets(listOf(target))
+ smartspaceRepository.setTimers(
+ listOf(
+ CommunalSmartspaceTimer(
+ smartspaceTargetId = "target",
+ createdTimestampMillis = 0L,
+ remoteViews = Mockito.mock(RemoteViews::class.java),
+ )
+ )
+ )
// Media playing.
mediaRepository.mediaActive()
@@ -342,6 +351,16 @@ class CommunalEditModeViewModelTest : SysuiTestCase() {
assertThat(showDisclaimer).isFalse()
}
+ @Test
+ fun scrollPosition_persistedOnEditCleanup() {
+ val index = 2
+ val offset = 30
+ underTest.onScrollPositionUpdated(index, offset)
+ underTest.cleanupEditModeState()
+
+ verify(communalInteractor).setScrollPosition(eq(index), eq(offset))
+ }
+
private companion object {
val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN)
const val WIDGET_PICKER_PACKAGE_NAME = "widget_picker_package_name"
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 2694cab09ab2..c480aa8e4a3d 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
@@ -16,7 +16,6 @@
package com.android.systemui.communal.view.viewmodel
-import android.app.smartspace.SmartspaceTarget
import android.appwidget.AppWidgetProviderInfo
import android.content.pm.UserInfo
import android.os.UserHandle
@@ -27,14 +26,18 @@ import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.data.model.CommunalSmartspaceTimer
import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
+import com.android.systemui.communal.data.repository.FakeCommunalSmartspaceRepository
import com.android.systemui.communal.data.repository.FakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository
import com.android.systemui.communal.data.repository.fakeCommunalMediaRepository
import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSmartspaceRepository
import com.android.systemui.communal.data.repository.fakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
@@ -69,12 +72,15 @@ import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.Transition
+import com.android.systemui.scene.data.repository.setTransition
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.fakeUserTracker
import com.android.systemui.shade.ShadeTestUtil
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.shadeTestUtil
-import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
-import com.android.systemui.smartspace.data.repository.fakeSmartspaceRepository
import com.android.systemui.statusbar.KeyguardIndicationController
import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.FakeUserRepository
@@ -92,7 +98,9 @@ import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
import org.mockito.kotlin.whenever
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
@@ -110,12 +118,13 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
private lateinit var keyguardRepository: FakeKeyguardRepository
private lateinit var tutorialRepository: FakeCommunalTutorialRepository
private lateinit var widgetRepository: FakeCommunalWidgetRepository
- private lateinit var smartspaceRepository: FakeSmartspaceRepository
+ private lateinit var smartspaceRepository: FakeCommunalSmartspaceRepository
private lateinit var mediaRepository: FakeCommunalMediaRepository
private lateinit var userRepository: FakeUserRepository
private lateinit var shadeTestUtil: ShadeTestUtil
private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository
private lateinit var communalRepository: FakeCommunalSceneRepository
+ private lateinit var communalInteractor: CommunalInteractor
private lateinit var underTest: CommunalViewModel
@@ -131,7 +140,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
tutorialRepository = kosmos.fakeCommunalTutorialRepository
widgetRepository = kosmos.fakeCommunalWidgetRepository
- smartspaceRepository = kosmos.fakeSmartspaceRepository
+ smartspaceRepository = kosmos.fakeCommunalSmartspaceRepository
mediaRepository = kosmos.fakeCommunalMediaRepository
userRepository = kosmos.fakeUserRepository
shadeTestUtil = kosmos.shadeTestUtil
@@ -149,6 +158,8 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
kosmos.powerInteractor.setAwakeForTest()
+ communalInteractor = spy(kosmos.communalInteractor)
+
underTest =
CommunalViewModel(
kosmos.testDispatcher,
@@ -159,7 +170,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
kosmos.keyguardInteractor,
mock<KeyguardIndicationController>(),
kosmos.communalSceneInteractor,
- kosmos.communalInteractor,
+ communalInteractor,
kosmos.communalSettingsInteractor,
kosmos.communalTutorialInteractor,
kosmos.shadeInteractor,
@@ -217,11 +228,15 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
widgetRepository.setCommunalWidgets(widgets)
// Smartspace available.
- val target = Mockito.mock(SmartspaceTarget::class.java)
- whenever(target.smartspaceTargetId).thenReturn("target")
- whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER)
- whenever(target.remoteViews).thenReturn(Mockito.mock(RemoteViews::class.java))
- smartspaceRepository.setCommunalSmartspaceTargets(listOf(target))
+ smartspaceRepository.setTimers(
+ listOf(
+ CommunalSmartspaceTimer(
+ smartspaceTargetId = "target",
+ createdTimestampMillis = 0L,
+ remoteViews = Mockito.mock(RemoteViews::class.java),
+ )
+ )
+ )
// Media playing.
mediaRepository.mediaActive()
@@ -288,7 +303,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
widgetRepository.setCommunalWidgets(emptyList())
// UMO playing
mediaRepository.mediaActive()
- smartspaceRepository.setCommunalSmartspaceTargets(emptyList())
+ smartspaceRepository.setTimers(emptyList())
val isEmptyState by collectLastValue(underTest.isEmptyState)
assertThat(isEmptyState).isTrue()
@@ -309,7 +324,7 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
),
)
mediaRepository.mediaInactive()
- smartspaceRepository.setCommunalSmartspaceTargets(emptyList())
+ smartspaceRepository.setTimers(emptyList())
val isEmptyState by collectLastValue(underTest.isEmptyState)
assertThat(isEmptyState).isFalse()
@@ -492,13 +507,16 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal))
)
// Transitioned to Glanceable hub.
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GLANCEABLE_HUB,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Communal),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GLANCEABLE_HUB,
+ )
)
// Shade not expanded.
- shadeTestUtil.setLockscreenShadeExpansion(0f)
+ if (!SceneContainerFlag.isEnabled) shadeTestUtil.setLockscreenShadeExpansion(0f)
assertThat(isFocusable).isEqualTo(true)
}
@@ -541,10 +559,13 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
keyguardRepository.setKeyguardOccluded(true)
// And on hub
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.DREAMING,
- to = KeyguardState.GLANCEABLE_HUB,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Communal),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.DREAMING,
+ to = KeyguardState.GLANCEABLE_HUB,
+ )
)
// Then flow is not frozen
@@ -558,10 +579,13 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
assertThat(isCommunalContentFlowFrozen).isEqualTo(true)
// 3. When transitioned to OCCLUDED and activity shows
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GLANCEABLE_HUB,
- to = KeyguardState.OCCLUDED,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Lockscreen),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.OCCLUDED,
+ )
)
// Then flow is not frozen
@@ -579,10 +603,13 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
keyguardRepository.setKeyguardOccluded(false)
// And transitioned to hub
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GLANCEABLE_HUB,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Communal),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GLANCEABLE_HUB,
+ )
)
// Then flow is not frozen
@@ -593,30 +620,30 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
runCurrent()
// And transitioning to occluded
- keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- from = KeyguardState.GLANCEABLE_HUB,
- to = KeyguardState.OCCLUDED,
- transitionState = TransitionState.STARTED,
- )
- )
-
- keyguardTransitionRepository.sendTransitionStep(
- from = KeyguardState.GLANCEABLE_HUB,
- to = KeyguardState.OCCLUDED,
- transitionState = TransitionState.RUNNING,
- value = 0.5f,
+ kosmos.setTransition(
+ sceneTransition = Transition(from = Scenes.Communal, to = Scenes.Lockscreen),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.OCCLUDED,
+ transitionState = TransitionState.STARTED,
+ value = 0f,
+ )
)
// Then flow is frozen
assertThat(isCommunalContentFlowFrozen).isEqualTo(true)
// 3. When transition is finished
- keyguardTransitionRepository.sendTransitionStep(
- from = KeyguardState.GLANCEABLE_HUB,
- to = KeyguardState.OCCLUDED,
- transitionState = TransitionState.FINISHED,
- value = 1f,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Lockscreen),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.OCCLUDED,
+ transitionState = TransitionState.FINISHED,
+ value = 1f,
+ )
)
// Then flow is not frozen
@@ -639,10 +666,13 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
keyguardRepository.setKeyguardOccluded(true)
// And transitioned to hub
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.DREAMING,
- to = KeyguardState.GLANCEABLE_HUB,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Communal),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.DREAMING,
+ to = KeyguardState.GLANCEABLE_HUB,
+ )
)
// Widgets available
@@ -669,11 +699,15 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
advanceTimeBy(60L)
// New timer available
- val target = Mockito.mock(SmartspaceTarget::class.java)
- whenever<String?>(target.smartspaceTargetId).thenReturn("target")
- whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER)
- whenever(target.remoteViews).thenReturn(Mockito.mock(RemoteViews::class.java))
- smartspaceRepository.setCommunalSmartspaceTargets(listOf(target))
+ smartspaceRepository.setTimers(
+ listOf(
+ CommunalSmartspaceTimer(
+ smartspaceTargetId = "target",
+ createdTimestampMillis = 0L,
+ remoteViews = Mockito.mock(RemoteViews::class.java),
+ )
+ )
+ )
runCurrent()
// Still only emits widgets and the CTA tile
@@ -728,11 +762,15 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
assertThat(communalContent).hasSize(3)
// When new timer available
- val target = Mockito.mock(SmartspaceTarget::class.java)
- whenever(target.smartspaceTargetId).thenReturn("target")
- whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER)
- whenever(target.remoteViews).thenReturn(Mockito.mock(RemoteViews::class.java))
- smartspaceRepository.setCommunalSmartspaceTargets(listOf(target))
+ smartspaceRepository.setTimers(
+ listOf(
+ CommunalSmartspaceTimer(
+ smartspaceTargetId = "target",
+ createdTimestampMillis = 0L,
+ remoteViews = Mockito.mock(RemoteViews::class.java),
+ )
+ )
+ )
runCurrent()
// Then emits timer, widgets and the CTA tile
@@ -747,6 +785,16 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
.isInstanceOf(CommunalContentModel.CtaTileInViewMode::class.java)
}
+ @Test
+ fun scrollPosition_persistedOnEditEntry() {
+ val index = 2
+ val offset = 30
+ underTest.onScrollPositionUpdated(index, offset)
+ underTest.onOpenWidgetEditor(false)
+
+ verify(communalInteractor).setScrollPosition(eq(index), eq(offset))
+ }
+
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/communal/widgets/CommunalTransitionAnimatorControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalTransitionAnimatorControllerTest.kt
new file mode 100644
index 000000000000..ac50db483301
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalTransitionAnimatorControllerTest.kt
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.ActivityTransitionAnimator
+import com.android.systemui.communal.domain.interactor.communalSceneInteractor
+import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.communal.widgets.CommunalTransitionAnimatorController
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CommunalTransitionAnimatorControllerTest : SysuiTestCase() {
+ private val controller = mock<ActivityTransitionAnimator.Controller>()
+ private val kosmos = testKosmos()
+
+ private lateinit var underTest: CommunalTransitionAnimatorController
+
+ @Before
+ fun setUp() {
+ with(kosmos) {
+ underTest = CommunalTransitionAnimatorController(controller, communalSceneInteractor)
+ }
+ }
+
+ @Test
+ fun doNotAnimate_launchingWidgetStateIsCleared() {
+ with(kosmos) {
+ testScope.runTest {
+ val launching by collectLastValue(communalSceneInteractor.isLaunchingWidget)
+
+ communalSceneInteractor.setIsLaunchingWidget(true)
+ assertTrue(launching!!)
+
+ underTest.onIntentStarted(willAnimate = false)
+ assertFalse(launching!!)
+ verify(controller).onIntentStarted(willAnimate = false)
+ }
+ }
+ }
+
+ @Test
+ fun animationCancelled_launchingWidgetStateIsClearedAndSceneIsNotChanged() {
+ with(kosmos) {
+ testScope.runTest {
+ val launching by collectLastValue(communalSceneInteractor.isLaunchingWidget)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
+
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
+ Truth.assertThat(scene).isEqualTo(CommunalScenes.Communal)
+ communalSceneInteractor.setIsLaunchingWidget(true)
+ assertTrue(launching!!)
+
+ underTest.onIntentStarted(willAnimate = true)
+ assertTrue(launching!!)
+ verify(controller).onIntentStarted(willAnimate = true)
+
+ underTest.onTransitionAnimationCancelled(newKeyguardOccludedState = true)
+ assertFalse(launching!!)
+ Truth.assertThat(scene).isEqualTo(CommunalScenes.Communal)
+ verify(controller).onTransitionAnimationCancelled(newKeyguardOccludedState = true)
+ }
+ }
+ }
+
+ @Test
+ fun animationComplete_launchingWidgetStateIsClearedAndSceneIsChanged() {
+ with(kosmos) {
+ testScope.runTest {
+ val launching by collectLastValue(communalSceneInteractor.isLaunchingWidget)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
+
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
+ Truth.assertThat(scene).isEqualTo(CommunalScenes.Communal)
+ communalSceneInteractor.setIsLaunchingWidget(true)
+ assertTrue(launching!!)
+
+ underTest.onIntentStarted(willAnimate = true)
+ assertTrue(launching!!)
+ verify(controller).onIntentStarted(willAnimate = true)
+
+ underTest.onTransitionAnimationEnd(isExpandingFullyAbove = true)
+ assertFalse(launching!!)
+ Truth.assertThat(scene).isEqualTo(CommunalScenes.Blank)
+ verify(controller).onTransitionAnimationEnd(isExpandingFullyAbove = true)
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
index 70448955eff0..ea8b5ab70cd9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
@@ -26,13 +26,21 @@ import androidx.core.util.component2
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.domain.interactor.communalSceneInteractor
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.isNull
import org.mockito.kotlin.mock
-import org.mockito.kotlin.notNull
import org.mockito.kotlin.refEq
import org.mockito.kotlin.verify
@@ -40,6 +48,7 @@ import org.mockito.kotlin.verify
@RunWith(AndroidJUnit4::class)
class WidgetInteractionHandlerTest : SysuiTestCase() {
private val activityStarter = mock<ActivityStarter>()
+ private val kosmos = testKosmos()
private val testIntent =
PendingIntent.getActivity(
@@ -50,30 +59,44 @@ class WidgetInteractionHandlerTest : SysuiTestCase() {
)
private val testResponse = RemoteResponse.fromPendingIntent(testIntent)
- private val underTest: WidgetInteractionHandler by lazy {
- WidgetInteractionHandler(activityStarter)
+ private lateinit var underTest: WidgetInteractionHandler
+
+ @Before
+ fun setUp() {
+ with(kosmos) {
+ underTest = WidgetInteractionHandler(activityStarter, communalSceneInteractor)
+ }
}
@Test
fun launchAnimatorIsUsedForWidgetView() {
- val parent = FrameLayout(context)
- val view = CommunalAppWidgetHostView(context)
- parent.addView(view)
- val (fillInIntent, activityOptions) = testResponse.getLaunchOptions(view)
+ with(kosmos) {
+ testScope.runTest {
+ val launching by collectLastValue(communalSceneInteractor.isLaunchingWidget)
+ assertFalse(launching!!)
- underTest.onInteraction(view, testIntent, testResponse)
+ val parent = FrameLayout(context)
+ val view = CommunalAppWidgetHostView(context)
+ parent.addView(view)
+ val (fillInIntent, activityOptions) = testResponse.getLaunchOptions(view)
- // Verify that we pass in a non-null animation controller
- verify(activityStarter)
- .startPendingIntentMaybeDismissingKeyguard(
- /* intent = */ eq(testIntent),
- /* dismissShade = */ eq(false),
- /* intentSentUiThreadCallback = */ isNull(),
- /* animationController = */ notNull(),
- /* fillInIntent = */ refEq(fillInIntent),
- /* extraOptions = */ refEq(activityOptions.toBundle()),
- /* customMessage */ isNull(),
- )
+ underTest.onInteraction(view, testIntent, testResponse)
+
+ // Verify that we set the state correctly
+ assertTrue(launching!!)
+ // Verify that we pass in a non-null Communal animation controller
+ verify(activityStarter)
+ .startPendingIntentMaybeDismissingKeyguard(
+ /* intent = */ eq(testIntent),
+ /* dismissShade = */ eq(false),
+ /* intentSentUiThreadCallback = */ isNull(),
+ /* animationController = */ any<CommunalTransitionAnimatorController>(),
+ /* fillInIntent = */ refEq(fillInIntent),
+ /* extraOptions = */ refEq(activityOptions.toBundle()),
+ /* customMessage */ isNull(),
+ )
+ }
+ }
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index 2546f27cb351..2bf50b3daa2f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -52,7 +52,6 @@ import com.android.systemui.deviceentry.shared.FaceAuthUiEvent.FACE_AUTH_TRIGGER
import com.android.systemui.deviceentry.shared.model.ErrorFaceAuthenticationStatus
import com.android.systemui.deviceentry.shared.model.FaceAuthenticationStatus
import com.android.systemui.deviceentry.shared.model.FaceDetectionStatus
-import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus
import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.dump.DumpManager
@@ -79,7 +78,6 @@ import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
-import com.android.systemui.res.R
import com.android.systemui.statusbar.commandQueue
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.testKosmos
@@ -478,29 +476,6 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
}
@Test
- fun faceHelpMessagesAreIgnoredBasedOnConfig() =
- testScope.runTest {
- overrideResource(
- R.array.config_face_acquire_device_entry_ignorelist,
- intArrayOf(10, 11)
- )
- underTest = createDeviceEntryFaceAuthRepositoryImpl()
- initCollectors()
- allPreconditionsToRunFaceAuthAreTrue()
-
- underTest.requestAuthenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
- faceAuthenticateIsCalled()
-
- authenticationCallback.value.onAuthenticationHelp(9, "help msg")
- authenticationCallback.value.onAuthenticationHelp(10, "Ignored help msg")
- authenticationCallback.value.onAuthenticationHelp(11, "Ignored help msg")
-
- val response = authStatus() as HelpFaceAuthenticationStatus
- assertThat(response.msg).isEqualTo("help msg")
- assertThat(response.msgId).isEqualTo(response.msgId)
- }
-
- @Test
fun dumpDoesNotErrorOutWhenFaceManagerOrBypassControllerIsNull() =
testScope.runTest {
fakeUserRepository.setSelectedUserInfo(primaryUser)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index 84c250ce355c..3253edfb5fca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -20,7 +20,6 @@ import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.SceneKey
-import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
@@ -32,27 +31,14 @@ import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
-import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason
-import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.AdaptiveAuthRequest
-import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.BouncerLockedOut
-import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot
-import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.NonStrongBiometricsSecurityTimeout
-import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.PolicyLockdown
-import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.SecurityTimeout
-import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.TrustAgentDisabled
-import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.UnattendedUpdate
-import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.UserLockdown
import com.android.systemui.flags.EnableSceneContainer
-import com.android.systemui.flags.fakeSystemPropertiesHelper
import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
-import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeTrustRepository
-import com.android.systemui.keyguard.shared.model.AuthenticationFlags
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
@@ -61,7 +47,6 @@ import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -438,204 +423,6 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
assertThat(isUnlocked).isTrue()
}
- @Test
- fun deviceEntryRestrictionReason_whenFaceOrFingerprintOrTrust_alwaysNull() =
- testScope.runTest {
- kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
- kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
- kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
- runCurrent()
-
- verifyRestrictionReasonsForAuthFlags(
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to null,
- LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to null,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to null,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to null,
- LockPatternUtils.StrongAuthTracker
- .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to null,
- LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
- null,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
- null,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to null
- )
- }
-
- @Test
- fun deviceEntryRestrictionReason_whenFaceIsEnrolledAndEnabled_mapsToAuthFlagsState() =
- testScope.runTest {
- kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
- kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
- kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
- kosmos.fakeSystemPropertiesHelper.set(
- DeviceEntryInteractor.SYS_BOOT_REASON_PROP,
- "not mainline reboot"
- )
- runCurrent()
-
- verifyRestrictionReasonsForAuthFlags(
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
- DeviceNotUnlockedSinceReboot,
- LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to
- AdaptiveAuthRequest,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to
- BouncerLockedOut,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
- SecurityTimeout,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
- UserLockdown,
- LockPatternUtils.StrongAuthTracker
- .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
- NonStrongBiometricsSecurityTimeout,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
- UnattendedUpdate,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
- PolicyLockdown,
- LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
- LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
- null,
- )
- }
-
- @Test
- fun deviceEntryRestrictionReason_whenFingerprintIsEnrolledAndEnabled_mapsToAuthFlagsState() =
- testScope.runTest {
- kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
- kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
- kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
- kosmos.fakeSystemPropertiesHelper.set(
- DeviceEntryInteractor.SYS_BOOT_REASON_PROP,
- "not mainline reboot"
- )
- runCurrent()
-
- verifyRestrictionReasonsForAuthFlags(
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
- DeviceNotUnlockedSinceReboot,
- LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to
- AdaptiveAuthRequest,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to
- BouncerLockedOut,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
- SecurityTimeout,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
- UserLockdown,
- LockPatternUtils.StrongAuthTracker
- .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
- NonStrongBiometricsSecurityTimeout,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
- UnattendedUpdate,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
- PolicyLockdown,
- LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
- LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
- null,
- )
- }
-
- @Test
- fun deviceEntryRestrictionReason_whenTrustAgentIsEnabled_mapsToAuthFlagsState() =
- testScope.runTest {
- kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
- kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
- kosmos.fakeTrustRepository.setTrustUsuallyManaged(true)
- kosmos.fakeTrustRepository.setCurrentUserTrustManaged(false)
- kosmos.fakeSystemPropertiesHelper.set(
- DeviceEntryInteractor.SYS_BOOT_REASON_PROP,
- "not mainline reboot"
- )
- runCurrent()
-
- verifyRestrictionReasonsForAuthFlags(
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
- DeviceNotUnlockedSinceReboot,
- LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to
- AdaptiveAuthRequest,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to
- BouncerLockedOut,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
- SecurityTimeout,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
- UserLockdown,
- LockPatternUtils.StrongAuthTracker
- .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
- NonStrongBiometricsSecurityTimeout,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
- UnattendedUpdate,
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
- PolicyLockdown,
- LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to
- TrustAgentDisabled,
- LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
- TrustAgentDisabled,
- )
- }
-
- @Test
- fun deviceEntryRestrictionReason_whenDeviceRebootedForMainlineUpdate_mapsToTheCorrectReason() =
- testScope.runTest {
- val deviceEntryRestrictionReason by
- collectLastValue(underTest.deviceEntryRestrictionReason)
- kosmos.fakeSystemPropertiesHelper.set(
- DeviceEntryInteractor.SYS_BOOT_REASON_PROP,
- DeviceEntryInteractor.REBOOT_MAINLINE_UPDATE
- )
- kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags(
- AuthenticationFlags(
- userId = 1,
- flag = LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
- )
- )
- runCurrent()
-
- kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
- kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
- kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
- runCurrent()
-
- assertThat(deviceEntryRestrictionReason).isNull()
-
- kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
- runCurrent()
-
- assertThat(deviceEntryRestrictionReason)
- .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)
-
- kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
- kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
- runCurrent()
-
- assertThat(deviceEntryRestrictionReason)
- .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)
-
- kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
- kosmos.fakeTrustRepository.setTrustUsuallyManaged(true)
- runCurrent()
-
- assertThat(deviceEntryRestrictionReason)
- .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)
- }
-
- private fun TestScope.verifyRestrictionReasonsForAuthFlags(
- vararg authFlagToDeviceEntryRestriction: Pair<Int, DeviceEntryRestrictionReason?>
- ) {
- val deviceEntryRestrictionReason by collectLastValue(underTest.deviceEntryRestrictionReason)
-
- authFlagToDeviceEntryRestriction.forEach { (flag, expectedReason) ->
- kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags(
- AuthenticationFlags(userId = 1, flag = flag)
- )
- runCurrent()
-
- if (expectedReason == null) {
- assertThat(deviceEntryRestrictionReason).isNull()
- } else {
- assertThat(deviceEntryRestrictionReason).isEqualTo(expectedReason)
- }
- }
- }
-
private fun switchToScene(sceneKey: SceneKey) {
sceneInteractor.changeScene(sceneKey, "reason")
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
index a7a7bea313fe..c2acc5ff6689 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
@@ -19,17 +19,20 @@ package com.android.systemui.deviceentry.domain.interactor
import android.content.pm.UserInfo
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
-import com.android.systemui.authentication.domain.interactor.authenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason
import com.android.systemui.deviceentry.shared.model.DeviceUnlockSource
+import com.android.systemui.flags.fakeSystemPropertiesHelper
+import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeTrustRepository
-import com.android.systemui.keyguard.domain.interactor.trustInteractor
+import com.android.systemui.keyguard.shared.model.AuthenticationFlags
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
@@ -40,6 +43,7 @@ import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.fakeUserRepository
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -54,18 +58,8 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() {
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val authenticationRepository = kosmos.fakeAuthenticationRepository
- private val deviceEntryRepository = kosmos.fakeDeviceEntryRepository
-
- val underTest =
- DeviceUnlockedInteractor(
- applicationScope = testScope.backgroundScope,
- authenticationInteractor = kosmos.authenticationInteractor,
- deviceEntryRepository = deviceEntryRepository,
- trustInteractor = kosmos.trustInteractor,
- faceAuthInteractor = kosmos.deviceEntryFaceAuthInteractor,
- fingerprintAuthInteractor = kosmos.deviceEntryFingerprintAuthInteractor,
- powerInteractor = kosmos.powerInteractor,
- )
+
+ val underTest = kosmos.deviceUnlockedInteractor
@Before
fun setup() {
@@ -100,6 +94,30 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() {
}
@Test
+ fun deviceUnlockStatus_whenUnlockedAndAuthMethodIsPinAndInLockdown_isFalse() =
+ testScope.runTest {
+ val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+ val isInLockdown by collectLastValue(underTest.isInLockdown)
+
+ authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags(
+ AuthenticationFlags(
+ userId = 1,
+ flag =
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN,
+ )
+ )
+ runCurrent()
+ assertThat(isInLockdown).isTrue()
+
+ assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
+ assertThat(deviceUnlockStatus?.deviceUnlockSource).isNull()
+ }
+
+ @Test
fun deviceUnlockStatus_whenUnlockedAndAuthMethodIsSim_isFalse() =
testScope.runTest {
val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
@@ -221,6 +239,218 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() {
assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
}
+ @Test
+ fun deviceEntryRestrictionReason_whenFaceOrFingerprintOrTrust_alwaysNull() =
+ testScope.runTest {
+ kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
+ kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+ kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
+ runCurrent()
+
+ verifyRestrictionReasonsForAuthFlags(
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to null,
+ LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to null,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to null,
+ LockPatternUtils.StrongAuthTracker
+ .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to null,
+ LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
+ null,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
+ null,
+ )
+ }
+
+ @Test
+ fun deviceEntryRestrictionReason_whenFaceOrFingerprintOrTrust_whenLockdown() =
+ testScope.runTest {
+ kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
+ kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+ kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
+ runCurrent()
+
+ verifyRestrictionReasonsForAuthFlags(
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
+ DeviceEntryRestrictionReason.UserLockdown,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+ DeviceEntryRestrictionReason.PolicyLockdown
+ )
+ }
+
+ @Test
+ fun deviceEntryRestrictionReason_whenFaceIsEnrolledAndEnabled_mapsToAuthFlagsState() =
+ testScope.runTest {
+ kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
+ kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+ kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
+ kosmos.fakeSystemPropertiesHelper.set(
+ DeviceUnlockedInteractor.SYS_BOOT_REASON_PROP,
+ "not mainline reboot"
+ )
+ runCurrent()
+
+ verifyRestrictionReasonsForAuthFlags(
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
+ DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot,
+ LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to
+ DeviceEntryRestrictionReason.AdaptiveAuthRequest,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to
+ DeviceEntryRestrictionReason.BouncerLockedOut,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
+ DeviceEntryRestrictionReason.SecurityTimeout,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
+ DeviceEntryRestrictionReason.UserLockdown,
+ LockPatternUtils.StrongAuthTracker
+ .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
+ DeviceEntryRestrictionReason.NonStrongBiometricsSecurityTimeout,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
+ DeviceEntryRestrictionReason.UnattendedUpdate,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+ DeviceEntryRestrictionReason.PolicyLockdown,
+ LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
+ LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
+ null,
+ )
+ }
+
+ @Test
+ fun deviceEntryRestrictionReason_whenFingerprintIsEnrolledAndEnabled_mapsToAuthFlagsState() =
+ testScope.runTest {
+ kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
+ kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+ kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
+ kosmos.fakeSystemPropertiesHelper.set(
+ DeviceUnlockedInteractor.SYS_BOOT_REASON_PROP,
+ "not mainline reboot"
+ )
+ runCurrent()
+
+ verifyRestrictionReasonsForAuthFlags(
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
+ DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot,
+ LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to
+ DeviceEntryRestrictionReason.AdaptiveAuthRequest,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to
+ DeviceEntryRestrictionReason.BouncerLockedOut,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
+ DeviceEntryRestrictionReason.SecurityTimeout,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
+ DeviceEntryRestrictionReason.UserLockdown,
+ LockPatternUtils.StrongAuthTracker
+ .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
+ DeviceEntryRestrictionReason.NonStrongBiometricsSecurityTimeout,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
+ DeviceEntryRestrictionReason.UnattendedUpdate,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+ DeviceEntryRestrictionReason.PolicyLockdown,
+ LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
+ LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
+ null,
+ )
+ }
+
+ @Test
+ fun deviceEntryRestrictionReason_whenTrustAgentIsEnabled_mapsToAuthFlagsState() =
+ testScope.runTest {
+ kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
+ kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+ kosmos.fakeTrustRepository.setTrustUsuallyManaged(true)
+ kosmos.fakeTrustRepository.setCurrentUserTrustManaged(false)
+ kosmos.fakeSystemPropertiesHelper.set(
+ DeviceUnlockedInteractor.SYS_BOOT_REASON_PROP,
+ "not mainline reboot"
+ )
+ runCurrent()
+
+ verifyRestrictionReasonsForAuthFlags(
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
+ DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot,
+ LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to
+ DeviceEntryRestrictionReason.AdaptiveAuthRequest,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to
+ DeviceEntryRestrictionReason.BouncerLockedOut,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
+ DeviceEntryRestrictionReason.SecurityTimeout,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
+ DeviceEntryRestrictionReason.UserLockdown,
+ LockPatternUtils.StrongAuthTracker
+ .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
+ DeviceEntryRestrictionReason.NonStrongBiometricsSecurityTimeout,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
+ DeviceEntryRestrictionReason.UnattendedUpdate,
+ LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+ DeviceEntryRestrictionReason.PolicyLockdown,
+ LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to
+ DeviceEntryRestrictionReason.TrustAgentDisabled,
+ LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
+ DeviceEntryRestrictionReason.TrustAgentDisabled,
+ )
+ }
+
+ @Test
+ fun deviceEntryRestrictionReason_whenDeviceRebootedForMainlineUpdate_mapsToTheCorrectReason() =
+ testScope.runTest {
+ val deviceEntryRestrictionReason by
+ collectLastValue(underTest.deviceEntryRestrictionReason)
+ kosmos.fakeSystemPropertiesHelper.set(
+ DeviceUnlockedInteractor.SYS_BOOT_REASON_PROP,
+ DeviceUnlockedInteractor.REBOOT_MAINLINE_UPDATE
+ )
+ kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags(
+ AuthenticationFlags(
+ userId = 1,
+ flag = LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
+ )
+ )
+ runCurrent()
+
+ kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
+ kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+ kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
+ runCurrent()
+
+ assertThat(deviceEntryRestrictionReason).isNull()
+
+ kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
+ runCurrent()
+
+ assertThat(deviceEntryRestrictionReason)
+ .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)
+
+ kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
+ kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+ runCurrent()
+
+ assertThat(deviceEntryRestrictionReason)
+ .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)
+
+ kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+ kosmos.fakeTrustRepository.setTrustUsuallyManaged(true)
+ runCurrent()
+
+ assertThat(deviceEntryRestrictionReason)
+ .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)
+ }
+
+ private fun TestScope.verifyRestrictionReasonsForAuthFlags(
+ vararg authFlagToDeviceEntryRestriction: Pair<Int, DeviceEntryRestrictionReason?>
+ ) {
+ val deviceEntryRestrictionReason by collectLastValue(underTest.deviceEntryRestrictionReason)
+
+ authFlagToDeviceEntryRestriction.forEach { (flag, expectedReason) ->
+ kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags(
+ AuthenticationFlags(userId = 1, flag = flag)
+ )
+ runCurrent()
+
+ if (expectedReason == null) {
+ assertThat(deviceEntryRestrictionReason).isNull()
+ } else {
+ assertThat(deviceEntryRestrictionReason).isEqualTo(expectedReason)
+ }
+ }
+ }
+
companion object {
private const val primaryUserId = 1
private val primaryUser = UserInfo(primaryUserId, "test user", UserInfo.FLAG_PRIMARY)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
index c48ced1e9a21..6412276ba34b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -32,11 +32,9 @@ import android.app.DreamManager;
import android.content.res.Resources;
import android.graphics.Region;
import android.os.Handler;
-import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.testing.TestableLooper.RunWithLooper;
import android.view.AttachedSurfaceControl;
-import android.view.View;
import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
@@ -46,7 +44,6 @@ import androidx.test.filters.SmallTest;
import com.android.dream.lowlight.LowLightTransitionCoordinator;
import com.android.keyguard.BouncerPanelExpansionCalculator;
-import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.ambient.statusbar.ui.AmbientStatusBarViewController;
import com.android.systemui.ambient.touch.scrim.BouncerlessScrimController;
@@ -101,9 +98,6 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
ViewGroup mDreamOverlayContentView;
@Mock
- View mHubGestureIndicatorView;
-
- @Mock
Handler mHandler;
@Mock
@@ -149,6 +143,8 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
when(mDreamOverlayContainerView.getRootSurfaceControl())
.thenReturn(mAttachedSurfaceControl);
when(mKeyguardTransitionInteractor.isFinishedInStateWhere(any())).thenReturn(emptyFlow());
+ when(mKeyguardTransitionInteractor.isFinishedIn(any(), any())).thenReturn(emptyFlow());
+ when(mKeyguardTransitionInteractor.isFinishedIn(any())).thenReturn(emptyFlow());
when(mShadeInteractor.isAnyExpanded()).thenReturn(MutableStateFlow(false));
when(mCommunalInteractor.isCommunalShowing()).thenReturn(MutableStateFlow(false));
@@ -156,7 +152,6 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
mDreamOverlayContainerView,
mComplicationHostViewController,
mDreamOverlayContentView,
- mHubGestureIndicatorView,
mAmbientStatusBarViewController,
mLowLightTransitionCoordinator,
mTouchInsetSession,
@@ -177,18 +172,6 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
mDreamManager);
}
- @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
- @Test
- public void testHubGestureIndicatorGoneWhenFlagOff() {
- verify(mHubGestureIndicatorView, never()).setVisibility(View.VISIBLE);
- }
-
- @EnableFlags({Flags.FLAG_COMMUNAL_HUB, Flags.FLAG_GLANCEABLE_HUB_GESTURE_HANDLE})
- @Test
- public void testHubGestureIndicatorVisibleWhenFlagOn() {
- verify(mHubGestureIndicatorView).setVisibility(View.VISIBLE);
- }
-
@Test
public void testRootSurfaceControlInsetSetOnAttach() {
mController.onViewAttached();
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index 5a39de8392be..60c9bb03b68e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -34,10 +34,14 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.app.viewcapture.ViewCapture
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager
+import com.android.app.viewcapture.ViewCaptureFactory
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.internal.logging.UiEventLogger
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
import com.android.systemui.ambient.touch.TouchMonitor
import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent
@@ -79,6 +83,7 @@ import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.isNull
+import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -154,8 +159,12 @@ class DreamOverlayServiceTest : SysuiTestCase() {
@Mock lateinit var mDreamOverlayCallbackController: DreamOverlayCallbackController
+ @Mock lateinit var mLazyViewCapture: Lazy<ViewCapture>
+
+ private lateinit var mViewCaptureAwareWindowManager: ViewCaptureAwareWindowManager
private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
private lateinit var communalRepository: FakeCommunalSceneRepository
+ private var viewCaptureSpy = spy(ViewCaptureFactory.getInstance(context))
@Captor var mViewCaptor: ArgumentCaptor<View>? = null
private lateinit var mService: DreamOverlayService
@@ -192,13 +201,20 @@ class DreamOverlayServiceTest : SysuiTestCase() {
whenever(mDreamOverlayContainerViewController.containerView)
.thenReturn(mDreamOverlayContainerView)
whenever(mScrimManager.getCurrentController()).thenReturn(mScrimController)
+ whenever(mLazyViewCapture.value).thenReturn(viewCaptureSpy)
mWindowParams = WindowManager.LayoutParams()
+ mViewCaptureAwareWindowManager =
+ ViewCaptureAwareWindowManager(
+ mWindowManager,
+ mLazyViewCapture,
+ isViewCaptureEnabled = false
+ )
mService =
DreamOverlayService(
mContext,
mLifecycleOwner,
mMainExecutor,
- mWindowManager,
+ mViewCaptureAwareWindowManager,
mComplicationComponentFactory,
mDreamComplicationComponentFactory,
mDreamOverlayComponentFactory,
@@ -623,7 +639,7 @@ class DreamOverlayServiceTest : SysuiTestCase() {
}
@Test
- @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT)
+ @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT, FLAG_COMMUNAL_HUB)
@kotlin.Throws(RemoteException::class)
fun testTransitionToGlanceableHub() =
testScope.runTest {
@@ -647,7 +663,7 @@ class DreamOverlayServiceTest : SysuiTestCase() {
}
@Test
- @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT)
+ @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT, FLAG_COMMUNAL_HUB)
@Throws(RemoteException::class)
fun testRedirectExit() =
testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt
new file mode 100644
index 000000000000..3a4b14b81e07
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright 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.education.data.repository
+
+import android.content.Context
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.SysuiTestableContext
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.shared.education.GestureType.BACK_GESTURE
+import com.google.common.truth.Truth.assertThat
+import java.io.File
+import java.time.Clock
+import java.time.Instant
+import javax.inject.Provider
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ContextualEducationRepositoryTest : SysuiTestCase() {
+
+ private lateinit var underTest: ContextualEducationRepository
+ private val kosmos = Kosmos()
+ private val testScope = kosmos.testScope
+ private val dsScopeProvider: Provider<CoroutineScope> = Provider {
+ TestScope(kosmos.testDispatcher).backgroundScope
+ }
+ private val clock: Clock = FakeEduClock(Instant.ofEpochMilli(1000))
+ private val testUserId = 1111
+
+ // For deleting any test files created after the test
+ @get:Rule val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build()
+
+ @Before
+ fun setUp() {
+ // Create TestContext here because TemporaryFolder.create() is called in @Before. It is
+ // needed before calling TemporaryFolder.newFolder().
+ val testContext = TestContext(context, tmpFolder.newFolder())
+ val userRepository = UserContextualEducationRepository(testContext, dsScopeProvider)
+ underTest = ContextualEducationRepositoryImpl(clock, userRepository)
+ underTest.setUser(testUserId)
+ }
+
+ @Test
+ fun changeRetrievedValueForNewUser() =
+ testScope.runTest {
+ // Update data for old user.
+ underTest.incrementSignalCount(BACK_GESTURE)
+ val model by collectLastValue(underTest.readGestureEduModelFlow(BACK_GESTURE))
+ assertThat(model?.signalCount).isEqualTo(1)
+
+ // User is changed.
+ underTest.setUser(1112)
+ // Assert count is 0 after user is changed.
+ assertThat(model?.signalCount).isEqualTo(0)
+ }
+
+ @Test
+ fun incrementSignalCount() =
+ testScope.runTest {
+ underTest.incrementSignalCount(BACK_GESTURE)
+ val model by collectLastValue(underTest.readGestureEduModelFlow(BACK_GESTURE))
+ assertThat(model?.signalCount).isEqualTo(1)
+ }
+
+ @Test
+ fun dataAddedOnUpdateShortcutTriggerTime() =
+ testScope.runTest {
+ val model by collectLastValue(underTest.readGestureEduModelFlow(BACK_GESTURE))
+ assertThat(model?.lastShortcutTriggeredTime).isNull()
+ underTest.updateShortcutTriggerTime(BACK_GESTURE)
+ assertThat(model?.lastShortcutTriggeredTime).isEqualTo(clock.instant())
+ }
+
+ /** Test context which allows overriding getFilesDir path */
+ private class TestContext(context: Context, private val folder: File) :
+ SysuiTestableContext(context) {
+ override fun getFilesDir(): File {
+ return folder
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
index 7d0f040793d8..693fcdabea58 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
@@ -17,10 +17,12 @@
package com.android.systemui.haptics.qs
import android.os.VibrationEffect
+import android.service.quicksettings.Tile
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.classifier.falsingManager
import com.android.systemui.haptics.vibratorHelper
import com.android.systemui.kosmos.testScope
import com.android.systemui.qs.qsTileFactory
@@ -69,6 +71,7 @@ class QSLongPressEffectTest : SysuiTestCase() {
QSLongPressEffect(
vibratorHelper,
kosmos.keyguardStateController,
+ kosmos.falsingManager,
)
longPressEffect.callback = callback
longPressEffect.qsTile = qsTile
@@ -175,17 +178,17 @@ class QSLongPressEffectTest : SysuiTestCase() {
}
@Test
- fun onAnimationComplete_keyguardDismissible_effectCompletes() =
+ fun onAnimationComplete_keyguardDismissible_effectEndsInLongClicked() =
testWhileInState(QSLongPressEffect.State.RUNNING_FORWARD) {
// GIVEN that the animation completes
longPressEffect.handleAnimationComplete()
- // THEN the long-press effect completes
- assertEffectCompleted()
+ // THEN the long-press effect completes with a long-click state
+ assertEffectCompleted(QSLongPressEffect.State.LONG_CLICKED)
}
@Test
- fun onAnimationComplete_keyguardNotDismissible_effectEndsWithReset() =
+ fun onAnimationComplete_keyguardNotDismissible_effectEndsInIdleWithReset() =
testWhileInState(QSLongPressEffect.State.RUNNING_FORWARD) {
// GIVEN that the keyguard is not dismissible
whenever(kosmos.keyguardStateController.isUnlocked).thenReturn(false)
@@ -193,19 +196,20 @@ class QSLongPressEffectTest : SysuiTestCase() {
// GIVEN that the animation completes
longPressEffect.handleAnimationComplete()
- // THEN the long-press effect completes and the properties are called to reset
- assertEffectCompleted()
+ // THEN the long-press effect ends in the idle state and the properties are reset
+ assertEffectCompleted(QSLongPressEffect.State.IDLE)
verify(callback, times(1)).onResetProperties()
}
@Test
- fun onAnimationComplete_whenRunningBackwardsFromUp_endsWithFinishedReversing() =
+ fun onAnimationComplete_whenRunningBackwardsFromUp_endsWithFinishedReversingAndClick() =
testWhileInState(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_UP) {
// GIVEN that the animation completes
longPressEffect.handleAnimationComplete()
- // THEN the callback for finished reversing is used.
+ // THEN the callback for finished reversing is used and the effect ends with a click.
verify(callback, times(1)).onEffectFinishedReversing()
+ assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.CLICKED)
}
@Test
@@ -262,19 +266,6 @@ class QSLongPressEffectTest : SysuiTestCase() {
}
@Test
- fun onTileClick_whileWaiting_withoutQSTile_cannotClick() =
- testWhileInState(QSLongPressEffect.State.TIMEOUT_WAIT) {
- // GIVEN that no QSTile has been set
- longPressEffect.qsTile = null
-
- // GIVEN that a click was detected
- val couldClick = longPressEffect.onTileClick()
-
- // THEN the click is not successful
- assertThat(couldClick).isFalse()
- }
-
- @Test
fun onTileClick_whileIdle_withQSTile_clicks() =
testWhileInState(QSLongPressEffect.State.IDLE) {
// GIVEN that a click was detected
@@ -285,18 +276,78 @@ class QSLongPressEffectTest : SysuiTestCase() {
}
@Test
- fun onTileClick_whileIdle_withoutQSTile_cannotClick() =
+ fun onTileClick_whenBouncerIsShowing_ignoresClick() =
testWhileInState(QSLongPressEffect.State.IDLE) {
- // GIVEN that no QSTile has been set
- longPressEffect.qsTile = null
+ // GIVEN that the bouncer is showing
+ whenever(kosmos.keyguardStateController.isPrimaryBouncerShowing).thenReturn(true)
- // GIVEN that a click was detected
+ // WHEN a click is detected by the tile view
val couldClick = longPressEffect.onTileClick()
// THEN the click is not successful
assertThat(couldClick).isFalse()
}
+ @Test
+ fun getStateForClick_withUnavailableTile_returnsIdle() {
+ // GIVEN an unavailable tile
+ qsTile.state?.state = Tile.STATE_UNAVAILABLE
+
+ // WHEN determining the state of a click action
+ val clickState = longPressEffect.getStateForClick()
+
+ // THEN the state is IDLE
+ assertThat(clickState).isEqualTo(QSLongPressEffect.State.IDLE)
+ }
+
+ @Test
+ fun getStateForClick_withFalseTapWhenLocked_returnsIdle() {
+ // GIVEN an active tile
+ qsTile.state?.state = Tile.STATE_ACTIVE
+
+ // GIVEN that the device is locked and a false tap is detected
+ whenever(kosmos.keyguardStateController.isUnlocked).thenReturn(false)
+ kosmos.falsingManager.setFalseTap(true)
+
+ // WHEN determining the state of a click action
+ val clickState = longPressEffect.getStateForClick()
+
+ // THEN the state is IDLE
+ assertThat(clickState).isEqualTo(QSLongPressEffect.State.IDLE)
+ }
+
+ @Test
+ fun getStateForClick_withValidTapAndTile_returnsClicked() {
+ // GIVEN an active tile
+ qsTile.state?.state = Tile.STATE_ACTIVE
+
+ // GIVEN that the device is locked and a false tap is not detected
+ whenever(kosmos.keyguardStateController.isUnlocked).thenReturn(false)
+ kosmos.falsingManager.setFalseTap(false)
+
+ // WHEN determining the state of a click action
+ val clickState = longPressEffect.getStateForClick()
+
+ // THEN the state is CLICKED
+ assertThat(clickState).isEqualTo(QSLongPressEffect.State.CLICKED)
+ }
+
+ @Test
+ fun getStateForClick_withNullTile_returnsIdle() {
+ // GIVEN that the tile is null
+ longPressEffect.qsTile = null
+
+ // GIVEN that the device is locked and a false tap is not detected
+ whenever(kosmos.keyguardStateController.isUnlocked).thenReturn(false)
+ kosmos.falsingManager.setFalseTap(false)
+
+ // WHEN determining the state of a click action
+ val clickState = longPressEffect.getStateForClick()
+
+ // THEN the state is IDLE
+ assertThat(clickState).isEqualTo(QSLongPressEffect.State.IDLE)
+ }
+
private fun testWithScope(initialize: Boolean = true, test: suspend TestScope.() -> Unit) =
with(kosmos) {
testScope.runTest {
@@ -362,14 +413,14 @@ class QSLongPressEffectTest : SysuiTestCase() {
/**
* Asserts that the effect completes by checking that:
* 1. The final snap haptics are played
- * 2. The internal state goes back to [QSLongPressEffect.State.IDLE]
+ * 2. The internal state goes back to specified end state.
*/
- private fun assertEffectCompleted() {
+ private fun assertEffectCompleted(endState: QSLongPressEffect.State) {
val snapEffect = LongPressHapticBuilder.createSnapEffect()
assertThat(snapEffect).isNotNull()
assertThat(vibratorHelper.hasVibratedWithEffects(snapEffect!!)).isTrue()
- assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.IDLE)
+ assertThat(longPressEffect.state).isEqualTo(endState)
}
/**
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
index 977f1db44258..bbfaf6fa4ce6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
@@ -24,7 +24,7 @@ import android.provider.Settings.Secure.ZEN_DURATION_FOREVER
import android.provider.Settings.Secure.ZEN_DURATION_PROMPT
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.settingslib.notification.EnableZenModeDialog
+import com.android.settingslib.notification.modes.EnableZenModeDialog
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.ContentDescription
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
index 612f2e73e4bb..b885800ab964 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
@@ -34,12 +34,14 @@ package com.android.systemui.keyguard.domain.interactor
import android.os.PowerManager
import android.platform.test.annotations.EnableFlags
+import android.service.dream.dreamManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
+import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
@@ -64,8 +66,10 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.reset
import org.mockito.Mockito.spy
+import org.mockito.kotlin.whenever
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -119,6 +123,66 @@ class FromDozingTransitionInteractorTest : SysuiTestCase() {
}
@Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR, Flags.FLAG_COMMUNAL_HUB)
+ fun testTransitionToLockscreen_onPowerButtonPress_canDream_glanceableHubAvailable() =
+ testScope.runTest {
+ whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true)
+ kosmos.setCommunalAvailable(true)
+ runCurrent()
+
+ powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_POWER_BUTTON)
+ runCurrent()
+
+ // If dreaming is possible and communal is available, then we should transition to
+ // GLANCEABLE_HUB when waking up due to power button press.
+ assertThat(transitionRepository)
+ .startedTransition(
+ from = KeyguardState.DOZING,
+ to = KeyguardState.GLANCEABLE_HUB,
+ )
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ fun testTransitionToLockscreen_onPowerButtonPress_canNotDream_glanceableHubAvailable() =
+ testScope.runTest {
+ whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(false)
+ kosmos.setCommunalAvailable(true)
+ runCurrent()
+
+ powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_POWER_BUTTON)
+ runCurrent()
+
+ // If dreaming is NOT possible but communal is available, then we should transition to
+ // LOCKSCREEN when waking up due to power button press.
+ assertThat(transitionRepository)
+ .startedTransition(
+ from = KeyguardState.DOZING,
+ to = KeyguardState.LOCKSCREEN,
+ )
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ fun testTransitionToLockscreen_onPowerButtonPress_canNDream_glanceableHubNotAvailable() =
+ testScope.runTest {
+ whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true)
+ kosmos.setCommunalAvailable(false)
+ runCurrent()
+
+ powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_POWER_BUTTON)
+ runCurrent()
+
+ // If dreaming is possible but communal is NOT available, then we should transition to
+ // LOCKSCREEN when waking up due to power button press.
+ assertThat(transitionRepository)
+ .startedTransition(
+ from = KeyguardState.DOZING,
+ to = KeyguardState.LOCKSCREEN,
+ )
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
fun testTransitionToGlanceableHub_onWakeup_ifIdleOnCommunal_noOccludingActivity() =
testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt
index 26b56a1be926..48621047016b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt
@@ -37,7 +37,6 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs
import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
@@ -81,10 +80,10 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
testScope.runTest {
val value by collectLastValue(underTest.clockShouldBeCentered)
kosmos.keyguardInteractor.setClockShouldBeCentered(true)
- assertThat(value).isEqualTo(true)
+ assertThat(value).isTrue()
kosmos.keyguardInteractor.setClockShouldBeCentered(false)
- assertThat(value).isEqualTo(false)
+ assertThat(value).isFalse()
}
@Test
@@ -103,7 +102,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
fun clockSize_SceneContainerFlagOn_shadeModeSingle_hasNotifs_SMALL() =
testScope.runTest {
val value by collectLastValue(underTest.clockSize)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Single)
+ kosmos.shadeRepository.setShadeLayoutWide(false)
kosmos.activeNotificationListRepository.setActiveNotifs(1)
assertThat(value).isEqualTo(ClockSize.SMALL)
}
@@ -113,7 +112,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
fun clockSize_SceneContainerFlagOn_shadeModeSingle_hasMedia_SMALL() =
testScope.runTest {
val value by collectLastValue(underTest.clockSize)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Single)
+ kosmos.shadeRepository.setShadeLayoutWide(false)
val userMedia = MediaData().copy(active = true)
kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
assertThat(value).isEqualTo(ClockSize.SMALL)
@@ -125,7 +124,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
testScope.runTest {
val value by collectLastValue(underTest.clockSize)
val userMedia = MediaData().copy(active = true)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
kosmos.keyguardRepository.setIsDozing(false)
assertThat(value).isEqualTo(ClockSize.SMALL)
@@ -136,7 +135,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
fun clockSize_SceneContainerFlagOn_shadeModeSplit_noMedia_LARGE() =
testScope.runTest {
val value by collectLastValue(underTest.clockSize)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
kosmos.keyguardRepository.setIsDozing(false)
assertThat(value).isEqualTo(ClockSize.LARGE)
}
@@ -147,7 +146,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
testScope.runTest {
val value by collectLastValue(underTest.clockSize)
val userMedia = MediaData().copy(active = true)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
kosmos.keyguardRepository.setIsDozing(true)
assertThat(value).isEqualTo(ClockSize.LARGE)
@@ -158,8 +157,8 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
fun clockShouldBeCentered_sceneContainerFlagOn_notSplitMode_true() =
testScope.runTest {
val value by collectLastValue(underTest.clockShouldBeCentered)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Single)
- assertThat(value).isEqualTo(true)
+ kosmos.shadeRepository.setShadeLayoutWide(false)
+ assertThat(value).isTrue()
}
@Test
@@ -167,9 +166,9 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
fun clockShouldBeCentered_sceneContainerFlagOn_splitMode_noActiveNotifications_true() =
testScope.runTest {
val value by collectLastValue(underTest.clockShouldBeCentered)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
kosmos.activeNotificationListRepository.setActiveNotifs(0)
- assertThat(value).isEqualTo(true)
+ assertThat(value).isTrue()
}
@Test
@@ -177,10 +176,10 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
fun clockShouldBeCentered_sceneContainerFlagOn_splitMode_isActiveDreamLockscreenHosted_true() =
testScope.runTest {
val value by collectLastValue(underTest.clockShouldBeCentered)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
kosmos.activeNotificationListRepository.setActiveNotifs(1)
kosmos.keyguardRepository.setIsActiveDreamLockscreenHosted(true)
- assertThat(value).isEqualTo(true)
+ assertThat(value).isTrue()
}
@Test
@@ -188,11 +187,11 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
fun clockShouldBeCentered_sceneContainerFlagOn_splitMode_hasPulsingNotifications_false() =
testScope.runTest {
val value by collectLastValue(underTest.clockShouldBeCentered)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
kosmos.activeNotificationListRepository.setActiveNotifs(1)
kosmos.headsUpNotificationRepository.isHeadsUpAnimatingAway.value = true
kosmos.keyguardRepository.setIsDozing(true)
- assertThat(value).isEqualTo(false)
+ assertThat(value).isFalse()
}
@Test
@@ -200,10 +199,10 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
fun clockShouldBeCentered_sceneContainerFlagOn_splitMode_onAod_true() =
testScope.runTest {
val value by collectLastValue(underTest.clockShouldBeCentered)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
kosmos.activeNotificationListRepository.setActiveNotifs(1)
transitionTo(KeyguardState.LOCKSCREEN, KeyguardState.AOD)
- assertThat(value).isEqualTo(true)
+ assertThat(value).isTrue()
}
@Test
@@ -211,10 +210,10 @@ class KeyguardClockInteractorTest : SysuiTestCase() {
fun clockShouldBeCentered_sceneContainerFlagOn_splitMode_offAod_false() =
testScope.runTest {
val value by collectLastValue(underTest.clockShouldBeCentered)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
kosmos.activeNotificationListRepository.setActiveNotifs(1)
transitionTo(KeyguardState.AOD, KeyguardState.LOCKSCREEN)
- assertThat(value).isEqualTo(false)
+ assertThat(value).isFalse()
}
private suspend fun transitionTo(from: KeyguardState, to: KeyguardState) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt
index 0f5e45814608..8914c80cdd5e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt
@@ -41,6 +41,7 @@ import com.android.systemui.authentication.data.repository.fakeAuthenticationRep
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
+import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
@@ -54,6 +55,9 @@ import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.data.repository.Transition
+import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -208,6 +212,7 @@ class KeyguardOcclusionInteractorTest : SysuiTestCase() {
}
@Test
+ @DisableSceneContainer
fun showWhenLockedActivityLaunchedFromPowerGesture_falseIfReturningToGone() =
testScope.runTest {
val values by collectValues(underTest.showWhenLockedActivityLaunchedFromPowerGesture)
@@ -245,6 +250,42 @@ class KeyguardOcclusionInteractorTest : SysuiTestCase() {
@Test
@EnableSceneContainer
+ fun showWhenLockedActivityLaunchedFromPowerGesture_falseIfReturningToGone_scene_container() =
+ testScope.runTest {
+ val values by collectValues(underTest.showWhenLockedActivityLaunchedFromPowerGesture)
+ powerInteractor.setAwakeForTest()
+ kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
+
+ powerInteractor.setAsleepForTest()
+
+ kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
+ transitionRepository.sendTransitionSteps(
+ from = KeyguardState.UNDEFINED,
+ to = KeyguardState.AOD,
+ testScope = testScope,
+ throughTransitionState = TransitionState.RUNNING
+ )
+
+ powerInteractor.onCameraLaunchGestureDetected()
+ kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true)
+ powerInteractor.setAwakeForTest()
+ runCurrent()
+
+ kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
+ transitionRepository.sendTransitionSteps(
+ from = KeyguardState.AOD,
+ to = KeyguardState.UNDEFINED,
+ testScope = testScope,
+ )
+
+ assertThat(values)
+ .containsExactly(
+ false,
+ )
+ }
+
+ @Test
+ @EnableSceneContainer
fun occludingActivityWillDismissKeyguard() =
testScope.runTest {
val occludingActivityWillDismissKeyguard by
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
index 0f061de5226c..a8eccc5add1a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
@@ -19,7 +19,6 @@ package com.android.systemui.keyguard.domain.interactor
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectValues
import com.android.systemui.flags.DisableSceneContainer
@@ -42,19 +41,15 @@ import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.Transition
-import com.android.systemui.scene.data.repository.sceneContainerRepository
import com.android.systemui.scene.data.repository.setSceneTransition
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import junit.framework.Assert.assertEquals
import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertThrows
-import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -67,36 +62,6 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
val repository = kosmos.fakeKeyguardTransitionRepository
val testScope = kosmos.testScope
- private val sceneTransitions =
- MutableStateFlow<ObservableTransitionState>(
- ObservableTransitionState.Idle(Scenes.Lockscreen)
- )
-
- private val lsToGone =
- ObservableTransitionState.Transition(
- Scenes.Lockscreen,
- Scenes.Gone,
- flowOf(Scenes.Lockscreen),
- flowOf(0f),
- false,
- flowOf(false)
- )
-
- private val goneToLs =
- ObservableTransitionState.Transition(
- Scenes.Gone,
- Scenes.Lockscreen,
- flowOf(Scenes.Lockscreen),
- flowOf(0f),
- false,
- flowOf(false)
- )
-
- @Before
- fun setUp() {
- kosmos.sceneContainerRepository.setTransitionState(sceneTransitions)
- }
-
@Test
fun transitionCollectorsReceivesOnlyAppropriateEvents() =
testScope.runTest {
@@ -318,7 +283,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
@Test
fun isInTransitionToAnyState() =
testScope.runTest {
- val inTransition by collectValues(underTest.isInTransitionToAnyState)
+ val inTransition by collectValues(underTest.isInTransition)
assertEquals(
listOf(
@@ -374,9 +339,50 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
}
@Test
+ @EnableSceneContainer
+ fun isInTransition_withScene() =
+ testScope.runTest {
+ val inTransition by collectValues(underTest.isInTransition)
+
+ assertEquals(
+ listOf(
+ false,
+ true, // The repo is seeded with a transition from OFF to LOCKSCREEN.
+ false,
+ ),
+ inTransition
+ )
+
+ kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Bouncer))
+
+ assertEquals(
+ listOf(
+ false,
+ true,
+ false,
+ true,
+ ),
+ inTransition
+ )
+
+ kosmos.setSceneTransition(Idle(Scenes.Bouncer))
+
+ assertEquals(
+ listOf(
+ false,
+ true,
+ false,
+ true,
+ false,
+ ),
+ inTransition
+ )
+ }
+
+ @Test
fun isInTransitionToAnyState_finishedStateIsStartedStateAfterCancels() =
testScope.runTest {
- val inTransition by collectValues(underTest.isInTransitionToAnyState)
+ val inTransition by collectValues(underTest.isInTransition)
assertEquals(
listOf(
@@ -731,9 +737,15 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
}
@Test
- fun isInTransitionFromStateWhere() =
+ fun isInTransitionWhere() =
testScope.runTest {
- val results by collectValues(underTest.isInTransitionFromStateWhere { it == DOZING })
+ val results by
+ collectValues(
+ underTest.isInTransitionWhere(
+ fromStatePredicate = { it == DOZING },
+ toStatePredicate = { it == GONE },
+ )
+ )
sendSteps(
TransitionStep(AOD, DOZING, 0f, STARTED),
@@ -817,7 +829,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
}
@Test
- fun isInTransitionWhere() =
+ fun isInTransitionWhere_withCanceledStep() =
testScope.runTest {
val results by
collectValues(
@@ -865,7 +877,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
)
sendSteps(
- TransitionStep(DOZING, GONE, 0f, FINISHED),
+ TransitionStep(DOZING, GONE, 0f, CANCELED),
)
assertThat(results)
@@ -873,7 +885,6 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
listOf(
false,
true,
- false,
)
)
@@ -909,15 +920,9 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
}
@Test
- fun isInTransitionWhere_withCanceledStep() =
+ fun isFinishedInStateWhere() =
testScope.runTest {
- val results by
- collectValues(
- underTest.isInTransitionWhere(
- fromStatePredicate = { it == DOZING },
- toStatePredicate = { it == GONE },
- )
- )
+ val results by collectValues(underTest.isFinishedInStateWhere { it == GONE })
sendSteps(
TransitionStep(AOD, DOZING, 0f, STARTED),
@@ -928,37 +933,29 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
assertThat(results)
.isEqualTo(
listOf(
- false,
+ false, // Finished in DOZING, not GONE.
)
)
- sendSteps(
- TransitionStep(DOZING, GONE, 0f, STARTED),
- )
+ sendSteps(TransitionStep(DOZING, GONE, 0f, STARTED))
assertThat(results)
.isEqualTo(
listOf(
false,
- true,
)
)
- sendSteps(
- TransitionStep(DOZING, GONE, 0f, RUNNING),
- )
+ sendSteps(TransitionStep(DOZING, GONE, 0f, RUNNING))
assertThat(results)
.isEqualTo(
listOf(
false,
- true,
)
)
- sendSteps(
- TransitionStep(DOZING, GONE, 0f, CANCELED),
- )
+ sendSteps(TransitionStep(DOZING, GONE, 1f, FINISHED))
assertThat(results)
.isEqualTo(
@@ -971,7 +968,6 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
sendSteps(
TransitionStep(GONE, DOZING, 0f, STARTED),
TransitionStep(GONE, DOZING, 0f, RUNNING),
- TransitionStep(GONE, DOZING, 1f, FINISHED),
)
assertThat(results)
@@ -979,6 +975,16 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
listOf(
false,
true,
+ )
+ )
+
+ sendSteps(TransitionStep(GONE, DOZING, 1f, FINISHED))
+
+ assertThat(results)
+ .isEqualTo(
+ listOf(
+ false,
+ true,
false,
)
)
@@ -994,15 +1000,27 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
false,
true,
false,
+ )
+ )
+
+ sendSteps(TransitionStep(DOZING, GONE, 1f, FINISHED))
+
+ assertThat(results)
+ .isEqualTo(
+ listOf(
+ false,
+ true,
+ false,
true,
)
)
}
@Test
- fun isFinishedInStateWhere() =
+ @DisableSceneContainer
+ fun isFinishedInState() =
testScope.runTest {
- val results by collectValues(underTest.isFinishedInStateWhere { it == GONE })
+ val results by collectValues(underTest.isFinishedIn(Scenes.Gone, GONE))
sendSteps(
TransitionStep(AOD, DOZING, 0f, STARTED),
@@ -1097,9 +1115,10 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
}
@Test
- fun isFinishedInState() =
+ @EnableSceneContainer
+ fun isFinishedIn() =
testScope.runTest {
- val results by collectValues(underTest.isFinishedInState(GONE))
+ val results by collectValues(underTest.isFinishedIn(Scenes.Gone, GONE))
sendSteps(
TransitionStep(AOD, DOZING, 0f, STARTED),
@@ -1114,16 +1133,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
)
)
- sendSteps(TransitionStep(DOZING, GONE, 0f, STARTED))
-
- assertThat(results)
- .isEqualTo(
- listOf(
- false,
- )
- )
-
- sendSteps(TransitionStep(DOZING, GONE, 0f, RUNNING))
+ kosmos.setSceneTransition(Transition(from = Scenes.Lockscreen, to = Scenes.Gone))
assertThat(results)
.isEqualTo(
@@ -1132,7 +1142,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
)
)
- sendSteps(TransitionStep(DOZING, GONE, 1f, FINISHED))
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
assertThat(results)
.isEqualTo(
@@ -1142,10 +1152,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
)
)
- sendSteps(
- TransitionStep(GONE, DOZING, 0f, STARTED),
- TransitionStep(GONE, DOZING, 0f, RUNNING),
- )
+ kosmos.setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen))
assertThat(results)
.isEqualTo(
@@ -1155,7 +1162,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
)
)
- sendSteps(TransitionStep(GONE, DOZING, 1f, FINISHED))
+ kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
assertThat(results)
.isEqualTo(
@@ -1166,10 +1173,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
)
)
- sendSteps(
- TransitionStep(DOZING, GONE, 0f, STARTED),
- TransitionStep(DOZING, GONE, 0f, RUNNING),
- )
+ kosmos.setSceneTransition(Transition(from = Scenes.Lockscreen, to = Scenes.Gone))
assertThat(results)
.isEqualTo(
@@ -1180,7 +1184,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
)
)
- sendSteps(TransitionStep(DOZING, GONE, 1f, FINISHED))
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
assertThat(results)
.isEqualTo(
@@ -1515,7 +1519,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
val currentStatesConverted by
collectValues(underTest.transition(Edge.create(LOCKSCREEN, UNDEFINED)))
- sceneTransitions.value = lsToGone
+ kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
@@ -1531,7 +1535,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
testScope.runTest {
val currentStates by collectValues(underTest.transition(Edge.create(LOCKSCREEN, GONE)))
- sceneTransitions.value = goneToLs
+ kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
@@ -1547,7 +1551,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
val currentStates by
collectValues(underTest.transition(Edge.create(LOCKSCREEN, DOZING)))
- sceneTransitions.value = goneToLs
+ kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
val sendStep1 = TransitionStep(LOCKSCREEN, DOZING, 0f, STARTED)
val sendStep2 = TransitionStep(LOCKSCREEN, DOZING, 1f, FINISHED)
val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
@@ -1564,7 +1568,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
val currentStatesReversed by
collectValues(underTest.transition(Edge.create(null, LOCKSCREEN)))
- sceneTransitions.value = goneToLs
+ kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
val sendStep1 = TransitionStep(LOCKSCREEN, DOZING, 0f, STARTED)
val sendStep2 = TransitionStep(LOCKSCREEN, DOZING, 1f, FINISHED)
val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
@@ -1582,7 +1586,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
val currentStates by collectValues(underTest.transition(Edge.create(null, UNDEFINED)))
val currentStatesMapped by collectValues(underTest.transition(Edge.create(null, GONE)))
- sceneTransitions.value = lsToGone
+ kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
val sendStep3 = TransitionStep(UNDEFINED, AOD, 0f, STARTED)
@@ -1599,7 +1603,7 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
testScope.runTest {
val currentStatesMapped by collectValues(underTest.transition(Edge.create(null, GONE)))
- sceneTransitions.value = goneToLs
+ kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
val sendStep3 = TransitionStep(UNDEFINED, AOD, 0f, STARTED)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/shared/model/KeyguardStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/shared/model/KeyguardStateTest.kt
new file mode 100644
index 000000000000..f1ffe66ec2bb
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/shared/model/KeyguardStateTest.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.keyguard.shared.model
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.EnableSceneContainer
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class KeyguardStateTest : SysuiTestCase() {
+
+ /**
+ * This test makes sure that the result of [deviceIsAwakeInState] are equal for all the states
+ * that are obsolete with scene container enabled and UNDEFINED. This means for example that if
+ * GONE is transformed to UNDEFINED it makes sure that GONE and UNDEFINED need to have the same
+ * value. This assumption is important as with scene container flag enabled call sites will only
+ * check the result passing in UNDEFINED.
+ *
+ * This is true today, but as more states may become obsolete this assumption may not be true
+ * anymore and therefore [deviceIsAwakeInState] would need to be rewritten to factor in the
+ * scene state.
+ */
+ @Test
+ @EnableSceneContainer
+ fun assertUndefinedResultMatchesObsoleteStateResults() {
+ for (state in KeyguardState.entries) {
+ val isAwakeInSceneContainer =
+ KeyguardState.deviceIsAwakeInState(state.mapToSceneContainerState())
+ val isAwake = KeyguardState.deviceIsAwakeInState(state)
+ assertThat(isAwakeInSceneContainer).isEqualTo(isAwake)
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
index de4b999b3899..3075c54fb069 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
@@ -14,8 +14,11 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
package com.android.systemui.keyguard.ui.viewmodel
+import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -27,17 +30,22 @@ import com.android.systemui.flags.Flags
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository
+import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
import com.android.systemui.keyguard.shared.model.ClockSize
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.shared.model.ShadeMode
+import com.android.systemui.shade.shared.flag.DualShade
import com.android.systemui.testKosmos
import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import java.util.Locale
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -69,7 +77,7 @@ class LockscreenContentViewModelTest(flags: FlagsParameterization) : SysuiTestCa
fun setup() {
with(kosmos) {
fakeFeatureFlagsClassic.set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, true)
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
underTest = lockscreenContentViewModel
}
}
@@ -118,8 +126,51 @@ class LockscreenContentViewModelTest(flags: FlagsParameterization) : SysuiTestCa
fun areNotificationsVisible_splitShadeTrue_true() =
with(kosmos) {
testScope.runTest {
- val areNotificationsVisible by collectLastValue(underTest.areNotificationsVisible)
- shadeRepository.setShadeMode(ShadeMode.Split)
+ val areNotificationsVisible by
+ collectLastValue(underTest.areNotificationsVisible(Scenes.Lockscreen))
+ shadeRepository.setShadeLayoutWide(true)
+ fakeKeyguardClockRepository.setClockSize(ClockSize.LARGE)
+
+ assertThat(areNotificationsVisible).isTrue()
+ }
+ }
+
+ @Test
+ @EnableFlags(DualShade.FLAG_NAME)
+ fun areNotificationsVisible_dualShadeWideOnLockscreen_true() =
+ with(kosmos) {
+ testScope.runTest {
+ val areNotificationsVisible by
+ collectLastValue(underTest.areNotificationsVisible(Scenes.Lockscreen))
+ shadeRepository.setShadeLayoutWide(true)
+ fakeKeyguardClockRepository.setClockSize(ClockSize.LARGE)
+
+ assertThat(areNotificationsVisible).isTrue()
+ }
+ }
+
+ @Test
+ @EnableFlags(DualShade.FLAG_NAME)
+ fun areNotificationsVisible_dualShadeWideOnNotificationsShade_false() =
+ with(kosmos) {
+ testScope.runTest {
+ val areNotificationsVisible by
+ collectLastValue(underTest.areNotificationsVisible(Scenes.NotificationsShade))
+ shadeRepository.setShadeLayoutWide(true)
+ fakeKeyguardClockRepository.setClockSize(ClockSize.LARGE)
+
+ assertThat(areNotificationsVisible).isFalse()
+ }
+ }
+
+ @Test
+ @EnableFlags(DualShade.FLAG_NAME)
+ fun areNotificationsVisible_dualShadeWideOnQuickSettingsShade_true() =
+ with(kosmos) {
+ testScope.runTest {
+ val areNotificationsVisible by
+ collectLastValue(underTest.areNotificationsVisible(Scenes.QuickSettingsShade))
+ shadeRepository.setShadeLayoutWide(true)
fakeKeyguardClockRepository.setClockSize(ClockSize.LARGE)
assertThat(areNotificationsVisible).isTrue()
@@ -131,7 +182,8 @@ class LockscreenContentViewModelTest(flags: FlagsParameterization) : SysuiTestCa
fun areNotificationsVisible_withSmallClock_true() =
with(kosmos) {
testScope.runTest {
- val areNotificationsVisible by collectLastValue(underTest.areNotificationsVisible)
+ val areNotificationsVisible by
+ collectLastValue(underTest.areNotificationsVisible(Scenes.Lockscreen))
fakeKeyguardClockRepository.setClockSize(ClockSize.SMALL)
assertThat(areNotificationsVisible).isTrue()
}
@@ -142,31 +194,32 @@ class LockscreenContentViewModelTest(flags: FlagsParameterization) : SysuiTestCa
fun areNotificationsVisible_withLargeClock_false() =
with(kosmos) {
testScope.runTest {
- val areNotificationsVisible by collectLastValue(underTest.areNotificationsVisible)
+ val areNotificationsVisible by
+ collectLastValue(underTest.areNotificationsVisible(Scenes.Lockscreen))
fakeKeyguardClockRepository.setClockSize(ClockSize.LARGE)
assertThat(areNotificationsVisible).isFalse()
}
}
@Test
- fun shouldUseSplitNotificationShade_withConfigTrue_true() =
+ fun isShadeLayoutWide_withConfigTrue_true() =
with(kosmos) {
testScope.runTest {
- val shouldUseSplitNotificationShade by
- collectLastValue(underTest.shouldUseSplitNotificationShade)
- shadeRepository.setShadeMode(ShadeMode.Split)
- assertThat(shouldUseSplitNotificationShade).isTrue()
+ val isShadeLayoutWide by collectLastValue(underTest.isShadeLayoutWide)
+ shadeRepository.setShadeLayoutWide(true)
+
+ assertThat(isShadeLayoutWide).isTrue()
}
}
@Test
- fun shouldUseSplitNotificationShade_withConfigFalse_false() =
+ fun isShadeLayoutWide_withConfigFalse_false() =
with(kosmos) {
testScope.runTest {
- val shouldUseSplitNotificationShade by
- collectLastValue(underTest.shouldUseSplitNotificationShade)
- shadeRepository.setShadeMode(ShadeMode.Single)
- assertThat(shouldUseSplitNotificationShade).isFalse()
+ val isShadeLayoutWide by collectLastValue(underTest.isShadeLayoutWide)
+ shadeRepository.setShadeLayoutWide(false)
+
+ assertThat(isShadeLayoutWide).isFalse()
}
}
@@ -201,6 +254,44 @@ class LockscreenContentViewModelTest(flags: FlagsParameterization) : SysuiTestCa
}
}
+ @Test
+ fun isContentVisible_whenNotOccluded_visible() =
+ with(kosmos) {
+ testScope.runTest {
+ val isContentVisible by collectLastValue(underTest.isContentVisible)
+
+ keyguardOcclusionRepository.setShowWhenLockedActivityInfo(false, null)
+ runCurrent()
+ assertThat(isContentVisible).isTrue()
+ }
+ }
+
+ @Test
+ fun isContentVisible_whenOccluded_notVisible() =
+ with(kosmos) {
+ testScope.runTest {
+ val isContentVisible by collectLastValue(underTest.isContentVisible)
+
+ keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, null)
+ runCurrent()
+ assertThat(isContentVisible).isFalse()
+ }
+ }
+
+ @Test
+ fun isContentVisible_whenOccluded_notVisible_evenIfShadeShown() =
+ with(kosmos) {
+ testScope.runTest {
+ val isContentVisible by collectLastValue(underTest.isContentVisible)
+ keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, null)
+ runCurrent()
+
+ sceneInteractor.snapToScene(Scenes.Shade, "")
+ runCurrent()
+ assertThat(isContentVisible).isFalse()
+ }
+ }
+
private fun prepareConfiguration(): Int {
val configuration = context.resources.configuration
configuration.setLayoutDirection(Locale.US)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index 4eb146dbbaba..3db9ef1eca71 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -44,7 +44,6 @@ import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.TransitionKeys
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.domain.interactor.shadeInteractor
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.mock
@@ -182,13 +181,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
}
)
sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
- kosmos.shadeRepository.setShadeMode(
- if (isSingleShade) {
- ShadeMode.Single
- } else {
- ShadeMode.Split
- }
- )
+ kosmos.shadeRepository.setShadeLayoutWide(!isSingleShade)
kosmos.setCommunalAvailable(isCommunalAvailable)
kosmos.fakePowerRepository.updateWakefulness(
rawState =
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 0551bfb89865..067b00c1658b 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
@@ -33,13 +33,14 @@ 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
-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
@@ -48,12 +49,16 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers
import org.mockito.Mockito
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.never
+import org.mockito.kotlin.reset
+import org.mockito.kotlin.verify
@SmallTest
@RunWith(AndroidJUnit4::class)
class MediaCarouselViewModelTest : SysuiTestCase() {
- private val kosmos = testKosmos()
+ private val kosmos = testKosmos().apply { mediaLogger = mockMediaLogger }
private val testScope = kosmos.testScope
private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
@@ -166,6 +171,64 @@ class MediaCarouselViewModelTest : SysuiTestCase() {
assertThat(mediaControl.isMediaFromRec).isTrue()
}
+ @Test
+ fun addMediaControlThenRemove_mediaEventsAreLogged() =
+ testScope.runTest {
+ val sortedMedia by collectLastValue(underTest.mediaItems)
+ val instanceId = InstanceId.fakeInstanceId(123)
+
+ loadMediaControl(KEY, instanceId)
+
+ val mediaControl = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl
+ assertThat(mediaControl.instanceId).isEqualTo(instanceId)
+
+ // when media control is added to carousel
+ mediaControl.onAdded(mediaControl)
+
+ verify(kosmos.mediaLogger).logMediaCardAdded(eq(instanceId))
+
+ reset(kosmos.mediaLogger)
+
+ // when media control is updated.
+ mediaControl.onUpdated(mediaControl)
+
+ verify(kosmos.mediaLogger, never()).logMediaCardAdded(eq(instanceId))
+
+ mediaDataFilter.onMediaDataRemoved(KEY, true)
+ assertThat(sortedMedia).isEmpty()
+
+ // when media control is removed from carousel
+ mediaControl.onRemoved(true)
+
+ verify(kosmos.mediaLogger).logMediaCardRemoved(eq(instanceId))
+ }
+
+ @Test
+ fun addMediaRecommendationThenRemove_mediaEventsAreLogged() =
+ testScope.runTest {
+ val sortedMedia by collectLastValue(underTest.mediaItems)
+ kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false)
+
+ 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)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/SettingObserverTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/SettingObserverTest.kt
new file mode 100644
index 000000000000..188f2aca5147
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/SettingObserverTest.kt
@@ -0,0 +1,117 @@
+/*
+ * 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.qs
+
+import android.net.Uri
+import android.os.Handler
+import android.os.Looper
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+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.util.settings.SettingsProxy
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.capture
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.reset
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SettingObserverTest : SysuiTestCase() {
+
+ private val DEFAULT_VALUE = 7
+
+ @Mock lateinit var settingsProxy: SettingsProxy
+ @Captor private lateinit var argumentCaptor: ArgumentCaptor<Runnable>
+
+ private lateinit var testSettingObserver: SettingObserver
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ whenever(settingsProxy.getInt(any(), any())).thenReturn(5)
+ whenever(settingsProxy.getUriFor(any())).thenReturn(Uri.parse("content://test_uri"))
+ testSettingObserver =
+ object :
+ SettingObserver(
+ settingsProxy,
+ Handler(Looper.getMainLooper()),
+ "test_setting",
+ DEFAULT_VALUE
+ ) {
+ override fun handleValueChanged(value: Int, observedChange: Boolean) {}
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_QS_REGISTER_SETTING_OBSERVER_ON_BG_THREAD)
+ fun setListening_true_settingsProxyRegistered() {
+ testSettingObserver.isListening = true
+ verify(settingsProxy)
+ .registerContentObserverAsync(
+ any<Uri>(),
+ eq(false),
+ eq(testSettingObserver),
+ capture(argumentCaptor)
+ )
+ assertThat(testSettingObserver.value).isEqualTo(5)
+
+ // Verify if the callback applies updated value after the fact
+ whenever(settingsProxy.getInt(any(), any())).thenReturn(12341234)
+ argumentCaptor.value.run()
+ assertThat(testSettingObserver.value).isEqualTo(12341234)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_QS_REGISTER_SETTING_OBSERVER_ON_BG_THREAD)
+ fun setListening_false_settingsProxyRegistered() {
+ testSettingObserver.isListening = true
+ reset(settingsProxy)
+ testSettingObserver.isListening = false
+
+ verify(settingsProxy).unregisterContentObserverAsync(eq(testSettingObserver))
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_QS_REGISTER_SETTING_OBSERVER_ON_BG_THREAD)
+ fun setListening_bgFlagDisabled_true_settingsProxyRegistered() {
+ testSettingObserver.isListening = true
+ verify(settingsProxy)
+ .registerContentObserverSync(any<Uri>(), eq(false), eq(testSettingObserver))
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_QS_REGISTER_SETTING_OBSERVER_ON_BG_THREAD)
+ fun setListening_bgFlagDisabled_false_settingsProxyRegistered() {
+ testSettingObserver.isListening = true
+ reset(settingsProxy)
+ testSettingObserver.isListening = false
+
+ verify(settingsProxy).unregisterContentObserverSync(eq(testSettingObserver))
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryTest.kt
index 8ac5b6c09e73..dda9cd5529a5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryTest.kt
@@ -24,6 +24,7 @@ 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.qs.pipeline.shared.TileSpec
import com.android.systemui.settings.userFileManager
import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.fakeUserRepository
@@ -40,6 +41,70 @@ class QSPreferencesRepositoryTest : SysuiTestCase() {
private val underTest = with(kosmos) { qsPreferencesRepository }
@Test
+ fun largeTilesSpecs_updatesFromSharedPreferences() =
+ with(kosmos) {
+ testScope.runTest {
+ val latest by collectLastValue(underTest.largeTilesSpecs)
+ assertThat(latest).isEqualTo(defaultLargeTilesRepository.defaultLargeTiles)
+
+ val newSet = setOf("tileA", "tileB")
+ setLargeTilesSpecsInSharedPreferences(newSet)
+ assertThat(latest).isEqualTo(newSet.toTileSpecs())
+ }
+ }
+
+ @Test
+ fun largeTilesSpecs_updatesFromUserChange() =
+ with(kosmos) {
+ testScope.runTest {
+ fakeUserRepository.setUserInfos(USERS)
+ val latest by collectLastValue(underTest.largeTilesSpecs)
+
+ fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
+ val newSet = setOf("tileA", "tileB")
+ setLargeTilesSpecsInSharedPreferences(newSet)
+
+ fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
+ setLargeTilesSpecsInSharedPreferences(emptySet())
+
+ fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
+ assertThat(latest).isEqualTo(newSet.toTileSpecs())
+ }
+ }
+
+ @Test
+ fun setLargeTilesSpecs_inSharedPreferences() {
+ val setA = setOf("tileA", "tileB")
+ underTest.setLargeTilesSpecs(setA.toTileSpecs())
+ assertThat(getLargeTilesSpecsFromSharedPreferences()).isEqualTo(setA)
+
+ val setB = setOf("tileA", "tileB")
+ underTest.setLargeTilesSpecs(setB.toTileSpecs())
+ assertThat(getLargeTilesSpecsFromSharedPreferences()).isEqualTo(setB)
+ }
+
+ @Test
+ fun setLargeTilesSpecs_forDifferentUser() =
+ with(kosmos) {
+ testScope.runTest {
+ fakeUserRepository.setUserInfos(USERS)
+
+ fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
+ val setA = setOf("tileA", "tileB")
+ underTest.setLargeTilesSpecs(setA.toTileSpecs())
+ assertThat(getLargeTilesSpecsFromSharedPreferences()).isEqualTo(setA)
+
+ fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
+ val setB = setOf("tileA", "tileB")
+ underTest.setLargeTilesSpecs(setB.toTileSpecs())
+ assertThat(getLargeTilesSpecsFromSharedPreferences()).isEqualTo(setB)
+
+ fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
+ assertThat(getLargeTilesSpecsFromSharedPreferences()).isEqualTo(setA)
+ }
+ }
+
+ @Test
fun showLabels_updatesFromSharedPreferences() =
with(kosmos) {
testScope.runTest {
@@ -109,6 +174,14 @@ class QSPreferencesRepositoryTest : SysuiTestCase() {
)
}
+ private fun setLargeTilesSpecsInSharedPreferences(specs: Set<String>) {
+ getSharedPreferences().edit().putStringSet(LARGE_TILES_SPECS_KEY, specs).apply()
+ }
+
+ private fun getLargeTilesSpecsFromSharedPreferences(): Set<String> {
+ return getSharedPreferences().getStringSet(LARGE_TILES_SPECS_KEY, emptySet())!!
+ }
+
private fun setShowLabelsInSharedPreferences(value: Boolean) {
getSharedPreferences().edit().putBoolean(ICON_LABELS_KEY, value).apply()
}
@@ -117,8 +190,13 @@ class QSPreferencesRepositoryTest : SysuiTestCase() {
return getSharedPreferences().getBoolean(ICON_LABELS_KEY, defaultValue)
}
+ private fun Set<String>.toTileSpecs(): Set<TileSpec> {
+ return map { TileSpec.create(it) }.toSet()
+ }
+
companion object {
private const val ICON_LABELS_KEY = "show_icon_labels"
+ private const val LARGE_TILES_SPECS_KEY = "large_tiles_specs"
private const val PRIMARY_USER_ID = 0
private val PRIMARY_USER = UserInfo(PRIMARY_USER_ID, "user 0", UserInfo.FLAG_MAIN)
private const val ANOTHER_USER_ID = 1
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryTest.kt
new file mode 100644
index 000000000000..ae6f576bcf3e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryTest.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.qs.panels.data.repository
+
+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.fakeConfigurationRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class QuickQuickSettingsRowRepositoryTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+
+ private val underTest = kosmos.quickQuickSettingsRowRepository
+
+ @Test
+ fun rows_followsConfig() =
+ with(kosmos) {
+ testScope.runTest {
+ val rows by collectLastValue(underTest.rows)
+
+ setRowsInConfig(2)
+ assertThat(rows).isEqualTo(2)
+
+ setRowsInConfig(3)
+ assertThat(rows).isEqualTo(3)
+ }
+ }
+
+ private fun setRowsInConfig(rows: Int) =
+ with(kosmos) {
+ testCase.context.orCreateTestableResources.addOverride(
+ R.integer.quick_qs_panel_max_rows,
+ rows,
+ )
+ fakeConfigurationRepository.onConfigurationChange()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt
index b206f56f95a6..56b3679b6835 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt
@@ -20,9 +20,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.panels.data.repository.IconTilesRepository
+import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepository
+import com.android.systemui.qs.panels.data.repository.defaultLargeTilesRepository
import com.android.systemui.qs.panels.data.repository.gridLayoutTypeRepository
-import com.android.systemui.qs.panels.data.repository.iconTilesRepository
import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType
import com.android.systemui.qs.panels.shared.model.PartitionedGridLayoutType
import com.android.systemui.qs.pipeline.data.repository.tileSpecRepository
@@ -42,22 +42,17 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class GridConsistencyInteractorTest : SysuiTestCase() {
- private val iconOnlyTiles =
- setOf(
- TileSpec.create("smallA"),
- TileSpec.create("smallB"),
- TileSpec.create("smallC"),
- TileSpec.create("smallD"),
- TileSpec.create("smallE"),
- )
-
private val kosmos =
testKosmos().apply {
- iconTilesRepository =
- object : IconTilesRepository {
- override fun isIconTile(spec: TileSpec): Boolean {
- return iconOnlyTiles.contains(spec)
- }
+ defaultLargeTilesRepository =
+ object : DefaultLargeTilesRepository {
+ override val defaultLargeTiles =
+ setOf(
+ TileSpec.create("largeA"),
+ TileSpec.create("largeB"),
+ TileSpec.create("largeC"),
+ TileSpec.create("largeD"),
+ )
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorTest.kt
new file mode 100644
index 000000000000..c3a5df06e2a4
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorTest.kt
@@ -0,0 +1,86 @@
+/*
+ * 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.qs.panels.domain.interactor
+
+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.qs.panels.data.repository.DefaultLargeTilesRepository
+import com.android.systemui.qs.panels.data.repository.defaultLargeTilesRepository
+import com.android.systemui.qs.panels.data.repository.qsPreferencesRepository
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class IconTilesInteractorTest : SysuiTestCase() {
+ private val kosmos =
+ testKosmos().apply {
+ defaultLargeTilesRepository =
+ object : DefaultLargeTilesRepository {
+ override val defaultLargeTiles: Set<TileSpec> = setOf(TileSpec.create("large"))
+ }
+ }
+ private val underTest = with(kosmos) { iconTilesInteractor }
+
+ @Test
+ fun isIconTile_returnsCorrectValue() {
+ assertThat(underTest.isIconTile(TileSpec.create("large"))).isFalse()
+ assertThat(underTest.isIconTile(TileSpec.create("small"))).isTrue()
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun isIconTile_updatesFromSharedPreferences() =
+ with(kosmos) {
+ testScope.runTest {
+ // Assert that new tile defaults to icon
+ assertThat(underTest.isIconTile(TileSpec.create("newTile"))).isTrue()
+
+ qsPreferencesRepository.setLargeTilesSpecs(setOf(TileSpec.create("newTile")))
+ runCurrent()
+
+ // Assert that the new tile was added to the large tiles set
+ assertThat(underTest.isIconTile(TileSpec.create("newTile"))).isFalse()
+ }
+ }
+
+ @Test
+ fun resize_updatesSharedPreferences() =
+ with(kosmos) {
+ testScope.runTest {
+ val latest by collectLastValue(qsPreferencesRepository.largeTilesSpecs)
+ val spec = TileSpec.create("large")
+
+ // Assert that the tile is added to the large tiles after resizing
+ underTest.resize(spec, toIcon = false)
+ assertThat(latest).contains(spec)
+
+ // Assert that the tile is removed from the large tiles after resizing
+ underTest.resize(spec, toIcon = true)
+ assertThat(latest).doesNotContain(spec)
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt
index 1e2e82ffeca5..ea51398e6256 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt
@@ -20,8 +20,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.panels.data.repository.IconTilesRepository
-import com.android.systemui.qs.panels.data.repository.iconTilesRepository
+import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepository
+import com.android.systemui.qs.panels.data.repository.defaultLargeTilesRepository
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -33,21 +33,17 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class InfiniteGridConsistencyInteractorTest : SysuiTestCase() {
- private val iconOnlyTiles =
- setOf(
- TileSpec.create("smallA"),
- TileSpec.create("smallB"),
- TileSpec.create("smallC"),
- TileSpec.create("smallD"),
- TileSpec.create("smallE"),
- )
private val kosmos =
testKosmos().apply {
- iconTilesRepository =
- object : IconTilesRepository {
- override fun isIconTile(spec: TileSpec): Boolean {
- return iconOnlyTiles.contains(spec)
- }
+ defaultLargeTilesRepository =
+ object : DefaultLargeTilesRepository {
+ override val defaultLargeTiles: Set<TileSpec> =
+ setOf(
+ TileSpec.create("largeA"),
+ TileSpec.create("largeB"),
+ TileSpec.create("largeC"),
+ TileSpec.create("largeD"),
+ )
}
}
private val underTest = with(kosmos) { infiniteGridConsistencyInteractor }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt
index 1c3021ef5839..73a00395606e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt
@@ -82,6 +82,20 @@ class DragAndDropStateTest : SysuiTestCase() {
TestEditTiles.forEach { assertThat(underTest.isMoving(it.tileSpec)).isFalse() }
}
+ @Test
+ fun onMoveOutOfBounds_removeMovingTileFromCurrentList() {
+ val movingTileSpec = TestEditTiles[0].tileSpec
+
+ // Start the drag movement
+ underTest.onStarted(movingTileSpec)
+
+ // Move the tile outside of the list
+ underTest.movedOutOfBounds()
+
+ // Asserts the moving tile is not current
+ assertThat(listState.tiles.first { it.tileSpec == movingTileSpec }.isCurrent).isFalse()
+ }
+
companion object {
private fun createEditTile(tileSpec: String): EditTileViewModel {
return EditTileViewModel(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt
index 914a09597d65..53384afb66be 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt
@@ -20,8 +20,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.panels.data.repository.IconTilesRepository
-import com.android.systemui.qs.panels.data.repository.iconTilesRepository
+import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepository
+import com.android.systemui.qs.panels.data.repository.defaultLargeTilesRepository
import com.android.systemui.qs.panels.ui.viewmodel.MockTileViewModel
import com.android.systemui.qs.panels.ui.viewmodel.fixedColumnsSizeViewModel
import com.android.systemui.qs.panels.ui.viewmodel.iconTilesViewModel
@@ -37,11 +37,9 @@ import org.junit.runner.RunWith
class InfiniteGridLayoutTest : SysuiTestCase() {
private val kosmos =
testKosmos().apply {
- iconTilesRepository =
- object : IconTilesRepository {
- override fun isIconTile(spec: TileSpec): Boolean {
- return spec.spec.startsWith("small")
- }
+ defaultLargeTilesRepository =
+ object : DefaultLargeTilesRepository {
+ override val defaultLargeTiles: Set<TileSpec> = setOf(TileSpec.create("large"))
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayoutTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayoutTest.kt
index 3354b4d4116b..55b7454fa2c1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayoutTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayoutTest.kt
@@ -20,8 +20,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.panels.data.repository.IconTilesRepository
-import com.android.systemui.qs.panels.data.repository.iconTilesRepository
+import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepository
+import com.android.systemui.qs.panels.data.repository.defaultLargeTilesRepository
import com.android.systemui.qs.panels.ui.viewmodel.MockTileViewModel
import com.android.systemui.qs.panels.ui.viewmodel.iconTilesViewModel
import com.android.systemui.qs.panels.ui.viewmodel.partitionedGridViewModel
@@ -37,11 +37,9 @@ import org.junit.runner.RunWith
class PartitionedGridLayoutTest : SysuiTestCase() {
private val kosmos =
testKosmos().apply {
- iconTilesRepository =
- object : IconTilesRepository {
- override fun isIconTile(spec: TileSpec): Boolean {
- return spec.spec.startsWith("small")
- }
+ defaultLargeTilesRepository =
+ object : DefaultLargeTilesRepository {
+ override val defaultLargeTiles: Set<TileSpec> = setOf(TileSpec.create("large"))
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
index 8b49d4361d48..601779f8fb02 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
@@ -54,8 +54,10 @@ import com.android.systemui.qs.tiles.viewmodel.qSTileConfigProvider
import com.android.systemui.settings.userTracker
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -103,9 +105,7 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
appName2,
)
- private val underTest: EditModeViewModel by lazy {
- kosmos.editModeViewModel
- }
+ private val underTest: EditModeViewModel by lazy { kosmos.editModeViewModel }
@Before
fun setUp() {
@@ -461,31 +461,87 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
}
@Test
- fun tileNotAvailable_notShowing() = with(kosmos) {
- testScope.runTest {
- val unavailableTile = "work"
- qsTileFactory = FakeQSFactory { spec ->
- FakeQSTile(userTracker.userId, spec != unavailableTile)
+ fun tileNotAvailable_notShowing() =
+ with(kosmos) {
+ testScope.runTest {
+ val unavailableTile = "work"
+ qsTileFactory = FakeQSFactory { spec ->
+ FakeQSTile(userTracker.userId, spec != unavailableTile)
+ }
+ tileAvailabilityInteractorsMap =
+ mapOf(
+ unavailableTile to
+ FakeTileAvailabilityInteractor(
+ emptyMap<Int, Flow<Boolean>>().withDefault { flowOf(false) }
+ )
+ )
+ val tiles by collectLastValue(underTest.tiles)
+ val currentTiles =
+ mutableListOf(
+ TileSpec.create("flashlight"),
+ TileSpec.create("airplane"),
+ TileSpec.create("alarm"),
+ )
+ currentTilesInteractor.setTiles(currentTiles)
+
+ underTest.startEditing()
+
+ assertThat(tiles!!.none { it.tileSpec == TileSpec.create(unavailableTile) })
+ .isTrue()
}
- tileAvailabilityInteractorsMap = mapOf(
- unavailableTile to FakeTileAvailabilityInteractor(
- emptyMap<Int, Flow<Boolean>>().withDefault { flowOf(false) }
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun currentTiles_moveTileDown() =
+ with(kosmos) {
+ testScope.runTest {
+ val tiles by collectLastValue(underTest.tiles)
+ val currentTiles =
+ mutableListOf(
+ TileSpec.create("flashlight"),
+ TileSpec.create("airplane"),
+ TileSpec.create("internet"),
+ TileSpec.create("alarm"),
)
- )
- val tiles by collectLastValue(underTest.tiles)
- val currentTiles =
+ currentTilesInteractor.setTiles(currentTiles)
+ underTest.startEditing()
+ runCurrent()
+
+ // Move flashlight tile to index 3
+ underTest.addTile(TileSpec.create("flashlight"), 3)
+
+ assertThat(tiles!!.filter { it.isCurrent }.map { it.tileSpec.spec })
+ .containsExactly("airplane", "internet", "alarm", "flashlight")
+ .inOrder()
+ }
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun currentTiles_moveTileUp() =
+ with(kosmos) {
+ testScope.runTest {
+ val tiles by collectLastValue(underTest.tiles)
+ val currentTiles =
mutableListOf(
- TileSpec.create("flashlight"),
- TileSpec.create("airplane"),
- TileSpec.create("alarm"),
+ TileSpec.create("flashlight"),
+ TileSpec.create("airplane"),
+ TileSpec.create("internet"),
+ TileSpec.create("alarm"),
)
- currentTilesInteractor.setTiles(currentTiles)
+ currentTilesInteractor.setTiles(currentTiles)
+ underTest.startEditing()
+ runCurrent()
- underTest.startEditing()
+ // Move alarm tile to index 0
+ underTest.addTile(TileSpec.create("alarm"), 0)
- assertThat(tiles!!.none { it.tileSpec == TileSpec.create(unavailableTile) }).isTrue()
+ assertThat(tiles!!.filter { it.isCurrent }.map { it.tileSpec.spec })
+ .containsExactly("alarm", "flashlight", "airplane", "internet")
+ .inOrder()
+ }
}
- }
companion object {
private val drawable1 = TestStubDrawable("drawable1")
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
new file mode 100644
index 000000000000..56156a8e6e61
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
@@ -0,0 +1,162 @@
+/*
+ * 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.qs.panels.ui.viewmodel
+
+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.fakeConfigurationRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepository
+import com.android.systemui.qs.panels.data.repository.defaultLargeTilesRepository
+import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class QuickQuickSettingsViewModelTest : SysuiTestCase() {
+
+ private val tiles =
+ listOf(
+ "$PREFIX_SMALL:1",
+ "$PREFIX_SMALL:2",
+ "$PREFIX_LARGE:3",
+ "$PREFIX_SMALL:4",
+ "$PREFIX_LARGE:5",
+ "$PREFIX_LARGE:6",
+ "$PREFIX_SMALL:7",
+ "$PREFIX_SMALL:8",
+ "$PREFIX_LARGE:9",
+ )
+ .map(TileSpec::create)
+
+ private val kosmos =
+ testKosmos().apply {
+ defaultLargeTilesRepository =
+ object : DefaultLargeTilesRepository {
+ override val defaultLargeTiles: Set<TileSpec> =
+ tiles.filter { it.spec.startsWith(PREFIX_LARGE) }.toSet()
+ }
+ }
+
+ private val underTest = kosmos.quickQuickSettingsViewModel
+
+ @Before
+ fun setUp() {
+ kosmos.setTiles(tiles)
+ }
+
+ @Test
+ fun splitIntoRows_onlyFirstTwoRowsOfTiles() =
+ with(kosmos) {
+ testScope.runTest {
+ setRows(2)
+ val columns by collectLastValue(underTest.columns)
+ val tileViewModels by collectLastValue(underTest.tileViewModels)
+
+ assertThat(columns).isEqualTo(4)
+ // All tiles in 4 columns
+ // [1] [2] [3 3]
+ // [4] [5 5]
+ // [6 6] [7] [8]
+ // [9 9]
+
+ assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(5))
+ }
+ }
+
+ @Test
+ fun changeRows_tilesChange() =
+ with(kosmos) {
+ testScope.runTest {
+ setRows(2)
+ val columns by collectLastValue(underTest.columns)
+ val tileViewModels by collectLastValue(underTest.tileViewModels)
+
+ assertThat(columns).isEqualTo(4)
+ // All tiles in 4 columns
+ // [1] [2] [3 3]
+ // [4] [5 5]
+ // [6 6] [7] [8]
+ // [9 9]
+
+ setRows(3)
+ assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(8))
+ setRows(1)
+ assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(3))
+ }
+ }
+
+ @Test
+ fun changeTiles_tilesChange() =
+ with(kosmos) {
+ testScope.runTest {
+ setRows(2)
+ val columns by collectLastValue(underTest.columns)
+ val tileViewModels by collectLastValue(underTest.tileViewModels)
+
+ assertThat(columns).isEqualTo(4)
+ // All tiles in 4 columns
+ // [1] [2] [3 3]
+ // [4] [5 5]
+ // [6 6] [7] [8]
+ // [9 9]
+
+ // Remove tile small:4
+ currentTilesInteractor.removeTiles(setOf(tiles[3]))
+
+ assertThat(tileViewModels!!.map { it.tile.spec })
+ .isEqualTo(
+ listOf(
+ "$PREFIX_SMALL:1",
+ "$PREFIX_SMALL:2",
+ "$PREFIX_LARGE:3",
+ "$PREFIX_LARGE:5",
+ "$PREFIX_LARGE:6",
+ )
+ .map(TileSpec::create)
+ )
+ }
+ }
+
+ private fun Kosmos.setTiles(tiles: List<TileSpec>) {
+ currentTilesInteractor.setTiles(tiles)
+ }
+
+ private fun Kosmos.setRows(rows: Int) {
+ testCase.context.orCreateTestableResources.addOverride(
+ R.integer.quick_qs_panel_max_rows,
+ rows,
+ )
+ fakeConfigurationRepository.onConfigurationChange()
+ }
+
+ private companion object {
+ const val PREFIX_SMALL = "small"
+ const val PREFIX_LARGE = "large"
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt
index 89b9b7f30297..67e2fba30822 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.qs.tiles.impl.airplate.domain.interactor
+package com.android.systemui.qs.tiles.impl.airplane.domain.interactor
import android.os.UserHandle
import android.platform.test.annotations.EnabledOnRavenwood
@@ -23,7 +23,6 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectValues
import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.impl.airplane.domain.interactor.AirplaneModeTileDataInteractor
import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
index 8982d810ad8a..79fcc92a967c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.qs.tiles.impl.airplate.domain.interactor
+package com.android.systemui.qs.tiles.impl.airplane.domain.interactor
import android.platform.test.annotations.EnabledOnRavenwood
import android.provider.Settings
@@ -26,7 +26,6 @@ import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandl
import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject.Companion.assertThat
import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click
import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.longClick
-import com.android.systemui.qs.tiles.impl.airplane.domain.interactor.AirplaneModeTileUserActionInteractor
import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
@@ -54,7 +53,7 @@ class AirplaneModeTileUserActionInteractorTest : SysuiTestCase() {
connectivityRepository,
mobileConnectionsRepository,
),
- inputHandler
+ inputHandler,
)
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt
new file mode 100644
index 000000000000..09dca25d693e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt
@@ -0,0 +1,93 @@
+/*
+ * 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.qs.tiles.impl.modes.domain.interactor
+
+import android.app.Flags
+import android.os.UserHandle
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.settingslib.notification.data.repository.FakeZenModeRepository
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.toCollection
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ModesTileDataInteractorTest : SysuiTestCase() {
+ private val zenModeRepository = FakeZenModeRepository()
+
+ private val underTest = ModesTileDataInteractor(zenModeRepository)
+
+ @EnableFlags(Flags.FLAG_MODES_UI)
+ @Test
+ fun availableWhenFlagIsOn() = runTest {
+ val availability = underTest.availability(TEST_USER).toCollection(mutableListOf())
+
+ assertThat(availability).containsExactly(true)
+ }
+
+ @DisableFlags(Flags.FLAG_MODES_UI)
+ @Test
+ fun unavailableWhenFlagIsOff() = runTest {
+ val availability = underTest.availability(TEST_USER).toCollection(mutableListOf())
+
+ assertThat(availability).containsExactly(false)
+ }
+
+ @EnableFlags(Flags.FLAG_MODES_UI)
+ @Test
+ fun isActivatedWhenModesChange() = runTest {
+ val dataList: List<ModesTileModel> by
+ collectValues(underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)))
+ runCurrent()
+ assertThat(dataList.map { it.isActivated }).containsExactly(false).inOrder()
+
+ // Add active mode
+ zenModeRepository.addMode(id = "One", active = true)
+ runCurrent()
+ assertThat(dataList.map { it.isActivated }).containsExactly(false, true).inOrder()
+
+ // Add another mode: state hasn't changed, so this shouldn't cause another emission
+ zenModeRepository.addMode(id = "Two", active = true)
+ runCurrent()
+ assertThat(dataList.map { it.isActivated }).containsExactly(false, true).inOrder()
+
+ // Remove a mode and disable the other
+ zenModeRepository.removeMode("One")
+ runCurrent()
+ zenModeRepository.deactivateMode("Two")
+ runCurrent()
+ assertThat(dataList.map { it.isActivated }).containsExactly(false, true, false).inOrder()
+ }
+
+ private companion object {
+
+ val TEST_USER = UserHandle.of(1)!!
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt
new file mode 100644
index 000000000000..9b9e584a936e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.qs.tiles.impl.modes.domain.interactor
+
+import android.platform.test.annotations.EnableFlags
+import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
+import com.google.common.truth.Truth
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@EnableFlags(android.app.Flags.FLAG_MODES_UI)
+class ModesTileUserActionInteractorTest : SysuiTestCase() {
+ private val inputHandler = FakeQSTileIntentUserInputHandler()
+
+ val underTest = ModesTileUserActionInteractor(inputHandler)
+
+ @Test
+ fun handleLongClick() = runTest {
+ underTest.handleInput(QSTileInputTestKtx.longClick(ModesTileModel(false)))
+
+ QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
+ Truth.assertThat(it.intent.action).isEqualTo(Settings.ACTION_ZEN_MODE_SETTINGS)
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt
index 2e5fde8e4bd6..a5f98a739b49 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt
@@ -30,7 +30,6 @@ import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBr
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.toCollection
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Test
@@ -56,8 +55,7 @@ class ReduceBrightColorsTileDataInteractorTest : SysuiTestCase() {
@Test
fun alwaysAvailable() =
testScope.runTest {
- val availability = underTest.availability(TEST_USER).toCollection(mutableListOf())
-
+ val availability by collectValues(underTest.availability(TEST_USER))
assertThat(availability).hasSize(1)
assertThat(availability.last()).isEqualTo(isAvailable)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt
index 6ea5e63fdff6..313331286b45 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt
@@ -17,9 +17,13 @@
package com.android.systemui.qs.tiles.impl.reducebrightness.domain.interactor
import android.platform.test.annotations.EnabledOnRavenwood
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.internal.R
+import com.android.server.display.feature.flags.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.accessibility.reduceBrightColorsController
import com.android.systemui.kosmos.Kosmos
@@ -43,11 +47,22 @@ class ReduceBrightColorsTileUserActionInteractorTest : SysuiTestCase() {
private val underTest =
ReduceBrightColorsTileUserActionInteractor(
+ context.resources,
+ inputHandler,
+ controller,
+ )
+
+ private val underTestEvenDimmerEnabled =
+ ReduceBrightColorsTileUserActionInteractor(
+ context.orCreateTestableResources
+ .apply { addOverride(R.bool.config_evenDimmerEnabled, true) }
+ .resources,
inputHandler,
controller,
)
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_EVEN_DIMMER)
fun handleClickWhenEnabled() = runTest {
val wasEnabled = true
controller.isReduceBrightColorsActivated = wasEnabled
@@ -58,6 +73,7 @@ class ReduceBrightColorsTileUserActionInteractorTest : SysuiTestCase() {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_EVEN_DIMMER)
fun handleClickWhenDisabled() = runTest {
val wasEnabled = false
controller.isReduceBrightColorsActivated = wasEnabled
@@ -68,6 +84,7 @@ class ReduceBrightColorsTileUserActionInteractorTest : SysuiTestCase() {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_EVEN_DIMMER)
fun handleLongClickWhenDisabled() = runTest {
val enabled = false
@@ -79,6 +96,7 @@ class ReduceBrightColorsTileUserActionInteractorTest : SysuiTestCase() {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_EVEN_DIMMER)
fun handleLongClickWhenEnabled() = runTest {
val enabled = true
@@ -88,4 +106,58 @@ class ReduceBrightColorsTileUserActionInteractorTest : SysuiTestCase() {
assertThat(it.intent.action).isEqualTo(Settings.ACTION_REDUCE_BRIGHT_COLORS_SETTINGS)
}
}
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
+ fun handleClickWhenEnabledEvenDimmer() = runTest {
+ val wasEnabled = true
+ controller.isReduceBrightColorsActivated = wasEnabled
+
+ underTestEvenDimmerEnabled.handleInput(
+ QSTileInputTestKtx.click(ReduceBrightColorsTileModel(wasEnabled))
+ )
+
+ assertThat(controller.isReduceBrightColorsActivated).isEqualTo(wasEnabled)
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
+ fun handleClickWhenDisabledEvenDimmer() = runTest {
+ val wasEnabled = false
+ controller.isReduceBrightColorsActivated = wasEnabled
+
+ underTestEvenDimmerEnabled.handleInput(
+ QSTileInputTestKtx.click(ReduceBrightColorsTileModel(wasEnabled))
+ )
+
+ assertThat(controller.isReduceBrightColorsActivated).isEqualTo(wasEnabled)
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
+ fun handleLongClickWhenDisabledEvenDimmer() = runTest {
+ val enabled = false
+
+ underTestEvenDimmerEnabled.handleInput(
+ QSTileInputTestKtx.longClick(ReduceBrightColorsTileModel(enabled))
+ )
+
+ QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
+ assertThat(it.intent.action).isEqualTo(Settings.ACTION_DISPLAY_SETTINGS)
+ }
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
+ fun handleLongClickWhenEnabledEvenDimmer() = runTest {
+ val enabled = true
+
+ underTestEvenDimmerEnabled.handleInput(
+ QSTileInputTestKtx.longClick(ReduceBrightColorsTileModel(enabled))
+ )
+
+ QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
+ assertThat(it.intent.action).isEqualTo(Settings.ACTION_DISPLAY_SETTINGS)
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
index b35b7bca4809..09580c5f17be 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
@@ -38,7 +38,6 @@ import com.android.systemui.qs.dagger.QSSceneComponent
import com.android.systemui.settings.brightness.MirrorController
import com.android.systemui.shade.data.repository.fakeShadeRepository
import com.android.systemui.shade.domain.interactor.shadeInteractor
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.capture
@@ -558,7 +557,7 @@ class QSSceneAdapterImplTest : SysuiTestCase() {
fun dispatchSplitShade() =
testScope.runTest {
val shadeRepository = kosmos.fakeShadeRepository
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
val qsImpl by collectLastValue(underTest.qsImpl)
underTest.inflate(context)
@@ -566,7 +565,7 @@ class QSSceneAdapterImplTest : SysuiTestCase() {
verify(qsImpl!!).setInSplitShade(false)
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
runCurrent()
verify(qsImpl!!).setInSplitShade(true)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
index 411a7a4c96f3..a7a3a0f3008a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
@@ -19,6 +19,7 @@ package com.android.systemui.qs.ui.viewmodel
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
@@ -31,12 +32,12 @@ import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintA
import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.resolver.homeSceneFamilyResolver
import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.fakeShadeRepository
-import com.android.systemui.shade.ui.viewmodel.quickSettingsShadeSceneViewModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -155,6 +156,24 @@ class QuickSettingsShadeSceneViewModelTest : SysuiTestCase() {
assertThat(homeScene).isEqualTo(Scenes.Gone)
}
+ @Test
+ fun backTransitionSceneKey_notEditing_Home() =
+ testScope.runTest {
+ val destinationScenes by collectLastValue(underTest.destinationScenes)
+
+ assertThat(destinationScenes?.get(Back)?.toScene).isEqualTo(SceneFamilies.Home)
+ }
+
+ @Test
+ fun backTransition_editing_noDestination() =
+ testScope.runTest {
+ val destinationScenes by collectLastValue(underTest.destinationScenes)
+ kosmos.editModeViewModel.startEditing()
+
+ assertThat(destinationScenes!!).isNotEmpty()
+ assertThat(destinationScenes?.get(Back)).isNull()
+ }
+
private fun TestScope.lockDevice() {
val deviceUnlockStatus by collectLastValue(deviceUnlockedInteractor.deviceUnlockStatus)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index 5242fe33a281..e3a69a964b45 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -24,6 +24,7 @@ import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
@@ -48,6 +49,7 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -62,6 +64,14 @@ class SceneInteractorTest : SysuiTestCase() {
private val underTest = kosmos.sceneInteractor
+ @Before
+ fun setUp() {
+ // Init lazy Fixtures. Accessing them once makes sure that the singletons are initialized
+ // and therefore starts to collect StateFlows eagerly (when there are any).
+ kosmos.deviceUnlockedInteractor
+ kosmos.keyguardEnabledInteractor
+ }
+
@Test
fun allSceneKeys() {
assertThat(underTest.allSceneKeys()).isEqualTo(kosmos.sceneKeys)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModelTest.kt
index 545a0c70719f..0ab6a8250dcf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModelTest.kt
@@ -28,7 +28,6 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.domain.interactor.shadeInteractor
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -63,7 +62,7 @@ class GoneSceneViewModelTest : SysuiTestCase() {
fun downTransitionKey_splitShadeEnabled_isGoneToSplitShade() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
runCurrent()
assertThat(destinationScenes?.get(Swipe(SwipeDirection.Down))?.transitionKey)
@@ -74,7 +73,7 @@ class GoneSceneViewModelTest : SysuiTestCase() {
fun downTransitionKey_splitShadeDisabled_isNull() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
runCurrent()
assertThat(destinationScenes?.get(Swipe(SwipeDirection.Down))?.transitionKey).isNull()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt
index 78c4def5689b..3283ea154b3f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt
@@ -19,6 +19,8 @@ package com.android.systemui.shade.domain.interactor
import android.app.StatusBarManager.DISABLE2_NONE
import android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE
import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -37,7 +39,10 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.power.shared.model.WakefulnessState
+import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.shadeTestUtil
+import com.android.systemui.shade.shared.flag.DualShade
+import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel
import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
import com.android.systemui.statusbar.phone.dozeParameters
@@ -452,4 +457,44 @@ class ShadeInteractorImplTest(flags: FlagsParameterization) : SysuiTestCase() {
val isShadeTouchable by collectLastValue(underTest.isShadeTouchable)
assertThat(isShadeTouchable).isTrue()
}
+
+ @Test
+ @DisableFlags(DualShade.FLAG_NAME)
+ fun legacyShadeMode_narrowScreen_singleShade() =
+ testScope.runTest {
+ val shadeMode by collectLastValue(underTest.shadeMode)
+ kosmos.shadeRepository.setShadeLayoutWide(false)
+
+ assertThat(shadeMode).isEqualTo(ShadeMode.Single)
+ }
+
+ @Test
+ @DisableFlags(DualShade.FLAG_NAME)
+ fun legacyShadeMode_wideScreen_splitShade() =
+ testScope.runTest {
+ val shadeMode by collectLastValue(underTest.shadeMode)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
+
+ assertThat(shadeMode).isEqualTo(ShadeMode.Split)
+ }
+
+ @Test
+ @EnableFlags(DualShade.FLAG_NAME)
+ fun shadeMode_wideScreen_isDual() =
+ testScope.runTest {
+ val shadeMode by collectLastValue(underTest.shadeMode)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
+
+ assertThat(shadeMode).isEqualTo(ShadeMode.Dual)
+ }
+
+ @Test
+ @EnableFlags(DualShade.FLAG_NAME)
+ fun shadeMode_narrowScreen_isDual() =
+ testScope.runTest {
+ val shadeMode by collectLastValue(underTest.shadeMode)
+ kosmos.shadeRepository.setShadeLayoutWide(false)
+
+ assertThat(shadeMode).isEqualTo(ShadeMode.Dual)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt
index b1bffdbb1bed..8a4319805802 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt
@@ -29,7 +29,6 @@ import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.testKosmos
import com.google.common.truth.Truth
import com.google.common.truth.Truth.assertThat
@@ -568,21 +567,6 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() {
sceneInteractor.setTransitionState(transitionState)
// THEN interacting is false
- Truth.assertThat(interacting).isFalse()
- }
-
- @Test
- fun shadeMode() =
- testScope.runTest {
- val shadeMode by collectLastValue(underTest.shadeMode)
-
- shadeRepository.setShadeMode(ShadeMode.Split)
- assertThat(shadeMode).isEqualTo(ShadeMode.Split)
-
- shadeRepository.setShadeMode(ShadeMode.Single)
- assertThat(shadeMode).isEqualTo(ShadeMode.Single)
-
- shadeRepository.setShadeMode(ShadeMode.Split)
- assertThat(shadeMode).isEqualTo(ShadeMode.Split)
+ assertThat(interacting).isFalse()
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index 673d5ef5d962..da22c6d7419d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.shade.ui.viewmodel
+import android.platform.test.annotations.DisableFlags
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -38,7 +39,6 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.qs.ui.adapter.fakeQSSceneAdapter
-import com.android.systemui.qs.ui.adapter.qsSceneAdapter
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.resolver.homeSceneFamilyResolver
@@ -47,6 +47,7 @@ import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.domain.startable.shadeStartable
+import com.android.systemui.shade.shared.flag.DualShade
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.testKosmos
import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider
@@ -66,6 +67,7 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@EnableSceneContainer
+@DisableFlags(DualShade.FLAG_NAME)
class ShadeSceneViewModelTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -157,7 +159,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
fun upTransitionKey_splitShadeEnabled_isGoneToSplitShade() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
runCurrent()
assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.transitionKey)
@@ -168,7 +170,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
fun upTransitionKey_splitShadeDisable_isNull() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
runCurrent()
assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.transitionKey).isNull()
@@ -268,13 +270,13 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
testScope.runTest {
val shadeMode by collectLastValue(underTest.shadeMode)
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
assertThat(shadeMode).isEqualTo(ShadeMode.Split)
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
assertThat(shadeMode).isEqualTo(ShadeMode.Single)
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
assertThat(shadeMode).isEqualTo(ShadeMode.Split)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
index e73cae257c37..355669bd8a59 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -38,8 +38,11 @@ import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.setTransition
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
@@ -392,11 +395,15 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest
)
assertThat(underTest.leaveOpenOnKeyguardHide()).isEqualTo(true)
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GONE,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Gone),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ )
)
+
assertThat(underTest.leaveOpenOnKeyguardHide()).isEqualTo(false)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinatorTest.kt
new file mode 100644
index 000000000000..8a9720ea3cb0
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinatorTest.kt
@@ -0,0 +1,104 @@
+/*
+ * 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.notification.collection.coordinator
+
+import android.app.NotificationChannel
+import android.app.NotificationChannel.NEWS_ID
+import android.app.NotificationChannel.PROMOTIONS_ID
+import android.app.NotificationChannel.RECS_ID
+import android.app.NotificationChannel.SOCIAL_MEDIA_ID
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.collection.render.NodeController
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper
+class BundleCoordinatorTest : SysuiTestCase() {
+ @Mock private lateinit var newsController: NodeController
+ @Mock private lateinit var socialController: NodeController
+ @Mock private lateinit var recsController: NodeController
+ @Mock private lateinit var promoController: NodeController
+
+ private lateinit var coordinator: BundleCoordinator
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ coordinator =
+ BundleCoordinator(
+ newsController,
+ socialController,
+ recsController,
+ promoController
+ )
+ }
+
+ @Test
+ fun newsSectioner() {
+ assertThat(coordinator.newsSectioner.isInSection(makeEntryOfChannelType(NEWS_ID))).isTrue()
+ assertThat(coordinator.newsSectioner.isInSection(makeEntryOfChannelType("news"))).isFalse()
+ }
+
+ @Test
+ fun socialSectioner() {
+ assertThat(coordinator.socialSectioner.isInSection(makeEntryOfChannelType(SOCIAL_MEDIA_ID)))
+ .isTrue()
+ assertThat(coordinator.socialSectioner.isInSection(makeEntryOfChannelType("social")))
+ .isFalse()
+ }
+
+ @Test
+ fun recsSectioner() {
+ assertThat(coordinator.recsSectioner.isInSection(makeEntryOfChannelType(RECS_ID))).isTrue()
+ assertThat(coordinator.recsSectioner.isInSection(makeEntryOfChannelType("recommendations")))
+ .isFalse()
+ }
+
+ @Test
+ fun promoSectioner() {
+ assertThat(coordinator.promoSectioner.isInSection(makeEntryOfChannelType(PROMOTIONS_ID)))
+ .isTrue()
+ assertThat(coordinator.promoSectioner.isInSection(makeEntryOfChannelType("promo"))).
+ isFalse()
+ }
+
+ private fun makeEntryOfChannelType(
+ type: String,
+ buildBlock: NotificationEntryBuilder.() -> Unit = {}
+ ): NotificationEntry {
+ val channel: NotificationChannel = NotificationChannel(type, type, 2)
+ val entry =
+ NotificationEntryBuilder()
+ .updateRanking {
+ it.setChannel(channel)
+ }
+ .also(buildBlock)
+ .build()
+ return entry
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorTest.kt
index 9ef42c30dcc1..0195e9d8418b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorTest.kt
@@ -21,8 +21,8 @@ import android.media.AudioManager
import android.provider.Settings.Global
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.settingslib.statusbar.notification.data.repository.updateNotificationPolicy
-import com.android.settingslib.statusbar.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.notification.data.repository.updateNotificationPolicy
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
import com.android.settingslib.volume.shared.model.AudioStream
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorTest.kt
index 50b77dcf9468..1356e93db549 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorTest.kt
@@ -22,7 +22,6 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimRounding
import com.android.systemui.testKosmos
@@ -66,11 +65,11 @@ class NotificationStackAppearanceInteractorTest : SysuiTestCase() {
testScope.runTest {
val stackRounding by collectLastValue(underTest.shadeScrimRounding)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Single)
+ kosmos.shadeRepository.setShadeLayoutWide(false)
assertThat(stackRounding)
.isEqualTo(ShadeScrimRounding(isTopRounded = true, isBottomRounded = false))
- kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
assertThat(stackRounding)
.isEqualTo(ShadeScrimRounding(isTopRounded = true, isBottomRounded = true))
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
index 40315a27da4f..f8e633731c42 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
@@ -23,7 +23,7 @@ import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
import android.provider.Settings
import androidx.test.filters.SmallTest
-import com.android.settingslib.statusbar.notification.data.repository.updateNotificationPolicy
+import com.android.settingslib.notification.data.repository.updateNotificationPolicy
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.Flags
@@ -633,7 +633,7 @@ class NotificationListViewModelTest(flags: FlagsParameterization) : SysuiTestCas
@Test
@EnableFlags(NotificationsHeadsUpRefactor.FLAG_NAME)
- fun headsUpAnimationsEnabled_keyguardShowing_false() =
+ fun headsUpAnimationsEnabled_keyguardShowing_true() =
testScope.runTest {
val animationsEnabled by collectLastValue(underTest.headsUpAnimationsEnabled)
@@ -641,6 +641,6 @@ class NotificationListViewModelTest(flags: FlagsParameterization) : SysuiTestCas
fakeKeyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
runCurrent()
- assertThat(animationsEnabled).isFalse()
+ assertThat(animationsEnabled).isTrue()
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index f14c96ded873..71cd95f828ef 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -64,7 +64,6 @@ import com.android.systemui.statusbar.notification.NotificationUtils.interpolate
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.whenever
import com.google.common.collect.Range
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -77,6 +76,7 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
+import org.mockito.kotlin.whenever
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
@@ -213,9 +213,11 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
}
@Test
- fun validatePaddingTop() =
+ fun validatePaddingTopInNonSplitShade_usesLargeScreenHeader() =
testScope.runTest {
+ whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight()).thenReturn(10)
overrideResource(R.bool.config_use_split_notification_shade, false)
+ overrideResource(R.bool.config_use_large_screen_shade_header, true)
overrideResource(R.dimen.large_screen_shade_header_height, 10)
overrideResource(R.dimen.keyguard_split_shade_top_margin, 50)
@@ -223,6 +225,21 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
configurationRepository.onAnyConfigurationChange()
+ assertThat(paddingTop).isEqualTo(10)
+ }
+
+ @Test
+ fun validatePaddingTopInNonSplitShade_doesNotUseLargeScreenHeader() =
+ testScope.runTest {
+ whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight()).thenReturn(10)
+ overrideResource(R.bool.config_use_split_notification_shade, false)
+ overrideResource(R.bool.config_use_large_screen_shade_header, false)
+ overrideResource(R.dimen.large_screen_shade_header_height, 10)
+ overrideResource(R.dimen.keyguard_split_shade_top_margin, 50)
+
+ val paddingTop by collectLastValue(underTest.paddingTopDimen)
+
+ configurationRepository.onAnyConfigurationChange()
assertThat(paddingTop).isEqualTo(0)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt
index ccd78ee82169..10a2f6407849 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt
@@ -38,8 +38,11 @@ import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.animation.LaunchableView
import com.android.systemui.assist.AssistManager
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction
import com.android.systemui.settings.UserTracker
import com.android.systemui.shade.ShadeController
import com.android.systemui.shade.data.repository.FakeShadeRepository
@@ -100,6 +103,7 @@ class LegacyActivityStarterInternalImplTest : SysuiTestCase() {
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var activityIntentHelper: ActivityIntentHelper
@Mock private lateinit var communalSceneInteractor: CommunalSceneInteractor
+ @Mock private lateinit var communalSettingsInteractor: CommunalSettingsInteractor
private lateinit var underTest: LegacyActivityStarterInternalImpl
private val mainExecutor = FakeExecutor(FakeSystemClock())
private val shadeAnimationInteractor =
@@ -134,9 +138,12 @@ class LegacyActivityStarterInternalImplTest : SysuiTestCase() {
activityIntentHelper = activityIntentHelper,
mainExecutor = mainExecutor,
communalSceneInteractor = communalSceneInteractor,
+ communalSettingsInteractor = communalSettingsInteractor,
)
`when`(userTracker.userHandle).thenReturn(UserHandle.OWNER)
+ `when`(communalSceneInteractor.isCommunalVisible).thenReturn(MutableStateFlow(false))
`when`(communalSceneInteractor.isIdleOnCommunal).thenReturn(MutableStateFlow(false))
+ `when`(communalSceneInteractor.isLaunchingWidget).thenReturn(MutableStateFlow(false))
}
@Test
@@ -335,6 +342,103 @@ class LegacyActivityStarterInternalImplTest : SysuiTestCase() {
)
}
+ @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
+ @Test
+ fun startPendingIntentDismissingKeyguard_transitionAnimator_animateCommunal() {
+ val parent = FrameLayout(context)
+ val view =
+ object : View(context), LaunchableView {
+ override fun setShouldBlockVisibilityChanges(block: Boolean) {}
+ }
+ parent.addView(view)
+ val controller = ActivityTransitionAnimator.Controller.fromView(view)
+ val pendingIntent = mock(PendingIntent::class.java)
+ `when`(pendingIntent.isActivity).thenReturn(true)
+ `when`(keyguardStateController.isShowing).thenReturn(true)
+ `when`(keyguardStateController.isOccluded).thenReturn(true)
+ `when`(communalSettingsInteractor.isCommunalFlagEnabled()).thenReturn(true)
+ `when`(communalSceneInteractor.isCommunalVisible).thenReturn(MutableStateFlow(true))
+ `when`(communalSceneInteractor.isLaunchingWidget).thenReturn(MutableStateFlow(true))
+ `when`(activityIntentHelper.wouldPendingLaunchResolverActivity(eq(pendingIntent), anyInt()))
+ .thenReturn(false)
+ `when`(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt()))
+ .thenReturn(false)
+
+ underTest.startPendingIntentDismissingKeyguard(
+ intent = pendingIntent,
+ dismissShade = false,
+ animationController = controller,
+ showOverLockscreen = true,
+ skipLockscreenChecks = false
+ )
+ mainExecutor.runAllReady()
+
+ val actionCaptor = argumentCaptor<OnDismissAction>()
+ verify(statusBarKeyguardViewManager)
+ .dismissWithAction(actionCaptor.capture(), eq(null), anyBoolean(), eq(null))
+ actionCaptor.firstValue.onDismiss()
+ mainExecutor.runAllReady()
+
+ verify(activityTransitionAnimator)
+ .startPendingIntentWithAnimation(
+ nullable(ActivityTransitionAnimator.Controller::class.java),
+ eq(true),
+ nullable(String::class.java),
+ eq(false),
+ any(),
+ )
+ }
+
+ @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
+ @Test
+ fun startPendingIntentDismissingKeyguard_transitionAnimator_doNotAnimateCommunal() {
+ val parent = FrameLayout(context)
+ val view =
+ object : View(context), LaunchableView {
+ override fun setShouldBlockVisibilityChanges(block: Boolean) {}
+ }
+ parent.addView(view)
+ val controller = ActivityTransitionAnimator.Controller.fromView(view)
+ val pendingIntent = mock(PendingIntent::class.java)
+ `when`(pendingIntent.isActivity).thenReturn(true)
+ `when`(keyguardStateController.isShowing).thenReturn(true)
+ `when`(keyguardStateController.isOccluded).thenReturn(true)
+ `when`(communalSceneInteractor.isCommunalVisible).thenReturn(MutableStateFlow(true))
+ `when`(communalSceneInteractor.isLaunchingWidget).thenReturn(MutableStateFlow(true))
+ `when`(activityIntentHelper.wouldPendingLaunchResolverActivity(eq(pendingIntent), anyInt()))
+ .thenReturn(false)
+ `when`(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt()))
+ .thenReturn(false)
+
+ underTest.startPendingIntentDismissingKeyguard(
+ intent = pendingIntent,
+ dismissShade = false,
+ animationController = controller,
+ showOverLockscreen = true,
+ skipLockscreenChecks = false
+ )
+ mainExecutor.runAllReady()
+
+ val actionCaptor = argumentCaptor<OnDismissAction>()
+ verify(statusBarKeyguardViewManager)
+ .dismissWithAction(actionCaptor.capture(), eq(null), anyBoolean(), eq(null))
+ actionCaptor.firstValue.onDismiss()
+ mainExecutor.runAllReady()
+
+ val runnableCaptor = argumentCaptor<Runnable>()
+ verify(statusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(runnableCaptor.capture())
+ runnableCaptor.firstValue.run()
+
+ verify(activityTransitionAnimator)
+ .startPendingIntentWithAnimation(
+ nullable(ActivityTransitionAnimator.Controller::class.java),
+ eq(false),
+ nullable(String::class.java),
+ eq(false),
+ any(),
+ )
+ }
+
@Test
fun startActivity_noUserHandleProvided_getUserHandle() {
val intent = mock(Intent::class.java)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
index 6b5d07282a08..495ab61600f9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.policy
import android.app.Notification
+import android.os.Handler
import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper.RunWithLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -59,6 +60,9 @@ class AvalancheControllerTest : SysuiTestCase() {
// For creating TestableHeadsUpManager
@Mock private val mAccessibilityMgr: AccessibilityManagerWrapper? = null
private val mUiEventLoggerFake = UiEventLoggerFake()
+
+ @Mock private lateinit var mBgHandler: Handler
+
private val mLogger = Mockito.spy(HeadsUpManagerLogger(logcatLogBuffer()))
private val mGlobalSettings = FakeGlobalSettings()
private val mSystemClock = FakeSystemClock()
@@ -78,7 +82,7 @@ class AvalancheControllerTest : SysuiTestCase() {
// Initialize AvalancheController and TestableHeadsUpManager during setUp instead of
// declaration, where mocks are null
- mAvalancheController = AvalancheController(dumpManager, mUiEventLoggerFake)
+ mAvalancheController = AvalancheController(dumpManager, mUiEventLoggerFake, mBgHandler)
testableHeadsUpManager =
TestableHeadsUpManager(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
index 206b39c28da3..df07b446667a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
@@ -38,6 +38,7 @@ import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Person;
+import android.os.Handler;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.FlagsParameterization;
@@ -81,7 +82,7 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {
private UiEventLoggerFake mUiEventLoggerFake = new UiEventLoggerFake();
private final HeadsUpManagerLogger mLogger = spy(new HeadsUpManagerLogger(logcatLogBuffer()));
-
+ @Mock private Handler mBgHandler;
@Mock private DumpManager dumpManager;
private AvalancheController mAvalancheController;
@@ -148,7 +149,7 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {
@Override
public void SysuiSetup() throws Exception {
super.SysuiSetup();
- mAvalancheController = new AvalancheController(dumpManager, mUiEventLoggerFake);
+ mAvalancheController = new AvalancheController(dumpManager, mUiEventLoggerFake, mBgHandler);
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java
deleted file mode 100644
index 7346323f733d..000000000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java
+++ /dev/null
@@ -1,246 +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.systemui.statusbar.policy;
-
-import static com.android.systemui.log.LogBufferHelperKt.logcatLogBuffer;
-import static com.android.systemui.util.concurrency.MockExecutorHandlerKt.mockExecutorHandler;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.os.Handler;
-import android.platform.test.flag.junit.FlagsParameterization;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.res.R;
-import com.android.systemui.shade.domain.interactor.ShadeInteractor;
-import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
-import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
-import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun;
-import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.util.concurrency.DelayableExecutor;
-import com.android.systemui.util.kotlin.JavaAdapter;
-import com.android.systemui.util.settings.GlobalSettings;
-import com.android.systemui.util.time.SystemClock;
-
-import kotlinx.coroutines.flow.StateFlowKt;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
-import platform.test.runner.parameterized.Parameters;
-
-import java.util.List;
-
-@SmallTest
-@RunWith(ParameterizedAndroidJunit4.class)
-@TestableLooper.RunWithLooper
-public class HeadsUpManagerPhoneTest extends BaseHeadsUpManagerTest {
- @Rule public MockitoRule rule = MockitoJUnit.rule();
-
- private final HeadsUpManagerLogger mHeadsUpManagerLogger = new HeadsUpManagerLogger(
- logcatLogBuffer());
- @Mock private GroupMembershipManager mGroupManager;
- @Mock private VisualStabilityProvider mVSProvider;
- @Mock private StatusBarStateController mStatusBarStateController;
- @Mock private KeyguardBypassController mBypassController;
- @Mock private ConfigurationControllerImpl mConfigurationController;
- @Mock private AccessibilityManagerWrapper mAccessibilityManagerWrapper;
- @Mock private UiEventLogger mUiEventLogger;
- @Mock private JavaAdapter mJavaAdapter;
- @Mock private ShadeInteractor mShadeInteractor;
- @Mock private DumpManager dumpManager;
- private AvalancheController mAvalancheController;
-
- @Mock private Handler mBgHandler;
-
- private static final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
- TestableHeadsUpManagerPhone(
- Context context,
- HeadsUpManagerLogger headsUpManagerLogger,
- GroupMembershipManager groupManager,
- VisualStabilityProvider visualStabilityProvider,
- StatusBarStateController statusBarStateController,
- KeyguardBypassController keyguardBypassController,
- ConfigurationController configurationController,
- GlobalSettings globalSettings,
- SystemClock systemClock,
- DelayableExecutor executor,
- AccessibilityManagerWrapper accessibilityManagerWrapper,
- UiEventLogger uiEventLogger,
- JavaAdapter javaAdapter,
- ShadeInteractor shadeInteractor,
- AvalancheController avalancheController,
- Handler bgHandler
- ) {
- super(
- context,
- headsUpManagerLogger,
- statusBarStateController,
- keyguardBypassController,
- groupManager,
- visualStabilityProvider,
- configurationController,
- mockExecutorHandler(executor),
- globalSettings,
- systemClock,
- executor,
- accessibilityManagerWrapper,
- uiEventLogger,
- javaAdapter,
- shadeInteractor,
- avalancheController,
- bgHandler
- );
- mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
- mAutoDismissTime = TEST_AUTO_DISMISS_TIME;
- }
- }
-
- private HeadsUpManagerPhone createHeadsUpManagerPhone() {
- return new TestableHeadsUpManagerPhone(
- mContext,
- mHeadsUpManagerLogger,
- mGroupManager,
- mVSProvider,
- mStatusBarStateController,
- mBypassController,
- mConfigurationController,
- mGlobalSettings,
- mSystemClock,
- mExecutor,
- mAccessibilityManagerWrapper,
- mUiEventLogger,
- mJavaAdapter,
- mShadeInteractor,
- mAvalancheController,
- mBgHandler
- );
- }
-
- @Parameters(name = "{0}")
- public static List<FlagsParameterization> getFlags() {
- return FlagsParameterization.allCombinationsOf(NotificationThrottleHun.FLAG_NAME);
- }
-
- public HeadsUpManagerPhoneTest(FlagsParameterization flags) {
- super(flags);
- }
-
- @Before
- public void setUp() {
- when(mShadeInteractor.isAnyExpanded()).thenReturn(StateFlowKt.MutableStateFlow(false));
- final AccessibilityManagerWrapper accessibilityMgr =
- mDependency.injectMockDependency(AccessibilityManagerWrapper.class);
- when(accessibilityMgr.getRecommendedTimeoutMillis(anyInt(), anyInt()))
- .thenReturn(TEST_AUTO_DISMISS_TIME);
- when(mVSProvider.isReorderingAllowed()).thenReturn(true);
- mDependency.injectMockDependency(NotificationShadeWindowController.class);
- mContext.getOrCreateTestableResources().addOverride(
- R.integer.ambient_notification_extension_time, 500);
-
- mAvalancheController = new AvalancheController(dumpManager, mUiEventLogger);
- }
-
- @Test
- public void testSnooze() {
- final HeadsUpManager hmp = createHeadsUpManagerPhone();
- final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
-
- hmp.showNotification(entry);
- hmp.snooze();
-
- assertTrue(hmp.isSnoozed(entry.getSbn().getPackageName()));
- }
-
- @Test
- public void testSwipedOutNotification() {
- final HeadsUpManager hmp = createHeadsUpManagerPhone();
- final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
-
- hmp.showNotification(entry);
- hmp.addSwipedOutNotification(entry.getKey());
-
- // Remove should succeed because the notification is swiped out
- final boolean removedImmediately = hmp.removeNotification(entry.getKey(),
- /* releaseImmediately = */ false);
-
- assertTrue(removedImmediately);
- assertFalse(hmp.isHeadsUpEntry(entry.getKey()));
- }
-
- @Test
- public void testCanRemoveImmediately_swipedOut() {
- final HeadsUpManager hmp = createHeadsUpManagerPhone();
- final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
-
- hmp.showNotification(entry);
- hmp.addSwipedOutNotification(entry.getKey());
-
- // Notification is swiped so it can be immediately removed.
- assertTrue(hmp.canRemoveImmediately(entry.getKey()));
- }
-
- @Ignore("b/141538055")
- @Test
- public void testCanRemoveImmediately_notTopEntry() {
- final HeadsUpManager hmp = createHeadsUpManagerPhone();
- final NotificationEntry earlierEntry =
- HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
- final NotificationEntry laterEntry =
- HeadsUpManagerTestUtil.createEntry(/* id = */ 1, mContext);
- laterEntry.setRow(mRow);
-
- hmp.showNotification(earlierEntry);
- hmp.showNotification(laterEntry);
-
- // Notification is "behind" a higher priority notification so we can remove it immediately.
- assertTrue(hmp.canRemoveImmediately(earlierEntry.getKey()));
- }
-
- @Test
- public void testExtendHeadsUp() {
- final HeadsUpManagerPhone hmp = createHeadsUpManagerPhone();
- final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
-
- hmp.showNotification(entry);
- hmp.extendHeadsUp();
- mSystemClock.advanceTime(TEST_AUTO_DISMISS_TIME + hmp.mExtensionTime / 2);
-
- assertTrue(hmp.isHeadsUpEntry(entry.getKey()));
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt
new file mode 100644
index 000000000000..d0ddbffecf9a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt
@@ -0,0 +1,439 @@
+/*
+ * 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.systemui.statusbar.policy
+
+import android.content.Context
+import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.log.logcatLogBuffer
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.res.R
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.statusbar.FakeStatusBarStateController
+import com.android.systemui.statusbar.NotificationShadeWindowController
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider
+import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager
+import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
+import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor
+import com.android.systemui.statusbar.phone.ConfigurationControllerImpl
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.testKosmos
+import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.concurrency.mockExecutorHandler
+import com.android.systemui.util.kotlin.JavaAdapter
+import com.android.systemui.util.settings.GlobalSettings
+import com.android.systemui.util.time.SystemClock
+import junit.framework.Assert
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.Mock
+import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(ParameterizedAndroidJunit4::class)
+@RunWithLooper
+class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManagerTest(flags) {
+
+ private val mHeadsUpManagerLogger = HeadsUpManagerLogger(logcatLogBuffer())
+
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
+ @Mock private lateinit var mGroupManager: GroupMembershipManager
+
+ @Mock private lateinit var mVSProvider: VisualStabilityProvider
+
+ @Mock private lateinit var mStatusBarStateController: StatusBarStateController
+
+ @Mock private lateinit var mBypassController: KeyguardBypassController
+
+ @Mock private lateinit var mConfigurationController: ConfigurationControllerImpl
+
+ @Mock private lateinit var mAccessibilityManagerWrapper: AccessibilityManagerWrapper
+
+ @Mock private lateinit var mUiEventLogger: UiEventLogger
+
+ private val mJavaAdapter: JavaAdapter = JavaAdapter(testScope.backgroundScope)
+
+ @Mock private lateinit var mShadeInteractor: ShadeInteractor
+
+ @Mock private lateinit var dumpManager: DumpManager
+ private lateinit var mAvalancheController: AvalancheController
+
+ @Mock private lateinit var mBgHandler: Handler
+
+ private class TestableHeadsUpManagerPhone(
+ context: Context,
+ headsUpManagerLogger: HeadsUpManagerLogger,
+ groupManager: GroupMembershipManager,
+ visualStabilityProvider: VisualStabilityProvider,
+ statusBarStateController: StatusBarStateController,
+ keyguardBypassController: KeyguardBypassController,
+ configurationController: ConfigurationController,
+ globalSettings: GlobalSettings,
+ systemClock: SystemClock,
+ executor: DelayableExecutor,
+ accessibilityManagerWrapper: AccessibilityManagerWrapper,
+ uiEventLogger: UiEventLogger,
+ javaAdapter: JavaAdapter,
+ shadeInteractor: ShadeInteractor,
+ avalancheController: AvalancheController
+ ) :
+ HeadsUpManagerPhone(
+ context,
+ headsUpManagerLogger,
+ statusBarStateController,
+ keyguardBypassController,
+ groupManager,
+ visualStabilityProvider,
+ configurationController,
+ mockExecutorHandler(executor),
+ globalSettings,
+ systemClock,
+ executor,
+ accessibilityManagerWrapper,
+ uiEventLogger,
+ javaAdapter,
+ shadeInteractor,
+ avalancheController
+ ) {
+ init {
+ mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME
+ mAutoDismissTime = TEST_AUTO_DISMISS_TIME
+ }
+
+ /** Wrapper for [BaseHeadsUpManager.shouldHeadsUpBecomePinned] for testing */
+ fun shouldHeadsUpBecomePinnedWrapper(entry: NotificationEntry): Boolean {
+ return shouldHeadsUpBecomePinned(entry)
+ }
+ }
+
+ private fun createHeadsUpManagerPhone(): HeadsUpManagerPhone {
+ return TestableHeadsUpManagerPhone(
+ mContext,
+ mHeadsUpManagerLogger,
+ mGroupManager,
+ mVSProvider,
+ mStatusBarStateController,
+ mBypassController,
+ mConfigurationController,
+ mGlobalSettings,
+ mSystemClock,
+ mExecutor,
+ mAccessibilityManagerWrapper,
+ mUiEventLogger,
+ mJavaAdapter,
+ mShadeInteractor,
+ mAvalancheController
+ )
+ }
+
+ @Before
+ fun setUp() {
+ whenever(mShadeInteractor.isAnyExpanded).thenReturn(MutableStateFlow(false))
+ whenever(mVSProvider.isReorderingAllowed).thenReturn(true)
+ val accessibilityMgr =
+ mDependency.injectMockDependency(AccessibilityManagerWrapper::class.java)
+ whenever(
+ accessibilityMgr.getRecommendedTimeoutMillis(
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.anyInt()
+ )
+ )
+ .thenReturn(TEST_AUTO_DISMISS_TIME)
+ mDependency.injectMockDependency(NotificationShadeWindowController::class.java)
+ mContext
+ .getOrCreateTestableResources()
+ .addOverride(R.integer.ambient_notification_extension_time, 500)
+ mAvalancheController = AvalancheController(dumpManager, mUiEventLogger, mBgHandler)
+ }
+
+ @Test
+ fun testSnooze() {
+ val hmp: HeadsUpManager = createHeadsUpManagerPhone()
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ hmp.showNotification(entry)
+ hmp.snooze()
+ Assert.assertTrue(hmp.isSnoozed(entry.sbn.packageName))
+ }
+
+ @Test
+ fun testSwipedOutNotification() {
+ val hmp: HeadsUpManager = createHeadsUpManagerPhone()
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ hmp.showNotification(entry)
+ hmp.addSwipedOutNotification(entry.key)
+
+ // Remove should succeed because the notification is swiped out
+ val removedImmediately = hmp.removeNotification(entry.key, /* releaseImmediately= */ false)
+ Assert.assertTrue(removedImmediately)
+ Assert.assertFalse(hmp.isHeadsUpEntry(entry.key))
+ }
+
+ @Test
+ fun testCanRemoveImmediately_swipedOut() {
+ val hmp: HeadsUpManager = createHeadsUpManagerPhone()
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ hmp.showNotification(entry)
+ hmp.addSwipedOutNotification(entry.key)
+
+ // Notification is swiped so it can be immediately removed.
+ Assert.assertTrue(hmp.canRemoveImmediately(entry.key))
+ }
+
+ @Ignore("b/141538055")
+ @Test
+ fun testCanRemoveImmediately_notTopEntry() {
+ val hmp: HeadsUpManager = createHeadsUpManagerPhone()
+ val earlierEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ val laterEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 1, mContext)
+ laterEntry.row = mRow
+ hmp.showNotification(earlierEntry)
+ hmp.showNotification(laterEntry)
+
+ // Notification is "behind" a higher priority notification so we can remove it immediately.
+ Assert.assertTrue(hmp.canRemoveImmediately(earlierEntry.key))
+ }
+
+ @Test
+ fun testExtendHeadsUp() {
+ val hmp = createHeadsUpManagerPhone()
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ hmp.showNotification(entry)
+ hmp.extendHeadsUp()
+ mSystemClock.advanceTime((TEST_AUTO_DISMISS_TIME + hmp.mExtensionTime / 2).toLong())
+ Assert.assertTrue(hmp.isHeadsUpEntry(entry.key))
+ }
+
+ @Test
+ fun shouldHeadsUpBecomePinned_shadeNotExpanded_true() =
+ testScope.runTest {
+ // GIVEN
+ val statusBarStateController = FakeStatusBarStateController()
+ whenever(mShadeInteractor.isAnyFullyExpanded).thenReturn(MutableStateFlow(false))
+ val hmp =
+ TestableHeadsUpManagerPhone(
+ mContext,
+ mHeadsUpManagerLogger,
+ mGroupManager,
+ mVSProvider,
+ statusBarStateController,
+ mBypassController,
+ mConfigurationController,
+ mGlobalSettings,
+ mSystemClock,
+ mExecutor,
+ mAccessibilityManagerWrapper,
+ mUiEventLogger,
+ mJavaAdapter,
+ mShadeInteractor,
+ mAvalancheController
+ )
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ statusBarStateController.setState(StatusBarState.SHADE)
+ runCurrent()
+
+ // THEN
+ Assert.assertTrue(hmp.shouldHeadsUpBecomePinnedWrapper(entry))
+ }
+
+ @Test
+ fun shouldHeadsUpBecomePinned_shadeLocked_false() =
+ testScope.runTest {
+ // GIVEN
+ val statusBarStateController = FakeStatusBarStateController()
+ val hmp =
+ TestableHeadsUpManagerPhone(
+ mContext,
+ mHeadsUpManagerLogger,
+ mGroupManager,
+ mVSProvider,
+ statusBarStateController,
+ mBypassController,
+ mConfigurationController,
+ mGlobalSettings,
+ mSystemClock,
+ mExecutor,
+ mAccessibilityManagerWrapper,
+ mUiEventLogger,
+ mJavaAdapter,
+ mShadeInteractor,
+ mAvalancheController
+ )
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ statusBarStateController.setState(StatusBarState.SHADE_LOCKED)
+ runCurrent()
+
+ // THEN
+ Assert.assertFalse(hmp.shouldHeadsUpBecomePinnedWrapper(entry))
+ }
+
+ @Test
+ fun shouldHeadsUpBecomePinned_shadeUnknown_false() =
+ testScope.runTest {
+ // GIVEN
+ val statusBarStateController = FakeStatusBarStateController()
+ val hmp =
+ TestableHeadsUpManagerPhone(
+ mContext,
+ mHeadsUpManagerLogger,
+ mGroupManager,
+ mVSProvider,
+ statusBarStateController,
+ mBypassController,
+ mConfigurationController,
+ mGlobalSettings,
+ mSystemClock,
+ mExecutor,
+ mAccessibilityManagerWrapper,
+ mUiEventLogger,
+ mJavaAdapter,
+ mShadeInteractor,
+ mAvalancheController
+ )
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ statusBarStateController.setState(1207)
+ runCurrent()
+
+ // THEN
+ Assert.assertFalse(hmp.shouldHeadsUpBecomePinnedWrapper(entry))
+ }
+
+ @Test
+ fun shouldHeadsUpBecomePinned_keyguardWithBypassOn_true() =
+ testScope.runTest {
+ // GIVEN
+ val statusBarStateController = FakeStatusBarStateController()
+ whenever(mBypassController.bypassEnabled).thenReturn(true)
+ val hmp =
+ TestableHeadsUpManagerPhone(
+ mContext,
+ mHeadsUpManagerLogger,
+ mGroupManager,
+ mVSProvider,
+ statusBarStateController,
+ mBypassController,
+ mConfigurationController,
+ mGlobalSettings,
+ mSystemClock,
+ mExecutor,
+ mAccessibilityManagerWrapper,
+ mUiEventLogger,
+ mJavaAdapter,
+ mShadeInteractor,
+ mAvalancheController
+ )
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ statusBarStateController.setState(StatusBarState.KEYGUARD)
+ runCurrent()
+
+ // THEN
+ Assert.assertTrue(hmp.shouldHeadsUpBecomePinnedWrapper(entry))
+ }
+
+ @Test
+ fun shouldHeadsUpBecomePinned_keyguardWithBypassOff_false() =
+ testScope.runTest {
+ // GIVEN
+ val statusBarStateController = FakeStatusBarStateController()
+ whenever(mBypassController.bypassEnabled).thenReturn(false)
+ val hmp =
+ TestableHeadsUpManagerPhone(
+ mContext,
+ mHeadsUpManagerLogger,
+ mGroupManager,
+ mVSProvider,
+ statusBarStateController,
+ mBypassController,
+ mConfigurationController,
+ mGlobalSettings,
+ mSystemClock,
+ mExecutor,
+ mAccessibilityManagerWrapper,
+ mUiEventLogger,
+ mJavaAdapter,
+ mShadeInteractor,
+ mAvalancheController
+ )
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ statusBarStateController.setState(StatusBarState.KEYGUARD)
+ runCurrent()
+
+ // THEN
+ Assert.assertFalse(hmp.shouldHeadsUpBecomePinnedWrapper(entry))
+ }
+
+ @Test
+ fun shouldHeadsUpBecomePinned_shadeExpanded_false() =
+ testScope.runTest {
+ // GIVEN
+ val statusBarStateController = FakeStatusBarStateController()
+ whenever(mShadeInteractor.isAnyExpanded).thenReturn(MutableStateFlow(true))
+ val hmp =
+ TestableHeadsUpManagerPhone(
+ mContext,
+ mHeadsUpManagerLogger,
+ mGroupManager,
+ mVSProvider,
+ statusBarStateController,
+ mBypassController,
+ mConfigurationController,
+ mGlobalSettings,
+ mSystemClock,
+ mExecutor,
+ mAccessibilityManagerWrapper,
+ mUiEventLogger,
+ mJavaAdapter,
+ mShadeInteractor,
+ mAvalancheController
+ )
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ statusBarStateController.setState(StatusBarState.SHADE)
+ runCurrent()
+
+ // THEN
+ Assert.assertFalse(hmp.shouldHeadsUpBecomePinnedWrapper(entry))
+ }
+
+ companion object {
+ @get:Parameters(name = "{0}")
+ val flags: List<FlagsParameterization>
+ get() = buildList {
+ addAll(FlagsParameterization.allCombinationsOf(NotificationThrottleHun.FLAG_NAME))
+ addAll(
+ FlagsParameterization.allCombinationsOf(NotificationsHeadsUpRefactor.FLAG_NAME)
+ )
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt
index f1fed1904bc5..88431f004665 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt
@@ -20,7 +20,7 @@ import android.app.NotificationManager.Policy
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.settingslib.statusbar.notification.data.repository.updateNotificationPolicy
+import com.android.settingslib.notification.data.repository.updateNotificationPolicy
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.kt
new file mode 100644
index 000000000000..1b704b4c4902
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.kt
@@ -0,0 +1,236 @@
+/*
+ * 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.util.service
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.dump.dumpManager
+import com.android.systemui.testKosmos
+import com.android.systemui.util.service.ObservableServiceConnection.DISCONNECT_REASON_DISCONNECTED
+import com.android.systemui.util.time.fakeSystemClock
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PersistentConnectionManagerTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+
+ private val fakeClock = kosmos.fakeSystemClock
+ private val fakeExecutor = kosmos.fakeExecutor
+
+ private class Proxy {
+ // Fake proxy class
+ }
+
+ private val connection: ObservableServiceConnection<Proxy> = mock()
+ private val observer: Observer = mock()
+
+ private val underTest: PersistentConnectionManager<Proxy> by lazy {
+ PersistentConnectionManager(
+ /* clock = */ fakeClock,
+ /* bgExecutor = */ fakeExecutor,
+ /* dumpManager = */ kosmos.dumpManager,
+ /* dumpsysName = */ DUMPSYS_NAME,
+ /* serviceConnection = */ connection,
+ /* maxReconnectAttempts = */ MAX_RETRIES,
+ /* baseReconnectDelayMs = */ RETRY_DELAY_MS,
+ /* minConnectionDurationMs = */ CONNECTION_MIN_DURATION_MS,
+ /* observer = */ observer
+ )
+ }
+
+ /** Validates initial connection. */
+ @Test
+ fun testConnect() {
+ underTest.start()
+ captureCallbackAndVerifyBind(connection).onConnected(connection, mock<Proxy>())
+ }
+
+ /** Ensures reconnection on disconnect. */
+ @Test
+ fun testExponentialRetryOnDisconnect() {
+ underTest.start()
+
+ // IF service is connected...
+ val captor = argumentCaptor<ObservableServiceConnection.Callback<Proxy>>()
+ verify(connection, times(1)).bind()
+ verify(connection).addCallback(captor.capture())
+ val callback = captor.lastValue
+ callback.onConnected(connection, mock<Proxy>())
+
+ // ...AND service becomes disconnected within CONNECTION_MIN_DURATION_MS
+ callback.onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+
+ // THEN verify we retry to bind after the retry delay. (RETRY #1)
+ verify(connection, times(1)).bind()
+ fakeClock.advanceTime(RETRY_DELAY_MS.toLong())
+ verify(connection, times(2)).bind()
+
+ // IF service becomes disconnected for a second time after first retry...
+ callback.onConnected(connection, mock<Proxy>())
+ callback.onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+
+ // THEN verify we retry after a longer delay of 2 * RETRY_DELAY_MS (RETRY #2)
+ fakeClock.advanceTime(RETRY_DELAY_MS.toLong())
+ verify(connection, times(2)).bind()
+ fakeClock.advanceTime(RETRY_DELAY_MS.toLong())
+ verify(connection, times(3)).bind()
+
+ // IF service becomes disconnected for a third time after the second retry...
+ callback.onConnected(connection, mock<Proxy>())
+ callback.onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+
+ // THEN verify we retry after a longer delay of 4 * RETRY_DELAY_MS (RETRY #3)
+ fakeClock.advanceTime(3 * RETRY_DELAY_MS.toLong())
+ verify(connection, times(3)).bind()
+ fakeClock.advanceTime(RETRY_DELAY_MS.toLong())
+ verify(connection, times(4)).bind()
+ }
+
+ @Test
+ fun testDoesNotRetryAfterMaxRetries() {
+ underTest.start()
+
+ val captor = argumentCaptor<ObservableServiceConnection.Callback<Proxy>>()
+ verify(connection).addCallback(captor.capture())
+ val callback = captor.lastValue
+
+ // IF we retry MAX_TRIES times...
+ for (attemptCount in 0 until MAX_RETRIES + 1) {
+ verify(connection, times(attemptCount + 1)).bind()
+ callback.onConnected(connection, mock<Proxy>())
+ callback.onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+ fakeClock.advanceTime(Math.scalb(RETRY_DELAY_MS.toDouble(), attemptCount).toLong())
+ }
+
+ // THEN we should not retry again after the last attempt.
+ fakeExecutor.advanceClockToLast()
+ verify(connection, times(MAX_RETRIES + 1)).bind()
+ }
+
+ @Test
+ fun testEnsureNoRetryIfServiceNeverConnectsAfterRetry() {
+ underTest.start()
+
+ with(captureCallbackAndVerifyBind(connection)) {
+ // IF service initially connects and then disconnects...
+ onConnected(connection, mock<Proxy>())
+ onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+ fakeExecutor.advanceClockToLast()
+ fakeExecutor.runAllReady()
+
+ // ...AND we retry once.
+ verify(connection, times(1)).bind()
+
+ // ...AND service disconnects after initial retry without ever connecting again.
+ onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+ fakeExecutor.advanceClockToLast()
+ fakeExecutor.runAllReady()
+
+ // THEN verify another retry is not triggered.
+ verify(connection, times(1)).bind()
+ }
+ }
+
+ @Test
+ fun testEnsureNoRetryIfServiceNeverInitiallyConnects() {
+ underTest.start()
+
+ with(captureCallbackAndVerifyBind(connection)) {
+ // IF service never connects and we just receive the disconnect signal...
+ onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+ fakeExecutor.advanceClockToLast()
+ fakeExecutor.runAllReady()
+
+ // THEN do not retry
+ verify(connection, never()).bind()
+ }
+ }
+
+ /** Ensures manual unbind does not reconnect. */
+ @Test
+ fun testStopDoesNotReconnect() {
+ underTest.start()
+
+ val connectionCallbackCaptor = argumentCaptor<ObservableServiceConnection.Callback<Proxy>>()
+ verify(connection).addCallback(connectionCallbackCaptor.capture())
+ verify(connection).bind()
+ clearInvocations(connection)
+
+ underTest.stop()
+ fakeExecutor.advanceClockToNext()
+ fakeExecutor.runAllReady()
+ verify(connection, never()).bind()
+ }
+
+ /** Ensures rebind on package change. */
+ @Test
+ fun testAttemptOnPackageChange() {
+ underTest.start()
+
+ verify(connection).bind()
+
+ val callbackCaptor = argumentCaptor<Observer.Callback>()
+ captureCallbackAndVerifyBind(connection).onConnected(connection, mock<Proxy>())
+
+ verify(observer).addCallback(callbackCaptor.capture())
+ callbackCaptor.lastValue.onSourceChanged()
+ verify(connection).bind()
+ }
+
+ @Test
+ fun testAddConnectionCallback() {
+ val connectionCallback: ObservableServiceConnection.Callback<Proxy> = mock()
+ underTest.addConnectionCallback(connectionCallback)
+ verify(connection).addCallback(connectionCallback)
+ }
+
+ @Test
+ fun testRemoveConnectionCallback() {
+ val connectionCallback: ObservableServiceConnection.Callback<Proxy> = mock()
+ underTest.removeConnectionCallback(connectionCallback)
+ verify(connection).removeCallback(connectionCallback)
+ }
+
+ /** Helper method to capture the [ObservableServiceConnection.Callback] */
+ private fun captureCallbackAndVerifyBind(
+ mConnection: ObservableServiceConnection<Proxy>,
+ ): ObservableServiceConnection.Callback<Proxy> {
+
+ val connectionCallbackCaptor = argumentCaptor<ObservableServiceConnection.Callback<Proxy>>()
+ verify(mConnection).addCallback(connectionCallbackCaptor.capture())
+ verify(mConnection).bind()
+ clearInvocations(mConnection)
+
+ return connectionCallbackCaptor.lastValue
+ }
+
+ companion object {
+ private const val MAX_RETRIES = 3
+ private const val RETRY_DELAY_MS = 1000
+ private const val CONNECTION_MIN_DURATION_MS = 5000
+ private const val DUMPSYS_NAME = "dumpsys_name"
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt
new file mode 100644
index 000000000000..142631e6aa07
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.volume.domain.interactor
+
+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.testKosmos
+import com.android.systemui.volume.data.repository.audioSharingRepository
+import com.google.common.truth.Truth
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class AudioSharingInteractorTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ lateinit var underTest: AudioSharingInteractor
+
+ @Before
+ fun setUp() {
+ with(kosmos) { underTest = audioSharingInteractor }
+ }
+
+ @Test
+ fun volumeChanges_returnVolume() {
+ with(kosmos) {
+ testScope.runTest {
+ with(audioSharingRepository) {
+ setSecondaryGroupId(TEST_GROUP_ID)
+ setVolumeMap(mapOf(TEST_GROUP_ID to TEST_VOLUME))
+ }
+ val volume by collectLastValue(underTest.volume)
+ runCurrent()
+
+ Truth.assertThat(volume).isEqualTo(TEST_VOLUME)
+ }
+ }
+ }
+
+ @Test
+ fun volumeChanges_returnNull() {
+ with(kosmos) {
+ testScope.runTest {
+ with(audioSharingRepository) {
+ setSecondaryGroupId(TEST_GROUP_ID_INVALID)
+ setVolumeMap(mapOf(TEST_GROUP_ID to TEST_VOLUME))
+ }
+ val volume by collectLastValue(underTest.volume)
+ runCurrent()
+
+ Truth.assertThat(volume).isNull()
+ }
+ }
+ }
+
+ @Test
+ fun volumeChanges_returnDefaultVolume() {
+ with(kosmos) {
+ testScope.runTest {
+ with(audioSharingRepository) {
+ setSecondaryGroupId(TEST_GROUP_ID)
+ setVolumeMap(emptyMap())
+ }
+ val volume by collectLastValue(underTest.volume)
+ runCurrent()
+
+ Truth.assertThat(volume).isEqualTo(TEST_VOLUME_DEFAULT)
+ }
+ }
+ }
+
+ private companion object {
+ const val TEST_GROUP_ID = 1
+ const val TEST_GROUP_ID_INVALID = -1
+ const val TEST_VOLUME = 10
+ const val TEST_VOLUME_DEFAULT = 20
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorTest.kt
index 6e49e431bd80..1ea8a6b8d9e5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorTest.kt
@@ -20,7 +20,7 @@ import android.media.AudioManager
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.settingslib.statusbar.notification.data.repository.updateNotificationPolicy
+import com.android.settingslib.notification.data.repository.updateNotificationPolicy
import com.android.settingslib.volume.domain.interactor.AudioVolumeInteractor
import com.android.settingslib.volume.shared.model.AudioStream
import com.android.settingslib.volume.shared.model.RingerMode
@@ -35,6 +35,7 @@ import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -48,6 +49,20 @@ class AudioVolumeInteractorTest : SysuiTestCase() {
private val underTest: AudioVolumeInteractor =
with(kosmos) { AudioVolumeInteractor(audioRepository, notificationsSoundPolicyInteractor) }
+ @Before
+ fun setUp() =
+ with(kosmos) {
+ audioRepository.setAudioStreamModel(
+ audioRepository.getAudioStream(audioStream).value.copy(isAffectedByMute = true)
+ )
+ audioRepository.setAudioStreamModel(
+ audioRepository
+ .getAudioStream(AudioStream(AudioManager.STREAM_RING))
+ .value
+ .copy(isAffectedByMute = true)
+ )
+ }
+
@Test
fun setMuted_mutesStream() {
with(kosmos) {
@@ -189,10 +204,14 @@ class AudioVolumeInteractorTest : SysuiTestCase() {
testScope.runTest {
val audioStreamModel by collectLastValue(underTest.getAudioStream(audioStream))
audioRepository.setAudioStreamModel(
- audioStreamModel!!.copy(isAffectedByMute = false)
+ audioStreamModel!!.copy(isAffectedByMute = false, isMuted = false)
)
+ underTest.setMuted(audioStream, true)
+ runCurrent()
+
assertThat(audioStreamModel!!.isAffectedByMute).isFalse()
+ assertThat(audioStreamModel!!.isMuted).isFalse()
}
}
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialog.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialog.java
index 9e5db73cf885..cd864026207b 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialog.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialog.java
@@ -26,6 +26,7 @@ import com.android.systemui.plugins.annotations.ProvidesInterface;
@DependsOn(target = Callback.class)
public interface VolumeDialog extends Plugin {
String ACTION = "com.android.systemui.action.PLUGIN_VOLUME";
+ String ACTION_VOLUME_UNDO = "com.android.systemui.volume.ACTION_VOLUME_UNDO";
int VERSION = 1;
void init(int windowType, Callback callback);
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
index c7998f089a6d..4812ff03ef36 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
@@ -50,8 +50,8 @@ interface ClockProvider {
/** Initializes and returns the target clock design */
fun createClock(settings: ClockSettings): ClockController
- /** A static thumbnail for rendering in some examples */
- fun getClockThumbnail(id: ClockId): Drawable?
+ /** Settings configuration parameters for the clock */
+ fun getClockPickerConfig(id: ClockId): ClockPickerConfig
}
/** Interface for controlling an active clock */
@@ -133,6 +133,7 @@ class DefaultClockFaceLayout(val view: View) : ClockFaceLayout {
// both small and large clock should have a container (RelativeLayout in
// SimpleClockFaceController)
override val views = listOf(view)
+
override fun applyConstraints(constraints: ConstraintSet): ConstraintSet {
if (views.size != 1) {
throw IllegalArgumentException(
@@ -267,6 +268,25 @@ data class ClockMetadata(
val clockId: ClockId,
)
+data class ClockPickerConfig(
+ val id: String,
+
+ /** Localized name of the clock */
+ val name: String,
+
+ /** Localized accessibility description for the clock */
+ val description: String,
+
+ /* Static & lightweight thumbnail version of the clock */
+ val thumbnail: Drawable,
+
+ /** True if the clock will react to tone changes in the seed color */
+ val isReactiveToTone: Boolean = true,
+
+ /** True if the clock is capable of chagning style in reaction to touches */
+ val isReactiveToTouch: Boolean = false,
+)
+
/** Render configuration for the full clock. Modifies the way systemUI behaves with this clock. */
data class ClockConfig(
val id: String,
@@ -280,7 +300,7 @@ data class ClockConfig(
/** Transition to AOD should move smartspace like large clock instead of small clock */
val useAlternateSmartspaceAODTransition: Boolean = false,
- /** True if the clock will react to tone changes in the seed color. */
+ @Deprecated("TODO(b/352049256): Remove")
val isReactiveToTone: Boolean = true,
/** True if the clock is large frame clock, which will use weather in compose. */
diff --git a/packages/SystemUI/res-product/values-fr-rCA/strings.xml b/packages/SystemUI/res-product/values-fr-rCA/strings.xml
index 1b6c6099b89d..15d3606977cb 100644
--- a/packages/SystemUI/res-product/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-product/values-fr-rCA/strings.xml
@@ -46,9 +46,9 @@
<string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Votre téléphone fonctionne normalement maintenant.\nTouchez pour en savoir plus"</string>
<string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Votre appareil fonctionne normalement maintenant.\nTouchez pour en savoir plus"</string>
<string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Votre tablette fonctionne normalement maintenant.\nTouchez pour en savoir plus."</string>
- <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Votre téléphone surchauffait et s\'est éteint afin de se refroidir. Il fonctionne normalement maintenant.\n\nIl peut surchauffer si vous :\n • utilisez. des applications qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n • téléchargez ou téléversez des fichiers lourds \n • si vous l\'utilisez lors de températures élevées."</string>
- <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Votre téléphone surchauffait et s\'est éteint afin de se refroidir. Il fonctionne normalement maintenant.\n\nIl peut surchauffer si vous :\n • utilisez. des applications qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n • téléchargez ou téléversez des fichiers lourds \n • ou si vous l\'utilisez lors de températures élevées."</string>
- <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Votre tablette surchauffait et s\'est éteinte afin de se refroidir. Elle fonctionne normalement maintenant.\n\nElle peut surchauffer si vous :\n • utilisez. des applications qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n • téléchargez ou téléversez des fichiers lourds \n • si vous l\'utilisez lors de températures élevées."</string>
+ <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Votre téléphone surchauffait et s\'est éteint afin de se refroidir. Il fonctionne normalement maintenant.\n\nIl peut surchauffer si vous :\n • utilisez. des applis qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n • téléchargez ou téléversez des fichiers lourds \n • si vous l\'utilisez lors de températures élevées."</string>
+ <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Votre téléphone surchauffait et s\'est éteint afin de se refroidir. Il fonctionne normalement maintenant.\n\nIl peut surchauffer si vous :\n • utilisez. des applis qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n • téléchargez ou téléversez des fichiers lourds \n • ou si vous l\'utilisez lors de températures élevées."</string>
+ <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Votre tablette surchauffait et s\'est éteinte afin de se refroidir. Elle fonctionne normalement maintenant.\n\nElle peut surchauffer si vous :\n • utilisez. des applis qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n • téléchargez ou téléversez des fichiers lourds \n • si vous l\'utilisez lors de températures élevées."</string>
<string name="high_temp_title" product="default" msgid="5365000411304924115">"Le téléphone surchauffe"</string>
<string name="high_temp_title" product="device" msgid="6622009907401563664">"L\'appareil surchauffe"</string>
<string name="high_temp_title" product="tablet" msgid="9039733706606446616">"La tablette surchauffe"</string>
diff --git a/packages/SystemUI/res-product/values-or/strings.xml b/packages/SystemUI/res-product/values-or/strings.xml
index a89dd7b78da1..4a6696869bd6 100644
--- a/packages/SystemUI/res-product/values-or/strings.xml
+++ b/packages/SystemUI/res-product/values-or/strings.xml
@@ -33,7 +33,7 @@
<string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଭୁଲ ପ୍ରୟାସ ପରେ, ଏହି ୟୁଜର ପ୍ରୋଫାଇଲ୍କୁ କାଢ଼ି ଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
<string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"ଆପଣ ଫୋନକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଭୁଲ ପ୍ରୟାସ ପରେ, ଏହି ୟୁଜର ପ୍ରୋଫାଇଲକୁ କାଢ଼ି ଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
<string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ୟୁଜରଙ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହାଦ୍ୱାରା ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
- <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"ଆପଣ ଫୋନ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ୍ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହାଦ୍ୱାରା ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"ଆପଣ ଫୋନକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ୟୁଜରଙ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହା ଦ୍ୱାରା ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହେବ।"</string>
<string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"ଆପଣ ଟାବ୍‌ଲେଟ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ୱାର୍କ ପ୍ରୋଫାଇଲ୍‌କୁ ବାହାର କରିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
<string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"ଆପଣ ଫୋନ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ୱାର୍କ ପ୍ରୋଫାଇଲ୍‌କୁ ବାହାର କରିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"ଆପଣ ଟାବ୍‌ଲେଟ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବାକୁ<xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। କାର୍ଯ୍ୟ ପ୍ରୋଫାଇଲ୍ ବାହାର କରିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
diff --git a/packages/SystemUI/res/layout/alert_dialog_systemui.xml b/packages/SystemUI/res/layout/alert_dialog_systemui.xml
index fd0623812745..14751ef901c8 100644
--- a/packages/SystemUI/res/layout/alert_dialog_systemui.xml
+++ b/packages/SystemUI/res/layout/alert_dialog_systemui.xml
@@ -31,7 +31,6 @@
android:id="@*android:id/contentPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="48dp"
android:paddingStart="@dimen/dialog_side_padding"
android:paddingEnd="@dimen/dialog_side_padding"
>
diff --git a/packages/SystemUI/res/layout/app_clips_screenshot.xml b/packages/SystemUI/res/layout/app_clips_screenshot.xml
index 6d4e410b3397..5191895549b6 100644
--- a/packages/SystemUI/res/layout/app_clips_screenshot.xml
+++ b/packages/SystemUI/res/layout/app_clips_screenshot.xml
@@ -16,6 +16,7 @@
-->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="@null"
@@ -30,9 +31,10 @@
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:background="@drawable/overlay_button_background"
+ android:backgroundTint="?androidprv:attr/materialColorPrimary"
android:paddingHorizontal="24dp"
android:text="@string/app_clips_save_add_to_note"
- android:textColor="?android:textColorSecondary"
+ android:textColor="?androidprv:attr/materialColorOnPrimary"
app:layout_constraintBottom_toTopOf="@id/preview"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -58,6 +60,7 @@
android:layout_marginStart="16dp"
android:checked="true"
android:text="@string/backlinks_include_link"
+ android:textColor="?android:textColorSecondary"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/preview"
app:layout_constraintStart_toEndOf="@id/cancel"
@@ -72,6 +75,7 @@
android:drawablePadding="4dp"
android:gravity="center"
android:paddingHorizontal="8dp"
+ android:textColor="?android:textColorSecondary"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/preview"
app:layout_constraintStart_toEndOf="@id/backlinks_include_data"
diff --git a/packages/SystemUI/res/layout/back.xml b/packages/SystemUI/res/layout/back.xml
index 046aecda44b3..acefaae900c2 100644
--- a/packages/SystemUI/res/layout/back.xml
+++ b/packages/SystemUI/res/layout/back.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/back"
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index 250076950907..65005f840598 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -24,18 +24,29 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/clipboard_overlay_window_name">
- <ImageView
+ <!-- Min edge spacing guideline off of which the preview and actions can be anchored (without
+ this we'd need to express margins as the sum of two different dimens). -->
+ <androidx.constraintlayout.widget.Guideline
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/min_edge_guideline"
+ app:layout_constraintGuide_begin="@dimen/overlay_action_container_minimum_edge_spacing"
+ android:orientation="vertical"/>
+ <!-- Negative horizontal margin because this container background must render beyond the thing
+ it's constrained by (the actions themselves). -->
+ <FrameLayout
android:id="@+id/actions_container_background"
android:visibility="gone"
android:layout_height="0dp"
android:layout_width="0dp"
android:elevation="4dp"
- android:background="@drawable/action_chip_container_background"
- android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
+ android:background="@drawable/shelf_action_chip_container_background"
+ android:layout_marginStart="@dimen/negative_overlay_action_container_minimum_edge_spacing"
+ android:layout_marginEnd="@dimen/negative_overlay_action_container_minimum_edge_spacing"
android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="@+id/actions_container"
- app:layout_constraintEnd_toEndOf="@+id/actions_container"
+ app:layout_constraintStart_toStartOf="@id/min_edge_guideline"
+ app:layout_constraintTop_toTopOf="@id/actions_container"
+ app:layout_constraintEnd_toEndOf="@id/actions_container"
app:layout_constraintBottom_toBottomOf="parent"/>
<HorizontalScrollView
android:id="@+id/actions_container"
@@ -56,10 +67,13 @@
android:id="@+id/actions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:paddingStart="@dimen/shelf_action_chip_margin_start"
+ android:showDividers="middle"
+ android:divider="@drawable/shelf_action_chip_divider"
android:animateLayoutChanges="true">
- <include layout="@layout/overlay_action_chip"
+ <include layout="@layout/shelf_action_chip"
android:id="@+id/share_chip"/>
- <include layout="@layout/overlay_action_chip"
+ <include layout="@layout/shelf_action_chip"
android:id="@+id/remote_copy_chip"/>
</LinearLayout>
</HorizontalScrollView>
@@ -73,7 +87,7 @@
android:layout_marginBottom="@dimen/overlay_preview_container_margin"
android:elevation="7dp"
android:background="@drawable/overlay_border"
- app:layout_constraintStart_toStartOf="@id/actions_container_background"
+ app:layout_constraintStart_toStartOf="@id/min_edge_guideline"
app:layout_constraintTop_toTopOf="@id/clipboard_preview"
app:layout_constraintEnd_toEndOf="@id/clipboard_preview"
app:layout_constraintBottom_toBottomOf="@id/actions_container_background"/>
diff --git a/packages/SystemUI/res/layout/clipboard_overlay2.xml b/packages/SystemUI/res/layout/clipboard_overlay2.xml
deleted file mode 100644
index 65005f840598..000000000000
--- a/packages/SystemUI/res/layout/clipboard_overlay2.xml
+++ /dev/null
@@ -1,202 +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.
- -->
-<com.android.systemui.clipboardoverlay.ClipboardOverlayView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/clipboard_ui"
- android:theme="@style/FloatingOverlay"
- android:alpha="0"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:contentDescription="@string/clipboard_overlay_window_name">
- <!-- Min edge spacing guideline off of which the preview and actions can be anchored (without
- this we'd need to express margins as the sum of two different dimens). -->
- <androidx.constraintlayout.widget.Guideline
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/min_edge_guideline"
- app:layout_constraintGuide_begin="@dimen/overlay_action_container_minimum_edge_spacing"
- android:orientation="vertical"/>
- <!-- Negative horizontal margin because this container background must render beyond the thing
- it's constrained by (the actions themselves). -->
- <FrameLayout
- android:id="@+id/actions_container_background"
- android:visibility="gone"
- android:layout_height="0dp"
- android:layout_width="0dp"
- android:elevation="4dp"
- android:background="@drawable/shelf_action_chip_container_background"
- android:layout_marginStart="@dimen/negative_overlay_action_container_minimum_edge_spacing"
- android:layout_marginEnd="@dimen/negative_overlay_action_container_minimum_edge_spacing"
- android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
- app:layout_constraintStart_toStartOf="@id/min_edge_guideline"
- app:layout_constraintTop_toTopOf="@id/actions_container"
- app:layout_constraintEnd_toEndOf="@id/actions_container"
- app:layout_constraintBottom_toBottomOf="parent"/>
- <HorizontalScrollView
- android:id="@+id/actions_container"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginEnd="@dimen/overlay_action_container_margin_horizontal"
- android:paddingEnd="@dimen/overlay_action_container_padding_end"
- android:paddingVertical="@dimen/overlay_action_container_padding_vertical"
- android:elevation="4dp"
- android:scrollbars="none"
- app:layout_constraintHorizontal_bias="0"
- app:layout_constraintWidth_percent="1.0"
- app:layout_constraintWidth_max="wrap"
- app:layout_constraintStart_toEndOf="@+id/preview_border"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/actions_container_background">
- <LinearLayout
- android:id="@+id/actions"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingStart="@dimen/shelf_action_chip_margin_start"
- android:showDividers="middle"
- android:divider="@drawable/shelf_action_chip_divider"
- android:animateLayoutChanges="true">
- <include layout="@layout/shelf_action_chip"
- android:id="@+id/share_chip"/>
- <include layout="@layout/shelf_action_chip"
- android:id="@+id/remote_copy_chip"/>
- </LinearLayout>
- </HorizontalScrollView>
- <View
- android:id="@+id/preview_border"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginStart="@dimen/overlay_preview_container_margin"
- android:layout_marginTop="@dimen/overlay_border_width_neg"
- android:layout_marginEnd="@dimen/overlay_border_width_neg"
- android:layout_marginBottom="@dimen/overlay_preview_container_margin"
- android:elevation="7dp"
- android:background="@drawable/overlay_border"
- app:layout_constraintStart_toStartOf="@id/min_edge_guideline"
- app:layout_constraintTop_toTopOf="@id/clipboard_preview"
- app:layout_constraintEnd_toEndOf="@id/clipboard_preview"
- app:layout_constraintBottom_toBottomOf="@id/actions_container_background"/>
- <FrameLayout
- android:id="@+id/clipboard_preview"
- android:layout_width="@dimen/clipboard_preview_size"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/overlay_border_width"
- android:layout_marginBottom="@dimen/overlay_border_width"
- android:layout_gravity="center"
- android:elevation="7dp"
- android:background="@drawable/overlay_preview_background"
- android:clipChildren="true"
- android:clipToOutline="true"
- android:clipToPadding="true"
- app:layout_constraintStart_toStartOf="@id/preview_border"
- app:layout_constraintBottom_toBottomOf="@id/preview_border">
- <TextView android:id="@+id/text_preview"
- android:textFontWeight="500"
- android:padding="8dp"
- android:gravity="center|start"
- android:ellipsize="end"
- android:autoSizeTextType="uniform"
- android:autoSizeMinTextSize="@dimen/clipboard_overlay_min_font"
- android:autoSizeMaxTextSize="@dimen/clipboard_overlay_max_font"
- android:textColor="?attr/overlayButtonTextColor"
- android:textColorLink="?attr/overlayButtonTextColor"
- android:background="?androidprv:attr/colorAccentSecondary"
- android:layout_width="@dimen/clipboard_preview_size"
- android:layout_height="@dimen/clipboard_preview_size"/>
- <ImageView
- android:id="@+id/image_preview"
- android:scaleType="fitCenter"
- android:adjustViewBounds="true"
- android:contentDescription="@string/clipboard_image_preview"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- <TextView
- android:id="@+id/hidden_preview"
- android:visibility="gone"
- android:textFontWeight="500"
- android:padding="8dp"
- android:gravity="center"
- android:textSize="14sp"
- android:textColor="?attr/overlayButtonTextColor"
- android:background="?androidprv:attr/colorAccentSecondary"
- android:layout_width="@dimen/clipboard_preview_size"
- android:layout_height="@dimen/clipboard_preview_size"/>
- </FrameLayout>
- <LinearLayout
- android:id="@+id/minimized_preview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:visibility="gone"
- android:elevation="7dp"
- android:padding="8dp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
- android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
- android:background="@drawable/clipboard_minimized_background">
- <ImageView
- android:src="@drawable/ic_content_paste"
- android:tint="?attr/overlayButtonTextColor"
- android:layout_width="24dp"
- android:layout_height="24dp"/>
- <ImageView
- android:src="@*android:drawable/ic_chevron_end"
- android:tint="?attr/overlayButtonTextColor"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:paddingEnd="-8dp"
- android:paddingStart="-4dp"/>
- </LinearLayout>
- <androidx.constraintlayout.widget.Barrier
- android:id="@+id/clipboard_content_top"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:barrierDirection="top"
- app:constraint_referenced_ids="clipboard_preview,minimized_preview"/>
- <androidx.constraintlayout.widget.Barrier
- android:id="@+id/clipboard_content_end"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- app:barrierDirection="end"
- app:constraint_referenced_ids="clipboard_preview,minimized_preview"/>
- <FrameLayout
- android:id="@+id/dismiss_button"
- android:layout_width="@dimen/overlay_dismiss_button_tappable_size"
- android:layout_height="@dimen/overlay_dismiss_button_tappable_size"
- android:elevation="10dp"
- android:visibility="gone"
- android:alpha="0"
- app:layout_constraintStart_toEndOf="@id/clipboard_content_end"
- app:layout_constraintEnd_toEndOf="@id/clipboard_content_end"
- app:layout_constraintTop_toTopOf="@id/clipboard_content_top"
- app:layout_constraintBottom_toTopOf="@id/clipboard_content_top"
- android:contentDescription="@string/clipboard_dismiss_description">
- <ImageView
- android:id="@+id/dismiss_image"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_margin="@dimen/overlay_dismiss_button_margin"
- android:background="@drawable/circular_background"
- android:backgroundTint="?androidprv:attr/materialColorPrimaryFixedDim"
- android:tint="?androidprv:attr/materialColorOnPrimaryFixed"
- android:padding="4dp"
- android:src="@drawable/ic_close"/>
- </FrameLayout>
-</com.android.systemui.clipboardoverlay.ClipboardOverlayView> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/contextual.xml b/packages/SystemUI/res/layout/contextual.xml
index 2cd7926b6e46..ac840d8ecabe 100644
--- a/packages/SystemUI/res/layout/contextual.xml
+++ b/packages/SystemUI/res/layout/contextual.xml
@@ -24,7 +24,7 @@
android:clipChildren="false"
android:clipToPadding="false"
>
- <com.android.systemui.navigationbar.buttons.KeyButtonView
+ <com.android.systemui.navigationbar.views.buttons.KeyButtonView
android:id="@+id/menu"
android:layout_height="match_parent"
android:layout_width="match_parent"
@@ -47,7 +47,7 @@
android:layout_height="match_parent"
android:visibility="invisible"
/>
- <com.android.systemui.navigationbar.buttons.KeyButtonView
+ <com.android.systemui.navigationbar.views.buttons.KeyButtonView
android:id="@+id/accessibility_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/custom_key.xml b/packages/SystemUI/res/layout/custom_key.xml
index dc65777542e2..0b0f4fab5c35 100644
--- a/packages/SystemUI/res/layout/custom_key.xml
+++ b/packages/SystemUI/res/layout/custom_key.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/navigation_side_padding"
diff --git a/packages/SystemUI/res/layout/dream_overlay_container.xml b/packages/SystemUI/res/layout/dream_overlay_container.xml
index dcd3fa66ef04..be1652b60250 100644
--- a/packages/SystemUI/res/layout/dream_overlay_container.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_container.xml
@@ -21,19 +21,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <ImageView
- android:id="@+id/glanceable_hub_handle"
- android:layout_width="4dp"
- android:layout_height="220dp"
- android:layout_centerVertical="true"
- android:layout_marginEnd="12dp"
- android:background="@drawable/hub_handle"
- android:visibility="gone"
- android:contentDescription="UI indicator for swiping open the glanceable hub"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/dream_overlay_content"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/home.xml b/packages/SystemUI/res/layout/home.xml
index 84eed6a233f8..227e390ed0bc 100644
--- a/packages/SystemUI/res/layout/home.xml
+++ b/packages/SystemUI/res/layout/home.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/home"
diff --git a/packages/SystemUI/res/layout/ime_switcher.xml b/packages/SystemUI/res/layout/ime_switcher.xml
index a2c8308b7f70..fa9a12b54e51 100644
--- a/packages/SystemUI/res/layout/ime_switcher.xml
+++ b/packages/SystemUI/res/layout/ime_switcher.xml
@@ -15,7 +15,7 @@
~ limitations under the License
-->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ime_switcher"
android:layout_width="@dimen/navigation_key_width"
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
index 2cfd644e9d62..45a4af92339c 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
@@ -85,7 +85,7 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
+ android:layout_gravity="center_vertical|start"
android:orientation="horizontal">
<Button
android:id="@+id/shortcut_system"
diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml
index 0bb622bb9c4f..443e4e3bbe87 100644
--- a/packages/SystemUI/res/layout/menu_ime.xml
+++ b/packages/SystemUI/res/layout/menu_ime.xml
@@ -25,7 +25,7 @@
are placed inside a view that has a size controlled by weight. Ensure weight is large enough to
support icon size. Use layout_width=navigation_side_padding like other navbar buttons. -->
- <com.android.systemui.navigationbar.buttons.KeyButtonView
+ <com.android.systemui.navigationbar.views.buttons.KeyButtonView
android:id="@+id/menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -43,7 +43,7 @@
android:paddingStart="0dp"
android:paddingEnd="0dp"
/>
- <com.android.systemui.navigationbar.buttons.KeyButtonView
+ <com.android.systemui.navigationbar.views.buttons.KeyButtonView
android:id="@+id/rotate_suggestion"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -51,7 +51,7 @@
android:scaleType="centerInside"
android:contentDescription="@string/accessibility_rotate_button"
/>
- <com.android.systemui.navigationbar.buttons.KeyButtonView
+ <com.android.systemui.navigationbar.views.buttons.KeyButtonView
android:id="@+id/accessibility_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 5f59e781ef5e..a868ec488675 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -17,7 +17,7 @@
*/
-->
-<com.android.systemui.navigationbar.NavigationBarView
+<com.android.systemui.navigationbar.views.NavigationBarView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/navigation_bar_view"
android:layout_height="match_parent"
@@ -26,11 +26,11 @@
android:clipToPadding="false"
android:background="@drawable/system_bar_background">
- <com.android.systemui.navigationbar.NavigationBarInflaterView
+ <com.android.systemui.navigationbar.views.NavigationBarInflaterView
android:id="@+id/navigation_inflater"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false" />
-</com.android.systemui.navigationbar.NavigationBarView>
+</com.android.systemui.navigationbar.views.NavigationBarView>
diff --git a/packages/SystemUI/res/layout/navigation_bar_window.xml b/packages/SystemUI/res/layout/navigation_bar_window.xml
index b2473cd82998..9442124bbc3e 100644
--- a/packages/SystemUI/res/layout/navigation_bar_window.xml
+++ b/packages/SystemUI/res/layout/navigation_bar_window.xml
@@ -16,7 +16,7 @@
** limitations under the License.
*/
-->
-<com.android.systemui.navigationbar.NavigationBarFrame
+<com.android.systemui.navigationbar.views.NavigationBarFrame
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_bar_frame"
@@ -24,4 +24,4 @@
android:layout_height="match_parent"
android:layout_width="match_parent">
-</com.android.systemui.navigationbar.NavigationBarFrame>
+</com.android.systemui.navigationbar.views.NavigationBarFrame>
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index 46f238cbe588..5c6c9a4e6e28 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -27,7 +27,7 @@
android:clipToPadding="false"
android:id="@+id/horizontal">
- <com.android.systemui.navigationbar.buttons.NearestTouchFrame
+ <com.android.systemui.navigationbar.views.buttons.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -53,6 +53,6 @@
android:clipToPadding="false"
android:clipChildren="false" />
- </com.android.systemui.navigationbar.buttons.NearestTouchFrame>
+ </com.android.systemui.navigationbar.views.buttons.NearestTouchFrame>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/navigation_layout_vertical.xml b/packages/SystemUI/res/layout/navigation_layout_vertical.xml
index 42e93249e95f..c64e3f7d82a2 100644
--- a/packages/SystemUI/res/layout/navigation_layout_vertical.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_vertical.xml
@@ -25,7 +25,7 @@
android:paddingBottom="@dimen/nav_content_padding"
android:id="@+id/vertical">
- <com.android.systemui.navigationbar.buttons.NearestTouchFrame
+ <com.android.systemui.navigationbar.views.buttons.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -33,7 +33,7 @@
android:clipToPadding="false"
systemui:isVertical="true">
- <com.android.systemui.navigationbar.buttons.ReverseLinearLayout
+ <com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout
android:id="@+id/ends_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -41,7 +41,7 @@
android:clipToPadding="false"
android:clipChildren="false" />
- <com.android.systemui.navigationbar.buttons.ReverseLinearLayout
+ <com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout
android:id="@+id/center_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -50,6 +50,6 @@
android:clipToPadding="false"
android:clipChildren="false" />
- </com.android.systemui.navigationbar.buttons.NearestTouchFrame>
+ </com.android.systemui.navigationbar.views.buttons.NearestTouchFrame>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/recent_apps.xml b/packages/SystemUI/res/layout/recent_apps.xml
index e2b1374b6a78..767e16c1f082 100644
--- a/packages/SystemUI/res/layout/recent_apps.xml
+++ b/packages/SystemUI/res/layout/recent_apps.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/recent_apps"
diff --git a/packages/SystemUI/res/layout/screen_share_dialog.xml b/packages/SystemUI/res/layout/screen_share_dialog.xml
index 2616e8ae25e8..aa083ad9fdea 100644
--- a/packages/SystemUI/res/layout/screen_share_dialog.xml
+++ b/packages/SystemUI/res/layout/screen_share_dialog.xml
@@ -46,7 +46,7 @@
android:layout_marginTop="@dimen/screenrecord_title_margin_top"
android:gravity="center"/>
<Spinner
- android:id="@+id/screen_share_mode_spinner"
+ android:id="@+id/screen_share_mode_options"
android:layout_width="match_parent"
android:layout_height="@dimen/screenrecord_spinner_height"
android:layout_marginTop="@dimen/screenrecord_spinner_margin"
diff --git a/packages/SystemUI/res/layout/screenshot.xml b/packages/SystemUI/res/layout/screenshot.xml
deleted file mode 100644
index c134c8e2d339..000000000000
--- a/packages/SystemUI/res/layout/screenshot.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ 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.
- -->
-<com.android.systemui.screenshot.ScreenshotView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/screenshot_frame"
- android:theme="@style/FloatingOverlay"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:importantForAccessibility="no">
- <ImageView
- android:id="@+id/screenshot_scrolling_scrim"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone"
- android:clickable="true"
- android:importantForAccessibility="no"/>
- <ImageView
- android:id="@+id/screenshot_flash"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone"
- android:elevation="7dp"
- android:src="@android:color/white"/>
- <include layout="@layout/screenshot_static"
- android:id="@+id/screenshot_static"/>
-</com.android.systemui.screenshot.ScreenshotView>
diff --git a/packages/SystemUI/res/layout/window_magnification_settings_view.xml b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
index 12e226a47bb5..afd4fa7a5edd 100644
--- a/packages/SystemUI/res/layout/window_magnification_settings_view.xml
+++ b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
@@ -33,9 +33,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:singleLine="true"
- android:scrollHorizontally="true"
- android:ellipsize="marquee"
+ android:layout_marginEnd="@dimen/magnification_setting_view_item_horizontal_spacing"
android:text="@string/accessibility_magnifier_size"
android:textAppearance="@style/TextAppearance.MagnificationSetting.Title"
android:focusable="true"
@@ -120,9 +118,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:singleLine="true"
- android:scrollHorizontally="true"
- android:ellipsize="marquee"
+ android:layout_marginEnd="@dimen/magnification_setting_view_item_horizontal_spacing"
android:text="@string/accessibility_allow_diagonal_scrolling"
android:textAppearance="@style/TextAppearance.MagnificationSetting.Title"
android:labelFor="@id/magnifier_horizontal_lock_switch"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index e38da0948b3f..adeafbc8eca2 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> het hierdie skermskoot bespeur."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> en ander oop apps het hierdie skermskoot bespeur."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Voeg by nota"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Sluit skakel in"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Skermopnemer"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Verwerk tans skermopname"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Deurlopende kennisgewing vir \'n skermopnamesessie"</string>
@@ -125,25 +126,41 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tik om te bekyk"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Kon nie skermopname stoor nie"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Kon nie skermopname begin nie"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
+ <skip />
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Jy sal ophou om &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; op te neem"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deel tans skerm"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
+ <skip />
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
+ <skip />
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
+ <skip />
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Jy sal ophou om &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; te deel"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Skerm word tans uitgesaai"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Hou op uitsaai?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Jy sal ophou om &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uit te saai"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -192,6 +209,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontsluit met gesig. Druk om voort te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesig is herken. Druk om voort te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesig is herken. Druk die ontsluitikoon om voort te gaan."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Ontsluit met gesig. Tik om voort te gaan."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Gestaaf"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kanselleer stawing"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Meer opsies"</string>
@@ -291,6 +309,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Sluimerskerm"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Moenie Steur Nie"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Geen saamgebinde toestelle beskikbaar nie"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Tik om ’n toestel te koppel of ontkoppel"</string>
@@ -472,6 +492,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Voeg meer legstukke by"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Langdruk om legstukke te pasmaak"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pasmaak legstukke"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Ontsluit om legstukke te pasmaak"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-ikoon vir gedeaktiveerde legstuk"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikoon vir ’n legstuk wat geïnstalleer word"</string>
<string name="edit_widget" msgid="9030848101135393954">"Wysig legstuk"</string>
@@ -490,6 +511,10 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"kies legstuk"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"verwyder legstuk"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plaas gekose legstuk"</string>
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
+ <skip />
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
+ <skip />
<!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
<skip />
<!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
@@ -549,12 +574,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Begin nou"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Geen kennisgewings nie"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Geen nuwe kennisgewings nie"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Aanpasbare kennisgewings is aan"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Jou toestel verlaag nou die volume en verminder opspringers op die skerm vir tot twee minute wanneer jy baie kennisgewings in ’n kort tydperk ontvang."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Skakel af"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ontsluit om ouer kennisgewings te sien"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Hierdie toestel word deur jou ouer bestuur"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Jou organisasie besit hierdie toestel en kan netwerkverkeer monitor"</string>
@@ -720,7 +742,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Verstek"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Outomaties"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Geen klank of vibrasie nie"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Geen klank of vibrasie nie en verskyn laer in gespreksafdeling"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Kan lui of vibreer op grond van toestelinstellings"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Kan lui of vibreer op grond van toestelinstellings. Gesprekke van <xliff:g id="APP_NAME">%1$s</xliff:g> af verskyn by verstek in ’n borrel."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Laat die stelsel bepaal of hierdie kennisgewing \'n klank moet maak of vibreer"</string>
@@ -777,6 +800,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,9 +1377,15 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Word gebruik deur <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Onlangs gebruik deur <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Stelsel"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Stelselkontroles"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Stelselapps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Verrigting van veelvuldige take"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Onlangse apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Verdeelde skerm"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Invoer"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Appkortpaaie"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toeganklikheid"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Kortpadsleutels"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Soekkortpaaie"</string>
@@ -1369,16 +1400,15 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Uitstekende werk!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gaan terug"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Swiep enige plek op die raakpaneel links of regs met drie vingers om terug te gaan."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Raakpaneel wat drie vingers wat regs en links beweeg wys"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Toestelskerm wat animasie vir teruggebaar wys"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Sleutelbordlig"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Vlak %1$d van %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Huiskontroles"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Kry vinnig toegang tot jou huiskontroles as ’n sluimerskerm"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml
index 1b4781d24ebc..1af9fd9c3415 100644
--- a/packages/SystemUI/res/values-af/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Af"</item>
<item msgid="4875147066469902392">"Aan"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Onbeskikbaar"</item>
<item msgid="5044688398303285224">"Af"</item>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 6b024e21d016..fb4c765886b7 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ይህን ቅጽበታዊ ገፅ ዕይታ ለይቷል።"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> እና ሌሎች ክፍት መተግበሪያዎች ይህን ቅጽበታዊ ገፅ ዕይታ ለይተዋል።"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ወደ ማስታወሻ አክል"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"አገናኝ አካትት"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"የማያ መቅረጫ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"የማያ ገፅ ቀረጻን በማሰናዳት ላይ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ለአንድ የማያ ገፅ ቀረጻ ክፍለ-ጊዜ በመካሄድ ያለ ማሳወቂያ"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"ለመመልከት መታ ያድርጉ"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"የማያ ገጽ ቀረጻን ማስቀመጥ ላይ ስህተት"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"የማያ ገፅ ቀረጻን መጀመር ላይ ስህተት"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"እርስዎ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; መቅረጽ ያቆማሉ"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"መቅረጽ አቁም"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ማያ ገፅን በማጋራት ላይ"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ማያ ገፅን ማጋራት ይቁም?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"እርስዎ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ማጋራት ያቆማሉ"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ማጋራት አቁም"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ማያ ገፅን cast በማድረግ ላይ"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"cast ማድረግ ይቁም?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"እርስዎ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; cast ማድረግ ያቆማሉ"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"cast ማድረግ አቁም"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"ዝጋ"</string>
<string name="issuerecord_title" msgid="286627115110121849">"ችግር መመዝገቢያ"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"የአሰራር ችግር አመዘጋገብ"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"ለችግር መሰብሰብ ክፍለ ጊዜ ቀጣይነት ያለው ማሳወቂያ"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"የችግር ምዝገባ ማስቀመጥ ላይ ስህተት"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"ችግር ምዝገባ ማስጀመር ላይ ስህተት"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"በሙሉ ገጽ ዕይታ በማየት ላይ"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"ለመውጣት ከማያ ገፅዎ አናት ወደታች ያንሸራትቱ"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"ገባኝ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ተመለስ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"መነሻ"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"በመልክ ተከፍቷል። ለመቀጠል ይጫኑ።"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"መልክ ተለይቶ ታውቋል። ለመቀጠል ይጫኑ።"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"መልክ ተለይቶ ታውቋል። ለመቀጠል የመክፈቻ አዶውን ይጫኑ።"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"በመልክ ተከፍቷል። ለመቀጠል መታ ያድርጉ።"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"የተረጋገጠ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ማረጋገጥን ሰርዝ"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ተጨማሪ አማራጮች"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"የማያ ገፅ ማቆያ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ኤተርኔት"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"አትረብሽ"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ብሉቱዝ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ምንም የተጣመሩ መሣሪያዎች አይገኝም"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"መሣሪያን ለማገናኘት ወይም ግንኙነቱን ለማቋረጥ መታ ያድርጉ"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ተቀምጧል"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ግንኙነትን አቋርጥ"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ያግብሩ"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"ነገ በራስ-ሰር ያብሩ"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"እንደ ፈጣን ማጋራት እና የእኔን መሣሪያ አግኝ ያሉ ባህሪዎች ብሉቱዝን ይጠቀማሉ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ብሉቱዝ ነገ ጠዋት ይበራል"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ኦዲዮ አጋራ"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ተጨማሪ ምግብሮችን ያክሉ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ምግብሮችን ለማበጀት በረጅሙ ይጫኑ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ምግብሮችን አብጅ"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ምግብሮችን ለማበጀት ይክፈቱ"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"የመተግበሪያ አዶ ለተሰናከለ ምግብር"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"የምግብር የመተግበሪያ አዶ ሲጫን"</string>
<string name="edit_widget" msgid="9030848101135393954">"ምግብርን አርትዕ"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ምግብር ይምረጡ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ምግብር አስወግድ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"በቦታ የተመረጠ ምግብር"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"የማያ ገፅ ቁልፍ ምግብሮች"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ምግብር በመጠቀም መተግበሪያ ለመክፈት እርስዎ መሆንዎን ማረጋገጥ አለብዎት። እንዲሁም የእርስዎ ጡባዊ በተቆለፈበት ጊዜ እንኳን ማንኛውም ሰው እነሱን ማየት እንደሚችል ከግምት ውስጥ ያስገቡ። አንዳንድ ምግብሮች ለማያ ገፅ ቁልፍዎ የታሰቡ ላይሆኑ ይችላሉ እና እዚህ ለማከል አስተማማኝ ላይሆኑ ይችላሉ።"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ገባኝ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ተጠቃሚ ቀይር"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ወደታች ተጎታች ምናሌ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"አሁን ጀምር"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ምንም ማሳወቂያ የለም"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ምንም አዲስ ማሳወቂያዎች የሉም"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ተለማማጅ ማሳወቂያዎች በርተዋል"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"በአጭር የጊዜ ቆይታ ውስጥ ብዙ ማሳወቂያዎች ሲደርሱዎት መሣሪያዎ አሁን ድምፁን ይቀንሳል እና በማያ ገፁ ላይ ብቅ ባዮችን እስከ ሁለት ደቂቃዎች ይቀንሳል።"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"አጥፋ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"የቆዩ ማሳወቂያዎችን ለማየት ይክፈቱ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው።"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"የእርስዎ ድርጅት የዚህ መሣሪያ ባለቤት ነው፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ነባሪ"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"ራስ-ሰር"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"ምንም ድምፅ ወይም ንዝረት የለም"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ምንም ድምፅ ወይም ንዝረት የለም እና በውይይት ክፍል ላይ አይታይም"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"በመሣሪያ ቅንብሮች መሰረት ሊጮህ ወይም ሊነዝር ይችላል"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"በስልክ ቅንብሮች መሰረት ሊጮህ ወይም ሊነዝር ይችላል። የ<xliff:g id="APP_NAME">%1$s</xliff:g> ውይይቶች በነባሪነት አረፋ ይሆናሉ።"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ይህ ማሳወቂያ ድምፅ ወይም ንዝረት መደረግ ካለበት ስርዓቱ እንዲወሰን ያድርጉት"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"ገፅ ወደ ላይ"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"ገፅ ወደ ታች"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"ሰርዝ"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"መነሻ"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"መጨረሻ"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"አስገባ"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"በ<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ጥቅም ላይ እየዋለ ነው"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"በቅርብ ጊዜ በ<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ጥቅም ላይ ውሏል"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ሥርዓት"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"የሥርዓት መቆጣጠሪያዎች"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"የሥርዓት መተግበሪያዎች"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ብዙ ተግባራትን በተመሳሳይ ጊዜ ማከናወን"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"የቅርብ ጊዜ መተግበሪያዎች"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"የተከፈለ ማያ ገፅ"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ግብዓት"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"የመተግበሪያ አቋራጮች"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ተደራሽነት"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"የቁልፍ ሰሌዳ አቋራጮች"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"የፍለጋ አቋራጮች"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"መሰብሰቢያ አዶ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"መዘርጊያ አዶ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ወይም"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"የተመለስ ምልክት"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"የቤት ምልክት"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"የተግባር ቁልፍ"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ተከናውኗል"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"ጥሩ ሠርተዋል!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ወደኋላ ተመለስ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ወደኋላ ለመመለስ በመዳሰሻ ሰሌዳው ላይ በየትኛውም ቦታ ሦስት ጣቶችን በመጠቀም ወደግራ ወይም ወደቀኝ ያንሸራትቱ።"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ሦስት ጣቶች ወደቀኝ እና ግራ ሲንቀሳቀሱ የሚያሳይ የመዳሰሻ ሰሌዳ"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"የኋላ ምልክት እነማ የሚያሳይ የመሣሪያ ማያ ገፅ"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"የቁልፍ ሰሌዳ የጀርባ ብርሃን"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"ደረጃ %1$d ከ %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"የቤት ውስጥ ቁጥጥሮች"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"የቤት መቆጣጠሪያዎችዎን እንደ የገጸ ማያ አሳራፊ በፍጥነት ይድረሱባቸው"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml
index a3c590c33a6f..8bad7ab52583 100644
--- a/packages/SystemUI/res/values-am/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"ጠፍቷል"</item>
<item msgid="4875147066469902392">"በርቷል"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"አይገኝም"</item>
<item msgid="5044688398303285224">"ጠፍቷል"</item>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 610056db75b0..b96793a38938 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"رصَد تطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" لقطة الشاشة هذه."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"رصَد تطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" والتطبيقات المفتوحة الأخرى لقطة الشاشة هذه."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"إضافة إلى الملاحظة"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"تضمين الرابط"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"مسجّل الشاشة"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"جارٍ معالجة تسجيل الشاشة"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"إشعار مستمر لجلسة تسجيل شاشة"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"انقر لعرض التسجيل"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"حدث خطأ أثناء حفظ تسجيل محتوى الشاشة."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"حدث خطأ في بدء تسجيل الشاشة"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"‏سيتم إيقاف تسجيل محتوى &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"إيقاف التسجيل"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"جارِ مشاركة محتوى الشاشة"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"هل تريد إيقاف مشاركة الشاشة؟"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"‏سيتم إيقاف مشاركة محتوى &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"إيقاف المشاركة"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"جارٍ بث محتوى الشاشة"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"هل تريد إيقاف البث؟"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"‏سيتم إيقاف بث محتوى &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"إيقاف البث"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"إغلاق"</string>
<string name="issuerecord_title" msgid="286627115110121849">"مسجّلة المشاكل"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"يجري معالجة تسجيل المشكلة."</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"إشعار بنشاط مستمر في الخلفية لجلسة جمع البيانات حول المشكلة"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"حدث خطأ أثناء حفظ تسجيل المشكلة."</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"حدث خطأ أثناء بدء تسجيل المشكلة."</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"جارٍ العرض بملء الشاشة"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"للخروج، مرِّر سريعًا من أسفل الشاشة لأعلاها"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"حسنًا"</string>
<string name="accessibility_back" msgid="6530104400086152611">"رجوع"</string>
<string name="accessibility_home" msgid="5430449841237966217">"الرئيسية"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"تم فتح الجهاز بالتعرّف على وجهك. اضغط للمتابعة."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"تم التعرّف على الوجه. اضغط للمتابعة."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"تم التعرّف على الوجه. للمتابعة، اضغط على رمز فتح القفل."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"تمّ فتح قفل جهازك باستخدام بصمة الوجه. انقر للمتابعة."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"مصادقة"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"إلغاء المصادقة"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"مزيد من الخيارات"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"شاشة الاستراحة"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"عدم الإزعاج"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"بلوتوث"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"لا يتوفر أي أجهزة مقترنة"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"انقر لربط جهاز أو إلغاء ربطه"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"محفوظ"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"إلغاء الربط"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"تفعيل"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"التفعيل تلقائيًا غدًا"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"‏يُستخدَم البلوتوث في ميزات مثل Quick Share و\"العثور على جهازي\""</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"سيتم تفعيل البلوتوث صباح الغد"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"مشاركة الصوت"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"إضافة المزيد من التطبيقات المصغّرة"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"اضغط مع الاستمرار لتخصيص التطبيقات المصغّرة."</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"تخصيص التطبيقات المصغَّرة"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"يجب فتح القفل لتخصيص التطبيقات المصغّرة"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"رمز التطبيق المصغّر غير المفعّل"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"رمز تطبيق مصغَّر جارٍ تثبيته"</string>
<string name="edit_widget" msgid="9030848101135393954">"تعديل التطبيق المصغَّر"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"اختيار التطبيق المصغّر"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"إزالة التطبيق المصغّر"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"إضافة التطبيق المصغّر المحدَّد"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"التطبيقات المصغّرة المصمَّمة لشاشة القفل"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"لفتح تطبيق باستخدام تطبيق مصغَّر، عليك إثبات هويتك. يُرجى ملاحظة أنّ أي شخص يمكنه الاطّلاع محتوى التطبيقات المصغَّرة، حتى وإن كان جهازك اللوحي مُقفلاً. بعض التطبيقات المصغّرة قد لا تكون مُصمَّمة لإضافتها إلى شاشة القفل، وقد يكون هذا الإجراء غير آمن."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"حسنًا"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تبديل المستخدم"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"القائمة المنسدلة"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"سيتم حذف كل التطبيقات والبيانات في هذه الجلسة."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"تلقائية"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"تلقائي"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"بدون صوت أو اهتزاز"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"بدون صوت أو اهتزاز وتظهر في أسفل قسم المحادثات"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"يمكن إصدار رنين أو اهتزاز بناءً على إعدادات الجهاز"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"يمكن إصدار رنين أو اهتزاز بناءً على إعدادات الجهاز. تظهر المحادثات من \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" كفقاعات تلقائيًا."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"السماح للنظام بتحديد ما إذا يجب اهتزاز الجهاز أو إصدار رنين عند تلقّي هذا الإشعار"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"الرئيسية"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -793,7 +811,7 @@
<string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"البحث في الاختصارات"</string>
<string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"لم يُعثَر على اختصارات."</string>
<string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"النظام"</string>
- <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"إدخال"</string>
+ <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"الإدخال"</string>
<string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"فتح التطبيقات"</string>
<string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"التطبيق الحالي"</string>
<string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"جارٍ عرض نتائج البحث"</string>
@@ -1349,23 +1367,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"قيد الاستخدام في <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"تم الاستخدام مؤخرًا في <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"النظام"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"عناصر التحكّم في النظام"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"تطبيقات النظام"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"تعدُّد المهام"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"التطبيقات المستخدمة مؤخرًا"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"تقسيم الشاشة"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"الإدخال"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"اختصارات التطبيقات"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"التطبيق الحالي"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"تسهيل الاستخدام"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"اختصارات لوحة المفاتيح"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"اختصارات طلبات البحث"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"رمز التصغير"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"رمز التوسيع"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"أو"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"إيماءة الرجوع"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"إيماءة الانتقال إلى الشاشة الرئيسية"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"مفتاح الإجراء"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"تم"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"أحسنت."</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"رجوع"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"للرجوع، مرِّر سريعًا لليسار أو لليمين باستخدام ثلاثة أصابع في أي مكان على لوحة اللمس."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"لوحة لمس تعرض ثلاثة أصابع تتحرك يمينًا ويسارًا"</string>
@@ -1374,4 +1394,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"‏مستوى الإضاءة: %1$d من %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"إدارة المنزل آليًّا"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"يمكنك إدارة المنزل آليًّا بشكل سريع من شاشة الاستراحة"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
index a89650aa6e19..62a6816a5602 100644
--- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"الميزة غير مفعّلة"</item>
<item msgid="4875147066469902392">"الميزة مفعّلة"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"الميزة غير متاحة"</item>
<item msgid="5044688398303285224">"الميزة غير مفعّلة"</item>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 764f4de18474..99c4326b6515 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>এ এই স্ক্ৰীনশ্বটটো চিনাক্ত কৰিছে।"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> আৰু আন খোলা এপ্‌সমূহে এই স্ক্ৰীনশ্বটটো চিনাক্ত কৰিছে।"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"টোকাত যোগ দিয়ক"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"লিংক অন্তৰ্ভুক্ত কৰক"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"স্ক্ৰীন ৰেকৰ্ডাৰ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রীন ৰেকৰ্ডিঙৰ প্ৰক্ৰিয়াকৰণ হৈ আছে"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রীন ৰেকৰ্ডিং ছেশ্বন চলি থকা সময়ত পোৱা জাননী"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"চাবলৈ টিপক"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"ৰেকৰ্ড কৰা স্ক্ৰীন ছেভ কৰোঁতে আসোঁৱাহ হৈছে"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রীন ৰেকৰ্ড কৰা আৰম্ভ কৰোঁতে আসোঁৱাহ হৈছে"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"আপুনি &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ৰেকৰ্ড কৰা বন্ধ কৰিব"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"আপুনি &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; শ্বেয়াৰ কৰা বন্ধ কৰিব"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"আপুনি &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; কাষ্ট কৰা বন্ধ কৰিব"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"ৰেকৰ্ডিং কৰা বন্ধ কৰিবনে?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"বৰ্তমান আপুনি আপোনাৰ গোটেই স্ক্ৰীনখন ৰেকৰ্ড কৰি আছে"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"বৰ্তমান আপুনি <xliff:g id="APP_NAME">%1$s</xliff:g> ৰেকৰ্ড কৰি আছে"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ৰেকৰ্ডিং বন্ধ কৰক"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"স্ক্ৰীন শ্বেয়াৰ কৰি থকা হৈছে"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"স্ক্ৰীন শ্বেয়াৰ কৰা বন্ধ কৰিবনে?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"বৰ্তমান আপুনি আপোনাৰ গোটেই স্ক্ৰীনখন <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>ৰ সৈতে শ্বেয়াৰ কৰি আছে"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"বৰ্তমান আপুনি আপোনাৰ গোটেই স্ক্ৰীনখন এটা এপৰ সৈতে শ্বেয়াৰ কৰি আছে"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"বৰ্তমান আপুনি <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> শ্বেয়াৰ কৰি আছে"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"বৰ্তমান আপুনি এটা এপ্ শ্বেয়াৰ কৰি আছে"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"শ্বেয়াৰ কৰা বন্ধ কৰক"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"স্ক্ৰীন কাষ্ট কৰি থকা হৈছে"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"কাষ্ট কৰা বন্ধ কৰিবনে?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"বৰ্তমান আপুনি আপোনাৰ সম্পূৰ্ণ স্ক্ৰীনখন <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ত কাষ্ট কৰি আছে"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"বৰ্তমান আপুনি আপোনাৰ সম্পূৰ্ণ স্ক্ৰীনখন আশে-পাশে থকা ডিভাইচ এটাত কাষ্ট কৰি আছে"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"বৰ্তমান আপুনি <xliff:g id="DEVICE_NAME">%2$s</xliff:g>ত <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> কাষ্ট কৰি আছে"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"বৰ্তমান আপুনি আশে-পাশে থকা ডিভাইচ এটাত <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> কাষ্ট কৰি আছে"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"বৰ্তমান আপুনি <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ত কাষ্ট কৰি আছে"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"বৰ্তমান আপুনি আশে-পাশে থকা ডিভাইচ এটাত কাষ্ট কৰি আছে"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"কাষ্ট বন্ধ কৰক"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"বন্ধ কৰক"</string>
<string name="issuerecord_title" msgid="286627115110121849">"সমস্যা ৰেকৰ্ডাৰ"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"সমস্যা ৰেকৰ্ড কৰি থকা হৈছে"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"সমস্যা সংগ্ৰহ কৰা এটা ছেশ্বনৰ বাবে চলিত জাননী"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"সমস্যাৰ ৰেকৰ্ডিং ছেভ কৰাত আসোঁৱাহ"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"সমস্যাৰ ৰেকৰ্ডিং আৰম্ভ কৰোঁতে আসোঁৱাহ হৈছে"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"পূৰ্ণ স্ক্ৰীনত চাই আছে"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"বাহিৰ হ’বলৈ, আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে ওপৰৰ পৰা তললৈ ছোৱাইপ কৰক"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"বুজি পালোঁ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"উভতি যাওক"</string>
<string name="accessibility_home" msgid="5430449841237966217">"গৃহ পৃষ্ঠাৰ বুটাম"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ বাতিল কৰক"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"অধিক বিকল্প"</string>
@@ -291,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"স্ক্ৰীন ছেভাৰ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ইথাৰনেট"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"অসুবিধা নিদিব"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"অগ্ৰাধিকাৰপ্ৰাপ্ত ম’ড"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ব্লুটুথ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"কোনো যোৰা লগোৱা ডিভাইচ উপলব্ধ নহয়।"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"ডিভাইচ সংযোগ কৰিবলৈ অথবা সংযোগ বিচ্ছিন্ন কৰিবলৈ টিপক"</string>
@@ -302,8 +302,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ছেভ কৰা হৈছে"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"সংযোগ বিচ্ছিন্ন কৰক"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"সক্ৰিয় কৰক"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"কাইলৈ স্বয়ংক্ৰিয়ভাৱে অন কৰক"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share আৰু Find My Deviceৰ দৰে সুবিধাসমূহে ব্লুটুথ ব্যৱহাৰ কৰে"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"কাইলৈ পুৱা ব্লুটুথ অন হ’ব"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"অডিঅ’ শ্বেয়াৰ কৰক"</string>
@@ -472,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"অধিক ৱিজেট যোগ দিয়ক"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ৱিজেট কাষ্টমাইজ কৰিবলৈ দীঘলীয়াকৈ টিপক"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ৱিজেট কাষ্টমাইজ কৰক"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ৱিজেট কাষ্টমাইজ কৰিবলৈ আনলক কৰক"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"অক্ষম কৰা ৱিজেটৰ বাবে এপৰ চিহ্ন"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ইনষ্টল কৰি থকা এটা ৱিজেটৰ বাবে এপৰ চিহ্ন"</string>
<string name="edit_widget" msgid="9030848101135393954">"ৱিজেট সম্পাদনা কৰক"</string>
@@ -490,12 +490,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ৱিজেট বাছনি কৰক"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ৱিজেট আঁতৰাওক"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"বাছনি কৰা ৱিজেটটো ৰাখক"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"লক স্ক্ৰীনৰ ৱিজেট"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"আপোনাৰ টেবলেটটো লক কৰি ৰাখিলেও যিকোনো লোকে আপোনাৰ লক স্ক্ৰীনত ৱিজেট চাব পাৰে।"</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"লক স্ক্ৰীন ৱিজেট"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"এটা ৱিজেট ব্যৱহাৰ কৰি কোনো এপ্ খুলিবলৈ, এয়া আপুনিয়েই বুলি সত্যাপন পৰীক্ষা কৰিব লাগিব। লগতে, মনত ৰাখিব যে যিকোনো লোকেই সেইবোৰ চাব পাৰে, আনকি আপোনাৰ টেবলেটটো লক হৈ থাকিলেও। কিছুমান ৱিজেট হয়তো আপোনাৰ লক স্ক্ৰীনৰ বাবে কৰা হোৱা নাই আৰু ইয়াত যোগ কৰাটো অসুৰক্ষিত হ’ব পাৰে।"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুজি পালোঁ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুল-ডাউনৰ মেনু"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই ছেশ্বনৰ আটাইবোৰ এপ্ আৰু ডেটা মচা হ\'ব।"</string>
@@ -550,7 +549,7 @@
<string name="empty_shade_text" msgid="8935967157319717412">"কোনো জাননী নাই"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"কোনো নতুন জাননী নাই"</string>
<string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"অভিযোজিত জাননী অন কৰা আছে"</string>
- <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"আপোনাৰ ডিভাইচে এতিয়া ভলিউম হ্ৰাস কৰে আৰু আপুনি কম সময়ৰ ভিতৰত বহুতো জাননী পালে দুই মিনিটলৈকে স্ক্ৰীনত ওলোৱা পপ-আপ হ্ৰাস কৰে।"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"আপোনাৰ ডিভাইচে এতিয়া ভলিউম কমায়, কম সময়ৰ ভিতৰত বহুতো জাননী পালে ২ মিনিটলৈকে স্ক্ৰীনত ওলোৱা পপ-আপ কমায়।"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"অফ কৰক"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"পুৰণি জাননী চবলৈ আনলক কৰক"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"এই ডিভাইচটো আপোনাৰ অভিভাৱকে পৰিচালনা কৰে"</string>
@@ -717,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ডিফ’ল্ট"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"স্বয়ংক্ৰিয়"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"কোনো ধ্বনি অথবা কম্পন নাই"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"কোনো ধ্বনি অথবা কম্পন নাই আৰু বাৰ্তালাপ শাখাটোৰ তলৰ অংশত দেখা পোৱা যায়"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"ডিভাইচৰ ছেটিঙৰ ওপৰত নিৰ্ভৰ কৰি ৰিং কৰিব অথবা কম্পন হ’ব পাৰে"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ডিভাইচৰ ছেটিঙৰ ওপৰত নিৰ্ভৰ কৰি ৰিং কৰিব অথবা কম্পন হ’ব পাৰে। <xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাৰ্তালাপ ডিফ’ল্টভাৱে বাবল হিচাপে প্ৰদৰ্শিত হয়।"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"এই জাননীটোৱে ধ্বনি নে কম্পন সৃষ্টি কৰিব সেয়া ছিষ্টেমটোক নিৰ্ধাৰণ কৰিবলৈ দিয়ক"</string>
@@ -774,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"পেজ আপ"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"পেজ ডাউন"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"মচক"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"এস্কে’প"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"হ\'ম"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"সমাপ্ত"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"ভৰাওক"</string>
@@ -1349,23 +1350,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)এ ব্যৱহাৰ কৰি আছে"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"শেহতীয়াকৈ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)এ ব্যৱহাৰ কৰিছে"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ছিষ্টেম"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ছিষ্টেমৰ নিয়ন্ত্ৰণ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ছিষ্টেম এপ্‌"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"মাল্টিটাস্কিং"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"শেহতীয়া এপ্‌সমূহ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"বিভাজিত স্ক্ৰীন"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ইনপুট"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"এপ্ শ্বৰ্টকাটসমূহ"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"বৰ্তমানৰ এপ্‌"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"সাধ্য সুবিধা"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"কীব’ৰ্ডৰ শ্বৰ্টকাট"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"সন্ধানৰ শ্বৰ্টকাট"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"সংকোচন কৰাৰ চিহ্ন"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"বিস্তাৰ কৰাৰ চিহ্ন"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"অথবা"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"উভতি যাওক নিৰ্দেশ"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"গৃহ স্ক্ৰীনলৈ যোৱাৰ নিৰ্দেশ"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"কাৰ্য কী"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"হ’ল"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"বঢ়িয়া!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"উভতি যাওক"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"উভতি যাবলৈ, টাচ্চপেডৰ যিকোনো স্থানত তিনিটা আঙুলি ব্যৱহাৰ কৰি বাওঁ বা সোঁফালে ছোৱাইপ কৰক।"</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"তিনিটা আঙুলি সোঁ আৰু বাওঁফালে লৰচৰ কৰা দেখুওৱা টাচ্চপেড"</string>
@@ -1374,4 +1377,5 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dৰ %1$d স্তৰ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ঘৰৰ সা-সৰঞ্জামৰ নিয়ন্ত্ৰণ"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"স্ক্ৰীনছেভাৰ হিচাপে ক্ষিপ্ৰতাৰে ঘৰৰ সা-সৰঞ্জামৰ নিয়ন্ত্ৰণ এক্সেছ কৰক"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"আনডু কৰক"</string>
</resources>
diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml
index e978fe279a6e..fdd1f103674d 100644
--- a/packages/SystemUI/res/values-as/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"অফ আছে"</item>
<item msgid="4875147066469902392">"অন কৰা আছে"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"উপলব্ধ নহয়"</item>
+ <item msgid="2004750556637773692">"অফ আছে"</item>
+ <item msgid="8968530753931637871">"অন আছে"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"উপলব্ধ নহয়"</item>
<item msgid="5044688398303285224">"অফ আছে"</item>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 9c50f46f9328..e2ca41b6f61d 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> bu skrinşotu aşkarladı."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> və digər açıq tətbiqlər bu skrinşotu aşkarladı."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Qeydə əlavə edin"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Keçid daxil edin"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Ekran yazıcısı"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran çəkilişi emal edilir"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekranın video çəkimi ərzində silinməyən bildiriş"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Baxmaq üçün toxunun"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran çəkimini yadda saxlayarkən xəta oldu"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranın yazılması ilə bağlı xəta"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinin çəkilməsini dayandıracaqsınız"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Qeydəalmanı dayandırın"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran paylaşılır"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ekran paylaşımı dayandırılsın?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinin paylaşılmasını dayandıracaqsınız"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Paylaşımı dayandırın"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Ekran yayımlanır"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Yayım dayandırılsın?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinin yayımlanmasını dayandıracaqsınız"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Yayımı dayandırın"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Bağlayın"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Problem qeydə alan"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Problem qeydi emal edilir"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Problemin əldə edilməsi sessiyası üçün davam edən bildiriş"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Problem qeydini yadda saxlayarkən xəta"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Problemi qeydə almağa başlayarkən xəta"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Tam ekran rejimi"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Çıxmaq üçün ekranın yuxarısından aşağı çəkin"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Anladım"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Geri"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Ana səhifə"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Üz ilə kiliddən çıxarılıb. Davam etmək üçün basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Üz tanınıb. Davam etmək üçün basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Üz tanınıb. \"Kiliddən çıxar\" ikonasına basıb davam edin."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Üz ilə kiliddən çıxarılıb. Davam etmək üçün toxunun."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Doğrulandı"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"İdentifikasiyanı ləğv edin"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Digər seçimlər"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Ekran qoruyucu"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Narahat etməyin"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Heç bir cütlənmiş cihaz əlçatan deyil"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Toxunaraq cihaza qoşulun, yaxud əlaqəni ayırın"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Yadda saxlandı"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"əlaqəni kəsin"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivləşdirin"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Sabah avtomatik aktiv edin"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Cəld Paylaşım və Cihazın Tapılması kimi funksiyalar Bluetooth istifadə edir"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth sabah səhər aktiv ediləcək"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Audio paylaşın"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Vidcetlər əlavə edin"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Basıb saxlayaraq vidcetləri fərdiləşdirin"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Vidcetləri fərdiləşdirin"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Vidcetləri fərdiləşdirmək üçün kiliddən çıxarın"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Deaktiv edilmiş vidcet üçün tətbiq ikonası"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Quraşdırılan vidcet üçün tətbiq ikonası"</string>
<string name="edit_widget" msgid="9030848101135393954">"Vidceti redaktə edin"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidcet seçin"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"vidceti silin"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"seçilmiş vidceti yerləşdirin"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Kilid ekranı vidcetləri"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Vidcetdən istifadə edərək tətbiqi açmaq üçün kimliyi doğrulamalısınız. Planşet kilidli olsa da, hər kəs vidcetlərə baxa bilər. Bəzi vidcetlər kilid ekranı üçün nəzərdə tutulmayıb və bura əlavə etmək təhlükəli ola bilər."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Anladım"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aşağı çəkilən menyu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu sessiyada bütün tətbiqlər və data silinəcək."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Defolt"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Avtomatik"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Səs və ya vibrasiya yoxdur"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Söhbət siyahısının aşağısında səssiz və vibrasiyasız görünür"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Cihaz ayarlarına əsasən zəng çala və ya vibrasiya edə bilər"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Cihaz ayarlarına əsasən zəng çala və ya vibrasiya edə bilər. <xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqindən söhbətlərdə defolt olaraq qabarcıq çıxır."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Bu bildirişin səs çıxarması və ya vibrasiya etməsi sistem tərəfindən təyin edilsin"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Yuxarı Səhifə"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Aşağı Səhifə"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Silin"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Son"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Daxil edin"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) istifadə edir"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Bu yaxınlarda <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) istifadə edib"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistem nizamlayıcıları"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistem tətbiqləri"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Çoxsaylı tapşırıq icrası"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Son tətbiqlər"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Bölünmüş ekran"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Daxiletmə"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Tətbiq qısayolları"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Xüsusi imkanlar"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatura qısayolları"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Axtarış qısayolları"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"İkonanı yığcamlaşdırın"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"İkonanı genişləndirin"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"və ya"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Geri jesti"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Əsas ekran jesti"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Əməliyyat düyməsi"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hazırdır"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Əla!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Geri qayıdın"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Geri qayıtmaq üçün taçpedin istənilən yerində üç barmaqla sola və ya sağa çəkin."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Üç barmağın sağa və sola hərəkət etdiyini göstərən taçped"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Səviyyə %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ev nizamlayıcıları"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Ekran qoruyucu kimi ev nizamlayıcılarına tez giriş"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml
index c24f4029e415..da6d2177f8d5 100644
--- a/packages/SystemUI/res/values-az/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Deaktiv"</item>
<item msgid="4875147066469902392">"Aktiv"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Əlçatan deyil"</item>
<item msgid="5044688398303285224">"Deaktiv"</item>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 034102c32a05..3a7cc669a273 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je otkrila ovaj snimak ekrana."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije su otkrile ovaj snimak ekrana."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj u belešku"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Uvrsti link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Snimač ekrana"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađujemo video snimka ekrana"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Obaveštenje o sesiji snimanja ekrana je aktivno"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da biste pregledali"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Greška pri čuvanju snimka ekrana"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Zaustavićete snimanje za: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Zaustavićete deljenje za: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Zaustavićete prebacivanje za: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Želite da zaustavite snimanje?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Trenutno snimate ceo ekran"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Trenutno snimate: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Zaustavi snimanje"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran se deli"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Želite da zaustavite deljenje ekrana?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Trenutno delite ceo ekran sa: <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Trenutno delite ceo ekran sa aplikacijom"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Trenutno delite: <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Trenutno delite aplikaciju"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Zaustavi deljenje"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Prebacuje se ekran"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Želite da zaustavite prebacivanje?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Trenutno prebacujete ceo ekran na: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Trenutno prebacujete ceo ekran na uređaj u blizini"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> se trenutno prebacuje na: <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> se trenutno prebacuje na uređaj u blizini"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Trenutno prebacujete na: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Trenutno prebacujete na uređaj u blizini"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Zaustavi prebacivanje"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Zatvori"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Snimač problema"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Obrađuje se snimak problema"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"obaveštenje o aktivnosti u toku za sesiju prikupljanja podataka o problemu"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Greška pri čuvanju snimka problema"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Greška pri pokretanju snimanja problema"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Prikazuje se ceo ekran"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Da biste zatvorili, prevucite nadole od vrha ekrana"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Važi"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Nazad"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Početna"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano je licem. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu otključavanja za nastavak."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Otključano je licem. Dodirnite da biste nastavili."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Identitet je potvrđen"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkažite potvrdu identiteta"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Još opcija"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Čuvar ekrana"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Eternet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne uznemiravaj"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nije dostupan nijedan upareni uređaj"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Dodirnite da biste povezali uređaj ili prekinuli vezu"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sačuvano"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekinite vezu"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivirajte"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automatski uključi sutra"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funkcije kao što su Quick Share i Pronađi moj uređaj koriste Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth će se uključiti sutra ujutru"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Deli zvuk"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte još vidžeta"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dugi pritisak za prilagođavanje vidžeta"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodi vidžete"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Otključajte da biste prilagodili vidžete"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućen vidžet"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za vidžet koji se instalira"</string>
<string name="edit_widget" msgid="9030848101135393954">"Izmeni vidžet"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"izaberite vidžet"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"uklonite vidžet"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavite izabrani vidžet"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Vidžeti za zaključani ekran"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Svi mogu da vide vedžete na zaključanom ekranu, čak i kada je tablet zaključan."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Vidžeti za zaključani ekran"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da biste otvorili aplikaciju koja koristi vidžet, treba da potvrdite da ste to vi. Imajte u vidu da svako može da ga vidi, čak i kada je tablet zaključan. Neki vidžeti možda nisu namenjeni za zaključani ekran i možda nije bezbedno da ih tamo dodate."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Važi"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Podrazumevano"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatska"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez zvuka i vibriranja"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Bez zvuka i vibriranja i prikazuje se u nastavku odeljka za konverzacije"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Može da zvoni ili vibrira u zavisnosti od podešavanja uređaja"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Može da zvoni ili vibrira u zavisnosti od podešavanja uređaja. Konverzacije iz aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> podrazumevano se prikazuju u oblačićima."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Neka sistem utvrdi da li ovo obaveštenje treba da emituje zvuk ili da vibrira"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Taster za stranicu nagore"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Taster za stranicu nadole"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Taster za brisanje"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Taster Početna"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Taster za kraj"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Taster za umetanje"</string>
@@ -1349,23 +1351,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koriste <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemske kontrole"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemske aplikacije"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Obavljanje više zadataka istovremeno"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podeljeni ekran"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Unos"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Prečice za aplikacije"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuelna aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tasterske prečice"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečice pretrage"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za skupljanje"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za proširivanje"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Pokret za vraćanje"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Pokret za početnu stranicu"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Taster radnji"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gotovo"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Odlično!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazad"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Da biste se vratili, prevucite ulevo ili udesno sa tri prsta bilo gde na tačpedu."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Tačped sa prikazom tri prsta koji se pomeraju udesno i ulevo"</string>
@@ -1374,4 +1378,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrole za dom"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Brz pristup kontrolama za dom kao čuvaru ekrana"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index df0b78664cba..6833c27c4208 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Isključeno"</item>
<item msgid="4875147066469902392">"Uključeno"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nedostupno"</item>
<item msgid="5044688398303285224">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index c2f2cd0b5bc9..72808664ea85 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Праграма \"<xliff:g id="APPNAME">%1$s</xliff:g>\" выявіла гэты здымак экрана."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> і іншыя адкрытыя праграмы выявілі гэты здымак экрана."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Дадаць у нататку"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Дадаць спасылку"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Запіс экрана"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Апрацоўваецца запіс экрана"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Бягучае апавяшчэнне для сеанса запісу экрана"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Націсніце для прагляду"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Памылка захавання запісу экрана"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Памылка пачатку запісу экрана"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Запіс з праграмы &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будзе спынены"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Абагульванне з праграмы &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будзе спынена"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Трансляцыя праграмы &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будзе спынена"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Спыніць запіс?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Зараз вы запісваеце змесціва ўсяго экрана"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Зараз вы запісваеце змесціва праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Спыніць запіс"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экран абагульваецца"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Спыніць абагульванне экрана?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Зараз вы абагульваеце змесціва ўсяго экрана з праграмай \"<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>\""</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Зараз вы абагульваеце змесціва ўсяго экрана з праграмай"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Зараз вы абагульваеце змесціва праграмы \"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>\""</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Зараз вы абагульваеце змесціва праграмы"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Спыніць абагульванне"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Экран трансліруецца"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Спыніць трансляцыю?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Зараз вы трансліруеце змесціва ўсяго экрана на прыладу \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\""</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Зараз вы трансліруеце змесціва ўсяго экрана на прыладу паблізу"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Зараз вы трансліруеце змесціва праграмы \"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>\" на прыладу \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\""</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Зараз вы трансліруеце змесціва праграмы \"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>\" на прыладу паблізу"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Зараз вы трансліруеце змесціва на прыладу \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\""</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Зараз вы трансліруеце змесціва на прыладу паблізу"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Спыніць трансляцыю"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Закрыць"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Запіс праблемы"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Ідзе апрацоўка запісу праблемы"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Бягучае апавяшчэнне пра сеанс збору даных аб праблеме"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Пры захаванні запісу праблемы адбылася памылка"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Пры спробе пачаць запіс праблемы адбылася памылка"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Прагляд у поўнаэкранным рэжыме"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Каб выйсці, правядзіце пальцам уніз ад верхняга краю экрана"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Зразумела"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"На Галоўную старонку"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблакіравана распазнаваннем твару. Націсніце для працягу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Твар распазнаны. Націсніце для працягу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Твар распазнаны. Для працягу націсніце значок разблакіроўкі."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Твар распазнаны. Націсніце, каб працягнуць."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Распазнана"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Скасаваць аўтэнтыфікацыю"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Іншыя варыянты"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Экранная застаўка"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не турбаваць"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Захавана"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"адключыць"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"актываваць"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Аўтаматычна ўключыць заўтра"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth выкарыстоўваецца такімі функцыямі і сэрвісамі, як Хуткае абагульванне і Знайсці прыладу"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth уключыцца заўтра раніцай"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Абагуліць аўдыя"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Дадаць іншыя віджэты"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Доўга націскайце, каб наладзіць віджэты"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Наладзіць віджэты"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Разблакіруйце, каб наладзіць віджэты"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок праграмы для адключанага віджэта"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Значок праграмы для віджэта ў працэсе ўсталявання"</string>
<string name="edit_widget" msgid="9030848101135393954">"Змяніць віджэт"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"выбраць віджэт"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"выдаліць віджэт"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"размясціць выбраны віджэт"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Віджэты на экране блакіроўкі"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Віджэты на экране блакіроўкі будуць бачныя, нават калі планшэт заблакіраваны."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Віджэты на экране блакіроўкі"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Каб адкрыць праграму з дапамогай віджэта, вам неабходна будзе пацвердзіць сваю асобу. Таксама памятайце, што такія віджэты могуць пабачыць іншыя людзі, нават калі экран планшэта заблакіраваны. Некаторыя віджэты могуць не падыходзіць для выкарыстання на экране блакіроўкі, і дадаваць іх сюды можа быць небяспечна."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Зразумела"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Перайсці да іншага карыстальніка"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"высоўнае меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string>
@@ -549,12 +549,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Пачаць зараз"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Апавяшчэнняў няма"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Няма новых апавяшчэнняў"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптыўныя апавяшчэнні ўключаны"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Пры атрыманні шматлікіх апавяшчэнняў за кароткі час прылада памяншае гучнасць і колькасць усплывальных вокнаў на 2 хв."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Выключыць"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Разблакіруйце, каб убачыць усе апавяшчэнні"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Гэта прылада знаходзіцца пад кантролем бацькоў"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша арганізацыя валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
@@ -720,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Стандартна"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Аўтаматычна"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Без гуку ці вібрацыі"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Паказваецца без гуку ці вібрацыі ў раздзеле размоў"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"У залежнасці ад налад прылады магчымы званок або вібрацыя"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"У залежнасці ад налад прылады магчымы званок або вібрацыя. Размовы ў праграме \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" стандартна паяўляюцца ў выглядзе ўсплывальных апавяшчэнняў."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Сістэма сама будзе вызначаць, ці трэба для гэтага апавяшчэння ўключаць гук або вібрацыю"</string>
@@ -777,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1351,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Зараз выкарыстоўваецца праграмай \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Нядаўна выкарыстоўваўся праграмай \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Сістэма"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Элементы кіравання сістэмай"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Сістэмныя праграмы"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Шматзадачнасць"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Нядаўнія праграмы"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Падзелены экран"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Увод"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Ярлыкі праграм"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Спецыяльныя магчымасці"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Спалучэнні клавіш"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пошук спалучэнняў клавіш"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Згарнуць\""</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок \"Разгарнуць\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"або"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Жэст для вяртання на папярэдні экран"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Жэст для вяртання на галоўны экран"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Клавіша дзеяння"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Гатова"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Цудоўна!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Каб вярнуцца на папярэдні экран, правядзіце трыма пальцамі ўлева або ўправа ў любым месцы сэнсарнай панэлі."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Паказваецца, як на сэнсарнай панэлі тры пальцы рухаюцца ўправа і ўлева"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"На экране прылады паказваецца анімацыя жэста \"Назад\""</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Падсветка клавіятуры"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Узровень %1$d з %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Кіраванне домам"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Хуткі доступ да кіравання домам на застаўцы"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml
index 33e704cae0b1..4cc09a756431 100644
--- a/packages/SystemUI/res/values-be/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Выключана"</item>
<item msgid="4875147066469902392">"Уключана"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Недаступна"</item>
<item msgid="5044688398303285224">"Выключана"</item>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 811177706cd2..5ac0be0c6e0d 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> установи заснемането на тази екранна снимка."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и други отворени приложения установиха заснемането на тази екранна снимка."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Добавяне към бележката"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Включване на връзката"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Запис на екрана"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Записът на екрана се обработва"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущо известие за сесия за записване на екрана"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Докоснете за преглед"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при запазването на записа на екрана"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"При стартирането на записа на екрана възникна грешка"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ще спрете да записвате &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Спиране на записа"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Екранът се споделя"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Да се спре ли споделянето на екрана?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ще спрете да споделяте &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Спиране на споделянето"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Екранът се предава"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Да се спре ли предаването?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ще спрете да предавате &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Спиране на предаването"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Затваряне"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Записване на проблем"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Записът се обработва"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Текущо известие за сесия за събиране на данни за проблем"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Грешка при запазването на записа на проблема"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Грешка при стартирането на записа на проблема"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Изглед на цял екран"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"За изход плъзнете надолу от горната част на екрана"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Разбрах"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Начало"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отключено с лице. Натиснете, за да продължите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето бе разпознато. Натиснете, за да продължите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето бе разпознато. Продължете чрез иконата за отключване."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Отключено с лице. Докоснете, за да продължите."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Удостоверено"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Анулиране на удостоверяването"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Още опции"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Скрийнсейвър"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не безпокойте"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Запазено"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"прекратяване на връзката"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активиране"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Автоматично включване утре"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Функции като „Бързо споделяне“ и „Намиране на устройството ми“ използват Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ще се включи утре сутрин"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Споделяне на звука"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Добавете още приспособления"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Натиснете продължително за персонализ. на приспос."</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Персонализиране на приспособленията"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Отключете, за да персонализирате приспособленията"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона на приложение за деактивирано приспособление"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Икона на приложение, чието приспособление се инсталира"</string>
<string name="edit_widget" msgid="9030848101135393954">"Редактиране на приспособлението"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"избиране на приспособление"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"премахване на приспособлението"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"поставяне на избраното приспособление"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Приспособления за заключения екран"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"За да отворите дадено приложение посредством приспособление, ще трябва да потвърдите, че това сте вие. Също така имайте предвид, че всеки ще вижда приспособленията дори когато таблетът ви е заключен. Възможно е някои от тях да не са предназначени за заключения екран и добавянето им на него може да е опасно."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Разбрах"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Превключване между потребителите"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падащо меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Всички приложения и данни в тази сесия ще бъдат изтрити."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Стандартно"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Автоматично"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звук или вибриране"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звук или вибриране и се показва по-долу в секцията с разговори"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Може да звъни или да вибрира въз основа на настройките на устройството"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Може да звъни или да вибрира въз основа на настройките на устройството. Разговорите от <xliff:g id="APP_NAME">%1$s</xliff:g> се показват като балончета по подразбиране."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Нека системата да определя дали дадено известие да се придружава от звук, или вибриране"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Страница нагоре"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Страница надолу"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Изтриване"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Използва се от <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Наскоро използвано от <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Системни"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системни контроли"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системни приложения"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Изпълняване на няколко задачи едновременно"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Скорошни приложения"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Разделен екран"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Въвеждане"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Преки пътища към приложения"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Достъпност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Клавишни комбинации"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Търсете клавишни комбинации"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за свиване"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за разгъване"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Жест за връщане назад"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Жест за преминаване към началния екран"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Клавиш за действия"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Отлично!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"За да се върнете назад, прекарайте три пръста наляво или надясно по сензорния панел."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Сензорен панел, върху който три пръста се движат надясно и наляво"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d от %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Контроли за дома"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Достъп до контролите за дома ви като скрийнсейвър"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
index e2fd65360020..92db27957f48 100644
--- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Изкл."</item>
<item msgid="4875147066469902392">"Вкл."</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Не е налице"</item>
<item msgid="5044688398303285224">"Изкл."</item>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index d3571b029d12..fa38ac3f2dca 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>, এই স্ক্রিনশট শনাক্ত করেছে।"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> এবং খোলা থাকা অন্য অ্যাপ এই স্ক্রিনশট শনাক্ত করেছে।"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"নোটে যোগ করুন"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"লিঙ্ক যোগ করুন"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"স্ক্রিন রেকর্ডার"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রিন রেকর্ডিং প্রসেস হচ্ছে"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রিন রেকর্ডিং সেশন চলার বিজ্ঞপ্তি"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"দেখতে ট্যাপ করুন"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"স্ক্রিন রেকর্ডিং সেভ করার সময় কোনও সমস্যা হয়েছে"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রিন রেকর্ডিং শুরু করার সময় সমস্যা হয়েছে"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"এটির জন্য &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; অ্যাপের কন্টেন্ট রেকর্ড হওয়া বন্ধ হয়ে যাবে"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"রেকর্ড করা বন্ধ করুন"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"স্ক্রিন শেয়ার করা হচ্ছে"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"স্ক্রিন শেয়ার করা বন্ধ করবেন?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"এটির জন্য &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; অ্যাপের কন্টেন্ট শেয়ার করা বন্ধ হয়ে যাবে"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"শেয়ার করা বন্ধ করুন"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"স্ক্রিন কাস্ট করা হচ্ছে"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"কাস্ট করা বন্ধ করবেন?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"এটির জন্য &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; অ্যাপের কন্টেন্ট কাস্ট হওয়া বন্ধ হয়ে যাবে"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"কাস্টিং বন্ধ করুন"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"বন্ধ করুন"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Recorder-এ সমস্যা হয়েছে"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"সমস্যা সংক্রান্ত রেকর্ডিং প্রসেস করা হচ্ছে"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"সমস্যা সংগ্রহ সেশনের জন্য অনগোইং নোটিফিকেশন"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"সমস্যা সংক্রান্ত রেকর্ডিং সেভ করার সময় সমস্যা হয়েছে"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"সমস্যা সংক্রান্ত রেকর্ডিং শুরু করতে সমস্যা হয়েছে"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"ফুল-স্ক্রিনে দেখা হচ্ছে"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"বেরিয়ে আসতে, আপনার স্ক্রিনের একেবারে উপর থেকে নিচের দিকে সোয়াইপ করুন"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"বুঝেছি"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ফিরুন"</string>
<string name="accessibility_home" msgid="5430449841237966217">"হোম"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে আনলক আইকন প্রেস করুন।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যেতে ট্যাপ করুন।"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"প্রমাণীকৃত"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"যাচাইকরণ বাতিল করুন"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"আরও বিকল্প"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"স্ক্রিন সেভার"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ইথারনেট"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"বিরক্ত করবে না"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ব্লুটুথ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"চেনা কোনও ডিভাইস নেই"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"কোনও ডিভাইস কানেক্ট বা ডিসকানেক্ট করতে ট্যাপ করুন"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"সেভ করা আছে"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ডিসকানেক্ট করুন"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"চালু করুন"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"আগামীকাল অটোমেটিক চালু হয়ে যাবে"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"দ্রুত শেয়ার ও Find My Device-এর মতো ফিচার ব্লুটুথ ব্যবহার করে"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ব্লুটুথ আগামীকাল সকালে চালু হয়ে যাবে"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"অডিও শেয়ার করুন"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"আরও উইজেট যোগ করুন"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"উইজেট কাস্টমাইজ করতে বেশিক্ষণ প্রেস করুন"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"উইজেট কাস্টমাইজ করুন"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"উইজেট কাস্টমাইজ করতে আনলক করুন"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"বন্ধ করা উইজেটের জন্য অ্যাপের আইকন"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ইনস্টল করা হচ্ছে এমন উইজেটের অ্যাপ আইকন"</string>
<string name="edit_widget" msgid="9030848101135393954">"উইজেট এডিট করুন"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"উইজেট বেছে নিন"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"উইজেট সরান"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"বেছে নেওয়া উইজেটটি রাখুন"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"লক স্ক্রিন উইজেট"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"উইজেট ব্যবহার করে কোনও অ্যাপ খুলতে, আপনাকে নিজের পরিচয় যাচাই করতে হবে। এছাড়াও, মনে রাখবেন, এমনকি আপনার ট্যাবলেট লক থাকাকালীন যেকেউ তা দেখতে পারবেন। কিছু উইজেট আপনার লক স্ক্রিনের উদ্দেশ্যে তৈরি করা হয়নি এবং এখানে যোগ করা নিরাপদ নাও হতে পারে।"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুঝেছি"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যবহারকারী পাল্টে দিন"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুলডাউন মেনু"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ ও ডেটা মুছে ফেলা হবে।"</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ডিফল্ট"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"অটোমেটিক"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"আওয়াজ করবে না বা ভাইব্রেট হবে না"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"আওয়াজ করবে না বা ভাইব্রেট হবে না এবং কথোপকথন বিভাগের নিচের দিকে দেখা যাবে"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"ডিভাইসের সেটিংস অনুযায়ী রিং বা ভাইব্রেট হতে পারে"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ডিভাইসের সেটিংস অনুযায়ী রিং বা ভাইব্রেট হতে পারে। <xliff:g id="APP_NAME">%1$s</xliff:g>-এর কথোপকথন সাধারণত বাবলের মতো দেখাবে।"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"এই বিজ্ঞপ্তি এলে ডিভাইস আওয়াজ করবে না ভাইব্রেট করবে তা সিস্টেমকে সেট করতে দিন"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"পেজ আপ"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"পেজ ডাউন"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"মুছুন"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"হোম"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"শেষ"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"ঢোকান"</string>
@@ -1349,23 +1367,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপে (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ব্যবহার করা হচ্ছে"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"সম্প্রতি <xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপে (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ব্যবহার করা হয়েছে"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"সিস্টেম"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"সিস্টেম কন্ট্রোল"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"সিস্টেম অ্যাপ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"মাল্টিটাস্কিং"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"সম্প্রতি ব্যবহার করা অ্যাপ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"স্প্লিট স্ক্রিন"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ইনপুট"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"অ্যাপ শর্টকাট"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"বর্তমান অ্যাপ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"অ্যাক্সেসিবিলিটি"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"কীবোর্ড শর্টকাট"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"সার্চ শর্টকাট"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"আইকন আড়াল করুন"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"আইকন বড় করুন"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"অথবা"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"ফিরে যাওয়ার জেসচার"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"হোমপেজে যাওয়ার জেসচার"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"অ্যাকশন কী"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"হয়ে গেছে"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"অসাধারণ!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ফিরে যান"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ফিরে যেতে, টাচপ্যাডের যেকোনও জায়গায় তিনটি আঙুল দিয়ে ডান বা বাঁদিকে সোয়াইপ করুন।"</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"টাচপ্যাডে, তিনটি আঙুল ডান ও বাঁদিকে সরানো দেখানো হচ্ছে"</string>
@@ -1374,4 +1394,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-এর মধ্যে %1$d লেভেল"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"হোম কন্ট্রোল"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"স্ক্রিন সেভার হিসেবে ঝটপট \'হোম কন্ট্রোল\' অ্যাক্সেস করুন"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
index 6e4dfbfbf745..b6336ba0ecca 100644
--- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"বন্ধ আছে"</item>
<item msgid="4875147066469902392">"চালু আছে"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"উপলভ্য নেই"</item>
<item msgid="5044688398303285224">"বন্ধ আছে"</item>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index b3fcf1ad5b1d..5a8543510ab1 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je otkrila ovaj snimak ekrana."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije su otkrile ovaj snimak ekrana."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj u bilješku"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Uključi link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Snimač ekrana"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađivanje snimka ekrana"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Obavještenje za sesiju snimanja ekrana je u toku"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da vidite"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Greška prilikom pohranjivanja snimka ekrana"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Zaustavit ćete snimanje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Zaustavit ćete dijeljenje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Zaustavit ćete emitiranje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Želite li zaustaviti snimanje?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Trenutačno snimate cijeli zaslon"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Trenutačno snimate aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Zaustavi snimanje"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Dijeljenje ekrana"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Zaustaviti dijeljenje ekrana?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Trenutačno dijelite cijeli zaslon s aplikacijom <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Trenutačno dijelite cijeli zaslon s aplikacijom"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Trenutačno dijelite aplikaciju <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Trenutačno dijelite aplikaciju"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Zaustavi dijeljenje"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Emitiranje ekrana"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Zaustaviti emitiranje?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Trenutačno emitirate cijeli zaslon na uređaj <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Trenutačno emitirate cijeli zaslon na uređaj u blizini"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Trenutačno emitirate aplikaciju <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> na uređaj <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Trenutačno emitirate aplikaciju <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> na uređaj u blizini"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Trenutačno emitirate na uređaj <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Trenutačno emitirate na uređaj u blizini"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Zaustavi emitiranje"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Zatvori"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Snimač problema"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Obrada snimka problema"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Obavještenje o aktivnosti u pozadini za sesiju prikupljanja podataka o problemu"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Došlo je do greške prilikom pohranjivanja snimka problema"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Došlo je do greške prilikom pokretanja snimanja problema"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Prikazivanje preko cijelog ekrana"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Da izađete, prevucite s vrha ekrana nadolje"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Razumijem"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Nazad"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Dugme za početnu stranicu"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano licem. Pritisnite da nastavite."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice prepoznato. Pritisnite da nastavite."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu za otklj. da nastavite."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Otključano je licem. Dodirnite da nastavite."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificirano"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkažite autentifikaciju"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Više opcija"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Čuvar ekrana"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne ometaj"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nema dostupnih uparenih uređaja"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Dodirnite da povežete ili prekinete povezanost uređaja"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sačuvano"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekid veze"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviranje"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automatski uključi sutra"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funkcije kao što su Quick Share i Pronađi moj uređaj koriste Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth će se uključiti sutra ujutro"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Dijeli zvuk"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte još vidžeta"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pritisnite i zadržite da prilagodite vidžete"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodite vidžete"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Otključajte da prilagodite vidžete"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućeni vidžet"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za vidžet koji se instalira"</string>
<string name="edit_widget" msgid="9030848101135393954">"Uredite vidžet"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"odabir vidžeta"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"uklanjanje vidžeta"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavljanje odabranog vidžeta"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgeti zaključanog zaslona"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Svi vide widgete na vašem zaključanom zaslonu, čak i ako je tablet zaključan."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Vidžeti zaključanog ekrana"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da otvorite aplikaciju pomoću vidžeta, morat ćete potvrditi identitet. Također imajte na umu da ih svako može pregledati, čak i ako je tablet zaključan. Neki vidžeti možda nisu namijenjeni za vaš zaključani ekran i njihovo dodavanje ovdje možda nije sigurno."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Razumijem"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zamijeni korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string>
@@ -549,8 +549,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nema obavještenja"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obavještenja"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Prilagodljive obavijesti uklj."</string>
- <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Uređaj sada stišava zvuk i smanjuje broj skočnih prozora na zaslonu na 2 minute kada primite jako puno obavijesti u kratkom vremenskom razdoblju."</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Prilagodljiva obavještenja su uključena"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Uređaj smanjuje jačinu zvuka i broj skočnih prozora na ekranu do dvije minute kada dobijate mnogo obavještenja unutar kratkog vremenskog raspona."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte da vidite starija obavještenja"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Zadano"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatski"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez zvuka ili vibracije"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Bez zvuka ili vibracije i pojavljuje se pri dnu odjeljka razgovora"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Može zvoniti ili vibrirati na osnovu postavki uređaja"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Može zvoniti ili vibrirati na osnovu postavki uređaja. Razgovori iz aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> prikazuju se u oblačićima prema zadanim postavkama."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Neka sistem odluči treba li se ovo obavještenje oglasiti zvukom ili vibracijom"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Tipka Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Tipka Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Tipka za brisanje"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Tipka za početak"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Kraj"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Tipka za umetanje"</string>
@@ -1349,29 +1351,33 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koristi aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno je koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemske kontrole"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemske aplikacije"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podijeljeni ekran"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Unos"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Prečice aplikacije"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Trenutna aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Prečice tastature"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečica pretraživanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sužavanja"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona proširivanja"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Natrag"</string>
- <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Za povratak trima prstima prijeđite ulijevo ili udesno bilo gdje na dodirnoj podlozi."</string>
- <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Dodirna podloga prikazuje tri prsta koji se kreću udesno i ulijevo"</string>
- <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Na zaslonu uređaja prikazuje se animacija za pokret za povratak"</string>
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Pokret za povratak"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Pokret za povratak na početni ekran"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tipka radnji"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gotovo"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Sjajno!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazad"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Da se vratite, prevucite ulijevo ili udesno s tri prsta bilo gdje na dodirnoj podlozi."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Dodirna podloga prikazuje tri prsta koji se pomjeraju desno-lijevo"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ekran uređaja pokazuje animaciju pokreta unazad"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tastature"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrole za dom"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Brzo pristupajte kontrolama za dom putem čuvara ekrana"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
index df0b78664cba..6833c27c4208 100644
--- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Isključeno"</item>
<item msgid="4875147066469902392">"Uključeno"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nedostupno"</item>
<item msgid="5044688398303285224">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index c4879c48d568..2b4e30984f61 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha detectat aquesta captura de pantalla."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i altres aplicacions obertes han detectat aquesta captura de pantalla."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Afegeix a una nota"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Inclou l\'enllaç"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Gravació de pantalla"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processant gravació de pantalla"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificació en curs d\'una sessió de gravació de la pantalla"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toca per veure-la"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"S\'ha produït un error en desar la gravació de la pantalla"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"S\'ha produït un error en iniciar la gravació de pantalla"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Deixaràs de gravar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Deixaràs de compartir &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Deixaràs d\'emetre &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Vols aturar la gravació?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Ara mateix estàs gravant tota la pantalla"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Ara mateix estàs gravant <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Atura la gravació"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"S\'està compartint la pantalla"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vols deixar de compartir la pantalla?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Ara mateix estàs compartint tota la pantalla amb <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Ara mateix estàs compartint tota la pantalla amb una aplicació"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Ara mateix estàs compartint <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Ara mateix estàs compartint una aplicació"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Deixa de compartir"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"S\'està emetent la pantalla"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vols aturar l\'emissió?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Ara mateix estàs emetent tota la pantalla a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Ara mateix estàs emetent tota la pantalla en un dispositiu proper"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Ara mateix estàs emetent <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> a <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Ara mateix estàs emetent <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> en un dispositiu proper"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Ara mateix estàs emetent a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Ara mateix estàs emetent en un dispositiu proper"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Atura l\'emissió"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Tanca"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Gravadora de problemes"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processant gravació del problema"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificació en curs d\'una sessió de recollida de dades del problema"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"S\'ha produït un error en desar la gravació del problema"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"S\'ha produït un error en iniciar la gravació del problema"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Visualització en pantalla completa"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Per sortir, llisca cap avall des de la part superior de la pantalla"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Entesos"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Enrere"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Inici"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S\'ha desbloquejat amb la cara. Prem per continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"S\'ha reconegut la cara. Prem per continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"S\'ha reconegut la cara. Prem la icona per continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"S\'ha desbloquejat amb la cara. Toca per continuar."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticat"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel·la l\'autenticació"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Més opcions"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Estalvi de pantalla"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"No molestis"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No hi ha dispositius vinculats disponibles"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Toca per connectar o desconnectar un dispositiu"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Desat"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconnecta"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activa"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Activa automàticament demà"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Les funcions com Quick Share i Troba el meu dispositiu utilitzen el Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"El Bluetooth s\'activarà demà al matí"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Comparteix l\'àudio"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Afegeix més widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén premut per personalitzar els widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalitza els widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloqueja per personalitzar els widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona de l\'aplicació per a widget desactivat"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icona de l\'aplicació d\'un widget que s\'està instal·lant"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edita el widget"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecciona el widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"suprimeix el widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"col·loca el widget seleccionat"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets de la pantalla de bloqueig"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Tothom pot veure widgets a la pantalla de bloqueig, fins i tot amb la tauleta bloquejada."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets de la pantalla de bloqueig"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per obrir una aplicació utilitzant un widget, necessitaràs verificar la teva identitat. També has de tenir en compte que qualsevol persona pot veure els widgets, fins i tot quan la tauleta està bloquejada. És possible que alguns widgets no estiguin pensats per a la pantalla de bloqueig i que no sigui segur afegir-los-hi."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entesos"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Canvia d\'usuari"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
@@ -549,12 +549,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hi ha cap notificació"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No hi ha cap notificació nova"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notif. adaptatives activades"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"El dispositiu abaixa el volum i redueix les notificacions emergents durant un màxim de 2 minuts quan reps moltes notificacions en poc temps."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactiva"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueja per veure notif. anteriors"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Els teus pares gestionen aquest dispositiu"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"La teva organització és propietària del dispositiu i és possible que supervisi el trànsit de xarxa"</string>
@@ -720,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Predeterminat"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automàtic"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sense so ni vibració"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sense so ni vibració i es mostra més avall a la secció de converses"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Pot sonar o vibrar en funció de la configuració del dispositiu"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Pot sonar o vibrar en funció de la configuració del dispositiu. Les converses de l\'aplicació <xliff:g id="APP_NAME">%1$s</xliff:g> es mostren com a bombolles de manera predeterminada."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Fes que el sistema determini si aquesta notificació ha d\'emetre un so o una vibració"</string>
@@ -777,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Re Pàg"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Av Pàg"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Tecla de supressió"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Inici"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Final"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Tecla d\'inserció"</string>
@@ -1352,33 +1351,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En ús per <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Utilitzat recentment per <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controls del sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicacions del sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasca"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicacions recents"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantalla dividida"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Dreceres d\'aplicacions"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilitat"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tecles de drecera"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Dreceres de cerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Replega la icona"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Desplega la icona"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gest Enrere"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gest Inici"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tecla d\'acció"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Fet"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Ben fet!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Torna"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Per tornar enrere, llisca cap a l\'esquerra o cap a la dreta amb tres dits en qualsevol lloc del ratolí tàctil."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Ratolí tàctil que mostra tres dits que es mouen cap a la dreta i cap a l\'esquerra"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Pantalla del dispositiu que mostra l\'animació del gest per anar enrere"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroil·luminació del teclat"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivell %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controls de la llar"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Utilitza controls de la llar com a estalvi de pantalla"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
index 67eb853c9ee6..3b908fd88520 100644
--- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Desactivat"</item>
<item msgid="4875147066469902392">"Activat"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"No disponible"</item>
<item msgid="5044688398303285224">"Desactivat"</item>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index c0db5aa28422..992b35b515c2 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikace <xliff:g id="APPNAME">%1$s</xliff:g> objevila tento snímek obrazovky."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> a ostatní otevřené aplikace objevily tento snímek obrazovky."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Přidat do poznámky"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Zahrnout odkaz"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Nahrávání obrazovky"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Záznam obrazovky se zpracovává"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Trvalé oznámení o relaci nahrávání"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Klepnutím nahrávku zobrazíte"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Při ukládání záznamu obrazovky došlo k chybě"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Při spouštění nahrávání obrazovky došlo k chybě"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Přestane se nahrávat aplikace &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Ukončit nahrávání"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sdílení obrazovky"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ukončit sdílení obrazovky?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Přestane se sdílet aplikace &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Ukončit sdílení"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Odesílání obsahu obrazovky"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Ukončit odesílání?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Přestane se odesílat aplikace &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Ukončit odesílání"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Zavřít"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Rekordér problémů"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Zpracování záznamu problému"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Upozornění na probíhající shromažďování dat o problému"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Při ukládání záznamu problému došlo k chybě"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Při zahájení záznamu problému došlo k chybě"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Zobrazování přes celou obrazovku"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Tento režim ukončíte přejetím prstem dolů z horní části obrazovky"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Rozumím"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Zpět"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Domů"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odemknuto obličejem. Pokračujte stisknutím."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obličej rozpoznán. Pokračujte stisknutím."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obličej rozpoznán. Klepněte na ikonu odemknutí."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Odemknuto obličejem. Pokračujte klepnutím."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ověřeno"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Zrušit ověření"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Další možnosti"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Spořič obrazovky"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Nerušit"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nejsou dostupná žádná spárovaná zařízení"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Klepnutím zařízení připojíte nebo odpojíte"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Uloženo"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"odpojit"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivovat"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Zítra automaticky zapnout"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth využívají funkce jako Quick Share a Najdi moje zařízení."</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth se zapne zítra ráno."</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Sdílet zvuk"</string>
@@ -398,7 +411,7 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zařízení"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Předvolbu nelze aktualizovat"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Předvolba"</string>
- <string name="live_caption_title" msgid="8916875614623730005">"Živý přepis"</string>
+ <string name="live_caption_title" msgid="8916875614623730005">"Okamžité titulky"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokovat mikrofon zařízení?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokovat fotoaparát zařízení?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Odblokovat fotoaparát a mikrofon zařízení?"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Přidat další widgety"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dlouhým stisknutím můžete přizpůsobit widgety"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Přizpůsobit widgety"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Widgety lze přizpůsobit po odemknutí"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikace s deaktivovaným widgetem"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikace při probíhající instalaci widgetu"</string>
<string name="edit_widget" msgid="9030848101135393954">"Upravit widget"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vybrat widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstranit widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"umístit vybraný widget"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgety na obrazovce uzamčení"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"K otevření aplikace pomocí widgetu budete muset ověřit svou totožnost. Také mějte na paměti, že widgety uvidí kdokoli, i když tablet bude uzamčen. Některé widgety nemusí být pro obrazovku uzamčení určeny a nemusí být bezpečné je na ni přidat."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Rozumím"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Přepnout uživatele"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbalovací nabídka"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Spustit"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Žádná oznámení"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Žádná nová oznámení"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Jsou zapnutá adaptivní oznámení"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Když během krátké chvíle obdržíte mnoho oznámení, zařízení teď až na dvě minuty sníží hlasitost a omezí na obrazovce vyskakovací okna."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vypnout"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Starší oznámení se zobrazí po odemknutí"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zařízení spravuje rodič"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Toto zařízení vlastní vaše organizace, která může sledovat síťový provoz"</string>
@@ -610,7 +622,7 @@
<string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktivovat"</string>
<string name="sound_settings" msgid="8874581353127418308">"Zvuk a vibrace"</string>
<string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Nastavení"</string>
- <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Živý přepis"</string>
+ <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Okamžité titulky"</string>
<string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Hlasitost byla snížena na bezpečnou úroveň"</string>
<string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Hlasitost sluchátek byla vysoká déle, než je doporučeno"</string>
<string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Hlasitost sluchátek překročila bezpečný limit pro tento týden"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Výchozí"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automaticky"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Žádný zvuk ani vibrace"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Žádný zvuk ani vibrace a zobrazuje se níže v sekci konverzací"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Vyzvání nebo vibruje podle nastavení zařízení"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Vyzvání nebo vibruje podle nastavení zařízení. Konverzace z aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> ve výchozím nastavení bublají."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Nechat systém rozhodnout, zda má toto oznámení vydat zvuk či zavibrovat"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Právě používán aplikací <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedávno použila aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Systém"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Ovládací prvky systému"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systémové aplikace"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Poslední aplikace"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Rozdělená obrazovka"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Vstup"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Zkratky aplikací"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Přístupnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové zkratky"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Vyhledat zkratky"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sbalení"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozbalení"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"nebo"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gesto zpět"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gesto domů"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Akční klávesa"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hotovo"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Výborně!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Zpět"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pokud se chcete vrátit zpět, stačí kdekoli na touchpadu přejet třemi prsty doleva nebo doprava."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad se třemi prsty, které se pohybují doprava a doleva"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Obrazovka zařízení s animaci gesta k vrácení zpět"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvícení klávesnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Úroveň %1$d z %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládání domácnosti"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Rychlý přístup k funkcím, jako je spořič obrazovky"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
index ae533a8623ec..c4d7388f572f 100644
--- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Vypnuto"</item>
<item msgid="4875147066469902392">"Zapnuto"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nedostupné"</item>
<item msgid="5044688398303285224">"Vypnuto"</item>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index cce4615d1e55..2750b429844e 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> har registreret dette screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og andre åbne apps har registreret dette screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Føj til note"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Inkluder link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Skærmoptagelse"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skærmoptagelse"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Konstant notifikation om skærmoptagelse"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tryk for at se"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Skærmoptagelsen kunne ikke gemmes"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Skærmoptagelsen kunne ikke startes"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Du stopper optagelse af &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop optagelse"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Skærmen deles"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop skærmdelingen?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Du stopper deling af &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop deling"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Skærmen castes"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vil du stoppe din cast?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Du stopper casting af &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Stop cast"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Luk"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Problemoptagelse"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Behandler optagelse af problem"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Igangværende notifikation om en session med problemindsamling"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Kunne ikke gemme optagelse af problem"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Fejl under forsøg på at starte optagelse af problem"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Visning i fuld skærm"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Stryg nedad fra toppen af skærmen for at afslutte"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Tilbage"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Hjem"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst op ved hjælp af ansigt. Tryk for at fortsætte."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansigt genkendt. Tryk for at fortsætte."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansigt genkendt. Tryk på oplåsningsikonet for at fortsætte."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Låst op ved hjælp af ansigt. Tryk for at fortsætte."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Godkendt"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuller godkendelsen"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Flere valgmuligheder"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Pauseskærm"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Forstyr ikke"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Der er ingen tilgængelige parrede enheder"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Tryk for at oprette eller afbryde forbindelse til en enhed"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gemt"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"afbryd forbindelse"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivér"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Aktivér automatisk i morgen"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funktioner som f.eks. Quick Share og Find min enhed anvender Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth aktiveres i morgen tidlig"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Del lyd"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tilføj flere widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Hold fingeren nede for at tilpasse widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tilpas widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Lås op for at tilpasse widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon for deaktiveret widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikonet for en widget er ved at blive installeret"</string>
<string name="edit_widget" msgid="9030848101135393954">"Rediger widget"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vælg widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjern widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placer valgt widget"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets på låseskærmen"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Hvis du vil åbne en app ved hjælp af en widget, skal du verificere din identitet. Husk også, at alle kan se dem, også når din tablet er låst. Nogle widgets er muligvis ikke beregnet til låseskærmen, og det kan være usikkert at tilføje dem her."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skift bruger"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullemenu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps og data i denne session slettes."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nu"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ingen notifikationer"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye notifikationer"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifikationer er aktiveret"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Din enhed skruer nu ned for lydstyrken og reducerer pop op-vinduer på skærmen i op til to minutter, når du modtager mange notifikationer over kort tid."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktiver"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås op for at se ældre notifikationer"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enhed administreres af din forælder"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Din organisation ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatisk"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Ingen lyd eller vibration"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ingen lyd eller vibration, og den vises længere nede i samtalesektionen"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Kan ringe eller vibrere baseret på enhedens indstillinger"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Kan ringe eller vibrere baseret på enhedens indstillinger. Samtaler fra <xliff:g id="APP_NAME">%1$s</xliff:g> vises som standard i bobler."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Få systemet til at afgøre, om denne notifikation skal vibrere eller afspille en lyd"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Bruges af <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Brugt for nylig af <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systemstyring"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systemapps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Seneste apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Opdelt skærm"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Appgenveje"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hjælpefunktioner"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tastaturgenveje"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Genveje til søgning"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon for Skjul"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikon for Udvid"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Bevægelse for at gå tilbage"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Bevægelse for at gå til startskærm"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Handlingstast"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Udfør"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Sådan!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gå tilbage"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Du kan gå tilbage ved at stryge mod venstre eller højre med tre fingre et vilkårligt sted på touchpladen."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchplade viser tre fingre, der bevæger sig til højre og venstre"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Enhedsskærm, der viser en animation, som demonstrerer, hvordan man går tilbage"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturets baggrundslys"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d af %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Hjemmestyring"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Tilgå hurtigt hjemmestyring via din pauseskærm"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml
index 2c3b0535cb33..3a9533a71251 100644
--- a/packages/SystemUI/res/values-da/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Fra"</item>
<item msgid="4875147066469902392">"Til"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Ikke tilgængelig"</item>
<item msgid="5044688398303285224">"Fra"</item>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 31ac8e81d61e..710ae57fbc70 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> hat diesen Screenshot erkannt."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> und andere geöffnete Apps haben diesen Screenshot erkannt."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Zu Notiz hinzufügen"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Link einschließen"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Bildschirmaufzeichnung"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Bildschirmaufzeichnung…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Fortlaufende Benachrichtigung für eine Bildschirmaufzeichnung"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Zum Ansehen tippen"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Fehler beim Speichern der Bildschirmaufzeichnung"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Fehler beim Start der Bildschirmaufzeichnung"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wird dann nicht mehr aufgezeichnet"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Aufnahme beenden"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Bildschirm wird geteilt"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Bildschirmfreigabe beenden?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wird dann nicht mehr geteilt"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Freigabe beenden"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Bildschirm wird übertragen"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Übertragung abbrechen?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wird dann nicht mehr übertragen"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Streaming beenden"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Schließen"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Problem aufzeichnen"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Aufzeichnung wird verarbeitet"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Benachrichtigung über laufende Aufzeichnung eines Problems"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Fehler beim Speichern der Aufzeichnung des Problems"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Fehler beim Starten der Aufzeichnung des Problems"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Vollbildmodus wird aktiviert"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Wenn du den Modus verlassen möchtest, wische vom oberen Displayrand nach unten"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Ok"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Zurück"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Startbildschirm"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Gerät mit dem Gesicht entsperrt. Tippe, um fortzufahren."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesicht erkannt. Tippe, um fortzufahren."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesicht erkannt. Tippe zum Fortfahren auf das Symbol „Entsperren“."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Per Gesichtserkennung entsperrt. Tippe, um fortzufahren."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifiziert"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Authentifizierung abbrechen"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Weitere Optionen"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Bildschirmschoner"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Bitte nicht stören"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Keine gekoppelten Geräte verfügbar"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Zum Verbinden oder Trennen eines Geräts tippen"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gespeichert"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"Verknüpfung aufheben"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivieren"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Morgen automatisch aktivieren"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funktionen wie „Quick Share“ und „Mein Gerät finden“ verwenden Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth wird morgen früh aktiviert"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Audioinhalte freigeben"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Weitere Widgets hinzufügen"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Lange drücken, um Widgets anzupassen"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widgets anpassen"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Entsperren, um Widgets zu personalisieren"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-Symbol für deaktiviertes Widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App-Symbol für ein Widget, das gerade installiert wird"</string>
<string name="edit_widget" msgid="9030848101135393954">"Widget bearbeiten"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"Widget auswählen"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"Widget entfernen"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ausgewähltes Widget in den Bearbeitungsmodus versetzen"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Sperrbildschirm-Widgets"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Wenn du eine App mit einem Widget öffnen möchtest, musst du deine Identität bestätigen. Beachte auch, dass jeder die Widgets sehen kann, auch wenn dein Tablet gesperrt ist. Einige Widgets sind möglicherweise nicht für den Sperrbildschirm vorgesehen, sodass es unsicher sein kann, sie hier hinzuzufügen."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ok"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Nutzer wechseln"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Pull-down-Menü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Jetzt starten"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Keine Benachrichtigungen"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Keine neuen Benachrichtigungen"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive Benachrichtigungen an"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Wenn du in kurzer Zeit viele Benachrichtigungen erhältst, reduziert dein Gerät jetzt die Lautstärke und Pop-ups bis zu 2 Minuten lang."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktivieren"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Für ältere Benachrichtigungen entsperren"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dieses Gerät wird von deinen Eltern verwaltet"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Deine Organisation verwaltet dieses Gerät und kann den Netzwerkverkehr überwachen"</string>
@@ -617,11 +629,11 @@
<string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Weiterhören"</string>
<string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Leiser stellen"</string>
<string name="screen_pinning_title" msgid="9058007390337841305">"App ist auf dem Bildschirm fixiert"</string>
- <string name="screen_pinning_description" msgid="8699395373875667743">"Die App bleibt so lange auf dem Bildschirm fixiert, bis du die Fixierung aufhebst. Berühre und halte dazu \"Zurück\" und \"Übersicht\"."</string>
- <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Die App bleibt so lange auf dem Bildschirm fixiert, bis du die Fixierung aufhebst. Berühre und halte dazu \"Zurück\" und \"Startbildschirm\"."</string>
+ <string name="screen_pinning_description" msgid="8699395373875667743">"Die App bleibt so lange auf dem Bildschirm fixiert, bis du die Fixierung aufhebst. Halte dazu \"Zurück\" und \"Übersicht\" gedrückt."</string>
+ <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Die App bleibt so lange auf dem Bildschirm fixiert, bis du die Fixierung aufhebst. Halte dazu \"Zurück\" und \"Startbildschirm\" gedrückt."</string>
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Die App bleibt so lange auf dem Bildschirm angepinnt, bis du die Fixierung aufhebst. Wische dazu nach oben und halte den Bildschirm gedrückt."</string>
- <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Die App bleibt so lange auf dem Bildschirm fixiert, bis du die Fixierung aufhebst. Berühre und halte dazu \"Übersicht\"."</string>
- <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Die App bleibt so lange auf dem Bildschirm fixiert, bis du die Fixierung aufhebst. Berühre und halte dazu \"Startbildschirm\"."</string>
+ <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Die App bleibt so lange auf dem Bildschirm fixiert, bis du die Fixierung aufhebst. Halte dazu \"Übersicht\" gedrückt."</string>
+ <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Die App bleibt so lange auf dem Bildschirm fixiert, bis du die Fixierung aufhebst. Halte dazu \"Startbildschirm\" gedrückt."</string>
<string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Möglicherweise kann auf personenbezogene Daten (Kontakte, E-Mails usw.) zugegriffen werden."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Die fixierte App kann ggf. andere Apps öffnen."</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"Zum Aufheben der Fixierung dieser App \"Zurück\" und \"Übersicht\" halten"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatisch"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Kein Ton und keine Vibration"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Kein Ton und keine Vibration, erscheint weiter unten im Bereich „Unterhaltungen“"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Kann je nach Geräteeinstellungen klingeln oder vibrieren"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Kann je nach Geräteeinstellungen klingeln oder vibrieren. Unterhaltungen von <xliff:g id="APP_NAME">%1$s</xliff:g> werden standardmäßig als Bubble angezeigt."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Das System entscheiden lassen, ob bei dieser Benachrichtigung ein Ton oder eine Vibration ausgegeben wird"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Nach oben"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Nach unten"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Entf"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Pos1"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Ende"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Einfg"</string>
@@ -827,7 +842,7 @@
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Eingabe"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Zur nächsten Sprache wechseln"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Zur vorherigen Sprache wechseln"</string>
- <string name="input_access_emoji" msgid="8105642858900406351">"Auf Emoji zugreifen"</string>
+ <string name="input_access_emoji" msgid="8105642858900406351">"Auf Emojis zugreifen"</string>
<string name="input_access_voice_typing" msgid="7291201476395326141">"Auf Spracheingabe zugreifen"</string>
<string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Apps"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
@@ -1296,7 +1311,7 @@
<string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• Mindestens ein Gerät oder Gerätesteuerfeld ist verfügbar"</string>
<string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Wähle eine Standard-App für Notizen aus, die du für die Verknüpfung verwenden möchtest"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"App wählen"</string>
- <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Verknüpfung berühren &amp; halten"</string>
+ <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Verknüpfung gedrückt halten"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Abbrechen"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Jetzt umdrehen"</string>
<string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Smartphone auffalten"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Verwendet von <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kürzlich von <xliff:g id="APP_NAME">%1$s</xliff:g> verwendet (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System­steuerelemente"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System-Apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Zuletzt aktive Apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Splitscreen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Eingabe"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-Verknüpfungen"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Bedienungshilfen"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tastenkürzel"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tastenkürzel suchen"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Symbol „Minimieren“"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Symbol „Maximieren“"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"oder"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Touch-Geste „Zurück“"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Touch-Geste „Startbildschirm“"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Aktionstaste"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Fertig"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Gut gemacht!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Zurück"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Wenn du zurückgehen möchtest, wische an einer beliebigen Stelle des Touchpads mit drei Fingern nach links oder rechts."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad mit drei Fingern, die sich nach links und rechts bewegen"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Bildschirm zeigt eine Animation der Touch-Geste „Zurück“"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturbeleuchtung"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d von %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Smart-Home-Steuerung"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Smart-Home-Steuerung als Bildschirmschoner nutzen"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml
index 0606cc79f2e9..8d9c7930fda8 100644
--- a/packages/SystemUI/res/values-de/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Aus"</item>
<item msgid="4875147066469902392">"An"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nicht verfügbar"</item>
<item msgid="5044688398303285224">"Aus"</item>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 80a836acd5bc..b77a9f1494d2 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Η εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> εντόπισε αυτό το στιγμιότυπο οθόνης."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Η εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> και άλλες ανοικτές εφαρμογές εντόπισαν το στιγμιότυπο οθόνης."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Προσθήκη σε σημείωση"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Συμπερίληψη συνδέσμου"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Εγγραφή οθόνης"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Επεξεργασία εγγραφής οθόνης"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ειδοποίηση σε εξέλιξη για μια περίοδο λειτουργίας εγγραφής οθόνης"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Πατήστε για προβολή"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Σφάλμα κατά την αποθήκευση της εγγραφής οθόνης"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Σφάλμα κατά την έναρξη της εγγραφής οθόνης"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Θα διακόψετε την εγγραφή της εφαρμογής &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Διακοπή εγγραφής"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Γίνεται κοινοποίηση οθόνης"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Διακοπή κοινής χρήσης οθόνης;"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Θα διακόψετε την κοινή χρήση της εφαρμογής &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Διακοπή κοινής χρήσης"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Μετάδοση οθόνης"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Τερματισμός μετάδοσης;"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Θα διακόψετε τη μετάδοση της εφαρμογής &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Διακοπή μετάδοσης"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Κλείσιμο"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Εργαλείο καταγραφής προβλημάτων"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Επεξερ. καταγραφής προβλήματος"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Ειδοποίηση σε εξέλιξη για μια περίοδο λειτουργίας συλλογής προβλημάτων"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Σφάλμα κατά την αποθήκευση της καταγραφής του προβλήματος"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Σφάλμα κατά την έναρξη της καταγραφής του προβλήματος"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Προβολή σε πλήρη οθόνη"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Για έξοδο, σύρετε προς τα κάτω από το επάνω μέρος της οθόνης"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Το κατάλαβα"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Πίσω"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Αρχική οθόνη"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για συνέχεια."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Το πρόσωπο αναγνωρίστηκε. Πατήστε για συνέχεια."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Το πρόσωπο αναγνωρ. Πατήστε το εικον. ξεκλειδ. για συνέχεια."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για συνέχεια."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ολοκληρώθηκε ο έλεγχος ταυτότητας"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Ακύρωση ελέγχου ταυτότητας"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Περισσότερες επιλογές"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Προφύλαξη οθόνης"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Μην ενοχλείτε"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Αποθηκεύτηκε"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"αποσύνδεση"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ενεργοποίηση"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Αυτόματη ενεργοποίηση αύριο"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Λειτουργίες όπως το Quick Share και η Εύρεση συσκευής χρησιμοποιούν το Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Το Bluetooth θα ενεργοποιηθεί αύριο το πρωί"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Κοινή χρήση ήχου"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Προσθήκη περισσότερων γραφικών στοιχείων"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Παρατεταμένο πάτημα για προσαρμογή γραφ. στοιχείων"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Προσαρμογή γραφικών στοιχείων"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Ξεκλειδώστε για προσαρμογή των γραφικών στοιχείων"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Εικονίδιο εφαρμογής για απενεργοποιημένο γραφικό στοιχείο"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Εικονίδιο εφαρμογής για ένα γραφικό στοιχείου που εγκαθίσταται"</string>
<string name="edit_widget" msgid="9030848101135393954">"Επεξεργασία γραφικού στοιχείου"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"επιλογή γραφικού στοιχείου"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"κατάργηση γραφικού στοιχείου"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"τοποθέτηση επιλεγμένου γραφικού στοιχείου"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Γραφικά στοιχεία οθόνης κλειδώματος"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Για να ανοίξετε μια εφαρμογή χρησιμοποιώντας ένα γραφικό στοιχείο, θα πρέπει να επαληθεύσετε την ταυτότητά σας. Επίσης, λάβετε υπόψη ότι η προβολή τους είναι δυνατή από οποιονδήποτε, ακόμα και όταν το tablet σας είναι κλειδωμένο. Ορισμένα γραφικά στοιχεία μπορεί να μην προορίζονται για την οθόνη κλειδώματος και η προσθήκη τους εδώ ενδέχεται να μην είναι ασφαλής."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Το κατάλαβα"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Εναλλαγή χρήστη"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"αναπτυσσόμενο μενού"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Όλες οι εφαρμογές και τα δεδομένα αυτής της περιόδου σύνδεσης θα διαγραφούν."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Έναρξη τώρα"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Δεν υπάρχουν ειδοποιήσεις"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Δεν υπάρχουν νέες ειδοποιήσεις"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Προσαρμοστ. ειδοπ. – Ενεργές"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Όταν λαμβάνετε πολλές ειδοποιήσεις σε σύντομο χρονικό διάστημα, η συσκευή θα χαμηλώνει την ένταση και θα μειώνει τα αναδυόμενα για έως και 2 λεπτά."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Απενεργοποίηση"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ξεκλειδώστε για εμφάνιση παλαιότ. ειδοπ."</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Αυτή η συσκευή είναι διαχειριζόμενη από τον γονέα σου"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ο οργανισμός σας κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Προεπιλογή"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Αυτόματο"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Χωρίς ήχο ή δόνηση"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Χωρίς ήχο ή δόνηση και εμφανίζεται χαμηλά στην ενότητα συζητήσεων"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Ενδέχεται να κουδουνίζει ή να δονείται βάσει των ρυθμίσεων συσκευής"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Ενδέχεται να κουδουνίζει ή να δονείται βάσει των ρυθμίσεων συσκευής. Οι συζητήσεις από την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> εμφανίζονται σε συννεφάκι από προεπιλογή."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Επιτρέψτε στο σύστημα να αποφασίσει αν αυτή η ειδοποίηση θα αναπαράγει έναν ήχο ή θα ενεργοποιήσει τη δόνηση της συσκευής"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Προηγούμενη σελίδα"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Επόμενη σελίδα"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Λήξη"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Χρησιμοποιείται από την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Χρησιμοποιήθηκε πρόσφατα από την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Σύστημα"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Στοιχεία ελέγχου συστήματος"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Εφαρμογές συστήματος"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Πολυδιεργασία"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Πρόσφατες εφαρμογές"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Διαχωρισμός οθόνης"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Είσοδος"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Συντομεύσεις εφαρμογών"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Προσβασιμότητα"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Συντομεύσεις πληκτρολογίου"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Συντομεύσεις αναζήτησης"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Εικονίδιο σύμπτυξης"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Εικονίδιο ανάπτυξης"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ή"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Κίνηση επιστροφής"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Κίνηση μετάβασης στην αρχική οθόνη"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Πλήκτρο ενέργειας"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Τέλος"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Μπράβο!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Επιστροφή"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Για επιστροφή, σύρετε προς τα αριστερά ή προς τα δεξιά χρησιμοποιώντας τρία δάχτυλα οπουδήποτε στην επιφάνεια αφής."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Επιφάνεια αφής στην οποία εμφανίζονται τρία δάχτυλα να κινούνται δεξιά και αριστερά"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Οθόνη συσκευής που εμφανίζει μια κινούμενη εικόνα σχετικά με την κίνηση επιστροφής"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Οπίσθιος φωτισμός πληκτρολογίου"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Επίπεδο %1$d από %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Οικιακοί έλεγχοι"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Γρήγ. πρόσβαση σε οικιακ. ελέγχους ως προφ. οθόνης"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml
index d4545ffa6641..3f27fb49806c 100644
--- a/packages/SystemUI/res/values-el/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Ανενεργό"</item>
<item msgid="4875147066469902392">"Ενεργό"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Μη διαθέσιμο"</item>
<item msgid="5044688398303285224">"Ανενεργό"</item>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 7c6262cb3d90..1b1ae9765e72 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Include link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Screen recorder"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop recording"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop sharing screen?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop sharing"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Casting screen"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Stop casting?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Stop casting"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Close"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Issue Recorder"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processing issue recording"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Ongoing notification for an issue collection session"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Error saving issue recording"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Error starting issue recording"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Viewing full screen"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"To exit, swipe down from the top of your screen"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Got it"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Unlocked by face. Tap to continue."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Tap to connect or disconnect a device"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automatically turn on tomorrow"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Features like Quick Share and Find My Device use Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth will turn on tomorrow morning"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Share audio"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Unlock to customise widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"No sound or vibration"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No sound or vibration and appears lower in conversation section"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"May ring or vibrate based on device settings"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"May ring or vibrate based on device settings. Conversations from <xliff:g id="APP_NAME">%1$s</xliff:g> bubble by default."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Have the system determine if this notification should make sound or vibration"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Back gesture"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Home gesture"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Action key"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Done"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Great work!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using 3 fingers anywhere on the touchpad."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing 3 fingers moving right and left"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Quickly access your home controls as a screensaver"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
index 39dd7c84b13e..27c23aa63a07 100644
--- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Off"</item>
<item msgid="4875147066469902392">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Unavailable"</item>
<item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index ed4ccf374964..0acb6744e869 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Include link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Screen Recorder"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -125,17 +126,25 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
- <string name="screenrecord_stop_dialog_title" msgid="2685522129492260887">"Stop recording screen?"</string>
- <string name="screenrecord_stop_dialog_message" msgid="1926783607059442889">"You will stop recording your screen"</string>
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Stop recording?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"You\'re currently recording your entire screen"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"You\'re currently recording <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop recording"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop sharing screen?"</string>
- <string name="share_to_app_stop_dialog_message" msgid="3181723638915877339">"You will stop sharing your screen"</string>
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"You\'re currently sharing your entire screen with <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"You\'re currently sharing your entire screen with an app"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"You\'re currently sharing <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"You\'re currently sharing an app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop sharing"</string>
- <string name="cast_to_other_device_stop_dialog_title" msgid="1910372600290258193">"Stop casting screen?"</string>
- <string name="cast_to_other_device_stop_dialog_message" msgid="1502520537030715412">"You will stop casting your screen"</string>
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Casting screen"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Stop casting?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"You\'re currently casting your entire screen to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"You\'re currently casting your entire screen to a nearby device"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"You\'re currently casting <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> to <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"You\'re currently casting <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> to a nearby device"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"You\'re currently casting to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"You\'re currently casting to a nearby device"</string>
<string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Stop casting"</string>
<string name="close_dialog_button" msgid="4749497706540104133">"Close"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Issue Recorder"</string>
@@ -181,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognized. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognized. Press the unlock icon to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Unlocked by face. Tap to continue."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel Authentication"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More Options"</string>
@@ -280,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"Priority modes"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Tap to connect or disconnect a device"</string>
@@ -460,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customize widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customize widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Unlock to customize widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -478,6 +490,8 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Lock screen widgets"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Anyone can view widgets on your lock screen, even if your tablet\'s locked."</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you’ll need to verify it’s you. Also, keep in mind that anyone can view them, even when your tablet’s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
@@ -702,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"No sound or vibration"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No sound or vibration and appears lower in conversation section"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"May ring or vibrate based on device settings"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"May ring or vibrate based on device settings. Conversations from <xliff:g id="APP_NAME">%1$s</xliff:g> bubble by default."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Have the system determine if this notification should make sound or vibration"</string>
@@ -759,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1334,9 +1350,14 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current App"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
@@ -1347,6 +1368,7 @@
<string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Home gesture"</string>
<string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Action key"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Done"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Great job!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using three fingers anywhere on the touchpad."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing three fingers moving right and left"</string>
@@ -1355,4 +1377,5 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home Controls"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Quickly access your home controls as a screensaver"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"Undo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
index 39dd7c84b13e..0658ce58e60f 100644
--- a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"Off"</item>
<item msgid="4875147066469902392">"On"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"Unavailable"</item>
+ <item msgid="2004750556637773692">"Off"</item>
+ <item msgid="8968530753931637871">"On"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Unavailable"</item>
<item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 7c6262cb3d90..1b1ae9765e72 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Include link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Screen recorder"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop recording"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop sharing screen?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop sharing"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Casting screen"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Stop casting?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Stop casting"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Close"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Issue Recorder"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processing issue recording"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Ongoing notification for an issue collection session"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Error saving issue recording"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Error starting issue recording"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Viewing full screen"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"To exit, swipe down from the top of your screen"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Got it"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Unlocked by face. Tap to continue."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Tap to connect or disconnect a device"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automatically turn on tomorrow"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Features like Quick Share and Find My Device use Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth will turn on tomorrow morning"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Share audio"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Unlock to customise widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"No sound or vibration"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No sound or vibration and appears lower in conversation section"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"May ring or vibrate based on device settings"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"May ring or vibrate based on device settings. Conversations from <xliff:g id="APP_NAME">%1$s</xliff:g> bubble by default."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Have the system determine if this notification should make sound or vibration"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Back gesture"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Home gesture"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Action key"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Done"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Great work!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using 3 fingers anywhere on the touchpad."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing 3 fingers moving right and left"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Quickly access your home controls as a screensaver"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
index 39dd7c84b13e..27c23aa63a07 100644
--- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Off"</item>
<item msgid="4875147066469902392">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Unavailable"</item>
<item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 7c6262cb3d90..1b1ae9765e72 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Include link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Screen recorder"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop recording"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop sharing screen?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop sharing"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Casting screen"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Stop casting?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Stop casting"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Close"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Issue Recorder"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processing issue recording"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Ongoing notification for an issue collection session"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Error saving issue recording"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Error starting issue recording"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Viewing full screen"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"To exit, swipe down from the top of your screen"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Got it"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Unlocked by face. Tap to continue."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Tap to connect or disconnect a device"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automatically turn on tomorrow"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Features like Quick Share and Find My Device use Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth will turn on tomorrow morning"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Share audio"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Unlock to customise widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"No sound or vibration"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No sound or vibration and appears lower in conversation section"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"May ring or vibrate based on device settings"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"May ring or vibrate based on device settings. Conversations from <xliff:g id="APP_NAME">%1$s</xliff:g> bubble by default."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Have the system determine if this notification should make sound or vibration"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Back gesture"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Home gesture"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Action key"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Done"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Great work!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using 3 fingers anywhere on the touchpad."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing 3 fingers moving right and left"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Quickly access your home controls as a screensaver"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
index 39dd7c84b13e..27c23aa63a07 100644
--- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Off"</item>
<item msgid="4875147066469902392">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Unavailable"</item>
<item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index b4fe1ec68c24..e4a6603df2bf 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ detected this screenshot.‎‏‎‎‏‎"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and other open apps detected this screenshot.‎‏‎‎‏‎"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎Add to note‎‏‎‎‏‎"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎Include link‎‏‎‎‏‎"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎Screen Recorder‎‏‎‎‏‎"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎Processing screen recording‎‏‎‎‏‎"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎Ongoing notification for a screen record session‎‏‎‎‏‎"</string>
@@ -125,17 +126,25 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎Tap to view‎‏‎‎‏‎"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎Error saving screen recording‎‏‎‎‏‎"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎Error starting screen recording‎‏‎‎‏‎"</string>
- <string name="screenrecord_stop_dialog_title" msgid="2685522129492260887">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎Stop recording screen?‎‏‎‎‏‎"</string>
- <string name="screenrecord_stop_dialog_message" msgid="1926783607059442889">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‎You will stop recording your screen‎‏‎‎‏‎"</string>
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‏‏‎‎You will stop recording &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt;‎‏‎‎‏‎"</string>
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‏‎Stop recording?‎‏‎‎‏‎"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎You\'re currently recording your entire screen‎‏‎‎‏‎"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎You\'re currently recording ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎Stop recording‎‏‎‎‏‎"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‎Sharing screen‎‏‎‎‏‎"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‎‎Stop sharing screen?‎‏‎‎‏‎"</string>
- <string name="share_to_app_stop_dialog_message" msgid="3181723638915877339">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‏‎You will stop sharing your screen‎‏‎‎‏‎"</string>
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎You will stop sharing &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt;‎‏‎‎‏‎"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‎You\'re currently sharing your entire screen with ‎‏‎‎‏‏‎<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‏‎‎You\'re currently sharing your entire screen with an app‎‏‎‎‏‎"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎You\'re currently sharing ‎‏‎‎‏‏‎<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‏‎You\'re currently sharing an app‎‏‎‎‏‎"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‏‎Stop sharing‎‏‎‎‏‎"</string>
- <string name="cast_to_other_device_stop_dialog_title" msgid="1910372600290258193">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎Stop casting screen?‎‏‎‎‏‎"</string>
- <string name="cast_to_other_device_stop_dialog_message" msgid="1502520537030715412">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎You will stop casting your screen‎‏‎‎‏‎"</string>
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎You will stop casting &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt;‎‏‎‎‏‎"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎Casting screen‎‏‎‎‏‎"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎Stop casting?‎‏‎‎‏‎"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎You\'re currently casting your entire screen to ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‎‏‎You\'re currently casting your entire screen to a nearby device‎‏‎‎‏‎"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎You\'re currently casting ‎‏‎‎‏‏‎<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎You\'re currently casting ‎‏‎‎‏‏‎<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to a nearby device‎‏‎‎‏‎"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‎‏‏‎You\'re currently casting to ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‎You\'re currently casting to a nearby device‎‏‎‎‏‎"</string>
<string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎Stop casting‎‏‎‎‏‎"</string>
<string name="close_dialog_button" msgid="4749497706540104133">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎Close‎‏‎‎‏‎"</string>
<string name="issuerecord_title" msgid="286627115110121849">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎Issue Recorder‎‏‎‎‏‎"</string>
@@ -181,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎Unlocked by face. Press to continue.‎‏‎‎‏‎"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎‎Face recognized. Press to continue.‎‏‎‎‏‎"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎Face recognized. Press the unlock icon to continue.‎‏‎‎‏‎"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎Unlocked by face. Tap to continue.‎‏‎‎‏‎"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎Authenticated‎‏‎‎‏‎"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎Cancel Authentication‎‏‎‎‏‎"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎More Options‎‏‎‎‏‎"</string>
@@ -280,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‏‏‏‎‎Screen saver‎‏‎‎‏‎"</string>
<string name="ethernet_label" msgid="2203544727007463351">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎Ethernet‎‏‎‎‏‎"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‎Do Not Disturb‎‏‎‎‏‎"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‎‏‎‏‎Priority modes‎‏‎‎‏‎"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‎Bluetooth‎‏‎‎‏‎"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‎‎‏‎‎No paired devices available‎‏‎‎‏‎"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‏‏‏‎‎Tap to connect or disconnect a device‎‏‎‎‏‎"</string>
@@ -460,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎Add more widgets‎‏‎‎‏‎"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎Long press to customize widgets‎‏‎‎‏‎"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‏‎‏‎Customize widgets‎‏‎‎‏‎"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎Unlock to customize widgets‎‏‎‎‏‎"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎App icon for disabled widget‎‏‎‎‏‎"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎App icon for a widget being installed‎‏‎‎‏‎"</string>
<string name="edit_widget" msgid="9030848101135393954">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎Edit widget‎‏‎‎‏‎"</string>
@@ -478,6 +490,8 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‏‏‏‏‎select widget‎‏‎‎‏‎"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‏‎‎remove widget‎‏‎‎‏‎"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‎‎place selected widget‎‏‎‎‏‎"</string>
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎Lock screen widgets‎‏‎‎‏‎"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‎‎‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‎‏‎‏‏‎‏‎‎‏‏‏‏‏‏‎Anyone can view widgets on your lock screen, even if your tablet\'s locked.‎‏‎‎‏‎"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎Lock screen widgets‎‏‎‎‏‎"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎To open an app using a widget, you’ll need to verify it’s you. Also, keep in mind that anyone can view them, even when your tablet’s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here.‎‏‎‎‏‎"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎Got it‎‏‎‎‏‎"</string>
@@ -702,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎Default‎‏‎‎‏‎"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎Automatic‎‏‎‎‏‎"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‎‏‏‎‎No sound or vibration‎‏‎‎‏‎"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎No sound or vibration and appears lower in conversation section‎‏‎‎‏‎"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‏‎‏‎May ring or vibrate based on device settings‎‏‎‎‏‎"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‎‎‎‎‎May ring or vibrate based on device settings. Conversations from ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ bubble by default.‎‏‎‎‏‎"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎Have the system determine if this notification should make sound or vibration‎‏‎‎‏‎"</string>
@@ -759,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‎Page Up‎‏‎‎‏‎"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‎Page Down‎‏‎‎‏‎"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎Delete‎‏‎‎‏‎"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‎‏‏‎‏‎‏‏‎‏‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‎Esc‎‏‎‎‏‎"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎Home‎‏‎‎‏‎"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‏‎‎End‎‏‎‎‏‎"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‎Insert‎‏‎‎‏‎"</string>
@@ -1334,9 +1350,14 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‎In use by ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ (‎‏‎‎‏‏‎<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>‎‏‎‎‏‏‏‎ • ‎‏‎‎‏‏‎<xliff:g id="PROXY_LABEL">%3$s</xliff:g>‎‏‎‎‏‏‏‎)‎‏‎‎‏‎"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎Recently used by ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ (‎‏‎‎‏‏‎<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>‎‏‎‎‏‏‏‎ • ‎‏‎‎‏‏‎<xliff:g id="PROXY_LABEL">%3$s</xliff:g>‎‏‎‎‏‏‏‎)‎‏‎‎‏‎"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎System‎‏‎‎‏‎"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‎‎System controls‎‏‎‎‏‎"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎System apps‎‏‎‎‏‎"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‎‎Multitasking‎‏‎‎‏‎"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎Recent apps‎‏‎‎‏‎"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎Split screen‎‏‎‎‏‎"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎Input‎‏‎‎‏‎"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‎App shortcuts‎‏‎‎‏‎"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‎‎‎Current App‎‏‎‎‏‎"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎Accessibility‎‏‎‎‏‎"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎Keyboard shortcuts‎‏‎‎‏‎"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎Search shortcuts‎‏‎‎‏‎"</string>
@@ -1347,6 +1368,7 @@
<string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎Home gesture‎‏‎‎‏‎"</string>
<string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎Action key‎‏‎‎‏‎"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎Done‎‏‎‎‏‎"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎Great job!‎‏‎‎‏‎"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎Go back‎‏‎‎‏‎"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‎To go back, swipe left or right using three fingers anywhere on the touchpad.‎‏‎‎‏‎"</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‏‎‎Touchpad showing three fingers moving right and left‎‏‎‎‏‎"</string>
@@ -1355,4 +1377,5 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎Level %1$d of %2$d‎‏‎‎‏‎"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‎‎‎‏‎Home Controls‎‏‎‎‏‎"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎Quickly access your home controls as a screensaver‎‏‎‎‏‎"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎Undo‎‏‎‎‏‎"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
index 35ab88b202de..a6a5fddbb8ef 100644
--- a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎Off‎‏‎‎‏‎"</item>
<item msgid="4875147066469902392">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‎‎On‎‏‎‎‏‎"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‏‏‏‎Unavailable‎‏‎‎‏‎"</item>
+ <item msgid="2004750556637773692">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎Off‎‏‎‎‏‎"</item>
+ <item msgid="8968530753931637871">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎On‎‏‎‎‏‎"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎Unavailable‎‏‎‎‏‎"</item>
<item msgid="5044688398303285224">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎Off‎‏‎‎‏‎"</item>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index b17e8dc2b5b9..1b751b46ec90 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detectó que tomaste una captura de pantalla."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> y otras apps en ejecución detectaron que tomaste una captura de pantalla."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Agregar a la nota"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir vínculo"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Grabadora de pantalla"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación pantalla"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación constante para una sesión de grabación de pantalla"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Presiona para ver"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Se produjo un error al guardar la grabación de pantalla"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error al iniciar la grabación de pantalla"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Dejarás de grabar contenido de &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Detener la grabación"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartiendo pantalla"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"¿Quieres dejar de compartir la pantalla?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Dejarás de compartir contenido de &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Dejar de compartir"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Transmitiendo pantalla"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"¿Detener la transmisión?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Dejarás de transmitir contenido de &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Detener transmisión"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Cerrar"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Grabadora de errores"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Procesando grabación del error"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificación continua por un error durante la sesión de recopilación de datos"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Se produjo un error al guardar la grabación del problema"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Se produjo un error al iniciar la grabación del problema"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Visualización en pantalla completa"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Para salir, desliza el dedo hacia abajo desde la parte superior de la pantalla"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Entendido"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Atrás"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Página principal"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueo con rostro. Presiona para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rostro reconocido. Presiona para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rostro reconocido. Presiona el desbloqueo para continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Se desbloqueó con el rostro. Presiona para continuar."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticación"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Más opciones"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Protector pantalla"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"No interrumpir"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No hay dispositivos sincronizados disponibles"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Presiona para conectar o desconectar un dispositivo"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activar"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Activar automáticamente mañana"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Las funciones como Quick Share y Encontrar mi dispositivo usan Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"El Bluetooth se activará mañana a la mañana"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartir audio"</string>
@@ -379,7 +392,7 @@
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Grabación de pantalla"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Detener"</string>
- <string name="qs_record_issue_label" msgid="8166290137285529059">"Grabar error"</string>
+ <string name="qs_record_issue_label" msgid="8166290137285529059">"Registrar problema"</string>
<string name="qs_record_issue_start" msgid="2979831312582567056">"Iniciar"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Detener"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Informe de errores"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Agregar más widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén presionado para personalizar los widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloquea para personalizar los widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícono de la app de widget inhabilitado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícono de la app para un widget que se está instalando"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modificar widget"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"Seleccionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"quitar widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar widget seleccionado"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets en la pantalla de bloqueo"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir una app usando un widget, debes verificar tu identidad. Además, ten en cuenta que cualquier persona podrá verlo, incluso cuando la tablet esté bloqueada. Es posible que algunos widgets no se hayan diseñados para la pantalla de bloqueo y podría ser peligroso agregarlos allí."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú expandible"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Comenzar ahora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No hay notificaciones nuevas"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notific. adaptables activadas"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Tu dispositivo ahora baja el volumen y reduce las ventanas emergentes en la pantalla por hasta dos minutos si recibes muchas notificaciones en poco tiempo."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver notificaciones anteriores"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tu padre o madre administra este dispositivo"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tu organización es propietaria de este dispositivo y podría controlar el tráfico de red"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Predeterminada"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sin sonido ni vibración"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No suena ni vibra, y aparece en la parte inferior de la sección de conversaciones"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Puede sonar o vibrar según la configuración del dispositivo"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Puede sonar o vibrar según la configuración del dispositivo. Conversaciones de la burbuja de <xliff:g id="APP_NAME">%1$s</xliff:g> de forma predeterminada."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Dejar que el sistema determine si esta notificación debe emitir un sonido o una vibración"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Re Pág"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Av Pág"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Borrar"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Inicio"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Fin"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insertar"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En uso por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Uso reciente en <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controles del sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps del sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Tareas múltiples"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apps recientes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantalla dividida"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Accesos directos a aplicaciones"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Buscar combinaciones de teclas"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícono de contraer"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícono de expandir"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gesto atrás"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gesto para ir a la pantalla principal"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tecla de acción"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Listo"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"¡Bien hecho!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atrás"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para volver, desliza tres dedos hacia la derecha o izquierda en cualquier lugar del panel táctil."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Panel táctil en el que aparecen tres dedos que se mueven hacia la derecha y la izquierda"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Pantalla de un dispositivo en la que aparece una animación del gesto atrás"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controles de la casa"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Usa rápidamente los controles de la casa como protector de pantalla"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
index 869efff07bdf..b82fafeb122c 100644
--- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Desactivado"</item>
<item msgid="4875147066469902392">"Activado"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"No disponible"</item>
<item msgid="5044688398303285224">"Desactivada"</item>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 01ea097554c2..56985bc4d478 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha detectado esta captura de pantalla."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> y otras aplicaciones abiertas han detectado esta captura de pantalla."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Añadir a nota"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir enlace"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Grabación de pantalla"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación de pantalla"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación continua de una sesión de grabación de la pantalla"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toca para verla"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"No se ha podido guardar la grabación de pantalla"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"No se ha podido empezar a grabar la pantalla"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Dejarás de grabar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Detener grabación"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartiendo pantalla"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"¿Dejar de compartir pantalla?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Dejarás de compartir &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Dejar de compartir"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Enviando pantalla"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"¿Dejar de enviar?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Dejarás de enviar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Dejar de enviar contenido"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Cerrar"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Grabadora de problemas"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Procesando grabación de problema"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificación continua de una sesión de obtención de datos del problema"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"No se ha podido guardar la grabación del problema"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"No se ha podido iniciar la grabación del problema"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Visualización en pantalla completa"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Para salir, desliza hacia abajo desde la parte superior de la pantalla"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Entendido"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Atrás"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Inicio"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado con la cara. Pulsa para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Cara reconocida. Pulsa para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Cara reconocida. Pulsa el icono de desbloquear para continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Desbloqueado con la cara. Toca para continuar."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Se ha autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticación"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Más opciones"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Salvapantallas"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"No molestar"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No hay dispositivos vinculados disponibles"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Toca para conectar o desconectar un dispositivo"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activar"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Activar automáticamente mañana"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Las funciones como Quick Share y Encontrar mi dispositivo usan Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"El Bluetooth se activará mañana por la mañana"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartir audio"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Añade más widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén pulsado para personalizar los widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloquea para personalizar los widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icono de la aplicación de widget inhabilitado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Instalando icono de aplicación para widget"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"seleccionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"eliminar widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar widget seleccionado"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets para la pantalla de bloqueo"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir una aplicación usando un widget, deberás verificar que eres tú. Además, ten en cuenta que cualquier persona podrá verlos, incluso aunque tu tablet esté bloqueada. Es posible que algunos widgets no estén pensados para la pantalla de bloqueo y no sea seguro añadirlos aquí."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar de usuario"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Empezar ahora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No hay notificaciones nuevas"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notificaciones adaptativas activadas"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Tu dispositivo baja el volumen y reduce las ventanas emergentes durante un máximo de 2 minutos cuando recibes muchas notificaciones en poco tiempo."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver notificaciones anteriores"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo lo gestionan tu padre o tu madre"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"El dispositivo pertenece a tu organización, que puede monitorizar su tráfico de red"</string>
@@ -688,7 +700,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Se ha producido un problema al obtener tus tarjetas. Inténtalo de nuevo más tarde."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Ajustes de pantalla de bloqueo"</string>
- <string name="qr_code_scanner_title" msgid="1938155688725760702">"Escáner de códigos QR"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"Escáner QR"</string>
<string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Actualizando"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo Avión"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Predeterminado"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sin sonido ni vibración"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sin sonido ni vibración, y se muestra más abajo en la sección de conversaciones"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Puede sonar o vibrar según los ajustes del dispositivo"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Puede sonar o vibrar según los ajustes del dispositivo. Las conversaciones de <xliff:g id="APP_NAME">%1$s</xliff:g> aparecen como burbujas de forma predeterminada."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Haz que el sistema determine si con esta notificación el dispositivo debe sonar o vibrar"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Re Pág"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Av Pág"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Supr"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Inicio"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Fin"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1054,7 +1069,7 @@
<string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Quitar"</string>
<string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activar/desactivar"</string>
<string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Editar"</string>
- <string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string>
+ <string name="quick_controls_title" msgid="6839108006171302273">"Control disposit."</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Elige una aplicación para añadir controles"</string>
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control añadido.}many{# controles añadidos.}other{# controles añadidos.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Quitado"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En uso por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recientemente por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controles del sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicaciones del sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarea"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicaciones recientes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantalla dividida"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Accesos directos a aplicaciones"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atajos de búsqueda"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icono de contraer"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icono de desplegar"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gesto para volver"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gesto para ir al inicio"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tecla de acción"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hecho"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"¡Bien hecho!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atrás"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para volver, desliza tres dedos hacia la izquierda o la derecha en cualquier punto del panel táctil."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Panel táctil con tres dedos moviéndose hacia la derecha y la izquierda"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Pantalla del dispositivo que muestra una animación del gesto para volver atrás"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controles de la casa"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Usa los controles de tu casa como salvapantallas"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml
index 5dbb2c132f4c..02365e5061a8 100644
--- a/packages/SystemUI/res/values-es/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Desactivado"</item>
<item msgid="4875147066469902392">"Activado"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"No disponible"</item>
<item msgid="5044688398303285224">"Desactivado"</item>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index b11804097548..111480fc9e2c 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> tuvastas selle ekraanipildi."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ja muud avatud rakendused tuvastasid selle ekraanipildi."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lisa märkmesse"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Kaasa link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Ekraanisalvesti"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekraanisalvestuse töötlemine"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Pooleli märguanne ekraanikuva salvestamise seansi puhul"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Puudutage kuvamiseks"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Viga ekraanisalvestise salvestamisel"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Viga ekraanikuva salvestamise alustamisel"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Lõpetate rakenduse &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sisu salvestamise"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Peata salvestamine"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekraani jagamine"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Kas lõpetada ekraanikuva jagamine?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Lõpetate rakenduse &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sisu jagamise"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Lõpeta jagamine"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Ekraanikuva ülekandmine"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Kas peatada ülekandmine?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Lõpetate rakenduse &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sisu ülekandmise"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Peata ülekandmine"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Sule"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Probleemisalvesti"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Probleemisalvestise töötlemine"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Probleemikogumise seansi taustamärguanne"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Viga probleemisalvestise salvestamisel"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Viga probleemi salvestamise alustamisel"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Kuvamine täisekraanil"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Väljumiseks pühkige ekraanikuva ülaosast alla"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Selge"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Tagasi"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Kodu"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avati näoga. Vajutage jätkamiseks."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nägu tuvastati. Vajutage jätkamiseks."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nägu tuvastati. Jätkamiseks vajutage avamise ikooni."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Avati näoga. Puudutage jätkamiseks."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenditud"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Tühista autentimine"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Rohkem valikuid"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Ekraanisäästja"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Mitte segada"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ühtegi seotud seadet pole saadaval"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Puudutage seadme ühendamiseks või ühenduse katkestamiseks"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvestatud"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"katkesta ühendus"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiveeri"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Lülita homme automaatselt sisse"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Sellised funktsioonid nagu Kiirjagamine ja Leia mu seade kasutavad Bluetoothi."</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth lülitub sisse homme hommikul"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Jaga heli"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lisage rohkem vidinaid"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Vajutage pikalt vidinate kohandamiseks"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Kohanda vidinaid"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Avage vidinate kohandamiseks"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Keelatud vidina rakenduseikoon"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Installitava vidina rakenduseikoon"</string>
<string name="edit_widget" msgid="9030848101135393954">"Muuda vidinat"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidina valimine"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"eemaldage vidin"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"asetage valitud vidin"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lukustuskuva vidinad"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Rakenduse avamiseks vidina abil peate kinnitama, et see olete teie. Samuti pidage meeles, et kõik saavad vidinaid vaadata, isegi kui teie tahvelarvuti on lukus. Mõni vidin ei pruugi olla ette nähtud teie lukustuskuva jaoks ja seda pole turvaline siia lisada."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Selge"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kasutaja vahetamine"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rippmenüü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Seansi kõik rakendused ja andmed kustutatakse."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Vaikeseade"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automaatne"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Ilma heli ja vibreerimiseta"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ilma heli ja vibreerimiseta, kuvatakse vestluste jaotises allpool"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Võib seadme seadete põhjal heliseda või vibreerida"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Võib seadme seadete põhjal heliseda või vibreerida. Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> vestlused kuvatakse vaikimisi mullis."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Laske süsteemil määrata, kas selle märguande puhul peaks esitama heli või vibreerima"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Lehe võrra üles"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Lehe võrra alla"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Kustuta"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Avakuva"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Lõpp"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Sisesta"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Seda kasutab <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kasutas hiljuti rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Süsteem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Süsteemi juhtelemendid"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Süsteemirakendused"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitegumtöö"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Hiljutised rakendused"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Jagatud ekraanikuva"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Sisend"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Rakenduse otseteed"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Juurdepääsetavus"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatuuri otseteed"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Otsingu otseteed"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ahendamisikoon"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Laiendamisikoon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"või"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Tagasiliikumisliigutus"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Avakuvale liikumise liigutus"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Toiminguklahv"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Valmis"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Väga hea!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Tagasi"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Tagasiliikumiseks pühkige puuteplaadil kolme sõrmega vasakule või paremale."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Puuteplaat kolme paremale ja vasakule liikuva sõrmega"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Tase %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kodu juhtelemendid"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Juurdepääs kodu juhtelementidele ekraanisäästjalt"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml
index 704649e77b86..3794f9ae109f 100644
--- a/packages/SystemUI/res/values-et/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Väljas"</item>
<item msgid="4875147066469902392">"Sees"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Pole saadaval"</item>
<item msgid="5044688398303285224">"Väljas"</item>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index d717b216b2b9..f082ea11de98 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioak pantaila-argazkia hauteman du."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioak eta irekitako beste aplikazio batzuek pantaila-argazkia hauteman dute."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Gehitu oharrean"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Sartu esteka"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Pantaila-grabagailua"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pantaila-grabaketa prozesatzen"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Pantailaren grabaketa-saioaren jakinarazpen jarraitua"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Sakatu ikusteko"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Errore bat gertatu da pantaila-grabaketa gordetzean"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Errore bat gertatu da pantaila grabatzen hastean"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; grabatzeari utziko diozu"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Utzi grabatzeari"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Pantaila partekatzen"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Pantaila partekatzeari utzi nahi diozu?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; partekatzeari utziko diozu"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Utzi partekatzeari"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Pantaila igortzen"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Igortzeari utzi nahi diozu?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; igortzeari utziko diozu"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Utzi igortzeari"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Itxi"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Arazo-grabagailua"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Arazoaren grabaketa prozesatzen"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Arazo bat biltzeko saio baten aktibo dagoen jakinarazpena"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Errore bat gertatu da arazoa grabatzean"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Errore bat gertatu da arazoa grabatzen hastean"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Pantaila osoa ikusgai"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Irteteko, pasatu hatza pantailaren goialdetik beherantz"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Ados"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Atzera"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Hasiera"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Aurpegiaren bidez desblokeatu da. Sakatu aurrera egiteko."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ezagutu da aurpegia. Sakatu aurrera egiteko."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ezagutu da aurpegia. Aurrera egiteko, sakatu desblokeatzeko ikonoa."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Aurpegiaren bidez desblokeatu da. Sakatu hau aurrera egiteko."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikatuta"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Utzi bertan behera autentifikazioa"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Aukera gehiago"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Pantaila-babeslea"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ez molestatzeko modua"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetootha"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ez dago parekatutako gailurik erabilgarri"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Sakatu hau gailu bat konektatu edo deskonektatzeko"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gordeta"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"deskonektatu"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktibatu"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Aktibatu automatikoki bihar"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share, Bilatu nire gailua eta beste eginbide batzuek Bluetootha erabiltzen dute"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bihar goizean aktibatuko da Bluetootha"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Partekatu audioa"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Gehitu widget gehiago"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widgetak pertsonalizatzeko, sakatu luze"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pertsonalizatu widgetak"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desblokeatu hau widgetak pertsonalizatzeko"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Desgaitutako widgetaren aplikazio-ikonoa"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Instalatzen ari den widget bati dagokion aplikazioaren ikonoa"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editatu widgeta"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"hautatu widget bat"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"kendu widgeta"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"kokatu hautatutako widgeta"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Pantaila blokeatuko widgetak"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Aplikazio bat widget baten bidez irekitzeko, zeu zarela egiaztatu beharko duzu. Gainera, kontuan izan edonork ikusi ahalko dituela halako widgetak, tableta blokeatuta badago ere. Baliteke widget batzuk pantaila blokeaturako egokiak ez izatea, eta agian ez da segurua haiek bertan gehitzea."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ados"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Aldatu erabiltzailea"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"zabaldu menua"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Saioko aplikazio eta datu guztiak ezabatuko dira."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Hasi"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ez dago jakinarazpenik"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ez dago jakinarazpen berririk"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Jakinarazpen egokituak aktibatuta"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Epe labur batean jakinarazpen ugari jasotzen badituzu, bolumena jaitsi, eta pantailako leiho gainerakorrak murriztuko ditu gailuak orain, gehienez 2 minutuz."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desaktibatu"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Jakinarazpen zaharragoak ikusteko, desblokeatu"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Zure gurasoak kudeatzen du gailua"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Gailu hau zure erakundearena da, eta baliteke hark sareko trafikoa gainbegiratzea"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Lehenetsia"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatikoa"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Ez du tonurik jotzen edo dar-dar egiten"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ez du tonurik jotzen edo dar-dar egiten, eta elkarrizketen atalaren behealdean agertzen da"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Baliteke tonua jotzea edo dardara egitea, gailuaren ezarpenen arabera"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Baliteke tonua jotzea edo dardara egitea, gailuaren ezarpenen arabera. Modu lehenetsian, <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioko elkarrizketak burbuila gisa agertzen dira."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Ezarri sistemak zehaztu dezala jakinarazpen honek soinua edo dardara egin behar duen ala ez"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Orrian gora"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Orrian behera"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Ezabatu"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Hasiera"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Amaitu"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Txertatu"</string>
@@ -1210,7 +1225,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Informazio gehiago lortzeko, sakatu hau"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarmarik ez"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"erabili pantailaren blokeoa"</string>
- <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Ukitu hatz-marken sentsorea. Pantailaren albo batean dagoen botoi laburra da."</string>
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Ukitu hatz-marken sentsorea. Telefonoaren albo batean dagoen botoi laburra da."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Hatz-marken sentsorea"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifikatu"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"sartu gailuan"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak darabil (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) aplikazioak erabili du duela gutxi"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistema kontrolatzeko aukerak"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemaren aplikazioak"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Zeregin bat baino gehiago aldi berean exekutatzea"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Azkenaldiko aplikazioak"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantaila zatitzea"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Sarrera"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Aplikazioetarako lasterbideak"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erabilerraztasuna"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Lasterbideak"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Bilatu lasterbideak"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tolesteko ikonoa"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Zabaltzeko ikonoa"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"edo"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Atzera egiteko keinua"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Orri nagusira joateko keinua"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Ekintza-tekla"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Eginda"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Bikain!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Egin atzera"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Atzera egiteko, pasatu 3 hatz ezkerrera edo eskuinera ukipen-panelean."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"3 hatz ukipen-panel baten gainean eskuinera eta ezkerrera mugitzen erakusten duen irudia"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Gailuaren pantailan atzera egiteko keinuaren animazioa erakusten duen irudia"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Teklatuaren hondoko argia"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d/%2$d maila"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Etxeko gailuen kontrola"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Kontrolatu etxeko gailuak pantaila-babesletik"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
index 13e14e0502c4..45d5121c4256 100644
--- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Desaktibatuta"</item>
<item msgid="4875147066469902392">"Aktibatuta"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Ez dago erabilgarri"</item>
<item msgid="5044688398303285224">"Desaktibatuta"</item>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index e690f3db9148..ceb62e48f3f5 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"‫«<xliff:g id="APPNAME">%1$s</xliff:g>» این نماگرفت را تشخیص داد."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> و سایر برنامه‌های باز این نماگرفت را تشخیص دادند."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"افزودن به یادداشت"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"اضافه کردن پیوند"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ضبط‌کن صفحه‌نمایش"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"درحال پردازش ضبط صفحه‌نمایش"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"اعلان درحال انجام برای جلسه ضبط صفحه‌نمایش"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"برای مشاهده تک‌ضرب بزنید"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"خطا در ذخیره‌سازی ضبط صفحه‌نمایش"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"خطا هنگام شروع ضبط صفحه‌نمایش"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"‏ضبط &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; را متوقف خواهید کرد"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"توقف ضبط"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"درحال هم‌رسانی صفحه‌نمایش"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"صفحه هم‌رسانی متوقف شود؟"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"‏هم‌رسانی &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; را متوقف خواهید کرد"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"توقف هم‌رسانی"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"درحال پخش محتوای صفحه‌نمایش"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"پخش محتوا متوقف شود؟"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"‏پخش محتوای &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; را متوقف خواهید کرد"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"توقف پخش محتوا"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"بستن"</string>
<string name="issuerecord_title" msgid="286627115110121849">"ضبط‌کننده مشکل"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"درحال پردازش کردن ضبط مشکل"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"اعلان جاری مربوط به جلسه جمع‌آوری مشکل"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"هنگام ذخیره کردن ضبط مشکل، خطایی پیش آمد"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"هنگام شروع ضبط مشکل، خطایی پیش آمد"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"درحال مشاهده در حالت تمام‌صفحه"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"برای خروج، از بالای صفحه تند به پایین بکشید"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"متوجه‌ام"</string>
<string name="accessibility_back" msgid="6530104400086152611">"برگشت"</string>
<string name="accessibility_home" msgid="5430449841237966217">"صفحهٔ اصلی"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"قفلْ با چهره باز شد. برای ادامه، فشار دهید."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چهره شناسایی شد. برای ادامه، فشار دهید."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چهره شناسایی شد. برای ادامه، نماد قفل‌گشایی را فشار دهید."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"قفل با چهره باز شد. برای ادامه ضربه بزنید."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"راستی‌آزمایی‌شده"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"لغو اصالت‌سنجی"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"گزینه‌های بیشتر"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"محافظ صفحه"</string>
<string name="ethernet_label" msgid="2203544727007463351">"اترنت"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"مزاحم نشوید"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"بلوتوث"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"هیچ دستگاه مرتبط شده‌ای موجود نیست"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"برای اتصال یا قطع اتصال دستگاه، تک‌ضرب بزنید"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ذخیره‌شده"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"قطع اتصال"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"فعال کردن"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"فردا به‌طور خودکار روشن شود"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ویژگی‌هایی مثل «هم‌رسانی سریع» و «پیدا کردن دستگاهم» از بلوتوث استفاده می‌کنند"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"بلوتوث فردا صبح روشن خواهد شد"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"هم‌رسانی صدا"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"افزودن ابزارک‌های بیشتر"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"برای سفارشی‌سازی ابزارک‌ها، فشار طولانی دهید"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"سفارشی‌سازی ابزارک‌ها"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"برای سفارشی‌سازی ابزاره‌ها، قفل دستگاه را باز کنید"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"نماد برنامه برای ابزارک غیرفعال"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"نماد برنامه مربوط به ابزارکی که درحال نصب است"</string>
<string name="edit_widget" msgid="9030848101135393954">"ویرایش ابزارک"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"انتخاب ابزارک"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"برداشتن ابزارک"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"جای‌گذاری ابزارک انتخاب‌شده"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ابزارک‌های صفحه قفل"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"برای باز کردن برنامه بااستفاده از ابزارک، باید هویت خودتان را به‌تأیید برسانید. همچنین، به‌خاطر داشته باشید که همه می‌توانند آن‌ها را مشاهده کنند، حتی وقتی رایانه لوحی‌تان قفل است. برخی‌از ابزارک‌ها ممکن است برای صفحه قفل درنظر گرفته نشده باشند و ممکن است اضافه کردن آن‌ها در اینجا ناامن باشد."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"متوجه‌ام"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تغییر کاربر"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"منوی پایین‌پر"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"همه برنامه‌ها و داده‌های این جلسه حذف خواهد شد."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"پیش‌فرض"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"خودکار"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"بدون صدا یا لرزش"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"بدون صدا و لرزش در پایین بخش مکالمه نشان داده می‌شود"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"بسته به تنظیمات دستگاه ممکن است زنگ بزند یا بلرزد"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"بسته به تنظیمات دستگاه ممکن است زنگ بزند یا بلرزد. مکالمه‌های <xliff:g id="APP_NAME">%1$s</xliff:g> به‌طور پیش‌فرض در حبابک نشان داده می‌شوند."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"سیستم را تنظیم کنید که تشخیص دهد اعلان صدا و لرزش داشته باشد یا نه"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"صفحه بعد"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"صفحه قبل"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"حذف"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"ابتدا"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1367,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> از آن استفاده می‌کند (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"اخیراً <xliff:g id="APP_NAME">%1$s</xliff:g> از آن استفاده کرده است (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"سیستم"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"کنترل‌های سیستم"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"برنامه‌های سیستم"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"چندوظیفگی"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"برنامه‌های اخیر"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"صفحهٔ دونیمه"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ورودی"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"میان‌برهای برنامه"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"برنامه فعلی"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"دسترس‌پذیری"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"میان‌برهای صفحه‌کلید"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"جستجوی میان‌برها"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"نماد جمع کردن"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"نماد ازهم بازکردن"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"یا"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"اشاره برگشت"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"اشاره صفحه اصلی"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"دکمه کنش"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"تمام"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"عالی است!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"برگشتن"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"برای برگشتن، در هر جایی از صفحه لمسی، با سه انگشت تند به‌چپ یا راست بکشید."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"صفحه لمسی که سه انگشت را درحال حرکت به‌سمت راست و چپ نشان می‌دهد"</string>
@@ -1374,4 +1394,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"‏سطح %1$d از %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"کنترل خانه هوشمند"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"به کنترل خانه هوشمند به‌عنوان محافظ صفحه‌نمایش دسترسی سریع دارید"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
index 756b442f5fc4..d6e0e8257196 100644
--- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"خاموش"</item>
<item msgid="4875147066469902392">"روشن"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"دردسترس نیست"</item>
<item msgid="5044688398303285224">"خاموش"</item>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 1c508c83884d..5ba52d570787 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> havaitsi tämän kuvakaappauksen."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ja jotkin muut sovellukset havaitsivat tämän kuvakaappauksen."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lisää muistiinpanoon"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Lisää linkki"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Näytön tallentaja"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Näytön tallennusta käsitellään"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Pysyvä ilmoitus näytön tallentamisesta"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Katso napauttamalla"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Virhe näyttötallenteen tallentamisessa"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Virhe näytön tallennuksen aloituksessa"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ei enää tallenna sisältöä"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Lopeta tallennus"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Näyttöä jaetaan"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Lopetetaanko näytön jakaminen?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ei enää jaa sisältöä"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Lopeta jakaminen"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Näyttöä striimataan"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Lopetetaanko striimaus?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ei enää striimaa sisältöä"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Lopeta striimaus"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Sulje"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Ongelman tallentaja"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Käsittely: Ongelman tallennus"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Ongelmankeräykseen liittyvä ilmoitus taustalla jatkuvasta toiminnasta"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Virhe ongelman tallenteen tallentamisessa"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Virhe ongelman tallentamisen aloituksessa"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Koko näytön tilassa"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Poistu pyyhkäisemällä alas näytön yläreunasta"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Selvä"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Takaisin"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Aloitus"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avattu kasvojen avulla. Jatka painamalla."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Kasvot tunnistettu. Jatka painamalla."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Kasvot tunnistettu. Jatka lukituksen avauskuvakkeella."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Avattu kasvojen avulla. Jatka napauttamalla."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Todennettu"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Peruuta todennus"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Lisää vaihtoehtoja"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Näytönsäästäjä"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Älä häiritse"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Laitepareja ei ole käytettävissä"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Muodosta yhteys laitteeseen tai katkaise yhteys napauttamalla"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Tallennettu"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"katkaise yhteys"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivoi"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Laita automaattisesti päälle huomenna"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share, Paikanna laite ja tietyt muut ominaisuudet käyttävät Bluetoothia"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth menee päälle huomisaamuna"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Jaa audio"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lisää widgetejä"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Yksilöi widgetit pitkällä painalluksella"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Muokkaa widgettejä"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Avaa widgetien yksilöintiä varten"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Käytöstä poistetun widgetin sovelluskuvake"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Sovelluskuvake widgetin asentamisesta"</string>
<string name="edit_widget" msgid="9030848101135393954">"Muokkaa widgetiä"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"valitse widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"poista widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"aseta valittu widget"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lukitusnäytön widgetit"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Jos haluat avata sovelluksen käyttämällä widgetiä, sinun täytyy vahvistaa henkilöllisyytesi. Muista myös, että widgetit näkyvät kaikille, vaikka tabletti olisi lukittuna. Jotkin widgetit on ehkä tarkoitettu lukitusnäytölle, ja niiden lisääminen tänne ei välttämättä ole turvallista."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Selvä"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Vaihda käyttäjää"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"alasvetovalikko"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Aloita nyt"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ei ilmoituksia"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ei uusia ilmoituksia"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Mukautuvat ilmoitukset päällä"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Laite vähentää nyt äänenvoimakkuutta ja ponnahdusikkunoiden määrää enintään kahdeksi minuutiksi, kun saat monta ilmoitusta lyhyellä aikavälillä."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Laita pois päältä"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Avaa lukitus niin näet ilmoituksia"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Vanhempasi ylläpitää tätä laitetta"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisaatiosi omistaa laitteen ja voi valvoa verkkoliikennettä"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Oletus"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automaattinen"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Ei ääntä tai värinää"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ei ääntä tai värinää ja näkyy alempana keskusteluosiossa"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Voi soida tai väristä laitteen asetuksista riippuen"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Voi soida tai väristä laitteen asetuksista riippuen. Keskusteluista (<xliff:g id="APP_NAME">%1$s</xliff:g>) luodaan oletuksena kuplia."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Järjestelmä valitsee, kuuluuko tästä ilmoituksesta ääntä tai väriseekö se"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Tämän käytössä: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> käytti tätä äskettäin (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Järjestelmä"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Järjestelmän hallinta"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Järjestelmäsovellukset"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitaskaus"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Viimeisimmät sovellukset"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Jaettu näyttö"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Syöte"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Sovellusten pikakuvakkeet"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Saavutettavuus"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pikanäppäimet"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pikahaut"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tiivistyskuvake"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Laajennuskuvake"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"tai"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Takaisin-ele"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Etusivu-ele"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Toimintonäppäin"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Valmis"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Hienoa!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Takaisin"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Jos haluat siirtyä takaisin, pyyhkäise kosketuslevyllä vasemmalle tai oikealle kolmella sormella."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Kosketuslevy, jolla kolme sormea liikkuu oikealle ja vasemmalle"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Laitteen näyttö, jolla näkyy animaatio takaisin-eleestä"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Näppämistön taustavalo"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Taso %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kodin ohjaus"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Avaa kodin ohjaus nopeasti näytönsäästäjän kautta"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
index 5ecc95956d1c..62900622551a 100644
--- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Poissa päältä"</item>
<item msgid="4875147066469902392">"Päällä"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Ei saatavilla"</item>
<item msgid="5044688398303285224">"Poissa päältä"</item>
diff --git a/packages/SystemUI/res/values-fr-rCA-ldrtl/strings.xml b/packages/SystemUI/res/values-fr-rCA-ldrtl/strings.xml
index 899fec0b89c6..9421af3f03ec 100644
--- a/packages/SystemUI/res/values-fr-rCA-ldrtl/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA-ldrtl/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Balayez l\'écran vers la gauche pour changer rapidement d\'application"</string>
+ <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Balayez l\'écran vers la gauche pour changer rapidement d\'appli"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 0d93e99d161b..a72cdc7e39a5 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -35,16 +35,16 @@
<string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extrême"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotation auto de l\'écran"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
- <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Autorisé <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nCette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
+ <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Autorisé <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nCette appli n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
<string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
- <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Cette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait capturer du contenu audio par l\'intermédiaire de cet appareil USB. L\'utilisation de <xliff:g id="APPLICATION">%1$s</xliff:g> avec cet appareil peut empêcher d\'entendre les appels, les notifications et les alarmes."</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Cette appli n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait capturer du contenu audio par l\'intermédiaire de cet appareil USB. L\'utilisation de <xliff:g id="APPLICATION">%1$s</xliff:g> avec cet appareil peut empêcher d\'entendre les appels, les notifications et les alarmes."</string>
<string name="usb_audio_device_prompt" msgid="7944987408206252949">"L\'utilisation de <xliff:g id="APPLICATION">%1$s</xliff:g> avec cet appareil peut empêcher d\'entendre les appels, les notifications et les alarmes."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
- <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour gérer <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nCette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
+ <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour gérer <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nCette appli n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
<string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Aucune application installée compatible avec accessoire USB. En savoir plus sur <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Aucune appli installée compatible avec accessoire USB. En savoir plus sur <xliff:g id="URL">%1$s</xliff:g>"</string>
<string name="title_usb_accessory" msgid="1236358027511638648">"Accessoire USB"</string>
<string name="label_view" msgid="6815442985276363364">"Afficher"</string>
<string name="always_use_device" msgid="210535878779644679">"Toujours ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> lorsque <xliff:g id="USB_DEVICE">%2$s</xliff:g> est connecté"</string>
@@ -83,7 +83,7 @@
<string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"L\'appareil doit être déverrouillé avant qu\'une capture d\'écran puisse être enregistrée"</string>
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Essayez de faire une autre capture d\'écran"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Impossible d\'enregistrer la capture d\'écran"</string>
- <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'application ou votre organisation n\'autorise pas les saisies d\'écran"</string>
+ <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'appli ou votre organisation n\'autorise pas les saisies d\'écran"</string>
<string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"La prise de captures d\'écran est bloquée par votre administrateur informatique"</string>
<string name="screenshot_edit_label" msgid="8754981973544133050">"Modifier"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Modifier la capture d\'écran"</string>
@@ -101,14 +101,15 @@
<string name="screenshot_private_profile_notification" msgid="1704440899154243171">"Enregistré dans <xliff:g id="APP">%1$s</xliff:g> dans le profil privé"</string>
<string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fichiers"</string>
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a détecté cette capture d\'écran."</string>
- <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> et d\'autres applications ouvertes ont détecté cette capture d\'écran."</string>
+ <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> et d\'autres applis ouvertes ont détecté cette capture d\'écran."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ajouter à une note"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Inclure le lien"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Enregistreur d\'écran"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Trait. de l\'enregist. d\'écran…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement d\'écran"</string>
<string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Commencer l\'enregistrement?"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Pendant l\'enregistrement, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Lorsque vous enregistrez une application, Android a accès à tout ce qui est visible ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Lorsque vous enregistrez une appli, Android a accès à tout ce qui est visible ou lu sur cette appli. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Commencer l\'enregistrement"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Enregistrer des fichiers audio"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio de l\'appareil"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Touchez pour afficher"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Erreur d\'enregistrement de l\'écran"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Une erreur s\'est produite lors du démarrage de l\'enregistrement d\'écran"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Vous arrêterez d\'enregistrer &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Arrêter l\'enregistrement"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Partage d\'écran en cours…"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Arrêter le partage d\'écran?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Vous arrêterez de partager &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Arrêter le partage"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Diffusion de l\'écran en cours…"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Arrêter de diffuser?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Vous arrêterez de diffuser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Arrêter la diffusion"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Fermer"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Enregistreur de problèmes"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Trait. de l\'enreg. du problème"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Notification continue pour une session de collecte d\'un problème"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Erreur lors de l\'enregistrement du problème"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Erreur lors du démarrage de l\'enregistrement du problème"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Affichage plein écran"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Pour quitter ce mode, balayer l\'écran vers le bas à partir du haut"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Précédent"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Domicile"</string>
@@ -177,7 +188,7 @@
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Numérisation du visage"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string>
<string name="cancel" msgid="1089011503403416730">"Annuler"</string>
- <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo de l\'application"</string>
+ <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo de l\'appli"</string>
<string-array name="biometric_dialog_package_names_for_logo_with_overrides">
</string-array>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmer"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverr. par reconnaissance faciale. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur Déverrouiller pour continuer."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Déverrouillé avec le visage. Touchez pour continuer."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuler l\'authentification"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Plus d\'options"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Écran de veille"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne pas déranger"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Aucun des appareils associés n\'est disponible"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Touchez pour connecter ou déconnecter un appareil"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Enregistré"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"Déconnecter"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"Activer"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"L\'activer automatiquement demain"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Les fonctionnalités comme Partage rapide et Localiser mon appareil utilisent le Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Le Bluetooth s\'activera demain matin"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Partager l\'audio"</string>
@@ -358,7 +371,7 @@
<string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"Quantité de données utilisées :<xliff:g id="DATA_USED">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Limite : <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Avertissement : <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
- <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Applications professionnelles"</string>
+ <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Applis professionnelles"</string>
<string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"En pause"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"Éclairage nocturne"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Activé la nuit"</string>
@@ -402,9 +415,9 @@
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le microphone de l\'appareil?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer l\'appareil photo de l\'appareil?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le microphone?"</string>
- <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Cette action débloque l\'accès pour toutes les applications et tous les services autorisés à utiliser le microphone."</string>
- <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Cette action débloque l\'accès pour toutes les applications et pour tous les services autorisés à utiliser l\'appareil photo."</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Cette action débloque l\'accès pour toutes les applications et tous les services autorisés à utiliser l\'appareil photo ou le microphone."</string>
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Cette action débloque l\'accès pour toutes les applis et tous les services autorisés à utiliser le microphone."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Cette action débloque l\'accès pour toutes les applis et pour tous les services autorisés à utiliser l\'appareil photo."</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Cette action débloque l\'accès pour toutes les applis et tous les services autorisés à utiliser l\'appareil photo ou le microphone."</string>
<string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Le microphone est bloqué"</string>
<string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"L\'appareil photo est bloqué"</string>
<string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"Le microphone et l\'appareil photo sont bloqués"</string>
@@ -416,13 +429,13 @@
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Microphone et appareil photo disponibles"</string>
<string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"Microphone activé"</string>
<string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"Microphone désactivé"</string>
- <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Le microphone est activé pour toutes les applications et tous les services."</string>
- <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"L\'accès au microphone est désactivé pour toutes les applications et tous les services. Vous pouvez l\'activer dans Paramètres &gt; Confidentialité &gt; Microphone."</string>
- <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"L\'accès au microphone est désactivé pour toutes les applications et tous les services. Vous pouvez modifier cette option dans Paramètres &gt; Confidentialité &gt; Microphone."</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Le microphone est activé pour toutes les applis et tous les services."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"L\'accès au microphone est désactivé pour toutes les applis et tous les services. Vous pouvez l\'activer dans Paramètres &gt; Confidentialité &gt; Microphone."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"L\'accès au microphone est désactivé pour toutes les applis et tous les services. Vous pouvez modifier cette option dans Paramètres &gt; Confidentialité &gt; Microphone."</string>
<string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"Appareil photo activé"</string>
<string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"Appareil photo désactivé"</string>
- <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"L\'appareil photo est activé pour toutes les applications et tous les services."</string>
- <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"L\'accès à l\'appareil photo est désactivé pour toutes les applications et tous les services."</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"L\'appareil photo est activé pour toutes les applis et tous les services."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"L\'accès à l\'appareil photo est désactivé pour toutes les applis et tous les services."</string>
<string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Pour utiliser le bouton du microphone, activez l\'accès au microphone dans les paramètres."</string>
<string name="sensor_privacy_dialog_open_settings" msgid="5635865896053011859">"Ouvrir les paramètres"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Autre appareil"</string>
@@ -472,14 +485,15 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ajouter plus de widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Maintenez le doigt pour personnaliser les widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personnaliser les widgets"</string>
- <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icône d\'application pour un widget désactivé"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Déverrouiller pour personnaliser des widgets"</string>
+ <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icône d\'appli pour un widget désactivé"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icône d\'appli indiquant qu\'un widget est en cours d\'installation"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modifier le widget"</string>
<string name="button_to_remove_widget" msgid="3948204829181214098">"Retirer"</string>
<string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ajouter un widget"</string>
<string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Terminé"</string>
<string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Ajouter des widgets"</string>
- <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Accédez rapidement aux widgets de vos applications préférées sans déverrouiller votre tablette."</string>
+ <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Accédez rapidement aux widgets de vos applis préférées sans déverrouiller votre tablette."</string>
<string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Autoriser n\'importe quel widget sur l\'écran de verrouillage?"</string>
<string name="button_text_to_open_settings" msgid="1987729256950941628">"Ouvrir les paramètres"</string>
<string name="work_mode_off_title" msgid="5794818421357835873">"Réactiver les applis pros?"</string>
@@ -490,53 +504,54 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"sélectionner le widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"retirer le widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placer le widget sélectionné"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets de l\'écran de verrouillage"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pour ouvrir une appli à l\'aide d\'un widget, vous devrez confirmer votre identité. En outre, gardez à l\'esprit que tout le monde peut les voir, même lorsque votre tablette est verrouillée. Certains widgets n\'ont peut-être pas été conçus pour votre écran de verrouillage et il pourrait être dangereux de les ajouter ici."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu déroulant"</string>
- <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
+ <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applis et les données de cette session seront supprimées."</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recommencer"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oui, continuer"</string>
<string name="guest_notification_app_name" msgid="2110425506754205509">"Mode Invité"</string>
<string name="guest_notification_session_active" msgid="5567273684713471450">"Vous êtes en mode Invité"</string>
- <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si vous ajoutez un nouvel utilisateur, vous quitterez le mode Invité, et toutes les applications et données de la session d\'invité en cours seront supprimées."</string>
+ <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si vous ajoutez un nouvel utilisateur, vous quitterez le mode Invité, et toutes les applis et données de la session d\'invité en cours seront supprimées."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Limite d\'utilisateurs atteinte"</string>
<string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Vous ne pouvez créer qu\'un seul utilisateur.}one{Vous pouvez ajouter jusqu\'à # utilisateur.}many{Vous pouvez ajouter jusqu\'à # d\'utilisateurs.}other{Vous pouvez ajouter jusqu\'à # utilisateurs.}}"</string>
<string name="user_remove_user_title" msgid="9124124694835811874">"Supprimer l\'utilisateur?"</string>
- <string name="user_remove_user_message" msgid="6702834122128031833">"Toutes les applications et les données de cet utilisateur seront supprimées."</string>
+ <string name="user_remove_user_message" msgid="6702834122128031833">"Toutes les applis et les données de cet utilisateur seront supprimées."</string>
<string name="user_remove_user_remove" msgid="8387386066949061256">"Supprimer"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Commencer à enregistrer ou à diffuser avec <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_dialog_warning" msgid="1303664408388363598">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aura accès à toute l\'information qui est visible sur votre écran ou lue sur votre appareil durant l\'enregistrement ou la diffusion. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et les contenus audio que vous faites jouer."</string>
<string name="media_projection_sys_service_dialog_title" msgid="3751133258891897878">"Commencer à enregistrer ou à diffuser?"</string>
<string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Le service offrant cette fonction aura accès à toute l\'information qui est visible sur votre écran ou lu sur votre appareil pendant que vous enregistrez ou diffusez. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et le contenu audio que vous faites jouer."</string>
<string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Écran entier"</string>
- <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Une seule application"</string>
- <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Partager ou enregistrer une application"</string>
+ <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Une seule appli"</string>
+ <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Partager ou enregistrer une appli"</string>
<string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Commencer à enregistrer ou à diffuser avec <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Lorsque vous partagez, enregistrez ou diffusez, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
- <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Lorsque vous partagez, enregistrez ou diffusez une application, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Lorsque vous partagez, enregistrez ou diffusez une appli, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur cette appli. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
<string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Commencer"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> a désactivé cette option"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Commencer la diffusion?"</string>
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Lorsque vous diffusez, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Lorsque vous diffusez une application, Android a accès à tout ce qui est visible sur votre écran ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Lorsque vous diffusez une appli, Android a accès à tout ce qui est visible sur votre écran ou lu sur cette appli. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
<string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Commencer la diffusion"</string>
<string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Commencer à partager?"</string>
<string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Lorsque vous partagez, enregistrez ou diffusez, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
- <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Lorsque vous partagez, enregistrez ou diffusez une application, Android a accès à tout ce qui est visible sur votre écran ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Lorsque vous partagez, enregistrez ou diffusez une appli, Android a accès à tout ce qui est visible sur votre écran ou lu sur cette appli. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
<string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Commencer"</string>
- <string name="media_projection_task_switcher_text" msgid="590885489897412359">"Le partage s\'interrompt lorsque vous changez d\'application"</string>
- <string name="media_projection_task_switcher_action_switch" msgid="8682258717291921123">"Partager plutôt cette application"</string>
+ <string name="media_projection_task_switcher_text" msgid="590885489897412359">"Le partage s\'interrompt lorsque vous changez d\'appli"</string>
+ <string name="media_projection_task_switcher_action_switch" msgid="8682258717291921123">"Partager plutôt cette appli"</string>
<string name="media_projection_task_switcher_action_back" msgid="5324164224147845282">"Revenir en arrière"</string>
- <string name="media_projection_task_switcher_notification_channel" msgid="7613206306777814253">"Commutateur d\'application"</string>
+ <string name="media_projection_task_switcher_notification_channel" msgid="7613206306777814253">"Commutateur d\'appli"</string>
<string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloquée par votre administrateur informatique"</string>
- <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"La fonctionnalité de capture d\'écran est désactivée par l\'application Device Policy"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"La fonctionnalité de capture d\'écran est désactivée par l\'appli Device Policy"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tout effacer"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gérer"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historique"</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Aucune nouvelle notification"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notifications adaptatives actives"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Votre appareil réduit le volume et les fenêtres contextuelles à l\'écran pendant 2 minutes max. quand vous recevez plusieurs notifications rapidement."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Désactiver"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Déverr. pour voir les anciennes notif."</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par ton parent"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Votre organisation possède cet appareil et peut contrôler le trafic réseau"</string>
@@ -571,8 +583,8 @@
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Votre administrateur informatique a accès à l\'activité sur le réseau de votre profil professionnel"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Le réseau peut être surveillé"</string>
<string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Cet appareil est connecté à Internet par l\'intermédiaire de RPV"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vos applications professionnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vos applications personnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vos applis professionnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vos applis personnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Cet appareil est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestion d\'appareils"</string>
@@ -581,9 +593,9 @@
<string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"Certificats CA"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Afficher les politiques"</string>
<string name="monitoring_button_view_controls" msgid="8316440345340701117">"Afficher les commandes"</string>
- <string name="monitoring_description_named_management" msgid="505833016545056036">"Votre appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
- <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> pourrait être en mesure d\'accéder aux données associées à cet appareil, de modifier ses paramètres et de gérer des applications.\n\nSi vous avez des questions, communiquez avec <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
- <string name="monitoring_description_management" msgid="4308879039175729014">"Cet appareil appartient à votre organisation.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à votre appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Votre appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applis, les données associées à l\'appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
+ <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> pourrait être en mesure d\'accéder aux données associées à cet appareil, de modifier ses paramètres et de gérer des applis.\n\nSi vous avez des questions, communiquez avec <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Cet appareil appartient à votre organisation.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applis, les données associées à votre appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Votre entreprise a installé une autorité de certification sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Votre entreprise a installé une autorité de certification dans votre profil professionnel. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Une autorité de certification est installée sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
@@ -592,11 +604,11 @@
<string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Cet appareil est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par le fournisseur de RPV."</string>
<string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Cet appareil est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par votre administrateur informatique."</string>
<string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Cet appareil est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP_0">%1$s</xliff:g> et de <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par votre administrateur informatique."</string>
- <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vos applications professionnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau dans les applications professionnelles, y compris les courriels et les données de navigation, est visible par votre administrateur informatique et par votre fournisseur de RPV."</string>
- <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vos applications personnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par votre fournisseur de RPV."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vos applis professionnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau dans les applis professionnelles, y compris les courriels et les données de navigation, est visible par votre administrateur informatique et par votre fournisseur de RPV."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vos applis personnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par votre fournisseur de RPV."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Ouvrir les paramètres RPV"</string>
- <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Cet appareil est géré par ton parent. Ton parent peut voir et gérer de l\'information, comme les applications que tu utilises, ta position et ton temps d\'utilisation des écrans."</string>
+ <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Cet appareil est géré par ton parent. Ton parent peut voir et gérer de l\'information, comme les applis que tu utilises, ta position et ton temps d\'utilisation des écrans."</string>
<string name="legacy_vpn_name" msgid="4174223520162559145">"RPV"</string>
<string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Maintenu déverrouillé par TrustAgent"</string>
<string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"L\'appareil a été verrouillé : trop de tentatives d\'authentification"</string>
@@ -616,21 +628,21 @@
<string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Le niveau du volume des écouteurs a dépassé la limite de sécurité pour cette semaine"</string>
<string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Poursuivre l\'écoute"</string>
<string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Diminuer le volume"</string>
- <string name="screen_pinning_title" msgid="9058007390337841305">"L\'application est épinglée"</string>
+ <string name="screen_pinning_title" msgid="9058007390337841305">"L\'appli est épinglée"</string>
<string name="screen_pinning_description" msgid="8699395373875667743">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur « Retour » et « Aperçu »."</string>
<string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur les touches Retour et Accueil."</string>
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'épinglage. Pour annuler l\'épinglage, balayez l\'écran vers le haut et gardez le doigt dessus."</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur « Aperçu »."</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur la touche Accueil."</string>
<string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Certaines données personnelles pourraient être accessibles (comme les contacts et le contenu des courriels)."</string>
- <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"L\'application épinglée peut ouvrir d\'autres applications."</string>
- <string name="screen_pinning_toast" msgid="8177286912533744328">"Pour annuler l\'épinglage de cette application, maintenez un doigt sur les touches Retour et Aperçu"</string>
- <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Pour annuler l\'épinglage de cette application, maintenez un doigt sur les touches Retour et Accueil"</string>
- <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Pour annuler l\'épinglage de cette application, balayez-la vers le haut et maintenez-la"</string>
+ <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"L\'appli épinglée peut ouvrir d\'autres applis."</string>
+ <string name="screen_pinning_toast" msgid="8177286912533744328">"Pour annuler l\'épinglage de cette appli, maintenez un doigt sur les touches Retour et Aperçu"</string>
+ <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Pour annuler l\'épinglage de cette appli, maintenez un doigt sur les touches Retour et Accueil"</string>
+ <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Pour annuler l\'épinglage de cette appli, balayez-la vers le haut et maintenez-la"</string>
<string name="screen_pinning_positive" msgid="3285785989665266984">"OK"</string>
<string name="screen_pinning_negative" msgid="6882816864569211666">"Non, merci"</string>
- <string name="screen_pinning_start" msgid="7483998671383371313">"Application épinglée"</string>
- <string name="screen_pinning_exit" msgid="4553787518387346893">"L\'épinglage de l\'application a été annulé"</string>
+ <string name="screen_pinning_start" msgid="7483998671383371313">"Appli épinglée"</string>
+ <string name="screen_pinning_exit" msgid="4553787518387346893">"L\'épinglage de l\'appli a été annulé"</string>
<string name="stream_voice_call" msgid="7468348170702375660">"Appeler"</string>
<string name="stream_system" msgid="7663148785370565134">"Système"</string>
<string name="stream_ring" msgid="7550670036738697526">"Sonnerie"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Par défaut"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatique"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Aucun son ni vibration"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Aucun son ni vibration, et s\'affiche plus bas dans la section des conversations"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Peut sonner ou vibrer, selon les paramètres de l\'appareil"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Peut sonner ou vibrer, selon les paramètres de l\'appareil. Conversations des bulles de <xliff:g id="APP_NAME">%1$s</xliff:g> par défaut."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Faire en sorte que le système détermine si cette notification devrait émettre un son ou vibrer"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page précédente"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page suivante"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Supprimer"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Accueil"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Fin"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insérer"</string>
@@ -802,34 +817,34 @@
<string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Affichage des résultats de recherche en cours…"</string>
<string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Affichage des raccourcis du système en cours…"</string>
<string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Affichage des raccourcis d\'entrée en cours…"</string>
- <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Affichage des raccourcis qui ouvrent les applications en cours…"</string>
- <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Affichage des raccourcis de l\'application actuelle en cours…"</string>
+ <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Affichage des raccourcis qui ouvrent les applis en cours…"</string>
+ <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Affichage des raccourcis de l\'appli actuelle en cours…"</string>
<string name="group_system_access_notification_shade" msgid="1619028907006553677">"Afficher les notifications"</string>
<string name="group_system_full_screenshot" msgid="5742204844232667785">"Prendre une capture d\'écran"</string>
<string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Afficher les raccourcis"</string>
<string name="group_system_go_back" msgid="2730322046244918816">"Retour"</string>
<string name="group_system_access_home_screen" msgid="4130366993484706483">"Aller à l’écran d’accueil"</string>
- <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Afficher les applications récentes"</string>
- <string name="group_system_cycle_forward" msgid="5478663965957647805">"Parcourir les applications récentes"</string>
- <string name="group_system_cycle_back" msgid="8194102916946802902">"Parcourir les applications récentes en sens inverse"</string>
- <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Ouvrir la liste des applications"</string>
+ <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Afficher les applis récentes"</string>
+ <string name="group_system_cycle_forward" msgid="5478663965957647805">"Parcourir les applis récentes"</string>
+ <string name="group_system_cycle_back" msgid="8194102916946802902">"Parcourir les applis récentes en sens inverse"</string>
+ <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Ouvrir la liste des applis"</string>
<string name="group_system_access_system_settings" msgid="8731721963449070017">"Ouvrir les paramètres"</string>
<string name="group_system_access_google_assistant" msgid="7210074957915968110">"Ouvrir l\'Assistant"</string>
<string name="group_system_lock_screen" msgid="7391191300363416543">"Écran de verrouillage"</string>
<string name="group_system_quick_memo" msgid="3764560265935722903">"Prendre une note"</string>
<string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Multitâche"</string>
- <string name="system_multitasking_rhs" msgid="8714224917276297810">"Utiliser l\'Écran divisé avec l\'application actuelle à droite"</string>
- <string name="system_multitasking_lhs" msgid="8402954791206308783">"Utiliser l\'Écran divisé avec l\'application actuelle à gauche"</string>
+ <string name="system_multitasking_rhs" msgid="8714224917276297810">"Utiliser l\'Écran divisé avec l\'appli actuelle à droite"</string>
+ <string name="system_multitasking_lhs" msgid="8402954791206308783">"Utiliser l\'Écran divisé avec l\'appli actuelle à gauche"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"Passer de l\'écran divisé au plein écran"</string>
- <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'application à droite ou en dessous avec l\'Écran divisé"</string>
- <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passer à l\'application à gauche ou au-dessus avec l\'Écran divisé"</string>
- <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode d\'écran divisé : remplacer une application par une autre"</string>
+ <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'appli à droite ou en dessous avec l\'Écran divisé"</string>
+ <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passer à l\'appli à gauche ou au-dessus avec l\'Écran divisé"</string>
+ <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode d\'écran divisé : remplacer une appli par une autre"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrée"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Passer à la langue suivante"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Passer à la langue précédente"</string>
<string name="input_access_emoji" msgid="8105642858900406351">"Accéder aux émojis"</string>
<string name="input_access_voice_typing" msgid="7291201476395326141">"Accéder à l\'entrée vocale"</string>
- <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applications"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applis"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Navigateur"</string>
<string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contacts"</string>
@@ -929,27 +944,27 @@
<string name="lockscreen_unlock_left" msgid="1417801334370269374">"Le raccourci gauche déverrouille aussi :"</string>
<string name="lockscreen_unlock_right" msgid="4658008735541075346">"Le raccourci droit déverrouille aussi :"</string>
<string name="lockscreen_none" msgid="4710862479308909198">"Aucun"</string>
- <string name="tuner_launch_app" msgid="3906265365971743305">"Lancer l\'application <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="tuner_other_apps" msgid="7767462881742291204">"Autres applications"</string>
+ <string name="tuner_launch_app" msgid="3906265365971743305">"Lancer l\'appli <xliff:g id="APP">%1$s</xliff:g>"</string>
+ <string name="tuner_other_apps" msgid="7767462881742291204">"Autres applis"</string>
<string name="tuner_circle" msgid="5270591778160525693">"Cercle"</string>
<string name="tuner_plus" msgid="4130366441154416484">"Plus"</string>
<string name="tuner_minus" msgid="5258518368944598545">"Moins"</string>
<string name="tuner_left" msgid="5758862558405684490">"Gauche"</string>
<string name="tuner_right" msgid="8247571132790812149">"Droite"</string>
<string name="tuner_menu" msgid="363690665924769420">"Menu"</string>
- <string name="tuner_app" msgid="6949280415826686972">"Application <xliff:g id="APP">%1$s</xliff:g>"</string>
+ <string name="tuner_app" msgid="6949280415826686972">"Appli <xliff:g id="APP">%1$s</xliff:g>"</string>
<string name="notification_channel_alerts" msgid="3385787053375150046">"Alertes"</string>
<string name="notification_channel_battery" msgid="9219995638046695106">"Pile"</string>
<string name="notification_channel_screenshot" msgid="7665814998932211997">"Saisies d\'écran"</string>
- <string name="notification_channel_instant" msgid="7556135423486752680">"Applications instantanées"</string>
+ <string name="notification_channel_instant" msgid="7556135423486752680">"Applis instantanées"</string>
<string name="notification_channel_setup" msgid="7660580986090760350">"Configuration"</string>
<string name="notification_channel_storage" msgid="2720725707628094977">"Stockage"</string>
<string name="notification_channel_hints" msgid="7703783206000346876">"Conseils"</string>
<string name="notification_channel_accessibility" msgid="8956203986976245820">"Accessibilité"</string>
- <string name="instant_apps" msgid="8337185853050247304">"Applications instantanées"</string>
+ <string name="instant_apps" msgid="8337185853050247304">"Applis instantanées"</string>
<string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> en cours d\'exécution"</string>
- <string name="instant_apps_message" msgid="6112428971833011754">"Application ouverte sans avoir été installée."</string>
- <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Application ouverte sans avoir été installée. Touchez ici pour en savoir plus."</string>
+ <string name="instant_apps_message" msgid="6112428971833011754">"Appli ouverte sans avoir été installée."</string>
+ <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Appli ouverte sans avoir été installée. Touchez ici pour en savoir plus."</string>
<string name="app_info" msgid="5153758994129963243">"Détails de l\'appli"</string>
<string name="go_to_web" msgid="636673528981366511">"Ouvrir le navigateur"</string>
<string name="mobile_data" msgid="4564407557775397216">"Données cellulaires"</string>
@@ -960,9 +975,9 @@
<string name="dnd_is_off" msgid="3185706903793094463">"Le mode Ne pas déranger est désactivé"</string>
<string name="dnd_is_on" msgid="7009368176361546279">"Mode Ne pas déranger activé"</string>
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Le mode Ne pas déranger a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>)."</string>
- <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode Ne pas déranger a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>)."</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode Ne pas déranger a été activé par une règle automatique ou une application."</string>
- <string name="running_foreground_services_title" msgid="5137313173431186685">"Applications qui fonctionnent en arrière-plan"</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode Ne pas déranger a été activé par une appli (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode Ne pas déranger a été activé par une règle automatique ou une appli."</string>
+ <string name="running_foreground_services_title" msgid="5137313173431186685">"Applis qui fonctionnent en arrière-plan"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Désactiver les données cellulaires?"</string>
<string name="mobile_data_disable_message" msgid="8604966027899770415">"Vous n\'aurez pas accès aux données ni à Internet avec <xliff:g id="CARRIER">%s</xliff:g>. Vous ne pourrez accéder à Internet que par Wi-Fi."</string>
@@ -971,18 +986,18 @@
<string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Il n\'y aura pas de basculement automatique entre les données mobiles selon la disponibilité"</string>
<string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"Non merci"</string>
<string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Oui, basculer"</string>
- <string name="touch_filtered_warning" msgid="8119511393338714836">"Une application obscurcit une demande d\'autorisation, alors Paramètres ne peut pas vérifier votre réponse."</string>
+ <string name="touch_filtered_warning" msgid="8119511393338714836">"Une appli obscurcit une demande d\'autorisation, alors Paramètres ne peut pas vérifier votre réponse."</string>
<string name="slice_permission_title" msgid="3262615140094151017">"Autoriser <xliff:g id="APP_0">%1$s</xliff:g> à afficher <xliff:g id="APP_2">%2$s</xliff:g> tranches?"</string>
<string name="slice_permission_text_1" msgid="6675965177075443714">"- Il peut lire de l\'information de <xliff:g id="APP">%1$s</xliff:g>"</string>
<string name="slice_permission_text_2" msgid="6758906940360746983">"- Il peut effectuer des actions dans <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="slice_permission_checkbox" msgid="4242888137592298523">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à afficher des tranches de n\'importe quelle application"</string>
+ <string name="slice_permission_checkbox" msgid="4242888137592298523">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à afficher des tranches de n\'importe quelle appli"</string>
<string name="slice_permission_allow" msgid="6340449521277951123">"Autoriser"</string>
<string name="slice_permission_deny" msgid="6870256451658176895">"Refuser"</string>
<string name="auto_saver_title" msgid="6873691178754086596">"Toucher pour activer la fonction Économiseur de pile"</string>
<string name="auto_saver_text" msgid="3214960308353838764">"Activer si la pile est susceptible de s\'épuiser totalement"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Non merci"</string>
<string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"En cours d\'utilisation"</string>
- <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applis utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" et "</string>
<string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"En cours d\'utilisation par : <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
@@ -1055,7 +1070,7 @@
<string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"basculer"</string>
<string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Modifier"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Commandes des appareils"</string>
- <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'application pour laquelle ajouter des commandes"</string>
+ <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'appli pour laquelle ajouter des commandes"</string>
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}many{# de commandes ajoutées.}other{# commandes ajoutées.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Ajouter <xliff:g id="APPNAME">%s</xliff:g>?"</string>
@@ -1072,11 +1087,11 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Faites glisser les commandes pour les réorganiser"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Toutes les commandes ont été retirées"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Modifications non enregistrées"</string>
- <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Afficher autres applications"</string>
+ <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Afficher autres applis"</string>
<string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Réorganiser"</string>
<string name="controls_favorite_add_controls" msgid="1221420435546694004">"Ajouter des commandes"</string>
<string name="controls_favorite_back_to_editing" msgid="184125114090062713">"Retour à la modification"</string>
- <string name="controls_favorite_load_error" msgid="5126216176144877419">"Impossible de charger les commandes. Vérifiez l\'application <xliff:g id="APP">%s</xliff:g> pour vous assurer que les paramètres de l\'application n\'ont pas changé."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Impossible de charger les commandes. Vérifiez l\'appli <xliff:g id="APP">%s</xliff:g> pour vous assurer que les paramètres de l\'appli n\'ont pas changé."</string>
<string name="controls_favorite_load_none" msgid="7687593026725357775">"Les commandes compatibles ne sont pas accessibles"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Autre"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Ajouter aux commandes des appareils"</string>
@@ -1085,9 +1100,9 @@
<string name="controls_dialog_message" msgid="342066938390663844">"Suggestion de <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Appareil verrouillé"</string>
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Afficher et contrôler les appareils à partir de l\'écran de verrouillage?"</string>
- <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Vous pouvez ajouter des commandes pour vos appareils externes à l\'écran de verrouillage.\n\nL\'application de votre appareil peut vous permettre de contrôler certains appareils sans déverrouiller votre téléphone ou votre tablette.\n\nVous pouvez apporter des modifications à tout moment dans les paramètres."</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Vous pouvez ajouter des commandes pour vos appareils externes à l\'écran de verrouillage.\n\nL\'appli de votre appareil peut vous permettre de contrôler certains appareils sans déverrouiller votre téléphone ou votre tablette.\n\nVous pouvez apporter des modifications à tout moment dans les paramètres."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Contrôler les appareils à partir de l\'écran de verrouillage?"</string>
- <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Vous pouvez contrôler certains appareils sans déverrouiller votre téléphone ou votre tablette. L\'application de votre appareil détermine quels appareils peuvent être contrôlés de cette manière."</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Vous pouvez contrôler certains appareils sans déverrouiller votre téléphone ou votre tablette. L\'appli de votre appareil détermine quels appareils peuvent être contrôlés de cette manière."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Non merci"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Oui"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Le NIP contient des lettres ou des symboles"</string>
@@ -1130,14 +1145,14 @@
<string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"La commande n\'est pas accessible"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"Impossible d\'accéder à <xliff:g id="DEVICE">%1$s</xliff:g>. Vérifiez l\'application <xliff:g id="APPLICATION">%2$s</xliff:g> pour vous assurer que la commande est toujours offerte et que les paramètres de l\'application n\'ont pas changé."</string>
- <string name="controls_open_app" msgid="483650971094300141">"Ouvrir l\'application"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Impossible d\'accéder à <xliff:g id="DEVICE">%1$s</xliff:g>. Vérifiez l\'appli <xliff:g id="APPLICATION">%2$s</xliff:g> pour vous assurer que la commande est toujours offerte et que les paramètres de l\'appli n\'ont pas changé."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Ouvrir l\'appli"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Impossible de charger l\'état"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Erreur. Veuillez réessayer."</string>
<string name="controls_menu_add" msgid="4447246119229920050">"Ajouter des commandes"</string>
<string name="controls_menu_edit" msgid="890623986951347062">"Modifier des commandes"</string>
- <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ajouter une application"</string>
- <string name="controls_menu_remove" msgid="3006525275966023468">"Retirer l\'application"</string>
+ <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ajouter une appli"</string>
+ <string name="controls_menu_remove" msgid="3006525275966023468">"Retirer l\'appli"</string>
<string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ajouter des sorties"</string>
<string name="media_output_dialog_group" msgid="5571251347877452212">"Groupe"</string>
<string name="media_output_dialog_single_device" msgid="3102758980643351058">"Un appareil sélectionné"</string>
@@ -1145,8 +1160,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(déconnecté)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Changement impossible. Touchez pour réessayer."</string>
<string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connecter un appareil"</string>
- <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour diffuser cette session, veuillez ouvrir l\'application."</string>
- <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Application inconnue"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour diffuser cette session, veuillez ouvrir l\'appli."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Appli inconnue"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Arrêter la diffusion"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Appareils disponibles pour la sortie audio."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
@@ -1234,13 +1249,13 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Connexion automatique au Wi-Fi impossible pour le moment"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Tout afficher"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Pour changer de réseau, débranchez le câble Ethernet"</string>
- <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Pour améliorer l\'expérience de l\'appareil, les applications et les services peuvent quand même rechercher des réseaux Wi-Fi en tout temps, même lorsque le Wi-Fi est désactivé. Vous pouvez modifier vos préférences dans les paramètres de recherche de réseaux Wi-Fi. "<annotation id="link">"Modifier"</annotation></string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Pour améliorer l\'expérience de l\'appareil, les applis et les services peuvent quand même rechercher des réseaux Wi-Fi en tout temps, même lorsque le Wi-Fi est désactivé. Vous pouvez modifier vos préférences dans les paramètres de recherche de réseaux Wi-Fi. "<annotation id="link">"Modifier"</annotation></string>
<string name="turn_off_airplane_mode" msgid="8425587763226548579">"Désactiver le mode Avion"</string>
- <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"L\'application <xliff:g id="APPNAME">%1$s</xliff:g> veut ajouter la tuile suivante au menu Paramètres rapides"</string>
+ <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"L\'appli <xliff:g id="APPNAME">%1$s</xliff:g> veut ajouter la tuile suivante au menu Paramètres rapides"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Ajouter la tuile"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne pas ajouter de tuile"</string>
<string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Choisir l\'utilisateur"</string>
- <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# application est active}one{# application est active}many{# d\'applications sont actives}other{# applications sont actives}}"</string>
+ <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# appli est active}one{# appli est active}many{# d\'applis sont actives}other{# applis sont actives}}"</string>
<string name="fgs_dot_content_description" msgid="2865071539464777240">"Nouvelle information"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Applis actives"</string>
<string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ces applis sont actives et s\'exécutent même lorsque vous ne les utilisez pas. Cela améliore leur fonctionnalité, mais peut également affecter l\'autonomie de la pile."</string>
@@ -1286,16 +1301,16 @@
<string name="log_access_confirmation_title" msgid="4843557604739943395">"Autoriser <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> à accéder à l\'ensemble des journaux de l\'appareil?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"Autoriser un accès unique"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ne pas autoriser"</string>
- <string name="log_access_confirmation_body" msgid="6883031912003112634">"Les journaux de l\'appareil enregistrent ce qui se passe sur celui-ci. Les applications peuvent utiliser ces journaux pour trouver et résoudre des problèmes.\n\nCertains journaux peuvent contenir des renseignements confidentiels. N\'autorisez donc que les applications auxquelles vous faites confiance puisque celles-ci pourront accéder à l\'ensemble des journaux de l\'appareil. \n\nMême si vous n\'autorisez pas cette application à accéder à l\'ensemble des journaux de l\'appareil, elle aura toujours accès à ses propres journaux. Le fabricant de votre appareil pourrait toujours être en mesure d\'accéder à certains journaux ou renseignements sur votre appareil."</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Les journaux de l\'appareil enregistrent ce qui se passe sur celui-ci. Les applis peuvent utiliser ces journaux pour trouver et résoudre des problèmes.\n\nCertains journaux peuvent contenir des renseignements confidentiels. N\'autorisez donc que les applis auxquelles vous faites confiance puisque celles-ci pourront accéder à l\'ensemble des journaux de l\'appareil. \n\nMême si vous n\'autorisez pas cette appli à accéder à l\'ensemble des journaux de l\'appareil, elle aura toujours accès à ses propres journaux. Le fabricant de votre appareil pourrait toujours être en mesure d\'accéder à certains journaux ou renseignements sur votre appareil."</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"En savoir plus"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"En savoir plus : <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Pour ajouter l\'application portefeuille sous forme de raccourci, assurez-vous que l\'application est installée"</string>
- <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Pour ajouter l\'application Portefeuille sous forme de raccourci, assurez-vous qu\'au moins une carte a été ajoutée"</string>
- <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Pour ajouter l\'application Home sous forme de raccourci, assurez-vous que l\'application est installée"</string>
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Pour ajouter l\'appli portefeuille sous forme de raccourci, assurez-vous que l\'appli est installée"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Pour ajouter l\'appli Portefeuille sous forme de raccourci, assurez-vous qu\'au moins une carte a été ajoutée"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Pour ajouter l\'appli Home sous forme de raccourci, assurez-vous que l\'appli est installée"</string>
<string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• Au moins un appareil ou un panneau d\'appareils est accessible"</string>
- <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Sélectionnez une application de prise de notes par défaut pour utiliser le raccourci de prise de notes"</string>
- <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Sélectionner l\'application"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Sélectionnez une appli de prise de notes par défaut pour utiliser le raccourci de prise de notes"</string>
+ <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Sélectionner l\'appli"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Maintenir le doigt sur raccourci"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Changer d\'écran maintenant"</string>
@@ -1312,10 +1327,10 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connectez votre stylet à un chargeur"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Pile du stylet faible"</string>
<string name="video_camera" msgid="7654002575156149298">"Caméra"</string>
- <string name="call_from_work_profile_title" msgid="5418253516453177114">"Impossible d\'appeler à partir d\'une application personnelle"</string>
- <string name="call_from_work_profile_text" msgid="2856337395968118274">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applications professionnelles"</string>
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Impossible d\'appeler à partir d\'une appli personnelle"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applis professionnelles"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string>
- <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installer une application de téléphone professionnelle"</string>
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installer une appli de téléphone professionnelle"</string>
<string name="call_from_work_profile_close" msgid="5830072964434474143">"Annuler"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Personn. l\'écran de verrouillage"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Déverrouiller pour personnaliser l\'écran de verrouillage"</string>
@@ -1325,8 +1340,8 @@
<string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microphone bloqué"</string>
<string name="priority_mode_dream_overlay_content_description" msgid="3361628029609329182">"Ne pas déranger"</string>
<string name="assistant_attention_content_description" msgid="4166330881435263596">"La présence d\'un utilisateur est détectée"</string>
- <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir l\'application de prise de notes par défaut dans les Paramètres"</string>
- <string name="install_app" msgid="5066668100199613936">"Installer l\'application"</string>
+ <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir l\'appli de prise de notes par défaut dans les Paramètres"</string>
+ <string name="install_app" msgid="5066668100199613936">"Installer l\'appli"</string>
<string name="dismissible_keyguard_swipe" msgid="8377597870094949432">"Balayer vers le haut pour continuer"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Dupliquer l\'écran sur un moniteur externe?"</string>
<string name="connected_display_dialog_dual_display_stop_warning" msgid="4174707498892447947">"Votre écran intérieur sera dupliqué. Votre écran frontal sera désactivé."</string>
@@ -1334,12 +1349,12 @@
<string name="dismiss_dialog" msgid="2195508495854675882">"Fermer"</string>
<string name="connected_display_icon_desc" msgid="6373560639989971997">"Écran connecté"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone et appareil photo"</string>
- <string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilisation récente par les applications"</string>
+ <string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilisation récente par les applis"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Afficher l\'accès récent"</string>
<string name="privacy_dialog_done_button" msgid="4504330708531434263">"OK"</string>
<string name="privacy_dialog_expand_action" msgid="9129262348628331377">"Développer et afficher les options"</string>
<string name="privacy_dialog_collapse_action" msgid="277419962019466347">"Réduire"</string>
- <string name="privacy_dialog_close_app_button" msgid="8006250171305878606">"Fermer cette application"</string>
+ <string name="privacy_dialog_close_app_button" msgid="8006250171305878606">"Fermer cette appli"</string>
<string name="privacy_dialog_close_app_message" msgid="1316408652526310985">"<xliff:g id="APP_NAME">%1$s</xliff:g> fermé"</string>
<string name="privacy_dialog_manage_service" msgid="8320590856621823604">"Gérer le service"</string>
<string name="privacy_dialog_manage_permissions" msgid="2543451567190470413">"Gérer l\'accès"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Utilisé par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Récemment utilisé par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Système"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Commandes système"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Applis système"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitâche"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Applis récentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Écran divisé"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrée"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Raccourcis des applis"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis-clavier"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Recherchez des raccourcis"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icône Développer"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Geste de retour"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Geste d\'accès à l\'écran d\'accueil"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Touche d\'action"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"OK"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Bon travail!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Retour"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pour revenir en arrière, balayez vers la gauche ou la droite en utilisant trois doigts n\'importe où sur le pavé tactile."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Pavé tactile montrant trois doigts se déplaçant à droite et à gauche"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Écran de l\'appareil montrant l\'animation pour le geste de retour"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Domotique"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Accès rapide : domotique sous forme d\'Écran de veille"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</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 52b763b4028d..e0445fa8c9e9 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Désactivé"</item>
<item msgid="4875147066469902392">"Activé"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Non disponible"</item>
<item msgid="5044688398303285224">"Désactivée"</item>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index afad40664355..240f0131ad50 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a détecté cette capture d\'écran."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> et d\'autres applis ouvertes ont détecté cette capture d\'écran."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ajouter à la note"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Inclure le lien"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Enregistreur d\'écran"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Enregistrement de l\'écran…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement de l\'écran"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Appuyez pour afficher"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Erreur lors de l\'enregistrement de l\'écran"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erreur lors du démarrage de l\'enregistrement de l\'écran"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Vous arrêterez d\'enregistrer &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Arrêter l\'enregistrement"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Partage de l\'écran…"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Arrêter le partage d\'écran ?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Vous arrêterez de partager &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Arrêter le partage"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Cast de l\'écran"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Arrêter de caster ?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Vous arrêterez de caster &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Arrêter de caster du contenu"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Fermer"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Enregistreur de problèmes"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Enregistrement du problème"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Notification d\'activité en cours concernant la session d\'enregistrement d\'un problème"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Erreur lors de l\'enregistrement du problème"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Erreur lors du démarrage de l\'enregistrement du problème"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Affichage en plein écran"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Pour quitter, balayez l\'écran de haut en bas"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Retour"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Accueil"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverrouillé par visage. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur l\'icône de déverrouillage pour continuer."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Déverrouillé par le visage. Appuyez pour continuer."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuler l\'authentification"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Plus d\'options"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Économiseur d\'écran"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne pas déranger"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Aucun appareil associé disponible."</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Appuyez pour connecter ou déconnecter un appareil"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Enregistré"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"dissocier"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activer"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Activer automatiquement demain"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Certaines fonctionnalités, telles que Quick Share et Localiser mon appareil, utilisent le Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Le Bluetooth sera activé demain matin"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Partager le contenu audio"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ajouter des widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Appuyez de manière prolongée pour personnaliser les widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personnaliser les widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Déverrouiller pour personnaliser les widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icône d\'appli du widget désactivé"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icône d\'application indiquant qu\'un widget est en cours d\'installation"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modifier le widget"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"sélectionner un widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"supprimer le widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"positionner le widget sélectionné"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets pour l\'écran de verrouillage"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pour ouvrir une appli à l\'aide d\'un widget, vous devez confirmer qu\'il s\'agit bien de vous. N\'oubliez pas non plus que tout le monde peut voir vos widgets, même lorsque votre tablette est verrouillée. Certains d\'entre eux n\'ont pas été conçus pour l\'écran de verrouillage et les ajouter à cet endroit peut s\'avérer dangereux."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu déroulant"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Aucune nouvelle notification"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Les notifications intelligentes sont activées"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Désormais, lorsque vous recevez de nombreuses notifications en peu de temps, votre appareil baisse le volume et réduit les pop-up qui apparaissent à l\'écran pendant deux minutes maximum."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Désactiver"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Déverrouiller pour voir anciennes notifications"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par tes parents"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Cet appareil appartient à votre organisation, qui peut contrôler votre trafic réseau"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Par défaut"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatique"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Ni son, ni vibreur"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ni son, ni vibreur ; s\'affiche plus bas dans la section des conversations"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Peut sonner ou vibrer en fonction des paramètres de l\'appareil"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Peut sonner ou vibrer en fonction des paramètres de l\'appareil. Les conversations provenant de <xliff:g id="APP_NAME">%1$s</xliff:g> s\'affichent sous forme de bulles par défaut."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Laisser le système déterminer si cette notification doit être accompagnée d\'un son ou d\'une vibration"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page précédente"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page suivante"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Supprimer"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Accueil"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Fin"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insérer"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En cours d\'utilisation par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Récemment utilisé par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Système"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Commandes système"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Applis système"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitâche"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Applis récentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Écran partagé"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrée"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Raccourcis d\'application"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis clavier"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Raccourcis de recherche"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icône Développer"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Geste Retour"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Geste Accueil"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Touche d\'action"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"OK"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Bravo !"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Retour"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pour retourner en arrière, balayez vers la gauche avec trois doigts n\'importe où sur le pavé tactile."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Pavé tactile sur lequel trois doigts glissent vers la droite, puis vers la gauche"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Écran d\'un appareil affichant l\'animation du geste Retour"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d sur %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Contrôle de la maison"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Domotique sous forme d\'économiseur d\'écran"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
index fcdd9f0e6e3a..adc9cb3789cf 100644
--- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Désactivé"</item>
<item msgid="4875147066469902392">"Activé"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Indisponible"</item>
<item msgid="5044688398303285224">"Désactivé"</item>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 5807602d4f7b..5388b09a0a58 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detectou esta captura de pantalla."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outras aplicacións abertas detectaron esta captura de pantalla."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Engadir a unha nota"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Incluír ligazón"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Gravadora da pantalla"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando gravación pantalla"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación de actividade en curso sobre unha sesión de gravación de pantalla"</string>
@@ -125,25 +126,28 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toca para ver o contido"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Produciuse un erro ao gardar a gravación da pantalla"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Produciuse un erro ao iniciar a gravación da pantalla"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Deixarás de gravar a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Queres deter a gravación?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Estás gravando toda a pantalla"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Estás gravando <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartindo pantalla"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Deixarás de compartir a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Estás compartindo toda a pantalla con <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Estás compartindo toda a pantalla cunha aplicación"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Estás compartindo <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Estás compartindo unha aplicación"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Deixarás de emitir a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Emitindo pantalla"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Queres deter a emisión?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Estás emitindo toda a pantalla en <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Estás emitindo toda a pantalla nun dispositivo próximo"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Estás emitindo <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> en <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Estás emitindo <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> nun dispositivo próximo"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Estás emitindo contido en <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Estás emitindo contido nun dispositivo próximo"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -192,6 +196,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Usouse o desbloqueo facial. Preme para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Recoñeceuse a cara. Preme para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Recoñeceuse a cara. Preme a icona de desbloquear."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Usouse o desbloqueo facial. Toca para continuar."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar a autenticación"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Máis opcións"</string>
@@ -291,6 +296,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Protector pantalla"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Non molestar"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Non hai dispositivos vinculados dispoñibles"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Toca para conectar ou desconectar un dispositivo"</string>
@@ -472,6 +479,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Engadir máis widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pulsación longa para personalizar os widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloquea o dispositivo para personalizar os widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona da aplicación de widget desactivado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icona da aplicación para un widget que se está instalando"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -490,6 +498,8 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"seleccionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"quitar o widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar o widget seleccionado"</string>
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets da pantalla de bloqueo"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Calquera pode ver os widgets na pantalla de bloqueo, mesmo coa tableta bloqueada"</string>
<!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
<skip />
<!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
@@ -717,7 +727,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Configuración predeterminada"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sen son nin vibración"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sen son nin vibración, e aparecen máis abaixo na sección de conversas"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Poderían facer que o dispositivo soe ou vibre en función da súa configuración"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Poderían facer que o dispositivo soe ou vibre en función da súa configuración. As conversas de <xliff:g id="APP_NAME">%1$s</xliff:g> móstranse en burbullas de forma predeterminada."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Fai que o sistema determine se a notificación debe emitir un son ou unha vibración"</string>
@@ -774,6 +785,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Re Páx"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Av Páx"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Supr"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Escape"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Inicio"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Fin"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Inserir"</string>
@@ -1349,9 +1361,14 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En uso por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"En uso recentemente por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controis do sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicacións do sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarefa"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicacións recentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantalla dividida"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atallos de aplicacións"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicación actual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atallos de teclado"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atallos de busca"</string>
@@ -1366,6 +1383,7 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Moi ben!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Volver"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para volver, pasa tres dedos cara á esquerda ou cara á dereita en calquera lugar do panel táctil."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Panel táctil que mostra tres dedos movéndose á dereita e á esquerda"</string>
@@ -1374,4 +1392,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controis domóticos"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Usa os controis domóticos como protector de pantalla"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
index 03b934eb9cb6..d2c8ea0906d3 100644
--- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Non"</item>
<item msgid="4875147066469902392">"Si"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Non dispoñible"</item>
<item msgid="5044688398303285224">"Non"</item>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 18107ccc88b7..66495f3642d1 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> દ્વારા આ સ્ક્રીનશૉટ લેવાયાની ભાળ મેળવવામાં આવી."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> અને કામ કરતી અન્ય ઍપ દ્વારા આ સ્ક્રીનશૉટ લેવાયાની ભાળ મેળવવામાં આવી."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"નોંધમાં ઉમેરો"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"લિંક શામેલ કરો"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"સ્ક્રીન રેકોર્ડર"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"સ્ક્રીન રેકૉર્ડિંગ ચાલુ છે"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"સ્ક્રીન રેકોર્ડિંગ સત્ર માટે ચાલુ નોટિફિકેશન"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"જોવા માટે ટૅપ કરો"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"સ્ક્રીન રેકોર્ડિંગ સાચવવામાં ભૂલ આવી"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"સ્ક્રીનને રેકૉર્ડ કરવાનું શરૂ કરવામાં ભૂલ"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"તમે &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને રેકોર્ડ કરવાનું બંધ કરશો"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"રેકોર્ડિંગ રોકો"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"સ્ક્રીન શેર કરી રહ્યાં છીએ"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"સ્ક્રીન શેર કરવાનું રોકીએ?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"તમે &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને શેર કરવાનું બંધ કરશો"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"શેર કરવાનું રોકો"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"સ્ક્રીન કાસ્ટ કરી રહ્યાં છીએ"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"શું કાસ્ટ કરવાનું બંધ કરીએ?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"તમે &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને કાસ્ટ કરવાનું બંધ કરશો"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"કાસ્ટ કરવાનું રોકો"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"બંધ કરો"</string>
<string name="issuerecord_title" msgid="286627115110121849">"સમસ્યા રેકોર્ડર"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"સમસ્યા રેકોર્ડિંગ ચાલુ છે"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"કોઈ સમસ્યા સંગ્રહના સત્ર માટે ચાલુ નોટિફિકેશન"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"સમસ્યા રેકોર્ડિંગને સાચવવામાં ભૂલ આવી"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"સમસ્યા રેકોર્ડિંગને શરૂ કરવામાં ભૂલ આવી"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"પૂર્ણ સ્ક્રીન જોઈ રહ્યાં છે"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"બહાર નીકળવા માટે, તમારી સ્ક્રીનની સૌથી ઉપરથી નીચેની તરફ સ્વાઇપ કરો"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"સમજાઈ ગયું"</string>
<string name="accessibility_back" msgid="6530104400086152611">"પાછળ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"હોમ"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ચહેરા દ્વારા અનલૉક કર્યું. આગળ વધવા માટે દબાવો."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ચહેરો ઓળખ્યો. આગળ વધવા માટે દબાવો."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ચહેરો ઓળખ્યો. આગળ વધવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ચહેરા દ્વારા અનલૉક કર્યું. ચાલુ રાખવા માટે ટૅપ કરો."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"પ્રમાણિત"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"પ્રમાણીકરણ રદ કરો"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"વધુ વિકલ્પો"</string>
@@ -291,6 +303,7 @@
<string name="start_dreams" msgid="9131802557946276718">"સ્ક્રીન સેવર"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ઇથરનેટ"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"ખલેલ પાડશો નહીં"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"પ્રાધાન્યતાના મોડ"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"બ્લૂટૂથ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"કોઈ જોડી કરેલ ઉપકરણો ઉપલબ્ધ નથી"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"કોઈ ડિવાઇસ કનેક્ટ કરવા કે ડિસ્કનેક્ટ કરવા માટે ટૅપ કરો"</string>
@@ -302,8 +315,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"સાચવેલું"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ડિસ્કનેક્ટ કરો"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"સક્રિય કરો"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"આવતીકાલે ઑટોમૅટિક રીતે ચાલુ કરો"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ક્વિક શેર અને Find My Device જેવી સુવિધાઓ બ્લૂટૂથનો ઉપયોગ કરે છે"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"બ્લૂટૂથ આવતીકાલે સવારે ચાલુ થશે"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ઑડિયો શેર કરો"</string>
@@ -472,6 +484,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"વધુ વિજેટ ઉમેરો"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"વિજેટ કસ્ટમાઇઝ કરવા માટે થોડીવાર દબાવી રાખો"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"વિજેટ કસ્ટમાઇઝ કરો"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"વિજેટ કસ્ટમાઇઝ કરવા માટે, અનલૉક કરો"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"બંધ કરેલા વિજેટ માટેની ઍપનું આઇકન"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ઇન્સ્ટૉલ થઈ રહેલા વિજેટ માટે ઍપનું આઇકન"</string>
<string name="edit_widget" msgid="9030848101135393954">"વિજેટમાં ફેરફાર કરો"</string>
@@ -490,12 +503,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"વિજેટ પસંદ કરો"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"વિજેટ કાઢી નાખો"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"પસંદ કરેલું વિજેટ મૂકો"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"લૉક સ્ક્રીન વિજેટ"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"વિજેટનો ઉપયોગ કરીને ઍપ ખોલવા માટે, તમારે એ ચકાસણી કરવાની જરૂર રહેશે કે આ તમે જ છો. તે ઉપરાંત, ધ્યાનમાં રાખો કે તમારું ટૅબ્લેટ લૉક કરેલું હોય તો પણ કોઈપણ વ્યક્તિ તેમને જોઈ શકે છે. અમુક વિજેટ કદાચ તમારી લૉક સ્ક્રીન માટે બનાવવામાં આવ્યા ન હોઈ શકે છે અને તેમને અહીં ઉમેરવાનું અસલામત હોઈ શકે છે."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"સમજાઈ ગયું"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"વપરાશકર્તા સ્વિચ કરો"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"પુલડાઉન મેનૂ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ અને ડેટા કાઢી નાખવામાં આવશે."</string>
@@ -717,7 +731,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ડિફૉલ્ટ"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"ઑટોમૅટિક રીતે"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"કોઈપણ સાઉન્ડ અથવા વાઇબ્રેશન નથી"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"કોઈપણ સાઉન્ડ અથવા વાઇબ્રેશન નથી અને વાતચીત વિભાગમાં તે વધુ નીચેની દિશાએ દેખાય છે"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"ડિવાઇસના સેટિંગના આધારે રિંગ અથવા વાઇબ્રેટ થઈ શકે છે"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ડિવાઇસના સેટિંગના આધારે રિંગ અથવા વાઇબ્રેટ થઈ શકે છે. ડિફૉલ્ટ તરીકે <xliff:g id="APP_NAME">%1$s</xliff:g> બબલની વાતચીત."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"આ નોટિફિકેશન સાઉન્ડ અથવા વાઇબ્રેટ કરી શકશે કે નહીં તે સિસ્ટમને નક્કી કરવા દો"</string>
@@ -774,6 +789,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1366,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) દ્વારા ઉપયોગ ચાલુ છે"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) દ્વારા તાજેતરમાં ઉપયોગ કરવામાં આવ્યો"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"સિસ્ટમ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"સિસ્ટમના નિયંત્રણો"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"સિસ્ટમ ઍપ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"એકથી વધુ કાર્યો કરવા"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"તાજેતરની ઍપ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"સ્ક્રીનને વિભાજિત કરો"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ઇનપુટ"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ઍપ શૉર્ટકટ"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"હાલની ઍપ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ઍક્સેસિબિલિટી"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"કીબોર્ડ શૉર્ટકટ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"શૉર્ટકટ શોધો"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\'નાનું કરો\'નું આઇકન"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"\'મોટું કરો\'નું આઇકન"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"અથવા"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"પાછળ જવાનો સંકેત"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"હોમ સ્ક્રીન પર જવાનો સંકેત"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"ઍક્શન કી"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"થઈ ગયું"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"ખૂબ સરસ કામ!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"પાછા જાઓ"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"પાછા જવા માટે, ત્રણ આંગળીઓનો ઉપયોગ કરીને ટચપૅડ પર કોઈપણ જગ્યાએ ડાબે કે જમણે સ્વાઇપ કરો."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"જમણી અને ડાબી તરફ ખસી રહેલી ત્રણ આંગળીઓ બતાવતું ટચપૅડ"</string>
@@ -1374,4 +1393,5 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dમાંથી %1$d લેવલ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ઘરેલું સાધનોના નિયંત્રણો"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"સ્ક્રીનસેવર તરીકે તમારા ઘરેલું સાધનોના નિયંત્રણો ઝડપથી ઍક્સેસ કરો"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"છેલ્લો ફેરફાર રદ કરો"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
index 5c4a4784c13f..196a05bc4ed5 100644
--- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"બંધ છે"</item>
<item msgid="4875147066469902392">"ચાલુ છે"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"અનુપલબ્ધ"</item>
+ <item msgid="2004750556637773692">"બંધ"</item>
+ <item msgid="8968530753931637871">"ચાલુ"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ઉપલબ્ધ નથી"</item>
<item msgid="5044688398303285224">"બંધ છે"</item>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 2e0864d6d350..1c956722609c 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> को इस स्क्रीनशॉट का पता चला है."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> और खुले हुए अन्य ऐप्लिकेशन को इस स्क्रीनशॉट का पता चला है."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"नोट में जोड़ें"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"लिंक जोड़ें"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"स्क्रीन रिकॉर्डर"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"देखने के लिए टैप करें"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रीन रिकॉर्डिंग सेव करते समय गड़बड़ी हुई"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन को रिकॉर्ड करने में गड़बड़ी आ रही है"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"इससे &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का कॉन्टेंट रिकॉर्ड होना बंद हो जाएगा"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"रिकॉर्ड करना बंद करें"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रीन शेयर की जा रही है"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"क्या स्क्रीन शेयरिंग बंद करनी है?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"इससे &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का कॉन्टेंट शेयर होना बंद हो जाएगा"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"शेयर करना बंद करें"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"स्क्रीन कास्ट की जा रही है"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"क्या कास्टिंग बंद करनी है?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"इससे &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का कॉन्टेंट कास्ट होना बंद हो जाएगा"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"कास्ट करना बंद करें"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"बंद करें"</string>
<string name="issuerecord_title" msgid="286627115110121849">"समस्या का डेटा सेव करने वाला टूल"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"समस्या का डेटा प्रोसेस हो रहा"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"समस्या का डेटा इकट्ठा करने के लिए बैकग्राउंड में जारी गतिविधि की सूचना"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"समस्या का डेटा सेव करते समय गड़बड़ी हुई"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"समस्या का डेटा सेव करने की प्रोसेस शुरू करते समय गड़बड़ी हुई"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"फ़ुल स्क्रीन मोड पर देखा जा रहा है"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"बंद करने के लिए, स्क्रीन के सबसे ऊपरी हिस्से से नीचे की ओर स्वाइप करें"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"ठीक है"</string>
<string name="accessibility_back" msgid="6530104400086152611">"वापस जाएं"</string>
<string name="accessibility_home" msgid="5430449841237966217">"होम"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहरे से अनलॉक किया गया. जारी रखने के लिए टैप करें."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरे की पहचान हो गई. जारी रखने के लिए टैप करें."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरे की पहचान हो गई. जारी रखने के लिए अनलॉक आइकॉन को टैप करें."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"चेहरे से अनलॉक किया गया. जारी रखने के लिए टैप करें."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"पुष्टि हो गई"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"पुष्टि करने की प्रोसेस को रद्द करें"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ज़्यादा विकल्प"</string>
@@ -291,6 +303,7 @@
<string name="start_dreams" msgid="9131802557946276718">"स्क्रीन सेवर"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ईथरनेट"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"परेशान न करें"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"अहम मोड"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ब्लूटूथ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"कोई भी युग्मित डिवाइस उपलब्ध नहीं"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"किसी डिवाइस को कनेक्ट या डिसकनेक्ट करने के लिए टैप करें"</string>
@@ -302,8 +315,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेव किया गया"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"डिसकनेक्ट करें"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"चालू करें"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"ब्लूटूथ कल अपने-आप चालू हो जाएगा"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक शेयर और Find My Device जैसी सुविधाएं, ब्लूटूथ का इस्तेमाल करती हैं"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ब्लूटूथ कल सुबह चालू होगा"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ऑडियो शेयर करें"</string>
@@ -472,6 +484,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ज़्यादा विजेट जोड़ें"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेट पसंद के मुताबिक बनाने के लिए उसे दबाकर रखें"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेट अपनी पसंद के मुताबिक बनाएं"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"विजेट को पसंद के मुताबिक बनाने के लिए, डिवाइस अनलॉक करें"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"बंद किए गए विजेट के लिए ऐप्लिकेशन आइकॉन"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"इंस्टॉल हो रहे विजेट के लिए ऐप्लिकेशन आइकॉन"</string>
<string name="edit_widget" msgid="9030848101135393954">"विजेट में बदलाव करें"</string>
@@ -490,12 +503,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट चुनें"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट हटाएं"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"चुने गए विजेट के लिए जगह चुनें"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लॉक स्क्रीन विजेट"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"किसी विजेट से कोई ऐप्लिकेशन खोलने के लिए, आपको अपनी पहचान की पुष्टि करनी होगी. ध्यान रखें कि टैबलेट के लॉक होने पर भी कोई व्यक्ति विजेट देख सकता है. ऐसा हो सकता है कि कुछ विजेट लॉक स्क्रीन पर दिखाने के लिए न बने हों. इन्हें लॉक स्क्रीन पर जोड़ना असुरक्षित हो सकता है."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ठीक है"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"उपयोगकर्ता बदलें"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेन्यू"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सेशन के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string>
@@ -717,7 +731,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"डिफ़ॉल्ट"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"अपने-आप"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"आवाज़ या वाइब्रेशन न हो"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"इससे किसी तरह की आवाज़ या वाइब्रेशन नहीं होता और बातचीत, सेक्शन में सबसे नीचे दिखती है"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"डिवाइस की सेटिंग के आधार पर, सूचना आने पर घंटी बज सकती है या वाइब्रेशन हो सकता है"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"डिवाइस की सेटिंग के आधार पर, सूचना आने पर घंटी बज सकती है या वाइब्रेशन हो सकता है. <xliff:g id="APP_NAME">%1$s</xliff:g> पर होने वाली बातचीत, डिफ़ॉल्ट रूप से बबल के तौर पर दिखती है."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"सिस्टम को यह तय करने की अनुमति दें कि इस सूचना के मिलने पर आवाज़ हो या वाइब्रेशन हो"</string>
@@ -774,6 +789,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1366,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) पर इस्तेमाल किया जा रहा है"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"हाल ही में, <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ने इस्तेमाल किया"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"सिस्टम"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"सिस्टम से जुड़े कंट्रोल"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"सिस्टम के ऐप्लिकेशन"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"मल्टीटास्किंग (एक साथ कई काम करना)"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"स्प्लिट स्क्रीन"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"इनपुट"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ऐप शॉर्टकट"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"मौजूदा ऐप्लिकेशन"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सुलभता"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"सर्च शॉर्टकट"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"छोटा करने का आइकॉन"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"बड़ा करने का आइकॉन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"या"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"पीछे जाने का जेस्चर"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"होम स्क्रीन पर जाने का जेस्चर"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"ऐक्शन बटन"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"हो गया"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"बहुत बढ़िया!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"वापस जाएं"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"वापस जाने के लिए, टचपैड पर कहीं भी तीन उंगलियों से बाईं या दाईं तरफ़ स्वाइप करें."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"टचपैड पर तीन उंगलियों को दाईं और बाईं तरफ़ ले जाया जा रहा है"</string>
@@ -1374,4 +1393,5 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d में से %1$d लेवल"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"स्क्रीनसेवर से तुरंत होम कंट्रोल ऐक्सेस करें"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"पहले जैसा करें"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
index b89eeb3c0f0f..b988d727b85d 100644
--- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"बंद है"</item>
<item msgid="4875147066469902392">"चालू है"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"उपलब्ध नहीं है"</item>
+ <item msgid="2004750556637773692">"बंद है"</item>
+ <item msgid="8968530753931637871">"चालू है"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"उपलब्ध नहीं है"</item>
<item msgid="5044688398303285224">"बंद है"</item>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index b0a47514229a..fce4ac09ad8c 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> otkrila je ovu snimku zaslona."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije otkrile su ovu snimku zaslona."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj bilješci"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Uključi vezu"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Snimač zaslona"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrada snimanja zaslona"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Tekuća obavijest za sesiju snimanja zaslona"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite za prikaz"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Pogreška prilikom spremanja snimke zaslona"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pogreška prilikom pokretanja snimanja zaslona"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Zaustavit ćete snimanje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Zaustavit ćete dijeljenje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Zaustavit ćete emitiranje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Želite li zaustaviti snimanje?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Trenutačno snimate cijeli zaslon"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Trenutačno snimate aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Zaustavi snimanje"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Dijeljenje zaslona"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Želite li zaustaviti dijeljenje zaslona?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Trenutačno dijelite cijeli zaslon s aplikacijom <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Trenutačno dijelite cijeli zaslon s aplikacijom"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Trenutačno dijelite aplikaciju <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Trenutačno dijelite aplikaciju"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Zaustavi dijeljenje"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Emitiranje zaslona"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Želite li prestati emitirati?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Trenutačno emitirate cijeli zaslon na uređaj <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Trenutačno emitirate cijeli zaslon na uređaj u blizini"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Trenutačno emitirate aplikaciju <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> na uređaj <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Trenutačno emitirate aplikaciju <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> na uređaj u blizini"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Trenutačno emitirate na uređaj <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Trenutačno emitirate na uređaj u blizini"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Zaustavi emitiranje"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Zatvori"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Snimač poteškoća"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Obrada snimke poteškoće"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Obavijest o aktivnosti u pozadini za sesiju prikupljanja poteškoća"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Pogreška pri spremanju snimke poteškoće"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Pogreška pri pokretanju snimke poteškoće"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Gledanje preko cijelog zaslona"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Za izlaz povucite prstom od vrha zaslona prema dolje"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Shvaćam"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Natrag"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Početna"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano pomoću lica. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice je prepoznato. Pritisnite ikonu otključavanja da biste nastavili."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Otključano licem. Dodirnite za nastavak."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikacija izvršena"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkaži autentifikaciju"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Više opcija"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Čuvar zaslona"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne uznemiravaj"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Upareni uređaji nisu dostupni"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Dodirnite da biste povezali uređaj ili prekinuli vezu s njim"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Spremljeno"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekini vezu"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviraj"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automatski uključi sutra"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Značajke kao što su brzo dijeljenje i Pronađi moj uređaj koriste Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth će se uključiti sutra ujutro"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Dijeli zvuk"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodavanje još widgeta"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dugo pritisnite za prilagodbu widgeta"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodi widgete"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Otključajte da biste prilagodili widgete"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućeni widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za widget koji se instalira"</string>
<string name="edit_widget" msgid="9030848101135393954">"Uredi widget"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"odaberi widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ukloni widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavi odabrani widget"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgeti zaključanog zaslona"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Svi vide widgete na vašem zaključanom zaslonu, čak i ako je tablet zaključan."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgeti na zaključanom zaslonu"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da biste otvorili aplikaciju pomoću widgeta, trebate potvrditi da ste to vi. Također napominjemo da ih svatko može vidjeti, čak i ako je vaš tablet zaključan. Neki widgeti možda nisu namijenjeni za zaključani zaslon, pa ih možda nije sigurno dodati ovdje."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Shvaćam"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Promjena korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući izbornik"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Izbrisat će se sve aplikacije i podaci u ovoj sesiji."</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Zadano"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatski"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez zvuka ili vibracije"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Bez zvuka ili vibracije i prikazuje se pri dnu odjeljka razgovora"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Može zvoniti ili vibrirati ovisno o postavkama uređaja"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Možda će zvoniti ili vibrirati, ovisno o postavkama uređaja. Razgovori iz aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> prikazuju se u oblačiću prema zadanim postavkama."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Neka sustav odredi treba li obavijest najaviti zvukom ili vibracijom"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Stranica prema gore"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Stranica prema dolje"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Izbriši"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Početak"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Kraj"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Umetni"</string>
@@ -1349,23 +1351,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koristi: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sustav"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kontrole sustava"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplikacije sustava"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Obavljanje više zadataka"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podijeljeni zaslon"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Unos"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Prečaci aplikacija"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tipkovni prečaci"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečaci za pretraživanje"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za sažimanje"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za proširivanje"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Pokret za povratak"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Pokret za otvaranje početnog zaslona"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tipka za radnju"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gotovo"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Sjajno!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Natrag"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Za povratak trima prstima prijeđite ulijevo ili udesno bilo gdje na dodirnoj podlozi."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Dodirna podloga prikazuje tri prsta koji se kreću udesno i ulijevo"</string>
@@ -1374,4 +1379,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Razina %1$d od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Upravljanje uređajima"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Brzo upravljajte uređajima putem čuvara zaslona"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
index df0b78664cba..6833c27c4208 100644
--- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Isključeno"</item>
<item msgid="4875147066469902392">"Uključeno"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nedostupno"</item>
<item msgid="5044688398303285224">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 3db930976e4d..f59622c83c22 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> észlelte ezt a képernyőképet."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> és más nyitott alkalmazások észlelték ezt a képernyőképet."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Hozzáadás jegyzethez"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Linkkel együtt"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Képernyőrögzítő"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Képernyőrögzítés feldolgozása"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Folyamatban lévő értesítés képernyőrögzítési munkamenethez"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Koppintson a megtekintéshez"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Hiba történt a képernyőrögzítés mentése során"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Hiba a képernyőrögzítés indításakor"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Le fogja állítani a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; rögzítését"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Felvétel leállítása"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Képernyő megosztása…"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Leállítja a képernyőmegosztást?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Le fogja állítani a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; megosztását"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Megosztás leállítása"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Képernyőtartalom átküldése…"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Leállítja az átküldést?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Le fogja állítani a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; átküldését"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Átküldés leállítása"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Bezárás"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Problémafelvevő"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Problémafelvétel feldolgozása…"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Folyamatban lévő értesítés egy problémagyűjtési munkamenethez"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Hiba történt a problémafelvétel mentésekor"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Hiba történt a problémafelvétel elindításakor"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Megtekintése teljes képernyőn"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"A kilépéshez csúsztasson gyorsan lefelé a képernyő tetejéről."</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Értem"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Vissza"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Főoldal"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Zárolás arccal feloldva. Koppintson a folytatáshoz."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Arc felismerve. Koppintson a folytatáshoz."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Arc felismerve. A folytatáshoz koppintson a Feloldásra."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Zárolás arccal feloldva. Koppintson a folytatáshoz."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Hitelesítve"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Hitelesítés megszakítása"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"További lehetőségek"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Képernyővédő"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne zavarjanak"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nem áll rendelkezésre párosított eszköz"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Koppintson egy eszköz csatlakoztatásához vagy leválasztásához"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Mentve"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"leválasztás"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiválás"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automatikus bekapcsolás holnap"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Egyes funkciók (például a Quick Share és a Készülékkereső) Bluetootht használnak"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"A Bluetooth holnap reggel bekapcsol"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Hang megosztása"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"További modulok hozzáadása"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nyomja meg hosszan a modulok személyre szabásához"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Modulok személyre szabása"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"A feloldással személyre szabhatja a modulokat"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Letiltott modul alkalmazásikonja"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Folyamatban van egy modul alkalmazásikonjának telepítése"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modul szerkesztése"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"modul kiválasztása"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"modul törlése"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"kijelölt modul áthelyezése"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"A lezárási képernyő moduljai"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ha modul használatával szeretne megnyitni egy alkalmazást, igazolnia kell a személyazonosságát. Ne felejtse továbbá, hogy bárki megtekintheti a modulokat, még akkor is, amikor zárolva van a táblagép. Előfordulhat, hogy bizonyos modulokat nem a lezárási képernyőn való használatra terveztek, ezért nem biztonságos a hozzáadásuk."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Értem"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Felhasználóváltás"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"lehúzható menü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Indítás most"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nincs értesítés"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nincsenek új értesítések"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Alkalmazkodó értesítések bekapcsolva"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Eszköze most legalább két percre csökkenti a hangerőt és a képernyőn előugró ablakok számát, amikor rövid időn belül sok értesítést kap."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Igen"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"A régebbiek feloldás után láthatók"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Az eszközt a szülőd felügyeli"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Az eszköz az Ön szervezetének tulajdonában van, és lehetséges, hogy a hálózati forgalmat is figyelik"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Alapértelmezett"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatikus"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Nincs hang és rezgés"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Nincs hang és rezgés, továbbá lejjebb jelenik meg a beszélgetések szakaszában"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Az eszközbeállítások alapján csöröghet és rezeghet"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Az eszközbeállítások alapján csöröghet és rezeghet. A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazásban lévő beszélgetések alapértelmezés szerint buborékban jelennek meg."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"A rendszer határozza meg, hogy ez az értesítés adjon-e ki hangot, illetve rezegjen-e"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Kezdőképernyő"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Használatban a következő által: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Legutóbb használta: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Rendszer"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Rendszervezérlők"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Rendszeralkalmazások"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Legutóbbi alkalmazások"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Osztott képernyő"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Bevitel"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Alkalmazás-parancsikonok"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kisegítő lehetőségek"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Billentyűparancsok"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Billentyűparancsok keresése"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Összecsukás ikon"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kibontás ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"vagy"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Vissza kézmozdulat"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Kezdőképernyő kézmozdulat"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Műveletbillentyű"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Kész"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Kiváló!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Vissza"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"A visszalépéshez csúsztasson három ujjal gyorsan balra vagy a jobbra az érintőpad tetszőleges területén."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Három, jobbra és balra mozgó ujjat ábrázoló érintőpad"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"A Vissza kézmozdulat animációját megjelenítő eszközképernyő"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"A billentyűzet háttérvilágítása"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Fényerő: %2$d/%1$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Otthon vezérlése"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Gyorsan vezérelheti otthonát képernyőkímélővel"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
index bbd6bc0ebbbb..6b54c5261fb4 100644
--- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Ki"</item>
<item msgid="4875147066469902392">"Be"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nem áll rendelkezésre"</item>
<item msgid="5044688398303285224">"Ki"</item>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 31fd75919422..2be9a3ce23c7 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը հայտնաբերել է այս սքրինշոթը։"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>-ն ու բացված այլ հավելվածներ հայտնաբերել են այս սքրինշոթը։"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ավելացնել նշմանը"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Ներառել հղումը"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Էկրանի տեսագրում"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Էկրանի տեսագրության մշակում"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Էկրանի տեսագրման աշխատաշրջանի ընթացիկ ծանուցում"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Հպեք՝ դիտելու համար"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Չհաջողվեց պահել էկրանի տեսագրությունը"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Չհաջողվեց սկսել տեսագրումը"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Դուք կկանգնեցնեք &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածից բովանդակության տեսագրումը"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Դուք կկանգնեցնեք &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածից բովանդակության փոխանցումը"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Դուք կկանգնեցնեք &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածից բովանդակության հեռարձակումը"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Կանգնեցնե՞լ ձայնագրումը"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Դուք ներկայումս ձայնագրում եք ձեր ամբողջ էկրանը"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Դուք ներկայումս ձայնագրում եք <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Կանգնեցնել տեսագրումը"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Միացված է էկրանի ցուցադրումը"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Դադարեցնե՞լ էկրանի ցուցադրումը"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Դուք ներկայումս կիսվում եք ձեր էկրանով <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> հավելվածի հետ"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Դուք ներկայումս կիսվում եք ձեր էկրանով հավելվածի հետ"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Դուք ներկայումս կիսվում եք <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> հավելվածով"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Դուք ներկայումս կիսվում եք հավելվածով"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Դադարեցնել էկրանի ցուցադրումը"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Էկրանի հեռարձակում"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Կանգնեցնե՞լ հեռարձակումը"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Դուք ներկայումս հեռարձակում եք ձեր ամբողջ էկրանը <xliff:g id="DEVICE_NAME">%1$s</xliff:g> սարքին"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Դուք ներկայումս հեռարձակում եք ձեր ամբողջ էկրանը մոտակա սարքին"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Դուք ներկայումս հեռարձակում եք <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> հավելվածը <xliff:g id="DEVICE_NAME">%2$s</xliff:g> սարքին"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Դուք ներկայումս հեռարձակում եք <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> հավելվածը մոտակա սարքին"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Դուք ներկայումս հեռարձակում եք <xliff:g id="DEVICE_NAME">%1$s</xliff:g> սարքին"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Դուք ներկայումս հեռարձակում եք մոտակա սարքին"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Դադարեցնել հեռարձակումը"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Փակել"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Խնդիրների տեսագրիչ"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Մշակում ենք տեսագրությունը"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Խնդրի տեսագրման մասին ընթացիկ ծանուցում"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Չհաջողվեց պահել տեսագրությունը"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Չհաջողվեց սկսել տեսագրումը"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Լիաէկրան դիտակերպ"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Դուրս գալու համար էկրանի վերևից մատը սահեցրեք ներքև"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Եղավ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Հետ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Տուն"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ապակողպվել է դեմքով։ Սեղմեք շարունակելու համար։"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Դեմքը ճանաչվեց։ Սեղմեք շարունակելու համար։"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Դեմքը ճանաչվեց։ Սեղմեք ապակողպման պատկերակը։"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Ապակողպվել է դեմքով։ Հպեք շարունակելու համար:"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Նույնականացված է"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Չեղարկել իսկորոշումը"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Լրացուցիչ ընտրանքներ"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Էկրանապահ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Չանհանգստացնել"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Պահված է"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"անջատել"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ակտիվացնել"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Ավտոմատ միացնել վաղը"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth-ն օգտագործում են, օրինակ, Quick Share և «Գտնել իմ սարքը» գործառույթները"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth-ը կմիանա վաղն առավոտյան"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Փոխանցել աուդիո"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ավելացնել վիջեթներ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Երկար սեղմեք՝ վիջեթները հարմարեցնելու համար"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Հարմարեցնել վիջեթները"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Ապակողպեք՝ վիջեթներն անհատականացնելու համար"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Հավելվածի պատկերակ անջատված վիջեթի համար"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Տեղադրվող վիջեթի հավելվածի պատկերակ"</string>
<string name="edit_widget" msgid="9030848101135393954">"Փոփոխել վիջեթը"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ընտրել վիջեթ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"հեռացնել վիջեթը"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"տեղադրել ընտրված վիջեթը"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Կողպէկրանի վիջեթներ"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Բոլորը կարող են դիտել ձեր կողպէկրանի վիջեթները, նույնիսկ եթե պլանշետը կողպված է"</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Կողպէկրանի վիջեթներ"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Վիջեթի միջոցով հավելված բացելու համար դուք պետք է հաստատեք ձեր ինքնությունը։ Նաև նկատի ունեցեք, որ ցանկացած ոք կարող է դիտել վիջեթները, նույնիսկ երբ ձեր պլանշետը կողպված է։ Որոշ վիջեթներ կարող են նախատեսված չլինել ձեր կողպէկրանի համար, և այստեղ դրանց ավելացնելը կարող է վտանգավոր լինել։"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Եղավ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Անջատել օգտվողին"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"իջնող ընտրացանկ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն:"</string>
@@ -549,12 +549,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Սկսել հիմա"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ծանուցումներ չկան"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Նոր ծանուցումներ չկան"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Հարմարվող ծանուցումները միացված են"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Եթե կարճ ժամանակամիջոցում շատ ծանուցումներ ստանաք, ձայնը և ելնող պատուհանների թիվը կնվազեցվի մինչև երկու րոպեով։"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Անջատել"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ապակողպեք՝ տեսնելու հին ծանուցումները"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Այս սարքը կառավարում է ձեր ծնողը"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ձեր կազմակերպությունը այս սարքի սեփականատերն է և կարող է վերահսկել ցանցային թրաֆիկը"</string>
@@ -720,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Կանխադրված"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Ավտոմատ"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Առանց ձայնի կամ թրթռոցի"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Առանց ձայնի և թրթռոցի, հայտնվում է զրույցների ցանկի ներքևում"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Կարող է զնգալ կամ թրթռալ՝ կախված սարքի կարգավորումներից"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Կարող է զնգալ կամ թրթռալ՝ կախված սարքի կարգավորումներից։ <xliff:g id="APP_NAME">%1$s</xliff:g>-ի զրույցներն ըստ կանխադրման հայտնվում են ամպիկների տեսքով։"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Թող համակարգն ավտոմատ որոշի՝ արդյոք այս ծանուցումը ձայնով, թե թրթռոցով է պետք մատուցել"</string>
@@ -777,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Ջնջել"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Գլխավոր էջ"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Վերջ"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Տեղադրել"</string>
@@ -1352,33 +1351,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Օգտագործվում է <xliff:g id="APP_NAME">%1$s</xliff:g>ի կողմից (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Վերջերս օգտագործվել է <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի կողմից (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Համակարգ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Համակարգի կառավարման տարրեր"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Համակարգային հավելվածներ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Բազմախնդրություն"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Վերջին օգտագործած հավելվածները"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Տրոհված էկրան"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ներածում"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Հավելվածի դյուրանցումներ"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Հատուկ գործառույթներ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Ստեղնային դյուրանցումներ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Դյուրանցումների որոնում"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ծալել պատկերակը"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ծավալել պատկերակը"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"կամ"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"«Հետ» ժեստ"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Հիմնական էկրան անցնելու ժեստ"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Գործողության ստեղն"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Պատրաստ է"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Կեցցե՛ք"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Հետ գնալ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Հետ գնալու համար հպահարթակի վրա երեք մատով սահեցրեք ձախ կամ աջ։"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Երեք մատները աջ ու ձախ են շարժվում հպահարթակի վրա"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Սարքի էկրանին ցուցադրվում է շարժանկար՝ հետ գնալու ժեստի համար"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Հետին լուսավորությամբ ստեղնաշար"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d՝ %2$d-ից"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Տան կառավարման տարրեր"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Տան կառավարման տարրերը դարձրեք էկրանապահ"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
index eb77ccf8c1fc..248840eddf5e 100644
--- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Անջատված է"</item>
<item msgid="4875147066469902392">"Միացված է"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Հասանելի չէ"</item>
<item msgid="5044688398303285224">"Անջատված է"</item>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 812daca5cd84..8f5ecfaff37f 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> mendeteksi screenshot ini."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dan aplikasi terbuka lainnya mendeteksi screenshot ini."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Tambahkan ke catatan"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Sertakan link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Perekam Layar"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses perekaman layar"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifikasi yang sedang berjalan untuk sesi rekaman layar"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Ketuk untuk melihat"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Terjadi error saat menyimpan rekaman layar"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Terjadi error saat memulai perekaman layar"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Anda akan berhenti merekam &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Berhenti merekam"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Membagikan layar"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Hentikan berbagi layar?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Anda akan berhenti membagikan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Berhenti berbagi"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Mentransmisikan layar"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Hentikan transmisi?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Anda akan berhenti mentransmisikan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Hentikan transmisi"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Tutup"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Perekam Masalah"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Memproses rekaman masalah"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Notifikasi berkelanjutan untuk sesi pengumpulan masalah"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Terjadi error saat menyimpan rekaman masalah"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Terjadi error saat memulai perekaman masalah"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Melihat layar penuh"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Untuk keluar, geser ke bawah dari bagian atas layar"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Oke"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Kembali"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Utama"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Kunci dibuka dengan wajah. Tekan untuk melanjutkan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dikenali. Tekan untuk melanjutkan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dikenali. Tekan ikon buka kunci untuk melanjutkan."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Kunci dibuka dengan wajah. Ketuk untuk melanjutkan."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Diautentikasi"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Batalkan Autentikasi"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Opsi Lainnya"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Screensaver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Jangan Ganggu"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Perangkat yang disandingkan tak tersedia"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Ketuk untuk memulai atau menghentikan koneksi perangkat"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Disimpan"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"putuskan koneksi"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktifkan"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Aktifkan otomatis besok"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Fitur seperti Quick Share dan Temukan Perangkat Saya menggunakan Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth akan dinyalakan besok pagi"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Bagikan audio"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tambahkan widget lainnya"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tekan lama untuk menyesuaikan widget"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sesuaikan widget"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Buka kunci untuk menyesuaikan widget"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikon aplikasi untuk widget yang dinonaktifkan"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikon aplikasi untuk widget yang sedang diinstal"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pilih widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"hapus widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"letakkan widget yang dipilih"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget layar kunci"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Untuk membuka aplikasi menggunakan widget, Anda perlu memverifikasi diri Anda. Selain itu, harap ingat bahwa siapa saja dapat melihatnya, bahkan saat tablet Anda terkunci. Beberapa widget mungkin tidak dirancang untuk layar kunci Anda dan mungkin tidak aman untuk ditambahkan di sini."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Oke"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Beralih pengguna"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pulldown"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data dalam sesi ini akan dihapus."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Otomatis"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Tidak ada suara atau getaran"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Tidak ada suara atau getaran dan ditampilkan lebih rendah di bagian percakapan"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Dapat berdering atau bergetar berdasarkan setelan perangkat"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Dapat berdering atau bergetar berdasarkan setelan perangkat. Percakapan <xliff:g id="APP_NAME">%1$s</xliff:g> ditampilkan sebagai balon secara default."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Biarkan sistem menentukan apakah notifikasi ini akan berbunyi atau bergetar"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Sedang digunakan oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Baru saja digunakan oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kontrol sistem"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplikasi sistem"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplikasi terbaru"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Layar terpisah"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Pintasan aplikasi"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aksesibilitas"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan keyboard"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pintasan penelusuran"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon ciutkan"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikon luaskan"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gestur kembali"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gestur layar utama"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tombol tindakan"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Selesai"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Bagus!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Untuk kembali, geser ke kiri atau ke kanan menggunakan tiga jari ke mana saja di touchpad."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad menampilkan tiga jari yang bergerak ke kanan dan ke kiri"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Tingkat %1$d dari %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrol Rumah"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Akses cepat kontrol rumah Anda sebagai screensaver"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml
index a415f644fb48..de505ca7eb60 100644
--- a/packages/SystemUI/res/values-in/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Nonaktif"</item>
<item msgid="4875147066469902392">"Aktif"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Tidak tersedia"</item>
<item msgid="5044688398303285224">"Mati"</item>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 443969df504a..c47475be33c0 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> greindi skjámyndina."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og önnur opin forrit greindu skjámyndina."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Bæta við glósu"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Hafa tengil með"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Skjáupptaka"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Vinnur úr skjáupptöku"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Áframhaldandi tilkynning fyrir skjáupptökulotu"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Ýttu til að skoða"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Villa við að vista skjáupptöku"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Villa við að hefja upptöku skjás"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Þú munt hætta upptöku úr &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stöðva upptöku"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deilir skjá"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Hætta að deila skjá?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Þú munt hætta að deila úr &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Hætta að deila"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Varpar skjá"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Hætta að varpa?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Þú munt hætta vörpun úr &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Hætta að varpa"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Loka"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Upptökutæki fyrir vandamál"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Vinnur úr upptöku af vandamáli"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Áframhaldandi tilkynning fyrir lotu vandamálasafns"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Villa kom upp við að vista upptöku af vandamáli"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Villa kom upp við að hefja upptöku af vandamáli"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Notar allan skjáinn"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Strjúktu niður frá efsta hluta skjásins til að hætta"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Ég skil"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Til baka"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Heim"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Opnað með andliti. Ýttu til að halda áfram."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Andlitið var greint. Ýttu til að halda áfram."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Andlitið var greint. Ýttu á opnunartáknið til að halda áfr."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Opnað með andliti. Ýttu til að halda áfram."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Auðkennt"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Hætta við auðkenningu"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Fleiri valkostir"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Skjávari"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ónáðið ekki"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Engin pöruð tæki til staðar"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Ýttu til að tengja eða aftengja tæki"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Vistað"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"aftengja"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"virkja"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Kveikja sjálfkrafa á morgun"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Eiginleikar eins og Flýtideiling og Finna tækið mitt nota Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Kveikt verður á Bluetooth í fyrramálið"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Deila hljóði"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Bæta við fleiri græjum"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Haltu inni til að sérsníða græjur"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sérsníða græjur"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Opnaðu til að sérsníða græjur"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Forritstákn fyrir græju sem slökkt er á"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Forritatákn fyrir græju sem verið er að setja upp"</string>
<string name="edit_widget" msgid="9030848101135393954">"Breyta græju"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"velja græju"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjarlægja græju"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"koma valinni græju fyrir"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Græjur fyrir lásskjá"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Þú þarft að staðfesta að þetta sért þú til að geta opnað forrit með græju. Hafðu einnig í huga að hver sem er getur skoðað þær, jafnvel þótt spjaldtölvan sé læst. Sumar græjur eru hugsanlega ekki ætlaðar fyrir lásskjá og því gæti verið óöruggt að bæta þeim við hér."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ég skil"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skipta um notanda"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Fellivalmynd"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Byrja núna"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Engar tilkynningar"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Engar nýjar tilkynningar"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Kveikt á breytil. tilkynningum"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Tækið þitt lækkar nú hljóðstyrkinn og fækkar sprettigluggum á skjánum í allt að tvær mínútur þegar þú færð margar tilkynningar á stuttum tíma."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Slökkva"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Taktu úr lás til að sjá eldri tilkynningar"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Foreldri þitt stjórnar þessu tæki"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Fyrirtækið þitt á þetta tæki og fylgist hugsanlega með netumferð"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Sjálfgefið"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Sjálfvirk"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Ekkert hljóð eða titringur"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ekkert hljóð eða titringur og birtist neðar í samtalshluta"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Gæti hringt eða titrað en það fer eftir stillingum tækisins"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Gæti hringt eða titrað en það fer eftir stillingum tækisins. Samtöl frá <xliff:g id="APP_NAME">%1$s</xliff:g> birtast sjálfkrafa í blöðru."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Láta kerfið ákvarða hvort hljóð eða titringur fylgir þessari tilkynningu"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Í notkun í <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nýlega notað af <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Kerfi"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kerfisstýringar"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Kerfisforrit"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Fjölvinnsla"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nýleg forrit"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Skjáskipting"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Inntak"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Flýtileiðir forrita"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aðgengi"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Flýtilyklar"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Leitarflýtileiðir"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Minnka tákn"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Stækka tákn"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eða"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Bending til að fara til baka"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Bending til að fara á upphafsskjá"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Aðgerðalykill"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Lokið"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Vel gert!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Til baka"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Strjúktu til vinstri eða hægri með þrem fingrum hvar sem er á snertifletinum til að fara til baka."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Snertiflötur sem sýnir þrjá fingur færast til hægri og vinstri"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Skjár tækis sem sýnir hreyfimynd fyrir bendinguna „til baka“."</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Baklýsing lyklaborðs"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Stig %1$d af %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Heimastýringar"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Fáðu skjótan aðgang að heimastýringum sem skjávara"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml
index c9befd6574c4..ee3b3116433c 100644
--- a/packages/SystemUI/res/values-is/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Slökkt"</item>
<item msgid="4875147066469902392">"Kveikt"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Ekki í boði"</item>
<item msgid="5044688398303285224">"Slökkt"</item>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 092cccc22534..1cfc8d4dd7d6 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha rilevato questo screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e altre app aperte hanno rilevato questo screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Aggiungi alla nota"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Includi link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Registrazione dello schermo"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Elaborazione registrazione…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tocca per visualizzare"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Errore durante il salvataggio della registrazione dello schermo"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Errore durante l\'avvio della registrazione dello schermo"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Interromperai la registrazione di &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Interrompi registrazione"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Condivisione dello schermo in corso"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vuoi interrompere la condivisione dello schermo?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Interromperai la condivisione di &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Interrompi condivisione"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Trasmissione dello schermo in corso…"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vuoi interrompere la trasmissione?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Interromperai la trasmissione di &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Interrompi trasmissione"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Chiudi"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Registratore dei problemi"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Elaborazione registrazione…"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Notifica continua per una sessione di raccolta di problemi"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Impossibile salvare la registrazione del problema"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Impossibile avviare la registrazione del problema"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Visualizzazione a schermo intero"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Per uscire, scorri verso il basso dalla parte superiore dello schermo"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Indietro"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Sbloccato con il volto. Premi per continuare."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Volto riconosciuto. Premi per continuare."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Volto riconosciuto. Premi l\'icona Sblocca e continua."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Sbloccato con il volto. Tocca per continuare."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticazione eseguita"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annulla autenticazione"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Altre opzioni"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Salvaschermo"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Non disturbare"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nessun dispositivo accoppiato disponibile"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Tocca per connettere o disconnettere un dispositivo"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Dispositivo salvato"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnetti"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"attiva"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Attiva automaticamente domani"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funzionalità come Quick Share e Trova il mio dispositivo usano il Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Il Bluetooth verrà attivato domani mattina"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Condividi audio"</string>
@@ -316,7 +329,7 @@
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Attivazione…"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotazione automatica"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotazione automatica dello schermo"</string>
- <string name="quick_settings_location_label" msgid="2621868789013389163">"Geolocalizzazione"</string>
+ <string name="quick_settings_location_label" msgid="2621868789013389163">"Posizione"</string>
<string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Salvaschermo"</string>
<string name="quick_settings_camera_label" msgid="5612076679385269339">"Accesso alla fotocamera"</string>
<string name="quick_settings_mic_label" msgid="8392773746295266375">"Accesso al microfono"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Aggiungi altri widget"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Premi a lungo per personalizzare i widget"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizza widget"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Sblocca per personalizzare i widget"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona dell\'app per widget disattivati"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icona dell\'app per un widget in fase di installazione"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modifica widget"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"seleziona widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"rimuovi widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posiziona il widget selezionato"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget della schermata di blocco"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per aprire un\'app utilizzando un widget, dovrai verificare la tua identità. Inoltre tieni presente che chiunque può vederlo, anche quando il tablet è bloccato. Alcuni widget potrebbero non essere stati progettati per la schermata di blocco e potrebbe non essere sicuro aggiungerli qui."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ok"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambio utente"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu a discesa"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Avvia adesso"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nessuna notifica"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nessuna nuova notifica"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notifiche adattive attivate"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Il dispositivo abbassa il volume e riduce i popup fino a 2 minuti quando ricevi molte notifiche."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Disattiva"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Sblocca per vedere le notifiche meno recenti"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Questo dispositivo è gestito dai tuoi genitori"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Questo dispositivo appartiene alla tua organizzazione, che potrebbe monitorare il traffico di rete"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Modalità predefinita"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatico"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Nessun suono o vibrazione"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Nessun suono o vibrazione e appare più in basso nella sezione delle conversazioni"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Potrebbero essere attivati lo squillo o la vibrazione in base alle impostazioni del dispositivo"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Potrebbero essere attivati lo squillo o la vibrazione in base alle impostazioni del dispositivo. Conversazioni dalla bolla <xliff:g id="APP_NAME">%1$s</xliff:g> per impostaz. predefinita."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Fai stabilire al sistema se questa notifica deve emettere suoni o vibrazioni"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Pagina su"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Pagina giù"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Elimina"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home page"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Fine"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"INS"</string>
@@ -1352,33 +1367,33 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In uso da <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recentemente in uso da <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controlli di sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"App di sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"App recenti"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Schermo diviso"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Scorciatoie app"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App corrente"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilità"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Scorciatoie da tastiera"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Scorciatoie per la ricerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona Comprimi"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icona Espandi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"oppure"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gesto Indietro"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gesto Home"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tasto azione"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Fine"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Ottimo lavoro"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Indietro"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Per tornare indietro, scorri verso sinistra o verso destra utilizzando tre dita in un punto qualsiasi del touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad che mostra tre dita che si muovono verso destra e sinistra"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Schermata del dispositivo che mostra l\'animazione del gesto per tornare indietro"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroilluminazione della tastiera"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Livello %1$d di %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controlli della casa"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Accedi rapidamente ai controlli della casa dal salvaschermo"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index aa76983ee211..e7c626f648af 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Off"</item>
<item msgid="4875147066469902392">"On"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Non disponibile"</item>
<item msgid="5044688398303285224">"Off"</item>
@@ -188,7 +191,7 @@
</string-array>
<string-array name="tile_states_hearing_devices">
<item msgid="1235334096484287173">"Non disponibile"</item>
- <item msgid="3079622119444911877">"Off"</item>
- <item msgid="3028994095749238254">"On"</item>
+ <item msgid="3079622119444911877">"Disattivi"</item>
+ <item msgid="3028994095749238254">"Attivi"</item>
</string-array>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 36eb97e6654c..2ff5f83a4f94 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"האפליקציה <xliff:g id="APPNAME">%1$s</xliff:g> זיהתה את צילום המסך הזה."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"האפליקציה <xliff:g id="APPNAME">%1$s</xliff:g> ואפליקציות פתוחות נוספות זיהו את צילום המסך הזה."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"הוספה לפתק"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"הכנסת הקישור"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"מקליט המסך"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"מתבצע עיבוד של הקלטת מסך"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"יש להקיש כדי להציג"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"שגיאה בשמירה של הקלטת המסך"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"שגיאה בהפעלה של הקלטת המסך"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"‏ההקלטה של &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; תיפסק"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"הפסקת ההקלטה"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"שיתוף המסך מתבצע"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"להפסיק את שיתוף המסך?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"‏השיתוף של &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; יופסק"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"הפסקת השיתוף"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"‏הפעלת Cast של המסך מתבצעת"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"‏להפסיק את הפעלת ה-Cast?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"‏הפעלת ה-Cast‏ של &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; תיפסק"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"‏הפסקת ה-Cast"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"סגירה"</string>
<string name="issuerecord_title" msgid="286627115110121849">"בעיה במכשיר ההקלטה"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"מתבצע עיבוד של בעיית ההקלטה"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"התראה מתמשכת לסשן איסוף הבעיה"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"שגיאה בשמירה של בעיית ההקלטה"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"שגיאה בהפעלה של בעיית ההקלטה"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"צפייה במסך מלא"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"כדי לצאת, מחליקים למטה מהחלק העליון של המסך"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"הבנתי"</string>
<string name="accessibility_back" msgid="6530104400086152611">"חזרה"</string>
<string name="accessibility_home" msgid="5430449841237966217">"בית"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"הנעילה בוטלה באמצעות זיהוי הפנים. יש ללחוץ כדי להמשיך."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"הפנים זוהו. יש ללחוץ כדי להמשיך."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"הפנים זוהו. להמשך יש ללחוץ על סמל ביטול הנעילה."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"הנעילה בוטלה באמצעות זיהוי הפנים. צריך להקיש כדי להמשיך."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"מאומת"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ביטול האימות"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"אפשרויות נוספות"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"שומר מסך"</string>
<string name="ethernet_label" msgid="2203544727007463351">"אתרנט"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"נא לא להפריע"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"נשמר"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ניתוק"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"הפעלה"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"הפעלה אוטומטית מחר"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"‏תכונות כמו \'שיתוף מהיר\' ו\'איפה המכשיר שלי\' משתמשות ב-Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"‏חיבור ה-Bluetooth יופעל מחר בבוקר"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"שיתוף האודיו"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"הוספת ווידג\'טים"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"לוחצים לחיצה ארוכה כדי להתאים אישית את הווידג\'טים"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"התאמה אישית של ווידג\'טים"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"כדי להתאים אישית את הווידג\'טים, צריך לבטל את הנעילה"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"סמל האפליקציה לווידג\'ט שהושבת"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"סמל האפליקציה של ווידג\'ט בתהליך התקנה"</string>
<string name="edit_widget" msgid="9030848101135393954">"עריכת הווידג\'ט"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"צריך לבחור ווידג\'ט"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"הסרת הווידג\'ט"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"צריך למקם את הווידג\'ט שנבחר"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ווידג\'טים במסך הנעילה"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"כדי לפתוח אפליקציה באמצעות ווידג\'ט, עליך לאמת את זהותך. בנוסף, כדאי לזכור שכל אחד יכול לראות את הווידג\'טים גם כשהטאבלט שלך נעול. יכול להיות שחלק מהווידג\'טים לא נועדו למסך הנעילה ושלא בטוח להוסיף אותם לכאן."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"הבנתי"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"החלפת משתמש"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"תפריט במשיכה למטה"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בסשן הזה יימחקו."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"כן, אפשר להתחיל"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"אין התראות"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"אין התראות חדשות"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ההתראות המותאמות מופעלות"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"מעכשיו, כשיש התראות רבות בזמן קצר, עוצמת הקול מופחתת ומופיעים פחות חלונות קופצים במשך עד שתי דקות."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"השבתה"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"יש לבטל את הנעילה כדי לראות התראות ישנות"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"המכשיר הזה מנוהל על ידי ההורה שלך"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"הארגון שלך הוא הבעלים של המכשיר הזה והוא עשוי לנטר את התנועה ברשת"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ברירת מחדל"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"באופן אוטומטי"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"ללא צליל או רטט"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ללא צליל או רטט ומופיעה למטה בקטע התראות השיחה"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"ייתכן שיופעל צלצול או רטט בהתאם להגדרות במכשיר"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ייתכן שיופעל צלצול או רטט בהתאם להגדרות במכשיר. שיחות מהאפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מופיעות בבועות כברירת מחדל."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"אפשר לתת למערכת לקבוע אם ההתראה הזאת צריכה להיות מלווה בצליל או ברטט"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"דפדוף למעלה"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"דפדוף למטה"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"מחיקה"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"דף הבית"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"סיום"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"הוספה"</string>
@@ -964,8 +979,8 @@
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה או על ידי כלל אוטומטי."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"אפליקציות שפועלות ברקע"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"אפשר להקיש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
- <string name="mobile_data_disable_title" msgid="5366476131671617790">"לכבות את חבילת הגלישה?"</string>
- <string name="mobile_data_disable_message" msgid="8604966027899770415">"‏לא תהיה לך גישה לנתונים או לאינטרנט באמצעות <xliff:g id="CARRIER">%s</xliff:g>. אינטרנט יהיה זמין רק באמצעות Wi-Fi."</string>
+ <string name="mobile_data_disable_title" msgid="5366476131671617790">"לכבות את השימוש בחבילת הגלישה?"</string>
+ <string name="mobile_data_disable_message" msgid="8604966027899770415">"‏לא תהיה לך גישה לנתונים או לאינטרנט דרך <xliff:g id="CARRIER">%s</xliff:g>. אפשר יהיה לגשת לאינטרנט רק דרך Wi-Fi."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"הספק שלך"</string>
<string name="auto_data_switch_disable_title" msgid="5146527155665190652">"לחזור אל <xliff:g id="CARRIER">%s</xliff:g>?"</string>
<string name="auto_data_switch_disable_message" msgid="5885533647399535852">"לא תתבצע החלפה אוטומטית של חבילת הגלישה על סמך זמינות"</string>
@@ -1352,33 +1367,33 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"בשימוש על ידי <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"נעשה שימוש לאחרונה על ידי <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"מערכת"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"הגדרות המערכת"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"אפליקציות מערכת"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ריבוי משימות"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"אפליקציות אחרונות"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"מסך מפוצל"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"קלט"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"קיצורי דרך של אפליקציות"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"האפליקציה הנוכחית"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"נגישות"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"מקשי קיצור"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"קיצורי דרך לחיפוש"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"סמל הכיווץ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"סמל ההרחבה"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"או"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"תנועת חזרה"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"תנועת חזרה למסך הבית"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"מקש הפעולה"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"סיום"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"מעולה!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"חזרה"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"כדי לחזור אחורה, מחליקים שמאלה או ימינה עם שלוש אצבעות בכל מקום על לוח המגע."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"לוח מגע שמראה שלוש אצבעות זזות ימינה ושמאלה"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"מסך מכשיר שמראה אנימציה לתנועה אחורה"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"התאורה האחורית במקלדת"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"‏רמה %1$d מתוך %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"שליטה במכשירים"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"גישה מהירה לממשק השליטה במכשירים כשומר מסך"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
index b5cb476484b2..a81cda4739bc 100644
--- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"כבוי"</item>
<item msgid="4875147066469902392">"פועל"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"לא זמין"</item>
<item msgid="5044688398303285224">"כבוי"</item>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 4f839abb23bf..4290be9f3667 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> がこのスクリーンショットを検出しました。"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> とその他の開いているアプリがこのスクリーンショットを検出しました。"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"メモに追加"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"リンクを含める"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"スクリーン レコーダー"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"画面の録画を処理しています"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"画面の録画セッション中の通知"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"タップすると表示されます"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"画面の録画の保存中にエラーが発生しました"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"画面の録画中にエラーが発生しました"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; の記録を停止します"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; の共有を停止します"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; のキャストを停止します"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"録画を停止しますか?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"現在、画面全体を録画しています"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"現在、<xliff:g id="APP_NAME">%1$s</xliff:g>を録画しています"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"録画を停止"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"画面を共有しています"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"画面の共有を停止しますか?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"現在、画面全体を<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>と共有しています"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"現在、画面全体をアプリと共有しています"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"現在、<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>を共有しています"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"現在、アプリを共有しています"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"共有を停止"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"画面をキャストしています"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"キャストを停止しますか?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"現在、<xliff:g id="DEVICE_NAME">%1$s</xliff:g>に画面全体をキャストしています"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"現在、付近のデバイスに画面全体をキャストしています"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"現在、<xliff:g id="DEVICE_NAME">%2$s</xliff:g>に<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>をキャストしています"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"現在、付近のデバイスに<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>をキャストしています"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"現在、<xliff:g id="DEVICE_NAME">%1$s</xliff:g>にキャストしています"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"現在、付近のデバイスにキャストしています"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"キャストを停止"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"閉じる"</string>
<string name="issuerecord_title" msgid="286627115110121849">"問題記録ツール"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"問題の記録を処理しています"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"問題の収集セッションに関する進行中の通知"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"問題の記録の保存中にエラーが発生しました"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"問題の記録の開始中にエラーが発生しました"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"全画面表示"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"終了するには画面の上部から下にスワイプします"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"戻る"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ホーム"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"顔でロック解除しました。押して続行してください。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"顔を認識しました。押して続行してください。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"顔を認識しました。ロック解除アイコンを押して続行します。"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"顔認証でロック解除しました。タップして続行します。"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"認証済み"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"認証をキャンセルします"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"その他のオプション"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"スクリーン セーバー"</string>
<string name="ethernet_label" msgid="2203544727007463351">"イーサネット"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"サイレント モード"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"保存済み"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"接続を解除"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"有効化"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"明日自動的に ON にする"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share や「デバイスを探す」などの機能は Bluetooth を使用します"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"明日の朝に Bluetooth が ON になります"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"音声を共有"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ウィジェットの追加"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長押ししてウィジェットをカスタマイズ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ウィジェットのカスタマイズ"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ウィジェットをカスタマイズするにはロックを解除してください"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"無効なウィジェットのアプリアイコン"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"インストール中のウィジェットのアプリアイコン"</string>
<string name="edit_widget" msgid="9030848101135393954">"ウィジェットを編集"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ウィジェットを選択"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ウィジェットを削除"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"選択したウィジェットを配置"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"ロック画面ウィジェット"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"タブレットがロックされていても、ロック画面のウィジェットは誰でも確認できます。"</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ロック画面ウィジェット"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ウィジェットを使用してアプリを起動するには、本人確認が必要です。タブレットがロックされた状態でも他のユーザーにウィジェットが表示されますので、注意してください。一部のウィジェットについてはロック画面での使用を想定していないため、ロック画面への追加は危険な場合があります。"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ユーザーを切り替える"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"プルダウン メニュー"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"デフォルト"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"着信音もバイブレーションも OFF になります"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"着信音もバイブレーションも無効になり会話セクションの下に表示されます"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"デバイスの設定を基に着信音またはバイブレーションが有効になります"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"デバイスの設定を基に着信音またはバイブレーションが有効になります。デフォルトでは <xliff:g id="APP_NAME">%1$s</xliff:g> からの会話がふきだしで表示されます。"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"この通知を音またはバイブレーションで知らせるかどうかの自動判断"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"PageUp"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"PageDown"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1351,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> が使用中(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> が最近使用(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"システム"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"システム コントロール"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"システムアプリ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"マルチタスク"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近使ったアプリ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分割画面"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"入力"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"アプリのショートカット"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ユーザー補助"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"キーボード ショートカット"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"検索ショートカット"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"閉じるアイコン"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"開くアイコン"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"または"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"「戻る」ジェスチャー"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"「ホーム」ジェスチャー"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"アクションキー"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"完了"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"よくできました。"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"戻る"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"戻るには、3 本の指でタッチパッドを左右にスワイプします。"</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"タッチパッドで 3 本の指を左右に動かしている様子"</string>
@@ -1374,4 +1379,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"レベル %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ホーム コントロール"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"ホーム コントロールにスクリーンセーバーからすばやくアクセス"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
index 790445c93c14..610385efabf7 100644
--- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"OFF"</item>
<item msgid="4875147066469902392">"ON"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"使用不可"</item>
<item msgid="5044688398303285224">"OFF"</item>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 6eb6e42808b5..b1b01b02c714 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>-მა აღმოაჩინა ეკრანის ეს ანაბეჭდი"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>-მა და სხვა გახსნილმა აპებმა აღმოაჩინეს ეკრანის ეს ანაბეჭდი."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"დაამატეთ შენიშვნა"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"ბმულის დართვა"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ეკრანის ჩამწერი"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ეკრანის ჩანაწერი მუშავდება"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"უწყვეტი შეტყობინება ეკრანის ჩაწერის სესიისთვის"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"შეეხეთ სანახავად"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"ეკრანის ჩანაწერის შენახვისას შეცდომა მოხდა"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ეკრანის ჩაწერის დაწყებისას წარმოიქმნა შეცდომა"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"თქვენ შეწყვეტთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ის&lt;/b&gt; ჩაწერას"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"თქვენ შეწყვეტთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ის&lt;/b&gt; გაზიარებას"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"თქვენ შეწყვეტთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ის&lt;/b&gt; ტრანსლირებას"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"გსურთ ჩაწერის შეწყვეტა?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"თქვენ ამჟამად იწერთ თქვენს მთლიან ეკრანს"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"თქვენ ამჟამად იწერთ <xliff:g id="APP_NAME">%1$s</xliff:g>-ს"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ჩაწერის შეწყვეტა"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"მიმდინარეობს ეკრანის გაზიარება"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"გსურთ ეკრანის გაზიარების შეწყვეტა?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"თქვენ ამჟამად უზიარებთ თქვენს მთლიან ეკრანს<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>-ს"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"თქვენ ამჟამად უზიარებთ თქვენს მთლიან ეკრანს აპს"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"თქვენ ამჟამად აზიარებთ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>-ს"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"თქვენ ამჟამად აზიარებთ აპს"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"გაზიარების შეწყვეტა"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"მიმდინარეობს ეკრანის ტრანსლირება"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"გსურთ ტრანსლირების შეწყვეტა?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"თქვენ ამჟამად ახდენთ თქვენი მთლიანი ეკრანის ტრანსლირებას <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ზე"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"თქვენ ამჟამად ახდენთ თქვენი მთლიანი ეკრანის ტრანსლირებას ახლომახლო მოწყობილობაზე"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"თქვენ ამჟამად ახდენთ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>-ის ტრანსლირებას <xliff:g id="DEVICE_NAME">%2$s</xliff:g>-ზე"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"თქვენ ამჟამად ახდენთ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>-ის ტრანსლირებას ახლომახლო მოწყობილობაზე."</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"თქვენ ამჟამად ახდენთ ტრანსლირებას <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ზე"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"თქვენ ამჟამად ახდენთ ტრანსლირებას ახლომახლო მოწყობილობაზე"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"ტრანსლირების შეწყვეტა"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"დახურვა"</string>
<string name="issuerecord_title" msgid="286627115110121849">"ჩანაწერის რეკორდერი"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"პრობლემის ჩანაწერის დამუშავება"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"მიმდინარე შეტყობინება პრობლემების შეგროვების სესიისთვის"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"პრობლემის ჩანაწერის შენახვისას წარმოიქმნა შეცდომა"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"პრობლემის ჩაწერის დაწყებისას წარმოიქმნა შეცდომა"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"მიმდინარეობს სრულ ეკრანზე ნახვა"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"თქვენი ეკრანის ზემოდან გადაფურცლეთ ქვემოთ, რათა გამოხვიდეთ"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"გასაგებია"</string>
<string name="accessibility_back" msgid="6530104400086152611">"უკან"</string>
<string name="accessibility_home" msgid="5430449841237966217">"საწყისი"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"განიბლოკა სახით. დააჭირეთ გასაგრძელებლად."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ამოცნობილია სახით. დააჭირეთ გასაგრძელებლად."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ამოცნობილია სახით. გასაგრძელებლად დააჭირეთ განბლოკვის ხატულას."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"განიბლოკა სახით. შეეხეთ გასაგრძელებლად."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ავტორიზებულია"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ავტორიზაციის გაუქმება"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"სხვა ვარიანტები"</string>
@@ -291,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"ეკრანმზოგი"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ეთერნეტი"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"არ შემაწუხოთ"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"პრიორიტეტული რეჟიმები"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"დაწყვილებული მოწყობილობები მიუწვდომელია"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"შეეხეთ მოწყობილობის დასაკავშირებლად ან გასათიშად"</string>
@@ -302,8 +302,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"შენახული"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"კავშირის გაწყვეტა"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"გააქტიურება"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"ხვალ ავტომატურად ჩართვა"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ისეთი ფუნქციები, როგორიცაა სწრაფი გაზიარება და ჩემი მოწყობილობის პოვნა, იყენებს Bluetooth-ს"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ჩაირთვება ხვალ დილით"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"აუდიოს გაზიარება"</string>
@@ -472,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ვიჯეტების დამატება"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ხანგრძლივად დააჭირეთ ვიჯეტების მოსარგებად"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ვიჯეტების მორგება"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ვიჯეტების მოსარგებად განბლოკეთ"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"აპის ხატულა გათიშული ვიჯეტისთვის"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ინსტალაციის პროცესში მყოფი ვიჯეტის აპის ხატულა"</string>
<string name="edit_widget" msgid="9030848101135393954">"ვიჯეტის რედაქტირება"</string>
@@ -490,12 +490,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ვიჯეტის არჩევა"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ვიჯეტის ამოშლა"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"არჩეული ვიჯეტის განთავსება"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"ჩაკეტილი ეკრანის ვიჯეტები"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"ნებისმიერს შეუძლია თქვენს ჩაკეტილ ეკრანზე ვიჯეტების ნახვა, თუნდაც ტაბლეტი ჩაკეტილი იყოს."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"დაბლოკილი ეკრანის ვიჯეტები"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"უნდა დაადასტუროთ თქვენი ვინაობა, რათა გახსნათ აპი ვიჯეტის გამოყენებით. გაითვალისწინეთ, რომ ნებისმიერს შეუძლია მათი ნახვა, მაშინაც კი, როცა ტაბლეტი დაბლოკილია. ზოგი ვიჯეტი შეიძლება არ იყოს გათვლილი თქვენი დაბლოკილი ეკრანისთვის და მათი აქ დამატება შეიძლება სახიფათო იყოს."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"გასაგებია"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"მომხმარებლის გადართვა"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ჩამოშლადი მენიუ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ამ სესიის ყველა აპი და მონაცემი წაიშლება."</string>
@@ -717,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ნაგულისხმევი"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"ავტომატური"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"ხმისა და ვიბრაციის გარეშე"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ხმისა და ვიბრაციის გარეშე, ჩნდება მიმოწერების სექციის ქვედა ნაწილში"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"დარეკვა ან ვიბრაცია მოწყობილობის პარამეტრების მიხედვით"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"დარეკვა ან ვიბრაცია მოწყობილობის პარამეტრების მიხედვით. მიმოწერები <xliff:g id="APP_NAME">%1$s</xliff:g>-ის ბუშტიდან, ნაგულისხმევად."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"სისტემისთვის ისეთი უფლების მინიჭება, რომ მან განსაზღვროს, ამ შეტყობინებამ ხმოვანი სიგნალი უნდა აამოქმედოს თუ ვიბრაცია"</string>
@@ -774,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1350,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"გამოიყენება <xliff:g id="APP_NAME">%1$s</xliff:g>-ის მიერ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ახლახან გამოყენებულია <xliff:g id="APP_NAME">%1$s</xliff:g>-ის მიერ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"სისტემა"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"სისტემის მართვის საშუალებები"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"სისტემის აპები"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"მრავალამოცანიანი რეჟიმი"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ბოლოდროინდელი აპები"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ეკრანის გაყოფა"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"შეყვანა"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"აპის მალსახმობები"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"მიმდინარე აპი"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"მისაწვდომობა"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"კლავიატურის მალსახმობები"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ძიების მალსახმობები"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ხატულის ჩაკეცვა"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ხატულის გაფართოება"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ან"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"უკან დაბრუნების ჟესტი"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"მთავარ ეკრანზე გადასვლის ჟესტი"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"მოქმედების კლავიში"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"მზადაა"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"შესანიშნავია!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"უკან დაბრუნება"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"უკან დასაბრუნებლად, სენსორულ პანელზე ნებისმიერ ადგილას სამი თითის გამოყენებით გადაფურცლეთ მარცხნივ ან მარჯვნივ."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"სენსორული პანელი, რომელიც აჩვენებს მარჯვენა და მარცხენა მიმართულებით მოძრავ სამ თითს"</string>
@@ -1374,4 +1377,5 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"დონე: %1$d %2$d-დან"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"სახლის კონტროლი"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"სწრაფი წვდომა სახლის კონტროლზე ეკრანმზოგის სახით"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"მოქმედების გაუქმება"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
index 21f8102036c9..2b11a15aee7e 100644
--- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"გამორთულია"</item>
<item msgid="4875147066469902392">"ჩართულია"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"მიუწვდომელია"</item>
+ <item msgid="2004750556637773692">"გამორთული"</item>
+ <item msgid="8968530753931637871">"ჩართული"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"მიუწვდომელია"</item>
<item msgid="5044688398303285224">"გამორთულია"</item>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 722b58e89447..c07b6a0a246e 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасы осы скриншотты анықтады."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> және басқа да ашық қолданбалар осы скриншотты анықтады."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ескертпеге қосу"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Сілтеме қосу"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Экран жазғыш"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экран жазғыш бейнесін өңдеу"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды бейнеге жазудың ағымдағы хабарландыруы"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Көру үшін түртіңіз."</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Экран жазбасын сақтау кезінде қате шықты."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Экрандағы бейнені жазу кезінде қате шықты."</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; қолданбасының контентін жазуды тоқтатасыз."</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Жазуды тоқтату"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экранды бөлісіп жатыр."</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Экранды бөлісуді тоқтатасыз ба?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; қолданбасының контентін бөлісуді тоқтатасыз."</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Бөлісуді тоқтату"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Экранды трансляциялап жатырсыз."</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Трансляциялау тоқтасын ба?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; қолданбасының контентін трансляциялауды тоқтатасыз."</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Трансляцияны тоқтату"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Жабу"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Мәселені жазу құралы"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Мәселе жазбасы өңделіп жатыр"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Мәселе туралы дерек жинау сеансына арналған ағымдағы хабарландыру"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Мәселе жазбасын сақтау кезінде қате шықты."</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Мәселені жазуды бастау кезінде қате шықты."</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Толық экранда көру"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Шығу үшін экранның жоғарғы жағынан төмен қарай сырғытыңыз."</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Түсінікті"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Артқа"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Үй"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Бетпен ашылды. Жалғастыру үшін басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Бет танылды. Жалғастыру үшін басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Бет танылды. Жалғастыру үшін құлыпты ашу белгішесін басыңыз."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Бетпен ашылды. Жалғастыру үшін түртіңіз."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификацияланған"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Аутентификациядан бас тарту"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Қосымша опциялар"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Скринсейвер"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Этернет"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Мазаламау"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сақталды"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ажырату"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"іске қосу"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Ертең автоматты түрде қосу"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share және Find My Device сияқты функциялар Bluetooth-ты пайдаланады."</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ертең таңертең қосылады."</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Аудионы бөлісу"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Басқа виджеттер қосыңыз."</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджеттерді бейімдеу үшін ұзақ басып тұрыңыз."</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджеттерді реттеу"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Виджеттерді бейімдеу үшін құлыпты ашыңыз."</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Өшірілген виджеттің қолданба белгішесі"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Виджетке арналған қолдана белгішесі орнатылып жатыр."</string>
<string name="edit_widget" msgid="9030848101135393954">"Виджетті өзгерту"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет таңдау"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетті өшіру"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"таңдалған виджетті орналастыру"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Құлып экранының виджеттері"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Қолданбаны виджет көмегімен ашу үшін жеке басыңызды растауыңыз керек. Сондай-ақ басқалар оларды планшетіңіз құлыптаулы кезде де көре алатынын ескеріңіз. Кейбір виджеттер құлып экранына арналмаған болады, сондықтан оларды мұнда қосу қауіпсіз болмауы мүмкін."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түсінікті"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Пайдаланушыны ауыстыру"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ашылмалы мәзір"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданба мен дерек жойылады."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Қазір бастау"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Хабарландырулар жоқ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңа хабарландырулар жоқ"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Бейімделетін хабарландырулар қосулы"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Қысқа уақыт аралығында көп хабарландыру алсаңыз, құрылғыңыз дыбыс деңгейін және экранда шығатын қалқымалы терезелердің уақытын екі минутқа дейін азайтады."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өшіру"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ескі хабарландырулар үшін құлыпты ашыңыз"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бұл құрылғыны ата-анаңыз басқарады."</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін."</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Әдепкі"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Автоматты"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Дыбыс не діріл болмайды."</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Дыбыс не діріл болмайды, әңгімелер бөлімінің төмен жағында тұрады."</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Құрылғы параметрлеріне байланысты шырылдауы не дірілдеуі мүмкін"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Құрылғы параметрлеріне байланысты шырылдауы не дірілдеуі мүмкін. <xliff:g id="APP_NAME">%1$s</xliff:g> чаттары әдепкісінше қалқымалы етіп көрсетіледі."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Хабарландыру дыбысының немесе дірілдің қосылуын жүйе анықтайтын болады"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) қолданбасы пайдаланып жатыр"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Соңғы рет <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) қолданбасы пайдаланды."</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Жүйе"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Жүйені басқару элементтері"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Жүйелік қолданбалар"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Мультитаскинг"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Соңғы қолданбалар"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Экранды бөлу"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Кіріс"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Қолданба таңбашалары"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Арнайы мүмкіндіктер"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Перне тіркесімдері"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Іздеу жылдам пәрмендері"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жию белгішесі"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жаю белгішесі"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"немесе"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Артқа қайтару қимылы"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Негізгі бетке қайтару қимылы"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Әрекет пернесі"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Дайын"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Жарайсыз!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Артқа"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Артқа қайту үшін сенсорлық тақтаның кез келген жерінен үш саусақпен солға немесе оңға сырғытыңыз."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Оңға және солға жылжитын үш саусақты көрсетіп тұрған сенсорлық тақта."</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Артқа қайту қимылын көрсетіп тұрған құрылғы экраны."</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Пернетақта жарығы"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Деңгей: %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Үй басқару элементтері"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Үй басқару элементтерін скринсейверден қолданыңыз."</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
index cf3aa69992f1..6410460e3ed7 100644
--- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Өшірулі"</item>
<item msgid="4875147066469902392">"Қосулы"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Қолжетімсіз"</item>
<item msgid="5044688398303285224">"Өшірулі"</item>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 733196f4fc23..bd31568b2689 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> បានរកឃើញ​រូបថតអេក្រង់នេះ។"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> និងកម្មវិធីដែលបើក​ផ្សេងទៀតបានរកឃើញ​រូបថតអេក្រង់នេះ។"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"បញ្ចូលទៅក្នុងកំណត់ចំណាំ"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"រួមបញ្ចូល​តំណ"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"មុខងារថត​វីដេអូអេក្រង់"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"កំពុង​ដំណើរការ​ការថតអេក្រង់"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ការជូនដំណឹង​ដែល​កំពុង​ដំណើរការ​សម្រាប់​រយៈពេលប្រើ​ការថត​សកម្មភាព​អេក្រង់"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"ចុចដើម្បីមើល"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"មានបញ្ហាក្នុងការរក្សាទុក​ការថតវីដេអូអេក្រង់"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"មានបញ្ហា​ក្នុងការ​ចាប់ផ្ដើម​ថត​អេក្រង់"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"អ្នកនឹងឈប់ថត &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"អ្នកនឹងឈប់ចែករំលែក &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"អ្នកនឹងឈប់បញ្ជូន &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"បញ្ឈប់ការថតឬ?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"បច្ចុប្បន្ន អ្នកកំពុងថតអេក្រង់ទាំងមូលរបស់អ្នក"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"បច្ចុប្បន្ន អ្នកកំពុងថត <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ឈប់ថត"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"កំពុងបង្ហាញអេក្រង់"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ឈប់បង្ហាញអេក្រង់ឬ?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"បច្ចុប្បន្ន អ្នកកំពុងបង្ហាញអេក្រង់ទាំងមូលរបស់អ្នកតាមរយៈ <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"បច្ចុប្បន្ន អ្នកកំពុងបង្ហាញអេក្រង់ទាំងមូលរបស់អ្នកតាមរយៈកម្មវិធីមួយ"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"បច្ចុប្បន្ន អ្នកកំពុងបង្ហាញ<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"បច្ចុប្បន្ន អ្នកកំពុងបង្ហាញកម្មវិធីមួយ"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ឈប់​ចែក​រំលែក"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"កំពុង​បញ្ជូន​អេក្រង់"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ឈប់បញ្ជូនឬ?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"បច្ចុប្បន្ន អ្នកកំពុងបញ្ជូនអេក្រង់ទាំងមូលរបស់អ្នកទៅ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"បច្ចុប្បន្ន អ្នកកំពុងបញ្ជូនអេក្រង់ទាំងមូលរបស់អ្នកទៅឧបករណ៍នៅជិត"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"បច្ចុប្បន្ន អ្នកកំពុងបញ្ជូន <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ទៅ <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"បច្ចុប្បន្ន អ្នកកំពុងបញ្ជូន <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ទៅឧបករណ៍នៅជិត"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"បច្ចុប្បន្ន អ្នកកំពុងបញ្ជូនទៅ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"បច្ចុប្បន្ន អ្នកកំពុងបញ្ជូនទៅឧបករណ៍នៅជិត"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"បញ្ឈប់ការបញ្ជូន"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"បិទ"</string>
<string name="issuerecord_title" msgid="286627115110121849">"កម្មវិធីកត់ត្រាបញ្ហា"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"កំពុងដំណើរការការកត់ត្រាបញ្ហា"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"ការជូនដំណឹងដែលកំពុងបន្តសម្រាប់វគ្គប្រមូលបញ្ហា"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"មានបញ្ហាក្នុងការរក្សាទុកកំណត់ត្រាបញ្ហា"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"មានបញ្ហាក្នុងការចាប់ផ្ដើមកត់ត្រាបញ្ហា"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"កំពុងមើលពេញអេក្រង់"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"ដើម្បីចេញ សូមអូសពីផ្នែកខាងលើនៃអេក្រង់របស់អ្នកចុះក្រោម"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"យល់ហើយ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ថយក្រោយ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"គេហ​ទំព័រ"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"បានដោះសោដោយប្រើមុខ។ សូមចុច ដើម្បីបន្ត។"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"បានស្គាល់មុខ។ សូមចុច ដើម្បីបន្ត។"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"បានស្គាល់មុខ។ សូមចុចរូបដោះសោ ដើម្បីបន្ត។"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"បានដោះសោដោយប្រើមុខ។ ចុច​ ដើម្បី​បន្ត។"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"បាន​ផ្ទៀងផ្ទាត់"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"បោះបង់ការផ្ទៀងផ្ទាត់"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ជម្រើស​ច្រើន​ទៀត"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"ធាតុរក្សាអេក្រង់"</string>
<string name="ethernet_label" msgid="2203544727007463351">"អ៊ីសឺរណិត"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"កុំ​រំខាន"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ប៊្លូធូស"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"មិន​មាន​ឧបករណ៍​ផ្គូផ្គង​ដែល​អាច​ប្រើ​បាន"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"ចុចដើម្បីភ្ជាប់ ឬផ្ដាច់ឧបករណ៍"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"បាន​រក្សាទុក"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ផ្ដាច់"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"បើកដំណើរការ"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"បើកនៅថ្ងៃស្អែកដោយស្វ័យប្រវត្តិ"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"មុខងារដូចជា Quick Share និង \"រកឧបករណ៍របស់ខ្ញុំ\" ប្រើប៊្លូធូស"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ប៊្លូធូសនឹងបើកនៅព្រឹកស្អែក"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ស្ដាប់សំឡេងរួមគ្នា"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"បញ្ចូលធាតុ​ក្រាហ្វិកច្រើនទៀត"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ចុច​ឱ្យ​យូរ ដើម្បីប្ដូរធាតុ​ក្រាហ្វិកតាមបំណង"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ប្ដូរ​ធាតុ​ក្រាហ្វិកតាម​បំណង"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ដោះសោ​ដើម្បីប្ដូរធាតុ​ក្រាហ្វិកតាមបំណង"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"រូបកម្មវិធីសម្រាប់ធាតុ​ក្រាហ្វិកដែលបានបិទ"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"រូបតំណាងកម្មវិធីសម្រាប់ធាតុ​ក្រាហ្វិកកំពុងត្រូវបានដំឡើង"</string>
<string name="edit_widget" msgid="9030848101135393954">"កែធាតុ​ក្រាហ្វិក"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ជ្រើសរើសធាតុ​ក្រាហ្វិក"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ដកធាតុ​ក្រាហ្វិកចេញ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ដាក់ធាតុ​ក្រាហ្វិកដែលបានជ្រើសរើស"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"ធាតុ​ក្រាហ្វិកអេក្រង់ចាក់សោ"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"អ្នកគ្រប់គ្នាអាចមើលធាតុក្រាហ្វិកលើអេក្រង់ចាក់សោរបស់អ្នក ទោះបីជាថេប្លេតរបស់អ្នកត្រូវបានចាក់សោក៏ដោយ។"</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ធាតុ​ក្រាហ្វិកលើអេក្រង់ចាក់សោ"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ដើម្បីបើកកម្មវិធីដោយប្រើធាតុ​ក្រាហ្វិក អ្នកនឹងត្រូវផ្ទៀងផ្ទាត់ថាជាអ្នក។ ទន្ទឹមនឹងនេះ សូមចងចាំថា នរណាក៏អាចមើលធាតុក្រាហ្វិកបាន សូម្បីពេលថេប្លេតរបស់អ្នកជាប់សោក៏ដោយ។ ធាតុ​ក្រាហ្វិកមួយចំនួនប្រហែលមិនត្រូវបានរចនាឡើងសម្រាប់អេក្រង់ចាក់សោរបស់អ្នកទេ និងមិនមានសុវត្ថិភាពឡើយ បើបញ្ចូលទៅទីនេះ។"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"យល់ហើយ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ប្ដូរ​អ្នក​ប្រើ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ម៉ឺនុយ​ទាញចុះ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"កម្មវិធី និងទិន្នន័យ​ទាំងអស់​ក្នុង​វគ្គ​នេះ​នឹង​ត្រូវ​លុប។"</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"លំនាំដើម"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"ស្វ័យប្រវត្តិ"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"គ្មាន​សំឡេង ឬការញ័រទេ"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"គ្មានសំឡេង​ឬការញ័រ និងបង្ហាញ​ទាបជាង​នៅក្នុង​ផ្នែកសន្ទនា"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"អាចរោទ៍ ឬញ័រ ដោយផ្អែកលើ​ការកំណត់ឧបករណ៍"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"អាចរោទ៍ ឬញ័រ ដោយផ្អែកលើ​ការកំណត់ឧបករណ៍។ ការសន្ទនា​ពីផ្ទាំងអណ្ដែត <xliff:g id="APP_NAME">%1$s</xliff:g> តាម​លំនាំដើម​។"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ឱ្យប្រព័ន្ធកំណត់ថាតើ​ការជូនដំណឹងនេះ​គួរតែបន្លឺសំឡេង ឬញ័រ"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1351,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"កំពុងប្រើដោយ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"បានប្រើនាពេលថ្មីៗនេះដោយ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ប្រព័ន្ធ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ការគ្រប់គ្រង​ប្រព័ន្ធ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"កម្មវិធី​ប្រព័ន្ធ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ការដំណើរការបានច្រើន"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"កម្មវិធី​ថ្មីៗ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"មុខងារ​បំបែកអេក្រង់"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ធាតុចូល"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ផ្លូវកាត់​កម្មវិធី"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ភាពងាយស្រួល"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ផ្លូវកាត់​ក្ដារ​ចុច"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ផ្លូវ​កាត់ការស្វែងរក"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"រូបតំណាង \"បង្រួម\""</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"រូបតំណាង \"ពង្រីក\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ឬ"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"ចលនាថយក្រោយ"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"ចលនាទៅទំព័រដើម"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"គ្រាប់ចុចសកម្មភាព"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"រួចរាល់"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"ធ្វើបានល្អ!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ថយ​ក្រោយ"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ដើម្បីថយក្រោយ សូមអូសទៅឆ្វេង ឬស្ដាំដោយប្រើម្រាមដៃបីនៅកន្លែងណាមួយនៅលើផ្ទាំងប៉ះ។"</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ផ្ទាំងប៉ះដែលបង្ហាញម្រាមដៃបីដែលផ្លាស់ទីទៅស្ដាំ និងឆ្វេង"</string>
@@ -1374,4 +1379,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"កម្រិតទី %1$d នៃ %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ការគ្រប់គ្រង​ផ្ទះ"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"ចូលប្រើការគ្រប់គ្រងផ្ទះអ្នកបានលឿនជាធាតុរក្សាអេក្រង់"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml
index 54790f6a028e..25f74858f9fb 100644
--- a/packages/SystemUI/res/values-km/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"បិទ"</item>
<item msgid="4875147066469902392">"បើក"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"មិនមានទេ"</item>
<item msgid="5044688398303285224">"បិទ"</item>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index cddc752db091..4bf89e174dfe 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"ಈ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು <xliff:g id="APPNAME">%1$s</xliff:g> ಪತ್ತೆಹಚ್ಚಿದೆ."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ಹಾಗೂ ತೆರೆದಿರುವ ಇತರ ಆ್ಯಪ್‌ಗಳು ಈ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು ಪತ್ತೆಹಚ್ಚಿವೆ."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ಟಿಪ್ಪಣಿಗೆ ಸೇರಿಸಿ"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"ಲಿಂಕ್ ಅನ್ನು ಸೇರಿಸಿ"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡರ್"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್‌ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ನೋಟಿಫಿಕೇಶನ್"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೇವ್‌ ಮಾಡುವಾಗ ದೋಷ ಎದುರಾಗಿದೆ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ಇದರಿಂದ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ನ ಕಂಟೆಂಟ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡುವುದು ನಿಂತುಹೋಗುತ್ತದೆ"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ಇದರಿಂದ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ನ ಕಂಟೆಂಟ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುವುದು ನಿಂತುಹೋಗುತ್ತದೆ"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ಇದರಿಂದ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ನ ಕಂಟೆಂಟ್ ಅನ್ನು ಬಿತ್ತರಿಸುವುದು ನಿಂತುಹೋಗುತ್ತದೆ"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"ರೆಕಾರ್ಡ್ ಮಾಡುವುದನ್ನು ನಿಲ್ಲಿಸಬೇಕೇ?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"ನೀವು ಪ್ರಸ್ತುತ ನಿಮ್ಮ ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"ನೀವು ಪ್ರಸ್ತುತ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸಿ"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ಪರದೆಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ಸ್ಕ್ರೀನ್ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ನಿಲ್ಲಿಸಬೇಕೆ?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"ನೀವು ಪ್ರಸ್ತುತ ನಿಮ್ಮ ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> ನೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"ನೀವು ಪ್ರಸ್ತುತ ನಿಮ್ಮ ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆ್ಯಪ್‌ನೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"ನೀವು ಪ್ರಸ್ತುತ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"ನೀವು ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ನಿಲ್ಲಿಸಿ"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ಬಿತ್ತರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಬೇಕೆ?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"ನೀವು ಪ್ರಸ್ತುತ ನಿಮ್ಮ ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಬಿತ್ತರಿಸುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"ನೀವು ಪ್ರಸ್ತುತ ನಿಮ್ಮ ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಕ್ಕೆ ಬಿತ್ತರಿಸುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"ನೀವು ಪ್ರಸ್ತುತ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ಅನ್ನು <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ಗೆ ಬಿತ್ತರಿಸುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"ನೀವು ಪ್ರಸ್ತುತ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ಅನ್ನು ಸಮೀಪದ ಸಾಧನಕ್ಕೆ ಬಿತ್ತರಿಸುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"ನೀವು ಪ್ರಸ್ತುತ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಬಿತ್ತರಿಸುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"ನೀವು ಪ್ರಸ್ತುತ ಸಮೀಪದ ಸಾಧನಕ್ಕೆ ಬಿತ್ತರಿಸುತ್ತಿದ್ದೀರಿ"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"ಬಿತ್ತರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿ"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"ಮುಚ್ಚಿರಿ"</string>
<string name="issuerecord_title" msgid="286627115110121849">"ಸಮಸ್ಯೆ ರೆಕಾರ್ಡರ್"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ಸಮಸ್ಯೆ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಕ್ರಿಯೆ…"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"ಸಮಸ್ಯೆ ಸಂಗ್ರಹಣೆಯ ಸೆಶನ್‌ಗಾಗಿ ಜರುಗುತ್ತಿರುವ ನೋಟಿಫಿಕೇಶನ್"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"ಸಮಸ್ಯೆಯ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ಸೇವ್‌ ಮಾಡುವಾಗ ದೋಷ ಎದುರಾಗಿದೆ"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"ಸಮಸ್ಯೆಯ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುವಲ್ಲಿ ದೋಷ ಎದುರಾಗಿದೆ"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ವೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"ನಿರ್ಗಮಿಸಲು, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲಿನಿಂದ ಕೆಳಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"ಅರ್ಥವಾಯಿತು"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ಹಿಂದೆ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ಮುಖಪುಟ"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ದೃಢೀಕರಣವನ್ನು ರದ್ದುಗೊಳಿಸಿ"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ಇನ್ನಷ್ಟು ಆಯ್ಕೆಗಳು"</string>
@@ -291,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"ಸ್ಕ್ರೀನ್ ಸೇವರ್"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ಇಥರ್ನೆಟ್"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"ಆದ್ಯತೆಯ ಮೋಡ್‌ಗಳು"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ಬ್ಲೂಟೂತ್‌"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ಯಾವುದೇ ಜೋಡಿಸಲಾದ ಸಾಧನಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"ಸಾಧನವನ್ನು ಕನೆಕ್ಟ್ ಅಥವಾ ಡಿಸ್‌ಕನೆಕ್ಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
@@ -302,8 +302,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ಸೇವ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ಡಿಸ್‌ಕನೆಕ್ಟ್ ಮಾಡಿ"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"ನಾಳೆ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆನ್ ಮಾಡಿ"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ಕ್ವಿಕ್ ಶೇರ್ ಮತ್ತು Find My Device ನಂತಹ ಫೀಚರ್‌ಗಳು ಬ್ಲೂಟೂತ್ ಅನ್ನು ಬಳಸುತ್ತವೆ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ಬ್ಲೂಟೂತ್ ನಾಳೆ ಬೆಳಗ್ಗೆ ಆನ್ ಆಗುತ್ತದೆ"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳಿ"</string>
@@ -472,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ಹೆಚ್ಚಿನ ವಿಜೆಟ್‌ಗಳನ್ನು ಸೇರಿಸಿ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ವಿಜೆಟ್‌ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ದೀರ್ಘಕಾಲ ಒತ್ತಿರಿ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ವಿಜೆಟ್‌ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ವಿಜೆಟ್‌ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾದ ವಿಜೆಟ್‌ಗಾಗಿ ಆ್ಯಪ್ ಐಕಾನ್"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲಾದ ವಿಜೆಟ್‌ಗಾಗಿ ಆ್ಯಪ್ ಐಕಾನ್"</string>
<string name="edit_widget" msgid="9030848101135393954">"ವಿಜೆಟ್ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
@@ -490,12 +490,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ವಿಜೆಟ್ ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ವಿಜೆಟ್ ಅನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ಆಯ್ಕೆಮಾಡಿದ ವಿಜೆಟ್ ಅನ್ನು ಇರಿಸಿ"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ವಿಜೆಟ್‌ಗಳು"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಲಾಕ್ ಆಗಿದ್ದರೂ ಸಹ ಯಾರಾದರೂ ನಿಮ್ಮ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ವಿಜೆಟ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ವಿಜೆಟ್‌ಗಳು"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ವಿಜೆಟ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ಆ್ಯಪ್ ತೆರೆಯಲು, ಇದು ನೀವೇ ಎಂದು ನೀವು ದೃಢೀಕರಿಸಬೇಕಾಗುತ್ತದೆ. ಅಲ್ಲದೆ, ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಲಾಕ್ ಆಗಿದ್ದರೂ ಸಹ ಯಾರಾದರೂ ಅವುಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಎಂಬುದನ್ನು ನೆನಪಿನಲ್ಲಿಡಿ. ಕೆಲವು ವಿಜೆಟ್‌ಗಳು ನಿಮ್ಮ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ಗಾಗಿ ಉದ್ದೇಶಿಸದೇ ಇರಬಹುದು ಮತ್ತು ಇಲ್ಲಿ ಸೇರಿಸುವುದು ಸುರಕ್ಷಿತವಲ್ಲದಿರಬಹುದು."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ಅರ್ಥವಾಯಿತು"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ಪುಲ್‌ಡೌನ್ ಮೆನು"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಶನ್‌ನಲ್ಲಿನ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
@@ -717,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ಡೀಫಾಲ್ಟ್"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"ಸ್ವಯಂಚಾಲಿತ"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"ಯಾವುದೇ ಧ್ವನಿ ಅಥವಾ ವೈಬ್ರೇಷನ್‌ ಆಗುವುದಿಲ್ಲ"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ಯಾವುದೇ ಧ್ವನಿ ಅಥವಾ ವೈಬ್ರೇಷನ್‌ ಆಗುವುದಿಲ್ಲ, ಸಂಭಾಷಣೆ ವಿಭಾಗದ ಕೆಳಭಾಗದಲ್ಲಿ ಗೋಚರಿಸುತ್ತದೆ"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಆಧರಿಸಿ ಸಾಧನ ರಿಂಗ್ ಅಥವಾ ವೈಬ್ರೇಟ್ ಆಗುತ್ತದೆ"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಆಧರಿಸಿ ಫೋನ್ ರಿಂಗ್ ಅಥವಾ ವೈಬ್ರೇಟ್ ಆಗುತ್ತದೆ. ಡಿಫಾಲ್ಟ್ ಆಗಿ, <xliff:g id="APP_NAME">%1$s</xliff:g> ಬಬಲ್ ಸಂಭಾಷಣೆಗಳು."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ಈ ಅಧಿಸೂಚನೆಯು ಶಬ್ದ ಮಾಡಬೇಕೇ ಅಥವಾ ವೈಬ್ರೇಟ್ ಮಾಡಬೇಕೇ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸುವ ಅವಕಾಶವನ್ನು ಸಿಸ್ಟಂಗೆ ನೀಡಿ"</string>
@@ -774,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1350,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನಿಂದ ಬಳಕೆಯಲ್ಲಿದೆ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ಇತ್ತೀಚೆಗೆ <xliff:g id="APP_NAME">%1$s</xliff:g> ಇದನ್ನು ಬಳಸಿದೆ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ಸಿಸ್ಟಂ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ಸಿಸ್ಟಂ ನಿಯಂತ್ರಣಗಳು"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ಸಿಸ್ಟಂ ಆ್ಯಪ್‌ಗಳು"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ಮಲ್ಟಿಟಾಸ್ಕಿಂಗ್"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳು"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ಇನ್‌ಪುಟ್"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ಆ್ಯಪ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ಪ್ರಸ್ತುತ ಆ್ಯಪ್"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ಹುಡುಕಾಟದ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ಕುಗ್ಗಿಸುವ ಐಕಾನ್"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ವಿಸ್ತೃತಗೊಳಿಸುವ ಐಕಾನ್"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ಅಥವಾ"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"ಹಿಂಬದಿ ಗೆಸ್ಚರ್"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"ಹೋಮ್ ಗೆಸ್ಚರ್"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"ಆ್ಯಕ್ಷನ್‌ ಕೀ"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ಮುಗಿದಿದೆ"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"ಭೇಷ್!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ಹಿಂತಿರುಗಿ"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ಹಿಂತಿರುಗಲು, ಟಚ್‌ಪ್ಯಾಡ್‌ನಲ್ಲಿ ಎಲ್ಲಿಯಾದರೂ ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಎಡ ಅಥವಾ ಬಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ಮೂರು ಬೆರಳುಗಳು ಬಲಕ್ಕೆ ಮತ್ತು ಎಡಕ್ಕೆ ಚಲಿಸುತ್ತಿರುವುದನ್ನು ತೋರಿಸುತ್ತಿರುವ ಟಚ್‌ಪ್ಯಾಡ್"</string>
@@ -1374,4 +1377,5 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ರಲ್ಲಿ %1$d ಮಟ್ಟ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ಮನೆ ನಿಯಂತ್ರಣಗಳು"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"ಮನೆ ನಿಯಂತ್ರಣವನ್ನು ಸ್ಕ್ರೀನ್‌ಸೇವರ್‌ನಂತೆ ಬೇಗ ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಿ"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"ರದ್ದುಗೊಳಿಸಿ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
index afc7c1a10e0e..b2a75231d589 100644
--- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"ಆಫ್"</item>
<item msgid="4875147066469902392">"ಆನ್"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"ಲಭ್ಯವಿಲ್ಲ"</item>
+ <item msgid="2004750556637773692">"ಆಫ್ ಆಗಿದೆ"</item>
+ <item msgid="8968530753931637871">"ಆನ್ ಆಗಿದೆ"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ಲಭ್ಯವಿಲ್ಲ"</item>
<item msgid="5044688398303285224">"ಆಫ್"</item>
@@ -188,7 +193,7 @@
</string-array>
<string-array name="tile_states_hearing_devices">
<item msgid="1235334096484287173">"ಲಭ್ಯವಿಲ್ಲ"</item>
- <item msgid="3079622119444911877">"ಆಫ್ ಆಗಿದೆ"</item>
+ <item msgid="3079622119444911877">"ಆಫ್"</item>
<item msgid="3028994095749238254">"ಆನ್"</item>
</string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index c33c29154100..764748632b0e 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>에서 이 스크린샷을 감지했습니다."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 및 기타 공개 앱에서 이 스크린샷을 감지했습니다."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"메모에 추가"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"링크 포함"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"화면 녹화"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"화면 녹화 처리 중"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"화면 녹화 세션에 관한 지속적인 알림"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"탭하여 보기"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"화면 녹화 저장 중에 오류가 발생했습니다."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"화면 녹화 시작 중 오류 발생"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; 녹화가 중단됩니다."</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"녹화 중지"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"화면 공유 중"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"화면 공유를 중지하시겠습니까?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; 공유가 중단됩니다."</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"공유 중지"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"화면 전송 중"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"전송을 중지할까요?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; 전송이 중단됩니다."</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"전송 중지"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"닫기"</string>
<string name="issuerecord_title" msgid="286627115110121849">"문제 녹화 도구"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"문제 녹화 처리 중"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"문제 수집 섹션에 대한 진행 중 알림"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"문제 녹화 저장 중에 오류가 발생했습니다."</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"문제 녹화 시작 중에 오류가 발생했습니다."</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"전체 화면 모드"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"종료하려면 화면 상단에서 아래로 스와이프합니다."</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"확인"</string>
<string name="accessibility_back" msgid="6530104400086152611">"뒤로"</string>
<string name="accessibility_home" msgid="5430449841237966217">"홈"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 누르세요."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"얼굴이 인식되었습니다. 계속하려면 누르세요."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"얼굴이 인식되었습니다. 계속하려면 아이콘을 누르세요."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 탭하세요."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"인증됨"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"인증 취소"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"옵션 더보기"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"화면 보호기"</string>
<string name="ethernet_label" msgid="2203544727007463351">"이더넷"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"방해 금지 모드"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"블루투스"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"페어링된 기기가 없습니다"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"기기를 연결 또는 연결 해제하려면 탭하세요"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"저장됨"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"연결 해제"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"실행"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"내일 자동으로 사용 설정"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share, 내 기기 찾기 등의 기능에서 블루투스를 사용합니다."</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"블루투스가 내일 아침에 켜집니다."</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"오디오 공유"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"더 많은 위젯 추가"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"위젯을 맞춤설정하려면 길게 누르기"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"위젯 맞춤설정"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"위젯을 맞춤설정하려면 잠금 해제하세요."</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"사용 중지된 위젯의 앱 아이콘"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"설치 중인 위젯의 앱 아이콘"</string>
<string name="edit_widget" msgid="9030848101135393954">"위젯 수정"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"위젯 선택"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"위젯 삭제"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"선택한 위젯 배치"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"잠금 화면 위젯"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"위젯을 사용하여 앱을 열려면 본인 인증을 해야 합니다. 또한 태블릿이 잠겨 있더라도 누구나 볼 수 있다는 점을 유의해야 합니다. 일부 위젯은 잠금 화면에 적합하지 않고 여기에 추가하기에 안전하지 않을 수 있습니다."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"확인"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"사용자 전환"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"풀다운 메뉴"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"시작하기"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"알림 없음"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"새로운 알림 없음"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"적응형 알림 사용 중"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"이제 짧은 시간 동안 많은 알림을 받으면 최대 2분 동안 기기의 볼륨을 낮추고 화면의 팝업을 줄입니다."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"사용 중지"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"잠금 해제하여 이전 알림 보기"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"부모님이 관리하는 기기입니다."</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"내 조직에서 이 기기를 소유하며 네트워크 트래픽을 모니터링할 수 있습니다."</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"기본값"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"자동"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"소리 또는 진동 없음"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"소리나 진동이 울리지 않으며 대화 섹션 하단에 표시됨"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"기기 설정에 따라 벨소리나 진동이 울릴 수 있음"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"기기 설정에 따라 벨소리나 진동이 울릴 수 있습니다. 기본적으로 <xliff:g id="APP_NAME">%1$s</xliff:g>의 대화는 대화창으로 표시됩니다."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"시스템에서 알림 시 소리 또는 진동을 사용할지 결정하도록 허용합니다."</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 사용 중(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"최근 <xliff:g id="APP_NAME">%1$s</xliff:g>에서 사용됨(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"시스템"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"시스템 컨트롤"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"시스템 앱"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"멀티태스킹"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"최근 앱"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"화면 분할"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"입력"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"앱 바로가기"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"접근성"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"단축키"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"검색 바로가기"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"접기 아이콘"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"확장 아이콘"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"또는"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"뒤로 동작"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"홈 동작"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"작업 키"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"완료"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"아주 좋습니다."</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"뒤로"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"돌아가려면 세 손가락을 사용해 터치패드의 아무 곳이나 왼쪽 또는 오른쪽으로 스와이프합니다."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"터치패드에서 세 손가락을 좌우로 움직이는 모습"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"뒤로 동작 애니메이션을 보여 주는 기기 화면"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"키보드 백라이트"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d단계 중 %1$d단계"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"홈 컨트롤"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"화면 보호기로 홈 컨트롤에 빠르게 액세스하기"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
index bc4740dbc23a..9116085bb0b9 100644
--- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"꺼짐"</item>
<item msgid="4875147066469902392">"켜짐"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"이용 불가"</item>
<item msgid="5044688398303285224">"꺼짐"</item>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 9cf0e98c15ba..d1aa663d83cc 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ушул скриншотту аныктады."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> жана ачылып турган башка колдонмолор ушул скриншотту аныктады."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Кыска жазууга кошуу"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Шилтеме кошуу"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Экрандан видео жаздырып алуу"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экрандан жаздырылып алынган видео иштетилүүдө"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Көрүү үчүн таптаңыз"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Экран тартылган жок"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Экранды жаздырууну баштоодо ката кетти"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосун жаздырууну токтотосуз"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосун бөлүшүүнү токтотосуз"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосун тышкы экранга чыгарууну токтотосуз"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Жаздырууну токтотосузбу?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Учурда бүтүндөй экраныңызды жаздырып жатасыз"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Учурда <xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун жаздырып жатасыз"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Жаздырууну токтотуу"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экран бөлүшүлүүдө"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Экранды бөлүшүү токтотулсунбу?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Учурда бүтүндөй экраныңызды <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> менен бөлүшүп жатасыз"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Учурда бүтүндөй экраныңызды колдонмо менен бөлүшүп жатасыз"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Учурда <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> колдонмосун бөлүшүп жатасыз"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Учурда колдонмону бөлүшүп жатасыз"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Бөлүшүүнү токтотуу"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Тышкы экранга чыгарылууда"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Тышкы экранга чыгаруу токтотулсунбу?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Учурда бүтүндөй экраныңызды <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүнө чыгарып жатасыз"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Учурда бүтүндөй экраныңызды жакын жердеги түзмөккө чыгарып жатасыз"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Учурда <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> контентин <xliff:g id="DEVICE_NAME">%2$s</xliff:g> түзмөгүнө чыгарып жатасыз"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> контентин жакын жердеги түзмөккө чыгарып жатасыз"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Учурда <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүнө чыгарып жатасыз"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Учурда жакын жердеги түзмөккө чыгарып жатасыз"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Тышкы экранга чыгарууну токтотуу"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Жабуу"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Маселе жаздыргыч"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Маселе жаздырылууда"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Маселе тууралуу маалымат чогултулуп жатканы жөнүндө учурдагы билдирме"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Жаздырылган маселе сакталган жок"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Башталбай койду"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Толук экран режимин көрүү"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Чыгуу үчүн экранды өйдө жагынан ылдый сүрүп коюңуз"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Түшүндүм"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Артка"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Үйгө"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Кулпуну жүзүңүз менен ачтыңыз. Улантуу үчүн басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Жүз таанылды. Улантуу үчүн басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Жүз таанылды. Улантуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Кулпусун жүзүңүз менен ачтыңыз. Улантуу үчүн таптап коюңуз."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аныктыгы текшерилди"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Аныктыгын текшерүүнү жокко чыгаруу"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Дагы параметрлер"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Көшөгө"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Тынчымды алба"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сакталды"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ажыратуу"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"иштетүү"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Эртең автоматтык түрдө күйгүзүлсүн"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth Тез бөлүшүү жана Түзмөгүм кайда? сыяктуу функцияларда колдонулат"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth эртең таңда күйөт"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Чогуу угуу"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Көбүрөөк виджеттерди кошуу"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджеттерди ыңгайлаштыруу үчүн кое бербей басып туруңуз"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджеттерди ыңгайлаштыруу"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Виджеттерди ыңгайлаштыруу үчүн кулпуну ачыңыз"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Өчүрүлгөн виджет үчүн колдонмонун сүрөтчөсү"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Виджет үчүн колдонмонун сүрөтчөсү орнотулууда"</string>
<string name="edit_widget" msgid="9030848101135393954">"Виджетти түзөтүү"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет тандоо"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетти алып салуу"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"тандалган виджетти жайгаштыруу"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Кулпуланган экрандагы виджеттер"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Планшетиңиз кулпуланган болсо да, кулпуланган экраныңыздан виджеттерди бардыгы көрө алат."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Кулпуланган экрандагы виджеттер"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Колдонмону виджет аркылуу ачуу үчүн бул сиз экениңизди ырасташыңыз керек. Аларды планшетиңиз кулпуланып турса да, баары көрө аларын эске алыңыз. Айрым виджеттер кулпуланган экранда колдонууга арналган эмес жана аларды бул жерге кошуу кооптуу болушу мүмкүн."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түшүндүм"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Колдонуучуну которуу"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ылдый түшүүчү меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана аларга байланыштуу нерселер өчүрүлөт."</string>
@@ -549,12 +549,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Азыр баштоо"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Билдирме жок"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңы билдирмелер жок"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивдүү билдирмелер күйүк"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Эгер кыска убакыттын ичинде билдирмелер көп келсе, үн көлөмү жана экрандагы калкыма терезелердин саны эки мүнөткө чейин азайтылат."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өчүрүү"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Билдирмелерди көрүү үчүн кулпуну ачыңыз"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бул түзмөктү ата-энең башкарат"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Бул түзмөк уюмуңузга таандык. Уюмуңуз тармактын трафигин көзөмөлдөй алат"</string>
@@ -720,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Демейки"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Автоматтык"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Үнү чыкпайт жана дирилдебейт"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Үнү чыкпайт же дирилдебейт жана сүйлөшүүлөр тизмесинин ылдый жагында көрүнөт"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Түзмөктүн параметрлерине жараша шыңгырап же дирилдеши мүмкүн"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Түзмөктүн параметрлерине жараша шыңгырап же дирилдеши мүмкүн. <xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосундагы сүйлөшүүлөр демейки шартта калкып чыкма билдирмелер болуп көрүнөт."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Билдирменин үнүн чыгартууну же басууну системага тапшырыңыз"</string>
@@ -777,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Өчүрүү"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Башкы бет"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Бүтүрүү"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1351,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда иштеп жатат (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Акыркы жолу <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) колдонмосунда иштетилди"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Система"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системанын башкаруу элементтери"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системанын колдонмолору"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Бир нече тапшырма аткаруу"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Акыркы колдонмолор"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Экранды бөлүү"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Киргизүү"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Колдонмодогу кыска жолдор"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Атайын мүмкүнчүлүктөр"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Ыкчам баскычтар"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ыкчам баскычтарды издөө"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жыйыштыруу сүрөтчөсү"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жайып көрсөтүү сүрөтчөсү"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"же"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Артка кайтуу жаңсоосу"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Башкы бетке өтүү жаңсоосу"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Аракет баскычы"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Бүттү"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Азаматсыз!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Артка кайтуу"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Кайтуу үчүн сенсордук тактанын каалаган жерин үч манжаңыз менен солго же оңго сүрүңүз."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Үч манжанын оңго жана солго жылып жатканы көрсөтүлгөн сенсордук такта"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Артка жаңсоосунун анимациясы көрсөтүлгөн түзмөктүн экраны"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Баскычтоптун жарыгы"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ичинен %1$d-деңгээл"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Үйдөгү түзмөктөрдү тескөө"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Үйдөгү түзмөктөрдү көшөгөдөн ыкчам тескеңиз"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
index 694967e3d8d6..d92f787b286b 100644
--- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Өчүк"</item>
<item msgid="4875147066469902392">"Күйүк"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Жеткиликсиз"</item>
<item msgid="5044688398303285224">"Өчүк"</item>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 7bb5041d34b8..5abef943ff51 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ກວດພົບຮູບໜ້າຈໍນີ້."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ແລະ ແອັບອື່ນໆທີ່ເປີດຢູ່ກວດພົບຮູບໜ້າຈໍນີ້."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ເພີ່ມໃສ່ບັນທຶກ"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"ຮວມລິ້ງ"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ໂປຣແກຣມບັນທຶກໜ້າຈໍ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ກຳລັງປະມວນຜົນການບັນທຶກໜ້າຈໍ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ການແຈ້ງເຕືອນສຳລັບເຊດຊັນການບັນທຶກໜ້າຈໍໃດໜຶ່ງ"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"ແຕະເພື່ອເບິ່ງ"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"ເກີດຂໍ້ຜິດພາດໃນການບັນທຶກໜ້າຈໍ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ເກີດຄວາມຜິດພາດໃນການບັນທຶກໜ້າຈໍ"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ທ່ານຈະຢຸດການບັນທຶກ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ທ່ານຈະຢຸດການແບ່ງປັນ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ທ່ານຈະຢຸດການສົ່ງສັນຍານ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"ຢຸດການບັນທຶກບໍ?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"ທ່ານກຳລັງບັນທຶກທັງໝົດໜ້າຈໍຂອງທ່ານ"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"ທ່ານກຳລັງບັນທຶກ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ຢຸດການບັນທຶກ"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ກຳລັງແບ່ງປັນໜ້າຈໍ"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ຢຸດການແບ່ງປັນໜ້າຈໍບໍ?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"ທ່ານກຳລັງແບ່ງປັນທັງໝົດໜ້າຈໍຂອງທ່ານກັບ <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"ທ່ານກຳລັງແບ່ງປັນທັງໝົດໜ້າຈໍຂອງທ່ານກັບແອັບ"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"ທ່ານກຳລັງແບ່ງປັນ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"ທ່ານກຳລັງແບ່ງປັນແອັບ"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ຢຸດການແບ່ງປັນ"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ກຳລັງສົ່ງສັນຍານໜ້າຈໍ"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ຢຸດການສົ່ງສັນຍານບໍ?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"ທ່ານກຳລັງສົ່ງສັນຍານທັງໝົດໜ້າຈໍຂອງທ່ານໄປຫາ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"ທ່ານກຳລັງສົ່ງສັນຍານທັງໝົດໜ້າຈໍຂອງທ່ານໄປຫາອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"ທ່ານກຳລັງສົ່ງສັນຍານ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ໄປຫາ <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"ທ່ານກຳລັງສົ່ງສັນຍານ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ໄປຫາອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"ທ່ານກຳລັງສົ່ງສັນຍານໄປຫາ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"ທ່ານກຳລັງສົ່ງສັນຍານໄປຫາອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"ຢຸດການສົ່ງສັນຍານ"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"ປິດ"</string>
<string name="issuerecord_title" msgid="286627115110121849">"ຕົວບັນທຶກບັນຫາ"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ກຳລັງປະມວນຜົນການບັນທຶກບັນຫາ"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"ການແຈ້ງເຕືອນທີ່ດຳເນີນຢູ່ສຳລັບເຊດຊັນການຮວບຮວມບັນຫາ"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"ເກີດຂໍ້ຜິດພາດໃນການບັນທຶກບັນຫາ"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"ເກີດຂໍ້ຜິດພາດໃນການເລີ່ມຕົ້ນການບັນທຶກບັນຫາ"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"ກຳລັງ​ເບິ່ງ​ເຕັມ​​ຈໍ"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"ເພື່ອອອກ, ໃຫ້ປັດລົງຈາກເທິງສຸດຂອງໜ້າຈໍຂອງທ່ານ"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"ເຂົ້າໃຈແລ້ວ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ກັບຄືນ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ໜ້າທຳອິດ"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອສືບຕໍ່."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ປົດລັອກດ້ວຍໃບໜ້າແລ້ວ. ແຕະເພື່ອສືບຕໍ່."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ຍົກເລີກການພິສູດຢືນຢັນ"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ຕົວເລືອກເພີ່ມເຕີມ"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"ພາບພັກໜ້າຈໍ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"ຫ້າມລົບກວນ"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ບັນທຶກແລ້ວ"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ຕັດການເຊື່ອມຕໍ່"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ເປີດນຳໃຊ້"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"ເປີດໂດຍອັດຕະໂນມັດໃນມື້ອື່ນ"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ຄຸນສົມບັດຕ່າງໆໃຊ້ Bluetooth ເຊັ່ນ: ການແຊຣ໌ດ່ວນ ແລະ ຊອກຫາອຸປະກອນຂອງຂ້ອຍ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ຈະເປີດມື້ອື່ນເຊົ້າ"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ແບ່ງປັນສຽງ"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ເພີ່ມວິດເຈັດເພີ່ມເຕີມ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ກົດຄ້າງໄວ້ເພື່ອປັບແຕ່ງວິດເຈັດ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ປັບແຕ່ງວິດເຈັດ"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ປົດລັອກເພື່ອປັບແຕ່ງວິດເຈັດ"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ໄອຄອນແອັບສຳລັບວິດເຈັດທີ່ຖືກປິດການນຳໃຊ້"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ກຳລັງຕິດຕັ້ງໄອຄອນແອັບສຳລັບວິດເຈັດ"</string>
<string name="edit_widget" msgid="9030848101135393954">"ແກ້ໄຂວິດເຈັດ"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ເລືອກວິດເຈັດ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ລຶບວິດເຈັດອອກ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ວາງວິດເຈັດທີ່ເລືອກ"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"ວິດເຈັດໃນໜ້າຈໍລັອກ"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"ທຸກຄົນສາມາດເບິ່ງວິດເຈັດຢູ່ໜ້າຈໍລັອກຂອງທ່ານໄດ້, ເຖິງແມ່ນວ່າແທັບເລັດຂອງທ່ານຈະລັອກຢູ່ກໍຕາມ."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ວິດເຈັດໃນໜ້າຈໍລັອກ"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ເພື່ອເປີດແອັບໂດຍໃຊ້ວິດເຈັດ, ທ່ານຈະຕ້ອງຢັ້ງຢືນວ່າແມ່ນທ່ານ. ນອກຈາກນັ້ນ, ກະລຸນາຮັບຊາບວ່າທຸກຄົນສາມາດເບິ່ງຂໍ້ມູນດັ່ງກ່າວໄດ້, ເຖິງແມ່ນວ່າແທັບເລັດຂອງທ່ານຈະລັອກຢູ່ກໍຕາມ. ວິດເຈັດບາງຢ່າງອາດບໍ່ໄດ້ມີໄວ້ສຳລັບໜ້າຈໍລັອກຂອງທ່ານ ແລະ ອາດບໍ່ປອດໄພທີ່ຈະເພີ່ມໃສ່ບ່ອນນີ້."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ເຂົ້າໃຈແລ້ວ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ສະຫຼັບຜູ້ໃຊ້"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ເມນູແບບດຶງລົງ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ແອັບຯ​ແລະ​ຂໍ້​ມູນ​ທັງ​ໝົດ​ໃນ​ເຊດ​ຊັນ​ນີ້​ຈະ​ຖືກ​ລຶບ​ອອກ."</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ຄ່າເລີ່ມຕົ້ນ"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"ອັດຕະໂນມັດ"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"ບໍ່ມີສຽງ ຫຼື ການສັ່ນເຕືອນ"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ບໍ່ມີສຽງ ຫຼື ການສັ່ນເຕືອນ ແລະ ປາກົດຢູ່ທາງລຸ່ມຂອງພາກສ່ວນການສົນທະນາ"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"ອາດສົ່ງສຽງ ຫຼື ສັ່ນເຕືອນໂດຍອ້າງອີງຈາກການຕັ້ງຄ່າອຸປະກອນ"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ອາດສົ່ງສຽງ ຫຼື ສັ່ນເຕືອນໂດຍອ້າງອີງຈາກການຕັ້ງຄ່າອຸປະກອນ. ການສົນທະນາຈາກ <xliff:g id="APP_NAME">%1$s</xliff:g> ຈະເປັນ bubble ຕາມຄ່າເລີ່ມຕົ້ນ."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ໃຫ້ລະບົບກຳນົດວ່າການແຈ້ງເຕືອນນິ້ຄວນມີສຽງ ຫຼື ສັ່ນເຕືອນຫຼືບໍ່"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1351,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"ໃຊ້ຢູ່ໂດຍ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ໃຊ້ຫຼ້າສຸດໂດຍ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ລະບົບ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ການຄວບຄຸມລະບົບ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ແອັບລະບົບ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ການເຮັດຫຼາຍໜ້າວຽກພ້ອມກັນ"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ແອັບຫຼ້າສຸດ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ແບ່ງໜ້າຈໍ"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ອິນພຸດ"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ທາງລັດແອັບ"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ການຊ່ວຍເຂົ້າເຖິງ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ຄີລັດ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ທາງລັດການຊອກຫາ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ໄອຄອນຫຍໍ້ລົງ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ໄອຄອນຂະຫຍາຍ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ຫຼື"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"ທ່າທາງສຳລັບກັບຄືນ"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"ທ່າທາງສຳລັບໜ້າຫຼັກ"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"ປຸ່ມຄຳສັ່ງ"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ແລ້ວໆ"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"ດີຫຼາຍ!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ກັບຄືນ"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ເພື່ອກັບຄືນ, ໃຫ້ໃຊ້ 3 ນິ້ວປັດຊ້າຍ ຫຼື ຂວາບ່ອນໃດກໍໄດ້ເທິງແຜ່ນສໍາຜັດ."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ແຜ່ນສໍາຜັດສະແດງພາບ 3 ນິ້ວເລື່ອນໄປທາງຂວາ ແລະ ຊ້າຍ"</string>
@@ -1374,4 +1379,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"ລະດັບທີ %1$d ຈາກ %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ການຄວບຄຸມເຮືອນ"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"ເຂົ້າເຖິງການຄວບຄຸມເຮືອນຂອງທ່ານໄດ້ຢ່າງວ່ອງໄວຢູ່ພາບພັກໜ້າຈໍ"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
index 9386e00af195..f33514af191f 100644
--- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"ປິດ"</item>
<item msgid="4875147066469902392">"ເປີດ"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
<item msgid="5044688398303285224">"ປິດ"</item>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 7f8da471e9a1..a395f2d2e4b9 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ aptiko šią ekrano kopiją."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ ir kitos atidarytos programos aptiko šią ekrano kopiją."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pridėti prie užrašo"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Įtraukti nuorodą"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Ekrano vaizdo įrašytuvas"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Apdorojam. ekrano vaizdo įraš."</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Šiuo metu rodomas ekrano įrašymo sesijos pranešimas"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Palieskite, kad peržiūrėtumėte"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Išsaugant ekrano įrašą įvyko klaida"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pradedant ekrano vaizdo įrašymą iškilo problema"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Programos (&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;) turinio įrašymas bus sustabdytas."</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Sustabdyti įrašymą"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Bendrinamas ekranas"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Nebebendrinti ekrano?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Programos (&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;) turinio bendrinimas bus sustabdytas."</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Nebebendrinti"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Perduodamas ekranas"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Sustabdyti perdavimą?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Programos (&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;) turinio perdavimas bus sustabdytas."</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Sustabdyti perdavimą"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Uždaryti"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Problemų įrašytuvas"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Apdorojamas problemos įrašas"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Šiuo metu rodomas problemos duomenų rinkimo seanso pranešimas"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Išsaugant problemos įrašą įvyko klaida"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Pradedant problemos įrašą įvyko klaida"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Peržiūrima viso ekrano režimu"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Jei norite išeiti, perbraukite žemyn nuo ekrano viršaus"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Supratau"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Atgal"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Pagrindinis"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Atrakinta pagal veidą. Paspauskite, jei norite tęsti."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Veidas atpažintas. Paspauskite, jei norite tęsti."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Veidas atpažintas. Tęskite paspaudę atrakinimo piktogramą."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Atrakinta pagal veidą. Palieskite ir tęskite."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikuota"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Atšaukti autentifikavimą"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Daugiau parinkčių"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Ekrano užsklanda"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Eternetas"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Netrukdymo režimas"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nėra pasiekiamų susietų įrenginių"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Palieskite, kad prijungtumėte ar atjungtumėte įrenginį"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Išsaugota"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"atjungti"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"suaktyvinti"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automatiškai įjungti rytoj"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Tokioms funkcijoms kaip „Spartusis bendrinimas“ ir „Rasti įrenginį“ naudojamas „Bluetooth“ ryšys"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"„Bluetooth“ ryšys bus įjungtas rytoj ryte"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Bendrinti garsą"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pridėkite daugiau valdiklių"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Ilgai paspauskite, kad tinkintumėte valdiklius"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tinkinti valdiklius"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Atrakinkite, kad galėtumėte tinkinti valdiklius"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Išjungto valdiklio programos piktograma"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Įdiegiamo valdiklio programos piktograma"</string>
<string name="edit_widget" msgid="9030848101135393954">"Redaguoti valdiklį"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pasirinkite valdiklį"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"pašalinti valdiklį"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"padėti pasirinktą valdiklį"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Užrakinimo ekrano valdikliai"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Kad galėtumėte atidaryti programą naudodami valdiklį, turėsite patvirtinti savo tapatybę. Be to, atminkite, kad bet kas gali peržiūrėti valdiklius net tada, kai planšetinis kompiuteris užrakintas. Kai kurie valdikliai gali būti neskirti jūsų užrakinimo ekranui ir gali būti nesaugu juos čia pridėti."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Supratau"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Perjungti naudotoją"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"išplečiamasis meniu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bus ištrintos visos šios sesijos programos ir duomenys."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Numatytasis"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatinis"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Neskamba ir nevibruoja"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Neskamba, nevibruoja ir rodoma apatinėje pokalbių skilties dalyje"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Gali skambėti arba vibruoti, atsižvelgiant į įrenginio nustatymus"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Gali skambėti arba vibruoti, atsižvelgiant į įrenginio nustatymus. Pokalbiai iš „<xliff:g id="APP_NAME">%1$s</xliff:g>“ debesėlio pagal numatytuosius nustatymus."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Nustatykite, kad sistema aptiktų, ar šis pranešimas turi skambėti, ar vibruoti"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Ankstesnis puslapis"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Tolesnis puslapis"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Ištrinti"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Pagrindinis"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Baigti"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Įterpti"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Naudoja <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Neseniai naudojo „<xliff:g id="APP_NAME">%1$s</xliff:g>“ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemos valdikliai"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemos programos"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Kelių užduočių atlikimas"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Naujausios programos"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Išskaidyto ekrano režimas"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Įvestis"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Programos šaukiniai"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pritaikomumas"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Spartieji klavišai"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Paieškos šaukiniai"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sutraukimo piktograma"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Išskleidimo piktograma"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"arba"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Grįžimo atgal gestas"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Pagrindinio ekrano gestas"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Veiksmų klavišas"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Atlikta"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Puiku!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Grįžti"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Jei norite grįžti, trimis pirštais perbraukite kairėn arba dešinėn bet kurioje jutiklinės dalies vietoje."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Jutiklinė dalis, kurioje rodomi trys dešinėn ir kairėn judantys pirštai"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d lygis iš %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Namų sistemos valdymas"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Pasiekite namų sistemos valdymą ekrano užsklandoje"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
index c975e7e3cc80..30584f7ef681 100644
--- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Išjungta"</item>
<item msgid="4875147066469902392">"Įjungta"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nepasiekiama"</item>
<item msgid="5044688398303285224">"Išjungta"</item>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 7121eba8a74d..3f54b4e5d6d9 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> konstatēja, ka tika veikts ekrānuzņēmums."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> un citas atvērtas lietotnes konstatēja, ka tika veikts ekrānuzņēmums."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pievienot piezīmei"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Iekļaut saiti"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Ekrāna ierakstītājs"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekrāna ieraksta apstrāde"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Aktīvs paziņojums par ekrāna ierakstīšanas sesiju"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Pieskarieties, lai skatītu"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Saglabājot ekrāna ierakstu, radās kļūda."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Sākot ierakstīt ekrāna saturu, radās kļūda."</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Tiks pārtraukta lietotnes &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; satura ierakstīšana"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Apturēt ierakstīšanu"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Notiek ekrāna kopīgošana"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vai apturēt ekrāna kopīgošanu?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Tiks pārtraukta lietotnes &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; satura kopīgošana"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Apturēt kopīgošanu"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Notiek ekrāna apraide"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vai pārtraukt apraidi?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Tiks pārtraukta lietotnes &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; satura apraide"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Apturēt apraidi"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Aizvērt"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Problēmu ierakstītājs"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Apstrādā problēmas ierakstu"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Aktīvs paziņojums par problēmu vākšanas sesiju"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Saglabājot problēmas ierakstu, radās kļūda."</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Sākot problēmas ierakstīšanu, radās kļūda."</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Skatīšanās pilnekrāna režīmā"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Lai izietu, velciet lejup no ekrāna augšdaļas."</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Labi"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Atpakaļ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Sākums"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ierīce atbloķēta ar seju. Nospiediet, lai turpinātu."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Seja atpazīta. Nospiediet, lai turpinātu."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Seja atpazīta. Lai turpinātu, nospiediet atbloķēšanas ikonu."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Ierīce atbloķēta pēc sejas. Pieskarieties, lai turpinātu."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikācija veikta"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Atcelt autentificēšanu"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Citas opcijas"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Ekrānsaudzētājs"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Tīkls Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Režīms “Netraucēt”"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nav pieejama neviena pārī savienota ierīce."</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Lai pievienotu vai atvienotu kādu ierīci, pieskarieties."</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saglabāta"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"atvienot"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivizēt"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automātiski ieslēgt rīt"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Tādas funkcijas kā “Ātrā kopīgošana” un “Atrast ierīci” izmanto Bluetooth savienojumu"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth savienojums tiks ieslēgts rīt no rīta"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Kopīgot audio"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pievienot citus logrīkus"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nospiediet un turiet, lai pielāgotu logrīkus."</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pielāgot logrīkus"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Atbloķējiet, lai pielāgotu logrīkus"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Lietotnes ikona atspējotam logrīkam"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Tiek instalēta lietotnes ikona logrīkam."</string>
<string name="edit_widget" msgid="9030848101135393954">"Rediģēt logrīku"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"atlasīt logrīku"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"noņemt logrīku"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"novietot atlasīto logrīku"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Bloķēšanas ekrāna logrīki"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Lai atvērtu lietotni, izmantojot logrīku, jums būs jāapstiprina sava identitāte. Turklāt ņemiet vērā, ka ikviens var skatīt logrīkus, pat ja planšetdators ir bloķēts. Iespējams, daži logrīki nav paredzēti izmantošanai bloķēšanas ekrānā, un var nebūt droši tos šeit pievienot."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Labi"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mainīt lietotāju"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"novelkamā izvēlne"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tiks dzēstas visas šīs sesijas lietotnes un dati."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Noklusējums"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automātiski"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Nav skaņas signāla vai vibrācijas"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Nav skaņas signāla vai vibrācijas, kā arī atrodas tālāk sarunu sadaļā"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Atkarībā no iestatījumiem var zvanīt vai vibrēt"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Atkarībā no ierīces iestatījumiem var zvanīt vai vibrēt. Sarunas no lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> pēc noklusējuma tiek parādītas burbulī."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Iestatiet, lai sistēma noteiktu, vai šim paziņojumam būs skaņa vai vibrācija"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Lapa uz augšu"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Lapa uz leju"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Dzēšanas taustiņš"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Sākumvietas taustiņš"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Beigvietas taustiņš"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Ievietošanas taustiņš"</string>
@@ -794,7 +812,7 @@
<string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nav atrasti"</string>
<string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"Sistēma"</string>
<string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Ievade"</string>
- <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Atvērtās"</string>
+ <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Atvērtās lietotnes"</string>
<string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Pašreizējā"</string>
<string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Tiek rādīti meklēšanas rezultāti"</string>
<string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Tiek rādīti sistēmas īsinājumtaustiņi"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"To izmanto lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nesen to izmantoja lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistēma"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistēmas vadīklas"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistēmas lietotnes"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Vairākuzdevumu režīms"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Pēdējās izmantotās lietotnes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ekrāna sadalīšana"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ievade"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Lietotņu saīsnes"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pieejamība"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Īsinājumtaustiņi"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Meklēšanas saīsnes"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sakļaušanas ikona"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Izvēršanas ikona"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"vai"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Žests pāriešanai atpakaļ"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Žests pāriešanai uz sākumu"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Darbību taustiņš"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gatavs"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Lieliski!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atpakaļ"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Lai pārietu atpakaļ, ar trim pirkstiem velciet pa kreisi vai pa labi jebkurā vietā uz skārienpaliktņa"</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Attēls ar skārienpaliktni, uz kura trīs pirksti kustas pa labi un pa kreisi"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Līmenis numur %1$d, kopā ir %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Mājas kontrolierīces"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Ātra piekļuve mājas kontrolierīcēm ekrānsaudzētājā"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
index c65a1d429492..8d23ef11d18c 100644
--- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Izslēgts"</item>
<item msgid="4875147066469902392">"Ieslēgts"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nav pieejams"</item>
<item msgid="5044688398303285224">"Izslēgts"</item>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 18b727d7742c..6eaf8b9883bc 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ја откри оваа слика од екранот."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и други отворени апликации ја открија оваа слика од екранот."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додај во белешка"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Опфати линк"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Снимач на екран"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Се обработува снимка од екран"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Тековно известување за сесија за снимање на екранот"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Допрете за прегледување"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при зачувувањето на снимката од екранот"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при почетокот на снимањето на екранот"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ќе го сопрете снимањето на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Сопри го снимањето"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Се споделува екранот"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Да се сопре споделувањето на екранот?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ќе го сопрете споделувањето на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Сопри го споделувањето"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Се емитува екранот"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Да се сопре емитувањето?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ќе го сопрете емитувањето на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Сопри го емитувањето"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Затвори"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Проблем со „Диктафон“"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Се обработува проб. со снимање"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Тековно известување за сесија за проблем со прибирање"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Грешка при зачувување на проблемот со снимање"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Грешка при започнување на проблемот со снимање"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Се прикажува на цел екран"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"За да излезете, повлечете надолу од горниот дел на екранот"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Сфатив"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Почетна страница"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отклучено со лик. Притиснете за да продолжите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето е препознаено. Притиснете за да продолжите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето е препознаено. Притиснете ја иконата за отклучување за да продолжите."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Отклучено со лик. Допрете за да продолжите."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Проверена"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Откажување автентикација"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Повеќе опции"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Штедач на екран"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Етернет"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не вознемирувај"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Зачувано"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"прекини врска"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активирај"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Автоматски вклучи го утре"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Функциите како „Брзо споделување“ и „Најди го мојот уред“ користат Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ќе се вклучи утре наутро"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Споделувај аудио"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додајте повеќе виџети"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Притиснете долго за да ги приспособите виџетите"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Приспособете ги виџетите"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Отклучете за да ги приспособите виџетите"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона за апликација за оневозможен виџет"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Икона за апликација за виџет што се инсталира"</string>
<string name="edit_widget" msgid="9030848101135393954">"Изменување виџети"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"изберете виџет"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"отстранете го виџетот"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"поставете го избраниот виџет"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виџети на заклучен екран"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"За да отворите апликација со помош на виџет, ќе треба да потврдите дека сте вие. Покрај тоа, имајте предвид дека секој може да ги гледа виџетите, дури и кога вашиот таблет е заклучен. Некои виџети можеби не се наменети за вашиот заклучен екран, па можеби не е безбедно да се додадат овде."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Сфатив"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Промени го корисникот"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"паѓачко мени"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијава ќе се избришат."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Започни сега"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нема известувања"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Нема нови известувања"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивни известув.: вклучено"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Уредот сега ја намалува јачината на звукот и ги намалува скокачките прозорци на екранот до 2 мин. кога добивате многу известувања за кратко време."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Исклучи"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Отклучете за да ги видите старите известувања"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Родителот управува со уредов"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацијата е сопственик на уредов и може да го следи мрежниот сообраќај"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Стандардно"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Автоматски"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звук или вибрации"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звук или вибрации и се појавува подолу во делот со разговори"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Може да ѕвони или да вибрира во зависност од поставките за уредот"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Може да ѕвони или да вибрира во зависност од поставките за уредот. Стандардно, разговорите од <xliff:g id="APP_NAME">%1$s</xliff:g> се во балончиња."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Дозволете системот да определи дали известувањево треба да испушти звук или да вибрира"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Страница нагоре"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Страница надолу"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Избриши"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home-копче"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Крај"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Вметни"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Се користи од <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Неодамна користено од <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Систем"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системски контроли"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системски апликации"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Мултитаскинг"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Неодамнешни апликации"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Поделен екран"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Внесување"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Кратенки за апликации"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Пристапност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Кратенки од тастатура"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Кратенки за пребарување"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за собирање"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за проширување"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Движење за назад"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Движење за почетен екран"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Копче за дејство"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Одлично сторено!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"За да се вратите назад, повлечете налево или надесно со три прста каде било на допирната подлога."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Допирната подлога покажува три прста што се движат десно и лево"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Екранот на уредот покажува анимација за движење назад"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Осветлување на тастатура"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d од %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Контроли за домот"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Контролите за домот како штедач на екран"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
index a8d96950b6f8..08cdc090a4bf 100644
--- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Исклучено"</item>
<item msgid="4875147066469902392">"Вклучено"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Недостапно"</item>
<item msgid="5044688398303285224">"Исклучено"</item>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index d075bfc8532a..5877d2b3d919 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ഈ സ്ക്രീൻഷോട്ട് തിരിച്ചറിഞ്ഞു."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്ന ആപ്പും തുറന്നിരിക്കുന്ന മറ്റ് ആപ്പും ഈ സ്ക്രീൻഷോട്ട് തിരിച്ചറിഞ്ഞു."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"കുറിപ്പിലേക്ക് ചേർക്കുക"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"ലിങ്ക് ഉൾപ്പെടുത്തുക"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"സ്ക്രീൻ റെക്കോർഡർ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"സ്ക്രീൻ റെക്കോർഡിംഗ് പ്രോസസുചെയ്യുന്നു"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ഒരു സ്ക്രീൻ റെക്കോർഡിംഗ് സെഷനായി നിലവിലുള്ള അറിയിപ്പ്"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"കാണാൻ ടാപ്പ് ചെയ്യുക"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"സ്ക്രീൻ റെക്കോർഡിംഗ് സംരക്ഷിക്കുന്നതിൽ പിശക്"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"സ്ക്രീൻ റെക്കോർഡിംഗ് ആരംഭിക്കുന്നതിൽ പിശക്"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; റെക്കോർഡ് ചെയ്യുന്നത് നിങ്ങൾ അവസാനിപ്പിക്കും"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; പങ്കിടുന്നത് നിങ്ങൾ അവസാനിപ്പിക്കും"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; കാസ്റ്റ് ചെയ്യുന്നത് നിങ്ങൾ അവസാനിപ്പിക്കും"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"റെക്കോർഡിംഗ് നിർത്തണോ?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"നിങ്ങൾ ഇപ്പോൾ മുഴുവൻ സ്ക്രീനും റെക്കോർഡ് ചെയ്യുകയാണ്"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"നിങ്ങൾ ഇപ്പോൾ <xliff:g id="APP_NAME">%1$s</xliff:g> റെക്കോർഡ് ചെയ്യുകയാണ്"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"റെക്കോർഡിംഗ് നിർത്തുക"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"സ്‌ക്രീൻ പങ്കിടുന്നു"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"സ്‌ക്രീൻ പങ്കിടുന്നത് നിർത്തണോ?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"നിങ്ങൾ ഇപ്പോൾ മുഴുവൻ സ്ക്രീനും <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> എന്നതുമായി പങ്കിടുകയാണ്"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"നിങ്ങൾ ഇപ്പോൾ മുഴുവൻ സ്ക്രീനും ഒരു ആപ്പുമായി പങ്കിടുകയാണ്"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"നിങ്ങൾ ഇപ്പോൾ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> പങ്കിടുകയാണ്"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"നിങ്ങൾ നിലവിൽ ഒരു ആപ്പ് പങ്കിടുകയാണ്"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"പങ്കിടൽ നിർത്തുക"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"സ്‌ക്രീൻ കാസ്‌റ്റ് ചെയ്യുന്നു"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"കാസ്റ്റ് ചെയ്യുന്നത് അവസാനിപ്പിക്കണോ?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതിലേക്ക് നിങ്ങളുടെ മുഴുവൻ സ്ക്രീനും ഇപ്പോൾ കാസ്റ്റ് ചെയ്യുകയാണ്"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"സമീപമുള്ള ഉപകരണത്തിലേക്ക് നിങ്ങളുടെ മുഴുവൻ സ്ക്രീനും ഇപ്പോൾ കാസ്റ്റ് ചെയ്യുകയാണ്"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> എന്നതിലേക്ക് നിങ്ങൾ ഇപ്പോൾ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> കാസ്റ്റ് ചെയ്യുകയാണ്"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"സമീപമുള്ള ഉപകരണത്തിലേക്ക് നിങ്ങൾ ഇപ്പോൾ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> കാസ്റ്റ് ചെയ്യുകയാണ്"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതിലേക്ക് നിങ്ങൾ ഇപ്പോൾ കാസ്റ്റ് ചെയ്യുകയാണ്"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"സമീപമുള്ള ഉപകരണത്തിലേക്ക് നിങ്ങൾ ഇപ്പോൾ കാസ്റ്റ് ചെയ്യുകയാണ്"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"കാസ്റ്റ് ചെയ്യുന്നത് നിർത്തുക"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"അടയ്ക്കുക"</string>
<string name="issuerecord_title" msgid="286627115110121849">"പ്രശ്‌ന റെക്കോർഡർ"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"പ്രശ്‌ന റെക്കോർഡിംഗ് പ്രോസസ് ചെയ്യുന്നു"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"ഒരു പ്രശ്‌ന ശേഖരണ സെഷന്റെ ഓൺ‌ഗോയിംഗ് അറിയിപ്പ്"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"പ്രശ്‌ന റെക്കോർഡിംഗ് സംരക്ഷിക്കുന്നതിൽ പിശക്"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"പ്രശ്‌ന റെക്കോർഡിംഗ് ആരംഭിക്കുന്നതിൽ പിശക്"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"പൂർണ്ണ സ്‌ക്രീനിൽ കാണുന്നു"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"പുറത്ത് കടക്കാൻ, സ്‌ക്രീനിന്റെ മുകളിൽ നിന്ന് താഴോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"മനസ്സിലായി"</string>
<string name="accessibility_back" msgid="6530104400086152611">"മടങ്ങുക"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ഹോം"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുടരാൻ അമർത്തുക."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അമർത്തുക."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"മുഖം വഴി അൺലോക്കുചെയ്തു. തുടരാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"പരിശോധിച്ചുറപ്പിച്ചു"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"പരിശോധിച്ചുറപ്പിക്കൽ റദ്ദാക്കുക"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"കൂടുതൽ ഓപ്‌ഷനുകൾ"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"സ്ക്രീൻ സേവർ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ഇതർനെറ്റ്"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"ശല്യപ്പെടുത്തരുത്"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"സംരക്ഷിച്ചു"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"വിച്ഛേദിക്കുക"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"സജീവമാക്കുക"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"നാളെ സ്വയമേവ ഓണാക്കുക"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ക്വിക്ക് ഷെയർ, Find My Device പോലുള്ള ഫീച്ചറുകൾ Bluetooth ഉപയോഗിക്കുന്നു"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth നാളെ രാവിലെ ഓണാകും"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ഓഡിയോ പങ്കിടുക"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"കൂടുതൽ വിജറ്റുകൾ ചേർക്കുക"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കാൻ ദീർഘനേരം അമർത്തുക"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കുക"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കാൻ അൺലോക്ക് ചെയ്യുക"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"പ്രവർത്തനരഹിതമാക്കിയ വിജറ്റിനുള്ള ആപ്പ് ഐക്കൺ"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"വിജറ്റിനുള്ള ആപ്പ് ഐക്കൺ ഇൻസ്റ്റാൾ ചെയ്തു"</string>
<string name="edit_widget" msgid="9030848101135393954">"വിജറ്റ് എഡിറ്റ് ചെയ്യുക"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"വിജറ്റ് തിരഞ്ഞെടുക്കുക"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"വിജറ്റ് നീക്കം ചെയ്യുക"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"തിരഞ്ഞെടുത്ത വിജറ്റ് നൽകുക"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"ലോക്ക് സ്‌ക്രീൻ വിജറ്റുകൾ"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"ടാബ്‌ലെറ്റ് ലോക്കാണെങ്കിൽ പോലും ലോക്ക് സ്ക്രീനിൽ ആർക്കും വിജറ്റുകൾ കാണാം."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ലോക്ക് സ്‌ക്രീൻ വിജറ്റുകൾ"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"വിജറ്റ് ഉപയോഗിച്ച് ഒരു ആപ്പ് തുറക്കാൻ, ഇത് നിങ്ങൾ തന്നെയാണെന്ന് പരിശോധിച്ചുറപ്പിക്കേണ്ടതുണ്ട്. നിങ്ങളുടെ ടാബ്‌ലെറ്റ് ലോക്കായിരിക്കുമ്പോഴും എല്ലാവർക്കും അത് കാണാനാകുമെന്നതും ഓർക്കുക. ചില വിജറ്റുകൾ നിങ്ങളുടെ ലോക്ക് സ്‌ക്രീനിന് ഉള്ളതായിരിക്കില്ല, അവ ഇവിടെ ചേർക്കുന്നത് സുരക്ഷിതവുമായിരിക്കില്ല."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"മനസ്സിലായി"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ഉപയോക്താവ് മാറുക"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"പുൾഡൗൺ മെനു"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ഡിഫോൾട്ട്"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"സ്വയമേവ"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"ശബ്ദമോ വൈബ്രേഷനോ ഇല്ല"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ശബ്‌ദമോ വൈബ്രേഷനോ ഇല്ല, സംഭാഷണ വിഭാഗത്തിന് താഴെയായി ദൃശ്യമാകും"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"ഉപകരണ ക്രമീകരണം അടിസ്ഥാനമാക്കി റിംഗ് ചെയ്യും അല്ലെങ്കിൽ വൈബ്രേറ്റ് ചെയ്യും"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ഉപകരണ ക്രമീകരണം അടിസ്ഥാനമാക്കി റിംഗ് ചെയ്യും അല്ലെങ്കിൽ വൈബ്രേറ്റ് ചെയ്യും. <xliff:g id="APP_NAME">%1$s</xliff:g> എന്ന ആപ്പിൽ നിന്നുള്ള സംഭാഷണങ്ങൾ ഡിഫോൾട്ടായി ബബിൾ ചെയ്യുന്നു."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ഈ അറിയിപ്പ് വരുമ്പോൾ ശബ്‌ദിക്കുകയാണോ വൈബ്രേറ്റ് ചെയ്യുകയാണോ വേണ്ടതെന്ന് നിർണ്ണയിക്കാൻ സിസ്‌റ്റത്തെ അനുവദിക്കുക"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"പേജ് അപ്പ്"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"പേജ് ഡൗൺ"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"ഡിലീറ്റ്"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"ഹോം"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"എൻഡ്"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"ഇൻസേർട്ട്"</string>
@@ -1349,23 +1351,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ഉപയോഗിക്കുന്നു"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) അടുത്തിടെ ഉപയോഗിച്ചു"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"സിസ്റ്റം"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"സിസ്‌റ്റം നിയന്ത്രണങ്ങൾ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"സിസ്‌റ്റം ആപ്പുകൾ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"മൾട്ടിടാസ്‌കിംഗ്"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"അടുത്തിടെ ഉപയോഗിച്ച ആപ്പുകൾ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"സ്‌ക്രീൻ വിഭജന മോഡ്"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ഇൻപുട്ട്"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ആപ്പ് കുറുക്കുവഴികൾ"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"നിലവിലെ ആപ്പ്"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ഉപയോഗസഹായി"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"കീബോഡ് കുറുക്കുവഴികൾ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"തിരയൽ കുറുക്കുവഴികൾ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ചുരുക്കൽ ഐക്കൺ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"വികസിപ്പിക്കൽ ഐക്കൺ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"അല്ലെങ്കിൽ"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"\'മടങ്ങുക\' ജെസ്ച്ചർ"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"ഹോം ജെസ്‌ച്ചർ"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"ആക്ഷൻ കീ"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"പൂർത്തിയായി"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"കൊള്ളാം!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"മടങ്ങുക"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"തിരികെ പോകാൻ, ടച്ച്പാഡിൽ എവിടെയെങ്കിലും മൂന്ന് വിരലുകൾ ഉപയോഗിച്ച് ഇടത്തേക്കോ വലത്തേക്കോ സ്വൈപ്പ് ചെയ്യുക."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"വലത്തേക്കും ഇടത്തേക്കും ചലിക്കുന്ന മൂന്ന് വിരലുകൾ കാണിക്കുന്ന ടച്ച്പാഡ്"</string>
@@ -1374,4 +1378,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-ൽ %1$d-ാമത്തെ ലെവൽ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ഹോം കൺട്രോളുകൾ"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"സ്‌ക്രീൻസേവറായി ഹോം കൺട്രോളുകൾ പെട്ടെന്ന് ആക്‌സസ് ചെയ്യൂ"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
index 609fdde3f5de..5999e3cfcb8f 100644
--- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"ഓഫാണ്"</item>
<item msgid="4875147066469902392">"ഓണാണ്"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ലഭ്യമല്ല"</item>
<item msgid="5044688398303285224">"ഓഫാണ്"</item>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 899a9462dad5..2e0115f5c4e6 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> энэ дэлгэцийн агшныг илрүүлсэн."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> болон бусад нээлттэй апп энэ дэлгэцийн агшныг илрүүлсэн."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Тэмдэглэлд нэмэх"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Холбоосыг оруулах"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Дэлгэцийн үйлдэл бичигч"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Дэлгэц бичлэг боловсруулж байна"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Дэлгэц бичих горимын үргэлжилж буй мэдэгдэл"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Харахын тулд товшино уу"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Дэлгэцийн бичлэгийг хадгалахад алдаа гарлаа"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Дэлгэцийн бичлэгийг эхлүүлэхэд алдаа гарлаа"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Та &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-г бичихээ болино"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Бичихийг зогсоох"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Дэлгэцийг хуваалцаж байна"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Дэлгэцийг хуваалцахыг зогсоох уу?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Та &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-г хуваалцахаа болино"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Хуваалцахыг зогсоох"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Дэлгэцийг дамжуулж байна"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Дамжуулахaa болих уу?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Та &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-г дамжуулахаа болино"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Дамжуулахыг зогсоох"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Хаах"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Асуудал бичигч"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Асуудлын бичлэгийг боловсруулж байна"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Асуудал цуглуулах харилцан үйлдлийн үргэлжилж буй мэдэгдэл"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Асуудлын бичлэгийг хадгалахад алдаа гарлаа"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Асуудлын бичлэгийг эхлүүлэхэд алдаа гарлаа"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Бүтэн дэлгэцээр үзэж байна"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Гарахын тулд дэлгэцийнхээ дээд талаас доош шударна уу"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Ойлголоо"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Буцах"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Гэрийн"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Царайг таньсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Царайг таньсан. Үргэлжлүүлэх бол түгжээг тайлах дүрсийг дар."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд товшино уу."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Баталгаажуулагдсан"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Баталгаажуулалтыг цуцлах"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Бусад сонголт"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Дэлгэц амраагч"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Этернет"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Бүү саад бол"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Хадгалсан"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"салгах"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"идэвхжүүлэх"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Маргааш автоматаар асаах"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Түргэн хуваалцах, Миний төхөөрөмжийг олох зэрэг онцлогууд Bluetooth-г ашигладаг"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth-г маргааш өглөө асаана"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Аудио хуваалцах"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Илүү олон виджет нэмэх"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджетүүдийг өөрчлөхийн тулд удаан дарна уу"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджетүүдийг өөрчлөх"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Виджетийг өөрчлөхийн тулд түгжээг тайлна уу"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Идэвхгүй болгосон виджетийн аппын дүрс тэмдэг"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Виджет суулгах явцын аппын дүрс тэмдэг"</string>
<string name="edit_widget" msgid="9030848101135393954">"Виджетийг засах"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет сонгох"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетийг хасах"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"сонгосон виджетийг байрлуулах"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Түгжээтэй дэлгэцийн виджет"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Виджет ашиглан аппыг нээхийн тулд та өөрийгөө мөн болохыг баталгаажуулах шаардлагатай болно. Мөн таны таблет түгжээтэй байсан ч тэдгээрийг дурын хүн үзэж болохыг санаарай. Зарим виджет таны түгжээтэй дэлгэцэд зориулагдаагүй байж магадгүй ба энд нэмэхэд аюултай байж болзошгүй."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ойлголоо"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Хэрэглэгчийг сэлгэх"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"эвхмэл цэс"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ харилцан үйлдлийн бүх апп болон дата устах болно."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Одоо эхлүүлэх"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Мэдэгдэл байхгүй"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Шинэ мэдэгдэл алга"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Дасан зохицох мэдэгдэл ассан"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Таныг богино хугацаанд олон мэдэгдэл авахад таны төхөөрөмж одоо дууны түвшнийг багасгаж, дэлгэц дээрх попапыг хоёр хүртэлх минутын турш багасгана."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Унтраах"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Хуучин мэдэгдлийг харах бол түгжээг тайл"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Энэ төхөөрөмжийг таны эцэг эх удирддаг"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Танай байгууллага энэ төхөөрөмжийг эзэмшдэг бөгөөд сүлжээний ачааллыг хянаж болно"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Өгөгдмөл"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Автомат"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Дуу эсвэл чичиргээ байхгүй"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Дуу эсвэл чичиргээ байхгүй бөгөөд харилцан ярианы хэсгийн доод талд харагдана"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Төхөөрөмжийн тохиргоонд тулгуурлан хонх дуугаргах эсвэл чичиргэж болзошгүй"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Төхөөрөмжийн тохиргоонд тулгуурлан хонх дуугаргах эсвэл чичиргэж болзошгүй. <xliff:g id="APP_NAME">%1$s</xliff:g>-н харилцан яриаг өгөгдмөлөөр бөмбөлөг болгоно."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Энэ мэдэгдэл дуу гаргах эсвэл чичрэх эсэхийг системээр тодорхойлуулаарай"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Хуудас дээш"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Хуудас доош"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Устгах"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Нүүр хуудас"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Төгсгөл"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Оруулах"</string>
@@ -1210,7 +1225,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нэмэлт мэдээлэл авахын тулд товшино уу"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Сэрүүлэг тавиагүй"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"дэлгэцийн түгжээ оруулах"</string>
- <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Хурууны хээ мэдрэгчид хүрнэ үү. Энэ нь утасны хажуу талын арай богино товчлуур юм"</string>
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Хурууны хээ мэдрэгчид хүрнэ үү. Энэ нь утасны хажуу талын арай богино товч юм"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Хурууны хээ мэдрэгч"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"баталгаажуулах"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"төхөөрөмж оруулах"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ашиглаж байна"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Саяхан <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ашигласан"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Систем"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системийн тохиргоо"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системийн аппууд"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Олон ажил зэрэг хийх"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Саяхны аппууд"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Дэлгэцийг хуваах"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Оролт"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Аппын товчлол"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Хандалт"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Товчлуурын шууд холбоос"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Товчлолууд хайх"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Хураах дүрс тэмдэг"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Дэлгэх дүрс тэмдэг"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"эсвэл"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Буцах зангаа"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Үндсэн нүүрний зангаа"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Тусгай товчлуур"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Болсон"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Үнэхээр сайн ажиллалаа!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Буцах"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Буцаж очихын тулд мэдрэгч самбар дээр гурван хуруугаараа хүссэн газраа зүүн эсвэл баруун тийш шударна уу."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Гурван хуруу баруун болон зүүн тийш хөдөлж буйг харуулсан мэдрэгч самбар"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Буцах зангаанд зориулсан анимацийг харуулсан төхөөрөмжийн дэлгэц"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Гарын арын гэрэл"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-с %1$d-р түвшин"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Гэрийн удирдлага"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Гэрийн удирдлагадаа дэлгэц амраагчаар шуурхай ханд"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
index a3f54541880d..b39457484a47 100644
--- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Унтраалттай"</item>
<item msgid="4875147066469902392">"Асаалттай"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Боломжгүй"</item>
<item msgid="5044688398303285224">"Унтраалттай"</item>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 574463486b13..ed870c7b435d 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ने हा स्क्रीनशॉट डिटेक्ट केला."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> आणि उघडलेल्या इतर अ‍ॅप्सनी हा स्क्रीनशॉट डिटेक्ट केला."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"टीप जोडा"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"लिंकचा समावेश करा"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"स्क्रीन रेकॉर्डर"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रेकॉर्डिंग प्रोसेस सुरू"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रेकॉर्ड सत्रासाठी सुरू असलेली सूचना"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"पाहण्यासाठी टॅप करा"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रीन रेकॉर्डिंग सेव्ह करताना एरर आली"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन रेकॉर्डिंग सुरू करताना एरर आली"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"तुम्ही &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; रेकॉर्ड करणे बंद कराल"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"तुम्ही &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; शेअर करणे बंद कराल"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"तुम्ही &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; कास्ट करणे बंद कराल"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"रेकॉर्डिंग थांबवायचे आहे का?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"तुम्ही सध्या तुमची संपूर्ण स्क्रीन रेकॉर्ड करत आहात"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"तुम्ही सध्या <xliff:g id="APP_NAME">%1$s</xliff:g> रेकॉर्ड करत आहात"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"रेकॉर्ड करणे थांबवा"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रीन शेअर करत आहे"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"स्क्रीन शेअर करणे थांबवायचे आहे का?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"तुम्ही सध्या तुमची संपूर्ण स्क्रीन <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> सह शेअर करत आहात"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"तुम्ही सध्या तुमची संपूर्ण स्क्रीन एका ॲपसह शेअर करत आहात"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"तुम्ही सध्या <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> शेअर करत आहात"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"तुम्ही सध्या एक ॲप शेअर करत आहात"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"शेअर करणे थांबवा"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"स्‍क्रीन कास्‍ट करत आहे"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"कास्ट करणे थांबवायचे आहे का?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"तुम्ही सध्या तुमच्या संपूर्ण स्क्रीनला <xliff:g id="DEVICE_NAME">%1$s</xliff:g> वर कास्ट करत आहात"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"तुम्ही सध्या तुमच्या संपूर्ण स्क्रीनला जवळपासच्या डिव्हाइसवर कास्ट करत आहात"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"तुम्ही सध्या <xliff:g id="DEVICE_NAME">%2$s</xliff:g> वर <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ला कास्ट करत आहात"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"तुम्ही सध्या <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ला जवळपासच्या डिव्हाइसवर कास्ट करत आहात"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"तुम्ही सध्या <xliff:g id="DEVICE_NAME">%1$s</xliff:g> वर कास्ट करत आहात"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"तुम्ही सध्या जवळपासच्या डिव्हाइसवर कास्ट करत आहात"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"कास्ट करणे थांबवा"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"बंद करा"</string>
<string name="issuerecord_title" msgid="286627115110121849">"समस्या रेकॉर्डर"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"प्रक्रियेच्या समस्येचे रेकॉर्डिंग"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"समस्या गोळा करण्याच्या सेशनसाठीची सद्य सूचना"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"समस्येचे रेकॉर्डिंग सेव्ह करताना एरर आली"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"समस्येचे रेकॉर्डिंग सुरू करताना एरर आली"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"पूर्ण स्क्रीन पाहत आहात"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"बाहेर पडण्यासाठी, तुमच्या स्क्रीनच्या सर्वात वरून खाली स्वाइप करा"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"समजले"</string>
<string name="accessibility_back" msgid="6530104400086152611">"मागे"</string>
<string name="accessibility_home" msgid="5430449841237966217">"होम"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहऱ्याने अनलॉक केले आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"चेहऱ्याने अनलॉक केले आहे. सुरू ठेवण्यासाठी टॅप करा."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ऑथेंटिकेशन केलेले"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ऑथेंटिकेशन रद्द करा"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"अधिक पर्याय"</string>
@@ -291,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"स्क्रीन सेव्हर"</string>
<string name="ethernet_label" msgid="2203544727007463351">"इथरनेट"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"व्यत्यय आणू नका"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"प्राधान्य मोड"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ब्लूटूथ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"कोणतेही जोडलेले डिव्हाइसेस उपलब्ध नाहीत"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"डिव्हाइस कनेक्ट किंवा डिस्कनेक्ट करण्यासाठी टॅप करा"</string>
@@ -302,8 +302,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेव्ह केले"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"डिस्कनेक्ट करा"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ॲक्टिव्हेट करा"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"उद्या आपोआप सुरू करा"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक शेअर आणि Find My Device यांसारखी वैशिष्‍ट्ये ब्लूटूथ वापरतात"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ब्लूटूथ उद्या सकाळी सुरू होईल"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ऑडिओ शेअर करा"</string>
@@ -472,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"आणखी विजेट जोडा"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेट कस्टमाइझ करण्यासाठी प्रेस करून ठेवा"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेट कस्टमाइझ करा"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"विजेट कस्टमाइझ करण्यासाठी अनलॉक करा"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"बंद केलेल्या विजेटच्या अ‍ॅपचे आयकन"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"इंस्टॉल होत असलेल्या विजेटसाठी अ‍ॅपचा आयकन"</string>
<string name="edit_widget" msgid="9030848101135393954">"विजेट संपादित करा"</string>
@@ -490,12 +490,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट निवडा"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट काढून टाका"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"निवडलेले विजेट ठेवा"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"लॉक स्‍क्रीन विजेट"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"तुमचा टॅबलेट लॉक केला, तरी कोणीही तुमच्या लॉक स्क्रीनवरील विजेट पाहू शकतो."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लॉक स्‍क्रीन विजेट"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"विजेट वापरून अ‍ॅप उघडण्यासाठी, तुम्हाला हे तुम्हीच असल्याची पडताळणी करावी लागेल. तसेच, लक्षात ठेवा, तुमचा टॅबलेट लॉक असतानादेखील कोणीही ती पाहू शकते. काही विजेट कदाचित तुमच्या लॉक स्‍क्रीनसाठी नाहीत आणि ती इथे जोडणे असुरक्षित असू शकते."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"समजले"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"वापरकर्ता स्विच करा"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनू"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अ‍ॅप्स आणि डेटा हटवला जाईल."</string>
@@ -717,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"डीफॉल्ट"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"ऑटोमॅटिक"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"आवाज किंवा व्हायब्रेशन नाही"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"आवाज किंवा व्हायब्रेशन नाही आणि संभाषण विभागात सर्वात तळाशी दिसते"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"डिव्‍हाइस सेटिंग्जनुसार रिंग किंवा व्हायब्रेट होऊ शकतो"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"डिव्‍हाइस सेटिंग्जनुसार रिंग किंवा व्हायब्रेट होऊ शकतो. <xliff:g id="APP_NAME">%1$s</xliff:g> मधील संभाषणे बाय डीफॉल्ट बबल होतात."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ही सूचना मिळाल्‍यावर आवाज व्‍हावा की व्हायब्रेशन व्‍हावे ते सिस्‍टममध्ये नमूद करा"</string>
@@ -774,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"हटवा"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"एस्केप"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"घाला"</string>
@@ -1349,23 +1350,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) द्वारे वापरले जात आहे"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"अलीकडे <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ने वापरले"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"सिस्टीम"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"सिस्‍टीमची नियंत्रणे"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"सिस्टीम अ‍ॅप्स"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"मल्टिटास्किंग"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"अलीकडील अ‍ॅप्स"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"स्प्लिट स्क्रीन"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"इनपुट"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"अ‍ॅप शॉर्टकट"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"सध्याचे अ‍ॅप"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"अ‍ॅक्सेसिबिलिटी"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शोधण्यासाठी शॉर्टकट"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"कोलॅप्स करा आयकन"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"विस्तार करा आयकन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"किंवा"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"मागे जा जेश्चर"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"होम जेश्चर"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"अ‍ॅक्शन की"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"पूर्ण झाले"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"उत्तम कामगिरी!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"मागे जा"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"मागे जाण्यासाठी, टचपॅडवर कुठेही तीन बोटांनी डावीकडे किंवा उजवीकडे स्‍वाइप करा."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"तीन बोट उजवीकडे आणि डावीकडे हलताना दाखवणारे टचपॅड"</string>
@@ -1374,4 +1377,5 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d पैकी %1$d पातळी"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"स्क्रीनसेव्हर म्हणून होम कंट्रोल झटपट ॲक्सेस करा"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"पहिल्यासारखे करा"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
index 54c320c953d5..fdb1f40b4803 100644
--- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"बंद आहे"</item>
<item msgid="4875147066469902392">"सुरू आहे"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"उपलब्ध नाही"</item>
+ <item msgid="2004750556637773692">"बंद आहे"</item>
+ <item msgid="8968530753931637871">"सुरू आहे"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"उपलब्ध नाही"</item>
<item msgid="5044688398303285224">"बंद आहे"</item>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 802d145a411e..43e97168d687 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> telah mengesan tangkapan skrin ini."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dan apl lain yang dibuka telah mengesan tangkapan skrin ini."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Tambahkan pada nota"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Sertakan pautan"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Perakam Skrin"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses rakaman skrin"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Pemberitahuan breterusan untuk sesi rakaman skrin"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Ketik untuk lihat"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Ralat semasa menyimpan rakaman skrin"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ralat semasa memulakan rakaman skrin"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Anda akan berhenti merakam &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Anda akan berhenti berkongsi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Anda akan berhenti menghantar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Hentikan rakaman?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Anda sedang merakam seluruh skrin anda"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Anda sedang merakam <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Hentikan rakaman"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Berkongsi skrin"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Hentikan perkongsian skrin?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Anda sedang berkongsi seluruh skrin anda dengan <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Anda sedang berkongsi seluruh skrin anda dengan apl"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Anda sedang berkongsi <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Anda sedang berkongsi apl"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Hentikan perkongsian"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Menghantar skrin"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Berhenti menghantar?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Anda sedang menghantar seluruh skrin anda kepada <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Anda sedang menghantar seluruh skrin anda kepada peranti berdekatan"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Anda sedang menghantar <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> kepada <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Anda sedang menghantar <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> kepada peranti berdekatan"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Anda sedang membuat penghantaran kepada <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Anda sedang membuat penghantaran kepada peranti berdekatan"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Hentikan penghantaran"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Tutup"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Perakam Masalah"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Memproses rakaman masalah"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Pemberitahuan sedang berlangsung untuk sesi pengumpulan masalah"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Ralat menyimpan rakaman masalah"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Ralat memulakan rakaman masalah"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Melihat skrin penuh"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Untuk keluar, leret ke bawah daripada bahagian atas skrin anda"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Kembali"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Rumah"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Dibuka kunci dengan wajah. Tekan untuk meneruskan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dicam. Tekan untuk meneruskan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dicam. Tekan ikon buka kunci untuk meneruskan."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Dibuka kunci dengan wajah. Ketik untuk meneruskan proses."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Disahkan"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Batalkan Pengesahan"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Lagi Pilihan"</string>
@@ -291,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"Penyelamat skrin"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Jangan Ganggu"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"Mod keutamaan"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Tiada peranti berpasangan tersedia"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Ketik untuk menyambungkan atau memutuskan sambungan peranti"</string>
@@ -302,8 +302,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Disimpan"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"putuskan sambungan"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktifkan"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Hidupkan secara automatik pada hari esok"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Ciri seperti Quick Share dan Find My Device menggunakan Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth akan dihidupkan esok pagi"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Kongsi audio"</string>
@@ -472,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tambahkan lagi widget"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tekan lama untuk menyesuaikan widget"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sesuaikan widget"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Buka kunci untuk menyesuaikan widget"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikon apl untuk melumpuhkan widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikon apl untuk widget yang sedang dipasang"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -490,12 +490,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pilih widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"alih keluar widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"letakkan widget dipilih"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Widget skrin kunci"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Sesiapa sahaja boleh melihat widget pada skrin kunci, walaupun tablet dikunci."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget skrin kunci"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Untuk membuka apl menggunakan widget, anda perlu mengesahkan identiti anda. Selain itu, perlu diingat bahawa sesiapa sahaja boleh melihat widget tersebut, walaupun semasa tablet anda dikunci. Sesetengah widget mungkin tidak sesuai untuk skrin kunci anda dan mungkin tidak selamat untuk ditambahkan di sini."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Tukar pengguna"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu tarik turun"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string>
@@ -717,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Lalai"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatik"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Tiada bunyi atau getaran"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Tiada bunyi atau getaran dan muncul di sebelah bawah dalam bahagian perbualan"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Mungkin berbunyi atau bergetar berdasarkan tetapan peranti"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Mungkin berbunyi atau bergetar berdasarkan tetapan peranti. Perbualan daripada gelembung <xliff:g id="APP_NAME">%1$s</xliff:g> secara lalai."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Minta sistem menentukan jika pemberitahuan ini patut menghasilkan bunyi atau getaran"</string>
@@ -774,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1350,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Digunakan oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Digunakan baru-baru ini oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kawalan sistem"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apl sistem"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Berbilang tugas"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apl terbaharu"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Skrin pisah"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Pintasan apl"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Apl Semasa"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kebolehaksesan"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan papan kekunci"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pintasan carian"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kuncupkan ikon"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kembangkan ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gerak isyarat kembali"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gerak isyarat pergi ke laman utama"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Kekunci tindakan"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Selesai"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Syabas!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Untuk kembali, leret ke kiri atau kanan menggunakan tiga jari di mana-mana sahaja pada pad sentuh."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Pad sentuh menunjukkan tiga jari bergerak ke kanan dan kiri"</string>
@@ -1374,4 +1377,5 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Tahap %1$d daripada %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kawalan Rumah"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Jadikan kawalan rumah anda sebagai penyelamat skrin"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"Buat asal"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
index 174e416e3508..db63e2c03e9e 100644
--- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"Mati"</item>
<item msgid="4875147066469902392">"Hidup"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"Tidak tersedia"</item>
+ <item msgid="2004750556637773692">"Mati"</item>
+ <item msgid="8968530753931637871">"Hidup"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Tidak tersedia"</item>
<item msgid="5044688398303285224">"Mati"</item>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 35964300fa55..c1f186abb3a7 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> က ဤဖန်သားပြင်ဓာတ်ပုံကို တွေ့ရှိသည်။"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> နှင့် အခြားဖွင့်ထားသော အက်ပ်များက ဤဖန်သားပြင်ဓာတ်ပုံကို တွေ့ရှိသည်။"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"မှတ်စုတွင် ထည့်ရန်"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"လင့်ခ်ထည့်သွင်းရန်"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ဖန်သားပြင်ရိုက်ကူးစက်"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"စကရင်ရိုက်ကူးမှု အပြီးသတ်နေသည်"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ဖန်သားပြင် ရိုက်ကူးသည့် စက်ရှင်အတွက် ဆက်တိုက်လာနေသော အကြောင်းကြားချက်"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"ကြည့်ရှုရန် တို့ပါ"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"ဖန်သားပြင်ရိုက်ကူးမှုကို သိမ်းရာတွင် အမှားရှိသည်"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ဖန်သားပြင် ရိုက်ကူးမှု စတင်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ၏ အကြောင်းအရာ ရိုက်ကူးခြင်းကို ရပ်ပါမည်"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ရိုက်ကူးမှု ရပ်ရန်"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ဖန်သားပြင်ကို မျှဝေနေသည်"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ဖန်သားပြင်မျှဝေခြင်း ရပ်မလား။"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ၏ အကြောင်းအရာ မျှဝေခြင်းကို ရပ်ပါမည်"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"မျှဝေခြင်း ရပ်ရန်"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ဖန်သားပြင်ကို ကာစ်လုပ်နေသည်"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ကာစ်လုပ်ခြင်းကို ရပ်လိုသလား။"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ၏ အကြောင်းအရာ ကာစ်လုပ်ခြင်းကို ရပ်ပါမည်"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"ကာစ် ရပ်ရန်"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"ပိတ်ရန်"</string>
<string name="issuerecord_title" msgid="286627115110121849">"ပြဿနာရိုက်ကူးစနစ်"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ပြဿနာရိုက်ကူးမှု လုပ်နေသည်"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"ပြဿနာစုစည်းခြင်း စက်ရှင်အတွက် လုပ်ဆောင်နေဆဲ အကြောင်းကြားချက်"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"ပြဿနာရိုက်ကူးမှုကို သိမ်း၍မရပါ"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"ပြဿနာရိုက်ကူးမှုကို စတင်၍မရပါ"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"ဖန်သားပြင်အပြည့် ကြည့်နေသည်"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"ထွက်ရန် သင့်ဖန်သားပြင်ထိပ်မှ အောက်သို့ ပွတ်ဆွဲပါ"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"နားလည်ပြီ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"နောက်သို့"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ပင်မစာမျက်နှာ"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ။"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ဆက်လုပ်ရန် တို့ပါ။"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"အထောက်အထားစိစစ်ပြီးပြီ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်ရန်"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"နောက်ထပ်ရွေးစရာများ"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"စခရင်နားချိန်ပုံ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"အီသာနက်"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"မနှောင့်ယှက်ရ"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ဘလူးတုသ်"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ချိတ်တွဲထားသည့် ကိရိယာများ မရှိ"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"စက်ကို ချိတ်ဆက်ရန် (သို့) ချိတ်ဆက်မှုဖြုတ်ရန် တို့ပါ"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"သိမ်းထားသည်"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ချိတ်ဆက်မှုဖြုတ်ရန်"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"စသုံးရန်"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"မနက်ဖြန် အလိုအလျောက်ဖွင့်ရန်"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"‘အမြန် မျှဝေပါ’ နှင့် Find My Device ကဲ့သို့ တူးလ်များသည် ဘလူးတုသ်သုံးသည်"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"မနက်ဖြန်နံနက်တွင် ဘလူးတုသ် ပွင့်ပါမည်"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"အသံမျှဝေရန်"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"နောက်ထပ်ဝိဂျက်များ ထည့်ရန်"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ဝိဂျက်များ စိတ်ကြိုက်လုပ်ရန် ကြာကြာနှိပ်ထားပါ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ဝိဂျက်များကို စိတ်ကြိုက်လုပ်ရန်"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ဝိဂျက်များ စိတ်ကြိုက်လုပ်ရန် ဖွင့်နိုင်သည်"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ပိတ်ထားသော ဝိဂျက်အတွက် အက်ပ်သင်္ကေတ"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ထည့်သွင်းနေသော ဝိဂျက်အတွက် အက်ပ်သင်္ကေတ"</string>
<string name="edit_widget" msgid="9030848101135393954">"ဝိဂျက်ပြင်ရန်"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ဝိဂျက် ရွေးရန်"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ဝိဂျက် ဖယ်ရှားရန်"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ရွေးချယ်ထားသော ဝိဂျက်ကို တင်ရန်"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"လော့ခ်မျက်နှာပြင် ဝိဂျက်များ"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ဝိဂျက်သုံး၍ အက်ပ်ဖွင့်ရန်အတွက် သင်ဖြစ်ကြောင်း အတည်ပြုရန်လိုသည်။ ထို့ပြင် သင့်တက်ဘလက် လော့ခ်ချထားချိန်၌ပင် မည်သူမဆို ၎င်းတို့ကို ကြည့်နိုင်ကြောင်း သတိပြုပါ။ ဝိဂျက်အချို့ကို လော့ခ်မျက်နှာပြင်အတွက် ရည်ရွယ်ထားခြင်း မရှိသဖြင့် ဤနေရာတွင် ထည့်ပါက မလုံခြုံနိုင်ပါ။"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"နားလည်ပြီ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"အသုံးပြုသူကို ပြောင်းလဲရန်"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ဆွဲချမီနူး"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ယခု စတင်ပါ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"အကြောင်းကြားချက် မရှိပါ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"အကြောင်းကြားချက်သစ် မရှိပါ"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"အလိုက်သင့်အကြောင်းကြားချက် ဖွင့်ထားသည်"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"သင့်စက်သည် အချိန်တိုအတွင်း အကြောင်းကြားချက်များစွာ ရပါက အသံတိုးပြီး စခရင်ရှိ ပေါ့ပ်အပ်များကို နှစ်မိနစ်အထိ လျှော့ပေးသည်။"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ပိတ်ရန်"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"အကြောင်းကြားချက်ဟောင်းကြည့်ရန် လော့ခ်ဖွင့်ပါ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ဤစက်ပစ္စည်းကို သင့်မိဘက စီမံခန့်ခွဲသည်"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"မူလ"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"အလိုအလျောက်"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"အသံ သို့မဟုတ် တုန်ခါမှုမရှိပါ"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"အသံ သို့မဟုတ် တုန်ခါမှုမရှိပါ၊ စကားဝိုင်းကဏ္ဍ၏ အောက်ပိုင်းတွင် မြင်ရသည်"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"စက်ပစ္စည်း ဆက်တင်များပေါ် အခြေခံပြီး အသံမြည်နိုင်သည် (သို့) တုန်ခါနိုင်သည်"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"စက်ပစ္စည်းဆက်တင်များပေါ် အခြေခံပြီး အသံမြည်နိုင်သည် (သို့) တုန်ခါနိုင်သည်။ မူရင်းသတ်မှတ်ချက်အဖြစ် <xliff:g id="APP_NAME">%1$s</xliff:g> မှ စကားဝိုင်းများကို ပူဖောင်းကွက်ဖြင့် ပြသည်။"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ဤအကြောင်းကြားချက်က အသံ သို့မဟုတ် တုန်ခါမှု ပေးရန် သင့်/မသင့်ကို စနစ်က ဆုံးဖြတ်ပါစေ"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"အပေါ်စာမျက်နှာသို့သွားပါ"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"အောက်စာမျက်နှာသို့သွားပါ"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"ဖျက်ရန်"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"ပင်မ"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"ပြီးပါပြီ"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"ထည့်ပါ"</string>
@@ -1352,33 +1367,33 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) က သုံးနေသည်"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) က လတ်တလောသုံးထားသည်"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"စနစ်"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"စနစ် ထိန်းချုပ်မှုများ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"စနစ် အက်ပ်များ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"တစ်ပြိုင်နက် များစွာလုပ်ခြင်း"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"မကြာသေးမီက အက်ပ်များ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"မျက်နှာပြင် ခွဲ၍ပြသခြင်း"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ထည့်သွင်းမှု"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"အက်ပ်ဖြတ်လမ်းလင့်ခ်များ"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"လက်ရှိအက်ပ်"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"အများသုံးနိုင်မှု"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"လက်ကွက်ဖြတ်လမ်းများ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ရှာဖွေစာလုံး ဖြတ်လမ်း"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"လျှော့ပြရန် သင်္ကေတ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ပိုပြရန် သင်္ကေတ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"သို့မဟုတ်"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"နောက်သို့ လက်ဟန်"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"ပင်မစာမျက်နှာ လက်ဟန်"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"လုပ်ဆောင်ချက်ကီး"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ပြီးပြီ"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"တော်ပါပေသည်။"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ပြန်သွားရန်"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ပြန်သွားရန်အတွက် တာ့ချ်ပက်တွင် မည်သည့်နေရာ၌မဆို လက်သုံးချောင်းသုံး၍ ဘယ် (သို့) ညာသို့ ပွတ်ဆွဲပါ။"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"တာ့ချ်ပက်တွင် ဘယ်ညာရွှေ့နေသော လက်သုံးချောင်းကို ပြထားသည်"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"စက်စခရင်တွင် နောက်သို့လက်ဟန်အတွက် လှုပ်ရှားသက်ဝင်ပုံကို ပြထားသည်"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ကီးဘုတ်နောက်မီး"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"အဆင့် %2$d အနက် %1$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"အိမ်ထိန်းချုပ်မှုများ"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"အိမ်ထိန်းချုပ်မှုများကို စခရင်နားချိန်ပုံအဖြစ် အမြန်ဝင်ကြည့်ရန်"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml
index f665a00a5214..3628c06df4f3 100644
--- a/packages/SystemUI/res/values-my/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"ပိတ်"</item>
<item msgid="4875147066469902392">"ဖွင့်"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"မရနိုင်ပါ"</item>
<item msgid="5044688398303285224">"ပိတ်"</item>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 28e7c54cbd07..199b3594c65a 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -71,7 +71,7 @@
<string name="usb_port_enabled" msgid="531823867664717018">"Registrering av ladere og tilbehør er slått på for USB-porten"</string>
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Slå på USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Finn ut mer"</string>
- <string name="global_action_screenshot" msgid="2760267567509131654">"Skjermdump"</string>
+ <string name="global_action_screenshot" msgid="2760267567509131654">"Skjermbilde"</string>
<string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Hold ulåst er slått av"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"har sendt et bilde"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Lagrer skjermbildet …"</string>
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> har registrert dette skjermbildet."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og andre åpne apper har registrert dette skjermbildet."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Legg til i notat"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Inkluder linken"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Skjermopptak"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skjermopptaket"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Vedvarende varsel for et skjermopptak"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Trykk for å se"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Feil ved lagring av skjermopptaket"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Feil ved start av skjermopptaket"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Du slutter å ta opp &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stopp opptaket"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deler skjermen"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vil du slutte å dele skjermen?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Du slutter å dele &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Slutt å dele"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Caster skjermen"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vil du stoppe castingen?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Du slutter å caste &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Stopp castingen"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Lukk"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Funksjon for opptak av problemer"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Opptak, databehandlingsproblem"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Pågående varsel for en innsamlingsøkt for et problem"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Feil ved lagring av problemopptaket"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Feil ved start av problemopptaket"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Visning i fullskjerm"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"For å gå ut, sveip ned fra toppen av skjermen"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Greit"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Tilbake"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Startside"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst opp med ansiktet. Trykk for å fortsette."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet er gjenkjent. Trykk for å fortsette."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Låst opp med ansiktet. Trykk for å fortsette."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentisert"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Avbryt autentisering"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Flere alternativer"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Skjermsparer"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ikke forstyrr"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ingen sammenkoblede enheter er tilgjengelige"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Trykk for å koble en enhet til eller fra"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Lagret"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"koble fra"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiver"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Slå på automatisk i morgen"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funksjoner som Quick Share og Finn enheten min bruker Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth slås på i morgen tidlig"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Del lyd"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Legg til flere moduler"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Trykk lenge for å tilpasse modulene"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tilpass moduler"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Lås opp for å tilpasse moduler"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon for deaktivert modul"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikon for en modul som installeres"</string>
<string name="edit_widget" msgid="9030848101135393954">"Endre modul"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"velg modul"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjern modul"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plasser den valgte modulen"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Låseskjermmoduler"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"For å åpne en app ved hjelp av en modul må du bekrefte at det er deg. Husk også at hvem som helst kan se dem, selv om nettbrettet er låst. Noen moduler er kanskje ikke laget for å være på låseskjermen og kan være utrygge å legge til der."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Greit"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Bytt bruker"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullegardinmeny"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apper og data i denne økten blir slettet."</string>
@@ -536,7 +551,7 @@
<string name="media_projection_task_switcher_action_back" msgid="5324164224147845282">"Bytt tilbake"</string>
<string name="media_projection_task_switcher_notification_channel" msgid="7613206306777814253">"Appbytte"</string>
<string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokkert av IT-administratoren"</string>
- <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Skjermdumper er deaktivert av enhetsinnstillingene"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Skjermbilder er deaktivert av enhetsinnstillingene"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Fjern alt"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Administrer"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Logg"</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nå"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ingen varsler"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye varsler"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Tilpassbare varsler er på"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Den nye enheten din senker volumet og reduserer antall forgrunnsvinduer på skjermen i opptil to minutter når du mottar mange varsler på kort tid."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Slå av"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås opp for å se eldre varsler"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enheten administreres av forelderen din"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasjonen din eier denne enheten og kan overvåke nettverkstrafikken"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatisk"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Ingen lyd eller vibrering"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ingen lyd eller vibrering, og vises lavere i samtaledelen"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Kan ringe eller vibrere basert på enhetsinnstillingene"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Kan ringe eller vibrere basert på enhetsinnstillingene. Samtaler fra <xliff:g id="APP_NAME">%1$s</xliff:g> vises som standard som bobler."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"La systemet velge om dette varselet skal lage lyd eller vibrere"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Startskjerm"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -940,7 +955,7 @@
<string name="tuner_app" msgid="6949280415826686972">"<xliff:g id="APP">%1$s</xliff:g>-appen"</string>
<string name="notification_channel_alerts" msgid="3385787053375150046">"Varsler"</string>
<string name="notification_channel_battery" msgid="9219995638046695106">"Batteri"</string>
- <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skjermdumper"</string>
+ <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skjermbilder"</string>
<string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
<string name="notification_channel_setup" msgid="7660580986090760350">"Konfigurering"</string>
<string name="notification_channel_storage" msgid="2720725707628094977">"Lagring"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"I bruk av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nylig brukt av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systemkontroller"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systemapper"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nylige apper"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Delt skjerm"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Inndata"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-snarveier"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tilgjengelighet"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Hurtigtaster"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Snarveier til søk"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Skjul-ikon"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Vis-ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Tilbakebevegelse"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Startskjermbevegelse"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Handlingstast"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Ferdig"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Bra jobbet!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gå tilbake"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"For å gå tilbake, sveip til venstre eller høyre med tre fingre hvor som helst på styreflaten."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"En styreflate med tre fingre som beveger seg til høyre og venstre"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Enhetsskjerm med animasjonen for tilbakebevegelse"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrunnslys for tastatur"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Hjemkontroller"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Gå raskt til hjemkontrollene som skjermsparer"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
index a9efd1d95a7d..2a57ecf9314d 100644
--- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Av"</item>
<item msgid="4875147066469902392">"På"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Utilgjengelig"</item>
<item msgid="5044688398303285224">"Av"</item>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 5d428815abff..672609ade4e9 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ले यो स्क्रिनसट भेट्टाएको छ।"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> र खुला रहेका अन्य एपहरूले यो स्क्रिनसट भेट्टाएका छन्।"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"नोटमा सेभ गर्नुहोस्"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"लिंक समावेश गर्नुहोस्"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"स्क्रिन रेकर्डर"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रिन रेकर्डिङको प्रक्रिया अघि बढाइँदै"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"हेर्नका लागि ट्याप गर्नुहोस्"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रिन रेकर्डिङ सेभ गर्ने क्रममा त्रुटि भयो"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रिन रेकर्ड गर्न थाल्ने क्रममा त्रुटि भयो"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का सामग्री रेकर्ड हुन छाड्ने छन्"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का सामग्री सेयर हुन छाड्ने छन्"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का सामग्री कास्ट हुन छाड्ने छन्"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"रेकर्ड गर्न छाड्ने हो?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"तपाईं अहिले आफ्नो डिभाइसको पूरै स्क्रिन रेकर्ड गरिरहनुभएको छ"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"तपाईं अहिले <xliff:g id="APP_NAME">%1$s</xliff:g> रेकर्ड गरिरहनुभएको छ"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"रेकर्ड गर्न छाड्नुहोस्"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रिन सेयर गरिँदै छ"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"स्क्रिन सेयर गर्न छाड्ने हो?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"तपाईं अहिले <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> सँग आफ्नो डिभाइसको पूरै स्क्रिन सेयर गरिरहनुभएको छ"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"तपाईं अहिले कुनै एपसँग आफ्नो डिभाइसको पूरै स्क्रिन सेयर गरिरहनुभएको छ"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"तपाईं अहिले <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> सेयर गरिरहनुभएको छ"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"तपाईं अहिले कुनै एप सेयर गरिरहनुभएको छ"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"सेयर गर्न छाड्नुहोस्"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"स्क्रिन कास्ट गरिँदै छ"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"कास्ट गर्न छाड्ने हो?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"तपाईं अहिले आफ्नो डिभाइसको पूरै स्क्रिन <xliff:g id="DEVICE_NAME">%1$s</xliff:g> मा कास्ट गरिरहनुभएको छ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"तपाईं अहिले आफ्नो डिभाइसको पूरै स्क्रिन नजिकैको डिभाइसमा कास्ट गरिरहनुभएको छ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"तपाईं अहिले <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> बाट <xliff:g id="DEVICE_NAME">%2$s</xliff:g> मा कास्ट गरिरहनुभएको छ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"तपाईं अहिले <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> बाट नजिकैको डिभाइसमा कास्ट गरिरहनुभएको छ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"तपाईं अहिले <xliff:g id="DEVICE_NAME">%1$s</xliff:g> मा कास्ट गरिरहनुभएको छ"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"तपाईं अहिले नजिकैको डिभाइसमा कास्ट गरिरहनुभएको छ"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"कास्ट गर्न छाड्नुहोस्"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"बन्द गर्नुहोस्"</string>
<string name="issuerecord_title" msgid="286627115110121849">"समस्यासम्बन्धी जानकारी रेकर्ड गर्ने रेकर्डर"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"समस्याको रेकर्डिङ प्रोसेस गरिँदै छ"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"समस्यासम्बन्धी जानकारी सङ्कलन गर्ने जारी सत्रसम्बन्धी सूचना"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"समस्याको रेकर्डिङ सेभ गर्ने क्रममा त्रुटि भयो"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"समस्यासम्बन्धी जानकारी रेकर्ड गर्न थाल्ने क्रममा त्रुटि भयो"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"फुल स्क्रिन हेरिँदै छ"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"यहाँबाट बाहिरिन स्क्रिनको सिरानबाट तलतिर स्वाइप गर्नुहोस्"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"बुझेँ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"पछाडि"</string>
<string name="accessibility_home" msgid="5430449841237966217">"गृह"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"अनुहार प्रयोग गरी अनलक गरियो। जारी राख्न थिच्नुहोस्।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"अनुहार पहिचान गरियो। जारी राख्न थिच्नुहोस्।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"अनुहार पहिचान गरियो। जारी राख्न अनलक आइकनमा थिच्नुहोस्।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"अनुहार प्रयोग गरी अनलक गरिएको छ। जारी राख्न ट्याप गर्नुहोस्।"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"प्रमाणीकरण गरियो"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"प्रमाणीकरण रद्द गर्नुहोस्"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"थप विकल्पहरू"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"स्क्रिन सेभर"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"बाधा नपुऱ्याउनुहोस्"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ब्लुटुथ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"जोडी उपकरणहरू उपलब्ध छैन"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"कुनै डिभाइस कनेक्ट गर्न वा डिस्कनेक्ट गर्न ट्याप गर्नुहोस्"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेभ गरिएको छ"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"डिस्कनेक्ट गर्नुहोस्"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"एक्टिभेट गर्नुहोस्"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"भोलि स्वतः अन गर्नुहोस्"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक सेयर र Find My Device जस्ता सुविधाहरू प्रयोग गर्न ब्लुटुथ चाहिन्छ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ब्लुटुथ भोलि बिहान अन हुने छ"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"अडियो सेयर गर्नुहोस्"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"थप विजेटहरू हाल्नुहोस्"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेटहरू कस्टमाइज गर्न केही बेरसम्म थिच्नुहोस्"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेटहरू कस्टमाइज गर्नुहोस्"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"विजेटहरू कस्टमाइज गर्न अन लक गर्नुहोस्"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"अफ गरिएको विजेटको एप जनाउने आइकन"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"इन्स्टल भइरहेको विजेटको एप आइकन"</string>
<string name="edit_widget" msgid="9030848101135393954">"विजेट सम्पादन गर्नुहोस्"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट चयन गर्नुहोस्"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट हटाउनुहोस्"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"चयन गरिएका विजेटका लागि ठाउँ चयन गर्नुहोस्"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"लक स्क्रिन विजेटहरू"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"तपाईंको ट्याब्लेट लक भएका बेला पनि सबैले लक स्क्रिनमा भएका विजेट हेर्न सक्छन्।"</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लक स्क्रिन विजेटहरू"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"विजेट प्रयोग गरी एप खोल्न तपाईंले आफ्नो पहिचान पुष्टि गर्नु पर्ने हुन्छ। साथै, तपाईंको ट्याब्लेट लक भएका बेला पनि सबै जनाले तिनलाई देख्न सक्छन् भन्ने कुरा ख्याल गर्नुहोस्। केही विजेटहरू लक स्क्रिनमा प्रयोग गर्ने उद्देश्यले नबनाइएका हुन सक्छन् र तिनलाई यहाँ हाल्नु सुरक्षित नहुन सक्छ।"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"बुझेँ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"प्रयोगकर्ता फेर्नुहोस्"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनु"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यो सत्रमा भएका सबै एपहरू र डेटा मेटाइने छ।"</string>
@@ -549,12 +549,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"अहिले न"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"कुनै सूचनाहरू छैनन्"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"कुनै पनि नयाँ सूचना छैन"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"एड्याप्टिभ नोटिफिकेसन अन छ"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"तपाईंले छोटो समयमा धेरै नोटिफिकेसन प्राप्त गर्दा तपाईंको डिभाइसले अब दुई मिनेटसम्म भोल्युम र स्क्रिनमा देखिने पप-अपको सङ्ख्या घटाउँछ।"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"अफ गर्नुहोस्"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"पुराना सूचनाहरू हेर्न अनलक गर्नुहोस्"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"यो डिभाइस तपाईंका अभिभावक व्यवस्थापन गर्नुहुन्छ"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"यो डिभाइस तपाईंको सङ्गठनको स्वामित्वमा छ र उक्त सङ्गठनले यसको नेटवर्क ट्राफिक अनुगमन गर्न सक्छ"</string>
@@ -720,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"डिफल्ट"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"स्वचालित"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"बज्दैन पनि, भाइब्रेट पनि हुँदैन"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"बज्दैन पनि, भाइब्रेट पनि हुँदैन र वार्तालाप खण्डको तलतिर देखा पर्छ"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"डिभाइसको सेटिङका आधारमा घन्टी बज्न वा भाइब्रेट हुन सक्छ"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"डिभाइसको सेटिङका आधारमा घन्टी बज्न वा कम्पन हुन सक्छ। <xliff:g id="APP_NAME">%1$s</xliff:g> मार्फत गरिएका वार्तालापहरू स्वतः बबलमा देखिन्छन्।"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"सिस्टमलाई यो सूचना आउँदा ध्वनि बज्नु पर्छ वा कम्पन हुनु पर्छ भन्ने कुराको निधो गर्न दिनुहोस्"</string>
@@ -777,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1351,33 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ले प्रयोग गरिरहेको छ"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ले हालसालै प्रयोग गरेको"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"सिस्टम"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"सिस्टमसँग सम्बन्धित नियन्त्रणहरू"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"सिस्टम एपहरू"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"एकै पटक एकभन्दा बढी एप चलाउन मिल्ने सुविधा"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"हालसालै चलाइएका एपहरू"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"स्प्लिट स्क्रिन"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"इनपुट"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"एपका सर्टकटहरू"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"हालको एप"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सर्वसुलभता"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"किबोर्डका सर्टकटहरू"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"खोजका सर्टकटहरू"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\"कोल्याप्स गर्नुहोस्\" आइकन"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"\"एक्स्पान्ड गर्नुहोस्\" आइकन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"वा"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"ब्याक जेस्चर"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"होम जेस्चर"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"एक्सन की"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"सम्पन्न भयो"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"अद्भुत!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"पछाडि जानुहोस्"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"पछाडि जान तिन वटा औँलाले टचप्याडमा कतै छोएर बायाँ वा दायाँतिर स्वाइप गर्नुहोस्।"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"तिन वटा औँला दायाँ र बायाँ सारेको देखाइएको टचप्याड"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"पछाडि जाने जेस्चरको एनिमेसन देखाइएको डिभाइसको स्क्रिन"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"किबोर्ड ब्याकलाइट"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d मध्ये %1$d औँ स्तर"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"होम कन्ट्रोलहरू"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"होम कन्ट्रोललाई तुरुन्तै स्क्रिनसेभरका रूपमा एक्सेस गर्नुहोस्"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
index c1b2f3420a40..7edd8bfb23a3 100644
--- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"अफ छ"</item>
<item msgid="4875147066469902392">"अन छ"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"उपलब्ध छैन"</item>
<item msgid="5044688398303285224">"अफ छ"</item>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index d53f556f124f..7f86f23999c4 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> heeft dit screenshot waargenomen."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> en andere geopende apps hebben dit screenshot waargenomen."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Toevoegen aan notitie"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Link opnemen"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Schermopname"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Schermopname verwerken"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Doorlopende melding voor een schermopname-sessie"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tik om te bekijken"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Fout bij opslaan van schermopname"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Fout bij starten van schermopname"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Je stopt met het opnemen van &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Je stopt met het delen van &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Je stopt met het casten van &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Opname stoppen?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Je neemt op dit moment je hele scherm op"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Je neemt op dit moment <xliff:g id="APP_NAME">%1$s</xliff:g> op"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Opname stoppen"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Scherm delen"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Scherm delen stoppen?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Je deelt op dit moment je hele scherm met <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Je deelt op dit moment je hele scherm met een app"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Je deelt op dit moment <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Je deelt op dit moment een app"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Delen stoppen"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Scherm casten"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Stoppen met casten?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Je cast op dit moment je hele scherm naar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Je cast op dit moment je hele scherm naar een apparaat in de buurt"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Je cast op dit moment <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> naar <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Je cast op dit moment <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> naar een apparaat in de buurt"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Je cast op dit moment naar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Je cast op dit moment naar een apparaat in de buurt"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Casten stoppen"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Sluiten"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Problemen opnemen"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Probleemopname verwerken"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Melding over actieve activiteit voor een sessie voor probleemverzameling"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Fout bij opslaan van probleemopname"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Fout bij starten van probleemopname"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Volledig scherm wordt getoond"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Swipe omlaag vanaf de bovenkant van het scherm om af te sluiten"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Terug"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Startscherm"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontgrendeld via gezicht. Druk om door te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gezicht herkend. Druk om door te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gezicht herkend. Druk op het ontgrendelicoon."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Ontgrendeld via gezicht. Tik om door te gaan."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Geverifieerd"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Verificatie annuleren"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Meer opties"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Screensaver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Niet storen"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Geen gekoppelde apparaten beschikbaar"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Tik om een apparaat te verbinden of de verbinding te verbreken"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Opgeslagen"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"loskoppelen"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activeren"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Morgen automatisch aanzetten"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Functies zoals Quick Share en Vind mijn apparaat gebruiken bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth wordt morgenochtend aangezet"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Audio delen"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Meer widgets toevoegen"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Houd lang ingedrukt om widgets aan te passen"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widgets aanpassen"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Ontgrendel om widgets aan te passen"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-icoon voor uitgezette widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App-icoon voor een widget die wordt geïnstalleerd"</string>
<string name="edit_widget" msgid="9030848101135393954">"Widget bewerken"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"widget selecteren"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"widget verwijderen"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"geselecteerde widget plaatsen"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets op het vergrendelscherm"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Iedereen kan widgets op je vergrendelscherm bekijken, ook als je tablet is vergrendeld."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets op het vergrendelscherm"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Als je een app wilt openen met een widget, moet je laten verifiëren dat jij het bent. Houd er ook rekening mee dat iedereen ze kan bekijken, ook als je tablet vergrendeld is. Bepaalde widgets zijn misschien niet bedoeld voor je vergrendelscherm en kunnen hier niet veilig worden toegevoegd."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Gebruiker wijzigen"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pull-downmenu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Standaard"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatisch"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Geen geluid of trilling"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Geen geluid of trilling en wordt lager in het gedeelte met gesprekken getoond"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Kan overgaan of trillen op basis van de apparaatinstellingen"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Kan overgaan of trillen op basis van de apparaatinstellingen. Gesprekken uit <xliff:g id="APP_NAME">%1$s</xliff:g> worden standaard als bubbels weergegeven."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Het systeem laten bepalen of deze melding geluid moet maken of moet trillen"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1207,7 +1209,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik hier voor meer informatie"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Geen wekker gezet"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"schermvergrendeling invoeren"</string>
- <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Raak de vingerafdruksensor aan. Dit is de kortere knop aan de zijkant van de telefoon."</string>
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Plaats je vinger op de vingerafdruksensor. Dat is de kortere knop aan de zijkant van de telefoon."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Vingerafdruksensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"verifiëren"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"apparaat opgeven"</string>
@@ -1349,23 +1351,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Gebruikt door <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recent gebruikt door <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Systeem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systeemopties"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systeem-apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recente apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Gesplitst scherm"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Invoer"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-snelkoppelingen"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Huidige app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toegankelijkheid"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Sneltoetsen"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Snelkoppelingen voor zoekopdrachten"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icoon voor samenvouwen"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icoon voor uitvouwen"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"of"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gebaar voor terug"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gebaar voor startscherm"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Actietoets"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Klaar"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Goed werk!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Terug"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Als je wilt teruggaan, swipe je met 3 vingers naar links of rechts op de touchpad."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad met 3 vingers die naar rechts en links bewegen"</string>
@@ -1374,4 +1378,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d van %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Bediening voor in huis"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Gebruik bediening voor in huis als screensaver"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
index c5d93610fb87..45664b827d79 100644
--- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Uit"</item>
<item msgid="4875147066469902392">"Aan"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Niet beschikbaar"</item>
<item msgid="5044688398303285224">"Uit"</item>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 860847137cae..88aea1599cf7 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ଏହି ସ୍କ୍ରିନସଟକୁ ଚିହ୍ନଟ କରିଛି।"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ଏବଂ ଅନ୍ୟ ଓପନ ଆପ୍ସ ଏହି ସ୍କ୍ରିନସଟକୁ ଚିହ୍ନଟ କରିଛି।"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ନୋଟରେ ଯୋଗ କରନ୍ତୁ"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"ଲିଙ୍କକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରନ୍ତୁ"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ସ୍କ୍ରିନ ରେକର୍ଡର"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ସ୍କ୍ରିନ ରେକର୍ଡିଂର ପ୍ରକ୍ରିୟାକରଣ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ଏକ ସ୍କ୍ରି‍ନ୍‍ ରେକର୍ଡ୍‍ ସେସନ୍‍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"ସ୍କ୍ରିନ ରେକର୍ଡିଂ ସେଭ କରିବାରେ ତ୍ରୁଟି"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବାରେ ତ୍ରୁଟି"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ଆପଣ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ ରେକର୍ଡ କରିବା ବନ୍ଦ କରିବେ"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ରେକର୍ଡିଂ ବନ୍ଦ କରନ୍ତୁ"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ସ୍କ୍ରିନ ସେୟାର କରାଯାଉଛି"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ସ୍କ୍ରିନ ସେୟାର କରିବା ବନ୍ଦ କରିବେ?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ଆପଣ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ ସେୟାର କରିବା ବନ୍ଦ କରିବେ"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ସେୟାର କରିବା ବନ୍ଦ କରନ୍ତୁ"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ସ୍କ୍ରିନ କାଷ୍ଟ କରାଯାଉଛି"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"କାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ଆପଣ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ କାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"କାଷ୍ଟ କରିବା ବନ୍ଦ କରନ୍ତୁ"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="issuerecord_title" msgid="286627115110121849">"ସମସ୍ୟା ରେକର୍ଡର"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ସମସ୍ୟାର ରେକର୍ଡିଂର ପ୍ରକ୍ରିୟାକରଣ"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"ଏକ ସମସ୍ୟା ସଂଗ୍ରହ ସେସନ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"ସମସ୍ୟାର ରେକର୍ଡିଂ କରିବାରେ ତ୍ରୁଟି"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"ସମସ୍ୟାର ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବାରେ ତ୍ରୁଟି"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନରେ ଦେଖିବା"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"ବାହାରି ଯିବା ପାଇଁ ଆପଣଙ୍କ ସ୍କ୍ରିନର ଶୀର୍ଷରୁ ତଳକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"ବୁଝିଗଲି"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ଫେରନ୍ତୁ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ହୋମ"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ପ୍ରମାଣୀକରଣକୁ ବାତିଲ କରନ୍ତୁ"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ଅଧିକ ବିକଳ୍ପ"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"ସ୍କ୍ରିନ୍‌ ସେଭର୍‌"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ଇଥରନେଟ୍‌"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ବ୍ଲୁଟୁଥ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ପେୟାର୍‍ ହୋଇଥିବା କୌଣସି ଡିଭାଇସ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"ଏକ ଡିଭାଇସ କନେକ୍ଟ କିମ୍ବା ଡିସକନେକ୍ଟ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ସେଭ କରାଯାଇଛି"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ଡିସକନେକ୍ଟ କରନ୍ତୁ"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ଚାଲୁ କରନ୍ତୁ"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"ଆସନ୍ତାକାଲି ସ୍ୱତଃ ଚାଲୁ ହେବ"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share ଏବଂ Find My Device ପରି ଫିଚରଗୁଡ଼ିକ ବ୍ଲୁଟୁଥ ବ୍ୟବହାର କରେ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ବ୍ଲୁଟୁଥ ଆସନ୍ତା କାଲି ସକାଳେ ଚାଲୁ ହେବ"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ଅଡିଓ ସେୟାର କରନ୍ତୁ"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ଅଧିକ ୱିଜେଟ ଯୋଗ କରନ୍ତୁ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ୱିଜେଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରିବା ପାଇଁ ଅଧିକ ସମୟ ଦବାନ୍ତୁ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ୱିଜେଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ୱିଜେଟ କଷ୍ଟମାଇଜ କରିବାକୁ ଅନଲକ କରନ୍ତୁ"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ଅକ୍ଷମ କରାଯାଇଥିବା ୱିଜେଟ ପାଇଁ ଆପ ଆଇକନ"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ଏକ ୱିଜେଟ ପାଇଁ ଆପ ଆଇକନକୁ ଇନଷ୍ଟଲ କରାଯାଉଛି"</string>
<string name="edit_widget" msgid="9030848101135393954">"ୱିଜେଟକୁ ଏଡିଟ କରନ୍ତୁ"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ୱିଜେଟ ଚୟନ କରନ୍ତୁ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ୱିଜେଟକୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ଚୟନିତ ୱିଜେଟ ରଖନ୍ତୁ"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ଲକ ସ୍କ୍ରିନ ୱିଜେଟଗୁଡ଼ିକ"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ଏକ ୱିଜେଟ ବ୍ୟବହାର କରି ଗୋଟିଏ ଆପ ଖୋଲିବା ପାଇଁ ଏହା ଆପଣ ଅଟନ୍ତି ବୋଲି ଆପଣଙ୍କୁ ଯାଞ୍ଚ କରିବାକୁ ହେବ। ଆହୁରି ମଧ୍ୟ, ଆପଣଙ୍କ ଟାବଲେଟ ଲକ ଥିଲେ ମଧ୍ୟ ଯେ କୌଣସି ବ୍ୟକ୍ତି ଏହାକୁ ଭ୍ୟୁ କରିପାରିବେ ବୋଲି ମନେ ରଖନ୍ତୁ। କିଛି ୱିଜେଟ ଆପଣଙ୍କ ଲକ ସ୍କ୍ରିନ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ହୋଇନଥାଇପାରେ ଏବଂ ଏଠାରେ ଯୋଗ କରିବା ଅସୁରକ୍ଷିତ ହୋଇପାରେ।"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ବୁଝିଗଲି"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ୟୁଜର୍‍ ବଦଳାନ୍ତୁ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ପୁଲଡାଉନ ମେନୁ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ସେସନର ସମସ୍ତ ଆପ୍‌ ଓ ଡାଟା ଡିଲିଟ୍‌ ହୋଇଯିବ।"</string>
@@ -506,7 +521,7 @@
<string name="guest_notification_app_name" msgid="2110425506754205509">"ଅତିଥି ମୋଡ"</string>
<string name="guest_notification_session_active" msgid="5567273684713471450">"ଆପଣ ଅତିଥି ମୋଡରେ ଅଛନ୍ତି"</string>
<string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବା ଦ୍ୱାରା ଅତିଥି ମୋଡରୁ ବାହାରି ଯିବ ଏବଂ ବର୍ତ୍ତମାନର ଅତିଥି ସେସନରୁ ସମସ୍ତ ଆପ ଓ ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
- <string name="user_limit_reached_title" msgid="2429229448830346057">"ଉପଯୋଗକର୍ତ୍ତା ସୀମାରେ ପହଞ୍ଚିଛି"</string>
+ <string name="user_limit_reached_title" msgid="2429229448830346057">"ୟୁଜର ସୀମାରେ ପହଞ୍ଚିଛି"</string>
<string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{କେବଳ ଜଣେ ୟୁଜର ତିଆରି କରାଯାଇପାରିବ।}other{କେବଳ # ଜଣ ୟୁଜର ତିଆରି କରାଯାଇପାରିବ।}}"</string>
<string name="user_remove_user_title" msgid="9124124694835811874">"ୟୁଜରଙ୍କୁ ବାହାର କରିବେ?"</string>
<string name="user_remove_user_message" msgid="6702834122128031833">"ଏହି ୟୁଜରଙ୍କ ସମସ୍ତ ଆପ୍‍ ଓ ଡାଟା ଡିଲିଟ୍‍ ହେବ।"</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ଡିଫଲ୍ଟ"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"ସ୍ୱଚାଳିତ"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"କୌଣସି ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ ନାହିଁ"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"କୌଣସି ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ ନାହିଁ ଏବଂ ବାର୍ତ୍ତାଳାପ ବିଭାଗର ନିମ୍ନରେ ଦେଖାଯାଏ"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"ଡିଭାଇସ ସେଟିଂସ ଆଧାରରେ ରିଂ କିମ୍ବା ଭାଇବ୍ରେଟ ହୋଇପାରେ"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ଡିଭାଇସ ସେଟିଂସ ଆଧାରରେ ରିଂ କିମ୍ବା ଭାଇବ୍ରେଟ ହୋଇପାରେ। ଡିଫଲ୍ଟ ଭାବରେ <xliff:g id="APP_NAME">%1$s</xliff:g>ରୁ ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ ବବଲ ଭାବେ ଦେଖାଯାଏ।"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ଏହି ବିଜ୍ଞପ୍ତି ପ୍ରାପ୍ତ ହେବା ସମୟରେ ସାଉଣ୍ଡ ହେବା ଉଚିତ ନା ଭାଇବ୍ରେସନ୍ ତାହା ସିଷ୍ଟମକୁ ସ୍ଥିର କରିବାକୁ ଦିଅନ୍ତୁ"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"ଉପର ପୃଷ୍ଠା"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"ତଳ ପୃଷ୍ଠା"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"ଡିଲିଟ କରନ୍ତୁ"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"ହୋମ"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"ସମାପ୍ତ"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"ଇନ୍‌ସର୍ଟ"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଦ୍ୱାରା ବ୍ୟବହାର କରାଯାଉଛି (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ଏବେ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ଦ୍ୱାରା ବ୍ୟବହାର କରାଯାଉଛି"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ସିଷ୍ଟମ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ସିଷ୍ଟମ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ସିଷ୍ଟମ ଆପ୍ସ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ମଲ୍ଟିଟାସ୍କିଂ"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ବର୍ତ୍ତମାନର ଆପ୍ସ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ଇନପୁଟ"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ଆପ ସର୍ଟକଟ"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ଆକ୍ସେସିବିଲିଟୀ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"କୀବୋର୍ଡ ସର୍ଟକଟ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ସର୍ଚ୍ଚ ସର୍ଟକଟ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ଆଇକନକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ଆଇକନକୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"କିମ୍ବା"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"ବେକ ଜେଶ୍ଚର"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"ହୋମ ଜେଶ୍ଚର"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"ଆକ୍ସନ କୀ"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ହୋଇଗଲା"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"ବଢ଼ିଆ କାମ!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ପଛକୁ ଫେରନ୍ତୁ"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ପଛକୁ ଫେରିବା ପାଇଁ ଯେ କୌଣସି ସ୍ଥାନରେ ତିନି ଆଙ୍ଗୁଠି ବ୍ୟବହାର କରି ବାମ କିମ୍ବା ଡାହାଣକୁ ସ୍ୱାଇପ କରନ୍ତୁ।"</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ଡାହାଣ ଏବଂ ବାମକୁ ତିନି ଆଙ୍ଗୁଠି ମୁଭ କରୁଥିବା ଟଚପେଡ ଦେଖାଉଛି"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dରୁ %1$d ନମ୍ବର ଲେଭେଲ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ହୋମ କଣ୍ଟ୍ରୋଲ୍ସ"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"ସ୍କ୍ରିନସେଭର ଭାବେ ହୋମ କଣ୍ଟ୍ରୋଲ୍ସକୁ ଶୀଘ୍ର ଆକ୍ସେସ କରନ୍ତୁ"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml
index fe187c2ff082..1bc369b2a777 100644
--- a/packages/SystemUI/res/values-or/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"ବନ୍ଦ ଅଛି"</item>
<item msgid="4875147066469902392">"ଚାଲୁ ଅଛି"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ଉପଲବ୍ଧ ନାହିଁ"</item>
<item msgid="5044688398303285224">"ବନ୍ଦ ଅଛି"</item>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 9fabdae6496c..3f06376afdd2 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ਨੂੰ ਇਸ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦਾ ਪਤਾ ਲੱਗਿਆ ਹੈ।"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ਅਤੇ ਹੋਰ ਖੁੱਲ੍ਹੀਆਂ ਐਪਾਂ ਨੂੰ ਇਸ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦਾ ਪਤਾ ਲੱਗਿਆ ਹੈ।"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ਨੋਟ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"ਲਿੰਕ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਰ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਜਾਰੀ ਹੈ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ਕਿਸੇ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਸੈਸ਼ਨ ਲਈ ਚੱਲ ਰਹੀ ਸੂਚਨਾ"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋ ਗਈ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋਈ"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ਤੁਸੀਂ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਰਿਕਾਰਡ ਕਰਨਾ ਬੰਦ ਕਰ ਦੇਵੋਗੇ"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ਰਿਕਾਰਡਿੰਗ ਬੰਦ ਕਰੋ"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ਸਕ੍ਰੀਨ ਸਾਂਝੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ਕੀ ਸਕ੍ਰੀਨ ਨੂੰ ਸਾਂਝਾ ਕਰਨਾ ਬੰਦ ਕਰਨਾ ਹੈ?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ਤੁਸੀਂ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਸਾਂਝਾ ਕਰਨਾ ਬੰਦ ਕਰ ਦੇਵੋਗੇ"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ਸਾਂਝਾਕਰਨ ਬੰਦ ਕਰੋ"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ਸਕ੍ਰੀਨ \'ਤੇ ਕਾਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ਕੀ ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰਨਾ ਹੈ?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ਤੁਸੀਂ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰ ਦੇਵੋਗੇ"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰੋ"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"ਬੰਦ ਕਰੋ"</string>
<string name="issuerecord_title" msgid="286627115110121849">"ਸਮੱਸਿਆ ਰਿਕਾਰਡਰ"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ਸਮੱਸਿਆ ਰਿਕਾਰਡਿੰਗ ਪ੍ਰਕਿਰਿਆ-ਅਧੀਨ ਹੈ"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"ਸਮੱਸਿਆ ਬਾਰੇ ਜਾਣਕਾਰੀ ਇਕੱਤਰ ਕਰਨ ਵਾਲੇ ਸੈਸ਼ਨ ਸੰਬੰਧੀ ਨਿਰੰਤਰ ਸੂਚਨਾ"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"ਸਮੱਸਿਆ ਰਿਕਾਰਡਿੰਗ ਰੱਖਿਅਤ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋ ਗਈ"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"ਸਮੱਸਿਆ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋ ਗਈ"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"ਪੂਰੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦੇਖਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"ਬਾਹਰ ਜਾਣ ਲਈ, ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਸਿਖਰ ਤੋਂ ਹੇਠਾਂ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"ਸਮਝ ਲਿਆ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ਪਿੱਛੇ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ਘਰ"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ਪ੍ਰਮਾਣੀਕਰਨ ਰੱਦ ਕਰੋ"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ਹੋਰ ਵਿਕਲਪ"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"ਸਕ੍ਰੀਨ ਸੇਵਰ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ਈਥਰਨੈਟ"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ਬਲੂਟੁੱਥ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ਕੋਈ ਜੋੜਾਬੱਧ ਕੀਤੀਆਂ ਡੀਵਾਈਸਾਂ ਉਪਲਬਧ ਨਹੀਂ"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"ਡੀਵਾਈਸ ਨੂੰ ਕਨੈਕਟ ਜਾਂ ਡਿਸਕਨੈਕਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ਕਿਰਿਆਸ਼ੀਲ ਕਰੋ"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"ਕੱਲ੍ਹ ਨੂੰ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਚਾਲੂ ਹੋ ਜਾਵੇਗਾ"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ਕਵਿੱਕ ਸ਼ੇਅਰ ਅਤੇ Find My Device ਵਰਗੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਬਲੂਟੁੱਥ ਵਰਤਦੀਆਂ ਹਨ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ਬਲੂਟੁੱਥ ਕੱਲ੍ਹ ਸਵੇਰੇ ਚਾਲੂ ਹੋ ਜਾਵੇਗਾ"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ਆਡੀਓ ਨੂੰ ਸਾਂਝਾ ਕਰੋ"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ਹੋਰ ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ਵਿਜੇਟਾਂ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਦਬਾਈ ਰੱਖੋ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ਵਿਜੇਟ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ਵਿਜੇਟਾਂ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ਬੰਦ ਵਿਜੇਟ ਲਈ ਐਪ ਪ੍ਰਤੀਕ"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ਸਥਾਪਤ ਕੀਤੇ ਜਾ ਰਹੇ ਵਿਜੇਟ ਲਈ ਐਪ ਪ੍ਰਤੀਕ"</string>
<string name="edit_widget" msgid="9030848101135393954">"ਵਿਜੇਟ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ਵਿਜੇਟ ਚੁਣੋ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ਵਿਜੇਟ ਹਟਾਓ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ਚੁਣੇ ਗਏ ਵਿਜੇਟ ਲਈ ਥਾਂ ਚੁਣੋ"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ਲਾਕ ਸਕ੍ਰੀਨ ਵਿਜੇਟ"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ਵਿਜੇਟ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਐਪ ਖੋਲ੍ਹਣ ਲਈ, ਤੁਹਾਨੂੰ ਇਹ ਪੁਸ਼ਟੀ ਕਰਨ ਦੀ ਲੋੜ ਪਵੇਗੀ ਕਿ ਇਹ ਤੁਸੀਂ ਹੀ ਹੋ। ਨਾਲ ਹੀ, ਇਹ ਵੀ ਧਿਆਨ ਵਿੱਚ ਰੱਖੋ ਕਿ ਕੋਈ ਵੀ ਉਨ੍ਹਾਂ ਨੂੰ ਦੇਖ ਸਕਦਾ ਹੈ, ਭਾਵੇਂ ਤੁਹਾਡੀ ਟੈਬਲੈੱਟ ਲਾਕ ਹੋਵੇ। ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਕੁਝ ਵਿਜੇਟ ਤੁਹਾਡੀ ਲਾਕ ਸਕ੍ਰੀਨ ਲਈ ਨਾ ਬਣੇ ਹੋਣ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਇੱਥੇ ਸ਼ਾਮਲ ਕਰਨਾ ਅਸੁਰੱਖਿਅਤ ਹੋਵੇ।"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ਸਮਝ ਲਿਆ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ਵਰਤੋਂਕਾਰ ਸਵਿੱਚ ਕਰੋ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ਪੁੱਲਡਾਊਨ ਮੀਨੂ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿਚਲੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟੇ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"ਸਵੈਚਲਿਤ"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"ਕੋਈ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਹੀਂ"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ਕੋਈ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਹੀਂ ਅਤੇ ਸੂਚਨਾਵਾਂ ਗੱਲਬਾਤ ਸੈਕਸ਼ਨ ਵਿੱਚ ਹੇਠਲੇ ਪਾਸੇ ਦਿਸਦੀਆਂ ਹਨ"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"ਡੀਵਾਈਸ ਸੈਟਿੰਗਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਘੰਟੀ ਵੱਜ ਸਕਦੀ ਹੈ ਜਾਂ ਥਰਥਰਾਹਟ ਹੋ ਸਕਦੀ ਹੈ"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ਡੀਵਾਈਸ ਸੈਟਿੰਗਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਘੰਟੀ ਵੱਜ ਸਕਦੀ ਹੈ ਜਾਂ ਥਰਥਰਾਹਟ ਹੋ ਸਕਦੀ ਹੈ। ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਤੌਰ \'ਤੇ <xliff:g id="APP_NAME">%1$s</xliff:g> ਬਬਲ ਤੋਂ ਗੱਲਾਂਬਾਤਾਂ।"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ਸਿਸਟਮ ਨੂੰ ਨਿਰਧਾਰਤ ਕਰਨ ਦਿਓ ਕਿ ਇਸ ਸੂਚਨਾ ਲਈ ਕੋਈ ਧੁਨੀ ਵਜਾਉਣੀ ਚਾਹੀਦੀ ਹੈ ਜਾਂ ਥਰਥਰਾਹਟ ਕਰਨੀ ਚਾਹੀਦੀ ਹੈ"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"ਮਿਟਾਓ"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ਵੱਲੋਂ ਵਰਤੋਂ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ਹਾਲ ਹੀ ਵਿੱਚ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ਵੱਲੋਂ ਵਰਤਿਆ ਗਿਆ"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ਸਿਸਟਮ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ਸਿਸਟਮ ਸੰਬੰਧੀ ਕੰਟਰੋਲ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ਸਿਸਟਮ ਐਪਾਂ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ਮਲਟੀਟਾਸਕਿੰਗ"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ਹਾਲੀਆ ਐਪਾਂ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ਇਨਪੁੱਟ"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ਐਪ ਸ਼ਾਰਟਕੱਟ"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ਪਹੁੰਚਯੋਗਤਾ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ਖੋਜ ਸੰਬੰਧੀ ਸ਼ਾਰਟਕੱਟ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ਪ੍ਰਤੀਕ ਨੂੰ ਸਮੇਟੋ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ਪ੍ਰਤੀਕ ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ਜਾਂ"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"ਪਿੱਛੇ ਜਾਣ ਦਾ ਇਸ਼ਾਰਾ"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"ਹੋਮ \'ਤੇ ਜਾਣ ਦਾ ਇਸ਼ਾਰਾ"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"ਕਾਰਵਾਈ ਕੁੰਜੀ"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ਹੋ ਗਿਆ"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"ਬਹੁਤ ਵਧੀਆ!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ਵਾਪਸ ਜਾਓ"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ਵਾਪਸ ਜਾਣ ਲਈ, ਟੱਚਪੈਡ \'ਤੇ ਕਿਤੇ ਵੀ ਤਿੰਨ ਉਂਗਲਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਖੱਬੇ ਜਾਂ ਸੱਜੇ ਪਾਸੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ।"</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ਟੱਚਪੈਡ \'ਤੇ ਤਿੰਨ ਉਂਗਲਾਂ ਨੂੰ ਸੱਜੇ ਅਤੇ ਖੱਬੇ ਪਾਸੇ ਵੱਲ ਲਿਜਾਂਦੇ ਹੋਏ ਦਿਖਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ਵਿੱਚੋਂ %1$d ਪੱਧਰ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ਹੋਮ ਕੰਟਰੋਲ"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"ਸਕ੍ਰੀਨ-ਸੇਵਰ ਵਜੋਂ ਆਪਣੇ ਹੋਮ ਕੰਟਰੋਲਾਂ ਤੱਕ ਤੁਰੰਤ ਪਹੁੰਚ ਕਰੋ"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
index 62dc05ad67bb..cc4c5c4eb228 100644
--- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"ਬੰਦ ਹੈ"</item>
<item msgid="4875147066469902392">"ਚਾਲੂ ਹੈ"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ਅਣਉਪਲਬਧ ਹੈ"</item>
<item msgid="5044688398303285224">"ਬੰਦ ਹੈ"</item>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index f592e09ae6dd..dedfc93c1606 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacja <xliff:g id="APPNAME">%1$s</xliff:g> wykryła ten zrzut ekranu."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Aplikacja <xliff:g id="APPNAME">%1$s</xliff:g> i inne aplikacje wykryły ten zrzut ekranu."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj do notatek"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Dołącz link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Nagrywanie ekranu"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Przetwarzam nagrywanie ekranu"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Kliknij, aby wyświetlić"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Podczas zapisywania nagrania ekranu wystąpił błąd"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Błąd podczas rozpoczynania rejestracji zawartości ekranu"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Przestaniesz nagrywać treści z aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Przestaniesz udostępniać treści z aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Przestaniesz przesyłać treści z aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Zatrzymać nagrywanie?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Obecnie nagrywasz cały widok ekranu"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Obecnie nagrywasz widok aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Zatrzymaj nagrywanie"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Udostępniam ekran"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Zatrzymać udostępnianie ekranu?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Obecnie udostępniasz aplikacji <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> cały widok ekranu"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Obecnie udostępniasz aplikacji cały widok ekranu"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Obecnie udostępniasz aplikację <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Obecnie udostępniasz aplikację"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Zatrzymaj udostępnianie"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Przesyłam zawartość ekranu"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Zatrzymać przesyłanie?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Obecnie przesyłasz cały widok ekranu na urządzenie <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Obecnie przesyłasz cały widok ekranu na urządzenie w pobliżu"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Obecnie przesyłasz widok aplikacji <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> na urządzenie <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Obecnie przesyłasz widok aplikacji <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> na urządzenie w pobliżu"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Obecnie przesyłasz widok ekranu na urządzenie <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Obecnie przesyłasz widok ekranu na urządzenie w pobliżu"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Zatrzymaj przesyłanie"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Zamknij"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Rejestrator problemów"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Przetwarzam nagranie problemu"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Powiadomienie o trwającej aktywności sesji nagrywania ekranu"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Błąd podczas zapisywania nagrania problemu"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Błąd podczas rozpoczynania nagrania problemu"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Włączony pełny ekran"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Aby zamknąć, przesuń palcem w dół z góry ekranu"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Wróć"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Ekran główny"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odblokowano rozpoznawaniem twarzy. Kliknij, aby kontynuować."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Twarz rozpoznana. Kliknij, aby kontynuować."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Twarz rozpoznana. Aby kontynuować, kliknij ikonę odblokowywania."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Odblokowano skanem twarzy. Kliknij, aby przejść dalej."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Uwierzytelniono"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anuluj uwierzytelnianie"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Więcej opcji"</string>
@@ -291,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"Wygaszacz ekranu"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Nie przeszkadzać"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"Tryby priorytetowe"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Brak dostępnych sparowanych urządzeń"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Kliknij, aby podłączyć lub odłączyć urządzenie"</string>
@@ -302,8 +302,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Zapisane"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"rozłącz"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktywuj"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automatycznie włącz jutro"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetootha używają funkcje takie jak szybkie udostępnianie czy Znajdź moje urządzenie"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth włączy się jutro rano"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Udostępnij dźwięk"</string>
@@ -472,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodaj więcej widżetów"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Przytrzymaj, aby dostosować widżety"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Dostosuj widżety"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Odblokuj, aby dostosować widżety"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacji z wyłączonym widżetem"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacji instalowanego widżetu"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edytuj widżet"</string>
@@ -490,12 +490,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"wybierz widżet"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"usuń widżet"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"umieść wybrany widżet"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Widżety na ekranie blokady"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Każdy zobaczy widżety na ekranie blokady, nawet gdy tablet jest zablokowany."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widżety na ekranie blokady"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Aby otworzyć aplikację za pomocą widżetu, musisz potwierdzić swoją tożsamość. Pamiętaj też, że każdy będzie mógł wyświetlić widżety nawet wtedy, gdy tablet będzie zablokowany. Niektóre widżety mogą nie być przeznaczone do umieszczenia na ekranie blokady i ich dodanie w tym miejscu może być niebezpieczne."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Przełącz użytkownika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string>
@@ -549,12 +548,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Rozpocznij teraz"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Brak powiadomień"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Brak nowych powiadomień"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Powiadomienia adaptacyjne włączone"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Urządzenie zmniejszy teraz głośność i ograniczy wyskakujące okienka przez maks. 2 minuty, gdy w krótkim czasie otrzymujesz wiele powiadomień."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Wyłącz"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odblokuj i zobacz starsze powiadomienia"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tym urządzeniem zarządza Twój rodzic"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Twoja organizacja jest właścicielem tego urządzenia i może monitorować ruch w sieci"</string>
@@ -720,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Domyślne"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatycznie"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez dźwięku i wibracji"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Brak dźwięku i wibracji, wyświetlają się niżej w sekcji rozmów"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Mogą włączać dzwonek lub wibracje w zależności od ustawień urządzenia"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Mogą włączać dzwonek lub wibracje w zależności od ustawień urządzenia. Rozmowy z aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> są domyślnie wyświetlane jako dymki."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Pozwól systemowi decydować, czy o powiadomieniu powinien informować dźwięk czy wibracja"</string>
@@ -777,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1350,33 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Używany przez aplikację <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Ostatnio używany przez aplikację <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systemowe elementy sterujące"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplikacje systemowe"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Wielozadaniowość"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Ostatnie aplikacje"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podzielony ekran"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Wprowadzanie"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Skróty do aplikacji"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ułatwienia dostępu"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Skróty klawiszowe"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Skróty do wyszukiwania"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zwijania"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozwijania"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"lub"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gest przejścia wstecz"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gest przejścia na ekran główny"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Klawisz działania"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gotowe"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Świetnie!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Wróć"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Aby wrócić, przesuń 3 palcami w lewo lub w prawo w dowolnym miejscu touchpada."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"3 palce na touchpadzie poruszające się w prawo i w lewo"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ekran urządzenia z animacją gestu cofania"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podświetlenie klawiatury"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Poziom %1$d z %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Sterowanie domem"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Szybki dostęp do sterowania domem na wygaszaczu ekranu"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"Cofnij"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index 5aa719f2ea75..2190cf81a3fa 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"Wyłączone"</item>
<item msgid="4875147066469902392">"Włączone"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"Niedostępne"</item>
+ <item msgid="2004750556637773692">"Wyłączono"</item>
+ <item msgid="8968530753931637871">"Włączono"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Niedostępny"</item>
<item msgid="5044688398303285224">"Wyłączona"</item>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 0c27fea268b3..1ab30c3bfaee 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"O app <xliff:g id="APPNAME">%1$s</xliff:g> detectou essa captura de tela."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outros apps abertos detectaram essa captura de tela."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Incluir anotação"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Gravador de tela"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao salvar a gravação da tela"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Você vai parar de gravar o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Você vai parar de compartilhar o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Você vai parar de transmitir o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Parar gravação?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Você está gravando a tela inteira"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Você está gravando o app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Parar gravação"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartilhando a tela"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Parar o compartilhamento de tela?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Você está compartilhando a tela inteira com o app <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Você está compartilhando a tela inteira com um app"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Você está compartilhando o app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Você está compartilhando um app"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Interromper compartilhamento"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Transmitindo a tela"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Parar transmissão?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Você está transmitindo a tela inteira para o <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Você está transmitindo a tela inteira para um dispositivo por perto"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Você está transmitindo o app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> para o <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Você está transmitindo o app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> para um dispositivo por perto"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Você está transmitindo para o <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Você está transmitindo para um dispositivo por perto"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Interromper transmissão"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Fechar"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Gravador de problemas"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processando a gravação do problema"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificação em andamento para uma sessão de coleta de problemas"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Erro ao salvar a gravação do problema"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Erro ao iniciar a gravação do problema"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Visualização em tela cheia"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Para sair, deslize de cima para baixo na tela"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Entendi"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Voltar"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Página inicial"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Desbloqueado pelo rosto. Toque para continuar."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Protetor de tela"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Não perturbe"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Não há dispositivos pareados disponíveis"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Toque para conectar ou desconectar um dispositivo"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvo"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Ativar automaticamente amanhã"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Recursos como o Quick Share e o Encontre Meu Dispositivo usam Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"O Bluetooth será ativado amanhã de manhã"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartilhar áudio"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicione mais widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloqueie para personalizar widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone do app para widget desativado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícone do app para um widget que está sendo instalado"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets da tela de bloqueio"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Todos podem ver os widgets na tela de bloqueio, mesmo com o tablet bloqueado."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets da tela de bloqueio"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir um app usando um widget, você precisará confirmar sua identidade. Além disso, não se esqueça que qualquer pessoa pode ver os widgets, mesmo quando o tablet está bloqueado. Alguns widgets podem não ter sido criados para ficar na tela de bloqueio e fazer isso talvez não seja seguro."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendi"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Padrão"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Som e vibração desativados"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"O som e a vibração estão desativados, e o balão aparece na parte inferior da seção de conversa"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Pode vibrar ou tocar com base nas configurações do dispositivo"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Pode vibrar ou tocar com base nas configurações do dispositivo. As conversas do app <xliff:g id="APP_NAME">%1$s</xliff:g> aparecem em balões por padrão."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Faça com que o sistema determine se a notificação resultará em som ou vibração"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1051,7 +1053,7 @@
<string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Remover"</string>
<string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"alternar"</string>
<string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Editar"</string>
- <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
+ <string name="quick_controls_title" msgid="6839108006171302273">"Controles do disp."</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string>
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
@@ -1349,23 +1351,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em uso pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recentemente pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controles do sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps do sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarefas"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apps recentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Tela dividida"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atalhos de apps"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atalhos de pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gesto de volta"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gesto de início"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tecla de ação"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Concluído"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Muito bem!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Voltar"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para voltar, deslize para a esquerda ou direita usando 3 dedos em qualquer lugar do touchpad."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad mostrando 3 dedos deslizando para a direita e esquerda"</string>
@@ -1374,4 +1378,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Automação residencial"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Controles de automação residencial no protetor de tela"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
index 3526c77d1e24..b8811426835e 100644
--- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Desativado"</item>
<item msgid="4875147066469902392">"Ativado"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Indisponível"</item>
<item msgid="5044688398303285224">"Desativada"</item>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 93359e4c3d4b..963b47c9bc05 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"A app <xliff:g id="APPNAME">%1$s</xliff:g> detetou esta captura de ecrã."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"A app <xliff:g id="APPNAME">%1$s</xliff:g> e outras apps abertas detetaram esta captura de ecrã."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Adicionar a uma nota"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Gravador de ecrã"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"A processar a gravação de ecrã"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação persistente de uma sessão de gravação de ecrã"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao guardar a gravação de ecrã"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ocorreu um erro ao iniciar a gravação do ecrã."</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Vai parar de gravar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Vai parar de partilhar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Vai parar de transmitir &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Parar a gravação?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Neste momento, está a gravar todo o seu ecrã"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Neste momento, está a gravar a app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Parar gravação"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"A partilhar o ecrã"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Parar a partilha do ecrã?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Neste momento, está a partilhar todo o seu ecrã com a app <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Neste momento, está a partilhar todo o seu ecrã com uma app"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Neste momento, está a partilhar a app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Neste momento, está a partilhar uma app"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Parar partilha"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"A transmitir o ecrã"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Parar a transmissão?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Neste momento, está a transmitir todo o seu ecrã para o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Neste momento, está a transmitir todo o seu ecrã para um dispositivo próximo"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Neste momento, está a transmitir a app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> para o dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Neste momento, está a transmitir a app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> para um dispositivo próximo"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Neste momento, está a transmitir para o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Neste momento, está a transmitir para um dispositivo próximo"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Parar transmissão"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Fechar"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Registador de problemas"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"A proc. registo de problemas"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificação em curso de uma sessão de recolha de problemas"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Erro ao guardar o registo de problemas"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Erro ao iniciar o registo de problemas"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Visualização de ecrã inteiro"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Para sair, deslize rapidamente para baixo a partir da parte superior do ecrã"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Anterior"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Página inicial"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado com o rosto. Prima para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Prima para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Prima ícone de desbloqueio para continuar"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Desbloqueado com o rosto. Toque para continuar."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
@@ -291,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"Proteção ecrã"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Não incomodar"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"Modos de prioridade"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Sem dispositivos sincronizados disponíveis"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Toque para associar ou desassociar um dispositivo"</string>
@@ -302,8 +302,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desassociar"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Ativar automaticamente amanhã"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funcionalidades como a Partilha rápida e o serviço Localizar o meu dispositivo usam o Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"O Bluetooth vai ser ativado amanhã de manhã"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Partilhar áudio"</string>
@@ -472,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicionar mais widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar os widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloqueie para personalizar widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone da app do widget desativado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícone da app para um widget que está a ser instalado"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -490,12 +490,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets do ecrã de bloqueio"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Todos podem pode ver widgets no ecrã de bloqueio, mesmo com o tablet bloqueado."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets do ecrã de bloqueio"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir uma app através de um widget, vai ter de validar a sua identidade. Além disso, tenha em atenção que qualquer pessoa pode ver os widgets, mesmo quando o tablet estiver bloqueado. Alguns widgets podem não se destinar ao ecrã de bloqueio e pode ser inseguro adicioná-los aqui."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mudar utilizador"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pendente"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string>
@@ -717,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Predefinição"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sem som ou vibração"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sem som ou vibração e aparece na parte inferior na secção de conversas"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Pode tocar ou vibrar com base nas definições do dispositivo"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Pode tocar ou vibrar com base nas definições do dispositivo. As conversas da app <xliff:g id="APP_NAME">%1$s</xliff:g> aparecem como um balão por predefinição."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Faça com que o sistema determine se esta notificação deve emitir um som ou uma vibração"</string>
@@ -774,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Página para cima"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Página para baixo"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Eliminar"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Início"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Fim"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Inserir"</string>
@@ -1349,23 +1350,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em utilização pela app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recentemente pela app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controlos do sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps do sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Execução de várias tarefas em simultâneo"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apps recentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ecrã dividido"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atalhos de apps"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos de teclado"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atalhos de pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone de reduzir"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone de expandir"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gesto para retroceder"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gesto para aceder ao ecrã principal"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tecla de ação"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Concluir"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Muito bem!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Voltar"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para retroceder, deslize rapidamente para a esquerda ou direita com três dedos em qualquer parte do touchpad."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad a mostrar três dedos a moverem-se para a direita e esquerda"</string>
@@ -1374,4 +1377,5 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controlos domésticos"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Use controlos domésticos como proteção de ecrã"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"Anular"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
index 34a5ed7b2ca9..d7a245a1fbba 100644
--- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"Desligado"</item>
<item msgid="4875147066469902392">"Ligado"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"Indisponível"</item>
+ <item msgid="2004750556637773692">"Desativado"</item>
+ <item msgid="8968530753931637871">"Ativado"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Indisponível"</item>
<item msgid="5044688398303285224">"Desligada"</item>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 0c27fea268b3..1ab30c3bfaee 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"O app <xliff:g id="APPNAME">%1$s</xliff:g> detectou essa captura de tela."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outros apps abertos detectaram essa captura de tela."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Incluir anotação"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Gravador de tela"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao salvar a gravação da tela"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Você vai parar de gravar o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Você vai parar de compartilhar o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Você vai parar de transmitir o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Parar gravação?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Você está gravando a tela inteira"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Você está gravando o app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Parar gravação"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartilhando a tela"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Parar o compartilhamento de tela?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Você está compartilhando a tela inteira com o app <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Você está compartilhando a tela inteira com um app"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Você está compartilhando o app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Você está compartilhando um app"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Interromper compartilhamento"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Transmitindo a tela"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Parar transmissão?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Você está transmitindo a tela inteira para o <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Você está transmitindo a tela inteira para um dispositivo por perto"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Você está transmitindo o app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> para o <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Você está transmitindo o app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> para um dispositivo por perto"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Você está transmitindo para o <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Você está transmitindo para um dispositivo por perto"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Interromper transmissão"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Fechar"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Gravador de problemas"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processando a gravação do problema"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificação em andamento para uma sessão de coleta de problemas"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Erro ao salvar a gravação do problema"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Erro ao iniciar a gravação do problema"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Visualização em tela cheia"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Para sair, deslize de cima para baixo na tela"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Entendi"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Voltar"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Página inicial"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Desbloqueado pelo rosto. Toque para continuar."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Protetor de tela"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Não perturbe"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Não há dispositivos pareados disponíveis"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Toque para conectar ou desconectar um dispositivo"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvo"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Ativar automaticamente amanhã"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Recursos como o Quick Share e o Encontre Meu Dispositivo usam Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"O Bluetooth será ativado amanhã de manhã"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartilhar áudio"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicione mais widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloqueie para personalizar widgets"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone do app para widget desativado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícone do app para um widget que está sendo instalado"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets da tela de bloqueio"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Todos podem ver os widgets na tela de bloqueio, mesmo com o tablet bloqueado."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets da tela de bloqueio"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir um app usando um widget, você precisará confirmar sua identidade. Além disso, não se esqueça que qualquer pessoa pode ver os widgets, mesmo quando o tablet está bloqueado. Alguns widgets podem não ter sido criados para ficar na tela de bloqueio e fazer isso talvez não seja seguro."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendi"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Padrão"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Som e vibração desativados"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"O som e a vibração estão desativados, e o balão aparece na parte inferior da seção de conversa"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Pode vibrar ou tocar com base nas configurações do dispositivo"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Pode vibrar ou tocar com base nas configurações do dispositivo. As conversas do app <xliff:g id="APP_NAME">%1$s</xliff:g> aparecem em balões por padrão."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Faça com que o sistema determine se a notificação resultará em som ou vibração"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1051,7 +1053,7 @@
<string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Remover"</string>
<string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"alternar"</string>
<string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Editar"</string>
- <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
+ <string name="quick_controls_title" msgid="6839108006171302273">"Controles do disp."</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string>
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
@@ -1349,23 +1351,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em uso pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recentemente pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controles do sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps do sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarefas"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apps recentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Tela dividida"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atalhos de apps"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atalhos de pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gesto de volta"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gesto de início"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tecla de ação"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Concluído"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Muito bem!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Voltar"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para voltar, deslize para a esquerda ou direita usando 3 dedos em qualquer lugar do touchpad."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad mostrando 3 dedos deslizando para a direita e esquerda"</string>
@@ -1374,4 +1378,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Automação residencial"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Controles de automação residencial no protetor de tela"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
index 3526c77d1e24..b8811426835e 100644
--- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Desativado"</item>
<item msgid="4875147066469902392">"Ativado"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Indisponível"</item>
<item msgid="5044688398303285224">"Desativada"</item>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index eab31cecbe56..285a3ca92048 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a detectat această captură de ecran."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> și alte aplicații deschise au detectat această captură de ecran."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Adaugă în notă"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Include linkul"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Recorder pentru ecran"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Se procesează înregistrarea"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificare în curs pentru o sesiune de înregistrare a ecranului"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Atinge pentru a afișa"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Eroare la salvarea înregistrării ecranului"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Eroare la începerea înregistrării ecranului"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Nu vei mai înregistra &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Oprește înregistrarea"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Se permite accesul la ecran"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Oprești accesul la ecran?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Nu vei mai permite accesul la &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Nu mai permite accesul"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Se proiectează ecranul"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Oprești proiectarea?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Nu vei mai proiecta &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Oprește proiectarea"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Închide"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Instrument de înregistrare a problemelor"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Se procesează înregistrarea problemei"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificare în curs pentru o sesiune de înregistrare a problemei"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Eroare la salvarea înregistrării problemei"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Eroare la începerea înregistrării problemei"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Vizualizare pe ecran complet"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Pentru a ieși, glisează în jos din partea de sus a ecranului"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Înapoi"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Ecranul de pornire"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S-a deblocat cu ajutorul feței. Apasă pentru a continua."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Chipul a fost recunoscut. Apasă pentru a continua."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Chip recunoscut. Apasă pictograma Deblocare ca să continui."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"S-a deblocat folosind fața. Atinge pentru a continua."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificat"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anulează autentificarea"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mai multe opțiuni"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Screensaver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Nu deranja"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Niciun dispozitiv conectat disponibil"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Atinge pentru a conecta sau deconecta un dispozitiv"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvat"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"deconectează"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activează"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Activează automat mâine"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funcții precum Quick Share și Găsește-mi dispozitivul folosesc Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth se va activa mâine dimineață"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Trimite audio"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adaugă mai multe widgeturi"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Apasă lung pentru a personaliza widgeturi"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizează widgeturile"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Deblochează ca să personalizezi widgeturi"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Pictograma aplicației pentru widgetul dezactivat"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Pictograma aplicației pentru un widget care se instalează"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editează widgetul"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selectează un widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"elimină widgetul"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plasează widgetul selectat"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgeturi pe ecranul de blocare"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pentru a deschide o aplicație folosind un widget, va trebui să-ți confirmi identitatea. În plus, reține că oricine poate să vadă widgeturile, chiar dacă tableta este blocată. Este posibil ca unele widgeturi să nu fi fost create pentru ecranul de blocare și poate fi nesigur să le adaugi aici."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Schimbă utilizatorul"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"meniu vertical"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Prestabilite"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automat"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Fără sunet sau vibrații"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Fără sunet sau vibrații și apare în partea de jos a secțiunii de conversație"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Poate să sune sau să vibreze, în funcție de setările dispozitivului"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Poate să sune sau să vibreze, în funcție de setările dispozitivului. Conversațiile din balonul <xliff:g id="APP_NAME">%1$s</xliff:g> în mod prestabilit."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Solicită-i sistemului să stabilească dacă această notificare e sonoră sau cu vibrații."</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"O pagină mai sus"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"O pagină mai jos"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Șterge"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"La început"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"La final"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Inserează"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Se folosește pentru <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Folosit recent de <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Comenzile sistemului"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicații de sistem"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicații recente"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ecran împărțit"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Intrare"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Comenzi rapide pentru aplicații"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilitate"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Comenzi rapide de la tastatură"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Comenzi directe de căutare"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Pictograma de restrângere"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Pictograma de extindere"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"sau"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gestul Înapoi"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gestul Ecran de pornire"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tastă de acțiuni"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gata"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Excelent!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Înapoi"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pentru a reveni, glisează spre stânga sau spre dreapta cu trei degete oriunde pe touchpad."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad cu trei degete care se mișcă spre dreapta și spre stânga"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivelul %1$d din %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Comenzi pentru locuință"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Accesează comenzile pentru locuință ca screensaver"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
index a68f1408dd83..25a2959b561b 100644
--- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Dezactivată"</item>
<item msgid="4875147066469902392">"Activată"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Indisponibilă"</item>
<item msgid="5044688398303285224">"Dezactivată"</item>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index be63043ec4ce..507b8d185072 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" обнаружило создание скриншота."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" и другие запущенные продукты обнаружили создание скриншота."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Добавить в заметку"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Добавить ссылку"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Запись видео с экрана"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обработка записи с экрана…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущее уведомление для записи видео с экрана"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Нажмите, чтобы посмотреть."</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Не удалось сохранить запись видео с экрана."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Не удалось начать запись видео с экрана."</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Запись в приложении &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будет прекращена."</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Демонстрация экрана приложения &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будет прекращена."</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Трансляция из приложения &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будет прекращена."</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Остановить запись?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Вы записываете свой экран."</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Вы записываете экран приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Остановить запись"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Демонстрация экрана"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Закрыть совместный доступ к экрану?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Вы демонстрируете свой экран в приложении \"<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>\"."</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Вы демонстрируете свой экран в приложении."</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Вы демонстрируете экран приложения \"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>\"."</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Вы демонстрируете экран приложения."</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Закрыть доступ"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Трансляция экрана"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Прекратить трансляцию?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Вы транслируете свой экран на устройство \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Вы транслируете свой экран на устройство поблизости."</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Вы транслируете приложение \"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>\" на устройство \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\"."</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Вы транслируете приложение \"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>\" на устройство поблизости."</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Вы транслируете на устройство \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Вы транслируете на устройство поблизости."</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Остановить трансляцию"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Закрыть"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Запись проблем на видео"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Обрабатываем запись"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Текущее уведомление о записи проблемы на видео"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Не удалось сохранить запись."</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Не удалось начать запись."</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Полноэкранный режим"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Чтобы выйти, проведите вниз от верхнего края экрана"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"ОК"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Главный экран"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблокировано сканированием лица. Нажмите, чтобы продолжить."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицо распознано. Нажмите, чтобы продолжить."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицо распознано. Нажмите на значок разблокировки."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Сканирование лица выполнено. Нажмите, чтобы продолжить."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификация выполнена"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Отмена распознавания лица"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Ещё"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Заставка"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не беспокоить"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сохранено"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"отключить"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активировать"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Включить автоматически завтра"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth используется в таких функциях и сервисах, как \"Быстрая отправка\" и \"Найти устройство\""</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth включится завтра утром"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Отправить аудио"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Добавить виджеты"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Нажмите и удерживайте, чтобы настроить виджеты."</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Настроить виджеты"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Чтобы настроить виджеты, разблокируйте устройство."</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок приложения для отключенного виджета"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Значок приложения для устанавливаемого виджета"</string>
<string name="edit_widget" msgid="9030848101135393954">"Изменить виджет"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"выбрать виджет"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"удалить виджет"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"разместить выбранный виджет"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Виджеты на заблокированном экране"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Они видны всем, даже если планшет заблокирован."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виджеты на заблокированном экране"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Чтобы открыть приложение, используя виджет, вам нужно будет подтвердить свою личность. Обратите внимание, что виджеты видны всем, даже если планшет заблокирован. Некоторые виджеты не предназначены для использования на заблокированном экране. Добавлять их туда может быть небезопасно."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ОК"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Сменить пользователя."</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"раскрывающееся меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string>
@@ -549,12 +549,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Начать"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нет уведомлений."</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Новых уведомлений нет"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивные уведомления включены"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Если за короткий промежуток времени придет много уведомлений, громкость звуков и количество всплывающих окон будут уменьшены на срок до двух минут."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Отключить"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Разблокируйте, чтобы увидеть уведомления"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Устройством управляет один из родителей."</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик"</string>
@@ -720,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"По умолчанию"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Автоматически"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звука и вибрации"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звука или вибрации, появляется в нижней части списка разговоров"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Звонок или вибрация в зависимости от настроек устройства"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Звонок или вибрация в зависимости от настроек устройства. Разговоры из приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" по умолчанию появляются в виде всплывающего чата."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Система будет сама определять, включать ли звуковой сигнал или вибрацию для уведомления"</string>
@@ -777,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1351,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Сейчас используется приложением \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Недавно использовалось приложением \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Система"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Управление системой"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системные приложения"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Многозадачность"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Недавние приложения"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Разделение экрана"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ввод"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Ярлыки приложений"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Специальные возможности"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Быстрые клавиши"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Найти быстрые клавиши"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Свернуть\""</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок \"Развернуть\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Жест \"назад\""</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Жест \"на главный экран\""</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Клавиша действия"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Отлично!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Чтобы вернуться, проведите тремя пальцами влево или вправо по сенсорной панели."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Три пальца двигаются вправо и влево по сенсорной панели"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"На экране устройства показана анимация для жеста \"Назад\""</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Подсветка клавиатуры"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Уровень %1$d из %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Управление домом"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Быстрый доступ к управлению домом через заставку"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
index 592937c7b9f6..2a0314e0e8f0 100644
--- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Откл."</item>
<item msgid="4875147066469902392">"Вкл."</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Функция недоступна"</item>
<item msgid="5044688398303285224">"Откл."</item>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 7462df650e78..ebcfa9d57ab7 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> මෙම තිර රුව අනාවරණය කර ගෙන ඇත."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> සහ අනෙකුත් විවෘත යෙදුම් මෙම තිර රුව අනාවරණය කර ගෙන ඇත."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"සටහනට එක් කරන්න"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"සබැඳිය ඇතුළත් කරන්න"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"තිර රෙකෝඩරය"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"තිර පටිගත කිරීම සකසමින්"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"තිර පටිගත කිරීමේ සැසියක් සඳහා කෙරෙන දැනුම් දීම"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"බැලීමට තට්ටු කරන්න"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"තිර පටිගත කිරීම සුරැකීමේ දෝෂයකි"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"තිර පටිගත කිරීම ආරම්භ කිරීමේ දෝෂයකි"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ඔබ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; පටිගත කිරීම නතර කරනු ඇත"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"පටිගත කිරීම නවත්වන්න"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"තිරය ​​බෙදා ගැනීම"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"තිරය ​​බෙදා ගැනීම නවත්වන්න ද?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ඔබ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; බෙදා ගැනීම නතර කරනු ඇත"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"බෙදා ගැනීම නවත්වන්න"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"විකාශ තිරය"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"විකාශය නවතන්න ද?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ඔබ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; විකාශය නතර කරනු ඇත"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"විකාශය නවතන්න"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"වසන්න"</string>
<string name="issuerecord_title" msgid="286627115110121849">"ගැටලු රෙකෝඩරය"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ගැටලු වාර්තාව සැකසුම් කිරීම"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"ගැටලු එකතු කිරීමේ සැසියක් සඳහා දැනට පවතින දැනුම්දීම"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"ගැටලුව සටහන් කිරීම සුරැකීමේ දෝෂය"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"ගැටලුව වාර්තා කිරීම ආරම්භ කිරීමේ දෝෂය"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"මුළු තිරය බලමින්"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"පිටවීමට, ඔබේ තිරයෙහි ඉහළ සිට පහළට ස්වයිප් කරන්න"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"තේරුණා"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ආපසු"</string>
<string name="accessibility_home" msgid="5430449841237966217">"මුල් පිටුව"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"මුහුණ මගින් අගුලු හරින ලදි. ඉදිරියට යාමට ඔබන්න."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට ඔබන්න."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"මුහුණ මගින් අගුළු හරින ලදි. ඉදිරියට යාමට තට්ටු කරන්න."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"සත්‍යාපනය විය"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"සත්‍යාපනය අවලංගු කරන්න"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"තවත් විකල්ප"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"තිර සුරැකුම"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ඊතර නෙට්"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"බාධා නොකරන්න"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"බ්ලූටූත්"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"යුගල කළ උපාංග නොතිබේ"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"උපාංගයක් සම්බන්ධ කිරීමට හෝ විසන්ධි කිරීමට තට්ටු කරන්න"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"සුරැකිණි"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"විසන්ධි කරන්න"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"සක්‍රිය කරන්න"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"හෙට ස්වයංක්‍රීයව ක්‍රියාත්මක කරන්න"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ඉක්මන් බෙදා ගැනීම සහ මගේ උපාංගය සෙවීම වැනි විශේෂාංග බ්ලූටූත් භාවිත කරයි"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"බ්ලූටූත් හෙට උදේ සක්‍රීය වෙයි"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ශ්‍රව්‍ය බෙදා ගන්න"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"තවත් විජට් එක් කරන්න"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"විජට් අභිරුචිකරණය කිරීමට දිගු ඔබන්න"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"විජට්ටු අභිරුචි කරන්න"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"විජට් අභිරුචිකරණය කිරීමට අගුළු හරින්න"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"අබල කළ විජට් සඳහා යෙදුම් නිරූපකය"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"විජට්ටුවක් සඳහා ස්ථාපන කරනු ලබන යෙදුම් නිරූපකය"</string>
<string name="edit_widget" msgid="9030848101135393954">"විජට්ටු සංස්කරණ කරන්න"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"විජට්ටුව තෝරන්න"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"විජට්ටුව ඉවත් කරන්න"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"තෝරන ලද විජට්ටුව තබන්න"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"අගුළු තිර විජට්"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"විජට් එකක් භාවිතයෙන් යෙදුමක් විවෘත කිරීමට, ඔබට ඒ ඔබ බව සත්‍යාපනය කිරීමට අවශ්‍ය වනු ඇත. එසේම, ඔබේ ටැබ්ලටය අගුළු දමා ඇති විට පවා ඕනෑම කෙනෙකුට ඒවා බැලිය හැකි බව මතක තබා ගන්න. සමහර විජට් ඔබේ අගුළු තිරය සඳහා අදහස් කර නොතිබිය හැකි අතර මෙහි එක් කිරීමට අනාරක්ෂිත විය හැක."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"තේරුණා"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"පරිශීලක මාරුව"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"නිපතන මෙනුව"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"පෙරනිමි"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"ස්වයංක්‍රිය"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"හඬක් හෝ කම්පනයක් නැත"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"හඬක් හෝ කම්පනයක් නැති අතර සංවාද කොටසේ පහළම දිස් වේ"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"උපාංග සැකසීම් මත පදනම්ව නාද වීමට හෝ කම්පනය විය හැක"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"උපාංග සැකසීම් මත පදනම්ව නාද වීමට හෝ කම්පනය විය හැක. <xliff:g id="APP_NAME">%1$s</xliff:g> වෙතින් සංවාද පෙරනිමියෙන් බුබුළු දමයි."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"මෙම දැනුම් දීම ශබ්දයක් හෝ කම්පනයක් ඇති කළ යුතු ද යන්න පද්ධතිය මගින් තීරණය කර තිබේද"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up යතුර"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down යතුර"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete යතුර"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home යතුර"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End යතුර"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert යතුර"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> භාවිත කරයි (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> විසින් මෑතකදී භාවිත කරන ලදි (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"පද්ධතිය"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"පද්ධති පාලන"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"පද්ධති යෙදුම්"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"බහුකාර්ය"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"මෑත යෙදුම්"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"බෙදුම් තිරය"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ආදානය"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"යෙදුම් කෙටිමං"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ප්‍රවේශ්‍යතාව"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"යතුරු පුවරු කෙටි මං"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"කෙටි මං සොයන්න"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"හැකුළුම් නිරූපකය"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"දිගහැරීම් නිරූපකය"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"හෝ"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"ආපසු අභිනය"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"නිවෙස් අභිනය"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"ක්‍රියා යතුර"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"නිමයි"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"අනර්ඝ වැඩක්!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ආපස්සට යන්න"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ආපසු යාමට, ස්පර්ශ පුවරුවේ ඕනෑම තැනක ඇඟිලි තුනක් භාවිතයෙන් වමට හෝ දකුණට ස්වයිප් කරන්න."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ඇඟිලි තුනක් දකුණට සහ වමට චලනය වන බව පෙන්වන ස්පර්ශක පුවරුව"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dන් %1$d වැනි මට්ටම"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"නිවෙස් පාලන"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"තිර සුරැකුමක් ලෙස ඔබේ නිවසේ පාලන වෙත ඉක්මනින් ප්‍රවේශ වන්න"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml
index 681f3d52bc09..8d1f2619a1d4 100644
--- a/packages/SystemUI/res/values-si/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"අක්‍රියයි"</item>
<item msgid="4875147066469902392">"සක්‍රියයි"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"නොමැත"</item>
<item msgid="5044688398303285224">"අක්‍රියයි"</item>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 6202a7e92794..2f9931661f16 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikácia <xliff:g id="APPNAME">%1$s</xliff:g> zaznamenala túto snímku obrazovky."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> a ďalšie otvorené aplikácie zaznamenali túto snímku obrazovky."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pridať do poznámky"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Zahrnúť odkaz"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Rekordér obrazovky"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Spracúva sa záznam obrazovky"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Zobrazuje sa upozornenie týkajúce sa relácie záznamu obrazovky"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Zobrazte klepnutím"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Pri ukladaní nahrávky obrazovky sa vyskytla chyba"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pri spustení nahrávania obrazovky sa vyskytla chyba"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Prestante zaznamenávať obsah aplikácie &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Zastaviť nahrávanie"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Zdieľa sa obrazovka"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Chcete prestať zdieľať obrazovku?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Prestanete zdieľať obsah aplikácie &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Prestať zdieľať"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Prenáša sa obrazovka"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Chcete zastaviť prenos?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Prestanete prenášať obsah aplikácie &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Zastaviť prenos"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Zavrieť"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Nástroj na zaznamenávanie problémov"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Záznam problému sa spracúva"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Upozornenie na prebiehajúcu aktivitu týkajúcu sa relácie zhromažďovania problémov"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Pri ukladaní záznamu problému sa vyskytla chyba"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Pri spúšťaní záznamu problému sa vyskytla chyba"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Zobrazenie na celú obrazovku"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Ukončíte potiahnutím zhora obrazovky nadol"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Dobre"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Späť"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Plocha"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odomknuté tvárou. Pokračujte stlačením."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Tvár bola rozpoznaná. Pokračujte stlačením."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Tvár bola rozpoznaná. Pokračujte stlačením ikony odomknutia"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Odomknuté tvárou. Pokračujte klepnutím."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Overené"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Zrušiť overenie"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Ďalšie možnosti"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Šetrič obrazovky"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Režim bez vyrušení"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nie sú k dispozícii žiadne spárované zariadenia"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Klepnutím pripojíte alebo odpojíte zariadenie"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Uložené"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"odpojiť"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivovať"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automaticky zapnúť zajtra"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funkcie ako Quick Share a Nájdi moje zariadenie používajú Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth sa zapne zajtra ráno"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Zdieľať zvuk"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pridať ďalšie miniaplikácie"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Miniaplikácie prispôsobíte dlhým stlačením"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prispôsobiť miniaplikácie"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Odomknite a prispôsobte si miniaplikácie"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona deaktivovanej miniaplikácie"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona inštalovanej miniaplikácie"</string>
<string name="edit_widget" msgid="9030848101135393954">"Upraviť miniaplikáciu"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vybrať miniaplikáciu"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstrániť miniaplikáciu"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"prepnúť vybranú miniaplikáciu"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Miniaplikácie na uzamknutej obrazovke"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ak chcete otvoriť aplikáciu pomocou miniaplikácie, budete musieť overiť svoju totožnosť. Pamätajte, že si miniaplikáciu môže pozrieť ktokoľvek, aj keď máte tablet uzamknutý. Niektoré miniaplikácie možno nie sú určené pre uzamknutú obrazovku a ich pridanie tu môže byť nebezpečné."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Dobre"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Prepnutie používateľa"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbaľovacia ponuka"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Predvolené"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automaticky"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Žiadny zvuk ani vibrácie"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Žiadny zvuk ani vibrácie a zobrazuje sa nižšie v sekcii konverzácií"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Môže zvoniť či vibrovať podľa nastavení v zariadení"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Môže zvoniť alebo vibrovať podľa nastavení v zariadení. Predvolene sa zobrazia konverzácie z bubliny aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Nechajte systém určiť, či má toto upozornenie vydávať zvuk alebo vibrovať"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Posunúť o stranu vyššie"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Posunúť o stranu nižšie"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Odstrániť"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Domov"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Ukončiť"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Vložiť"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Využíva <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedávno využila aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Systém"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Ovládanie systému"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systémové aplikácie"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedávne aplikácie"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Rozdelená obrazovka"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Vstup"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Odkazy do aplikácií"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostupnosť"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové skratky"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Vyhľadávacie odkazy"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zbalenia"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozbalenia"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"alebo"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gesto prechodu späť"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gesto prechodu domov"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Akčný kláves"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hotovo"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Skvelé!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Prejsť späť"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ak chcete prejsť späť, potiahnite doľava alebo doprava troma prstami kdekoľvek na touchpade."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Tri prsty na touchpade pohybujúce sa doprava a doľava"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. úroveň z %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládanie domácnosti"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Rýchly prístup k ovládaniu domácnosti z šetriča obrazovky"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
index 6b5af805f15b..340af48ba576 100644
--- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Vypnuté"</item>
<item msgid="4875147066469902392">"Zapnuté"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nie je k dispozícii"</item>
<item msgid="5044688398303285224">"Vypnuté"</item>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 2f8dc70a03aa..ac78905d500e 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je zaznala ta posnetek zaslona."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> in druge odprte aplikacije so zaznale ta posnetek zaslona."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj v zapisek"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Vključi povezavo"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Snemalnik zaslona"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obdelava videoposnetka zaslona"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Nenehno obveščanje o seji snemanja zaslona"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Dotaknite se za ogled."</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Napaka pri shranjevanju posnetka zaslona"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Napaka pri začenjanju snemanja zaslona"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ustavili boste snemanje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ustavili boste deljenje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ustavili boste predvajanje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Želite ustaviti snemanje?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Trenutno snemate celotni zaslon"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Trenutno snemate aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Ustavi snemanje"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deljenje zaslona"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Želite ustaviti deljenje zaslona?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Trenutno delite celotni zaslon z aplikacijo <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Trenutno delite celotni zaslon z eno od aplikacij"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Trenutno delite aplikacijo <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Trenutno delite eno od aplikacij"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Ustavi deljenje"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Predvajanje vsebine zaslona"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Želite ustaviti predvajanje?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Trenutno predvajate celotni zaslon v napravi <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Trenutno predvajate celotni zaslon v napravi v bližini"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Trenutno predvajate aplikacijo <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> v napravi <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Trenutno predvajate aplikacijo <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> v napravi v bližini"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Trenutno predvajate v napravi <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Trenutno predvajate v napravi v bližini"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Ustavi predvajanje"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Zapri"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Snemalnik težav"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Obdelovanje posnetka težave"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Obvestilo o aktivni dejavnosti za sejo zbiranja težav"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Napaka pri shranjevanju posnetka težave"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Napaka pri zagonu snemanja težave"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Vklopljen je celozaslonski način."</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Če želite zapreti, povlecite navzdol z vrha zaslona"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Razumem"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Nazaj"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Začetni zaslon"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odklenjeno z obrazom. Pritisnite za nadaljevanje."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obraz je prepoznan. Pritisnite za nadaljevanje."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obraz je prepoznan. Za nadaljevanje pritisnite ikono za odklepanje."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Odklenjeno z obrazom. Dotaknite se, če želite nadaljevati."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Preverjena pristnost"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Prekliči preverjanje pristnosti"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Več možnosti"</string>
@@ -291,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"Ohranjeval. zaslona"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne moti"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"Prednostni načini"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Na voljo ni nobene seznanjene naprave"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Dotaknite se za vzpostavitev ali prekinitev povezave z napravo"</string>
@@ -302,8 +302,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Shranjeno"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekinitev povezave"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviranje"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Samodejno vklopi jutri"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funkcije, kot sta Hitro deljenje in Poišči mojo napravo, uporabljajo Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth se bo vklopil jutri zjutraj"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Deli zvok"</string>
@@ -472,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte več pripomočkov"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pridržite za prilagajanje pripomočkov"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagajanje pripomočkov"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Odklenite, če želite prilagoditi pripomočke"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogočen pripomoček"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za nameščanje pripomočka"</string>
<string name="edit_widget" msgid="9030848101135393954">"Urejanje pripomočka"</string>
@@ -490,12 +490,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"izberite pripomoček"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstranitev pripomočka"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavitev izbranega pripomočka"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Pripomočki na zaklenjenem zaslonu"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Pripomočki na zaklenjenem zaslonu so vidni vsem, tudi če je tablica zaklenjena."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Pripomočki na zaklenjenem zaslonu"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Če želite aplikacijo odpreti s pripomočkom, morate potrditi, da ste to vi. Upoštevajte tudi, da si jih lahko ogledajo vsi, tudi ko je tablični računalnik zaklenjen. Nekateri pripomočki morda niso predvideni za uporabo na zaklenjenem zaslonu, zato jih tukaj morda ni varno dodati."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Razumem"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Preklop med uporabniki"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"spustni meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string>
@@ -549,12 +548,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Začni zdaj"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ni obvestil"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ni novih obvestil"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Prilagodljiva obvestila so vklopljena"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Naprava za do dve minuti zmanjša glasnost in število pojavnih elementov na zaslonu, ko v kratkem času prejmete veliko obvestil."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Izklopi"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odklenite za ogled starejših obvestil"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"To napravo upravlja tvoj starš"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je lastnica te naprave in lahko nadzira omrežni promet"</string>
@@ -720,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Privzeto"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Samodejno"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Brez zvočnega opozarjanja ali vibriranja."</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Brez zvočnega opozarjanja ali vibriranja, prikaz nižje v razdelku Pogovor."</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Zvonjenje ali vibriranje je omogočeno na podlagi nastavitev naprave."</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Zvonjenje ali vibriranje je omogočeno na podlagi nastavitev naprave. Pogovori v aplikaciji <xliff:g id="APP_NAME">%1$s</xliff:g> so privzeto prikazani v oblačkih."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Naj sistem določi, ali ob prejemu tega obvestila naprava predvaja zvok ali zavibrira"</string>
@@ -777,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Stran gor"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Stran dol"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Izbriši"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Začetek"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Konec"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Vstavi"</string>
@@ -1352,33 +1350,32 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Uporablja aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno uporabljala aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemski kontrolniki"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemske aplikacije"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Večopravilnost"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Razdeljen zaslon"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Vnos"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Bližnjice do aplikacij"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Trenutna aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostopnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Bližnjične tipke"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Bližnjice za iskanje"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za strnitev"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za razširitev"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ali"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Poteza za pomik nazaj"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Poteza za začetni zaslon"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Gumb za dejanje"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Končano"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Odlično!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazaj"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Za pomik nazaj povlecite levo ali desno s tremi prsti kjer koli na sledilni ploščici."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Sledilna ploščica s tremi prsti, ki se premikajo desno in levo"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Zaslon naprave z animacijo, ki prikazuje potezo za pomik nazaj"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Osvetlitev tipkovnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Stopnja %1$d od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrolniki za dom"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Hiter dostop do kontrolnikov za dom na ohranjevalniku zaslona"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"Razveljavi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
index 5f60ffdaebf7..e57b87b794b3 100644
--- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"Izklopljeno"</item>
<item msgid="4875147066469902392">"Vklopljeno"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"Ni na voljo"</item>
+ <item msgid="2004750556637773692">"Izklopljeno"</item>
+ <item msgid="8968530753931637871">"Vklopljeno"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Ni na voljo"</item>
<item msgid="5044688398303285224">"Izklopljeno"</item>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index fcc19c19a0f7..926a73f4baab 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> zbuloi këtë pamje ekrani."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dhe aplikacionet e tjera të hapura zbuluan këtë pamje ekrani."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Shto te shënimi"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Përfshi lidhjen"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Regjistruesi i ekranit"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Regjistrimi i ekranit po përpunohet"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Njoftim i vazhdueshëm për një seancë regjistrimi të ekranit"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Trokit për të parë"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Gabim gjatë ruajtjes së regjistrimit të ekranit"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Gabim gjatë nisjes së regjistrimit të ekranit"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Do të ndalosh regjistrimin me &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Ndalo regjistrimin"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekrani po ndahet"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Të ndalohet ndarja e ekranit?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Do të ndalosh ndarjen e &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Ndalo ndarjen"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Po transmeton ekranin"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Të ndalohet transmetimi?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Do të ndalosh transmetimin e &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Ndalo transmetimin"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Mbyll"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Regjistruesi i problemeve"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Regjistrimi i problemeve me përpunimin"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Njoftim në vazhdim për një seancë për mbledhjen e problemeve"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Gabim gjatë ruajtjes së regjistrimit të problemit"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Gabim gjatë nisjes së regjistrimit të problemit"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Po shikon ekranin e plotë"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Për të dalë, rrëshqit shpejt poshtë nga kreu i ekranit"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"E kuptova"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Prapa"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Faqja bazë"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"U shkyç me fytyrë. Shtyp për të vazhduar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Fytyra u njoh. Shtyp për të vazhduar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Fytyra u njoh. Shtyp ikonën e shkyçjes për të vazhduar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"U shkyç me fytyrë. Trokit për të vazhduar."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"U vërtetua"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anulo vërtetimin"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Opsione të tjera"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Mbrojtësi i ekranit"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Eternet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Mos shqetëso"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth-i"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nuk ofrohet për përdorim asnjë pajisje e çiftuar"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Trokit për të lidhur ose shkëputur një pajisje"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Ruajtur"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"shkëput"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivizo"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Aktivizo automatikisht nesër"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Veçoritë e tilla si \"Ndarja e shpejtë\" dhe \"Gjej pajisjen time\" përdorin Bluetooth-in"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth-i do të aktivizohet nesër në mëngjes"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Ndaj audion"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Shto miniaplikacione të tjera"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Shtyp gjatë për të personalizuar miniaplikacionet"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizo miniaplikacionet"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Shkyç për të personalizuar miniaplikacionet"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona e aplikacionit për miniaplikacionin e çaktivizuar"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona e aplikacionit për një miniaplikacion që po instalohet"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modifiko miniaplikacionin"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"zgjidh miniaplikacionin"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"hiq miniaplikacionin"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"vendos miniaplikacionin e zgjedhur"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Kyç miniaplikacionet e ekranit"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Për të hapur një aplikacion duke përdorur një miniaplikacion, do të duhet të verifikosh që je ti. Ki parasysh gjithashtu që çdo person mund t\'i shikojë, edhe kur tableti yt është i kyçur. Disa miniaplikacione mund të mos jenë planifikuar për ekranin tënd të kyçjes dhe mund të mos jetë e sigurt t\'i shtosh këtu."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"E kuptova"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Ndërro përdorues"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyja me tërheqje poshtë"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Fillo tani"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Asnjë njoftim"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nuk ka njoftime të reja"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Njoftimet me përshtatje janë aktive"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Pajisja jote tani ul volumin dhe zvogëlon numrin e dritareve kërcyese në ekran për deri në dy minuta kur ti merr shumë njoftime në një periudhë të shkurtër kohe."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Çaktivizo"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Shkyç për të parë njoftimet e vjetra"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kjo pajisje menaxhohet nga prindi yt"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizata jote e zotëron këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"E parazgjedhur"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatike"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Asnjë tingull ose dridhje"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Asnjë tingull ose dridhje dhe shfaqet më poshtë në seksionin e bisedave"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Mund të bjerë zilja ose të dridhet në bazë të cilësimeve të pajisjes"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Mund të bjerë zilja ose të dridhet në bazë të cilësimeve të pajisjes. Bisedat nga flluska e <xliff:g id="APP_NAME">%1$s</xliff:g> si parazgjedhje."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Kërkoji sistemit të përcaktojë nëse ky njoftim duhet të lëshojë tingull apo dridhje"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Faqja lart"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Faqja poshtë"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Fshi"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Kreu"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Fundi"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Fut"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Në përdorim nga <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Përdorur së fundi nga <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistemi"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kontrollet e sistemit"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplikacionet e sistemit"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Kryerja e shumë detyrave"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplikacionet e fundit"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ekrani i ndarë"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Hyrja"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Shkurtoret e aplikacionit"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qasshmëria"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Shkurtoret e tastierës"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Kërko për shkurtoret"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona e palosjes"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona e zgjerimit"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ose"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Gjesti i kthimit prapa"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Gjesti për të shkuar tek ekrani bazë"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Tasti i veprimit"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"U krye"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Punë e shkëlqyer!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kthehu prapa"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Për t\'u kthyer prapa, rrëshqit shpejt majtas ose djathtas duke përdorur tre gishta kudo në bllokun me prekje."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Blloku me prekje që tregon tre gishta që lëvizin djathtas dhe majtas"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ekrani i pajisjes që tregon një animacion për gjestin e kthimit prapa"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Drita e sfondit e tastierës"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveli: %1$d nga %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrollet e shtëpisë"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Qasu te kontrollet e shtëpisë si mbrojtës ekrani"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index 9b5032eecbd8..4f42c308baa8 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Joaktiv"</item>
<item msgid="4875147066469902392">"Aktiv"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nuk ofrohet"</item>
<item msgid="5044688398303285224">"Joaktiv"</item>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index ad3eb2309083..e5b9445926e9 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Апликација <xliff:g id="APPNAME">%1$s</xliff:g> је открила овај снимак екрана."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и друге отворене апликације су откриле овај снимак екрана."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додај у белешку"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Уврсти линк"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Снимач екрана"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обрађујемо видео снимка екрана"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Обавештење о сесији снимања екрана је активно"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Додирните да бисте прегледали"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при чувању снимка екрана"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при покретању снимања екрана"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Зауставићете снимање за: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Зауставићете дељење за: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Зауставићете пребацивање за: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Желите да зауставите снимање?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Тренутно снимате цео екран"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Тренутно снимате: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Заустави снимање"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Екран се дели"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Желите да зауставите дељење екрана?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Тренутно делите цео екран са: <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Тренутно делите цео екран са апликацијом"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Тренутно делите: <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Тренутно делите апликацију"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Заустави дељење"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Пребацује се екран"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Желите да зауставите пребацивање?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Тренутно пребацујете цео екран на: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Тренутно пребацујете цео екран на уређај у близини"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> се тренутно пребацује на: <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> се тренутно пребацује на уређај у близини"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Тренутно пребацујете на: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Тренутно пребацујете на уређај у близини"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Заустави пребацивање"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Затвори"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Снимач проблема"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Обрађује се снимак проблема"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"обавештење о активности у току за сесију прикупљања података о проблему"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Грешка при чувању снимка проблема"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Грешка при покретању снимања проблема"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Приказује се цео екран"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Да бисте затворили, превуците надоле од врха екрана"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Важи"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Почетна"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Откључано је лицем. Притисните да бисте наставили."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лице је препознато. Притисните да бисте наставили."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лице препознато. Притисните икону откључавања за наставак."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Откључано је лицем. Додирните да бисте наставили."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Идентитет је потврђен"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Откажите потврду идентитета"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Још опција"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Чувар екрана"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Етернет"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не узнемиравај"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сачувано"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"прекините везу"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активирајте"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Аутоматски укључи сутра"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Функције као што су Quick Share и Пронађи мој уређај користе Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ће се укључити сутра ујутру"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Дели звук"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додајте још виџета"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Дуги притисак за прилагођавање виџета"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Прилагоди виџете"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Откључајте да бисте прилагодили виџете"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона апликације за онемогућен виџет"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Икона апликације за виџет који се инсталира"</string>
<string name="edit_widget" msgid="9030848101135393954">"Измени виџет"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"изаберите виџет"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"уклоните виџет"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"поставите изабрани виџет"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Виџети за закључани екран"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Сви могу да виде веџете на закључаном екрану, чак и када је таблет закључан."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виџети за закључани екран"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Да бисте отворили апликацију која користи виџет, треба да потврдите да сте то ви. Имајте у виду да свако може да га види, чак и када је таблет закључан. Неки виџети можда нису намењени за закључани екран и можда није безбедно да их тамо додате."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Важи"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Замени корисника"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падајући мени"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Подразумевано"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Аутоматска"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звука и вибрирања"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звука и вибрирања и приказује се у наставку одељка за конверзације"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Може да звони или вибрира у зависности од подешавања уређаја"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Може да звони или вибрира у зависности од подешавања уређаја. Конверзације из апликације <xliff:g id="APP_NAME">%1$s</xliff:g> подразумевано се приказују у облачићима."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Нека систем утврди да ли ово обавештење треба да емитује звук или да вибрира"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Тастер за страницу нагоре"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Тастер за страницу надоле"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Тастер за брисање"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Тастер Почетна"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Тастер за крај"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Тастер за уметање"</string>
@@ -1349,23 +1351,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Користе <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Недавно користила апликација <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Систем"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системске контроле"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системске апликације"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Обављање више задатака истовремено"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Недавне апликације"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Подељени екран"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Унос"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Пречице за апликације"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Актуелна апликација"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Приступачност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Тастерске пречице"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пречице претраге"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за скупљање"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за проширивање"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Покрет за враћање"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Покрет за почетну страницу"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Тастер радњи"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Одлично!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Да бисте се вратили, превуците улево или удесно са три прста било где на тачпеду."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Тачпед са приказом три прста који се померају удесно и улево"</string>
@@ -1374,4 +1378,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. ниво од %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Контроле за дом"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Брз приступ контролама за дом као чувару екрана"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
index 2acf1d264213..904fb23b1e77 100644
--- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Искључено"</item>
<item msgid="4875147066469902392">"Укључено"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Недоступно"</item>
<item msgid="5044688398303285224">"Искључено"</item>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 5bc3a26da819..68063d662786 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> identifierade skärmbilden."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> och andra öppna appar identifierade skärmbilden."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lägg till i anteckning"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Inkludera länk"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Skärminspelare"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandlar skärminspelning"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Avisering om att skärminspelning pågår"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tryck för att visa"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Det gick inte att spara skärminspelningen"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Det gick inte att starta skärminspelningen"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Du slutar att spela in &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Sluta spela in"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Skärmen delas"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vill du sluta dela skärmen?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Du slutar att dela &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Sluta dela"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Skärmen castas"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vill du sluta att casta?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Du slutar att casta &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Sluta casta"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Stäng"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Probleminspelare"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Behandlar probleminspelning"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Avisering om pågående probleminsamlingssession"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Det gick inte att spara probleminspelning"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Det gick inte att starta probleminspelning"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Visar på fullskärm"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Svep nedåt från skärmens överkant för att avsluta"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Tillbaka"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Startsida"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Upplåst med ansiktslås. Tryck för att fortsätta."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet har identifierats. Tryck för att fortsätta."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet har identifierats. Tryck på ikonen lås upp."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Upplåst med ansiktslås. Tryck för att fortsätta."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentiserad"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Avbryt autentiseringen"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Fler alternativ"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Skärmsläckare"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Stör ej"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Det finns inga kopplade enheter tillgängliga"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Tryck för att ansluta eller koppla från en enhet"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sparad"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"koppla från"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivera"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Aktivera automatiskt i morgon"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funktioner som Snabbdelning och Hitta min enhet använder Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth aktiveras i morgon bitti"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Dela ljud"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lägg till fler widgetar"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tryck länge för att anpassa widgetar"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Anpassa widgetar"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Lås upp för att anpassa widgetar"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon för inaktiverad widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikon för en widget som installeras"</string>
<string name="edit_widget" msgid="9030848101135393954">"Redigera widget"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"välj widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ta bort widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placera vald widget"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgetar för låsskärm"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Du måste verifiera din identitet innan du öppnar en app med en widget. Tänk också på att alla kan se dem, även när surfplattan är låst. Vissa widgetar kanske inte är avsedda för låsskärmen och det kan vara osäkert att lägga till dem här."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Byt användare"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullgardinsmeny"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alla appar och data i denna session kommer att raderas."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatiskt"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Inga ljud eller vibrationer"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Inga ljud eller vibrationer och visas längre ned bland konversationerna"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Kan ringa eller vibrera beroende på inställningarna på enheten"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Kan ringa eller vibrera beroende på inställningarna på enheten. Konversationer från <xliff:g id="APP_NAME">%1$s</xliff:g> visas i bubblor som standard."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Låt systemet avgöra om den här aviseringen ska låta eller vibrera"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Sida upp"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Sida ned"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Radera"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Start"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Slut"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Infoga"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Används av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Användes nyligen av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systeminställningar"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systemappar"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multikörning"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Senaste apparna"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Delad skärm"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ingång"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Genvägar till appar"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tillgänglighet"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Kortkommandon"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sökgenvägar"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikonen Komprimera"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikonen Utöka"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Tillbaka-rörelse"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Rörelse för att öppna startskärmen"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Åtgärdstangent"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Klar"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Bra jobbat!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Tillbaka"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Gå tillbaka genom att svepa åt vänster eller höger med tre fingrar var som helst på styrplattan."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Tre fingrar rör sig åt höger och vänster på en styrplatta"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Hemstyrning"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Kom snabbt åt hemstyrningen via skärmsläckaren"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
index cf49f8db2606..bd62fc146d33 100644
--- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Av"</item>
<item msgid="4875147066469902392">"På"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Inte tillgängligt"</item>
<item msgid="5044688398303285224">"Av"</item>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 368d5c579d50..986e00e5e539 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> imetambua picha hii ya skrini."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> na zingine zinazotumika zimetambua picha hii ya skrini."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ongeza kwenye dokezo"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Jumuisha kiungo"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Kinasa Skrini"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Inachakata rekodi ya skrini"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Arifa inayoendelea ya kipindi cha kurekodi skrini"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Gusa ili uangalie"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Hitilafu imetokea wakati wa kuhifadhi rekodi ya skrini"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Hitilafu imetokea wakati wa kuanza kurekodi skrini"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Utaacha kurekodi maudhui ya &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Acha kurekodi"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Inaruhusu ufikiaji kwenye skrini"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ungependa kuacha kuonyesha skrini?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Utakomesha ufikiaji wa maudhui ya &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Acha kuonyesha skrini"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Inatuma skrini"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Ungependa kuacha kutuma?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Utaacha kutuma maudhui ya &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Acha kutuma maudhui"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Funga"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Kifaa cha Kurekodi Hitilafu"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Mchakato wa kurekodi hitilafu unaendelea"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Arifa inayoendelea kuhusu kipindi cha ukusanyaji wa data ya hitilafu"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Hitilafu imetokea wakati wa kuhifadhi rekodi ya hitilafu"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Hitilafu imetokea wakati wa kuanza kurekodi hitilafu"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Unatazama kwenye skrini nzima"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Telezesha kidole chini kutoka sehemu ya juu ya skrini yako ili ufunge"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Nimeelewa"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Nyuma"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Nyumbani"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili uendelee."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Uso umetambuliwa. Bonyeza ili uendelee."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Uso umetambuliwa. Bonyeza aikoni ya kufungua ili uendelee."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Imefunguliwa kwa kutumia uso wako. Gusa ili uendelee."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Umethibitishwa"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Ghairi Uthibitishaji"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Chaguo Zaidi"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Taswira ya skrini"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Usinisumbue"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Hakuna vifaa vilivyooanishwa vinavyopatikana"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Gusa ili uunganishe au utenganishe kifaa"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Imehifadhiwa"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ondoa"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"anza kutumia"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Washa kesho kiotomatiki"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Vipengele kama vile Kutuma Haraka na Tafuta Kifaa Changu hutumia Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth itawaka kesho asubuhi"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Sikiliza pamoja na wengine"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Weka wijeti zingine"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Bonyeza kwa muda mrefu uweke mapendeleo ya wijeti"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Badilisha wijeti upendavyo"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Fungua ili ubadilishe wijeti upendavyo"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Aikoni ya programu ya wijeti iliyozimwa"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Aikoni ya programu ya wijeti inayowekwa"</string>
<string name="edit_widget" msgid="9030848101135393954">"Badilisha wijeti"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"chagua wijeti"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ondoa wijeti"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"weka wijeti uliyochagua"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Wijeti zinazoonekana kwenye skrini iliyofungwa"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Utahitaji kuthibitisha kuwa ni wewe ili ufungue programu ukitumia wijeti. Pia, kumbuka kuwa mtu yeyote anaweza kuziona, hata kishikwambi chako kikiwa kimefungwa. Huenda baadhi ya wijeti hazikukusudiwa kutumika kwenye skrini yako iliyofungwa na huenda si salama kuziweka hapa."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Nimeelewa"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Badili mtumiaji"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyu ya kuvuta chini"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Chaguomsingi"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Otomatiki"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Hakuna sauti wala mtetemo"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Hakuna sauti wala mtetemo na huonekana upande wa chini katika sehemu ya mazungumzo"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Huenda ikalia au kutetema kulingana na mipangilio ya kifaa"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Huenda ikalia au kutetema kulingana na mipangilio ya kifaa. Mazungumzo kutoka kiputo cha <xliff:g id="APP_NAME">%1$s</xliff:g> kwa chaguomsingi."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Ruhusu mfumo ubainishe iwapo arifa hii inapaswa kutoa sauti au mtetemo"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Futa"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Mwanzo"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Mwisho"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Ingiza"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Inatumiwa na <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Ilitumiwa hivi majuzi na <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Mfumo"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Vidhibiti vya mfumo"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Programu za mfumo"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Majukumu mengi"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Programu za hivi majuzi"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Gawa skrini"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Kifaa cha kuingiza data"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Njia za mikato za programu"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ufikivu"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Mikato ya kibodi"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Njia mkato za kutafutia"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kunja aikoni"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Panua aikoni"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"au"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Ishara ya kurudi nyuma"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Mguso wa kurudi kwenye skrini ya kwanza"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Kitufe cha vitendo"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Nimemaliza"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Kazi nzuri!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Rudi nyuma"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ili kurudi nyuma, telezesha vidole vitatu kushoto au kulia mahali popote kwenye padi ya kugusa."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Padi ya kugusa inayoonyesha vidole vitatu vikisonga kulia na kushoto"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Kiwango cha %1$d kati ya %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Dhibiti Vifaa Nyumbani"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Fikia haraka vidhibiti vya vifaa nyumbani vikiwa taswira ya skrini"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
index 15de7f88694c..b291f0dfee2c 100644
--- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Kimezimwa"</item>
<item msgid="4875147066469902392">"Kimewashwa"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Hakipatikani"</item>
<item msgid="5044688398303285224">"Kimezimwa"</item>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 702ad2275fc2..315e19872986 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"இந்த ஸ்கிரீன்ஷாட்டை <xliff:g id="APPNAME">%1$s</xliff:g> கண்டறிந்துள்ளது."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"இந்த ஸ்கிரீன்ஷாட்டை <xliff:g id="APPNAME">%1$s</xliff:g> மற்றும் திறந்திருக்கும் பிற ஆப்ஸ் கண்டறிந்துள்ளன."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"குறிப்பில் சேர்"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"இணைப்பைச் சேர்"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ஸ்கிரீன் ரெக்கார்டர்"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ஸ்க்ரீன் ரெக்கார்டிங் செயலாக்கப்படுகிறது"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"பார்க்கத் தட்டவும்"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"ஸ்கிரீன் ரெக்கார்டிங்கைச் சேமிப்பதில் பிழை ஏற்பட்டது"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ஸ்கிரீன் ரெக்கார்டிங்கைத் தொடங்குவதில் பிழை"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ஆப்ஸை ரெக்கார்டு செய்வதை நிறுத்துவீர்கள்"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ரெக்கார்டிங்கை நிறுத்து"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"திரையைப் பகிர்கிறது"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"திரையைப் பகிர்வதை நிறுத்தவா?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ஆப்ஸைப் பகிர்வதை நிறுத்துவீர்கள்"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"பகிர்வதை நிறுத்து"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"திரையை அலைபரப்புகிறது"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"அலைபரப்பை நிறுத்தவா?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ஆப்ஸை அலைபரப்புவதை நிறுத்துவீர்கள்"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"அலைபரப்புவதை நிறுத்து"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"மூடு"</string>
<string name="issuerecord_title" msgid="286627115110121849">"சிக்கல் ரெக்கார்டர்"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"சிக்கல் ரெக்கார்டிங்கைச் செயலாக்குகிறது"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"சிக்கல் சேகரிப்பு அமர்வுக்கான பின்னணிச் செயல்பாட்டின் அறிவிப்பு"</string>
@@ -158,13 +170,12 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"சிக்கல் தொடர்பான ரெக்கார்டிங்கைச் சேமிப்பதில் பிழை ஏற்பட்டது"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"சிக்கலை ரெக்கார்டிங் செய்யத் தொடங்குவதில் பிழை ஏற்பட்டது"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"முழுத் திரையில் காட்டுகிறது"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"வெளியேற, உங்கள் திரையின் மேலிருந்து கீழ்நோக்கி ஸ்வைப் செய்யவும்"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"சரி"</string>
<string name="accessibility_back" msgid="6530104400086152611">"பின்செல்"</string>
<string name="accessibility_home" msgid="5430449841237966217">"முகப்பு"</string>
<string name="accessibility_menu" msgid="2701163794470513040">"மெனு"</string>
- <string name="accessibility_accessibility_button" msgid="4089042473497107709">"அணுகல்தன்மை"</string>
+ <string name="accessibility_accessibility_button" msgid="4089042473497107709">"மாற்றுத்திறன் வசதி"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"திரையைச் சுழற்று"</string>
<string name="accessibility_recent" msgid="901641734769533575">"மேலோட்டப் பார்வை"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"கேமரா"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. தொடர அழுத்தவும்."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அழுத்தவும்."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அன்லாக் ஐகானை அழுத்தவும்."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"முகம் கொண்டு அன்லாக் செய்யப்பட்டது. தொடர தட்டவும்."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"அங்கீகரிக்கப்பட்டது"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"அங்கீகரிப்பை ரத்துசெய்"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"கூடுதல் விருப்பங்கள்"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"ஸ்கிரீன் சேவர்"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ஈதர்நெட்"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"தொந்தரவு செய்ய வேண்டாம்"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"புளூடூத்"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"இணைக்கப்பட்ட சாதனங்கள் இல்லை"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"சாதனத்தை இணைக்க/துண்டிக்க தட்டவும்"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"சேமிக்கப்பட்டது"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"இணைப்பு நீக்கும்"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"செயல்படுத்தும்"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"தானாகவே நாளை இயக்கப்படும்"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"விரைவுப் பகிர்தல், Find My Device போன்ற அம்சங்கள் புளூடூத்தைப் பயன்படுத்துகின்றன"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"நாளை காலை புளூடூத் இயக்கப்படும்"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ஆடியோவைப் பகிர்"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"கூடுதல் விட்ஜெட்களைச் சேருங்கள்"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"விட்ஜெட்களைப் பிரத்தியேகமாக்க நீண்ட நேரம் அழுத்துக"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"விட்ஜெட்களைப் பிரத்தியேகமாக்குங்கள்"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"விட்ஜெட்களைப் பிரத்தியேகப்படுத்த அன்லாக் செய்யுங்கள்"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"முடக்கப்பட்ட விட்ஜெட்டுக்கான ஆப்ஸ் ஐகான்"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"நிறுவப்படும் விட்ஜெட்டுக்கான ஆப்ஸ் ஐகான்"</string>
<string name="edit_widget" msgid="9030848101135393954">"விட்ஜெட்டைத் திருத்து"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"விட்ஜெட்டைத் தேர்ந்தெடுக்கும்"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"விட்ஜெட்டை அகற்றும்"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"தேர்ந்தெடுத்த விட்ஜெட்டைக் காட்சிப்படுத்தும்"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"பூட்டுத் திரை விட்ஜெட்கள்"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"விட்ஜெட்டைப் பயன்படுத்தி ஆப்ஸைத் திறக்க, அது நீங்கள்தான் என்பதை உறுதிசெய்ய வேண்டும். அத்துடன், உங்கள் டேப்லெட் பூட்டப்பட்டிருந்தாலும்கூட அவற்றை யார் வேண்டுமானாலும் பார்க்கலாம் என்பதை நினைவில்கொள்ளுங்கள். சில விட்ஜெட்கள் உங்கள் பூட்டுத் திரைக்காக உருவாக்கப்பட்டவை அல்ல என்பதையும் அவற்றை இங்கே சேர்ப்பது பாதுகாப்பற்றதாக இருக்கக்கூடும் என்பதையும் நினைவில்கொள்ளுங்கள்."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"சரி"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"பயனரை மாற்று"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"கீழ் இழுக்கும் மெனு"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா ஆப்ஸும் தரவும் நீக்கப்படும்."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"இப்போது தொடங்கு"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"அறிவிப்புகள் இல்லை"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"புதிய அறிவிப்புகள் இல்லை"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"சூழல்சார் அறிவிப்புகள் இயக்கப்பட்டது"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"குறைந்த நேரத்தில் அதிக அறிவிப்பைப் பெறும்போது இரண்டு நிமிடங்கள் வரை உங்கள் சாதனம் ஒலியையும், திரையில் காட்டப்படும் பாப்-அப்களின் எண்ணிக்கையையும் குறைக்கிறது."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"முடக்கு"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"பழைய அறிவிப்பைப் பார்க்க அன்லாக் செய்க"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"இந்தச் சாதனம் உங்கள் பெற்றோரால் நிர்வகிக்கப்படுகிறது"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு உரியது, நெட்வொர்க் ட்ராஃபிக்கையும் நிறுவனமே கண்காணிக்கக்கூடும்"</string>
@@ -639,7 +651,7 @@
<string name="stream_notification" msgid="7930294049046243939">"அறிவிப்பு"</string>
<string name="stream_bluetooth_sco" msgid="6234562365528664331">"புளூடூத்"</string>
<string name="stream_dtmf" msgid="7322536356554673067">"டூயல் டோன் மல்டி ஃப்ரீக்வென்சி"</string>
- <string name="stream_accessibility" msgid="3873610336741987152">"அணுகல்தன்மை"</string>
+ <string name="stream_accessibility" msgid="3873610336741987152">"மாற்றுத்திறன் வசதி"</string>
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"ஒலி"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"அதிர்வு"</string>
<string name="volume_ringer_status_silent" msgid="3691324657849880883">"அமைதி"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"இயல்புநிலை"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"தானியங்கு"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"ஒலி / அதிர்வு இல்லை"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ஒலி / அதிர்வு இல்லாமல் உரையாடல் பிரிவின் கீழ்ப் பகுதியில் தோன்றும்"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"சாதன அமைப்புகளைப் பொறுத்து ஒலிக்கக்கூடும் அல்லது அதிர்வடையக்கூடும்"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"சாதன அமைப்புகளைப் பொறுத்து ஒலிக்கக்கூடும் அல்லது அதிர்வடையக்கூடும். இயல்பாக, <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸில் பெறப்படும் உரையாடல் அறிவிப்புகள் குமிழ்களாகத் தோன்றும்."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"இந்த அறிவிப்பு ஒலி எழுப்ப வேண்டுமா அதிர வேண்டுமா என்பதை சிஸ்டம் தீர்மானிக்கும்"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"பேஜ் அப்"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"பேஜ் டவுன்"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"டெலிட்"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"ஹோம்"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"என்ட்"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"இன்சர்ட்"</string>
@@ -945,7 +960,7 @@
<string name="notification_channel_setup" msgid="7660580986090760350">"அமைவு"</string>
<string name="notification_channel_storage" msgid="2720725707628094977">"சேமிப்பிடம்"</string>
<string name="notification_channel_hints" msgid="7703783206000346876">"குறிப்புகள்"</string>
- <string name="notification_channel_accessibility" msgid="8956203986976245820">"அணுகல்தன்மை"</string>
+ <string name="notification_channel_accessibility" msgid="8956203986976245820">"மாற்றுத்திறன் வசதி"</string>
<string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
<string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> இயங்குகிறது"</string>
<string name="instant_apps_message" msgid="6112428971833011754">"நிறுவ வேண்டிய தேவையில்லாமல் ஆப்ஸ் திறக்கப்பட்டது."</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ஆப்ஸால் பயன்படுத்தப்படுகிறது"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ஆப்ஸால் சமீபத்தில் பயன்படுத்தப்பட்டது"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"சிஸ்டம்"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"சிஸ்டம் கட்டுப்பாடுகள்"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"சிஸ்டம் ஆப்ஸ்"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"பல வேலைகளைச் செய்தல்"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"சமீபத்திய ஆப்ஸ்"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"திரைப் பிரிப்பு"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"உள்ளீடு"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ஆப்ஸ் ஷார்ட்கட்கள்"</string>
- <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"அணுகல்தன்மை"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
+ <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"மாற்றுத்திறன் வசதி"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"கீபோர்டு ஷார்ட்கட்கள்"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"தேடல் ஷார்ட்கட்கள்"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"சுருக்குவதற்கான ஐகான்"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"விரிவாக்குவதற்கான ஐகான்"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"அல்லது"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"பின்செல்வதற்கான சைகை"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"முகப்பிற்குச் செல்வதற்கான சைகை"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"ஆக்ஷன் பட்டன்"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"முடிந்தது"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"அருமை!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"பின்செல்"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"பின்செல்ல, உங்கள் டச்பேடில் எங்கு வேண்டுமானாலும் இடது அல்லது வலதுபுறமாக மூன்று விரல்களால் ஸ்வைப் செய்யவும்."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"மூன்று விரல்கள் வலது மற்றும் இடதுபுறம் நகர்வதை டச்பேட் காட்டுகிறது"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"பின்செல்லும் சைகைக்கான அனிமேஷனை சாதனத்தின் திரை காட்டுகிறது"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"கீபோர்டு பேக்லைட்"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"நிலை, %2$d இல் %1$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ஹோம் கன்ட்ரோல்கள்"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"ஹோம் கன்ட்ரோல்களை ஸ்கிரீன் சேவராக அணுகலாம்"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
index a3b9538f891c..a180f4907a18 100644
--- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"முடக்கப்பட்டுள்ளது"</item>
<item msgid="4875147066469902392">"இயக்கப்பட்டுள்ளது"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"கிடைக்கவில்லை"</item>
<item msgid="5044688398303285224">"முடக்கப்பட்டுள்ளது"</item>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 3dd729379bf4..87e205bfec16 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>, ఈ స్క్రీన్‌షాట్‌ను గుర్తించింది."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>, ఇతర ఓపెన్ యాప్‌లు ఈ స్క్రీన్‌షాట్‌ను గుర్తించాయి."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"గమనికకు జోడించండి"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"లింక్‌ను చేర్చండి"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"స్క్రీన్ రికార్డర్"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"స్క్రీన్ రికార్డింగ్ అవుతోంది"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"స్క్రీన్ రికార్డ్ సెషన్ కోసం ఆన్‌గోయింగ్ నోటిఫికేషన్"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"చూడటానికి ట్యాప్ చేయండి"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"స్క్రీన్ రికార్డింగ్‌ను సేవ్ చేయడంలో ఎర్రర్ ఏర్పడింది"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"స్క్రీన్ రికార్డింగ్ ప్రారంభించడంలో ఎర్రర్ ఏర్పడింది"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"మీరు &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను రికార్డ్ చేయడం ఆపివేస్తారు"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"మీరు &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను షేర్ చేయడం ఆపివేస్తారు"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"మీరు &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను ప్రసారం చేయడం ఆపివేస్తారు"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"రికార్డింగ్‌ను ఆపివేయాలా?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"మీరు ప్రస్తుతం మీ మొత్తం స్క్రీన్‌ను రికార్డ్ చేస్తున్నారు"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"మీరు ప్రస్తుతం <xliff:g id="APP_NAME">%1$s</xliff:g>‌ను రికార్డ్ చేస్తున్నారు"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"రికార్డింగ్‌ను ఆపివేయండి"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"స్క్రీన్‌ను షేర్ చేస్తోంది"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"స్క్రీన్‌ను షేర్ చేయడం ఆపివేయాలా?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"మీరు ప్రస్తుతం మీ మొత్తం స్క్రీన్‌ను <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>‌తో షేర్ చేస్తున్నారు"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"మీరు ప్రస్తుతం మీ మొత్తం స్క్రీన్‌ను యాప్‌తో షేర్ చేస్తున్నారు"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"మీరు ప్రస్తుతం <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>‌ను షేర్ చేస్తున్నారు"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"మీరు ప్రస్తుతం యాప్‌ను షేర్ చేస్తున్నారు"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"షేర్ చేయడాన్ని ఆపివేయండి"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"స్క్రీన్‌ను ప్రసారం చేస్తోంది"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ప్రసారం చేయడం ఆపివేయాలా?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"మీరు ప్రస్తుతం మీ స్క్రీన్ మొత్తాన్ని <xliff:g id="DEVICE_NAME">%1$s</xliff:g>‌కు ప్రసారం చేస్తున్నారు"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"మీరు ప్రస్తుతం మీ స్క్రీన్ మొత్తాన్ని సమీపంలోని పరికరానికి ప్రసారం చేస్తున్నారు"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"మీరు ప్రస్తుతం <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>‌ను <xliff:g id="DEVICE_NAME">%2$s</xliff:g>‌కు ప్రసారం చేస్తున్నారు"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"మీరు ప్రస్తుతం <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>‌ను సమీపంలోని పరికరానికి ప్రసారం చేస్తున్నారు"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"మీరు ప్రస్తుతం <xliff:g id="DEVICE_NAME">%1$s</xliff:g>‌కు ప్రసారం చేస్తున్నారు"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"మీరు ప్రస్తుతం సమీపంలోని పరికరానికి ప్రసారం చేస్తున్నారు"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"ప్రసారాన్ని ఆపివేయండి"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"మూసివేయండి"</string>
<string name="issuerecord_title" msgid="286627115110121849">"సమస్య రికార్డర్"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"సమస్య రికార్డింగ్ ప్రాసెసింగ్"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"సమస్య సేకరణ సెషన్ కోసం కొనసాగుతోన్న నోటిఫికేషన్"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"సమస్య రికార్డింగ్‌ను సేవ్ చేయడంలో ఎర్రర్ ఏర్పడింది"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"సమస్య రికార్డింగ్‌ను ప్రారంభించడంలో ఎర్రర్ ఏర్పడింది"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"ఫుల్ స్క్రీన్‌లో చూస్తున్నారు"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"ఎగ్జిట్ అవ్వడానికి, మీ స్క్రీన్ పై నుండి కిందికి స్వైప్ చేయండి"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"సరే"</string>
<string name="accessibility_back" msgid="6530104400086152611">"వెనుకకు"</string>
<string name="accessibility_home" msgid="5430449841237966217">"హోమ్"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. కొనసాగించడానికి నొక్కండి."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ముఖం గుర్తించబడింది. కొనసాగించడానికి నొక్కండి."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ముఖం గుర్తించబడింది. కొనసాగడానికి అన్‌లాక్ చిహ్నం నొక్కండి."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ముఖం ద్వారా అన్‌లాక్ అయింది. కొనసాగడానికి ట్యాప్ చేయండి."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ప్రామాణీకరించబడింది"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ప్రామాణీకరణను రద్దు చేయండి"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"మరిన్ని ఆప్షన్‌లు"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"స్క్రీన్ సేవర్"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ఈథర్‌నెట్"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"అంతరాయం కలిగించవద్దు"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"బ్లూటూత్"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"జత చేసిన పరికరాలు ఏవీ అందుబాటులో లేవు"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"పరికరాన్ని కనెక్ట్ చేయడానికి లేదా డిస్‌కనెక్ట్ చేయడానికి ట్యాప్ చేయండి"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"సేవ్ అయ్యింది"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"డిస్‌కనెక్ట్ చేయండి"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"యాక్టివేట్ చేయండి"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"రేపు ఆటోమేటిక్‌గా ఆన్ చేస్తుంది"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"క్విక్ షేర్, Find My Device వంటి ఫీచర్‌లు బ్లూటూత్‌ను ఉపయోగిస్తాయి"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"బ్లూటూత్ రేపు ఉదయం ఆన్ అవుతుంది"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ఆడియోను షేర్ చేయండి"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"మరిన్ని విడ్జెట్‌లను జోడించండి"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"విడ్జెట్‌లను అనుకూలీకరించడానికి, నొక్కి, ఉంచండి"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"విడ్జెట్‌లను అనుకూలంగా మార్చండి"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"విడ్జెట్‌లను అనుకూలంగా మార్చుకోవడానికి అన్‌లాక్ చేయండి"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"డిజేబుల్ చేయబడిన విడ్జెట్ కోసం యాప్ చిహ్నం"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ఇన్‌స్టాల్ చేస్తున్న విడ్జెట్ కోసం యాప్ చిహ్నం"</string>
<string name="edit_widget" msgid="9030848101135393954">"విడ్జెట్‌ను ఎడిట్ చేయండి"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"విడ్జెట్‌ను ఎంచుకోండి"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"విడ్జెట్‌ను తీసివేయండి"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ఎంచుకున్న విడ్జెట్ కోసం ప్లేస్‌ను ఎంచుకోండి"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"లాక్ స్క్రీన్ విడ్జెట్‌లు"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"మీ టాబ్లెట్ లాక్ చేసి ఉన్నా, మీ లాక్ స్క్రీన్‌లో విడ్జెట్‌లను ఎవరైనా చూడవచ్చు."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"లాక్ స్క్రీన్ విడ్జెట్‌లు"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"విడ్జెట్‌ను ఉపయోగించి యాప్‌ను తెరవడానికి, ఇది మీరేనని వెరిఫై చేయాల్సి ఉంటుంది. అలాగే, మీ టాబ్లెట్ లాక్ చేసి ఉన్నప్పటికీ, ఎవరైనా వాటిని చూడగలరని గుర్తుంచుకోండి. కొన్ని విడ్జెట్‌లు మీ లాక్ స్క్రీన్‌కు తగినవి కాకపోవచ్చు, వాటిని ఇక్కడ జోడించడం సురక్షితం కాకపోవచ్చు."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"అర్థమైంది"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"వినియోగదారుని మార్చు"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"పుల్‌డౌన్ మెనూ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్‌లోని అన్ని యాప్‌లు మరియు డేటా తొలగించబడతాయి."</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ఆటోమేటిక్ సెట్టింగ్"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"ఆటోమేటిక్"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"సౌండ్ లేదా వైబ్రేషన్‌లు ఏవీ ఉండవు"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"శబ్దం లేదా వైబ్రేషన్ లేదు, సంభాషణ విభాగం దిగువన కనిపిస్తుంది"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"పరికర సెట్టింగ్‌ల ఆధారంగా రింగ్ లేదా వైబ్రేట్ కావచ్చు"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"పరికర సెట్టింగ్‌ల ఆధారంగా రింగ్ లేదా వైబ్రేట్ కావచ్చు. <xliff:g id="APP_NAME">%1$s</xliff:g> నుండి సంభాషణలు ఆటోమేటిక్‌గా బబుల్‌లో కనిపిస్తాయి."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ఈ నోటిఫికేషన్ వచ్చినప్పుడు శబ్దం చేయాలా లేదా వైబ్రేట్ చేయాలా అనేది నిర్ణయించడానికి సిస్టమ్‌కు అనుమతి ఇవ్వండి"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1351,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ద్వారా వినియోగంలో ఉంది"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ద్వారా ఇటీవల ఉపయోగించబడింది"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"సిస్టమ్"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"సిస్టమ్ కంట్రోల్స్"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"సిస్టమ్ యాప్‌లు"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"మల్టీ-టాస్కింగ్"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ఇటీవలి యాప్‌లు"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"స్ప్లిట్ స్క్రీన్"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ఇన్‌పుట్"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"యాప్ షార్ట్‌కట్‌లు"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ప్రస్తుత యాప్"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"యాక్సెసిబిలిటీ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"కీబోర్డ్ షార్ట్‌కట్‌లు"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"సెర్చ్ షార్ట్‌కట్‌లు"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"కుదించండి చిహ్నం"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"విస్తరించండి చిహ్నం"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"లేదా"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"వెనుకకు పంపే సంజ్ఞ"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"హోమ్‌కు పంపే సంజ్ఞ"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"యాక్షన్ కీ"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"పూర్తయింది"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"విజయవంతమైంది!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"వెనుకకు"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"వెనుకకు వెళ్లడానికి, టచ్‌ప్యాడ్‌లో ఎక్కడైనా మూడు వేళ్లను ఉపయోగించి ఎడమ లేదా కుడికి స్వైప్ చేయండి."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"మూడు వేళ్లు కుడి, ఎడమకు కదులుతున్నట్లు చూపే టచ్‌ప్యాడ్"</string>
@@ -1374,4 +1378,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dలో %1$dవ స్థాయి"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"హోమ్ కంట్రోల్స్"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"హోమ్ కంట్రోల్స్‌ను స్క్రీన్ సేవర్‌గా చేసి వేగంగా యాక్సెస్ పొందండి"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml
index 6584cdd59282..609a846cd936 100644
--- a/packages/SystemUI/res/values-te/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"ఆఫ్‌లో ఉంది"</item>
<item msgid="4875147066469902392">"ఆన్‌లో ఉంది"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"అందుబాటులో లేదు"</item>
<item msgid="5044688398303285224">"ఆఫ్‌లో ఉంది"</item>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 92f4bc98c706..6449dd85056f 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ตรวจพบภาพหน้าจอนี้"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> และแอปอื่นๆ ที่เปิดอยู่ตรวจพบภาพหน้าจอนี้"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"เพิ่มลงในโน้ต"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"รวมลิงก์"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"โปรแกรมบันทึกหน้าจอ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"กำลังประมวลผลการอัดหน้าจอ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการบันทึกหน้าจอ"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"แตะเพื่อดู"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"เกิดข้อผิดพลาดในการบันทึกหน้าจอ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"เกิดข้อผิดพลาดขณะเริ่มบันทึกหน้าจอ"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"คุณจะหยุดการบันทึก &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"คุณจะหยุดการแชร์ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"คุณจะหยุดการแคสต์ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"หยุดบันทึกใช่ไหม"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"คุณกำลังบันทึกทั้งหน้าจอ"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"คุณกำลังบันทึก <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"หยุดบันทึก"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"กำลังแชร์หน้าจอ"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"หยุดแชร์หน้าจอไหม"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"คุณกำลังแชร์ทั้งหน้าจอกับ <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"คุณกำลังแชร์ทั้งหน้าจอกับแอป"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"คุณกำลังแชร์ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"คุณกำลังแชร์แอป"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"หยุดแชร์"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"กำลังแคสต์หน้าจอ"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"หยุดการแคสต์ไหม"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"คุณกำลังแคสต์ทั้งหน้าจอไปยัง <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"คุณกำลังแคสต์ทั้งหน้าจอไปยังอุปกรณ์ที่อยู่ใกล้เคียง"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"คุณกำลังแคสต์ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ไปยัง <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"คุณกำลังแคสต์ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ไปยังอุปกรณ์ที่อยู่ใกล้เคียง"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"คุณกำลังแคสต์ไปยัง <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"คุณกำลังแคสต์ไปยังอุปกรณ์ที่อยู่ใกล้เคียง"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"หยุดแคสต์"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"ปิด"</string>
<string name="issuerecord_title" msgid="286627115110121849">"โปรแกรมบันทึกปัญหา"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"กำลังประมวลผลการบันทึกปัญหา"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการรวบรวมปัญหา"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"เกิดข้อผิดพลาดในการบันทึกไฟล์บันทึกปัญหา"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"เกิดข้อผิดพลาดในการเริ่มบันทึกปัญหา"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"กำลังดูแบบเต็มหน้าจอ"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"หากต้องการออก ให้ปัดลงจากด้านบนของหน้าจอ"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"รับทราบ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"กลับ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"หน้าแรก"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ปลดล็อกด้วยใบหน้าแล้ว กดเพื่อดำเนินการต่อ"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"จดจำใบหน้าได้ กดเพื่อดำเนินการต่อ"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"จดจำใบหน้าได้ กดไอคอนปลดล็อกเพื่อดำเนินการต่อ"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ปลดล็อกด้วยใบหน้าแล้ว แตะเพื่อดำเนินการต่อ"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ตรวจสอบสิทธิ์แล้ว"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ยกเลิกการตรวจสอบสิทธิ์"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ตัวเลือกเพิ่มเติม"</string>
@@ -291,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"ภาพพักหน้าจอ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"อีเทอร์เน็ต"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"ห้ามรบกวน"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"โหมดสำคัญ"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"บลูทูธ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ไม่มีอุปกรณ์ที่จับคู่ที่สามารถใช้ได้"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"แตะเพื่อเชื่อมต่อหรือยกเลิกการเชื่อมต่ออุปกรณ์"</string>
@@ -302,8 +302,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"บันทึกแล้ว"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ยกเลิกการเชื่อมต่อ"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"เปิดใช้งาน"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"เปิดอัตโนมัติในวันพรุ่งนี้"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ฟีเจอร์ต่างๆ เช่น Quick Share และ \"หาอุปกรณ์ของฉัน\" ใช้บลูทูธ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"บลูทูธจะเปิดพรุ่งนี้เช้า"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"แชร์เสียง"</string>
@@ -472,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"เพิ่มวิดเจ็ตอีก"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"กดค้างเพื่อปรับแต่งวิดเจ็ต"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ปรับแต่งวิดเจ็ต"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ปลดล็อกเพื่อปรับแต่งวิดเจ็ต"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ไอคอนแอปสำหรับวิดเจ็ตที่ปิดใช้อยู่"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ไอคอนแอปสำหรับวิดเจ็ตที่กำลังติดตั้ง"</string>
<string name="edit_widget" msgid="9030848101135393954">"แก้ไขวิดเจ็ต"</string>
@@ -490,12 +490,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"เลือกวิดเจ็ต"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"นำวิดเจ็ตออก"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"จัดวางวิดเจ็ตที่เลือก"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"วิดเจ็ตในหน้าจอล็อก"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"ทุกคนจะดูวิดเจ็ตที่อยู่ในหน้าจอล็อกของคุณได้ แม้ว่าแท็บเล็ตจะล็อกอยู่ก็ตาม"</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"วิดเจ็ตในหน้าจอล็อก"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"หากต้องการเปิดแอปโดยใช้วิดเจ็ต คุณจะต้องยืนยันตัวตนของคุณ นอกจากนี้ โปรดทราบว่าผู้อื่นจะดูวิดเจ็ตเหล่านี้ได้แม้ว่าแท็บเล็ตจะล็อกอยู่ก็ตาม วิดเจ็ตบางอย่างอาจไม่ได้มีไว้สำหรับหน้าจอล็อกของคุณ และอาจไม่ปลอดภัยที่จะเพิ่มที่นี่"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"รับทราบ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"สลับผู้ใช้"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"เมนูแบบเลื่อนลง"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string>
@@ -549,12 +548,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"เริ่มเลย"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ไม่มีการแจ้งเตือน"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ไม่มีการแจ้งเตือนใหม่"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"การแจ้งเตือนแบบปรับอัตโนมัติเปิดอยู่"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"จากนี้ไปอุปกรณ์จะลดระดับเสียงและจำนวนป๊อปอัปบนหน้าจอสูงสุด 2 นาทีเมื่อคุณได้รับการแจ้งเตือนจำนวนมากในระยะเวลาสั้นๆ"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ปิด"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ปลดล็อกเพื่อดูการแจ้งเตือนเก่า"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"อุปกรณ์นี้จัดการโดยผู้ปกครอง"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย"</string>
@@ -720,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ค่าเริ่มต้น"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"อัตโนมัติ"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"ไม่มีเสียงหรือการสั่น"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ไม่มีเสียงหรือการสั่น และปรากฏต่ำลงมาในส่วนการสนทนา"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"อาจส่งเสียงหรือสั่นโดยขึ้นอยู่กับการตั้งค่าอุปกรณ์"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"อาจส่งเสียงหรือสั่นโดยขึ้นอยู่กับการตั้งค่าอุปกรณ์ การสนทนาจาก <xliff:g id="APP_NAME">%1$s</xliff:g> จะแสดงเป็นบับเบิลโดยค่าเริ่มต้น"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ให้ระบบพิจารณาว่าจะให้การแจ้งเตือนนี้ส่งเสียงหรือสั่นหรือไม่"</string>
@@ -777,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"เลื่อนหน้าขึ้น"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"เลื่อนหน้าลง"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"ลบ"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"แทรก"</string>
@@ -1352,33 +1350,33 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"ใช้อยู่โดย <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ใช้ล่าสุดโดย <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ระบบ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"การควบคุมระบบ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"แอประบบ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"การทํางานหลายอย่างพร้อมกัน"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"แอปล่าสุด"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"แยกหน้าจอ"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"อินพุต"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"แป้นพิมพ์ลัดของแอป"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"การช่วยเหลือพิเศษ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"แป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ค้นหาแป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ไอคอนยุบ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ไอคอนขยาย"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"หรือ"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"ท่าทางสัมผัสสำหรับย้อนกลับ"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"ท่าทางสัมผัสสำหรับหน้าแรก"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"ปุ่มดำเนินการ"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"เสร็จสิ้น"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"เก่งมาก"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ย้อนกลับ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"หากต้องการย้อนกลับ ให้ใช้ 3 นิ้วปัดไปทางซ้ายหรือขวาที่ใดก็ได้บนทัชแพด"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ทัชแพดแสดงภาพ 3 นิ้วเลื่อนไปทางขวาและซ้าย"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"หน้าจออุปกรณ์แสดงภาพเคลื่อนไหวของท่าทางสัมผัสย้อนกลับ"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ไฟแบ็กไลต์ของแป้นพิมพ์"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"ระดับที่ %1$d จาก %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ระบบควบคุมอุปกรณ์สมาร์ทโฮม"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"เข้าถึงระบบควบคุมอุปกรณ์สมาร์ทโฮมได้อย่างรวดเร็วผ่านภาพพักหน้าจอ"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"เลิกทำ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml
index 8b7187b66baa..20f66da1bfe0 100644
--- a/packages/SystemUI/res/values-th/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"ปิด"</item>
<item msgid="4875147066469902392">"เปิด"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"ไม่พร้อมใช้งาน"</item>
+ <item msgid="2004750556637773692">"ปิด"</item>
+ <item msgid="8968530753931637871">"เปิด"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ไม่พร้อมใช้งาน"</item>
<item msgid="5044688398303285224">"ปิด"</item>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index d8c819f6c369..e52ebccf58fb 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Na-detect ng <xliff:g id="APPNAME">%1$s</xliff:g> ang screenshot. na ito"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Na-detect ng <xliff:g id="APPNAME">%1$s</xliff:g> at ng iba pang bukas na app ang screenshot na ito."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Idagdag sa tala"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Isama ang link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Recorder ng Screen"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pinoproseso screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Kasalukuyang notification para sa session ng pag-record ng screen"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"I-tap para tingnan"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Nagka-error sa pag-save ng recording ng screen"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Nagkaroon ng error sa pagsisimula ng pag-record ng screen"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Hihinto ka sa pag-record ng &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Hihinto ka sa pagbabahagi ng &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Hihinto ka sa pag-cast ng &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Ihinto ang pag-record?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Kasalukuyan mong nire-record ang iyong buong screen"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Kasalukuyan mong nire-record ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Huminto sa pag-record"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ibinabahagi ang screen"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ihinto ang pagbabahagi ng screen?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Kasalukuyan mong ibinabahagi ang iyong buong screen sa <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Kasalukuyan mong ibinabahagi ang iyong buong screen sa isang app"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Kasalukuyan kang nagbabahagi ng <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Kasalukuyan kang nagbabahagi ng app"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Ihinto ang pagbabahagi"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Kina-cast ang screen"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Ihinto ang pag-cast?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Kasalukuyan mong kina-cast ang iyong buong screen sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Kasalukuyan mong kina-cast ang iyong buong screen sa isang kalapit na device"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Kasalukuyan kang nagka-cast ng <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> sa <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Kasalukuyan kang nagka-cast ng <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> sa isang kalapit na device"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Kasalukuyan kang nagka-cast sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Kasalukuyan kang nagka-cast sa isang kalapit na device"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Ihinto ang pag-cast"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Isara"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Recorder ng Isyu"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Pinoproseso: recording ng isyu"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Kasalukuyang notification para sa session ng pangongolekta ng isyu"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Nagkaroon ng error sa pag-save ng recording ng isyu"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Nagkaroon ng error sa pagsisimula ng pag-record ng isyu"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Nanonood sa full screen"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Para lumabas, mag-swipe pababa mula sa itaas ng iyong screen"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Bumalik"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Na-unlock gamit ang mukha. Pindutin para magpatuloy."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nakilala ang mukha. Pindutin para magpatuloy."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nakilala ang mukha. Pindutin ang unlock para magpatuloy."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Na-unlock gamit ang mukha. I-tap para magpatuloy."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Na-authenticate"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kanselahin ang Pag-authenticate"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Higit Pang Opsyon"</string>
@@ -291,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Huwag Istorbohin"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"Mga mode ng priyoridad"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Walang available na mga magkapares na device"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Mag-tap para magkonekta o magdiskonekta ng device"</string>
@@ -302,8 +302,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Na-save"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"idiskonekta"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"i-activate"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Awtomatikong i-on bukas"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Gumagamit ng Bluetooth ang mga feature tulad ng Quick Share at Hanapin ang Aking Device"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Mag-o-on ang Bluetooth bukas ng umaga"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Ibahagi ang audio"</string>
@@ -472,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Magdagdag ng higit pang widget"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pindutin nang matagal para i-customize ang mga widget"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"I-customize ang mga widget"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Mag-unlock para ma-customize ang mga widget"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icon ng app para sa na-disable na widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ini-install ang icon ng app para sa isang widget"</string>
<string name="edit_widget" msgid="9030848101135393954">"I-edit ang widget"</string>
@@ -490,12 +490,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pumili ng widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"alisin ang widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ilagay ang napiling widget"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Mga widget ng lock screen"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Makikita ng sinuman ang mga widget sa lock screen, kahit naka-lock ang tablet."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Mga widget ng lock screen"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para magbukas ng app gamit ang isang widget, kakailanganin mong i-verify na ikaw iyan. Bukod pa rito, tandaang puwedeng tingnan ng kahit na sino ang mga ito, kahit na naka-lock ang iyong tablet. Posibleng hindi para sa iyong lock screen ang ilang widget at posibleng hindi ligtas ang mga ito na idagdag dito."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Magpalit ng user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string>
@@ -549,12 +548,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Magsimula ngayon"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Walang mga notification"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Walang bagong notification"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"On ang adaptive notifications"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Hinihinaan ng device ang volume at binabawasan nito ang pop-ups nang hanggang 2 minuto kapag nakatanggap ng maraming notification sa maikling oras."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"I-off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"I-unlock para makita ang mga mas lumang notification"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Pinapamahalaan ng magulang mo itong device"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Pagmamay-ari ng organisasyon mo ang device na ito at puwede nitong subaybayan ang trapiko sa network"</string>
@@ -720,7 +716,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Awtomatiko"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Walang tunog o pag-vibrate"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Walang tunog o pag-vibrate at lumalabas nang mas mababa sa seksyon ng pag-uusap"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Puwedeng mag-ring o mag-vibrate batay sa mga setting ng device"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Puwedeng mag-ring o mag-vibrate batay sa mga setting ng device. Mga pag-uusap mula sa <xliff:g id="APP_NAME">%1$s</xliff:g> bubble bilang default."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Ipatukoy sa system kung dapat gumawa ng tunog o pag-vibrate ang notification na ito"</string>
@@ -777,6 +774,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1350,33 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Ginagamit ng <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kamakailang ginamit ng <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Mga kontrol ng system"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Mga system app"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Pag-multitask"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Kamakailang mga app"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Mga shortcut ng app"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Mga keyboard shortcut"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Mga shortcut ng paghahanap"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"I-collapse ang icon"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"I-expand ang icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Galaw para bumalik"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Galaw para sa Home"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Action key"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Tapos na"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Magaling!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Bumalik"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para bumalik, mag-swipe pakaliwa o pakanan gamit ang tatlong daliri kahit saan sa touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad na nagpapakita ng tatlong daliring gumagalaw pakanan at pakaliwa"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Screen ng device na nagpapakita ng animation para sa galaw sa pagbalik"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Backlight ng keyboard"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d sa %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Mga Home Control"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Mabilis i-access ang home control bilang screensaver"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"I-undo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
index fe2827f6a4e9..85c4cfab149c 100644
--- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"Naka-off"</item>
<item msgid="4875147066469902392">"Naka-on"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"Hindi available"</item>
+ <item msgid="2004750556637773692">"Naka-off"</item>
+ <item msgid="8968530753931637871">"Naka-on"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Hindi available"</item>
<item msgid="5044688398303285224">"Naka-off"</item>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 7eb08dd42bd7..2c429d8caa36 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> bu ekran görüntüsünü algıladı."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ve diğer açık uygulamalar bu ekran görüntüsünü algıladı."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Nota ekle"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Bağlantıyı dahil et"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Ekran Kaydedicisi"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran kaydı işleniyor"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekran kaydı oturumu için devam eden bildirim"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Görüntülemek için dokunun"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran kaydı saklanırken hata oluştu"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekran kaydı başlatılırken hata oluştu"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; içeriğini kaydetmeyi durdurursunuz"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Kaydı durdur"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran paylaşılıyor"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ekran paylaşımı durdurulsun mu?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; içeriğini paylaşmayı durdurursunuz"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Paylaşımı durdur"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Ekran yayınlanıyor"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Yayın durdurulsun mu?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; içeriğini yayınlamayı durdurursunuz"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Yayını durdur"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Kapat"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Sorun Kaydedici"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Sorun kaydı işleniyor"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Sorun toplama oturumuyla ilgili devam eden görev bildirimi"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Sorun kaydı saklanırken hata oluştu"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Sorun kaydı başlatılırken hata oluştu"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Tam ekran olarak görüntüleme"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Çıkmak için ekranın üst kısmından aşağı doğru kaydırın"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Anladım"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Geri"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Ana sayfa"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Cihazın kilidini yüzünüzle açtınız. Devam etmek için basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yüzünüz tanındı. Devam etmek için basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yüzünüz tanındı. Kilit açma simgesine basın."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Kilidi yüzünüzle açtınız. Devam etmek için dokunun."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kimliği Doğrulandı"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kimlik doğrulamayı iptal et"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Diğer Seçenekler"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Ekran koruyucu"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Rahatsız Etmeyin"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Kullanılabilir eşlenmiş cihaz yok"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Cihaz bağlamak veya cihazın bağlantısını kesmek için dokunun"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Kaydedildi"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"bağlantıyı kes"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"etkinleştir"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Yarın otomatik olarak aç"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share ve Cihazımı Bul gibi özellikler Bluetooth\'u kullanır"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth yarın sabah açılacak"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Sesi paylaş"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Daha fazla widget ekle"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widget\'ları özelleştirmek için uzun basın"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widget\'ları özelleştir"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Widget\'ları özelleştirmek için kilidi açın"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Devre dışı bırakılan widget\'ın uygulama simgesi"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Yüklenmeye devam eden bir widget\'ın uygulama simgesi"</string>
<string name="edit_widget" msgid="9030848101135393954">"Widget\'ı düzenle"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"widget seçin"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"widget\'ı kaldır"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"seçilen widget\'ı yerleştir"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Kilit ekranı widget\'ları"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Widget kullanarak bir uygulamayı açmak için kimliğinizi doğrulamanız gerekir. Ayrıca, tabletiniz kilitliyken bile widget\'ların herkes tarafından görüntülenebileceğini unutmayın. Bazı widget\'lar kilit ekranınız için tasarlanmamış olabileceğinden buraya eklenmeleri güvenli olmayabilir."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Anladım"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kullanıcı değiştirme"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"açılır menü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string>
@@ -717,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Varsayılan"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Otomatik"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sessiz veya titreşim yok"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ses veya titreşim yok, görüşme bölümünün altında görünür"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Cihaz ayarlarına bağlı olarak zili çalabilir veya titreyebilir"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Cihaz ayarlarına bağlı olarak zili çalabilir veya titreyebilir <xliff:g id="APP_NAME">%1$s</xliff:g> adlı uygulamadan görüşmeler varsayılan olarak baloncukla gösterilir."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Bu bildirimin ses çıkarması veya titreşmesi gerekip gerekmediğine sistem karar versin"</string>
@@ -774,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Sayfa Yukarı"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Sayfa Aşağı"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1349,23 +1367,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) tarafından kullanılıyor"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"En son <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) tarafından kullanıldı"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistem kontrolleri"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistem uygulamaları"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Çoklu görev becerisi"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Son uygulamalar"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Bölünmüş ekran"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Giriş"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Uygulama kısayolları"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erişilebilirlik"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klavye kısayolları"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Arama kısayolları"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Daralt simgesi"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Genişlet simgesi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"veya"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Geri hareketi"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Ana sayfa hareketi"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Eylem tuşu"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Bitti"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Tebrikler!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Geri dön"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Geri dönmek için dokunmatik alanın herhangi bir yerinde üç parmağınızla sola veya sağa kaydırın."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Sağa ve sola hareket eden üç parmağın gösterildiği dokunmatik alan"</string>
@@ -1374,4 +1395,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Seviye %1$d / %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ev Kontrolleri"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Ekran koruyucu olarak ev kontrollerinize hızla erişin"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
index 1ed106f4efd2..b26588befe4d 100644
--- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Kapalı"</item>
<item msgid="4875147066469902392">"Açık"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Kullanılamıyor"</item>
<item msgid="5044688398303285224">"Kapalı"</item>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 2fc79e5efed1..3ebb787fd1ac 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Додаток <xliff:g id="APPNAME">%1$s</xliff:g> виявив цей знімок екрана."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> та інші відкриті додатки виявили цей знімок екрана."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додати до примітки"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Додати посилання"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Запис відео з екрана"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обробка записування екрана"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Сповіщення про сеанс запису екрана"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Натисніть, щоб переглянути"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Не вдалося зберегти запис відео з екрана"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Не вдалося почати запис екрана"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ви зупините запис контенту з додатка &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Зупинити запис"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Показ екрана"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Зупинити показ екрана?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ви зупините надсилання контенту з додатка &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Зупинити показ"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Трансляція екрана"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Зупинити трансляцію?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ви зупините трансляцію контенту з додатка &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Припинити трансляцію"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Закрити"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Засіб запису проблем"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Обробка запису проблеми"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Поточне сповіщення про сеанс збирання даних про проблему"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Не вдалося зберегти запис проблеми"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Не вдалося почати запис проблеми"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Перегляд на весь екран"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Щоб вийти, проведіть пальцем униз від верхнього краю екрана"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Головна"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Розблоковано (фейс-контроль). Натисніть, щоб продовжити."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Обличчя розпізнано. Натисніть, щоб продовжити."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Обличчя розпізнано. Натисніть значок розблокування."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Розблоковано (фейс-контроль). Натисніть, щоб продовжити."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Автентифіковано"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Скасувати автентифікацію"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Інші опції"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Заставка"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не турбувати"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<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>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Збережено"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"від’єднати"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активувати"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Автоматично ввімкнути завтра"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Такі функції, як швидкий обмін і \"Знайти пристрій\", використовують Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth увімкнеться завтра вранці"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Поділитись аудіо"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додати більше віджетів"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Утримуйте, щоб налаштувати віджети"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Налаштувати віджети"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Розблокуйте екран, щоб налаштувати віджети"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок додатка для вимкненого віджета"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Значок додатка для віджета, що встановлюється"</string>
<string name="edit_widget" msgid="9030848101135393954">"Редагувати віджет"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виберіть віджет"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"видалити віджет"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"розмістити вибраний віджет"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Віджети для заблокованого екрана"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Щоб відкрити додаток за допомогою віджета, вам потрібно буде підтвердити особу. Пам’ятайте також, що бачити віджети можуть усі, навіть коли планшет заблоковано. Можливо, деякі віджети не призначені для заблокованого екрана, і додавати їх на нього може бути небезпечно."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Змінити користувача"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"спадне меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усі додатки й дані з цього сеансу буде видалено."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Почати зараз"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Сповіщень немає"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Немає нових сповіщень"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивні сповіщення ввімкнено"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Пристрій знижує гучність і зменшує кількість спливаючих вікон на екрані на період до двох хвилин, коли ви отримуєте багато сповіщень за короткий час."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Вимкнути"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Розблокуйте, щоб переглянути старіші"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Цим пристроєм керує батько або мати"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Цей пристрій належить вашій організації. Її адміністратор може відстежувати мережевий трафік"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"За умовчанням"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Автоматично"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звуку чи вібрації"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звуку чи вібрації, з\'являється нижче в розділі розмов"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Дзвінок або вібрація залежно від налаштувань пристрою"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Може дзвонити або вібрувати залежно від налаштувань пристрою. Показує спливаючі розмови з додатка <xliff:g id="APP_NAME">%1$s</xliff:g> за умовчанням."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Дозволити системі визначати, чи має сповіщення супроводжуватися звуком або вібрацією"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Сторінка вгору"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Сторінка вниз"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Використовується додатком <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Нещодавно використано (<xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Система"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Елементи керування системою"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системні додатки"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Багатозадачність"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Нещодавні додатки"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Розділити екран"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Введення"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Комбінації клавіш для додатків"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Доступність"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Комбінації клавіш"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Комбінації клавіш для пошуку"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок згортання"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок розгортання"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"або"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Жест \"Назад\""</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Жест переходу на головний екран"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Клавіша дії"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Чудово!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Щоб перейти назад, проведіть трьома пальцями вліво або вправо по сенсорній панелі."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Сенсорна панель із зображенням трьох пальців, що рухаються вправо й уліво"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Екран пристрою, на якому показано анімацію щодо жесту \"Назад\""</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Підсвічування клавіатури"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Рівень %1$d з %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Автоматизація дому"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Швидкий доступ до керування домом через заставку"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
index 61e62e4395ce..2d869166d475 100644
--- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Вимкнено"</item>
<item msgid="4875147066469902392">"Увімкнено"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Недоступно"</item>
<item msgid="5044688398303285224">"Вимкнено"</item>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 7d43c0a2c867..fe8eb4da467b 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"‫<xliff:g id="APPNAME">%1$s</xliff:g> نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"‫<xliff:g id="APPNAME">%1$s</xliff:g> اور دیگر کھلی ایپس نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"نوٹ میں شامل کریں"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"لنک شامل کریں"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"اسکرین ریکارڈر"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"سکرین ریکارڈنگ پروسیس ہورہی ہے"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"اسکرین ریکارڈ سیشن کیلئے جاری اطلاع"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"دیکھنے کے لیے تھپتھپائیں"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"اسکرین ریکارڈنگ محفوظ کرنے میں خرابی"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"اسکرین ریکارڈنگ شروع کرنے میں خرابی"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"‏آپ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو ریکارڈ نہیں کر پائیں گے"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"‏آپ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کا اشتراک نہیں کر پائیں گے"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"‏آپ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو کاسٹ نہیں کر پائیں گے"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"ریکارڈنگ روکیں؟"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"آپ فی الحال اپنی پوری اسکرین ریکارڈ کر رہے ہیں"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"آپ فی الحال <xliff:g id="APP_NAME">%1$s</xliff:g> ریکارڈ کر رہے ہیں"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ریکارڈنگ روکیں"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"اسکرین کا اشتراک ہو رہا ہے"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"اسکرین کا اشتراک روکیں؟"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"آپ فی الحال <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> کے ساتھ اپنی پوری اسکرین کا اشتراک کر رہے ہیں"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"آپ فی الحال ایک ایپ کے ساتھ اپنی پوری اسکرین کا اشتراک کر رہے ہیں"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"آپ فی الحال <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> کا اشتراک کر رہے ہیں"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"آپ فی الحال ایک ایپ کا اشتراک کر رہے ہیں"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"اشتراک کرنا روکیں"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"اسکرین کاسٹ ہو رہی ہے"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"کاسٹ کرنا بند کریں؟"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"آپ فی الحال اپنی پوری اسکرین کو <xliff:g id="DEVICE_NAME">%1$s</xliff:g> پر کاسٹ کر رہے ہیں"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"آپ فی الحال اپنی پوری اسکرین کو ایک قریبی آلہ پر کاسٹ کر رہے ہیں"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"آپ فی الحال <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> کو <xliff:g id="DEVICE_NAME">%2$s</xliff:g> پر کاسٹ کر رہے ہیں"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"آپ فی الحال <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> کو ایک قریبی آلہ پر کاسٹ کر رہے ہیں"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"آپ فی الحال <xliff:g id="DEVICE_NAME">%1$s</xliff:g> پر کاسٹ کر رہے ہیں"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"آپ فی الحال ایک قریبی آلہ پر کاسٹ کر رہے ہیں"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"کاسٹ کرنا بند کریں"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"بند کریں"</string>
<string name="issuerecord_title" msgid="286627115110121849">"ایشو ریکارڈر"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ایشو ریکارڈنگ پروسیس ہو رہی ہے"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"ایشو کلیکشن سیشن کے لیے جاری اطلاع"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"ایشو ریکارڈنگ محفوظ کرنے میں خرابی"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"ایشو ریکارڈنگ شروع کرنے میں خرابی"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"فُل اسکرین میں دیکھ رہے ہیں"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"باہر نکلنے کے لیے اپنی اسکرین کے اوپری حصے سے نیچے کی طرف سوائپ کریں"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"سمجھ آ گئی"</string>
<string name="accessibility_back" msgid="6530104400086152611">"واپس جائیں"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ہوم"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"چہرے سے انلاک کیا گیا۔ جاری رکھنے کے لیے دبائیں۔"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کے لیے دبائیں۔"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کیلئے انلاک آئیکن دبائیں۔"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"چہرے سے غیر مقفل کیا گیا۔ جاری رکھنے کیلئے تھپتھپائیں۔"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"تصدیق کردہ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"تصدیق کو منسوخ کریں"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"مزید اختیارات"</string>
@@ -291,6 +290,7 @@
<string name="start_dreams" msgid="9131802557946276718">"اسکرین سیور"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ایتھرنیٹ"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"ڈسٹرب نہ کریں"</string>
+ <string name="quick_settings_modes_label" msgid="5407025818652750501">"ترجیحی وضع"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"بلوٹوتھ"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"کوئی جوڑا بنائے ہوئے آلات دستیاب نہیں ہیں"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"کسی آلے کو منسلک یا غیر منسلک کرنے کے لیے تھپتھپائیں"</string>
@@ -302,8 +302,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"محفوظ ہے"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"غیر منسلک کریں"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"فعال کریں"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"خودکار طور پر کل آن کریں"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"فوری اشتراک اور \'میرا آلہ ڈھونڈیں\' جیسی خصوصیات بلوٹوتھ کا استعمال کرتی ہیں"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"بلوٹوتھ کل صبح آن ہو جائے گا"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"آڈیو کا اشتراک کریں"</string>
@@ -472,6 +471,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"مزید ویجٹس شامل کریں"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ویجٹس کو حسب ضرورت بنانے کے لیے لانگ پریس کریں"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ویجیٹس کو حسب ضرورت بنائیں"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ویجیٹس کو حسب ضرورت بنانے کے لیے غیر مقفل کریں"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"غیر فعال ویجیٹ کے لئے ایپ آئیکن"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"انسٹال ہونے والے ویجیٹ کا ایپ آئیکن"</string>
<string name="edit_widget" msgid="9030848101135393954">"ویجیٹ میں ترمیم کریں"</string>
@@ -490,12 +490,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ویجیٹ منتخب کریں"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ویجیٹ ہٹائیں"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"منتخب ویجیٹ رکھیں"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"مقفل اسکرین کے ویجیٹس"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"کوئی بھی آپ کی مقفل اسکرین پر ویجیٹ دیکھ سکتا ہے اگرچہ آپ کا ٹیبلیٹ مقفل ہو۔"</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"مقفل اسکرین کے ویجیٹس"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ویجیٹ کے ذریعے ایپ کھولنے کے لیے آپ کو تصدیق کرنی ہوگی کہ یہ آپ ہی ہیں۔ نیز، ذہن میں رکھیں کہ کوئی بھی انہیں دیکھ سکتا ہے، یہاں تک کہ جب آپ کا ٹیبلیٹ مقفل ہو۔ ہو سکتا ہے کچھ ویجٹس آپ کی لاک اسکرین کے لیے نہ بنائے گئے ہوں اور یہاں شامل کرنا غیر محفوظ ہو سکتا ہے۔"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"سمجھ آ گئی"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"صارف سوئچ کریں"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"پل ڈاؤن مینیو"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string>
@@ -721,7 +720,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"ڈیفالٹ"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"خودکار"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"کوئی آواز یا وائبریشن نہیں"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"کوئی آواز یا وائبریشن نہیں اور گفتگو کے سیکشن میں نیچے ظاہر ہوتا ہے"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"آلے کی ترتیبات کی بنیاد پر وائبریٹ یا گھنٹی بج سکتی ہے"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"آلے کی ترتیبات بنیاد پر وائبریٹ یا گھنٹی بج سکتی ہے۔ بذریعہ ڈیفالٹ <xliff:g id="APP_NAME">%1$s</xliff:g> بلبلہ سے گفتگوئیں۔"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"سسٹم کو اس بات کا تعین کرنے دیں کہ آیا اس اطلاع کی آواز ہو یا وائبریٹ ہونا چاہیے"</string>
@@ -778,6 +778,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1353,23 +1354,25 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) کے زیر استعمال"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) کے ذریعے حال ہی میں استعمال کیا گیا"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"سسٹم"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"سسٹم کنٹرولز"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"سسٹم ایپس"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ملٹی ٹاسکنگ"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"حالیہ ایپس"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"اسپلٹ اسکرین"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ان پٹ"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ایپ شارٹ کٹس"</string>
+ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"موجودہ ایپ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ایکسیسبیلٹی"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"کی بورڈ شارٹ کٹس"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"تلاش کے شارٹ کٹس"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"آئیکن سکیڑیں"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"آئیکن پھیلائیں"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"یا"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"پیچھے جانے کا اشارہ"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"ہوم کا اشارہ"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"ایکشن کلید"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ہو گیا"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"بہترین!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"واپس جائیں"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"واپس جانے کے لیے، ٹچ پیڈ پر کہیں بھی تین انگلیوں کی مدد سے دائیں یا بائیں سوائپ کریں۔"</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ٹچ پیڈ دائیں اور بائیں حرکت کرتی ہوئی تین انگلیاں دکھا رہا ہے"</string>
@@ -1378,4 +1381,5 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"‏%2$d میں سے ‎%1$d کا لیول"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ہوم کنٹرولز"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"اسکرین سیور کے بطور اپنے ہوم کنٹرولز تک فوری رسائی حاصل کریں"</string>
+ <string name="volume_undo_action" msgid="5815519725211877114">"کالعدم کریں"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
index ebbc30ebca58..e398b2f84803 100644
--- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
@@ -56,6 +56,11 @@
<item msgid="5376619709702103243">"آف ہے"</item>
<item msgid="4875147066469902392">"آن ہے"</item>
</string-array>
+ <string-array name="tile_states_modes">
+ <item msgid="7764936419245199023">"دستیاب نہیں ہے"</item>
+ <item msgid="2004750556637773692">"آف ہے"</item>
+ <item msgid="8968530753931637871">"آن ہے"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"دستیاب نہیں ہے"</item>
<item msgid="5044688398303285224">"آف ہے"</item>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 825c507d06f7..7e9466c35b21 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> skrinshot olinganini aniqladi."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> va boshqa ochiq ilovalar skrinshot olinganini aniqladi."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Qaydga qoʻshish"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Havolani kiritish"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Ekranni yozib olish"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran yozib olinmoqda"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekrandan yozib olish seansi uchun joriy bildirishnoma"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Koʻrish uchun bosing"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran yozuvi saqlanmadi"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranni yozib olish boshlanmadi"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; yozib olinishini toʻxtatasiz"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ulashuvini toʻxtatasiz"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; translatsiyasini toʻxtatasiz"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Yozuv toʻxtatilsinmi?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Hozir butun ekran yozib olinmoqda"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Hozir <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi yozib olinmoqda"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Yozuvni toʻxtatish"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran ulashilmoqda"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ekran namoyishi toʻxtatilsinmi?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Hozir butun ekran <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> ilovasiga ulashilmoqda"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Hozir butun ekran ilovaga ulashilmoqda"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Hozir <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ilovasiga kontent ulashilmoqda"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Hozir ilovaga kontent ulashilmoqda"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Namoyishni toʻxtatish"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Ekran translatsiya qilinmoqda"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Toʻxtatilsinmi?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Hozir butun ekran <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasiga translatsiya qilinmoqda"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Hozir butun ekran atrofdagi qurilmaga translatsiya qilinmoqda"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Hozir <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_NAME">%2$s</xliff:g> qurilmasiga translatsiya qilinmoqda"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Hozir <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ilovasi atrofdagi qurilmaga translatsiya qilinmoqda"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Hozir <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasiga kontent translatsiya qilinmoqda"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Hozir atrofdagi qurilmaga kontent translatsiya qilinmoqda"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Toʻxtatish"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Yopish"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Muammoni yozib olish vositasi"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Yozuv qayta ishlanmoqda"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Muammo toʻplash seansi uchun faol bildirishnoma"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Yozuv saqlanmadi"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Yozib olish boshlanmadi"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Butun ekran rejimi"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Chiqish uchun ekranning tepasidan pastga suring"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Orqaga"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Uyga"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Yuz orqali ochildi. Davom etish uchun bosing."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yuz aniqlandi. Davom etish uchun bosing."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yuz aniqlandi. Davom etish uchun ochish belgisini bosing."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Yuz bilan ochildi. Davom etish uchun bosing."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Tasdiqlandi"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Autentifikatsiyani bekor qilish"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Boshqa parametrlar"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Ekran lavhasi"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Bezovta qilinmasin"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ulangan qurilmalar topilmadi"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Qurilma ulash yoki uzish uchun tegining"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saqlangan"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"uzish"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"faollashtirish"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Ertaga avtomatik yoqilsin"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Tezkor ulashuv va Qurilmamni top kabi funksiyalar Bluetooth ishlatadi"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ertaga ertalab yoqiladi"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Audioni ulashish"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Koʻproq vidjetlar qoʻshish"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Vidjetlarni sozlash uchun bosib turing"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Vidjetlarni moslashtirish"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Vidjetlarni moslash uchun qulfdan chiqaring"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Faolsizlantirilgan vidjet uchun ilova belgisi"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Oʻrnatilayotgan vidjet uchun ilova belgisi"</string>
<string name="edit_widget" msgid="9030848101135393954">"Vidjetni tahrirlash"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidjet tanlash"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"vidjetni olib tashlash"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"tanlangan vidjetni joylash"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Ekran qulfi vidjetlari"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Ekran quflidagi vidjetlar hammaga koʻrinadi, hatto planshet qulflanganda ham."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Ekran qulfi vidjetlari"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ilovani vidjet orqali ochish uchun shaxsingizni tasdiqlashingiz kerak. Shuningdek, planshet qulflanganda ham bu axborotlar hammaga koʻrinishini unutmang. Ayrim vidjetlar ekran qulfiga moslanmagan va ularni bu yerda chiqarish xavfli boʻlishi mumkin."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Foydalanuvchini almashtirish"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"tortib tushiriladigan menyu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string>
@@ -549,12 +549,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Boshlash"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Bildirishnomalar yo‘q"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Yangi bildirishoma yoʻq"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptiv bildirishnomalar yoniq"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Qisqa vaqt oraligʻida koʻp bildirishnoma kelsa, qurilmadagi tovush balandligi hamda bildirgi oynalar soni ikki daqiqagacha kamaytiriladi."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Faolsizlantirish"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Eskilarini koʻrish uchun qulfni yeching"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu qurilmani ota-onangiz boshqaradi"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu qurilma tashkilotingizga tegishli va tarmoq trafigi tashkilotingiz tomonidan kuzatilishi mumkin"</string>
@@ -720,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Standart"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Avtomatik"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Tovush yoki tebranishsiz"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Tovush yoki tebranishsiz hamda suhbatlar ruknining pastida chiqadi"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Qurilma sozlamalari asosida jiringlashi yoki tebranishi mumkin"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Qurilma sozlamalari asosida jiringlashi yoki tebranishi mumkin. <xliff:g id="APP_NAME">%1$s</xliff:g> suhbatlari standart holatda bulutcha shaklida chiqadi."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Bu bildirishnoma jiringlashi yoki tebranishini hal qilsin"</string>
@@ -777,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1351,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ishlatmoqda"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Yaqinda <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ishlatgan"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Tizim"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Tizim boshqaruvi tugmalari"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Tizim ilovalari"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multi-vazifalilik"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Oxirgi ilovalar"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ekranni ikkiga ajratish"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Kiritish"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Ilova yorliqlari"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qulayliklar"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tezkor tugmalar"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tezkor tugmalar qidiruvi"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Yigʻish belgisi"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Yoyish belgisi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"yoki"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Orqaga qaytish ishorasi"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Asosiy ekran ishorasi"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Amal tugmasi"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Tayyor"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Barakalla!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Orqaga qaytish"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ortga qaytish uchun sensorli panelda uchta barmoqni chapga yoki oʻngga suring."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Sensorli panelda uchta barmoq chapga va oʻngga harakatlanishi"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Qurilma ekranidagi ortga qaytish ishorasi animatsiyasi"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura orqa yoritkichi"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Daraja: %1$d / %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Uy boshqaruvi"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Uy boshqaruvi tugmalarini ekran lavhasida tezkor oching"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
index 2ae811233176..da9c98f82df8 100644
--- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Oʻchiq"</item>
<item msgid="4875147066469902392">"Yoniq"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Ishlamaydi"</item>
<item msgid="5044688398303285224">"Oʻchiq"</item>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index bf0126ce03d7..42909c996e2c 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> đã phát hiện thấy ảnh chụp màn hình này."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> và các ứng dụng đang mở khác đã phát hiện thấy ảnh chụp màn hình này."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Thêm vào ghi chú"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Thêm đường liên kết"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Trình ghi màn hình"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Đang xử lý video ghi màn hình"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Thông báo đang diễn ra về phiên ghi màn hình"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Nhấn để xem"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Có lỗi xảy ra khi lưu video ghi màn hình"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Lỗi khi bắt đầu ghi màn hình"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Bạn sẽ dừng ghi âm nội dung của &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Dừng ghi"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Đang chia sẻ màn hình"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Dừng chia sẻ màn hình?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Bạn sẽ dừng chia sẻ nội dung của &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Dừng chia sẻ"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Đang truyền màn hình"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Dừng truyền?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Bạn sẽ dừng truyền nội dung của &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Dừng truyền"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Đóng"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Trình ghi sự cố"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Đang xử lý bản ghi sự cố"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Thông báo hiển thị liên tục cho một phiên thu thập sự cố"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Đã xảy ra lỗi khi lưu bản ghi sự cố"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Đã xảy ra lỗi khi bắt đầu ghi sự cố"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Xem toàn màn hình"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Để thoát, hãy vuốt xuống từ đầu màn hình"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Tôi hiểu"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Quay lại"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Trang chủ"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Đã mở khoá bằng khuôn mặt. Hãy nhấn để tiếp tục."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Đã nhận diện khuôn mặt. Hãy nhấn để tiếp tục."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Đã nhận diện khuôn mặt. Nhấn biểu tượng mở khoá để tiếp tục."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Đã mở khoá bằng khuôn mặt. Nhấn để tiếp tục."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Đã xác thực"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Huỷ quy trình xác thực"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Tuỳ chọn khác"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Trình bảo vệ m.hình"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Không làm phiền"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Không có thiết bị nào được ghép nối"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Nhấn để kết nối/ngắt kết nối với một thiết bị"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Đã lưu"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ngắt kết nối"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"kích hoạt"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Tự động bật vào ngày mai"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Các tính năng như Chia sẻ nhanh và Tìm thiết bị của tôi đều sử dụng Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth sẽ bật vào sáng mai"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Chia sẻ âm thanh"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Thêm tiện ích khác"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nhấn và giữ để tuỳ chỉnh tiện ích"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tuỳ chỉnh tiện ích"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Mở khoá để tuỳ chỉnh các tiện ích"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Biểu tượng ứng dụng của tiện ích đã bị vô hiệu hoá"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Đang cài đặt biểu tượng ứng dụng của một tiện ích"</string>
<string name="edit_widget" msgid="9030848101135393954">"Chỉnh sửa tiện ích"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"chọn tiện ích"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"xoá tiện ích"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"đặt tiện ích đã chọn vào vị trí"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Tiện ích trên màn hình khoá"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Để dùng tiện ích mở một ứng dụng, bạn cần xác minh danh tính của mình. Ngoài ra, hãy lưu ý rằng bất kỳ ai cũng có thể xem các tiện ích này, ngay cả khi máy tính bảng của bạn được khoá. Một số tiện ích có thể không dành cho màn hình khoá và không an toàn khi thêm vào đây."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Tôi hiểu"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Chuyển đổi người dùng"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"trình đơn kéo xuống"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tất cả ứng dụng và dữ liệu trong phiên này sẽ bị xóa."</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Bắt đầu ngay"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Không có thông báo nào"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Không có thông báo mới"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Thông báo thích ứng đang bật"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Giờ đây, thiết bị sẽ giảm âm lượng và giảm số cửa sổ bật lên trên màn hình trong tối đa 2 phút khi bạn nhận được nhiều thông báo trong một khoảng thời gian ngắn."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Tắt"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Mở khoá để xem thông báo cũ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Thiết bị này do cha mẹ của bạn quản lý"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tổ chức của bạn sở hữu thiết bị này và có thể giám sát lưu lượng truy cập mạng"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Mặc định"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Tự động"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Không phát âm thanh hoặc rung"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Không phát âm thanh hoặc rung và xuất hiện phía dưới trong phần cuộc trò chuyện"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Có thể đổ chuông hoặc rung tuỳ theo chế độ cài đặt trên thiết bị"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Có thể đổ chuông hoặc rung tuỳ theo chế độ cài đặt trên thiết bị. Theo mặc định, các cuộc trò chuyện từ <xliff:g id="APP_NAME">%1$s</xliff:g> sẽ hiển thị dưới dạng bong bóng."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Cho phép hệ thống quyết định xem thông báo này phát âm thanh hay rung"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Cuối"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) đang dùng"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) đã dùng gần đây"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Hệ thống"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Cài đặt hệ thống"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Ứng dụng hệ thống"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Đa nhiệm"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Ứng dụng gần đây"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Chia đôi màn hình"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Phương thức nhập"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Lối tắt ứng dụng"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hỗ trợ tiếp cận"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Phím tắt"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Lối tắt tìm kiếm"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Biểu tượng Thu gọn"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Biểu tượng Mở rộng"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"hoặc"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Cử chỉ quay lại"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Cử chỉ chuyển đến màn hình chính"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Phím hành động"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Xong"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Tuyệt vời!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Quay lại"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Để quay lại, hãy vuốt sang trái hoặc sang phải bằng 3 ngón tay ở vị trí bất kỳ trên bàn di chuột."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Minh hoạ thao tác di chuyển sang phải và sang trái bằng 3 ngón tay trên bàn di chuột"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Màn hình thiết bị hiện ảnh động minh hoạ cử chỉ quay lại"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Đèn nền bàn phím"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Độ sáng %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Điều khiển nhà"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Điều khiển nhà nhanh bằng trình bảo vệ màn hình"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
index d9d8af1d644c..efcc373124a3 100644
--- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Đang tắt"</item>
<item msgid="4875147066469902392">"Đang bật"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Không hoạt động"</item>
<item msgid="5044688398303285224">"Đang tắt"</item>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index c47248d96c38..b21bd9799086 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> 检测到此屏幕截图。"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 及其他打开的应用检测到此屏幕截图。"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"添加到备注中"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"包括链接"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"屏幕录制器"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在处理屏幕录制视频"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"持续显示屏幕录制会话通知"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"点按即可查看"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"保存屏幕录制内容时出错"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"启动屏幕录制时出错"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"将停止录制&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;的内容"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"停止录制"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在共享屏幕"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"要停止共享屏幕吗?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"将停止分享&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;的内容"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"停止共享"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"正在投屏"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"停止投屏吗?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"将停止投放&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;的内容"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"停止投屏"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"关闭"</string>
<string name="issuerecord_title" msgid="286627115110121849">"问题录制器"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"正在处理问题录制"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"针对问题收集会话的持续性通知"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"保存问题录制内容时出错"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"启动问题录制时出错"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"目前处于全屏模式"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"若要退出,请从屏幕顶部向下滑动"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"知道了"</string>
<string name="accessibility_back" msgid="6530104400086152611">"返回"</string>
<string name="accessibility_home" msgid="5430449841237966217">"主屏幕"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已通过面孔识别解锁。点按即可继续。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"识别出面孔。点按即可继续。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"识别出面孔。按下解锁图标即可继续。"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"已通过面孔识别解锁。点按即可继续。"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已经过身份验证"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消身份验证"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多选项"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"屏保"</string>
<string name="ethernet_label" msgid="2203544727007463351">"有线网络"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"勿扰"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"蓝牙"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"没有可用的配对设备"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"点按即可连接设备或断开设备连接"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已保存"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"断开连接"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"启用"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"明天自动开启"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"快速分享、查找我的设备等功能会使用蓝牙"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"蓝牙将在明天早上开启"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"分享音频"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"添加更多微件"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"长按即可自定义微件"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自定义微件"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"解锁即可自定义微件"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"已停用微件的应用图标"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"代表正在安装的微件的应用图标"</string>
<string name="edit_widget" msgid="9030848101135393954">"修改微件"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"选择微件"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除微件"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所选微件"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"锁定的屏幕中的微件"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"若要使用微件打开应用,您需要验证是您本人在操作。另外请注意,任何人都可以查看此类微件,即使您的平板电脑已锁定。有些微件可能不适合显示在锁定的屏幕中,因此添加到这里可能不安全。"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"知道了"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切换用户"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉菜单"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"立即开始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"没有通知"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"没有新通知"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"自适应通知功能已开启"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"现在,当在短时间内收到许多通知时,您的设备会调低音量并减少屏幕上的弹出式窗口,最多持续两分钟。"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"关闭"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解锁即可查看旧通知"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此设备由您的家长管理"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"贵单位拥有此设备,且可能会监控网络流量"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"默认"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"自动"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"不发出提示音,也不振动"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"不发出提示音,也不振动;显示在对话部分的靠下位置"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"可能会响铃或振动,取决于设备设置"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"可能会响铃或振动,取决于设备设置。默认情况下,来自<xliff:g id="APP_NAME">%1$s</xliff:g>的对话会以消息气泡的形式显示。"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"让系统决定是否应让设备在收到此通知时发出提示音或振动"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"向上翻页"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"PgDn"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"删除"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正在使用(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”最近使用过(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"系统"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"系统控件"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"系统应用"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"多任务处理"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近用过的应用"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分屏"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"输入"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"应用快捷键"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"无障碍功能"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"键盘快捷键"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜索快捷键"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收起图标"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展开图标"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"返回手势"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"主屏幕手势"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"快捷操作按键"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"完成"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"太棒了!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"如要返回,请使用三根手指在触控板上的任意位置左滑或右滑。"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"触控板,其中显示了三根手指右移和左移"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"设备屏幕,其中显示了返回手势的动画"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"键盘背光"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 级,共 %2$d 级"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"家居控制"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"通过屏保快速访问家居控制功能"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
index bce57773de9d..a0d37b945d0f 100644
--- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"已关闭"</item>
<item msgid="4875147066469902392">"已开启"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"不可用"</item>
<item msgid="5044688398303285224">"已关闭"</item>
@@ -189,6 +192,6 @@
<string-array name="tile_states_hearing_devices">
<item msgid="1235334096484287173">"不可用"</item>
<item msgid="3079622119444911877">"已关闭"</item>
- <item msgid="3028994095749238254">"开启"</item>
+ <item msgid="3028994095749238254">"已开启"</item>
</string-array>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index b448943d3ce0..daac54e264bc 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> 偵測到此螢幕截圖。"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 和其他開啟的應用程式偵測到此螢幕截圖。"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"新增至筆記"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"加入連結"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"螢幕錄影機"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在處理螢幕錄影內容"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示錄影畫面工作階段通知"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"輕按即可查看"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"儲存螢幕錄影時發生錯誤"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄影畫面時發生錯誤"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"你將停止錄影「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"停止錄製"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在分享螢幕"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"要停止分享螢幕嗎?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"你將停止分享「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"停止分享"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"正在投放螢幕"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"要停止投放嗎?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"你將停止投放「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"停止投放"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"關閉"</string>
<string name="issuerecord_title" msgid="286627115110121849">"問題記錄工具"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"正在處理問題記錄"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"問題收集工作階段的持續通知"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"儲存錄影問題時發生錯誤"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"開始記錄問題時發生錯誤"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"以全螢幕檢視"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"如要離開,請從螢幕頂部向下滑動"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"知道了"</string>
<string name="accessibility_back" msgid="6530104400086152611">"返回"</string>
<string name="accessibility_home" msgid="5430449841237966217">"首頁"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已使用面孔解鎖。按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"已識別面孔。按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"已識別面孔。按解鎖圖示即可繼續。"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"已使用面孔解鎖,輕按即可繼續。"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"驗證咗"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消驗證"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多選項"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"螢幕保護程式"</string>
<string name="ethernet_label" msgid="2203544727007463351">"以太網"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"請勿騷擾"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"藍牙"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"找不到配對的裝置"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"輕按即可連結或解除連結裝置"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已儲存"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"解除連結"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"啟動"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"明天自動開啟"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"「快速共享」和「尋找我的裝置」等功能都會使用藍牙"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"藍牙將於明天上午開啟"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"分享音訊"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"新增更多小工具"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長按即可自訂小工具"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自訂小工具"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"解鎖即可自訂小工具"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"已停用小工具的應用程式圖示"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"此應用程式圖示用來表示安裝中的小工具"</string>
<string name="edit_widget" msgid="9030848101135393954">"編輯小工具"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"揀小工具"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除小工具"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所選小工具"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"上鎖畫面小工具"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"如要使用小工具開啟應用程式,系統會要求你驗證身分。請注意,即使平板電腦已鎖定,所有人還是能查看小工具。部分小工具可能不適用於上鎖畫面,而且新增至這裡後可能會有安全疑慮。"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"知道了"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"已啟用自動調節通知"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"現在每當你於短時間內收到大量通知,裝置便會調低音量並減少螢幕上的彈出式視窗最多兩分鐘。"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此裝置由你的家長管理"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"你的機構擁有此裝置,並可能會監察網絡流量"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"預設"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"無音效或震動"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"無音效或震動,並在對話部分的較低位置顯示"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"可能會根據裝置設定發出鈴聲或震動"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"可能會根據裝置設定發出鈴聲或震動。根據預設,來自 <xliff:g id="APP_NAME">%1$s</xliff:g> 的對話會以對話氣泡顯示。"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"由系統判斷是否要讓此通知發出音效或震動"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"上一頁"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"下一頁"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"刪除"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"插入"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> 正在使用 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」最近使用過此權限 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"系統"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"系統控制項"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"系統應用程式"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"多工處理"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近使用的應用程式"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分割螢幕"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"輸入"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"應用程式捷徑"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙功能"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展開圖示"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"返去手勢"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"主畫面手勢"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"快捷操作鍵"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"完成"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"太好了!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"用三隻手指在觸控板上任何一處左右滑動即可返回。"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"觸控板上有三隻手指左右移動"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"裝置畫面顯示返回手勢動畫"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"智能家居"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"在螢幕保護程式畫面上控制智能家居"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
index cca7ac42906a..de07c6c05376 100644
--- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"已關閉"</item>
<item msgid="4875147066469902392">"已開啟"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"無法使用"</item>
<item msgid="5044688398303285224">"已關閉"</item>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 2a8430ae3ff4..a29d47b0743b 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"「<xliff:g id="APPNAME">%1$s</xliff:g>」偵測到這張螢幕截圖。"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"「<xliff:g id="APPNAME">%1$s</xliff:g>」和其他開啟的應用程式偵測到這張螢幕截圖。"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"新增至記事本"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"包含連結"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"螢幕錄影器"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"處理螢幕錄影內容"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示螢幕畫面錄製工作階段通知"</string>
@@ -125,29 +126,40 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"輕觸即可查看"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"儲存螢幕錄影內容時發生錯誤"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄製螢幕畫面時發生錯誤"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
+ <!-- no translation found for screenrecord_stop_dialog_title (8716193661764511095) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
+ <!-- no translation found for screenrecord_stop_dialog_message (6262768207331626817) -->
<skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"系統將停止錄製「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」的內容"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
+ <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5995770227684523244) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"停止錄音"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在分享畫面"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"要停止分享畫面嗎?"</string>
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen_with_host_app (522823522115375414) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_entire_screen (5090115386271179270) -->
<skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"系統將停止分享「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」的內容"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_specific (5923772039347985172) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
+ <!-- no translation found for share_to_app_stop_dialog_message_single_app_generic (6681016774654578261) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"停止分享"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"正在投放畫面"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"要停止投放嗎?"</string>
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen_with_device (1474703115926205251) -->
<skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"系統將停止投放「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」的內容"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_entire_screen (8419219169553867625) -->
<skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app_with_device (2715934698604085519) -->
<skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (8616103075630934513) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic_with_device (9213582497852420203) -->
+ <skip />
+ <!-- no translation found for cast_to_other_device_stop_dialog_message_generic (4100272100480415076) -->
+ <skip />
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"停止投放"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"關閉"</string>
<string name="issuerecord_title" msgid="286627115110121849">"問題記錄工具"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"正在處理問題記錄"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"問題收集工作階段的持續性通知"</string>
@@ -158,8 +170,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"儲存問題記錄時發生錯誤"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"開始記錄問題時發生錯誤"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"以全螢幕檢視"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"如要離開,請從螢幕頂端向下滑動"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"我知道了"</string>
<string name="accessibility_back" msgid="6530104400086152611">"返回"</string>
<string name="accessibility_home" msgid="5430449841237966217">"主畫面"</string>
@@ -192,6 +203,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"裝置已透過你的臉解鎖,按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"臉孔辨識完成,按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"臉孔辨識完成,按下「解鎖」圖示即可繼續操作。"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"裝置已透過你的臉解鎖,輕觸這裡即可繼續。"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已通過驗證"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消驗證"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多選項"</string>
@@ -291,6 +303,8 @@
<string name="start_dreams" msgid="9131802557946276718">"螢幕保護程式"</string>
<string name="ethernet_label" msgid="2203544727007463351">"乙太網路"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"零打擾"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"藍牙"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"找不到配對的裝置"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"輕觸即可連結/取消連結裝置"</string>
@@ -302,8 +316,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已儲存"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"取消連結"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"啟用"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"明天自動開啟"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"「快速分享」和「尋找我的裝置」等功能都需要使用藍牙技術"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"藍牙會在明天早上開啟"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"分享音訊"</string>
@@ -472,6 +485,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"新增更多小工具"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長按即可自訂小工具"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自訂小工具"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"解鎖即可自訂小工具"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"所停用小工具的應用程式圖示"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"這個應用程式圖示用來表示安裝中的小工具"</string>
<string name="edit_widget" msgid="9030848101135393954">"編輯小工具"</string>
@@ -490,12 +504,13 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"選取小工具"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除小工具"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所選小工具"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <!-- no translation found for communal_widget_picker_title (1953369090475731663) -->
<skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <!-- no translation found for communal_widget_picker_description (490515450110487871) -->
<skip />
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"螢幕鎖定小工具"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"如要使用小工具開啟應用程式,系統會要求你驗證身分。請注意,即使平板電腦已鎖定,所有人還是能查看小工具。某些小工具可能不適用於螢幕鎖定畫面,而且新增到這裡可能有安全疑慮。"</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"我知道了"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會刪除。"</string>
@@ -549,12 +564,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (5720882373252389461) -->
- <skip />
- <!-- no translation found for adaptive_notification_edu_hun_text (4260536236101821273) -->
- <skip />
- <!-- no translation found for go_to_adaptive_notification_settings (2423690125178298479) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"自動調整通知功能已開啟"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"如果在短時間內收到多則通知,裝置會在最長兩分鐘內調降音量,並減少在畫面上顯示彈出式視窗。"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"這個裝置是由你的家長管理"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"貴機構擁有這部裝置,而且可能會監控網路流量"</string>
@@ -720,7 +732,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"預設"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"不震動或發出聲音"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"不震動或發出聲音,並顯示在對話區的下方"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"根據裝置的設定響鈴或震動"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"根據裝置的設定響鈴或震動。根據預設,來自「<xliff:g id="APP_NAME">%1$s</xliff:g>」的對話會以對話框形式顯示。"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"由系統判斷要讓裝置在收到這則通知時震動還是發出音效"</string>
@@ -777,6 +790,8 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up 鍵"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down 鍵"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete 鍵"</string>
+ <!-- no translation found for keyboard_key_esc (6230365950511411322) -->
+ <skip />
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Home 鍵"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"End 鍵"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Insert 鍵"</string>
@@ -1352,33 +1367,34 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"正由「<xliff:g id="APP_NAME">%1$s</xliff:g>」使用 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」最近用過這項權限 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"系統"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"系統控制選項"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"系統應用程式"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"多工處理"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近使用的應用程式"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分割畫面"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"輸入"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"應用程式捷徑"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展開圖示"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_action_title (7199067250654332735) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_guidance (4222430588599527272) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_animation_content_description (2646107450922379918) -->
- <skip />
- <!-- no translation found for touchpad_back_gesture_screen_animation_content_description (4036267494237748710) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"返回手勢"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"主畫面手勢"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"快捷操作鍵"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"完成"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"太棒了!"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"如要返回,請用三指在觸控板上向左或右滑動。"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"動畫顯示三指正在觸控板上向左右移動"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"裝置畫面顯示返回手勢的動畫"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"居家控制"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"在螢幕保護程式畫面上快速存取居家控制功能"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
index 4cc580434a36..cbbea4106375 100644
--- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"已關閉"</item>
<item msgid="4875147066469902392">"已開啟"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"無法使用"</item>
<item msgid="5044688398303285224">"已關閉"</item>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 7e974bf16938..a23c69f5d771 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"I-<xliff:g id="APPNAME">%1$s</xliff:g> ithole lesi sithombe-skrini."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"I-<xliff:g id="APPNAME">%1$s</xliff:g> namanye ama-app avuliwe athole lesi sithombe-skrini."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Engeza kunothi"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Faka ilinki"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Okokuqopha iskrini"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Icubungula okokuqopha iskrini"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Isaziso esiqhubekayo seseshini yokurekhoda isikrini"</string>
@@ -125,29 +126,27 @@
<string name="screenrecord_save_text" msgid="3008973099800840163">"Thepha ukuze ubuke"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"Iphutha lokulondoloza okokuqopha iskrini"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Iphutha lokuqala ukurekhoda isikrini"</string>
- <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
- <skip />
- <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
- <skip />
- <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Uzoyeka ukurekhoda &lt;b&gt;i-<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
- <skip />
- <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
- <skip />
- <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Uzoyeka ukwaba &lt;b&gt;i-<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
- <skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
- <skip />
- <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Uzoyeka ukusakaza &lt;b&gt;i-<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
- <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
- <skip />
- <!-- no translation found for close_dialog_button (4749497706540104133) -->
- <skip />
+ <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Misa ukurekhoda?"</string>
+ <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Njengamanje urekhoda sonke isikrini sakho"</string>
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Njengamanje urekhoda i-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Misa ukurekhoda"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Yabelana ngesikrini"</string>
+ <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Misa ukwabelana ngeskrini?"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Njengamanje wabelana ngaso sonke isikrini sakho ne-<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Njengamanje wabelana ngaso sonke isikrini sakho ne-app"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Njengamanje wabelana nge-<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
+ <string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Njengamanje wabelana nge-app"</string>
+ <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Misa ukwabelana"</string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Isikrini sokusakaza"</string>
+ <string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Misa ukusakaza?"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device" msgid="1474703115926205251">"Njengamanje usakaza sonke isikrini sakho ku-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen" msgid="8419219169553867625">"Njengamanje usakaza sonke isikrini sakho kudivayisi eseduzane"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device" msgid="2715934698604085519">"Njengamanje usakaza i-<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ku-<xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="8616103075630934513">"Njengamanje usakaza i-<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> kudivayisi eseduzane"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device" msgid="9213582497852420203">"Njengamanje usakaza ku-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="cast_to_other_device_stop_dialog_message_generic" msgid="4100272100480415076">"Njengamanje usakaza kudivayisi eseduzane"</string>
+ <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Misa ukusakaza"</string>
+ <string name="close_dialog_button" msgid="4749497706540104133">"Vala"</string>
<string name="issuerecord_title" msgid="286627115110121849">"Ushicilelo Lokurekhoda"</string>
<string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Icubungula ushicilelo lokurekhoda"</string>
<string name="issuerecord_channel_description" msgid="6142326363431474632">"Isaziso esiqhubekayo seqoqo leseshini yoshicilelo"</string>
@@ -158,8 +157,7 @@
<string name="issuerecord_save_error" msgid="6913040083446722726">"Iphutha ekulondolozeni ushicilelo lokurekhoda"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"Iphutha lokuqalisa ushicilelo lokurekhoda"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Ukubuka isikrini esigcwele"</string>
- <!-- no translation found for immersive_cling_description (2717426731830851921) -->
- <skip />
+ <string name="immersive_cling_description" msgid="2717426731830851921">"Ukuze uphume, swayiphela phansi kusukela phezulu esikrinini sakho"</string>
<string name="immersive_cling_positive" msgid="3076681691468978568">"Ngiyezwa"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Emuva"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Ekhaya"</string>
@@ -192,6 +190,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Vula ngobuso. Cindezela ukuze uqhubeke."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ubuso buyaziwa. Cindezela ukuze uqhubeke."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ubuso buyaziwa. Cindezela isithonjana sokuvula ukuze uqhubeke."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Kuvulwe ngobuso. Thepha ukuze uqhubeke."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kugunyaziwe"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Khansela Ukuqinisekisa"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Okukhethwayo Okwengeziwe"</string>
@@ -291,6 +290,8 @@
<string name="start_dreams" msgid="9131802557946276718">"Isigciniskrini"</string>
<string name="ethernet_label" msgid="2203544727007463351">"I-Ethernet"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ungaphazamisi"</string>
+ <!-- no translation found for quick_settings_modes_label (5407025818652750501) -->
+ <skip />
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"I-Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Awekho amadivayisi abhanqiwe atholakalayo"</string>
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Thepha ukuze uxhumae noma ungaxhumi idivaysi"</string>
@@ -302,8 +303,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Ilondoloziwe"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"nqamula"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"yenza kusebenze"</string>
- <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
- <skip />
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Vula ngokuzenzekelayo kusasa"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Izakhi ezifana nokuthi Ukwabelana Ngokushesha kanye nokuthi Thola Idivayisi Yami zisebenzisa i-Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"IBluetooth izovuleka kusasa ekuseni"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Yabelana ngomsindo"</string>
@@ -472,6 +472,7 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Engeza amawijethi engeziwe"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Cindezela isikhathi eside ukuze wenze ngokwezifiso amawijethi"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Yenza ngokwezifiso amawijethi"</string>
+ <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Vula ukuze uhlele amawijethi ngendlela oyifisayo"</string>
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Isithonjana se-app sewijethi evaliwe"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Isithonjana se-app sewijethi siyafakwa"</string>
<string name="edit_widget" msgid="9030848101135393954">"Hlela amawijethi"</string>
@@ -490,12 +491,11 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"khetha iwijethi"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"susa iwijethi"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"beka iwijethi ekhethiwe"</string>
- <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
- <skip />
- <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
- <skip />
+ <string name="communal_widget_picker_title" msgid="1953369090475731663">"Amawijethi wesikrini esikhiyiwe"</string>
+ <string name="communal_widget_picker_description" msgid="490515450110487871">"Noma ubani angabuka amawijethi ngisho noma ithebulethi ikhiyiwe."</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Amawijethi wesikrini esikhiyiwe"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ukuze uvule i-app usebenzisa iwijethi, uzodinga ukuqinisekisa ukuthi nguwe. Futhi, khumbula ukuthi noma ubani angakwazi ukuzibuka, nanoma ithebhulethi yakho ikhiyiwe. Amanye amawijethi kungenzeka abengahloselwe ukukhiya isikrini sakho futhi kungenzeka awaphephile ukuthi angafakwa lapha."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ngiyezwa"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Shintsha umsebenzisi"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"imenyu yokudonsela phansi"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wonke ama-app nedatha kulesi sikhathi azosuswa."</string>
@@ -717,7 +717,8 @@
<string name="notification_alert_title" msgid="3656229781017543655">"Okuzenzekelayo"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Okuzenzekelayo"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Awukho umsindo noma ukudlidliza"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Awukho umsindo noma ukudlidliza futhi ivela ngezansi esigabeni sengxoxo"</string>
+ <!-- no translation found for notification_conversation_summary_low (3855696451919728790) -->
+ <skip />
<string name="notification_channel_summary_default" msgid="777294388712200605">"Ingase ikhale noma idlidlize ngokusekelwe kumasethingi edivayisi"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Ingase ikhale noma idlidlize kuya ngamasethingi wedivayisi. Izingxoxo ezivela ku-<xliff:g id="APP_NAME">%1$s</xliff:g> ziba yibhamuza ngokuzenzakalela."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Vumela isistimu inqume uma lesi saziso kufanele senze umsindo noma sidlidlize"</string>
@@ -774,6 +775,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Ikhasi phezulu"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Ikhasi phansi"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Susa"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Ekhaya"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Phelisa"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Faka"</string>
@@ -1349,23 +1351,26 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Isetshenziswa yi-<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kusetshenziswe kamuva yi-<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Isistimu"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Izilawuli zesistimu"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Ama-app esistimu"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Ukwenza imisebenzi eminingi"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Ama-app wakamuva"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Hlukanisa isikrini"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Okokufaka"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Izinqamuleli Zohlelo lokusebenza"</string>
+ <!-- no translation found for shortcut_helper_category_current_app_shortcuts (4017840565974573628) -->
+ <skip />
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ukufinyeleleka"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Izinqamuleli zekhibhodi"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sesha izinqamuleli"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Goqa isithonjana"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Nweba isithonjana"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"noma"</string>
- <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
- <skip />
- <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
- <skip />
+ <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Ukunyakazisa umzimba kwangemuva"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Ukunyakazisa umzimba kwasekhaya"</string>
+ <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Inkinobho yokufinyelela"</string>
+ <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Kwenziwe"</string>
+ <string name="touchpad_tutorial_gesture_done" msgid="4784438360736821255">"Umsebenzi omuhle!"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Buyela emuva"</string>
<string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ukuze ubuyele emuva, swayiphela kwesokunxele noma kwesokudla usebenzisa iminwe emithathu noma yikuphi ephedini yokuthinta."</string>
<string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Iphedi yokuthinta ebonisa iminwe emithathu iya kwesokudla nakwesokunxele"</string>
@@ -1374,4 +1379,6 @@
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Ileveli %1$d ka-%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Izilawuli Zasekhaya"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Finyelela ngokushesha izilawuli zakho zasekhaya njengesigcini-skrini"</string>
+ <!-- no translation found for volume_undo_action (5815519725211877114) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
index a795ee8b9d75..8d6b84357e25 100644
--- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
@@ -56,6 +56,9 @@
<item msgid="5376619709702103243">"Valiwe"</item>
<item msgid="4875147066469902392">"Vuliwe"</item>
</string-array>
+ <!-- no translation found for tile_states_modes:0 (7764936419245199023) -->
+ <!-- no translation found for tile_states_modes:1 (2004750556637773692) -->
+ <!-- no translation found for tile_states_modes:2 (8968530753931637871) -->
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Akutholakali"</item>
<item msgid="5044688398303285224">"Valiwe"</item>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 80b9ec7748b9..30f23bfc9753 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -104,7 +104,7 @@
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
<string name="quick_settings_tiles_stock" translatable="false">
- internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling,record_issue,hearing_devices
+ internet,bt,flashlight,dnd,modes,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling,record_issue,hearing_devices
</string>
<!-- The tiles to display in QuickSettings -->
@@ -287,7 +287,8 @@
<integer name="doze_small_icon_alpha">222</integer><!-- 87% of 0xff -->
<!-- Doze: Table that translates sensor values from the doze_brightness_sensor_type sensor
- to brightness values; -1 means keeping the current brightness. -->
+ to brightness values in the integer scale [1, 255]; -1 means keeping the current
+ brightness. -->
<integer-array name="config_doze_brightness_sensor_to_brightness">
<item>-1</item> <!-- 0: OFF -->
<item>2</item> <!-- 1: NIGHT -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 40bdc3eb50f8..eda7bb0e7f6d 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1323,6 +1323,7 @@
<dimen name="magnifier_drag_handle_padding">3dp</dimen>
<!-- Magnification settings panel -->
<dimen name="magnification_setting_view_margin">24dp</dimen>
+ <dimen name="magnification_setting_view_item_horizontal_spacing">12dp</dimen>
<dimen name="magnification_setting_text_size">18sp</dimen>
<dimen name="magnification_setting_background_padding">24dp</dimen>
<dimen name="magnification_setting_background_corner_radius">28dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e92b942635f2..2bd97d9a2f91 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -321,11 +321,11 @@
<!-- A toast message shown when the screen recording cannot be started due to a generic error [CHAR LIMIT=NONE] -->
<string name="screenrecord_start_error">Error starting screen recording</string>
<!-- Title for a dialog shown to the user that will let them stop recording their screen [CHAR LIMIT=50] -->
- <string name="screenrecord_stop_dialog_title">Stop recording screen?</string>
- <!-- Text telling a user that they will stop recording their screen if they click the "Stop recording" button [CHAR LIMIT=100] -->
- <string name="screenrecord_stop_dialog_message">You will stop recording your screen</string>
- <!-- Text telling a user that they will stop recording the contents of the specified [app_name] if they click the "Stop recording" button. Note that the app name will appear in bold. [CHAR LIMIT=100] -->
- <string name="screenrecord_stop_dialog_message_specific_app">You will stop recording &lt;b><xliff:g id="app_name" example="Photos App">%1$s</xliff:g>&lt;/b></string>
+ <string name="screenrecord_stop_dialog_title">Stop recording?</string>
+ <!-- Text telling a user that they're currently recording their screen [CHAR LIMIT=100] -->
+ <string name="screenrecord_stop_dialog_message">You\'re currently recording your entire screen</string>
+ <!-- Text telling a user that they're currently recording the contents of the specified [app_name]. [CHAR LIMIT=100] -->
+ <string name="screenrecord_stop_dialog_message_specific_app">You\'re currently recording <xliff:g id="app_name" example="Photos App">%1$s</xliff:g></string>
<!-- Button to stop a screen recording [CHAR LIMIT=35] -->
<string name="screenrecord_stop_dialog_button">Stop recording</string>
@@ -333,21 +333,33 @@
<string name="share_to_app_chip_accessibility_label">Sharing screen</string>
<!-- Title for a dialog shown to the user that will let them stop sharing their screen to another app on the device [CHAR LIMIT=50] -->
<string name="share_to_app_stop_dialog_title">Stop sharing screen?</string>
- <!-- Text telling a user that they will stop sharing their screen if they click the "Stop sharing" button [CHAR LIMIT=100] -->
- <string name="share_to_app_stop_dialog_message">You will stop sharing your screen</string>
- <!-- Text telling a user that they will stop sharing the contents of the specified [app_name] if they click the "Stop sharing" button. Note that the app name will appear in bold. [CHAR LIMIT=100] -->
- <string name="share_to_app_stop_dialog_message_specific_app">You will stop sharing &lt;b><xliff:g id="app_name" example="Photos App">%1$s</xliff:g>&lt;/b></string>
+ <!-- Text telling a user that they're currently sharing their entire screen to [host_app_name] (i.e. [host_app_name] can currently see all screen content) [CHAR LIMIT=150] -->
+ <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app">You\'re currently sharing your entire screen with <xliff:g id="host_app_name" example="Screen Recorder App">%1$s</xliff:g></string>
+ <!-- Text telling a user that they're currently sharing their entire screen to an app (but we don't know what app) [CHAR LIMIT=150] -->
+ <string name="share_to_app_stop_dialog_message_entire_screen">You\'re currently sharing your entire screen with an app</string>
+ <!-- Text telling a user that they're currently sharing the contents of [app_being_shared_name]. (i.e. some app can currently see the content of [app_being_shared_name]). [CHAR LIMIT=150] -->
+ <string name="share_to_app_stop_dialog_message_single_app_specific">You\'re currently sharing <xliff:g id="app_being_shared_name" example="Photos App">%1$s</xliff:g></string>
+ <!-- Text telling a user that they're currently sharing their screen [CHAR LIMIT=150] -->
+ <string name="share_to_app_stop_dialog_message_single_app_generic">You\'re currently sharing an app</string>
<!-- Button to stop screen sharing [CHAR LIMIT=35] -->
<string name="share_to_app_stop_dialog_button">Stop sharing</string>
<!-- Content description for the status bar chip shown to the user when they're casting their screen to a different device [CHAR LIMIT=NONE] -->
- <string name="cast_to_other_device_chip_accessibility_label">Casting screen</string>
- <!-- Title for a dialog shown to the user that will let them stop casting their screen to a different device [CHAR LIMIT=50] -->
- <string name="cast_to_other_device_stop_dialog_title">Stop casting screen?</string>
- <!-- Text telling a user that they will stop casting their screen to a different device if they click the "Stop casting" button [CHAR LIMIT=100] -->
- <string name="cast_to_other_device_stop_dialog_message">You will stop casting your screen</string>
- <!-- Text telling a user that they will stop casting the contents of the specified [app_name] to a different device if they click the "Stop casting" button. Note that the app name will appear in bold. [CHAR LIMIT=100] -->
- <string name="cast_to_other_device_stop_dialog_message_specific_app">You will stop casting &lt;b><xliff:g id="app_name" example="Photos App">%1$s</xliff:g>&lt;/b></string>
+ <string name="cast_screen_to_other_device_chip_accessibility_label">Casting screen</string>
+ <!-- Title for a dialog shown to the user that will let them stop casting to a different device [CHAR LIMIT=50] -->
+ <string name="cast_to_other_device_stop_dialog_title">Stop casting?</string>
+ <!-- Text telling a user that they're currently casting their screen to a different device. The device receiving the cast is named [device_name]. [CHAR LIMIT=150] -->
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device">You\'re currently casting your entire screen to <xliff:g id="device_name" example="Living Room Device">%1$s</xliff:g></string>
+ <!-- Text telling a user that they're currently casting their screen to a nearby device. [CHAR LIMIT=150] -->
+ <string name="cast_to_other_device_stop_dialog_message_entire_screen">You\'re currently casting your entire screen to a nearby device</string>
+ <!-- Text telling a user that they're currently casting the contents of [app_being_shared_name] to a different device. The device receiving the cast is named [device_name]. [CHAR LIMIT=150] -->
+ <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device">You\'re currently casting <xliff:g id="app_being_shared_name" example="Photos App">%1$s</xliff:g> to <xliff:g id="device_name" example="Living Room Device">%2$s</xliff:g></string>
+ <!-- Text telling a user that they're currently casting the contents of [app_being_shared_name] to a different device. [CHAR LIMIT=150] -->
+ <string name="cast_to_other_device_stop_dialog_message_specific_app">You\'re currently casting <xliff:g id="app_being_shared_name" example="Photos App">%1$s</xliff:g> to a nearby device</string>
+ <!-- Text telling a user that they're currently casting to a different device. The device receiving the cast is named [device_name]. [CHAR LIMIT=100] -->
+ <string name="cast_to_other_device_stop_dialog_message_generic_with_device">You\'re currently casting to <xliff:g id="device_name" example="Living Room Device">%1$s</xliff:g></string>
+ <!-- Text telling a user that they're currently casting to a nearby device [CHAR LIMIT=100] -->
+ <string name="cast_to_other_device_stop_dialog_message_generic">You\'re currently casting to a nearby device</string>
<!-- Button to stop screen casting to a different device [CHAR LIMIT=35] -->
<string name="cast_to_other_device_stop_dialog_button">Stop casting</string>
@@ -704,6 +716,8 @@
<!-- QuickSettings: Do not disturb - Priority only [CHAR LIMIT=NONE] -->
<!-- QuickSettings: Do not disturb - Alarms only [CHAR LIMIT=NONE] -->
<!-- QuickSettings: Do not disturb - Total silence [CHAR LIMIT=NONE] -->
+ <!-- QuickSettings: Priority modes [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_modes_label">Priority modes</string>
<!-- QuickSettings: Bluetooth [CHAR LIMIT=NONE] -->
<string name="quick_settings_bluetooth_label">Bluetooth</string>
<!-- QuickSettings: Bluetooth (Multiple) [CHAR LIMIT=NONE] -->
@@ -1231,6 +1245,10 @@
<string name="accessibility_action_label_remove_widget">remove widget</string>
<!-- Label for accessibility action to place a widget in edit mode after selecting move widget. [CHAR LIMIT=NONE] -->
<string name="accessibility_action_label_place_widget">place selected widget</string>
+ <!-- Title in the communal widget picker. [CHAR LIMIT=50] -->
+ <string name="communal_widget_picker_title">Lock screen widgets</string>
+ <!-- Text displayed below the title in the communal widget picker providing additional details about the communal surface. [CHAR LIMIT=80] -->
+ <string name="communal_widget_picker_description">Anyone can view widgets on your lock screen, even if your tablet\'s locked.</string>
<!-- Title shown above information regarding lock screen widgets. [CHAR LIMIT=50] -->
<string name="communal_widgets_disclaimer_title">Lock screen widgets</string>
<!-- Information about lock screen widgets presented to the user. [CHAR LIMIT=NONE] -->
@@ -1855,7 +1873,7 @@
<string name="notification_channel_summary_low">No sound or vibration</string>
<!-- [CHAR LIMIT=150] Notification Importance title: low importance level summary -->
- <string name="notification_conversation_summary_low">No sound or vibration and appears lower in conversation section</string>
+ <string name="notification_conversation_summary_low">No sound or vibration but still appears in the conversation section</string>
<!-- [CHAR LIMIT=150] Notification Importance title: normal importance level summary -->
<string name="notification_channel_summary_default">May ring or vibrate based on device settings</string>
@@ -2034,6 +2052,8 @@
<string name="keyboard_key_page_down">Page Down</string>
<!-- Name used to refer to the "Delete" key on the keyboard. -->
<string name="keyboard_key_forward_del">Delete</string>
+ <!-- Name used to refer to the "Esc" or "Escape" key on the keyboard. -->
+ <string name="keyboard_key_esc">Esc</string>
<!-- Name used to refer to the "Home" move key on the keyboard. -->
<string name="keyboard_key_move_home">Home</string>
<!-- Name used to refer to the "End" move key on the keyboard. -->
@@ -3579,6 +3599,10 @@
that shows the user which keyboard shortcuts they can use. The "App shortcuts" are
for example "Open browser" or "Open calculator". [CHAR LIMIT=NONE] -->
<string name="shortcut_helper_category_app_shortcuts">App shortcuts</string>
+ <!-- Default Title of the keyboard shortcut helper category for current app. The helper is a
+ component that shows the user which keyboard shortcuts they can use. The current app
+ shortcuts are shortcuts provided by the currently open app. [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_category_current_app_shortcuts">Current App</string>
<!-- Title of the keyboard shortcut helper category "Accessibility". The helper is a component
that shows the user which keyboard shortcuts they can use. The "Accessibility" shortcuts
are for example "Turn on talkback". [CHAR LIMIT=NONE] -->
@@ -3617,6 +3641,8 @@
<string name="touchpad_tutorial_action_key_button">Action key</string>
<!-- Label for button finishing touchpad tutorial [CHAR LIMIT=NONE] -->
<string name="touchpad_tutorial_done_button">Done</string>
+ <!-- Screen title after gesture was done successfully [CHAR LIMIT=NONE] -->
+ <string name="touchpad_tutorial_gesture_done">Great job!</string>
<!-- Touchpad back gesture action name in tutorial [CHAR LIMIT=NONE] -->
<string name="touchpad_back_gesture_action_title">Go back</string>
<!-- Touchpad back gesture guidance in gestures tutorial [CHAR LIMIT=NONE] -->
@@ -3632,4 +3658,6 @@
<string name="home_controls_dream_label">Home Controls</string>
<!-- Description for home control panel [CHAR LIMIT=67] -->
<string name="home_controls_dream_description">Quickly access your home controls as a screensaver</string>
+ <!-- Label for volume undo action [CHAR LIMIT=NONE] -->
+ <string name="volume_undo_action">Undo</string>
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 7475eb2eceaa..36912acbbdb9 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -1604,7 +1604,6 @@
<item name="android:fontFamily">google-sans</item>
<item name="android:textColor">?androidprv:attr/textColorPrimary</item>
<item name="android:textSize">@dimen/magnification_setting_text_size</item>
- <item name="android:singleLine">true</item>
</style>
<style name="TextAppearance.MagnificationSetting.EditButton">
diff --git a/packages/SystemUI/res/values/tiles_states_strings.xml b/packages/SystemUI/res/values/tiles_states_strings.xml
index ad09b466dd3e..c7029272db7d 100644
--- a/packages/SystemUI/res/values/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values/tiles_states_strings.xml
@@ -85,6 +85,16 @@
<item>On</item>
</string-array>
+ <!-- State names for modes (Priority modes) tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_modes">
+ <item>Unavailable</item>
+ <item>Off</item>
+ <item>On</item>
+ </string-array>
+
<!-- State names for flashlight tile: unavailable, off, on.
This subtitle is shown when the tile is in that particular state but does not set its own
subtitle, so some of these may never appear on screen. They should still be translated as
diff --git a/packages/SystemUI/res/xml/large_screen_shade_header.xml b/packages/SystemUI/res/xml/large_screen_shade_header.xml
index fe61c46e341d..eb0aae9ebcf1 100644
--- a/packages/SystemUI/res/xml/large_screen_shade_header.xml
+++ b/packages/SystemUI/res/xml/large_screen_shade_header.xml
@@ -33,6 +33,7 @@
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginStart="8dp"
+ app:layout_constraintBaseline_toBaselineOf="@id/clock"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/clock"
app:layout_constraintTop_toTopOf="parent" />
diff --git a/packages/SystemUI/schemas/com.android.systemui.communal.data.db.CommunalDatabase/2.json b/packages/SystemUI/schemas/com.android.systemui.communal.data.db.CommunalDatabase/2.json
new file mode 100644
index 000000000000..f10d92a3fc0f
--- /dev/null
+++ b/packages/SystemUI/schemas/com.android.systemui.communal.data.db.CommunalDatabase/2.json
@@ -0,0 +1,81 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 2,
+ "identityHash": "02e2da2d36e6955200edd5fb49e63c72",
+ "entities": [
+ {
+ "tableName": "communal_widget_table",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `widget_id` INTEGER NOT NULL, `component_name` TEXT NOT NULL, `item_id` INTEGER NOT NULL, `user_serial_number` INTEGER NOT NULL DEFAULT -1)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "widgetId",
+ "columnName": "widget_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "componentName",
+ "columnName": "component_name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "itemId",
+ "columnName": "item_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "userSerialNumber",
+ "columnName": "user_serial_number",
+ "affinity": "INTEGER",
+ "notNull": true,
+ "defaultValue": "-1"
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ }
+ },
+ {
+ "tableName": "communal_item_rank_table",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `rank` INTEGER NOT NULL DEFAULT 0)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "rank",
+ "columnName": "rank",
+ "affinity": "INTEGER",
+ "notNull": true,
+ "defaultValue": "0"
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ }
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '02e2da2d36e6955200edd5fb49e63c72')"
+ ]
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/education/GestureType.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/education/GestureType.kt
new file mode 100644
index 000000000000..9a5c77ac1679
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/education/GestureType.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 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.shared.education
+
+enum class GestureType {
+ BACK_GESTURE,
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index 090033d41ffa..5d804cc22b39 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -120,7 +120,7 @@ interface ISystemUiProxy {
oneway void notifyTaskbarAutohideSuspend(boolean suspend) = 48;
/**
- * Notifies SystemUI to invoke IME Switcher.
+ * Notifies that the IME switcher button has been pressed.
*/
oneway void onImeSwitcherPressed() = 49;
@@ -167,5 +167,10 @@ interface ISystemUiProxy {
*/
oneway void toggleQuickSettingsPanel() = 56;
- // Next id = 57
+ /**
+ * Notifies that the IME Switcher button has been long pressed.
+ */
+ oneway void onImeSwitcherLongPress() = 57;
+
+ // Next id = 58
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index a614fc118636..484e758bf973 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -124,8 +124,8 @@ public class QuickStepContract {
public static final long SYSUI_STATE_SHORTCUT_HELPER_SHOWING = 1L << 32;
// Touchpad gestures are disabled
public static final long SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED = 1L << 33;
- // PiP animation is running
- public static final long SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING = 1L << 34;
+ // Communal hub is showing
+ public static final long SYSUI_STATE_COMMUNAL_HUB_SHOWING = 1L << 35;
// Mask for SystemUiStateFlags to isolate SYSUI_STATE_AWAKE and
// SYSUI_STATE_WAKEFULNESS_TRANSITION, to match WAKEFULNESS_* constants
@@ -175,7 +175,7 @@ public class QuickStepContract {
SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY,
SYSUI_STATE_SHORTCUT_HELPER_SHOWING,
SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED,
- SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING,
+ SYSUI_STATE_COMMUNAL_HUB_SHOWING,
})
public @interface SystemUiStateFlags {}
@@ -280,8 +280,8 @@ public class QuickStepContract {
if ((flags & SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED) != 0) {
str.add("touchpad_gestures_disabled");
}
- if ((flags & SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING) != 0) {
- str.add("disable_gesture_pip_animating");
+ if ((flags & SYSUI_STATE_COMMUNAL_HUB_SHOWING) != 0) {
+ str.add("communal_hub_showing");
}
return str.toString();
@@ -336,7 +336,8 @@ public class QuickStepContract {
// the keyguard)
if ((sysuiStateFlags & SYSUI_STATE_BOUNCER_SHOWING) != 0
|| (sysuiStateFlags & SYSUI_STATE_DIALOG_SHOWING) != 0
- || (sysuiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0) {
+ || (sysuiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0
+ || (sysuiStateFlags & SYSUI_STATE_COMMUNAL_HUB_SHOWING) != 0) {
return false;
}
if ((sysuiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) {
diff --git a/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt b/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
index af29b05a3fb1..8d1de0e65da5 100644
--- a/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
+++ b/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
@@ -62,6 +62,8 @@ object DebugLogger {
* @param error: a [Throwable] to log.
* @param message: a lazily evaluated message you wish to log.
*/
+ @JvmOverloads
+ @JvmName("logcatMessage")
inline fun Any.debugLog(
enabled: Boolean = Build.IS_DEBUGGABLE,
priority: Int = Log.DEBUG,
diff --git a/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt b/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
index 2764a1fdfe3d..e29ce2da9970 100644
--- a/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
+++ b/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
@@ -22,6 +22,7 @@ import android.util.Log
/** An empty logger for release builds. */
object DebugLogger {
+ @JvmOverloads
@JvmName("logcatMessage")
inline fun Any.debugLog(
enabled: Boolean = Build.IS_DEBUGGABLE,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 4af366c8674e..0f1171774d7f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -39,7 +39,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.statusbar.policy.KeyguardStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index a42f4c2dda4c..baf8f5aeba29 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -54,7 +54,6 @@ import com.android.systemui.statusbar.phone.SystemUIDialogManager;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.window.StatusBarWindowController;
-import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
import com.android.systemui.tuner.TunerService;
import dagger.Lazy;
@@ -129,7 +128,6 @@ public class Dependency {
@Nullable
@Inject Lazy<VolumeDialogController> mVolumeDialogController;
@Inject Lazy<MetricsLogger> mMetricsLogger;
- @Inject Lazy<TunablePaddingService> mTunablePaddingService;
@Inject Lazy<UiOffloadThread> mUiOffloadThread;
@Inject Lazy<LightBarController> mLightBarController;
@Inject Lazy<OverviewProxyService> mOverviewProxyService;
@@ -177,7 +175,6 @@ public class Dependency {
mProviders.put(FragmentService.class, mFragmentService::get);
mProviders.put(VolumeDialogController.class, mVolumeDialogController::get);
mProviders.put(MetricsLogger.class, mMetricsLogger::get);
- mProviders.put(TunablePaddingService.class, mTunablePaddingService::get);
mProviders.put(UiOffloadThread.class, mUiOffloadThread::get);
mProviders.put(LightBarController.class, mLightBarController::get);
mProviders.put(OverviewProxyService.class, mOverviewProxyService::get);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
index b4530ace68d6..ed7062b5a335 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
@@ -26,6 +26,7 @@ import android.content.res.Configuration;
import android.util.Range;
import android.view.WindowManager;
+import com.android.internal.accessibility.common.MagnificationConstants;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.systemui.util.settings.SecureSettings;
@@ -40,7 +41,8 @@ import com.android.systemui.util.settings.SecureSettings;
public class MagnificationSettingsController implements ComponentCallbacks {
// It should be consistent with the value defined in WindowMagnificationGestureHandler.
- private static final Range<Float> A11Y_ACTION_SCALE_RANGE = new Range<>(1.0f, 8.0f);
+ private static final Range<Float> A11Y_ACTION_SCALE_RANGE =
+ new Range<>(1.0f, MagnificationConstants.SCALE_MAX_VALUE);
private final Context mContext;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index 37e9dc1a9d48..7750f6bf4178 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -233,7 +233,7 @@ public class SystemActions implements CoreStartable, ConfigurationController.Con
// NotificationShadeWindowController.registerCallback() only keeps weak references.
mNotificationShadeCallback =
(keyguardShowing, keyguardOccluded, keyguardGoingAway, bouncerShowing, mDozing,
- panelExpanded, isDreaming) ->
+ panelExpanded, isDreaming, communalShowing) ->
registerOrUnregisterDismissNotificationShadeAction();
mScreenshotHelper = new ScreenshotHelper(mContext);
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index f2a68a8d9fd7..5f6f21a6845b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -55,7 +55,6 @@ import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.Switch;
-import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
@@ -90,7 +89,6 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
private SeekBarWithIconButtonsView mZoomSeekbar;
private LinearLayout mAllowDiagonalScrollingView;
- private TextView mAllowDiagonalScrollingTitle;
private Switch mAllowDiagonalScrollingSwitch;
private LinearLayout mPanelView;
private LinearLayout mSettingView;
@@ -98,7 +96,6 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
private ImageButton mMediumButton;
private ImageButton mLargeButton;
private Button mDoneButton;
- private TextView mSizeTitle;
private Button mEditButton;
private ImageButton mFullScreenButton;
private int mLastSelectedButtonIndex = MagnificationSize.NONE;
@@ -522,11 +519,8 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
mMediumButton = mSettingView.findViewById(R.id.magnifier_medium_button);
mLargeButton = mSettingView.findViewById(R.id.magnifier_large_button);
mDoneButton = mSettingView.findViewById(R.id.magnifier_done_button);
- mSizeTitle = mSettingView.findViewById(R.id.magnifier_size_title);
mEditButton = mSettingView.findViewById(R.id.magnifier_edit_button);
mFullScreenButton = mSettingView.findViewById(R.id.magnifier_full_button);
- mAllowDiagonalScrollingTitle =
- mSettingView.findViewById(R.id.magnifier_horizontal_lock_title);
mZoomSeekbar = mSettingView.findViewById(R.id.magnifier_zoom_slider);
mZoomSeekbar.setMax((int) (mZoomSeekbar.getChangeMagnitude()
@@ -550,8 +544,6 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
mDoneButton.setOnClickListener(mButtonClickListener);
mFullScreenButton.setOnClickListener(mButtonClickListener);
mEditButton.setOnClickListener(mButtonClickListener);
- mSizeTitle.setSelected(true);
- mAllowDiagonalScrollingTitle.setSelected(true);
mSettingView.setOnApplyWindowInsetsListener((v, insets) -> {
// Adds a pending post check to avoiding redundant calculation because this callback
@@ -578,6 +570,7 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
// CONFIG_FONT_SCALE: font size change
// CONFIG_LOCALE: language change
// CONFIG_DENSITY: display size change
+ mParams.width = getPanelWidth(mContext);
mParams.accessibilityTitle = getAccessibilityWindowTitle(mContext);
boolean showSettingPanelAfterConfigChange = mIsVisible;
@@ -660,9 +653,22 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
mCallback.onEditMagnifierSizeMode(enable);
}
- private static LayoutParams createLayoutParams(Context context) {
+ private int getPanelWidth(Context context) {
+ // The magnification settings panel width is limited to the minimum of
+ // 1. display width
+ // 2. panel done button width + left and right padding
+ // So we can directly calculate the proper panel width at runtime
+ int displayWidth = mWindowManager.getCurrentWindowMetrics().getBounds().width();
+ int contentWidth = context.getResources()
+ .getDimensionPixelSize(R.dimen.magnification_setting_button_done_width);
+ int padding = context.getResources()
+ .getDimensionPixelSize(R.dimen.magnification_setting_background_padding);
+ return Math.min(displayWidth, contentWidth + 2 * padding);
+ }
+
+ private LayoutParams createLayoutParams(Context context) {
final LayoutParams params = new LayoutParams(
- LayoutParams.WRAP_CONTENT,
+ getPanelWidth(context),
LayoutParams.WRAP_CONTENT,
LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
LayoutParams.FLAG_NOT_FOCUSABLE,
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/AccessibilityRepository.kt b/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/AccessibilityRepository.kt
index 6032f0b7b618..b33924ca0b70 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/AccessibilityRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/AccessibilityRepository.kt
@@ -18,10 +18,10 @@ package com.android.systemui.accessibility.data.repository
import android.view.accessibility.AccessibilityManager
import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener
-import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import com.android.app.tracing.FlowTracing.tracedAwaitClose
+import com.android.app.tracing.FlowTracing.tracedConflatedCallbackFlow
import dagger.Module
import dagger.Provides
-import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -38,24 +38,28 @@ interface AccessibilityRepository {
}
}
+private const val TAG = "AccessibilityRepository"
+
private class AccessibilityRepositoryImpl(
manager: AccessibilityManager,
) : AccessibilityRepository {
override val isTouchExplorationEnabled: Flow<Boolean> =
- conflatedCallbackFlow {
+ tracedConflatedCallbackFlow(TAG) {
val listener = TouchExplorationStateChangeListener(::trySend)
manager.addTouchExplorationStateChangeListener(listener)
trySend(manager.isTouchExplorationEnabled)
- awaitClose { manager.removeTouchExplorationStateChangeListener(listener) }
+ tracedAwaitClose(TAG) {
+ manager.removeTouchExplorationStateChangeListener(listener)
+ }
}
.distinctUntilChanged()
override val isEnabled: Flow<Boolean> =
- conflatedCallbackFlow {
+ tracedConflatedCallbackFlow(TAG) {
val listener = AccessibilityManager.AccessibilityStateChangeListener(::trySend)
manager.addAccessibilityStateChangeListener(listener)
trySend(manager.isEnabled)
- awaitClose { manager.removeAccessibilityStateChangeListener(listener) }
+ tracedAwaitClose(TAG) { manager.removeAccessibilityStateChangeListener(listener) }
}
.distinctUntilChanged()
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
index 4a28d8b05661..27ded747fd55 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
@@ -515,7 +515,7 @@ class MenuViewLayer extends FrameLayout implements
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY));
if (!activities.isEmpty()) {
- mContext.startActivity(intent);
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
mStatusBarManager.collapsePanels();
}
}
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 961d6aa1b821..f041f4d5963f 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
@@ -186,7 +186,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
}
@Override
- public void onDeviceItemGearClicked(@NonNull DeviceItem deviceItem, @NonNull View view) {
+ public void onDeviceItemGearClicked(@NonNull DeviceItem deviceItem, @NonNull View view) {
dismissDialogIfExists();
Intent intent = new Intent(ACTION_BLUETOOTH_DEVICE_DETAILS);
Bundle bundle = new Bundle();
@@ -198,7 +198,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
}
@Override
- public void onDeviceItemOnClicked(@NonNull DeviceItem deviceItem, @NonNull View view) {
+ public void onDeviceItemOnClicked(@NonNull DeviceItem deviceItem, @NonNull View view) {
CachedBluetoothDevice cachedBluetoothDevice = deviceItem.getCachedBluetoothDevice();
switch (deviceItem.getType()) {
case ACTIVE_MEDIA_BLUETOOTH_DEVICE, CONNECTED_BLUETOOTH_DEVICE ->
@@ -226,8 +226,8 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
final int activePresetIndex = mPresetsController.getActivePresetIndex();
refreshPresetInfoAdapter(presetInfos, activePresetIndex);
mPresetSpinner.setVisibility(
- (activeHearingDevice != null && !mPresetInfoAdapter.isEmpty()) ? VISIBLE
- : GONE);
+ (activeHearingDevice != null && activeHearingDevice.isConnectedHapClientDevice()
+ && !mPresetInfoAdapter.isEmpty()) ? VISIBLE : GONE);
});
}
@@ -303,6 +303,11 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
mLocalBluetoothManager.getEventManager().unregisterCallback(this);
}
+ @VisibleForTesting
+ void setHearingDevicesPresetsController(HearingDevicesPresetsController controller) {
+ mPresetsController = controller;
+ }
+
private void setupDeviceListView(SystemUIDialog dialog) {
mDeviceList.setLayoutManager(new LinearLayoutManager(dialog.getContext()));
mHearingDeviceItemList = getHearingDevicesList();
@@ -311,12 +316,15 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
}
private void setupPresetSpinner(SystemUIDialog dialog) {
- mPresetsController = new HearingDevicesPresetsController(mProfileManager, mPresetCallback);
+ if (mPresetsController == null) {
+ mPresetsController = new HearingDevicesPresetsController(mProfileManager,
+ mPresetCallback);
+ }
final CachedBluetoothDevice activeHearingDevice = getActiveHearingDevice(
mHearingDeviceItemList);
mPresetsController.setActiveHearingDevice(activeHearingDevice);
- mPresetInfoAdapter = new ArrayAdapter<String>(dialog.getContext(),
+ mPresetInfoAdapter = new ArrayAdapter<>(dialog.getContext(),
R.layout.hearing_devices_preset_spinner_selected,
R.id.hearing_devices_preset_option_text);
mPresetInfoAdapter.setDropDownViewResource(
@@ -350,7 +358,8 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
final int activePresetIndex = mPresetsController.getActivePresetIndex();
refreshPresetInfoAdapter(presetInfos, activePresetIndex);
mPresetSpinner.setVisibility(
- (activeHearingDevice != null && !mPresetInfoAdapter.isEmpty()) ? VISIBLE : GONE);
+ (activeHearingDevice != null && activeHearingDevice.isConnectedHapClientDevice()
+ && !mPresetInfoAdapter.isEmpty()) ? VISIBLE : GONE);
}
private void setupPairNewDeviceButton(SystemUIDialog dialog, @Visibility int visibility) {
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/touch/ShadeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/ambient/touch/ShadeTouchHandler.java
index fcd7ef53d42a..f1fb45c9b16e 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/touch/ShadeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/ambient/touch/ShadeTouchHandler.java
@@ -26,7 +26,7 @@ import android.view.MotionEvent;
import androidx.annotation.NonNull;
-import com.android.systemui.Flags;
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
@@ -44,6 +44,8 @@ public class ShadeTouchHandler implements TouchHandler {
private final ShadeViewController mShadeViewController;
private final DreamManager mDreamManager;
private final int mInitiationHeight;
+ private final CommunalSettingsInteractor
+ mCommunalSettingsInteractor;
/**
* Tracks whether or not we are capturing a given touch. Will be null before and after a touch.
@@ -54,10 +56,12 @@ public class ShadeTouchHandler implements TouchHandler {
ShadeTouchHandler(Optional<CentralSurfaces> centralSurfaces,
ShadeViewController shadeViewController,
DreamManager dreamManager,
+ CommunalSettingsInteractor communalSettingsInteractor,
@Named(NOTIFICATION_SHADE_GESTURE_INITIATION_HEIGHT) int initiationHeight) {
mSurfaces = centralSurfaces;
mShadeViewController = shadeViewController;
mDreamManager = dreamManager;
+ mCommunalSettingsInteractor = communalSettingsInteractor;
mInitiationHeight = initiationHeight;
}
@@ -107,7 +111,7 @@ public class ShadeTouchHandler implements TouchHandler {
}
private void sendTouchEvent(MotionEvent event) {
- if (Flags.communalHub() && !mDreamManager.isDreaming()) {
+ if (mCommunalSettingsInteractor.isCommunalFlagEnabled() && !mDreamManager.isDreaming()) {
// Send touches to central surfaces only when on the glanceable hub while not dreaming.
// While sending touches where while dreaming will open the shade, the shade
// while closing if opened then closed in the same gesture.
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index d30f33f5ba2c..a67dcdb70b67 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -515,7 +515,7 @@ public class AssistManager {
}
@Nullable
- private ComponentName getAssistInfo() {
+ public ComponentName getAssistInfo() {
return getAssistInfoForUser(mSelectedUserInteractor.getSelectedUserId());
}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
index 56273eb9a2cf..6e257442d139 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
@@ -33,6 +33,7 @@ import android.view.WindowManager;
import android.view.animation.PathInterpolator;
import android.widget.FrameLayout;
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.assist.AssistLogger;
@@ -66,7 +67,7 @@ public class DefaultUiController implements AssistManager.UiController {
protected InvocationLightsView mInvocationLightsView;
protected final AssistLogger mAssistLogger;
- private final WindowManager mWindowManager;
+ private final ViewCaptureAwareWindowManager mWindowManager;
private final MetricsLogger mMetricsLogger;
private final Lazy<AssistManager> mAssistManagerLazy;
private final WindowManager.LayoutParams mLayoutParams;
@@ -80,12 +81,12 @@ public class DefaultUiController implements AssistManager.UiController {
@Inject
public DefaultUiController(Context context, AssistLogger assistLogger,
- WindowManager windowManager, MetricsLogger metricsLogger,
- Lazy<AssistManager> assistManagerLazy,
+ ViewCaptureAwareWindowManager viewCaptureAwareWindowManager,
+ MetricsLogger metricsLogger, Lazy<AssistManager> assistManagerLazy,
NavigationBarController navigationBarController) {
mAssistLogger = assistLogger;
mRoot = new FrameLayout(context);
- mWindowManager = windowManager;
+ mWindowManager = viewCaptureAwareWindowManager;
mMetricsLogger = metricsLogger;
mAssistManagerLazy = assistManagerLazy;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
index 0cdb376e7a27..7dfa4f91bb47 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
@@ -31,9 +31,9 @@ import android.view.ContextThemeWrapper;
import android.view.View;
import com.android.settingslib.Utils;
-import com.android.systemui.navigationbar.NavigationBar;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarTransitions;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarTransitions;
import com.android.systemui.res.R;
import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
index a9f985f0955b..468737d9372f 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
@@ -288,6 +288,7 @@ constructor(
override suspend fun reportAuthenticationAttempt(isSuccessful: Boolean) {
withContext(backgroundDispatcher) {
if (isSuccessful) {
+ lockPatternUtils.userPresent(selectedUserId)
lockPatternUtils.reportSuccessfulPasswordAttempt(selectedUserId)
_hasLockoutOccurred.value = false
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index d6d40f28d288..b466f31cc509 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -995,6 +995,16 @@ public class AuthController implements
}
/**
+ * @return true if ultrasonic udfps HW is supported on this device. Can return true even if
+ * the user has not enrolled udfps. This may be false if called before
+ * onAllAuthenticatorsRegistered.
+ */
+ public boolean isUltrasonicUdfpsSupported() {
+ return getUdfpsProps() != null && !getUdfpsProps().isEmpty() && getUdfpsProps()
+ .get(0).isUltrasonicUdfps();
+ }
+
+ /**
* @return true if sfps HW is supported on this device. Can return true even if the user has
* not enrolled sfps. This may be false if called before onAllAuthenticatorsRegistered.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDebouncer.kt b/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDebouncer.kt
new file mode 100644
index 000000000000..1685f49e4f3e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDebouncer.kt
@@ -0,0 +1,125 @@
+/*
+ * 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.biometrics
+
+import android.util.Log
+import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus
+
+/**
+ * Debounces face help messages with parameters:
+ * - window: Window of time (in milliseconds) to analyze face acquired messages)
+ * - startWindow: Window of time on start required before showing the first help message
+ * - shownFaceMessageFrequencyBoost: Frequency boost given to messages that are currently shown to
+ * the user
+ */
+class FaceHelpMessageDebouncer(
+ private val window: Long = DEFAULT_WINDOW_MS,
+ private val startWindow: Long = window,
+ private val shownFaceMessageFrequencyBoost: Int = 4,
+) {
+ private val TAG = "FaceHelpMessageDebouncer"
+ private var startTime = 0L
+ private var helpFaceAuthStatuses: MutableList<HelpFaceAuthenticationStatus> = mutableListOf()
+ private var lastMessageIdShown: Int? = null
+
+ /** Remove messages that are outside of the time [window]. */
+ private fun removeOldMessages(currTimestamp: Long) {
+ var numToRemove = 0
+ // This works under the assumption that timestamps are ordered from first to last
+ // in chronological order
+ for (index in helpFaceAuthStatuses.indices) {
+ if ((helpFaceAuthStatuses[index].createdAt + window) >= currTimestamp) {
+ break // all timestamps from here and on are within the window
+ }
+ numToRemove += 1
+ }
+
+ // Remove all outside time window
+ repeat(numToRemove) { helpFaceAuthStatuses.removeFirst() }
+
+ if (numToRemove > 0) {
+ Log.v(TAG, "removedFirst=$numToRemove")
+ }
+ }
+
+ private fun getMostFrequentHelpMessage(): HelpFaceAuthenticationStatus? {
+ // freqMap: msgId => frequency
+ val freqMap = helpFaceAuthStatuses.groupingBy { it.msgId }.eachCount().toMutableMap()
+
+ // Give shownFaceMessageFrequencyBoost to lastMessageIdShown
+ if (lastMessageIdShown != null) {
+ freqMap.computeIfPresent(lastMessageIdShown!!) { _, value ->
+ value + shownFaceMessageFrequencyBoost
+ }
+ }
+ // Go through all msgId keys & find the highest frequency msgId
+ val msgIdWithHighestFrequency =
+ freqMap.entries
+ .maxWithOrNull { (msgId1, freq1), (msgId2, freq2) ->
+ // ties are broken by more recent message
+ if (freq1 == freq2) {
+ helpFaceAuthStatuses
+ .findLast { it.msgId == msgId1 }!!
+ .createdAt
+ .compareTo(
+ helpFaceAuthStatuses.findLast { it.msgId == msgId2 }!!.createdAt
+ )
+ } else {
+ freq1.compareTo(freq2)
+ }
+ }
+ ?.key
+ return helpFaceAuthStatuses.findLast { it.msgId == msgIdWithHighestFrequency }
+ }
+
+ fun addMessage(helpFaceAuthStatus: HelpFaceAuthenticationStatus) {
+ helpFaceAuthStatuses.add(helpFaceAuthStatus)
+ Log.v(TAG, "added message=$helpFaceAuthStatus")
+ }
+
+ fun getMessageToShow(atTimestamp: Long): HelpFaceAuthenticationStatus? {
+ if (helpFaceAuthStatuses.isEmpty() || (atTimestamp - startTime) < startWindow) {
+ // there's not enough time that has passed to determine whether to show anything yet
+ Log.v(TAG, "No message; haven't made initial threshold window OR no messages")
+ return null
+ }
+ removeOldMessages(atTimestamp)
+ val messageToShow = getMostFrequentHelpMessage()
+ if (lastMessageIdShown != messageToShow?.msgId) {
+ Log.v(
+ TAG,
+ "showMessage previousLastMessageId=$lastMessageIdShown" +
+ "\n\tmessageToShow=$messageToShow " +
+ "\n\thelpFaceAuthStatusesSize=${helpFaceAuthStatuses.size}" +
+ "\n\thelpFaceAuthStatuses=$helpFaceAuthStatuses"
+ )
+ lastMessageIdShown = messageToShow?.msgId
+ }
+ return messageToShow
+ }
+
+ fun startNewFaceAuthSession(faceAuthStartedTime: Long) {
+ Log.d(TAG, "startNewFaceAuthSession at startTime=$startTime")
+ startTime = faceAuthStartedTime
+ helpFaceAuthStatuses.clear()
+ lastMessageIdShown = null
+ }
+
+ companion object {
+ const val DEFAULT_WINDOW_MS = 200L
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 9d3c6a49a616..3dd375846499 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -270,6 +270,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {
@Override
public void showUdfpsOverlay(long requestId, int sensorId, int reason,
@NonNull IUdfpsOverlayControllerCallback callback) {
+ mUdfpsOverlayInteractor.setRequestId(requestId);
mFgExecutor.execute(() -> UdfpsController.this.showUdfpsOverlay(
new UdfpsControllerOverlay(
mContext,
@@ -404,6 +405,15 @@ public class UdfpsController implements DozeReceiver, Dumpable {
handler::post,
authenticationCallback);
}
+
+ /**
+ * Debug to run setIgnoreDisplayTouches
+ */
+ public void debugSetIgnoreDisplayTouches(boolean ignoreTouch) {
+ final long requestId = (mOverlay != null) ? mOverlay.getRequestId() : 0L;
+ UdfpsController.this.mFingerprintManager.setIgnoreDisplayTouches(
+ requestId, mSensorProps.sensorId, ignoreTouch);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
index f5e3d29cb878..97ece11b8fbb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
@@ -75,6 +75,8 @@ class UdfpsShell @Inject constructor(commandRegistry: CommandRegistry) : Command
simFingerUp()
} else if (args.size == 1 && args[0] == "biometricPrompt") {
launchBiometricPrompt()
+ } else if (args.size == 2 && args[0] == "setIgnoreDisplayTouches") {
+ setIgnoreDisplayTouches(args[1].toBoolean())
} else {
invalidCommand(pw)
}
@@ -186,6 +188,11 @@ class UdfpsShell @Inject constructor(commandRegistry: CommandRegistry) : Command
upEvent?.recycle()
}
+ @VisibleForTesting
+ fun setIgnoreDisplayTouches(ignoreTouches: Boolean) {
+ udfpsOverlayController?.debugSetIgnoreDisplayTouches(ignoreTouches)
+ }
+
private fun obtainMotionEvent(
action: Int,
x: Float,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
index a742c0e33bc5..8c64b76af393 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
package com.android.systemui.biometrics.domain.interactor
import android.hardware.biometrics.AuthenticateOptions
@@ -21,16 +23,22 @@ import android.hardware.biometrics.IBiometricContextListener
import android.util.Log
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.display.data.repository.DeviceStateRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
@@ -76,22 +84,36 @@ constructor(
deviceStateRepository: DeviceStateRepository,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
udfpsOverlayInteractor: UdfpsOverlayInteractor,
+ deviceEntryInteractor: Lazy<DeviceEntryInteractor>,
) : LogContextInteractor {
- override val displayState =
- keyguardTransitionInteractor.startedKeyguardTransitionStep.map {
- when (it.to) {
- KeyguardState.LOCKSCREEN,
- KeyguardState.OCCLUDED,
- KeyguardState.ALTERNATE_BOUNCER,
- KeyguardState.PRIMARY_BOUNCER -> AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN
- KeyguardState.AOD -> AuthenticateOptions.DISPLAY_STATE_AOD
- KeyguardState.OFF,
- KeyguardState.DOZING -> AuthenticateOptions.DISPLAY_STATE_NO_UI
- KeyguardState.DREAMING -> AuthenticateOptions.DISPLAY_STATE_SCREENSAVER
- else -> AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+ override val displayState: Flow<Int> by lazy {
+ if (SceneContainerFlag.isEnabled) {
+ combine(
+ deviceEntryInteractor.get().isDeviceEntered,
+ keyguardTransitionInteractor.startedKeyguardTransitionStep,
+ ) { isDeviceEntered, transitionStep ->
+ if (isDeviceEntered) {
+ AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+ } else {
+ transitionStep.toAuthenticateOptions(
+ // Here when isDeviceEntered=false which always means that the device is on
+ // top of the keyguard. Therefore, any KeyguardState that doesn't have a
+ // more specific mapping as a sub-state of keyguard, maps to LOCKSCREEN
+ // instead of UNKNOWN, because it _is_ a known display state and that
+ // display state is undeniably LOCKSCREEN.
+ default = AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN
+ )
+ }
+ }
+ } else {
+ keyguardTransitionInteractor.startedKeyguardTransitionStep.map { transitionStep ->
+ transitionStep.toAuthenticateOptions(
+ default = AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+ )
}
}
+ }
override val isHardwareIgnoringTouches: Flow<Boolean> =
udfpsOverlayInteractor.shouldHandleTouches.map { shouldHandle -> !shouldHandle }
@@ -152,6 +174,21 @@ constructor(
}
}
+ private fun TransitionStep.toAuthenticateOptions(default: Int): Int {
+ return when (this.to) {
+ KeyguardState.LOCKSCREEN,
+ KeyguardState.OCCLUDED,
+ KeyguardState.ALTERNATE_BOUNCER,
+ KeyguardState.PRIMARY_BOUNCER -> AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN
+ KeyguardState.AOD -> AuthenticateOptions.DISPLAY_STATE_AOD
+ KeyguardState.OFF,
+ KeyguardState.DOZING -> AuthenticateOptions.DISPLAY_STATE_NO_UI
+ KeyguardState.DREAMING -> AuthenticateOptions.DISPLAY_STATE_SCREENSAVER
+ KeyguardState.GONE -> AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+ else -> default
+ }
+ }
+
companion object {
private const val TAG = "ContextRepositoryImpl"
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
index a77cc1fea6a6..bb450c0b6d90 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
@@ -17,6 +17,7 @@
package com.android.systemui.biometrics.domain.interactor
import android.content.Context
+import android.hardware.fingerprint.FingerprintManager
import android.util.Log
import android.view.MotionEvent
import com.android.systemui.biometrics.AuthController
@@ -46,6 +47,7 @@ constructor(
@Application private val context: Context,
private val authController: AuthController,
private val selectedUserInteractor: SelectedUserInteractor,
+ private val fingerprintManager: FingerprintManager?,
@Application scope: CoroutineScope
) {
private fun calculateIconSize(): Int {
@@ -70,8 +72,25 @@ constructor(
return isUdfpsEnrolled && isWithinOverlayBounds
}
+ private var _requestId = MutableStateFlow(0L)
+
+ /** RequestId of current AcquisitionClient */
+ val requestId: StateFlow<Long> = _requestId.asStateFlow()
+
+ fun setRequestId(requestId: Long) {
+ _requestId.value = requestId
+ }
+
/** Sets whether Udfps overlay should handle touches */
fun setHandleTouches(shouldHandle: Boolean = true) {
+ if (authController.isUltrasonicUdfpsSupported
+ && shouldHandle != _shouldHandleTouches.value) {
+ fingerprintManager?.setIgnoreDisplayTouches(
+ requestId.value,
+ authController.udfpsProps!!.get(0).sensorId,
+ !shouldHandle
+ )
+ }
_shouldHandleTouches.value = shouldHandle
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index c868d01de743..430887dfcab6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -94,8 +94,16 @@ object BiometricViewBinder {
val textColorError =
view.resources.getColor(R.color.biometric_dialog_error, view.context.theme)
+
+ val attributes =
+ view.context.obtainStyledAttributes(
+ R.style.TextAppearance_AuthCredential_Indicator,
+ intArrayOf(android.R.attr.textColor)
+ )
val textColorHint =
- view.resources.getColor(R.color.biometric_dialog_gray, view.context.theme)
+ if (constraintBp()) attributes.getColor(0, 0)
+ else view.resources.getColor(R.color.biometric_dialog_gray, view.context.theme)
+ attributes.recycle()
val logoView = view.requireViewById<ImageView>(R.id.logo)
val logoDescriptionView = view.requireViewById<TextView>(R.id.logo_description)
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
index 1d11dfbc48a8..4984fc61c8f8 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
@@ -102,11 +102,7 @@ constructor(
if (alternateBouncerSupported) {
combine(
keyguardTransitionInteractor.get().currentKeyguardState,
- if (SceneContainerFlag.isEnabled) {
- sceneInteractor.get().currentScene
- } else {
- flowOf(Scenes.Lockscreen)
- },
+ sceneInteractor.get().currentScene,
::Pair
)
.flatMapLatest { (currentKeyguardState, transitionState) ->
@@ -220,6 +216,7 @@ constructor(
return (systemClock.uptimeMillis() - bouncerRepository.lastAlternateBouncerVisibleTime) >
MIN_VISIBILITY_DURATION_UNTIL_TOUCHES_DISMISS_ALTERNATE_BOUNCER_MS
}
+
/**
* Should only be called through StatusBarKeyguardViewManager which propagates the source of
* truth to other concerned controllers. Will hide the alternate bouncer if it's no longer
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt
index 6cb9b16e2f9b..810b6d10f355 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt
@@ -32,7 +32,7 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.BiometricMessageInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFingerprintAuthInteractor
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason
import com.android.systemui.deviceentry.shared.model.FaceFailureMessage
import com.android.systemui.deviceentry.shared.model.FaceLockoutMessage
@@ -75,7 +75,7 @@ class BouncerMessageViewModel(
private val clock: SystemClock,
private val biometricMessageInteractor: BiometricMessageInteractor,
private val faceAuthInteractor: DeviceEntryFaceAuthInteractor,
- private val deviceEntryInteractor: DeviceEntryInteractor,
+ private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
private val fingerprintInteractor: DeviceEntryFingerprintAuthInteractor,
flags: ComposeBouncerFlags,
) {
@@ -119,7 +119,7 @@ class BouncerMessageViewModel(
}
} else if (authMethod.isSecure) {
combine(
- deviceEntryInteractor.deviceEntryRestrictionReason,
+ deviceUnlockedInteractor.deviceEntryRestrictionReason,
lockoutMessage,
fingerprintInteractor.isFingerprintCurrentlyAllowedOnBouncer,
resetToDefault,
@@ -413,7 +413,7 @@ object BouncerMessageViewModelModule {
clock: SystemClock,
biometricMessageInteractor: BiometricMessageInteractor,
faceAuthInteractor: DeviceEntryFaceAuthInteractor,
- deviceEntryInteractor: DeviceEntryInteractor,
+ deviceUnlockedInteractor: DeviceUnlockedInteractor,
fingerprintInteractor: DeviceEntryFingerprintAuthInteractor,
flags: ComposeBouncerFlags,
userSwitcherViewModel: UserSwitcherViewModel,
@@ -427,7 +427,7 @@ object BouncerMessageViewModelModule {
clock = clock,
biometricMessageInteractor = biometricMessageInteractor,
faceAuthInteractor = faceAuthInteractor,
- deviceEntryInteractor = deviceEntryInteractor,
+ deviceUnlockedInteractor = deviceUnlockedInteractor,
fingerprintInteractor = fingerprintInteractor,
flags = flags,
selectedUser = userSwitcherViewModel.selectedUser,
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
index f991d5b8405f..8270db1e89a8 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
@@ -16,7 +16,7 @@
package com.android.systemui.brightness.ui.compose
-import androidx.compose.animation.core.animateIntAsState
+import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
@@ -57,12 +57,12 @@ private fun BrightnessSlider(
) {
var value by remember(gammaValue) { mutableIntStateOf(gammaValue) }
val animatedValue by
- animateIntAsState(targetValue = value, label = "BrightnessSliderAnimatedValue")
+ animateFloatAsState(targetValue = value.toFloat(), label = "BrightnessSliderAnimatedValue")
val floatValueRange = valueRange.first.toFloat()..valueRange.last.toFloat()
- val isRestricted = restriction is PolicyRestriction.Restricted
+ val isRestricted = remember(restriction) { restriction is PolicyRestriction.Restricted }
PlatformSlider(
- value = animatedValue.toFloat(),
+ value = animatedValue,
valueRange = floatValueRange,
enabled = !isRestricted,
onValueChange = {
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
index ba236ba016ff..1762d82b3237 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
@@ -18,8 +18,6 @@ package com.android.systemui.clipboardoverlay;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
-import static com.android.systemui.Flags.screenshotShelfUi2;
-
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -61,7 +59,6 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import com.android.systemui.res.R;
import com.android.systemui.screenshot.DraggableConstraintLayout;
import com.android.systemui.screenshot.FloatingWindowUtil;
-import com.android.systemui.screenshot.OverlayActionChip;
import com.android.systemui.screenshot.ui.binder.ActionButtonViewBinder;
import com.android.systemui.screenshot.ui.viewmodel.ActionButtonAppearance;
import com.android.systemui.screenshot.ui.viewmodel.ActionButtonViewModel;
@@ -152,66 +149,47 @@ public class ClipboardOverlayView extends DraggableConstraintLayout {
}
private void bindDefaultActionChips() {
- if (screenshotShelfUi2()) {
- mActionButtonViewBinder.bind(mRemoteCopyChip,
- ActionButtonViewModel.Companion.withNextId(
- new ActionButtonAppearance(
- Icon.createWithResource(mContext,
- R.drawable.ic_baseline_devices_24).loadDrawable(
- mContext),
- null,
- mContext.getString(R.string.clipboard_send_nearby_description),
- true),
- new Function0<>() {
- @Override
- public Unit invoke() {
- if (mClipboardCallbacks != null) {
- mClipboardCallbacks.onRemoteCopyButtonTapped();
- }
- return null;
+ mActionButtonViewBinder.bind(mRemoteCopyChip,
+ ActionButtonViewModel.Companion.withNextId(
+ new ActionButtonAppearance(
+ Icon.createWithResource(mContext,
+ R.drawable.ic_baseline_devices_24).loadDrawable(
+ mContext),
+ null,
+ mContext.getString(R.string.clipboard_send_nearby_description),
+ true),
+ new Function0<>() {
+ @Override
+ public Unit invoke() {
+ if (mClipboardCallbacks != null) {
+ mClipboardCallbacks.onRemoteCopyButtonTapped();
}
- }));
- mActionButtonViewBinder.bind(mShareChip,
- ActionButtonViewModel.Companion.withNextId(
- new ActionButtonAppearance(
- Icon.createWithResource(mContext,
- R.drawable.ic_screenshot_share).loadDrawable(mContext),
- null,
- mContext.getString(com.android.internal.R.string.share),
- true),
- new Function0<>() {
- @Override
- public Unit invoke() {
- if (mClipboardCallbacks != null) {
- mClipboardCallbacks.onShareButtonTapped();
- }
- return null;
+ return null;
+ }
+ }));
+ mActionButtonViewBinder.bind(mShareChip,
+ ActionButtonViewModel.Companion.withNextId(
+ new ActionButtonAppearance(
+ Icon.createWithResource(mContext,
+ R.drawable.ic_screenshot_share).loadDrawable(mContext),
+ null,
+ mContext.getString(com.android.internal.R.string.share),
+ true),
+ new Function0<>() {
+ @Override
+ public Unit invoke() {
+ if (mClipboardCallbacks != null) {
+ mClipboardCallbacks.onShareButtonTapped();
}
- }));
- } else {
- mShareChip.setAlpha(1);
- mRemoteCopyChip.setAlpha(1);
-
- ((ImageView) mRemoteCopyChip.findViewById(R.id.overlay_action_chip_icon)).setImageIcon(
- Icon.createWithResource(mContext, R.drawable.ic_baseline_devices_24));
- ((ImageView) mShareChip.findViewById(R.id.overlay_action_chip_icon)).setImageIcon(
- Icon.createWithResource(mContext, R.drawable.ic_screenshot_share));
-
- mShareChip.setContentDescription(
- mContext.getString(com.android.internal.R.string.share));
- mRemoteCopyChip.setContentDescription(
- mContext.getString(R.string.clipboard_send_nearby_description));
- }
+ return null;
+ }
+ }));
}
@Override
public void setCallbacks(SwipeDismissCallbacks callbacks) {
super.setCallbacks(callbacks);
ClipboardOverlayCallbacks clipboardCallbacks = (ClipboardOverlayCallbacks) callbacks;
- if (!screenshotShelfUi2()) {
- mShareChip.setOnClickListener(v -> clipboardCallbacks.onShareButtonTapped());
- mRemoteCopyChip.setOnClickListener(v -> clipboardCallbacks.onRemoteCopyButtonTapped());
- }
mDismissButton.setOnClickListener(v -> clipboardCallbacks.onDismissButtonTapped());
mClipboardPreview.setOnClickListener(v -> clipboardCallbacks.onPreviewTapped());
mMinimizedPreview.setOnClickListener(v -> clipboardCallbacks.onMinimizedViewTapped());
@@ -495,12 +473,7 @@ public class ClipboardOverlayView extends DraggableConstraintLayout {
void setActionChip(RemoteAction action, Runnable onFinish) {
mActionContainerBackground.setVisibility(View.VISIBLE);
- View chip;
- if (screenshotShelfUi2()) {
- chip = constructShelfActionChip(action, onFinish);
- } else {
- chip = constructActionChip(action, onFinish);
- }
+ View chip = constructShelfActionChip(action, onFinish);
mActionContainer.addView(chip);
mActionChips.add(chip);
}
@@ -534,17 +507,6 @@ public class ClipboardOverlayView extends DraggableConstraintLayout {
return chip;
}
- private OverlayActionChip constructActionChip(RemoteAction action, Runnable onFinish) {
- OverlayActionChip chip = (OverlayActionChip) LayoutInflater.from(mContext).inflate(
- R.layout.overlay_action_chip, mActionContainer, false);
- chip.setText(action.getTitle());
- chip.setContentDescription(action.getTitle());
- chip.setIcon(action.getIcon(), false);
- chip.setPendingIntent(action.getActionIntent(), onFinish);
- chip.setAlpha(1);
- return chip;
- }
-
private static void updateTextSize(CharSequence text, TextView textView) {
Paint paint = new Paint(textView.getPaint());
Resources res = textView.getResources();
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 740a93eb081c..ff9fba4c03f1 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java
@@ -18,8 +18,6 @@ package com.android.systemui.clipboardoverlay.dagger;
import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
-import static com.android.systemui.Flags.screenshotShelfUi2;
-
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import android.content.Context;
@@ -59,13 +57,8 @@ public interface ClipboardOverlayModule {
*/
@Provides
static ClipboardOverlayView provideClipboardOverlayView(@OverlayWindowContext Context context) {
- if (screenshotShelfUi2()) {
- return (ClipboardOverlayView) LayoutInflater.from(context).inflate(
- R.layout.clipboard_overlay2, null);
- } else {
- return (ClipboardOverlayView) LayoutInflater.from(context).inflate(
- R.layout.clipboard_overlay, null);
- }
+ return (ClipboardOverlayView) LayoutInflater.from(context).inflate(
+ R.layout.clipboard_overlay, null);
}
@Qualifier
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalBackupRestoreStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalBackupRestoreStartable.kt
index cdeeb6ff0b23..7abad1448318 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalBackupRestoreStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalBackupRestoreStartable.kt
@@ -21,6 +21,9 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
+import android.database.ContentObserver
+import android.os.Handler
+import android.provider.Settings.Secure.USER_SETUP_COMPLETE
import com.android.systemui.CoreStartable
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.communal.domain.interactor.CommunalInteractor
@@ -29,6 +32,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.Logger
import com.android.systemui.log.dagger.CommunalLog
+import com.android.systemui.util.settings.SecureSettings
import javax.inject.Inject
@SysUISingleton
@@ -38,10 +42,15 @@ constructor(
private val broadcastDispatcher: BroadcastDispatcher,
private val communalInteractor: CommunalInteractor,
@CommunalLog logBuffer: LogBuffer,
+ private val secureSettings: SecureSettings,
+ handler: Handler,
) : CoreStartable, BroadcastReceiver() {
private val logger = Logger(logBuffer, TAG)
+ private var oldToNewWidgetIdMap = emptyMap<Int, Int>()
+ private var userSetupComplete = false
+
override fun start() {
broadcastDispatcher.registerReceiver(
receiver = this,
@@ -73,8 +82,53 @@ constructor(
return
}
- val oldToNewWidgetIdMap = oldIds.zip(newIds).toMap()
- communalInteractor.restoreWidgets(oldToNewWidgetIdMap)
+ oldToNewWidgetIdMap = oldIds.zip(newIds).toMap()
+
+ logger.i({ "On old to new widget ids mapping updated: $str1" }) {
+ str1 = oldToNewWidgetIdMap.toString()
+ }
+
+ maybeRestoreWidgets()
+
+ // Start observing if user setup is not complete
+ if (!userSetupComplete) {
+ startObservingUserSetupComplete()
+ }
+ }
+
+ private val userSetupObserver =
+ object : ContentObserver(handler) {
+ override fun onChange(selfChange: Boolean) {
+ maybeRestoreWidgets()
+
+ // Stop observing once user setup is complete
+ if (userSetupComplete) {
+ stopObservingUserSetupComplete()
+ }
+ }
+ }
+
+ private fun maybeRestoreWidgets() {
+ val newValue = secureSettings.getInt(USER_SETUP_COMPLETE) > 0
+
+ if (userSetupComplete != newValue) {
+ userSetupComplete = newValue
+ logger.i({ "User setup complete: $bool1" }) { bool1 = userSetupComplete }
+ }
+
+ if (userSetupComplete && oldToNewWidgetIdMap.isNotEmpty()) {
+ logger.i("Starting to restore widgets")
+ communalInteractor.restoreWidgets(oldToNewWidgetIdMap.toMap())
+ oldToNewWidgetIdMap = emptyMap()
+ }
+ }
+
+ private fun startObservingUserSetupComplete() {
+ secureSettings.registerContentObserverSync(USER_SETUP_COMPLETE, userSetupObserver)
+ }
+
+ private fun stopObservingUserSetupComplete() {
+ secureSettings.unregisterContentObserverSync(userSetupObserver)
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt
index 38f51daca2a4..0582cc20927c 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt
@@ -19,9 +19,9 @@ package com.android.systemui.communal
import android.annotation.SuppressLint
import android.app.DreamManager
import com.android.systemui.CoreStartable
-import com.android.systemui.Flags.communalHub
import com.android.systemui.Flags.glanceableHubAllowKeyguardWhenDreaming
import com.android.systemui.Flags.restartDreamOnUnocclude
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
@@ -48,6 +48,7 @@ class CommunalDreamStartable
@Inject
constructor(
private val powerInteractor: PowerInteractor,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
private val keyguardInteractor: KeyguardInteractor,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val dreamManager: DreamManager,
@@ -55,7 +56,7 @@ constructor(
) : CoreStartable {
@SuppressLint("MissingPermission")
override fun start() {
- if (!communalHub()) {
+ if (!communalSettingsInteractor.isCommunalFlagEnabled()) {
return
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalOngoingContentStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalOngoingContentStartable.kt
new file mode 100644
index 000000000000..b1b02cec871d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalOngoingContentStartable.kt
@@ -0,0 +1,58 @@
+/*
+ * 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.communal
+
+import com.android.systemui.CoreStartable
+import com.android.systemui.communal.data.repository.CommunalMediaRepository
+import com.android.systemui.communal.data.repository.CommunalSmartspaceRepository
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+@SysUISingleton
+class CommunalOngoingContentStartable
+@Inject
+constructor(
+ @Background val bgScope: CoroutineScope,
+ private val communalInteractor: CommunalInteractor,
+ private val communalMediaRepository: CommunalMediaRepository,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
+ private val communalSmartspaceRepository: CommunalSmartspaceRepository,
+) : CoreStartable {
+
+ override fun start() {
+ if (!communalSettingsInteractor.isCommunalFlagEnabled()) {
+ return
+ }
+
+ bgScope.launch {
+ communalInteractor.isCommunalEnabled.collect { enabled ->
+ if (enabled) {
+ communalMediaRepository.startListening()
+ communalSmartspaceRepository.startListening()
+ } else {
+ communalMediaRepository.stopListening()
+ communalSmartspaceRepository.stopListening()
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
index 88c3f9f6af2e..e9b23850627a 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
@@ -18,9 +18,11 @@ package com.android.systemui.communal
import android.provider.Settings
import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.TransitionKey
import com.android.systemui.CoreStartable
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.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalTransitionKeys
import com.android.systemui.dagger.SysUISingleton
@@ -28,6 +30,7 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dock.DockManager
+import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -68,12 +71,14 @@ class CommunalSceneStartable
constructor(
private val dockManager: DockManager,
private val communalInteractor: CommunalInteractor,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
private val communalSceneInteractor: CommunalSceneInteractor,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val keyguardInteractor: KeyguardInteractor,
private val systemSettings: SystemSettings,
centralSurfacesOpt: Optional<CentralSurfaces>,
private val notificationShadeWindowController: NotificationShadeWindowController,
+ private val featureFlagsClassic: FeatureFlagsClassic,
@Application private val applicationScope: CoroutineScope,
@Background private val bgScope: CoroutineScope,
@Main private val mainDispatcher: CoroutineDispatcher,
@@ -87,12 +92,22 @@ constructor(
private val centralSurfaces: CentralSurfaces? by centralSurfacesOpt
override fun start() {
+ if (!communalSettingsInteractor.isCommunalFlagEnabled()) {
+ return
+ }
+
// Handle automatically switching based on keyguard state.
keyguardTransitionInteractor.startedKeyguardTransitionStep
.mapLatest(::determineSceneAfterTransition)
.filterNotNull()
- .onEach { nextScene ->
- communalSceneInteractor.changeScene(nextScene, CommunalTransitionKeys.SimpleFade)
+ .onEach { (nextScene, nextTransition) ->
+ if (!communalSceneInteractor.isLaunchingWidget.value) {
+ // When launching a widget, we don't want to animate the scene change or the
+ // Communal Hub will reveal the wallpaper even though it shouldn't. Instead we
+ // snap to the new scene as part of the launch animation, once the activity
+ // launch is done, so we don't change scene here.
+ communalSceneInteractor.changeScene(nextScene, nextTransition)
+ }
}
.launchIn(applicationScope)
@@ -188,7 +203,7 @@ constructor(
private suspend fun determineSceneAfterTransition(
lastStartedTransition: TransitionStep,
- ): SceneKey? {
+ ): Pair<SceneKey, TransitionKey>? {
val to = lastStartedTransition.to
val from = lastStartedTransition.from
val docked = dockManager.isDocked
@@ -201,22 +216,27 @@ constructor(
// underneath the hub is shown. When launching activities over lockscreen, we only
// change scenes once the activity launch animation is finished, so avoid
// changing the scene here.
- CommunalScenes.Blank
+ Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
}
to == KeyguardState.GLANCEABLE_HUB && from == KeyguardState.OCCLUDED -> {
// When transitioning to the hub from an occluded state, fade out the hub without
// doing any translation.
- CommunalScenes.Communal
+ Pair(CommunalScenes.Communal, CommunalTransitionKeys.SimpleFade)
}
// Transitioning to Blank scene when entering the edit mode will be handled separately
// with custom animations.
to == KeyguardState.GONE && !communalInteractor.editModeOpen.value ->
- CommunalScenes.Blank
+ Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
!docked && !KeyguardState.deviceIsAwakeInState(to) -> {
// If the user taps the screen and wakes the device within this timeout, we don't
// want to dismiss the hub
delay(AWAKE_DEBOUNCE_DELAY)
- CommunalScenes.Blank
+ Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
+ }
+ from == KeyguardState.DOZING && to == KeyguardState.GLANCEABLE_HUB -> {
+ // Make sure the communal hub is showing (immediately, not fading in) when
+ // transitioning from dozing to hub.
+ Pair(CommunalScenes.Communal, CommunalTransitionKeys.Immediately)
}
else -> null
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
index 2406cc6bcea2..3d201a36417b 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
@@ -23,6 +23,7 @@ import com.android.systemui.communal.data.repository.CommunalMediaRepositoryModu
import com.android.systemui.communal.data.repository.CommunalPrefsRepositoryModule
import com.android.systemui.communal.data.repository.CommunalRepositoryModule
import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryModule
+import com.android.systemui.communal.data.repository.CommunalSmartspaceRepositoryModule
import com.android.systemui.communal.data.repository.CommunalTutorialRepositoryModule
import com.android.systemui.communal.data.repository.CommunalWidgetRepositoryModule
import com.android.systemui.communal.shared.model.CommunalScenes
@@ -52,6 +53,8 @@ import kotlinx.coroutines.CoroutineScope
CommunalWidgetModule::class,
CommunalPrefsRepositoryModule::class,
CommunalSettingsRepositoryModule::class,
+ CommunalSmartspaceRepositoryModule::class,
+ CommunalStartableModule::class,
]
)
interface CommunalModule {
diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalStartableModule.kt b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalStartableModule.kt
new file mode 100644
index 000000000000..74a2cd3f22c4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalStartableModule.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.communal.dagger
+
+import com.android.systemui.CoreStartable
+import com.android.systemui.communal.CommunalBackupRestoreStartable
+import com.android.systemui.communal.CommunalDreamStartable
+import com.android.systemui.communal.CommunalOngoingContentStartable
+import com.android.systemui.communal.CommunalSceneStartable
+import com.android.systemui.communal.log.CommunalLoggerStartable
+import com.android.systemui.communal.widgets.CommunalAppWidgetHostStartable
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+
+@Module
+interface CommunalStartableModule {
+ @Binds
+ @IntoMap
+ @ClassKey(CommunalLoggerStartable::class)
+ fun bindCommunalLoggerStartable(impl: CommunalLoggerStartable): CoreStartable
+
+ @Binds
+ @IntoMap
+ @ClassKey(CommunalSceneStartable::class)
+ fun bindCommunalSceneStartable(impl: CommunalSceneStartable): CoreStartable
+
+ @Binds
+ @IntoMap
+ @ClassKey(CommunalDreamStartable::class)
+ fun bindCommunalDreamStartable(impl: CommunalDreamStartable): CoreStartable
+
+ @Binds
+ @IntoMap
+ @ClassKey(CommunalAppWidgetHostStartable::class)
+ fun bindCommunalAppWidgetHostStartable(impl: CommunalAppWidgetHostStartable): CoreStartable
+
+ @Binds
+ @IntoMap
+ @ClassKey(CommunalBackupRestoreStartable::class)
+ fun bindCommunalBackupRestoreStartable(impl: CommunalBackupRestoreStartable): CoreStartable
+
+ @Binds
+ @IntoMap
+ @ClassKey(CommunalOngoingContentStartable::class)
+ fun bindCommunalOngoingContentStartable(impl: CommunalOngoingContentStartable): CoreStartable
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/backup/CommunalBackupUtils.kt b/packages/SystemUI/src/com/android/systemui/communal/data/backup/CommunalBackupUtils.kt
index a8e5174494a1..c3d2683ce953 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/backup/CommunalBackupUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/backup/CommunalBackupUtils.kt
@@ -43,11 +43,13 @@ class CommunalBackupUtils(
val widgetsFromDb = runBlocking { database.communalWidgetDao().getWidgets().first() }
val widgetsState = mutableListOf<CommunalHubState.CommunalWidgetItem>()
widgetsFromDb.keys.forEach { rankItem ->
+ val widget = widgetsFromDb[rankItem]!!
widgetsState.add(
CommunalHubState.CommunalWidgetItem().apply {
rank = rankItem.rank
- widgetId = widgetsFromDb[rankItem]!!.widgetId
- componentName = widgetsFromDb[rankItem]?.componentName
+ widgetId = widget.widgetId
+ componentName = widget.componentName
+ userSerialNumber = widget.userSerialNumber
}
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalDatabase.kt b/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalDatabase.kt
index 3ce81094b696..dff63527ba05 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalDatabase.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalDatabase.kt
@@ -17,17 +17,21 @@
package com.android.systemui.communal.data.db
import android.content.Context
+import android.util.Log
import androidx.annotation.VisibleForTesting
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
import com.android.systemui.res.R
-@Database(entities = [CommunalWidgetItem::class, CommunalItemRank::class], version = 1)
+@Database(entities = [CommunalWidgetItem::class, CommunalItemRank::class], version = 2)
abstract class CommunalDatabase : RoomDatabase() {
abstract fun communalWidgetDao(): CommunalWidgetDao
companion object {
+ private const val TAG = "CommunalDatabase"
private var instance: CommunalDatabase? = null
/**
@@ -51,7 +55,8 @@ abstract class CommunalDatabase : RoomDatabase() {
context.resources.getString(R.string.config_communalDatabase)
)
.also { builder ->
- builder.fallbackToDestructiveMigration(dropAllTables = false)
+ builder.addMigrations(MIGRATION_1_2)
+ builder.fallbackToDestructiveMigration(dropAllTables = true)
callback?.let { callback -> builder.addCallback(callback) }
}
.build()
@@ -64,5 +69,23 @@ abstract class CommunalDatabase : RoomDatabase() {
fun setInstance(database: CommunalDatabase) {
instance = database
}
+
+ /**
+ * This migration adds a user_serial_number column and sets its default value as
+ * [CommunalWidgetItem.USER_SERIAL_NUMBER_UNDEFINED]. Work profile widgets added before the
+ * migration still work as expected, but they would be backed up as personal.
+ */
+ @VisibleForTesting
+ val MIGRATION_1_2 =
+ object : Migration(1, 2) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+ Log.i(TAG, "Migrating from version 1 to 2")
+ db.execSQL(
+ "ALTER TABLE communal_widget_table " +
+ "ADD COLUMN user_serial_number INTEGER NOT NULL DEFAULT " +
+ "${CommunalWidgetItem.USER_SERIAL_NUMBER_UNDEFINED}"
+ )
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalEntities.kt b/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalEntities.kt
index 0d5336ab8540..e33aead11842 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalEntities.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalEntities.kt
@@ -29,7 +29,28 @@ data class CommunalWidgetItem(
@ColumnInfo(name = "component_name") val componentName: String,
/** Reference the id of an item persisted in the glanceable hub */
@ColumnInfo(name = "item_id") val itemId: Long,
-)
+ /**
+ * A serial number of the user that the widget provider is associated with. For example, a work
+ * profile widget.
+ *
+ * A serial number may be different from its user id in that user ids may be recycled but serial
+ * numbers are unique until the device is wiped.
+ *
+ * Most commonly, this value would be 0 for the primary user, and 10 for the work profile.
+ */
+ @ColumnInfo(name = "user_serial_number", defaultValue = "$USER_SERIAL_NUMBER_UNDEFINED")
+ val userSerialNumber: Int,
+) {
+ companion object {
+ /**
+ * The user serial number associated with the widget is undefined.
+ *
+ * This should only happen for widgets migrated from V1 before user serial number was
+ * included in the schema.
+ */
+ const val USER_SERIAL_NUMBER_UNDEFINED = -1
+ }
+}
@Entity(tableName = "communal_item_rank_table")
data class CommunalItemRank(
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt b/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt
index d174fd1c97ea..933a25a21578 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt
@@ -17,6 +17,7 @@
package com.android.systemui.communal.data.db
import android.content.ComponentName
+import android.os.UserManager
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Query
@@ -26,7 +27,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase
import com.android.systemui.communal.nano.CommunalHubState
import com.android.systemui.communal.widgets.CommunalWidgetHost
import com.android.systemui.communal.widgets.CommunalWidgetModule.Companion.DEFAULT_WIDGETS
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.Logger
@@ -34,58 +35,96 @@ import com.android.systemui.log.dagger.CommunalLog
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Provider
-import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
/**
* Callback that will be invoked when the Room database is created. Then the database will be
* populated with pre-configured default widgets to be rendered in the glanceable hub.
*/
+@SysUISingleton
class DefaultWidgetPopulation
@Inject
constructor(
- @Application private val applicationScope: CoroutineScope,
- @Background private val bgDispatcher: CoroutineDispatcher,
+ @Background private val bgScope: CoroutineScope,
private val communalWidgetHost: CommunalWidgetHost,
private val communalWidgetDaoProvider: Provider<CommunalWidgetDao>,
@Named(DEFAULT_WIDGETS) private val defaultWidgets: Array<String>,
@CommunalLog logBuffer: LogBuffer,
+ private val userManager: UserManager,
) : RoomDatabase.Callback() {
companion object {
private const val TAG = "DefaultWidgetPopulation"
}
+
private val logger = Logger(logBuffer, TAG)
+ /**
+ * Reason for skipping default widgets population. Do not skip if this value is
+ * [SkipReason.NONE].
+ */
+ private var skipReason = SkipReason.NONE
+
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
- applicationScope.launch {
- addDefaultWidgets()
- logger.i("Default widgets were populated in the database.")
+
+ if (skipReason != SkipReason.NONE) {
+ logger.i("Skipped populating default widgets. Reason: $skipReason")
+ return
}
- }
- // Read default widgets from config.xml and populate the database.
- private suspend fun addDefaultWidgets() =
- withContext(bgDispatcher) {
+ bgScope.launch {
+ // Default widgets should be associated with the main user.
+ val user = userManager.mainUser
+
+ if (user == null) {
+ logger.w(
+ "Skipped populating default widgets. Reason: device does not have a main user"
+ )
+ return@launch
+ }
+
+ val userSerialNumber = userManager.getUserSerialNumber(user.identifier)
+
defaultWidgets.forEachIndexed { index, name ->
val provider = ComponentName.unflattenFromString(name)
provider?.let {
- val id = communalWidgetHost.allocateIdAndBindWidget(provider)
+ val id = communalWidgetHost.allocateIdAndBindWidget(provider, user)
id?.let {
communalWidgetDaoProvider
.get()
.addWidget(
widgetId = id,
- provider = provider,
- priority = defaultWidgets.size - index
+ componentName = name,
+ priority = defaultWidgets.size - index,
+ userSerialNumber = userSerialNumber,
)
}
}
}
+
+ logger.i("Populated default widgets in the database.")
}
+ }
+
+ /**
+ * Skip populating default widgets in the Glanceable Hub when the database is created. This has
+ * no effect if default widgets have been populated already.
+ *
+ * @param skipReason Reason for skipping the default widgets population.
+ */
+ fun skipDefaultWidgetsPopulation(skipReason: SkipReason) {
+ this.skipReason = skipReason
+ }
+
+ /** Reason for skipping default widgets population. */
+ enum class SkipReason {
+ /** Do not skip. */
+ NONE,
+ /** Widgets are restored from a backup. */
+ RESTORED_FROM_BACKUP,
+ }
}
@Dao
@@ -106,10 +145,16 @@ interface CommunalWidgetDao {
fun deleteItemRankById(itemId: Long)
@Query(
- "INSERT INTO communal_widget_table(widget_id, component_name, item_id) " +
- "VALUES(:widgetId, :componentName, :itemId)"
+ "INSERT INTO communal_widget_table" +
+ "(widget_id, component_name, item_id, user_serial_number) " +
+ "VALUES(:widgetId, :componentName, :itemId, :userSerialNumber)"
)
- fun insertWidget(widgetId: Int, componentName: String, itemId: Long): Long
+ fun insertWidget(
+ widgetId: Int,
+ componentName: String,
+ itemId: Long,
+ userSerialNumber: Int,
+ ): Long
@Query("INSERT INTO communal_item_rank_table(rank) VALUES(:rank)")
fun insertItemRank(rank: Int): Long
@@ -132,28 +177,41 @@ interface CommunalWidgetDao {
}
@Transaction
- fun addWidget(widgetId: Int, provider: ComponentName, priority: Int): Long {
+ fun addWidget(
+ widgetId: Int,
+ provider: ComponentName,
+ priority: Int,
+ userSerialNumber: Int,
+ ): Long {
return addWidget(
widgetId = widgetId,
componentName = provider.flattenToString(),
priority = priority,
+ userSerialNumber = userSerialNumber,
)
}
@Transaction
- fun addWidget(widgetId: Int, componentName: String, priority: Int): Long {
+ fun addWidget(
+ widgetId: Int,
+ componentName: String,
+ priority: Int,
+ userSerialNumber: Int,
+ ): Long {
return insertWidget(
widgetId = widgetId,
componentName = componentName,
itemId = insertItemRank(priority),
+ userSerialNumber = userSerialNumber,
)
}
@Transaction
fun deleteWidgetById(widgetId: Int): Boolean {
val widget =
- getWidgetByIdNow(widgetId) ?: // no entry to delete from db
- return false
+ getWidgetByIdNow(widgetId)
+ ?: // no entry to delete from db
+ return false
deleteItemRankById(widget.itemId)
deleteWidgets(widget)
@@ -166,6 +224,8 @@ interface CommunalWidgetDao {
clearCommunalWidgetsTable()
clearCommunalItemRankTable()
- state.widgets.forEach { addWidget(it.widgetId, it.componentName, it.rank) }
+ state.widgets.forEach {
+ addWidget(it.widgetId, it.componentName, it.rank, it.userSerialNumber)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalSmartspaceTimer.kt b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalSmartspaceTimer.kt
new file mode 100644
index 000000000000..ff9dddd7c516
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalSmartspaceTimer.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.communal.data.model
+
+import android.widget.RemoteViews
+
+/** Data model of a smartspace timer in the Glanceable Hub. */
+data class CommunalSmartspaceTimer(
+ /** Unique id that identifies the timer. */
+ val smartspaceTargetId: String,
+ /** Timestamp in milliseconds of when the timer was created. */
+ val createdTimestampMillis: Long,
+ /** Remote views for the timer that is rendered in Glanceable Hub. */
+ val remoteViews: RemoteViews,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalMediaRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalMediaRepository.kt
index e5a0e5070b94..fe9154c192c5 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalMediaRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalMediaRepository.kt
@@ -30,6 +30,12 @@ import kotlinx.coroutines.flow.MutableStateFlow
/** Encapsulates the state of smartspace in communal. */
interface CommunalMediaRepository {
val mediaModel: Flow<CommunalMediaModel>
+
+ /** Start listening for media updates. */
+ fun startListening()
+
+ /** Stop listening for media updates. */
+ fun stopListening()
}
@SysUISingleton
@@ -38,29 +44,7 @@ class CommunalMediaRepositoryImpl
constructor(
private val mediaDataManager: MediaDataManager,
@CommunalTableLog tableLogBuffer: TableLogBuffer,
-) : CommunalMediaRepository {
-
- private val mediaDataListener =
- object : MediaDataManager.Listener {
- override fun onMediaDataLoaded(
- key: String,
- oldKey: String?,
- data: MediaData,
- immediately: Boolean,
- receivedSmartspaceCardLatency: Int,
- isSsReactivated: Boolean
- ) {
- updateMediaModel(data)
- }
-
- override fun onMediaDataRemoved(key: String, userInitiated: Boolean) {
- updateMediaModel()
- }
- }
-
- init {
- mediaDataManager.addListener(mediaDataListener)
- }
+) : CommunalMediaRepository, MediaDataManager.Listener {
private val _mediaModel: MutableStateFlow<CommunalMediaModel> =
MutableStateFlow(CommunalMediaModel.INACTIVE)
@@ -72,6 +56,29 @@ constructor(
initialValue = CommunalMediaModel.INACTIVE,
)
+ override fun startListening() {
+ mediaDataManager.addListener(this)
+ }
+
+ override fun stopListening() {
+ mediaDataManager.removeListener(this)
+ }
+
+ override fun onMediaDataLoaded(
+ key: String,
+ oldKey: String?,
+ data: MediaData,
+ immediately: Boolean,
+ receivedSmartspaceCardLatency: Int,
+ isSsReactivated: Boolean
+ ) {
+ updateMediaModel(data)
+ }
+
+ override fun onMediaDataRemoved(key: String, userInitiated: Boolean) {
+ updateMediaModel()
+ }
+
private fun updateMediaModel(data: MediaData? = null) {
if (mediaDataManager.hasActiveMediaOrRecommendation()) {
_mediaModel.value =
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
index 2940a95fdc33..7b54815ab344 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
@@ -20,6 +20,7 @@ import android.app.admin.DevicePolicyManager
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL
import android.content.IntentFilter
import android.content.pm.UserInfo
+import android.os.UserHandle
import android.provider.Settings
import com.android.systemui.Flags.communalHub
import com.android.systemui.broadcast.BroadcastDispatcher
@@ -51,6 +52,14 @@ interface CommunalSettingsRepository {
/** A [CommunalEnabledState] for the specified user. */
fun getEnabledState(user: UserInfo): Flow<CommunalEnabledState>
+ /**
+ * Returns true if both the communal trunk-stable flag and resource flag are enabled.
+ *
+ * The trunk-stable flag is controlled by server rollout and is on all devices. The resource
+ * flag is enabled via resource overlay only on products we want the hub to be present on.
+ */
+ fun getFlagEnabled(): Boolean
+
/** Keyguard widgets enabled state by Device Policy Manager for the specified user. */
fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean>
@@ -69,15 +78,15 @@ constructor(
private val devicePolicyManager: DevicePolicyManager,
) : CommunalSettingsRepository {
- private val flagEnabled: Boolean by lazy {
- featureFlagsClassic.isEnabled(Flags.COMMUNAL_SERVICE_ENABLED) && communalHub()
+ override fun getFlagEnabled(): Boolean {
+ return featureFlagsClassic.isEnabled(Flags.COMMUNAL_SERVICE_ENABLED) && communalHub()
}
override fun getEnabledState(user: UserInfo): Flow<CommunalEnabledState> {
if (!user.isMain) {
return flowOf(CommunalEnabledState(DISABLED_REASON_INVALID_USER))
}
- if (!flagEnabled) {
+ if (!getFlagEnabled()) {
return flowOf(CommunalEnabledState(DISABLED_REASON_FLAG))
}
return combine(
@@ -102,7 +111,10 @@ constructor(
.broadcastFlow(
filter =
IntentFilter(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
- user = user.userHandle
+ // In COPE management mode, the restriction from the managed profile may
+ // propagate to the main profile. Therefore listen to this broadcast across
+ // all users and update the state each time it changes.
+ user = UserHandle.ALL,
)
.emitOnStart()
.map { devicePolicyManager.areKeyguardWidgetsAllowed(user.id) }
@@ -115,11 +127,11 @@ constructor(
val intType =
secureSettings.getIntForUser(
GLANCEABLE_HUB_BACKGROUND_SETTING,
- CommunalBackgroundType.DEFAULT.value,
+ CommunalBackgroundType.ANIMATED.value,
user.id
)
CommunalBackgroundType.entries.find { type -> type.value == intType }
- ?: CommunalBackgroundType.DEFAULT
+ ?: CommunalBackgroundType.ANIMATED
}
private fun getEnabledByUser(user: UserInfo): Flow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepository.kt
new file mode 100644
index 000000000000..e1d9bef67490
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepository.kt
@@ -0,0 +1,123 @@
+/*
+ * 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.communal.data.repository
+
+import android.app.smartspace.SmartspaceTarget
+import android.os.Parcelable
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.communal.data.model.CommunalSmartspaceTimer
+import com.android.systemui.communal.smartspace.CommunalSmartspaceController
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.util.time.SystemClock
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+
+interface CommunalSmartspaceRepository {
+ /** Smartspace timer targets for the communal surface. */
+ val timers: Flow<List<CommunalSmartspaceTimer>>
+
+ /** Start listening for smartspace updates. */
+ fun startListening()
+
+ /** Stop listening for smartspace updates. */
+ fun stopListening()
+}
+
+@SysUISingleton
+class CommunalSmartspaceRepositoryImpl
+@Inject
+constructor(
+ private val communalSmartspaceController: CommunalSmartspaceController,
+ @Main private val uiExecutor: Executor,
+ private val systemClock: SystemClock,
+) : CommunalSmartspaceRepository, BcSmartspaceDataPlugin.SmartspaceTargetListener {
+
+ private val _timers: MutableStateFlow<List<CommunalSmartspaceTimer>> =
+ MutableStateFlow(emptyList())
+ override val timers: Flow<List<CommunalSmartspaceTimer>> = _timers
+
+ private var targetCreationTimes = emptyMap<String, Long>()
+
+ override fun onSmartspaceTargetsUpdated(targetsNullable: MutableList<out Parcelable>?) {
+ val targets = targetsNullable?.filterIsInstance<SmartspaceTarget>() ?: emptyList()
+ val timerTargets =
+ targets
+ .filter { target ->
+ target.featureType == SmartspaceTarget.FEATURE_TIMER &&
+ target.remoteViews != null
+ }
+ .associateBy { stableId(it.smartspaceTargetId) }
+
+ // The creation times from smartspace targets are unreliable (b/318535930). Therefore,
+ // SystemUI uses the timestamp of which a timer first appears, and caches these values to
+ // prevent timers from swapping positions in the hub.
+ targetCreationTimes =
+ timerTargets.mapValues { (stableId, _) ->
+ targetCreationTimes[stableId] ?: systemClock.currentTimeMillis()
+ }
+
+ _timers.value =
+ timerTargets.map { (stableId, target) ->
+ CommunalSmartspaceTimer(
+ // The view layer should have the instance based smartspaceTargetId instead of
+ // stable id, so that when a new instance of the timer is created, for example,
+ // when it is paused, the view should re-render its remote views.
+ smartspaceTargetId = target.smartspaceTargetId,
+ createdTimestampMillis = targetCreationTimes[stableId]!!,
+ remoteViews = target.remoteViews!!,
+ )
+ }
+ }
+
+ override fun startListening() {
+ if (android.app.smartspace.flags.Flags.remoteViews()) {
+ uiExecutor.execute {
+ communalSmartspaceController.addListener(
+ listener = this@CommunalSmartspaceRepositoryImpl
+ )
+ }
+ }
+ }
+
+ override fun stopListening() {
+ uiExecutor.execute {
+ communalSmartspaceController.removeListener(
+ listener = this@CommunalSmartspaceRepositoryImpl
+ )
+ }
+ }
+
+ companion object {
+ /**
+ * The smartspace target id is instance-based, meaning a single timer (from the user's
+ * perspective) can have multiple instances. For example, when a timer is paused, a new
+ * instance is created. To address this, SystemUI manually removes the instance id to
+ * maintain a consistent id across sessions.
+ *
+ * It is assumed that timer target ids follow this format: timer-${stableId}-${instanceId}.
+ * This function returns timer-${stableId}, stripping out the instance id.
+ */
+ @VisibleForTesting
+ fun stableId(targetId: String): String {
+ return targetId.split("-").take(2).joinToString("-")
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/data/repository/SmartspaceRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryModule.kt
index c77bcc50b69a..b11c6d6d5d55 100644
--- a/packages/SystemUI/src/com/android/systemui/smartspace/data/repository/SmartspaceRepositoryModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryModule.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,12 +14,15 @@
* limitations under the License.
*/
-package com.android.systemui.smartspace.data.repository
+package com.android.systemui.communal.data.repository
import dagger.Binds
import dagger.Module
@Module
-interface SmartspaceRepositoryModule {
- @Binds fun smartspaceRepository(impl: SmartspaceRepositoryImpl): SmartspaceRepository
+interface CommunalSmartspaceRepositoryModule {
+ @Binds
+ fun communalSmartspaceRepository(
+ impl: CommunalSmartspaceRepositoryImpl
+ ): CommunalSmartspaceRepository
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt
index fdb797d5ba06..e65e5e5688f5 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt
@@ -20,10 +20,14 @@ import android.app.backup.BackupManager
import android.appwidget.AppWidgetProviderInfo
import android.content.ComponentName
import android.os.UserHandle
+import android.os.UserManager
import com.android.systemui.common.data.repository.PackageChangeRepository
import com.android.systemui.common.shared.model.PackageInstallSession
import com.android.systemui.communal.data.backup.CommunalBackupUtils
import com.android.systemui.communal.data.db.CommunalWidgetDao
+import com.android.systemui.communal.data.db.CommunalWidgetItem
+import com.android.systemui.communal.data.db.DefaultWidgetPopulation
+import com.android.systemui.communal.data.db.DefaultWidgetPopulation.SkipReason.RESTORED_FROM_BACKUP
import com.android.systemui.communal.nano.CommunalHubState
import com.android.systemui.communal.proto.toCommunalHubState
import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
@@ -98,6 +102,8 @@ constructor(
private val backupManager: BackupManager,
private val backupUtils: CommunalBackupUtils,
packageChangeRepository: PackageChangeRepository,
+ private val userManager: UserManager,
+ private val defaultWidgetPopulation: DefaultWidgetPopulation,
) : CommunalWidgetRepository {
companion object {
const val TAG = "CommunalWidgetRepository"
@@ -185,6 +191,7 @@ constructor(
widgetId = id,
provider = provider,
priority = priority,
+ userSerialNumber = userManager.getUserSerialNumber(user.identifier),
)
backupManager.dataChanged()
} else {
@@ -228,9 +235,38 @@ constructor(
return@launch
}
+ // Abort restoring widgets if this code is somehow run on a device that does not have
+ // a main user, e.g. auto.
+ val mainUser = userManager.mainUser
+ if (mainUser == null) {
+ logger.w("Skipped restoring widgets because device does not have a main user")
+ return@launch
+ }
+
val widgetsWithHost = appWidgetHost.appWidgetIds.toList()
val widgetsToRemove = widgetsWithHost.toMutableList()
+ val oldUserSerialNumbers = state.widgets.map { it.userSerialNumber }.distinct()
+ val usersMap =
+ oldUserSerialNumbers.associateWith { oldUserSerialNumber ->
+ if (oldUserSerialNumber == CommunalWidgetItem.USER_SERIAL_NUMBER_UNDEFINED) {
+ // If user serial number from the backup is undefined, the widget was added
+ // to the hub before user serial numbers are stored in the database. In this
+ // case, we restore the widget with the main user.
+ mainUser
+ } else {
+ // If the user serial number is defined, look up whether the user is
+ // restored. This API returns a user handle matching its backed up user
+ // serial number, if the user is restored. Otherwise, null is returned.
+ backupManager.getUserForAncestralSerialNumber(oldUserSerialNumber.toLong())
+ ?: null
+ }
+ }
+ logger.d({ "Restored users map: $str1" }) { str1 = usersMap.toString() }
+
+ // A set to hold all widgets that belong to non-main users
+ val secondaryUserWidgets = mutableSetOf<CommunalHubState.CommunalWidgetItem>()
+
// Produce a new state to be restored, skipping invalid widgets
val newWidgets =
state.widgets.mapNotNull { restoredWidget ->
@@ -249,20 +285,67 @@ constructor(
return@mapNotNull null
}
+ // Skip if user / profile is not registered
+ val newUser = usersMap[restoredWidget.userSerialNumber]
+ if (newUser == null) {
+ logger.d({
+ "Skipped restoring widget $int1 because its user $int2 is not " +
+ "registered"
+ }) {
+ int1 = restoredWidget.widgetId
+ int2 = restoredWidget.userSerialNumber
+ }
+ return@mapNotNull null
+ }
+
+ // Place secondary user widgets in a bucket to be manually bound later because
+ // of a platform bug (b/349852237) that backs up work profile widgets as
+ // personal.
+ if (newUser.identifier != mainUser.identifier) {
+ logger.d({
+ "Skipped restoring widget $int1 for now because its new user $int2 " +
+ "is secondary. This widget will be bound later."
+ }) {
+ int1 = restoredWidget.widgetId
+ int2 = newUser.identifier
+ }
+ secondaryUserWidgets.add(restoredWidget)
+ return@mapNotNull null
+ }
+
widgetsToRemove.remove(newWidgetId)
CommunalHubState.CommunalWidgetItem().apply {
widgetId = newWidgetId
componentName = restoredWidget.componentName
rank = restoredWidget.rank
+ userSerialNumber = userManager.getUserSerialNumber(newUser.identifier)
}
}
val newState = CommunalHubState().apply { widgets = newWidgets.toTypedArray() }
+ // Skip default widgets population
+ defaultWidgetPopulation.skipDefaultWidgetsPopulation(RESTORED_FROM_BACKUP)
+
// Restore database
- logger.i("Restoring communal database $newState")
+ logger.i("Restoring communal database:\n$newState")
communalWidgetDao.restoreCommunalHubState(newState)
+ // Manually bind each secondary user widget due to platform bug b/349852237
+ secondaryUserWidgets.forEach { widget ->
+ val newUser = usersMap[widget.userSerialNumber]!!
+ logger.i({ "Binding secondary user ($int1) widget $int2: $str1" }) {
+ int1 = newUser.identifier
+ int2 = widget.widgetId
+ str1 = widget.componentName
+ }
+ addWidget(
+ provider = ComponentName.unflattenFromString(widget.componentName)!!,
+ user = newUser,
+ priority = widget.rank,
+ )
+ }
+
// Delete restored state file from disk
backupUtils.clear()
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index f5255ac4d545..3fffd76ab6a9 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -16,10 +16,10 @@
package com.android.systemui.communal.domain.interactor
-import android.app.smartspace.SmartspaceTarget
import android.content.ComponentName
import android.content.Intent
import android.content.IntentFilter
+import android.content.pm.UserInfo
import android.os.UserHandle
import android.os.UserManager
import android.provider.Settings
@@ -28,6 +28,7 @@ import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.TransitionKey
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.communal.data.repository.CommunalMediaRepository
+import com.android.systemui.communal.data.repository.CommunalSmartspaceRepository
import com.android.systemui.communal.data.repository.CommunalWidgetRepository
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.domain.model.CommunalContentModel.WidgetContent
@@ -59,7 +60,6 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.UserTracker
-import com.android.systemui.smartspace.data.repository.SmartspaceRepository
import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
import com.android.systemui.util.kotlin.BooleanFlowOperators.not
import com.android.systemui.util.kotlin.emitOnStart
@@ -81,7 +81,6 @@ import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
@@ -100,7 +99,7 @@ constructor(
private val widgetRepository: CommunalWidgetRepository,
private val communalPrefsInteractor: CommunalPrefsInteractor,
private val mediaRepository: CommunalMediaRepository,
- smartspaceRepository: SmartspaceRepository,
+ private val smartspaceRepository: CommunalSmartspaceRepository,
keyguardInteractor: KeyguardInteractor,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
communalSettingsInteractor: CommunalSettingsInteractor,
@@ -386,11 +385,11 @@ constructor(
combine(
widgetRepository.communalWidgets
.map { filterWidgetsByExistingUsers(it) }
- .combine(communalSettingsInteractor.allowedByDevicePolicyForWorkProfile) {
+ .combine(communalSettingsInteractor.workProfileUserDisallowedByDevicePolicy) {
// exclude widgets under work profile if not allowed by device policy
widgets,
- allowedForWorkProfile ->
- filterWidgetsAllowedByDevicePolicy(widgets, allowedForWorkProfile)
+ disallowedByPolicyUser ->
+ filterWidgetsAllowedByDevicePolicy(widgets, disallowedByPolicyUser)
},
updateOnWorkProfileBroadcastReceived,
) { widgets, _ ->
@@ -418,13 +417,11 @@ constructor(
/** Filter widgets based on whether their associated profile is allowed by device policy. */
private fun filterWidgetsAllowedByDevicePolicy(
list: List<CommunalWidgetContentModel>,
- allowedByDevicePolicyForWorkProfile: Boolean
+ disallowedByDevicePolicyUser: UserInfo?
): List<CommunalWidgetContentModel> =
- if (allowedByDevicePolicyForWorkProfile) {
+ if (disallowedByDevicePolicyUser == null) {
list
} else {
- // Get associated work profile for the currently selected user.
- val workProfile = userTracker.userProfiles.find { it.isManagedProfile }
list.filter { model ->
val uid =
when (model) {
@@ -432,20 +429,7 @@ constructor(
model.providerInfo.profile.identifier
is CommunalWidgetContentModel.Pending -> model.user.identifier
}
- uid != workProfile?.id
- }
- }
-
- /** A flow of available smartspace targets. Currently only showing timers. */
- private val smartspaceTargets: Flow<List<SmartspaceTarget>> =
- if (!smartspaceRepository.isSmartspaceRemoteViewsEnabled) {
- flowOf(emptyList())
- } else {
- smartspaceRepository.communalSmartspaceTargets.map { targets ->
- targets.filter { target ->
- target.featureType == SmartspaceTarget.FEATURE_TIMER &&
- target.remoteViews != null
- }
+ uid != disallowedByDevicePolicyUser.id
}
}
@@ -473,16 +457,16 @@ constructor(
* sized dynamically.
*/
fun getOngoingContent(mediaHostVisible: Boolean): Flow<List<CommunalContentModel.Ongoing>> =
- combine(smartspaceTargets, mediaRepository.mediaModel) { smartspace, media ->
+ combine(smartspaceRepository.timers, mediaRepository.mediaModel) { timers, media ->
val ongoingContent = mutableListOf<CommunalContentModel.Ongoing>()
- // Add smartspace
+ // Add smartspace timers
ongoingContent.addAll(
- smartspace.map { target ->
+ timers.map { timer ->
CommunalContentModel.Smartspace(
- smartspaceTargetId = target.smartspaceTargetId,
- remoteViews = target.remoteViews!!,
- createdTimestampMillis = target.creationTimeMillis,
+ smartspaceTargetId = timer.smartspaceTargetId,
+ remoteViews = timer.remoteViews,
+ createdTimestampMillis = timer.createdTimestampMillis,
)
}
)
@@ -557,4 +541,29 @@ constructor(
)
}
}
+
+ /**
+ * {@link #setScrollPosition} persists the current communal grid scroll position (to volatile
+ * memory) so that the next presentation of the grid (either as glanceable hub or edit mode) can
+ * restore position.
+ */
+ fun setScrollPosition(firstVisibleItemIndex: Int, firstVisibleItemOffset: Int) {
+ _firstVisibleItemIndex = firstVisibleItemIndex
+ _firstVisibleItemOffset = firstVisibleItemOffset
+ }
+
+ fun resetScrollPosition() {
+ _firstVisibleItemIndex = 0
+ _firstVisibleItemOffset = 0
+ }
+
+ val firstVisibleItemIndex: Int
+ get() = _firstVisibleItemIndex
+
+ private var _firstVisibleItemIndex: Int = 0
+
+ val firstVisibleItemOffset: Int
+ get() = _firstVisibleItemOffset
+
+ private var _firstVisibleItemOffset: Int = 0
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
index fd540c4b6708..122f964713a9 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
@@ -48,6 +48,15 @@ constructor(
@Application private val applicationScope: CoroutineScope,
private val communalSceneRepository: CommunalSceneRepository,
) {
+ val _isLaunchingWidget = MutableStateFlow(false)
+
+ /** Whether a widget launch is currently in progress. */
+ val isLaunchingWidget: StateFlow<Boolean> = _isLaunchingWidget.asStateFlow()
+
+ fun setIsLaunchingWidget(launching: Boolean) {
+ _isLaunchingWidget.value = launching
+ }
+
/**
* Asks for an asynchronous scene witch to [newScene], which will use the corresponding
* installed transition or the one specified by [transitionKey], if provided.
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
index 47b75c458d20..0cdbad40b2d1 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
@@ -69,6 +69,18 @@ constructor(
// Start this eagerly since the value is accessed synchronously in many places.
.stateIn(scope = bgScope, started = SharingStarted.Eagerly, initialValue = false)
+ /**
+ * Returns true if both the communal trunk-stable flag and resource flag are enabled.
+ *
+ * The trunk-stable flag is controlled by server rollout and is on all devices. The resource
+ * flag is enabled via resource overlay only on products we want the hub to be present on.
+ *
+ * If this is false, then the hub is definitely not available on the device. If this is true,
+ * refer to [isCommunalEnabled] which takes into account other factors that can change at
+ * runtime.
+ */
+ fun isCommunalFlagEnabled(): Boolean = repository.getFlagEnabled()
+
/** The type of background to use for the hub. Used to experiment with different backgrounds */
val communalBackground: Flow<CommunalBackgroundType> =
userInteractor.selectedUserInfo
@@ -92,15 +104,22 @@ constructor(
awaitClose { userTracker.removeCallback(callback) }
}
- /** Whether or not keyguard widgets are allowed for work profile by device policy manager. */
- val allowedByDevicePolicyForWorkProfile: StateFlow<Boolean> =
+ /**
+ * A user that device policy says shouldn't allow communal widgets, or null if there are no
+ * restrictions.
+ */
+ val workProfileUserDisallowedByDevicePolicy: StateFlow<UserInfo?> =
workProfileUserInfoCallbackFlow
.flatMapLatest { workProfile ->
- workProfile?.let { repository.getAllowedByDevicePolicy(it) } ?: flowOf(false)
+ workProfile?.let {
+ repository.getAllowedByDevicePolicy(it).map { allowed ->
+ if (!allowed) it else null
+ }
+ } ?: flowOf(null)
}
.stateIn(
scope = bgScope,
started = SharingStarted.WhileSubscribed(),
- initialValue = false
+ initialValue = null
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/proto/communal_hub_state.proto b/packages/SystemUI/src/com/android/systemui/communal/proto/communal_hub_state.proto
index 08162593b4d5..bc14ae1eaff4 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/proto/communal_hub_state.proto
+++ b/packages/SystemUI/src/com/android/systemui/communal/proto/communal_hub_state.proto
@@ -35,5 +35,8 @@ message CommunalHubState {
// Rank or order of the widget in the communal hub.
int32 rank = 3;
+
+ // Serial number of the user associated with the widget.
+ int32 user_serial_number = 4;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
index 4eaba065e078..3b23ba955899 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
@@ -18,7 +18,7 @@ package com.android.systemui.communal.shared.model
/** Models the types of background that can be shown on the hub. */
enum class CommunalBackgroundType(val value: Int) {
- DEFAULT(0),
+ STATIC(0),
STATIC_GRADIENT(1),
ANIMATED(2),
NONE(3),
diff --git a/packages/SystemUI/src/com/android/systemui/communal/smartspace/SmartspaceInteractionHandler.kt b/packages/SystemUI/src/com/android/systemui/communal/smartspace/SmartspaceInteractionHandler.kt
index a88b777be785..4e3d3ff8a265 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/smartspace/SmartspaceInteractionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/smartspace/SmartspaceInteractionHandler.kt
@@ -22,21 +22,25 @@ import android.content.Intent
import android.view.View
import android.widget.RemoteViews
import com.android.systemui.animation.ActivityTransitionAnimator
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.util.InteractionHandlerDelegate
import com.android.systemui.communal.widgets.SmartspaceAppWidgetHostView
import com.android.systemui.plugins.ActivityStarter
import javax.inject.Inject
-/**
- * Handles interactions on smartspace elements on the hub.
- */
-class SmartspaceInteractionHandler @Inject constructor(
+/** Handles interactions on smartspace elements on the hub. */
+class SmartspaceInteractionHandler
+@Inject
+constructor(
private val activityStarter: ActivityStarter,
+ communalSceneInteractor: CommunalSceneInteractor,
) : RemoteViews.InteractionHandler {
- private val delegate = InteractionHandlerDelegate(
- findViewToAnimate = { view -> view is SmartspaceAppWidgetHostView },
- intentStarter = this::startIntent,
- )
+ private val delegate =
+ InteractionHandlerDelegate(
+ communalSceneInteractor,
+ findViewToAnimate = { view -> view is SmartspaceAppWidgetHostView },
+ intentStarter = this::startIntent,
+ )
override fun onInteraction(
view: View,
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
index 6ec6ec1113a0..19d7ceba2310 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
@@ -59,6 +59,18 @@ abstract class BaseCommunalViewModel(
/** Accessibility delegate to be set on CommunalAppWidgetHostView. */
open val widgetAccessibilityDelegate: View.AccessibilityDelegate? = null
+ /**
+ * The up-to-date value of the grid scroll offset. persisted to interactor on
+ * {@link #persistScrollPosition}
+ */
+ private var currentScrollOffset = 0
+
+ /**
+ * The up-to-date value of the grid scroll index. persisted to interactor on
+ * {@link #persistScrollPosition}
+ */
+ private var currentScrollIndex = 0
+
fun signalUserInteraction() {
communalInteractor.signalUserInteraction()
}
@@ -147,6 +159,28 @@ abstract class BaseCommunalViewModel(
/** Called as the user request to show the customize widget button. */
open fun onLongClick() {}
+ /** Called when the grid scroll position has been updated. */
+ open fun onScrollPositionUpdated(firstVisibleItemIndex: Int, firstVisibleItemScroll: Int) {
+ currentScrollIndex = firstVisibleItemIndex
+ currentScrollOffset = firstVisibleItemScroll
+ }
+
+ /** Stores scroll values to interactor. */
+ protected fun persistScrollPosition() {
+ communalInteractor.setScrollPosition(currentScrollIndex, currentScrollOffset)
+ }
+
+ /** Invoked after scroll values are used to initialize grid position. */
+ open fun clearPersistedScrollPosition() {
+ communalInteractor.setScrollPosition(0, 0)
+ }
+
+ val savedFirstScrollIndex: Int
+ get() = communalInteractor.firstVisibleItemIndex
+
+ val savedFirstScrollOffset: Int
+ get() = communalInteractor.firstVisibleItemOffset
+
/** Set the key of the currently selected item */
fun setSelectedKey(key: String?) {
_selectedKey.value = key
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
index fab243575670..7b0aadfdcebd 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
@@ -43,6 +43,7 @@ import com.android.systemui.log.dagger.CommunalLog
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.dagger.MediaModule
import com.android.systemui.res.R
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
import com.android.systemui.util.kotlin.BooleanFlowOperators.not
import javax.inject.Inject
@@ -93,7 +94,10 @@ constructor(
*/
val canShowEditMode =
allOf(
- keyguardTransitionInteractor.isFinishedInState(KeyguardState.GONE),
+ keyguardTransitionInteractor.isFinishedIn(
+ scene = Scenes.Gone,
+ stateWithoutSceneContainer = KeyguardState.GONE
+ ),
communalInteractor.editModeOpen
)
.filter { it }
@@ -186,7 +190,16 @@ constructor(
AppWidgetManager.EXTRA_CATEGORY_FILTER,
CommunalWidgetCategories.defaultCategories
)
+
+ communalSettingsInteractor.workProfileUserDisallowedByDevicePolicy.value?.let {
+ putExtra(EXTRA_USER_ID_FILTER, arrayListOf(it.id))
+ }
putExtra(EXTRA_UI_SURFACE_KEY, EXTRA_UI_SURFACE_VALUE)
+ putExtra(EXTRA_PICKER_TITLE, resources.getString(R.string.communal_widget_picker_title))
+ putExtra(
+ EXTRA_PICKER_DESCRIPTION,
+ resources.getString(R.string.communal_widget_picker_description)
+ )
putParcelableArrayListExtra(EXTRA_ADDED_APP_WIDGETS_KEY, excludeList)
}
}
@@ -207,6 +220,9 @@ constructor(
/** Called when exiting the edit mode, before transitioning back to the communal scene. */
fun cleanupEditModeState() {
communalSceneInteractor.setEditModeState(null)
+
+ // Set the scroll position of the glanceable hub to match where we are now.
+ persistScrollPosition()
}
companion object {
@@ -214,8 +230,11 @@ constructor(
private const val EXTRA_DESIRED_WIDGET_WIDTH = "desired_widget_width"
private const val EXTRA_DESIRED_WIDGET_HEIGHT = "desired_widget_height"
+ private const val EXTRA_PICKER_TITLE = "picker_title"
+ private const val EXTRA_PICKER_DESCRIPTION = "picker_description"
private const val EXTRA_UI_SURFACE_KEY = "ui_surface"
private const val EXTRA_UI_SURFACE_VALUE = "widgets_hub"
+ private const val EXTRA_USER_ID_FILTER = "filtered_user_ids"
const val EXTRA_ADDED_APP_WIDGETS_KEY = "added_app_widgets"
}
}
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 0466bbc748d9..1e087f789faa 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
@@ -17,6 +17,7 @@
package com.android.systemui.communal.ui.viewmodel
import android.content.res.Resources
+import android.os.Bundle
import android.view.View
import android.view.accessibility.AccessibilityNodeInfo
import com.android.systemui.communal.domain.interactor.CommunalInteractor
@@ -40,6 +41,7 @@ import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.media.dagger.MediaModule
import com.android.systemui.res.R
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.KeyguardIndicationController
import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
@@ -144,7 +146,10 @@ constructor(
*/
override val isCommunalContentFlowFrozen: Flow<Boolean> =
allOf(
- keyguardTransitionInteractor.isFinishedInState(KeyguardState.GLANCEABLE_HUB),
+ keyguardTransitionInteractor.isFinishedIn(
+ scene = Scenes.Communal,
+ stateWithoutSceneContainer = KeyguardState.GLANCEABLE_HUB
+ ),
keyguardInteractor.isKeyguardOccluded,
not(keyguardInteractor.isAbleToDream)
)
@@ -177,7 +182,10 @@ constructor(
// opened.
override val isFocusable: Flow<Boolean> =
combine(
- keyguardTransitionInteractor.isFinishedInState(KeyguardState.GLANCEABLE_HUB),
+ keyguardTransitionInteractor.isFinishedIn(
+ scene = Scenes.Communal,
+ stateWithoutSceneContainer = KeyguardState.GLANCEABLE_HUB
+ ),
communalInteractor.isIdleOnCommunal,
shadeInteractor.isAnyFullyExpanded,
) { transitionedToGlanceableHub, isIdleOnCommunal, isAnyFullyExpanded ->
@@ -202,6 +210,20 @@ constructor(
)
)
}
+
+ override fun performAccessibilityAction(
+ host: View,
+ action: Int,
+ args: Bundle?
+ ): Boolean {
+ when (action) {
+ AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK.id -> {
+ onOpenWidgetEditor()
+ return true
+ }
+ }
+ return super.performAccessibilityAction(host, action, args)
+ }
}
private val _isEnableWidgetDialogShowing: MutableStateFlow<Boolean> = MutableStateFlow(false)
@@ -226,7 +248,10 @@ constructor(
override fun onOpenWidgetEditor(
shouldOpenWidgetPickerOnStart: Boolean,
- ) = communalInteractor.showWidgetEditor(selectedKey.value, shouldOpenWidgetPickerOnStart)
+ ) {
+ persistScrollPosition()
+ communalInteractor.showWidgetEditor(selectedKey.value, shouldOpenWidgetPickerOnStart)
+ }
override fun onDismissCtaTile() {
scope.launch {
@@ -315,14 +340,6 @@ constructor(
not(shadeInteractor.isAnyFullyExpanded)
.stateIn(bgScope, SharingStarted.Eagerly, initialValue = false)
- // TODO(b/339667383): remove this temporary swipe gesture handle
- /**
- * The dream overlay has its own gesture handle as the SysUI window is not visible above the
- * dream. This flow will be false when dreaming so that we don't show a duplicate handle when
- * opening the hub over the dream.
- */
- val showGestureIndicator: Flow<Boolean> = not(keyguardInteractor.isDreaming)
-
/** The type of background to use for the hub. */
val communalBackground: Flow<CommunalBackgroundType> =
communalSettingsInteractor.communalBackground
diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt b/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
index 1e04fe7b6eb0..421774462974 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
@@ -56,7 +56,7 @@ constructor(
Color.valueOf(
Utils.getColorAttrDefaultColor(
context,
- com.android.internal.R.attr.materialColorOutlineVariant
+ com.android.internal.R.attr.materialColorPrimary
)
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/InteractionHandlerDelegate.kt b/packages/SystemUI/src/com/android/systemui/communal/util/InteractionHandlerDelegate.kt
index 40b182dba817..51a5fcd6b873 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/util/InteractionHandlerDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/util/InteractionHandlerDelegate.kt
@@ -24,17 +24,17 @@ import android.widget.RemoteViews
import androidx.core.util.component1
import androidx.core.util.component2
import com.android.systemui.animation.ActivityTransitionAnimator
-
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
+import com.android.systemui.communal.widgets.CommunalTransitionAnimatorController
/** A delegate that can be used to launch activities from [RemoteViews] */
class InteractionHandlerDelegate(
+ private val communalSceneInteractor: CommunalSceneInteractor,
private val findViewToAnimate: (View) -> Boolean,
private val intentStarter: IntentStarter,
) : RemoteViews.InteractionHandler {
- /**
- * Responsible for starting the pending intent for launching activities.
- */
+ /** Responsible for starting the pending intent for launching activities. */
fun interface IntentStarter {
fun startPendingIntent(
intent: PendingIntent,
@@ -57,7 +57,10 @@ class InteractionHandlerDelegate(
// activities.
val hostView = getNearestParent(view)
val animationController =
- hostView?.let(ActivityTransitionAnimator.Controller::fromView)
+ hostView?.let(ActivityTransitionAnimator.Controller::fromView)?.let {
+ communalSceneInteractor.setIsLaunchingWidget(true)
+ CommunalTransitionAnimatorController(it, communalSceneInteractor)
+ }
val (fillInIntent, activityOptions) = launchOptions
intentStarter.startPendingIntent(
pendingIntent,
@@ -66,7 +69,6 @@ class InteractionHandlerDelegate(
animationController
)
}
-
else -> RemoteViews.startPendingIntent(view, pendingIntent, launchOptions)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalTransitionAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalTransitionAnimatorController.kt
new file mode 100644
index 000000000000..4efaf878f33f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalTransitionAnimatorController.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.communal.widgets
+
+import com.android.systemui.animation.ActivityTransitionAnimator
+import com.android.systemui.animation.DelegateTransitionAnimatorController
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
+import com.android.systemui.communal.shared.model.CommunalScenes
+
+/**
+ * An [ActivityTransitionAnimator.Controller] that takes care of updating the state of the Communal
+ * Hub at the right time.
+ */
+class CommunalTransitionAnimatorController(
+ delegate: ActivityTransitionAnimator.Controller,
+ private val communalSceneInteractor: CommunalSceneInteractor,
+) : DelegateTransitionAnimatorController(delegate) {
+ override fun onIntentStarted(willAnimate: Boolean) {
+ if (!willAnimate) {
+ // Other callbacks won't happen, so reset the state here.
+ communalSceneInteractor.setIsLaunchingWidget(false)
+ }
+ delegate.onIntentStarted(willAnimate)
+ }
+
+ override fun onTransitionAnimationCancelled(newKeyguardOccludedState: Boolean?) {
+ communalSceneInteractor.setIsLaunchingWidget(false)
+ delegate.onTransitionAnimationCancelled(newKeyguardOccludedState)
+ }
+
+ override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) {
+ communalSceneInteractor.snapToScene(CommunalScenes.Blank)
+ communalSceneInteractor.setIsLaunchingWidget(false)
+ delegate.onTransitionAnimationEnd(isExpandingFullyAbove)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalWidgetModule.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalWidgetModule.kt
index 2000f96bcdb0..684303ae73cc 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalWidgetModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalWidgetModule.kt
@@ -43,12 +43,6 @@ interface CommunalWidgetModule {
@SysUISingleton
@Provides
- fun provideAppWidgetManager(@Application context: Context): Optional<AppWidgetManager> {
- return Optional.ofNullable(AppWidgetManager.getInstance(context))
- }
-
- @SysUISingleton
- @Provides
fun provideCommunalAppWidgetHost(
@Application context: Context,
@Background backgroundScope: CoroutineScope,
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
index 72f9180c51d2..519903e55c50 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
@@ -22,6 +22,7 @@ import android.content.Intent
import android.view.View
import android.widget.RemoteViews
import com.android.systemui.animation.ActivityTransitionAnimator
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.util.InteractionHandlerDelegate
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.plugins.ActivityStarter
@@ -32,10 +33,12 @@ class WidgetInteractionHandler
@Inject
constructor(
private val activityStarter: ActivityStarter,
+ private val communalSceneInteractor: CommunalSceneInteractor
) : RemoteViews.InteractionHandler {
private val delegate =
InteractionHandlerDelegate(
+ communalSceneInteractor,
findViewToAnimate = { view -> view is CommunalAppWidgetHostView },
intentStarter = this::startIntent,
)
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index b0fc60e74b52..2ea27b76d81b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -16,6 +16,9 @@
package com.android.systemui.dagger;
+import static com.android.systemui.Flags.enableViewCaptureTracing;
+import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy;
+
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
@@ -39,6 +42,7 @@ import android.app.job.JobScheduler;
import android.app.role.RoleManager;
import android.app.smartspace.SmartspaceManager;
import android.app.trust.TrustManager;
+import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.companion.virtual.VirtualDeviceManager;
@@ -111,6 +115,9 @@ import android.view.textclassifier.TextClassificationManager;
import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
import androidx.core.app.NotificationManagerCompat;
+import com.android.app.viewcapture.ViewCapture;
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
+import com.android.app.viewcapture.ViewCaptureFactory;
import com.android.internal.app.IBatteryStats;
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.jank.InteractionJankMonitor;
@@ -125,6 +132,7 @@ import com.android.systemui.shared.system.PackageManagerWrapper;
import com.android.systemui.user.utils.UserScopedService;
import com.android.systemui.user.utils.UserScopedServiceImpl;
+import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
@@ -367,6 +375,12 @@ public class FrameworkServicesModule {
@Provides
@Singleton
+ static Optional<AppWidgetManager> provideAppWidgetManager(@Application Context context) {
+ return Optional.ofNullable(AppWidgetManager.getInstance(context));
+ }
+
+ @Provides
+ @Singleton
static IAppWidgetService provideIAppWidgetService() {
return IAppWidgetService.Stub.asInterface(
ServiceManager.getService(Context.APPWIDGET_SERVICE));
@@ -680,6 +694,15 @@ public class FrameworkServicesModule {
@Provides
@Singleton
+ static ViewCaptureAwareWindowManager provideViewCaptureAwareWindowManager(
+ WindowManager windowManager, Lazy<ViewCapture> daggerLazyViewCapture) {
+ return new ViewCaptureAwareWindowManager(windowManager,
+ /* lazyViewCapture= */ toKotlinLazy(daggerLazyViewCapture),
+ /* isViewCaptureEnabled= */ enableViewCaptureTracing());
+ }
+
+ @Provides
+ @Singleton
static PermissionManager providePermissionManager(Context context) {
PermissionManager pm = context.getSystemService(PermissionManager.class);
if (pm != null) {
@@ -764,4 +787,10 @@ public class FrameworkServicesModule {
return IDeviceIdleController.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
}
+
+ @Provides
+ @Singleton
+ static ViewCapture provideViewCapture(Context context) {
+ return ViewCaptureFactory.getInstance(context);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index 593196c54dae..88601dab891d 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -24,11 +24,6 @@ import com.android.systemui.accessibility.Magnification
import com.android.systemui.back.domain.interactor.BackActionInteractor
import com.android.systemui.biometrics.BiometricNotificationService
import com.android.systemui.clipboardoverlay.ClipboardListener
-import com.android.systemui.communal.CommunalDreamStartable
-import com.android.systemui.communal.CommunalBackupRestoreStartable
-import com.android.systemui.communal.CommunalSceneStartable
-import com.android.systemui.communal.log.CommunalLoggerStartable
-import com.android.systemui.communal.widgets.CommunalAppWidgetHostStartable
import com.android.systemui.controls.dagger.StartControlsStartableModule
import com.android.systemui.dagger.qualifiers.PerUser
import com.android.systemui.dreams.AssistantAttentionMonitor
@@ -80,12 +75,13 @@ import dagger.multibindings.IntoMap
* @deprecated
*/
@Module(
- includes = [
- MultiUserUtilsModule::class,
- StartControlsStartableModule::class,
- StartBinderLoggerModule::class,
- WallpaperModule::class,
- ]
+ includes =
+ [
+ MultiUserUtilsModule::class,
+ StartControlsStartableModule::class,
+ StartBinderLoggerModule::class,
+ WallpaperModule::class,
+ ]
)
abstract class SystemUICoreStartableModule {
/** Inject into BiometricNotificationService */
@@ -96,25 +92,25 @@ abstract class SystemUICoreStartableModule {
service: BiometricNotificationService
): CoreStartable
- /** Inject into ClipboardListener. */
+ /** Inject into ClipboardListener. */
@Binds
@IntoMap
@ClassKey(ClipboardListener::class)
abstract fun bindClipboardListener(sysui: ClipboardListener): CoreStartable
- /** Inject into GlobalActionsComponent. */
+ /** Inject into GlobalActionsComponent. */
@Binds
@IntoMap
@ClassKey(GlobalActionsComponent::class)
abstract fun bindGlobalActionsComponent(sysui: GlobalActionsComponent): CoreStartable
- /** Inject into InstantAppNotifier. */
+ /** Inject into InstantAppNotifier. */
@Binds
@IntoMap
@ClassKey(InstantAppNotifier::class)
abstract fun bindInstantAppNotifier(sysui: InstantAppNotifier): CoreStartable
- /** Inject into KeyboardUI. */
+ /** Inject into KeyboardUI. */
@Binds
@IntoMap
@ClassKey(KeyboardUI::class)
@@ -125,7 +121,7 @@ abstract class SystemUICoreStartableModule {
@IntoMap
@ClassKey(MediaProjectionTaskSwitcherCoreStartable::class)
abstract fun bindProjectedTaskListener(
- sysui: MediaProjectionTaskSwitcherCoreStartable
+ sysui: MediaProjectionTaskSwitcherCoreStartable
): CoreStartable
/** Inject into KeyguardBiometricLockoutLogger */
@@ -136,38 +132,38 @@ abstract class SystemUICoreStartableModule {
sysui: KeyguardBiometricLockoutLogger
): CoreStartable
- /** Inject into KeyguardViewMediator. */
+ /** Inject into KeyguardViewMediator. */
@Binds
@IntoMap
@ClassKey(KeyguardViewMediator::class)
abstract fun bindKeyguardViewMediator(sysui: KeyguardViewMediator): CoreStartable
- /** Inject into LatencyTests. */
+ /** Inject into LatencyTests. */
@Binds
@IntoMap
@ClassKey(LatencyTester::class)
abstract fun bindLatencyTester(sysui: LatencyTester): CoreStartable
- /** Inject into DisplaySwitchLatencyTracker. */
+ /** Inject into DisplaySwitchLatencyTracker. */
@Binds
@IntoMap
@ClassKey(DisplaySwitchLatencyTracker::class)
abstract fun bindDisplaySwitchLatencyTracker(sysui: DisplaySwitchLatencyTracker): CoreStartable
- /** Inject into NotificationChannels. */
+ /** Inject into NotificationChannels. */
@Binds
@IntoMap
@ClassKey(NotificationChannels::class)
@PerUser
abstract fun bindNotificationChannels(sysui: NotificationChannels): CoreStartable
- /** Inject into ImmersiveModeConfirmation. */
+ /** Inject into ImmersiveModeConfirmation. */
@Binds
@IntoMap
@ClassKey(ImmersiveModeConfirmation::class)
abstract fun bindImmersiveModeConfirmation(sysui: ImmersiveModeConfirmation): CoreStartable
- /** Inject into RingtonePlayer. */
+ /** Inject into RingtonePlayer. */
@Binds
@IntoMap
@ClassKey(RingtonePlayer::class)
@@ -179,50 +175,49 @@ abstract class SystemUICoreStartableModule {
@ClassKey(GesturePointerEventListener::class)
abstract fun bindGesturePointerEventListener(sysui: GesturePointerEventListener): CoreStartable
- /** Inject into SessionTracker. */
+ /** Inject into SessionTracker. */
@Binds
@IntoMap
@ClassKey(SessionTracker::class)
abstract fun bindSessionTracker(service: SessionTracker): CoreStartable
- /** Inject into ShortcutKeyDispatcher. */
+ /** Inject into ShortcutKeyDispatcher. */
@Binds
@IntoMap
@ClassKey(ShortcutKeyDispatcher::class)
abstract fun bindShortcutKeyDispatcher(sysui: ShortcutKeyDispatcher): CoreStartable
- /** Inject into SliceBroadcastRelayHandler. */
+ /** Inject into SliceBroadcastRelayHandler. */
@Binds
@IntoMap
@ClassKey(SliceBroadcastRelayHandler::class)
abstract fun bindSliceBroadcastRelayHandler(sysui: SliceBroadcastRelayHandler): CoreStartable
- /** Inject into StorageNotification. */
+ /** Inject into StorageNotification. */
@Binds
@IntoMap
@ClassKey(StorageNotification::class)
abstract fun bindStorageNotification(sysui: StorageNotification): CoreStartable
- /** Inject into ThemeOverlayController. */
+ /** Inject into ThemeOverlayController. */
@Binds
@IntoMap
@ClassKey(ThemeOverlayController::class)
abstract fun bindThemeOverlayController(sysui: ThemeOverlayController): CoreStartable
-
- /** Inject into MediaOutputSwitcherDialogUI. */
+ /** Inject into MediaOutputSwitcherDialogUI. */
@Binds
@IntoMap
@ClassKey(MediaOutputSwitcherDialogUI::class)
abstract fun MediaOutputSwitcherDialogUI(sysui: MediaOutputSwitcherDialogUI): CoreStartable
- /** Inject into Magnification. */
+ /** Inject into Magnification. */
@Binds
@IntoMap
@ClassKey(Magnification::class)
abstract fun bindMagnification(sysui: Magnification): CoreStartable
- /** Inject into WMShell. */
+ /** Inject into WMShell. */
@Binds
@IntoMap
@ClassKey(WMShell::class)
@@ -239,7 +234,7 @@ abstract class SystemUICoreStartableModule {
@IntoMap
@ClassKey(MediaTttChipControllerReceiver::class)
abstract fun bindMediaTttChipControllerReceiver(
- sysui: MediaTttChipControllerReceiver
+ sysui: MediaTttChipControllerReceiver
): CoreStartable
/** Inject into MediaTttCommandLineHelper. */
@@ -254,8 +249,6 @@ abstract class SystemUICoreStartableModule {
@ClassKey(ChipbarCoordinator::class)
abstract fun bindChipbarController(sysui: ChipbarCoordinator): CoreStartable
-
-
/** Inject into StylusUsiPowerStartable) */
@Binds
@IntoMap
@@ -267,21 +260,21 @@ abstract class SystemUICoreStartableModule {
@ClassKey(PhysicalKeyboardCoreStartable::class)
abstract fun bindKeyboardCoreStartable(listener: PhysicalKeyboardCoreStartable): CoreStartable
- /** Inject into MuteQuickAffordanceCoreStartable*/
+ /** Inject into MuteQuickAffordanceCoreStartable */
@Binds
@IntoMap
@ClassKey(MuteQuickAffordanceCoreStartable::class)
abstract fun bindMuteQuickAffordanceCoreStartable(
- sysui: MuteQuickAffordanceCoreStartable
+ sysui: MuteQuickAffordanceCoreStartable
): CoreStartable
- /**Inject into DreamMonitor */
+ /** Inject into DreamMonitor */
@Binds
@IntoMap
@ClassKey(DreamMonitor::class)
abstract fun bindDreamMonitor(sysui: DreamMonitor): CoreStartable
- /**Inject into AssistantAttentionMonitor */
+ /** Inject into AssistantAttentionMonitor */
@Binds
@IntoMap
@ClassKey(AssistantAttentionMonitor::class)
@@ -321,35 +314,6 @@ abstract class SystemUICoreStartableModule {
@Binds
@IntoMap
- @ClassKey(CommunalLoggerStartable::class)
- abstract fun bindCommunalLoggerStartable(impl: CommunalLoggerStartable): CoreStartable
-
- @Binds
- @IntoMap
- @ClassKey(CommunalSceneStartable::class)
- abstract fun bindCommunalSceneStartable(impl: CommunalSceneStartable): CoreStartable
-
- @Binds
- @IntoMap
- @ClassKey(CommunalDreamStartable::class)
- abstract fun bindCommunalDreamStartable(impl: CommunalDreamStartable): CoreStartable
-
- @Binds
- @IntoMap
- @ClassKey(CommunalAppWidgetHostStartable::class)
- abstract fun bindCommunalAppWidgetHostStartable(
- impl: CommunalAppWidgetHostStartable
- ): CoreStartable
-
- @Binds
- @IntoMap
- @ClassKey(CommunalBackupRestoreStartable::class)
- abstract fun bindCommunalBackupRestoreStartable(
- impl: CommunalBackupRestoreStartable
- ): CoreStartable
-
- @Binds
- @IntoMap
@ClassKey(HomeControlsDreamStartable::class)
abstract fun bindHomeControlsDreamStartable(impl: HomeControlsDreamStartable): CoreStartable
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 4b2fb44de310..1771f4dc8572 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -61,6 +61,7 @@ import com.android.systemui.display.DisplayModule;
import com.android.systemui.doze.dagger.DozeComponent;
import com.android.systemui.dreams.dagger.DreamModule;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.education.dagger.ContextualEducationModule;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.FlagDependenciesModule;
import com.android.systemui.flags.FlagsModule;
@@ -74,6 +75,7 @@ import com.android.systemui.log.table.TableLogBuffer;
import com.android.systemui.mediaprojection.MediaProjectionModule;
import com.android.systemui.mediaprojection.appselector.MediaProjectionActivitiesModule;
import com.android.systemui.mediaprojection.taskswitcher.MediaProjectionTaskSwitcherModule;
+import com.android.systemui.mediarouter.MediaRouterModule;
import com.android.systemui.model.SceneContainerPlugin;
import com.android.systemui.model.SysUiState;
import com.android.systemui.motiontool.MotionToolModule;
@@ -109,6 +111,7 @@ import com.android.systemui.startable.Dependencies;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.chips.StatusBarChipsModule;
import com.android.systemui.statusbar.connectivity.ConnectivityModule;
import com.android.systemui.statusbar.dagger.StatusBarModule;
import com.android.systemui.statusbar.disableflags.dagger.DisableFlagsModule;
@@ -220,6 +223,7 @@ import javax.inject.Named;
MediaProjectionActivitiesModule.class,
MediaProjectionModule.class,
MediaProjectionTaskSwitcherModule.class,
+ MediaRouterModule.class,
MotionToolModule.class,
NotificationIconAreaControllerModule.class,
PeopleHubModule.class,
@@ -242,6 +246,7 @@ import javax.inject.Named;
SmartspaceModule.class,
StatusBarEventsModule.class,
StatusBarModule.class,
+ StatusBarChipsModule.class,
StatusBarPipelineModule.class,
StatusBarPolicyModule.class,
StatusBarViewBinderModule.class,
@@ -257,7 +262,8 @@ import javax.inject.Named;
UserModule.class,
UtilModule.class,
NoteTaskModule.class,
- WalletModule.class
+ WalletModule.class,
+ ContextualEducationModule.class
},
subcomponents = {
ComplicationComponent.class,
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
index 813fccffb62f..9460eaf8abca 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -57,15 +57,13 @@ import com.android.systemui.log.FaceAuthenticationLogger
import com.android.systemui.log.SessionTracker
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.power.domain.interactor.PowerInteractor
-import com.android.systemui.res.R
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.UserRepository
import com.google.errorprone.annotations.CompileTimeConstant
import java.io.PrintWriter
-import java.util.Arrays
import java.util.concurrent.Executor
-import java.util.stream.Collectors
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
@@ -169,7 +167,6 @@ constructor(
) : DeviceEntryFaceAuthRepository, Dumpable {
private var authCancellationSignal: CancellationSignal? = null
private var detectCancellationSignal: CancellationSignal? = null
- private var faceAcquiredInfoIgnoreList: Set<Int>
private var retryCount = 0
private var pendingAuthenticateRequest = MutableStateFlow<AuthenticationRequest?>(null)
@@ -221,8 +218,7 @@ constructor(
trySendWithFailureLogging(it.bypassEnabled, TAG, "BypassStateChanged")
awaitClose { it.unregisterOnBypassStateChangedListener(callback) }
}
- }
- ?: flowOf(false)
+ } ?: flowOf(false)
override fun setLockedOut(isLockedOut: Boolean) {
_isLockedOut.value = isLockedOut
@@ -240,14 +236,6 @@ constructor(
faceManager?.addLockoutResetCallback(faceLockoutResetCallback)
faceAuthLogger.addLockoutResetCallbackDone()
}
- faceAcquiredInfoIgnoreList =
- Arrays.stream(
- context.resources.getIntArray(
- R.array.config_face_acquire_device_entry_ignorelist
- )
- )
- .boxed()
- .collect(Collectors.toSet())
dumpManager.registerCriticalDumpable("DeviceEntryFaceAuthRepositoryImpl", this)
canRunFaceAuth =
@@ -303,7 +291,10 @@ constructor(
private fun listenForSchedulingWatchdog() {
keyguardTransitionInteractor
- .transition(Edge.create(to = KeyguardState.GONE))
+ .transition(
+ edge = Edge.create(to = Scenes.Gone),
+ edgeWithoutSceneContainer = Edge.create(to = KeyguardState.GONE),
+ )
.filter { it.transitionState == TransitionState.FINISHED }
.onEach {
// We deliberately want to run this in background because scheduleWatchdog does
@@ -322,7 +313,10 @@ constructor(
merge(
powerInteractor.isAsleep,
combine(
- keyguardTransitionInteractor.isFinishedInState(KeyguardState.GONE),
+ keyguardTransitionInteractor.isFinishedIn(
+ scene = Scenes.Gone,
+ stateWithoutSceneContainer = KeyguardState.GONE,
+ ),
keyguardInteractor.statusBarState,
) { isFinishedInGoneState, statusBarState ->
// When the user is dragging the primary bouncer in (up) by manually scrolling
@@ -394,7 +388,7 @@ constructor(
Pair(keyguardRepository.isKeyguardGoingAway.isFalse(), "keyguardNotGoingAway"),
Pair(
keyguardTransitionInteractor
- .isInTransitionToStateWhere(KeyguardState::deviceIsAsleepInState)
+ .isInTransitionWhere(toStatePredicate = KeyguardState::deviceIsAsleepInState)
.isFalse(),
"deviceNotTransitioningToAsleepState"
),
@@ -479,10 +473,8 @@ constructor(
}
override fun onAuthenticationHelp(code: Int, helpStr: CharSequence?) {
- if (faceAcquiredInfoIgnoreList.contains(code)) {
- return
- }
- _authenticationStatus.value = HelpFaceAuthenticationStatus(code, helpStr.toString())
+ _authenticationStatus.value =
+ HelpFaceAuthenticationStatus(code, helpStr?.toString())
}
override fun onAuthenticationSucceeded(result: FaceManager.AuthenticationResult) {
@@ -725,7 +717,6 @@ constructor(
pw.println(" _pendingAuthenticateRequest: ${pendingAuthenticateRequest.value}")
pw.println(" authCancellationSignal: $authCancellationSignal")
pw.println(" detectCancellationSignal: $detectCancellationSignal")
- pw.println(" faceAcquiredInfoIgnoreList: $faceAcquiredInfoIgnoreList")
pw.println(" _authenticationStatus: ${_authenticationStatus.value}")
pw.println(" _detectionStatus: ${_detectionStatus.value}")
pw.println(" currentUserId: $currentUserId")
@@ -733,6 +724,7 @@ constructor(
pw.println(" lockscreenBypassEnabled: ${keyguardBypassController?.bypassEnabled ?: false}")
}
}
+
/** Combine two boolean flows by and-ing both of them */
private fun and(flow: Flow<Boolean>, anotherFlow: Flow<Boolean>) =
flow.combine(anotherFlow) { a, b -> a && b }
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
index f779ac8fb0bb..e2ad7741557f 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
@@ -78,10 +78,6 @@ constructor(
SharingStarted.Eagerly,
initialValue = keyguardBypassController.bypassEnabled,
)
-
- companion object {
- private const val TAG = "DeviceEntryRepositoryImpl"
- }
}
@Module
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractor.kt
new file mode 100644
index 000000000000..34b1544489bd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractor.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.deviceentry.domain.interactor
+
+import android.content.res.Resources
+import android.hardware.biometrics.BiometricFaceConstants
+import com.android.systemui.biometrics.FaceHelpMessageDebouncer
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.deviceentry.data.repository.DeviceEntryFaceAuthRepository
+import com.android.systemui.deviceentry.shared.model.AcquiredFaceAuthenticationStatus
+import com.android.systemui.deviceentry.shared.model.FaceAuthenticationStatus
+import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus
+import com.android.systemui.res.R
+import java.util.Arrays
+import java.util.stream.Collectors
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.transform
+
+/**
+ * Process face authentication statuses.
+ * - Ignores face help messages based on R.array.config_face_acquire_device_entry_ignorelist.
+ * - Uses FaceHelpMessageDebouncer to debounce flickery help messages.
+ */
+@SysUISingleton
+class DeviceEntryFaceAuthStatusInteractor
+@Inject
+constructor(
+ repository: DeviceEntryFaceAuthRepository,
+ @Main private val resources: Resources,
+ @Application private val applicationScope: CoroutineScope,
+) {
+ private val faceHelpMessageDebouncer = FaceHelpMessageDebouncer()
+ private var faceAcquiredInfoIgnoreList: Set<Int> =
+ Arrays.stream(resources.getIntArray(R.array.config_face_acquire_device_entry_ignorelist))
+ .boxed()
+ .collect(Collectors.toSet())
+
+ val authenticationStatus: StateFlow<FaceAuthenticationStatus?> =
+ repository.authenticationStatus
+ .transform { authenticationStatus ->
+ if (authenticationStatus is AcquiredFaceAuthenticationStatus) {
+ if (
+ authenticationStatus.acquiredInfo ==
+ BiometricFaceConstants.FACE_ACQUIRED_START
+ ) {
+ faceHelpMessageDebouncer.startNewFaceAuthSession(
+ authenticationStatus.createdAt
+ )
+ }
+ }
+
+ if (authenticationStatus is HelpFaceAuthenticationStatus) {
+ if (!faceAcquiredInfoIgnoreList.contains(authenticationStatus.msgId)) {
+ faceHelpMessageDebouncer.addMessage(authenticationStatus)
+ }
+
+ val messageToShow =
+ faceHelpMessageDebouncer.getMessageToShow(
+ atTimestamp = authenticationStatus.createdAt,
+ )
+ if (messageToShow != null) {
+ emit(messageToShow)
+ }
+
+ return@transform
+ }
+
+ emit(authenticationStatus)
+ }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = null,
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
index 4c7142b7aeb0..ea0e59bb6ccc 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
@@ -16,31 +16,23 @@
package com.android.systemui.deviceentry.domain.interactor
-import androidx.annotation.VisibleForTesting
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.data.repository.DeviceEntryRepository
-import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason
-import com.android.systemui.flags.SystemPropertiesHelper
-import com.android.systemui.keyguard.domain.interactor.TrustInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.util.kotlin.Quad
import com.android.systemui.utils.coroutines.flow.mapLatestConflated
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
@@ -60,12 +52,7 @@ constructor(
private val repository: DeviceEntryRepository,
private val authenticationInteractor: AuthenticationInteractor,
private val sceneInteractor: SceneInteractor,
- faceAuthInteractor: DeviceEntryFaceAuthInteractor,
- private val fingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor,
- private val biometricSettingsInteractor: DeviceEntryBiometricSettingsInteractor,
- private val trustInteractor: TrustInteractor,
private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
- private val systemPropertiesHelper: SystemPropertiesHelper,
private val alternateBouncerInteractor: AlternateBouncerInteractor,
) {
/**
@@ -150,70 +137,6 @@ constructor(
initialValue = null,
)
- private val faceEnrolledAndEnabled = biometricSettingsInteractor.isFaceAuthEnrolledAndEnabled
- private val fingerprintEnrolledAndEnabled =
- biometricSettingsInteractor.isFingerprintAuthEnrolledAndEnabled
- private val trustAgentEnabled = trustInteractor.isEnrolledAndEnabled
-
- private val faceOrFingerprintOrTrustEnabled: Flow<Triple<Boolean, Boolean, Boolean>> =
- combine(faceEnrolledAndEnabled, fingerprintEnrolledAndEnabled, trustAgentEnabled, ::Triple)
-
- /**
- * Reason why device entry is restricted to certain authentication methods for the current user.
- *
- * Emits null when there are no device entry restrictions active.
- */
- val deviceEntryRestrictionReason: Flow<DeviceEntryRestrictionReason?> =
- faceOrFingerprintOrTrustEnabled.flatMapLatest {
- (faceEnabled, fingerprintEnabled, trustEnabled) ->
- if (faceEnabled || fingerprintEnabled || trustEnabled) {
- combine(
- biometricSettingsInteractor.authenticationFlags,
- faceAuthInteractor.isLockedOut,
- fingerprintAuthInteractor.isLockedOut,
- trustInteractor.isTrustAgentCurrentlyAllowed,
- ::Quad
- )
- .map { (authFlags, isFaceLockedOut, isFingerprintLockedOut, trustManaged) ->
- when {
- authFlags.isPrimaryAuthRequiredAfterReboot &&
- wasRebootedForMainlineUpdate ->
- DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate
- authFlags.isPrimaryAuthRequiredAfterReboot ->
- DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot
- authFlags.isPrimaryAuthRequiredAfterDpmLockdown ->
- DeviceEntryRestrictionReason.PolicyLockdown
- authFlags.isInUserLockdown -> DeviceEntryRestrictionReason.UserLockdown
- authFlags.isPrimaryAuthRequiredForUnattendedUpdate ->
- DeviceEntryRestrictionReason.UnattendedUpdate
- authFlags.isPrimaryAuthRequiredAfterTimeout ->
- DeviceEntryRestrictionReason.SecurityTimeout
- authFlags.isPrimaryAuthRequiredAfterLockout ->
- DeviceEntryRestrictionReason.BouncerLockedOut
- isFingerprintLockedOut ->
- DeviceEntryRestrictionReason.StrongBiometricsLockedOut
- isFaceLockedOut && faceAuthInteractor.isFaceAuthStrong() ->
- DeviceEntryRestrictionReason.StrongBiometricsLockedOut
- isFaceLockedOut -> DeviceEntryRestrictionReason.NonStrongFaceLockedOut
- authFlags.isSomeAuthRequiredAfterAdaptiveAuthRequest ->
- DeviceEntryRestrictionReason.AdaptiveAuthRequest
- (trustEnabled && !trustManaged) &&
- (authFlags.someAuthRequiredAfterTrustAgentExpired ||
- authFlags.someAuthRequiredAfterUserRequest) ->
- DeviceEntryRestrictionReason.TrustAgentDisabled
- authFlags.strongerAuthRequiredAfterNonStrongBiometricsTimeout ->
- DeviceEntryRestrictionReason.NonStrongBiometricsSecurityTimeout
- else -> null
- }
- }
- } else {
- flowOf(null)
- }
- }
-
- /** Whether the device is in lockdown mode, where bouncer input is required to unlock. */
- val isInLockdown: Flow<Boolean> = deviceEntryRestrictionReason.map { it.isInLockdown() }
-
/**
* Attempt to enter the device and dismiss the lockscreen. If authentication is required to
* unlock the device it will transition to bouncer.
@@ -262,27 +185,6 @@ constructor(
return repository.isLockscreenEnabled()
}
- fun DeviceEntryRestrictionReason?.isInLockdown(): Boolean {
- return when (this) {
- DeviceEntryRestrictionReason.UserLockdown -> true
- DeviceEntryRestrictionReason.PolicyLockdown -> true
-
- // Add individual enum value instead of using "else" so new reasons are guaranteed
- // to be added here at compile-time.
- null -> false
- DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot -> false
- DeviceEntryRestrictionReason.BouncerLockedOut -> false
- DeviceEntryRestrictionReason.AdaptiveAuthRequest -> false
- DeviceEntryRestrictionReason.NonStrongBiometricsSecurityTimeout -> false
- DeviceEntryRestrictionReason.TrustAgentDisabled -> false
- DeviceEntryRestrictionReason.StrongBiometricsLockedOut -> false
- DeviceEntryRestrictionReason.SecurityTimeout -> false
- DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate -> false
- DeviceEntryRestrictionReason.UnattendedUpdate -> false
- DeviceEntryRestrictionReason.NonStrongFaceLockedOut -> false
- }
- }
-
/**
* Whether lockscreen bypass is enabled. When enabled, the lockscreen will be automatically
* dismissed once the authentication challenge is completed. For example, completing a biometric
@@ -290,12 +192,4 @@ constructor(
* lockscreen.
*/
val isBypassEnabled: StateFlow<Boolean> = repository.isBypassEnabled
-
- private val wasRebootedForMainlineUpdate
- get() = systemPropertiesHelper.get(SYS_BOOT_REASON_PROP) == REBOOT_MAINLINE_UPDATE
-
- companion object {
- @VisibleForTesting const val SYS_BOOT_REASON_PROP = "sys.boot.reason.last"
- @VisibleForTesting const val REBOOT_MAINLINE_UPDATE = "reboot,mainline_update"
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
index 51416905b0c0..e17e530a03d9 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
@@ -16,20 +16,26 @@
package com.android.systemui.deviceentry.domain.interactor
+import androidx.annotation.VisibleForTesting
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.data.repository.DeviceEntryRepository
+import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason
import com.android.systemui.deviceentry.shared.model.DeviceUnlockSource
import com.android.systemui.deviceentry.shared.model.DeviceUnlockStatus
+import com.android.systemui.flags.SystemPropertiesHelper
import com.android.systemui.keyguard.domain.interactor.TrustInteractor
import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
@@ -49,6 +55,8 @@ constructor(
faceAuthInteractor: DeviceEntryFaceAuthInteractor,
fingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor,
private val powerInteractor: PowerInteractor,
+ private val biometricSettingsInteractor: DeviceEntryBiometricSettingsInteractor,
+ private val systemPropertiesHelper: SystemPropertiesHelper,
) {
private val deviceUnlockSource =
@@ -69,6 +77,75 @@ constructor(
.map { DeviceUnlockSource.BouncerInput }
)
+ private val faceEnrolledAndEnabled = biometricSettingsInteractor.isFaceAuthEnrolledAndEnabled
+ private val fingerprintEnrolledAndEnabled =
+ biometricSettingsInteractor.isFingerprintAuthEnrolledAndEnabled
+ private val trustAgentEnabled = trustInteractor.isEnrolledAndEnabled
+
+ private val faceOrFingerprintOrTrustEnabled: Flow<Triple<Boolean, Boolean, Boolean>> =
+ combine(faceEnrolledAndEnabled, fingerprintEnrolledAndEnabled, trustAgentEnabled, ::Triple)
+
+ /**
+ * Reason why device entry is restricted to certain authentication methods for the current user.
+ *
+ * Emits null when there are no device entry restrictions active.
+ */
+ val deviceEntryRestrictionReason: Flow<DeviceEntryRestrictionReason?> =
+ faceOrFingerprintOrTrustEnabled.flatMapLatest {
+ (faceEnabled, fingerprintEnabled, trustEnabled) ->
+ if (faceEnabled || fingerprintEnabled || trustEnabled) {
+ combine(
+ biometricSettingsInteractor.authenticationFlags,
+ faceAuthInteractor.isLockedOut,
+ fingerprintAuthInteractor.isLockedOut,
+ trustInteractor.isTrustAgentCurrentlyAllowed,
+ ) { authFlags, isFaceLockedOut, isFingerprintLockedOut, trustManaged ->
+ when {
+ authFlags.isPrimaryAuthRequiredAfterReboot &&
+ wasRebootedForMainlineUpdate() ->
+ DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate
+ authFlags.isPrimaryAuthRequiredAfterReboot ->
+ DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot
+ authFlags.isPrimaryAuthRequiredAfterDpmLockdown ->
+ DeviceEntryRestrictionReason.PolicyLockdown
+ authFlags.isInUserLockdown -> DeviceEntryRestrictionReason.UserLockdown
+ authFlags.isPrimaryAuthRequiredForUnattendedUpdate ->
+ DeviceEntryRestrictionReason.UnattendedUpdate
+ authFlags.isPrimaryAuthRequiredAfterTimeout ->
+ DeviceEntryRestrictionReason.SecurityTimeout
+ authFlags.isPrimaryAuthRequiredAfterLockout ->
+ DeviceEntryRestrictionReason.BouncerLockedOut
+ isFingerprintLockedOut ->
+ DeviceEntryRestrictionReason.StrongBiometricsLockedOut
+ isFaceLockedOut && faceAuthInteractor.isFaceAuthStrong() ->
+ DeviceEntryRestrictionReason.StrongBiometricsLockedOut
+ isFaceLockedOut -> DeviceEntryRestrictionReason.NonStrongFaceLockedOut
+ authFlags.isSomeAuthRequiredAfterAdaptiveAuthRequest ->
+ DeviceEntryRestrictionReason.AdaptiveAuthRequest
+ (trustEnabled && !trustManaged) &&
+ (authFlags.someAuthRequiredAfterTrustAgentExpired ||
+ authFlags.someAuthRequiredAfterUserRequest) ->
+ DeviceEntryRestrictionReason.TrustAgentDisabled
+ authFlags.strongerAuthRequiredAfterNonStrongBiometricsTimeout ->
+ DeviceEntryRestrictionReason.NonStrongBiometricsSecurityTimeout
+ else -> null
+ }
+ }
+ } else {
+ biometricSettingsInteractor.authenticationFlags.map { authFlags ->
+ when {
+ authFlags.isInUserLockdown -> DeviceEntryRestrictionReason.UserLockdown
+ authFlags.isPrimaryAuthRequiredAfterDpmLockdown ->
+ DeviceEntryRestrictionReason.PolicyLockdown
+ else -> null
+ }
+ }
+ }
+ }
+
+ /** Whether the device is in lockdown mode, where bouncer input is required to unlock. */
+ val isInLockdown: Flow<Boolean> = deviceEntryRestrictionReason.map { it.isInLockdown() }
+
/**
* Whether the device is unlocked or not, along with the information about the authentication
* method that was used to unlock the device.
@@ -90,13 +167,18 @@ constructor(
// Device is locked if SIM is locked.
flowOf(DeviceUnlockStatus(false, null))
} else {
- powerInteractor.isAsleep.flatMapLatest { isAsleep ->
- if (isAsleep) {
- flowOf(DeviceUnlockStatus(false, null))
- } else {
- deviceUnlockSource.map { DeviceUnlockStatus(true, it) }
+ combine(
+ powerInteractor.isAsleep,
+ isInLockdown,
+ ::Pair,
+ )
+ .flatMapLatestConflated { (isAsleep, isInLockdown) ->
+ if (isAsleep || isInLockdown) {
+ flowOf(DeviceUnlockStatus(false, null))
+ } else {
+ deviceUnlockSource.map { DeviceUnlockStatus(true, it) }
+ }
}
- }
}
}
.stateIn(
@@ -104,4 +186,34 @@ constructor(
started = SharingStarted.Eagerly,
initialValue = DeviceUnlockStatus(false, null),
)
+
+ private fun DeviceEntryRestrictionReason?.isInLockdown(): Boolean {
+ return when (this) {
+ DeviceEntryRestrictionReason.UserLockdown -> true
+ DeviceEntryRestrictionReason.PolicyLockdown -> true
+
+ // Add individual enum value instead of using "else" so new reasons are guaranteed
+ // to be added here at compile-time.
+ null -> false
+ DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot -> false
+ DeviceEntryRestrictionReason.BouncerLockedOut -> false
+ DeviceEntryRestrictionReason.AdaptiveAuthRequest -> false
+ DeviceEntryRestrictionReason.NonStrongBiometricsSecurityTimeout -> false
+ DeviceEntryRestrictionReason.TrustAgentDisabled -> false
+ DeviceEntryRestrictionReason.StrongBiometricsLockedOut -> false
+ DeviceEntryRestrictionReason.SecurityTimeout -> false
+ DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate -> false
+ DeviceEntryRestrictionReason.UnattendedUpdate -> false
+ DeviceEntryRestrictionReason.NonStrongFaceLockedOut -> false
+ }
+ }
+
+ private fun wasRebootedForMainlineUpdate(): Boolean {
+ return systemPropertiesHelper.get(SYS_BOOT_REASON_PROP) == REBOOT_MAINLINE_UPDATE
+ }
+
+ companion object {
+ @VisibleForTesting const val SYS_BOOT_REASON_PROP = "sys.boot.reason.last"
+ @VisibleForTesting const val REBOOT_MAINLINE_UPDATE = "reboot,mainline_update"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
index d12ea4573fbe..c536d6b4f6f8 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
@@ -90,6 +90,7 @@ constructor(
private val powerInteractor: PowerInteractor,
private val biometricSettingsRepository: BiometricSettingsRepository,
private val trustManager: TrustManager,
+ deviceEntryFaceAuthStatusInteractor: DeviceEntryFaceAuthStatusInteractor,
) : DeviceEntryFaceAuthInteractor {
private val listeners: MutableList<FaceAuthenticationListener> = mutableListOf()
@@ -276,9 +277,13 @@ constructor(
}
private val faceAuthenticationStatusOverride = MutableStateFlow<FaceAuthenticationStatus?>(null)
+
/** Provide the status of face authentication */
override val authenticationStatus =
- merge(faceAuthenticationStatusOverride.filterNotNull(), repository.authenticationStatus)
+ merge(
+ faceAuthenticationStatusOverride.filterNotNull(),
+ deviceEntryFaceAuthStatusInteractor.authenticationStatus.filterNotNull(),
+ )
/** Provide the status of face detection */
override val detectionStatus = repository.detectionStatus
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
index 0bcfa9616b76..69ddb62cc05a 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
@@ -44,6 +44,7 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
@@ -137,6 +138,7 @@ constructor(
override val displayAdditionEvent: Flow<Display?> =
allDisplayEvents.filterIsInstance<DisplayEvent.Added>().map { getDisplay(it.displayId) }
+ // TODO: b/345472038 - Delete after the flag is ramped up.
private val oldEnabledDisplays: Flow<Set<Display>> =
allDisplayEvents
.map { getDisplays() }
@@ -167,6 +169,9 @@ constructor(
}
.debugLog("enabledDisplayIds")
+ private val defaultDisplay by lazy {
+ getDisplay(Display.DEFAULT_DISPLAY) ?: error("Unable to get default display.")
+ }
/**
* Represents displays that went though the [DisplayListener.onDisplayAdded] callback.
*
@@ -181,11 +186,7 @@ constructor(
.stateIn(
bgApplicationScope,
started = SharingStarted.WhileSubscribed(),
- initialValue =
- setOf(
- getDisplay(Display.DEFAULT_DISPLAY)
- ?: error("Unable to get default display.")
- )
+ initialValue = setOf(defaultDisplay)
)
} else {
oldEnabledDisplays
@@ -344,9 +345,10 @@ constructor(
.debugLog("pendingDisplay")
override val defaultDisplayOff: Flow<Boolean> =
- displays
- .map { displays -> displays.firstOrNull { it.displayId == Display.DEFAULT_DISPLAY } }
- .map { it?.state == Display.STATE_OFF }
+ displayChangeEvent
+ .filter { it == Display.DEFAULT_DISPLAY }
+ .map { defaultDisplay.state == Display.STATE_OFF }
+ .distinctUntilChanged()
private fun <T> Flow<T>.debugLog(flowName: String): Flow<T> {
return if (DEBUG) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 8776ec5496c8..17b455d7ef6f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -18,6 +18,8 @@ package com.android.systemui.doze;
import android.annotation.NonNull;
+import androidx.annotation.MainThread;
+
/**
* Interface the doze service uses to communicate with the rest of system UI.
*/
@@ -27,6 +29,7 @@ public interface DozeHost {
void startDozing();
void pulseWhileDozing(@NonNull PulseCallback callback, int reason);
void stopDozing();
+ @MainThread
void dozeTimeTick();
boolean isPowerSaveActive();
boolean isPulsingBlocked();
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 7ae840938fe7..e07b5c228585 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -48,6 +48,7 @@ import com.android.internal.R;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
+import com.android.systemui.Flags;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.plugins.SensorManagerPlugin;
import com.android.systemui.statusbar.phone.DozeParameters;
@@ -426,7 +427,11 @@ public class DozeSensors {
}
if (!anyListening) {
- mSecureSettings.unregisterContentObserverSync(mSettingsObserver);
+ if (Flags.registerContentObserversAsync()) {
+ mSecureSettings.unregisterContentObserverAsync(mSettingsObserver);
+ } else {
+ mSecureSettings.unregisterContentObserverSync(mSettingsObserver);
+ }
} else if (!mSettingRegistered) {
for (TriggerSensor s : mTriggerSensors) {
s.registerSettingsObserver(mSettingsObserver);
@@ -750,8 +755,13 @@ public class DozeSensors {
public void registerSettingsObserver(ContentObserver settingsObserver) {
if (mConfigured && !TextUtils.isEmpty(mSetting)) {
- mSecureSettings.registerContentObserverForUserSync(
- mSetting, mSettingsObserver, UserHandle.USER_ALL);
+ if (Flags.registerContentObserversAsync()) {
+ mSecureSettings.registerContentObserverForUserAsync(
+ mSetting, mSettingsObserver, UserHandle.USER_ALL);
+ } else {
+ mSecureSettings.registerContentObserverForUserSync(
+ mSetting, mSettingsObserver, UserHandle.USER_ALL);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 1a06418065a2..9def81a89e3a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -27,6 +27,8 @@ import android.os.SystemClock;
import android.text.format.Formatter;
import android.util.Log;
+import androidx.annotation.AnyThread;
+
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.dagger.DozeScope;
@@ -55,7 +57,7 @@ public class DozeUi implements DozeMachine.Part {
private final DozeParameters mDozeParameters;
private final DozeLog mDozeLog;
private final DelayableExecutor mBgExecutor;
- private long mLastTimeTickElapsed = 0;
+ private volatile long mLastTimeTickElapsed = 0;
// If time tick is scheduled and there's not a pending runnable to cancel:
private volatile boolean mTimeTickScheduled;
private final Runnable mCancelTimeTickerRunnable = new Runnable() {
@@ -218,10 +220,15 @@ public class DozeUi implements DozeMachine.Part {
return calendar.getTimeInMillis();
}
+ @AnyThread
private void onTimeTick() {
verifyLastTimeTick();
- mHost.dozeTimeTick();
+ if (dozeuiSchedulingAlarmsBackgroundExecution()) {
+ mHandler.post(mHost::dozeTimeTick);
+ } else {
+ mHost.dozeTimeTick();
+ }
// Keep wakelock until a frame has been pushed.
mHandler.post(mWakeLock.wrap(() -> {}));
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index 245def8fd27b..76c7d2383751 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -21,8 +21,6 @@ import static android.service.dreams.Flags.dreamHandlesBeingObscured;
import static com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress;
import static com.android.keyguard.BouncerPanelExpansionCalculator.getDreamAlphaScaledExpansion;
import static com.android.keyguard.BouncerPanelExpansionCalculator.getDreamYPositionScaledExpansion;
-import static com.android.systemui.Flags.communalHub;
-import static com.android.systemui.Flags.glanceableHubGestureHandle;
import static com.android.systemui.complication.ComplicationLayoutParams.POSITION_BOTTOM;
import static com.android.systemui.complication.ComplicationLayoutParams.POSITION_TOP;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
@@ -53,6 +51,7 @@ import com.android.systemui.dreams.dagger.DreamOverlayModule;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.shared.model.KeyguardState;
import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.model.Scenes;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.BlurUtils;
@@ -191,7 +190,6 @@ public class DreamOverlayContainerViewController extends
DreamOverlayContainerView containerView,
ComplicationHostViewController complicationHostViewController,
@Named(DreamOverlayModule.DREAM_OVERLAY_CONTENT_VIEW) ViewGroup contentView,
- @Named(DreamOverlayModule.HUB_GESTURE_INDICATOR_VIEW) View hubGestureIndicatorView,
AmbientStatusBarViewController statusBarViewController,
LowLightTransitionCoordinator lowLightTransitionCoordinator,
TouchInsetManager.TouchInsetSession touchInsetSession,
@@ -229,12 +227,6 @@ public class DreamOverlayContainerViewController extends
mComplicationHostViewController = complicationHostViewController;
mDreamOverlayMaxTranslationY = resources.getDimensionPixelSize(
R.dimen.dream_overlay_y_offset);
-
- if (communalHub() && glanceableHubGestureHandle()) {
- // TODO(b/339667383): remove this temporary swipe gesture handle
- hubGestureIndicatorView.setVisibility(View.VISIBLE);
- }
-
final View view = mComplicationHostViewController.getView();
mDreamOverlayContentView.addView(view,
@@ -274,13 +266,19 @@ public class DreamOverlayContainerViewController extends
collectFlow(
mView,
FlowKt.distinctUntilChanged(combineFlows(
- mKeyguardTransitionInteractor.isFinishedInStateWhere(
- KeyguardState::isBouncerState),
+ mKeyguardTransitionInteractor.isFinishedIn(
+ Scenes.Bouncer, KeyguardState.PRIMARY_BOUNCER),
+ mKeyguardTransitionInteractor.isFinishedIn(
+ KeyguardState.ALTERNATE_BOUNCER),
mShadeInteractor.isAnyExpanded(),
mCommunalInteractor.isCommunalShowing(),
- (anyBouncerShowing, shadeExpanded, communalShowing) -> {
- mAnyBouncerShowing = anyBouncerShowing;
- return anyBouncerShowing || shadeExpanded || communalShowing;
+ (primaryBouncerShowing,
+ alternateBouncerShowing,
+ shadeExpanded,
+ communalShowing) -> {
+ mAnyBouncerShowing = primaryBouncerShowing
+ || alternateBouncerShowing;
+ return mAnyBouncerShowing || shadeExpanded || communalShowing;
})),
mDreamManager::setDreamIsObscured,
mBackgroundDispatcher);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index c6c5747973b3..83fa001d104e 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -45,6 +45,7 @@ import androidx.lifecycle.LifecycleService;
import androidx.lifecycle.ServiceLifecycleDispatcher;
import androidx.lifecycle.ViewModelStore;
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
import com.android.dream.lowlight.dagger.LowLightDreamModule;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
@@ -97,7 +98,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
@Nullable
private final ComponentName mHomeControlPanelDreamComponent;
private final UiEventLogger mUiEventLogger;
- private final WindowManager mWindowManager;
+ private final ViewCaptureAwareWindowManager mWindowManager;
private final String mWindowTitle;
// A reference to the {@link Window} used to hold the dream overlay.
@@ -244,7 +245,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
Context context,
DreamOverlayLifecycleOwner lifecycleOwner,
@Main DelayableExecutor executor,
- WindowManager windowManager,
+ ViewCaptureAwareWindowManager viewCaptureAwareWindowManager,
ComplicationComponent.Factory complicationComponentFactory,
com.android.systemui.dreams.complication.dagger.ComplicationComponent.Factory
dreamComplicationComponentFactory,
@@ -267,7 +268,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
super(executor);
mContext = context;
mExecutor = executor;
- mWindowManager = windowManager;
+ mWindowManager = viewCaptureAwareWindowManager;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mScrimManager = scrimManager;
mLowLightDreamComponent = lowLightDreamComponent;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
index 76fcabd635d8..12984efb52c2 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
@@ -18,7 +18,6 @@ package com.android.systemui.dreams.dagger;
import android.content.res.Resources;
import android.view.LayoutInflater;
-import android.view.View;
import android.view.ViewGroup;
import androidx.lifecycle.Lifecycle;
@@ -42,7 +41,6 @@ import javax.inject.Named;
@Module
public abstract class DreamOverlayModule {
public static final String DREAM_OVERLAY_CONTENT_VIEW = "dream_overlay_content_view";
- public static final String HUB_GESTURE_INDICATOR_VIEW = "hub_gesture_indicator_view";
public static final String MAX_BURN_IN_OFFSET = "max_burn_in_offset";
public static final String BURN_IN_PROTECTION_UPDATE_INTERVAL =
"burn_in_protection_update_interval";
@@ -75,18 +73,6 @@ public abstract class DreamOverlayModule {
"R.id.dream_overlay_content must not be null");
}
- /**
- * Gesture indicator bar on the right edge of the screen to indicate to users that they can
- * swipe to see their widgets on lock screen.
- */
- @Provides
- @DreamOverlayComponent.DreamOverlayScope
- @Named(HUB_GESTURE_INDICATOR_VIEW)
- public static View providesHubGestureIndicatorView(DreamOverlayContainerView view) {
- return Preconditions.checkNotNull(view.findViewById(R.id.glanceable_hub_handle),
- "R.id.glanceable_hub_handle must not be null");
- }
-
/** */
@Provides
public static TouchInsetManager.TouchInsetSession providesTouchInsetSession(
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/TaskFragmentComponent.kt b/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/TaskFragmentComponent.kt
index 297ad847caa6..befd822e14cd 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/TaskFragmentComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/TaskFragmentComponent.kt
@@ -161,5 +161,6 @@ constructor(
TASK_FRAGMENT_TRANSIT_CLOSE,
false
)
+ organizer.unregisterOrganizer()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt b/packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt
new file mode 100644
index 000000000000..53b9261991e0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright 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.education.dagger
+
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.education.data.repository.ContextualEducationRepository
+import com.android.systemui.education.data.repository.ContextualEducationRepositoryImpl
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import java.time.Clock
+import javax.inject.Qualifier
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.SupervisorJob
+
+@Module
+interface ContextualEducationModule {
+ @Binds
+ fun bindContextualEducationRepository(
+ impl: ContextualEducationRepositoryImpl
+ ): ContextualEducationRepository
+
+ @Qualifier annotation class EduDataStoreScope
+
+ @Qualifier annotation class EduClock
+
+ companion object {
+ @EduDataStoreScope
+ @Provides
+ fun provideEduDataStoreScope(
+ @Background bgDispatcher: CoroutineDispatcher
+ ): CoroutineScope {
+ return CoroutineScope(bgDispatcher + SupervisorJob())
+ }
+
+ @EduClock
+ @Provides
+ fun provideEduClock(): Clock {
+ return Clock.systemUTC()
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/education/data/model/GestureEduModel.kt b/packages/SystemUI/src/com/android/systemui/education/data/model/GestureEduModel.kt
new file mode 100644
index 000000000000..9f6cb4d027e6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/education/data/model/GestureEduModel.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 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.education.data.model
+
+import java.time.Instant
+
+/**
+ * Model to store education data related to each gesture (e.g. Back, Home, All Apps, Overview). Each
+ * gesture stores its own model separately.
+ */
+data class GestureEduModel(
+ val signalCount: Int = 0,
+ val educationShownCount: Int = 0,
+ val lastShortcutTriggeredTime: Instant? = null,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt b/packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt
new file mode 100644
index 000000000000..248b7a526256
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright 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.education.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.education.dagger.ContextualEducationModule.EduClock
+import com.android.systemui.education.data.model.GestureEduModel
+import com.android.systemui.shared.education.GestureType
+import java.time.Clock
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+/** Encapsulates the functions of ContextualEducationRepository. */
+interface ContextualEducationRepository {
+ fun setUser(userId: Int)
+
+ fun readGestureEduModelFlow(gestureType: GestureType): Flow<GestureEduModel>
+
+ suspend fun incrementSignalCount(gestureType: GestureType)
+
+ suspend fun updateShortcutTriggerTime(gestureType: GestureType)
+}
+
+/**
+ * Provide methods to read and update on field level and allow setting datastore when user is
+ * changed
+ */
+@SysUISingleton
+class ContextualEducationRepositoryImpl
+@Inject
+constructor(
+ @EduClock private val clock: Clock,
+ private val userEduRepository: UserContextualEducationRepository
+) : ContextualEducationRepository {
+ /** To change data store when user is changed */
+ override fun setUser(userId: Int) = userEduRepository.setUser(userId)
+
+ override fun readGestureEduModelFlow(gestureType: GestureType) =
+ userEduRepository.readGestureEduModelFlow(gestureType)
+
+ override suspend fun incrementSignalCount(gestureType: GestureType) {
+ userEduRepository.updateGestureEduModel(gestureType) {
+ it.copy(signalCount = it.signalCount + 1)
+ }
+ }
+
+ override suspend fun updateShortcutTriggerTime(gestureType: GestureType) {
+ userEduRepository.updateGestureEduModel(gestureType) {
+ it.copy(lastShortcutTriggeredTime = clock.instant())
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt b/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt
new file mode 100644
index 000000000000..b7fc7733f3e6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright 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.education.data.repository
+
+import android.content.Context
+import androidx.datastore.core.DataStore
+import androidx.datastore.preferences.core.MutablePreferences
+import androidx.datastore.preferences.core.PreferenceDataStoreFactory
+import androidx.datastore.preferences.core.Preferences
+import androidx.datastore.preferences.core.edit
+import androidx.datastore.preferences.core.intPreferencesKey
+import androidx.datastore.preferences.core.longPreferencesKey
+import androidx.datastore.preferences.preferencesDataStoreFile
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.education.dagger.ContextualEducationModule.EduDataStoreScope
+import com.android.systemui.education.data.model.GestureEduModel
+import com.android.systemui.shared.education.GestureType
+import java.time.Instant
+import javax.inject.Inject
+import javax.inject.Provider
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
+
+/**
+ * A contextual education repository to:
+ * 1) store education data per user
+ * 2) provide methods to read and update data on model-level
+ * 3) provide method to enable changing datastore when user is changed
+ */
+@SysUISingleton
+class UserContextualEducationRepository
+@Inject
+constructor(
+ @Application private val applicationContext: Context,
+ @EduDataStoreScope private val dataStoreScopeProvider: Provider<CoroutineScope>
+) {
+ companion object {
+ const val SIGNAL_COUNT_SUFFIX = "_SIGNAL_COUNT"
+ const val NUMBER_OF_EDU_SHOWN_SUFFIX = "_NUMBER_OF_EDU_SHOWN"
+ const val LAST_SHORTCUT_TRIGGERED_TIME_SUFFIX = "_LAST_SHORTCUT_TRIGGERED_TIME"
+
+ const val DATASTORE_DIR = "education/USER%s_ContextualEducation"
+ }
+
+ private var dataStoreScope: CoroutineScope? = null
+
+ private val datastore = MutableStateFlow<DataStore<Preferences>?>(null)
+
+ @OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+ private val prefData: Flow<Preferences> = datastore.filterNotNull().flatMapLatest { it.data }
+
+ internal fun setUser(userId: Int) {
+ dataStoreScope?.cancel()
+ val newDsScope = dataStoreScopeProvider.get()
+ datastore.value =
+ PreferenceDataStoreFactory.create(
+ produceFile = {
+ applicationContext.preferencesDataStoreFile(
+ String.format(DATASTORE_DIR, userId)
+ )
+ },
+ scope = newDsScope,
+ )
+ dataStoreScope = newDsScope
+ }
+
+ internal fun readGestureEduModelFlow(gestureType: GestureType): Flow<GestureEduModel> =
+ prefData.map { preferences -> getGestureEduModel(gestureType, preferences) }
+
+ private fun getGestureEduModel(
+ gestureType: GestureType,
+ preferences: Preferences
+ ): GestureEduModel {
+ return GestureEduModel(
+ signalCount = preferences[getSignalCountKey(gestureType)] ?: 0,
+ educationShownCount = preferences[getEducationShownCountKey(gestureType)] ?: 0,
+ lastShortcutTriggeredTime =
+ preferences[getLastShortcutTriggeredTimeKey(gestureType)]?.let {
+ Instant.ofEpochMilli(it)
+ },
+ )
+ }
+
+ internal suspend fun updateGestureEduModel(
+ gestureType: GestureType,
+ transform: (GestureEduModel) -> GestureEduModel
+ ) {
+ datastore.filterNotNull().first().edit { preferences ->
+ val currentModel = getGestureEduModel(gestureType, preferences)
+ val updatedModel = transform(currentModel)
+ preferences[getSignalCountKey(gestureType)] = updatedModel.signalCount
+ preferences[getEducationShownCountKey(gestureType)] = updatedModel.educationShownCount
+ updateTimeByInstant(
+ preferences,
+ updatedModel.lastShortcutTriggeredTime,
+ getLastShortcutTriggeredTimeKey(gestureType)
+ )
+ }
+ }
+
+ private fun getSignalCountKey(gestureType: GestureType): Preferences.Key<Int> =
+ intPreferencesKey(gestureType.name + SIGNAL_COUNT_SUFFIX)
+
+ private fun getEducationShownCountKey(gestureType: GestureType): Preferences.Key<Int> =
+ intPreferencesKey(gestureType.name + NUMBER_OF_EDU_SHOWN_SUFFIX)
+
+ private fun getLastShortcutTriggeredTimeKey(gestureType: GestureType): Preferences.Key<Long> =
+ longPreferencesKey(gestureType.name + LAST_SHORTCUT_TRIGGERED_TIME_SUFFIX)
+
+ private fun updateTimeByInstant(
+ preferences: MutablePreferences,
+ instant: Instant?,
+ key: Preferences.Key<Long>
+ ) {
+ if (instant != null) {
+ preferences[key] = instant.toEpochMilli()
+ } else {
+ preferences.remove(key)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index 1e4fb4f15062..493afde96aff 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -64,7 +64,6 @@ import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
-import android.service.dreams.IDreamManager;
import android.sysprop.TelephonyProperties;
import android.telecom.TelecomManager;
import android.telephony.ServiceState;
@@ -197,7 +196,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
private final Context mContext;
private final GlobalActionsManager mWindowManagerFuncs;
private final AudioManager mAudioManager;
- private final IDreamManager mDreamManager;
private final DevicePolicyManager mDevicePolicyManager;
private final LockPatternUtils mLockPatternUtils;
private final SelectedUserInteractor mSelectedUserInteractor;
@@ -345,7 +343,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
Context context,
GlobalActionsManager windowManagerFuncs,
AudioManager audioManager,
- IDreamManager iDreamManager,
DevicePolicyManager devicePolicyManager,
LockPatternUtils lockPatternUtils,
BroadcastDispatcher broadcastDispatcher,
@@ -382,7 +379,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
mContext = context;
mWindowManagerFuncs = windowManagerFuncs;
mAudioManager = audioManager;
- mDreamManager = iDreamManager;
mDevicePolicyManager = devicePolicyManager;
mLockPatternUtils = lockPatternUtils;
mTelephonyListenerManager = telephonyListenerManager;
@@ -510,20 +506,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
mHandler.sendEmptyMessage(MESSAGE_DISMISS);
}
- protected void awakenIfNecessary() {
- if (mDreamManager != null) {
- try {
- if (mDreamManager.isDreaming()) {
- mDreamManager.awaken();
- }
- } catch (RemoteException e) {
- // we tried
- }
- }
- }
-
protected void handleShow(@Nullable Expandable expandable) {
- awakenIfNecessary();
mDialog = createDialog();
prepareDialog();
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
index 6cbe29ef6f7c..c44eb471d460 100644
--- a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
+++ b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
@@ -17,8 +17,10 @@
package com.android.systemui.haptics.qs
import android.os.VibrationEffect
+import android.service.quicksettings.Tile
import androidx.annotation.VisibleForTesting
import com.android.systemui.animation.Expandable
+import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -40,6 +42,7 @@ class QSLongPressEffect
constructor(
private val vibratorHelper: VibratorHelper?,
private val keyguardStateController: KeyguardStateController,
+ private val falsingManager: FalsingManager,
) {
var effectDuration = 0
@@ -130,18 +133,18 @@ constructor(
fun handleAnimationComplete() {
when (state) {
State.RUNNING_FORWARD -> {
- setState(State.IDLE)
vibrate(snapEffect)
if (keyguardStateController.isUnlocked) {
- qsTile?.longClick(expandable)
+ setState(State.LONG_CLICKED)
} else {
callback?.onResetProperties()
- qsTile?.longClick(expandable)
+ setState(State.IDLE)
}
+ qsTile?.longClick(expandable)
}
State.RUNNING_BACKWARDS_FROM_UP -> {
- setState(State.IDLE)
callback?.onEffectFinishedReversing()
+ setState(getStateForClick())
qsTile?.click(expandable)
}
State.RUNNING_BACKWARDS_FROM_CANCEL -> setState(State.IDLE)
@@ -160,14 +163,37 @@ constructor(
}
fun onTileClick(): Boolean {
- if (state == State.TIMEOUT_WAIT || state == State.IDLE) {
- setState(State.IDLE)
- qsTile?.let {
- it.click(expandable)
- return true
- }
+ val isStateClickable = state == State.TIMEOUT_WAIT || state == State.IDLE
+
+ // Ignore View-generated clicks on invalid states or if the bouncer is showing
+ if (keyguardStateController.isPrimaryBouncerShowing || !isStateClickable) return false
+
+ setState(getStateForClick())
+ qsTile?.click(expandable)
+ return true
+ }
+
+ /**
+ * Get the appropriate state for a click action.
+ *
+ * In some occasions, the click action will not result in a subsequent action that resets the
+ * state upon completion (e.g., a launch transition animation). In these cases, the state needs
+ * to be reset before the click is dispatched.
+ */
+ @VisibleForTesting
+ fun getStateForClick(): State {
+ val isTileUnavailable = qsTile?.state?.state == Tile.STATE_UNAVAILABLE
+ val isFalseTapWhileLocked =
+ !keyguardStateController.isUnlocked &&
+ falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)
+ val handlesLongClick = qsTile?.state?.handlesLongClick == true
+ return if (isTileUnavailable || isFalseTapWhileLocked || !handlesLongClick) {
+ // The click event will not perform an action that resets the state. Therefore, this is
+ // the last opportunity to reset the state back to IDLE.
+ State.IDLE
+ } else {
+ State.CLICKED
}
- return false
}
/**
@@ -194,6 +220,8 @@ constructor(
return true
}
+ fun resetState() = setState(State.IDLE)
+
enum class State {
IDLE, /* The effect is idle waiting for touch input */
TIMEOUT_WAIT, /* The effect is waiting for a tap timeout period */
@@ -202,6 +230,8 @@ constructor(
RUNNING_BACKWARDS_FROM_UP,
/* The effect was interrupted by an ACTION_CANCEL and is now running backwards */
RUNNING_BACKWARDS_FROM_CANCEL,
+ CLICKED, /* The effect has ended with a click */
+ LONG_CLICKED, /* The effect has ended with a long-click */
}
/** Callbacks to notify view and animator actions */
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/data/repository/InputDeviceRepository.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/data/repository/InputDeviceRepository.kt
new file mode 100644
index 000000000000..3b161b659af9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/data/repository/InputDeviceRepository.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.inputdevice.data.repository
+
+import android.annotation.SuppressLint
+import android.hardware.input.InputManager
+import android.os.Handler
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.SendChannel
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.shareIn
+
+@SysUISingleton
+class InputDeviceRepository
+@Inject
+constructor(
+ @Background private val backgroundHandler: Handler,
+ @Background private val backgroundScope: CoroutineScope,
+ private val inputManager: InputManager
+) {
+
+ sealed interface DeviceChange
+
+ data class DeviceAdded(val deviceId: Int) : DeviceChange
+
+ data object DeviceRemoved : DeviceChange
+
+ data object FreshStart : DeviceChange
+
+ /**
+ * Emits collection of all currently connected keyboards and what was the last [DeviceChange].
+ * It emits collection so that every new subscriber to this SharedFlow can get latest state of
+ * all keyboards. Otherwise we might get into situation where subscriber timing on
+ * initialization matter and later subscriber will only get latest device and will miss all
+ * previous devices.
+ */
+ // TODO(b/351984587): Replace with StateFlow
+ @SuppressLint("SharedFlowCreation")
+ val deviceChange: Flow<Pair<Collection<Int>, DeviceChange>> =
+ conflatedCallbackFlow {
+ var connectedDevices = inputManager.inputDeviceIds.toSet()
+ val listener =
+ object : InputManager.InputDeviceListener {
+ override fun onInputDeviceAdded(deviceId: Int) {
+ connectedDevices = connectedDevices + deviceId
+ sendWithLogging(connectedDevices to DeviceAdded(deviceId))
+ }
+
+ override fun onInputDeviceChanged(deviceId: Int) = Unit
+
+ override fun onInputDeviceRemoved(deviceId: Int) {
+ connectedDevices = connectedDevices - deviceId
+ sendWithLogging(connectedDevices to DeviceRemoved)
+ }
+ }
+ sendWithLogging(connectedDevices to FreshStart)
+ inputManager.registerInputDeviceListener(listener, backgroundHandler)
+ awaitClose { inputManager.unregisterInputDeviceListener(listener) }
+ }
+ .shareIn(
+ scope = backgroundScope,
+ started = SharingStarted.Lazily,
+ replay = 1,
+ )
+
+ private fun <T> SendChannel<T>.sendWithLogging(element: T) {
+ trySendWithFailureLogging(element, TAG)
+ }
+
+ companion object {
+ const val TAG = "InputDeviceRepository"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt
index 91d528074723..817849c41297 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt
@@ -21,21 +21,23 @@ import android.hardware.input.InputManager
import android.hardware.input.InputManager.KeyboardBacklightListener
import android.hardware.input.KeyboardBacklightState
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository.DeviceAdded
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository.DeviceChange
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository.DeviceRemoved
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository.FreshStart
import com.android.systemui.keyboard.data.model.Keyboard
import com.android.systemui.keyboard.shared.model.BacklightModel
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import java.util.concurrent.Executor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.emptyFlow
@@ -44,7 +46,6 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
-import kotlinx.coroutines.flow.shareIn
/**
* Provides information about physical keyboard states. [CommandLineKeyboardRepository] can be
@@ -71,50 +72,15 @@ interface KeyboardRepository {
class KeyboardRepositoryImpl
@Inject
constructor(
- @Application private val applicationScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
private val inputManager: InputManager,
+ inputDeviceRepository: InputDeviceRepository
) : KeyboardRepository {
- private sealed interface DeviceChange
- private data class DeviceAdded(val deviceId: Int) : DeviceChange
- private object DeviceRemoved : DeviceChange
- private object FreshStart : DeviceChange
-
- /**
- * Emits collection of all currently connected keyboards and what was the last [DeviceChange].
- * It emits collection so that every new subscriber to this SharedFlow can get latest state of
- * all keyboards. Otherwise we might get into situation where subscriber timing on
- * initialization matter and later subscriber will only get latest device and will miss all
- * previous devices.
- */
private val keyboardsChange: Flow<Pair<Collection<Int>, DeviceChange>> =
- conflatedCallbackFlow {
- var connectedDevices = inputManager.inputDeviceIds.toSet()
- val listener =
- object : InputManager.InputDeviceListener {
- override fun onInputDeviceAdded(deviceId: Int) {
- connectedDevices = connectedDevices + deviceId
- sendWithLogging(connectedDevices to DeviceAdded(deviceId))
- }
-
- override fun onInputDeviceChanged(deviceId: Int) = Unit
-
- override fun onInputDeviceRemoved(deviceId: Int) {
- connectedDevices = connectedDevices - deviceId
- sendWithLogging(connectedDevices to DeviceRemoved)
- }
- }
- sendWithLogging(connectedDevices to FreshStart)
- inputManager.registerInputDeviceListener(listener, /* handler= */ null)
- awaitClose { inputManager.unregisterInputDeviceListener(listener) }
- }
- .map { (ids, change) -> ids.filter { id -> isPhysicalFullKeyboard(id) } to change }
- .shareIn(
- scope = applicationScope,
- started = SharingStarted.Lazily,
- replay = 1,
- )
+ inputDeviceRepository.deviceChange.map { (ids, change) ->
+ ids.filter { id -> isPhysicalFullKeyboard(id) } to change
+ }
@FlowPreview
override val newlyConnectedKeyboard: Flow<Keyboard> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
index 8a40c0326523..906f600e3826 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
@@ -20,6 +20,17 @@ import android.app.Activity
import com.android.systemui.CoreStartable
import com.android.systemui.Flags.keyboardShortcutHelperRewrite
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
+import com.android.systemui.keyboard.shortcut.data.source.AppCategoriesShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.CurrentAppShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.InputShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
+import com.android.systemui.keyboard.shortcut.qualifiers.AppCategoriesShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.CurrentAppShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.InputShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts
import com.android.systemui.keyboard.shortcut.ui.ShortcutHelperActivityStarter
import com.android.systemui.keyboard.shortcut.ui.view.ShortcutHelperActivity
import dagger.Binds
@@ -37,6 +48,28 @@ interface ShortcutHelperModule {
@ClassKey(ShortcutHelperActivity::class)
fun activity(impl: ShortcutHelperActivity): Activity
+ @Binds
+ @SystemShortcuts
+ fun systemShortcutsSource(impl: SystemShortcutsSource): KeyboardShortcutGroupsSource
+
+ @Binds
+ @MultitaskingShortcuts
+ fun multitaskingShortcutsSource(impl: MultitaskingShortcutsSource): KeyboardShortcutGroupsSource
+
+ @Binds
+ @CurrentAppShortcuts
+ fun currentAppShortcutsSource(impl: CurrentAppShortcutsSource): KeyboardShortcutGroupsSource
+
+ @Binds
+ @InputShortcuts
+ fun inputShortcutsSources(impl: InputShortcutsSource): KeyboardShortcutGroupsSource
+
+ @Binds
+ @AppCategoriesShortcuts
+ fun appCategoriesShortcutsSource(
+ impl: AppCategoriesShortcutsSource
+ ): KeyboardShortcutGroupsSource
+
companion object {
@Provides
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/KeyboardShortcutInfo.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/KeyboardShortcutInfo.kt
new file mode 100644
index 000000000000..8e94901c1698
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/KeyboardShortcutInfo.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.keyboard.shortcut.data.model
+
+import android.view.KeyboardShortcutInfo
+
+class KeyboardShortcutInfoBuilder(val label: String) {
+
+ private var modifiers = 0
+ private var keyCode = 0
+
+ fun command(modifiers: Int, keyCode: Int = 0) {
+ this.modifiers = modifiers
+ this.keyCode = keyCode
+ }
+
+ fun build() = KeyboardShortcutInfo(label, keyCode, modifiers)
+}
+
+fun shortcutInfo(label: String, block: KeyboardShortcutInfoBuilder.() -> Unit) =
+ KeyboardShortcutInfoBuilder(label).apply(block).build()
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt
index c00bd6ff93b0..495e8f322f00 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt
@@ -16,93 +16,261 @@
package com.android.systemui.keyboard.shortcut.data.repository
+import android.content.Context
+import android.graphics.drawable.Icon
+import android.hardware.input.InputManager
+import android.util.Log
+import android.view.InputDevice
+import android.view.KeyCharacterMap
import android.view.KeyEvent
import android.view.KeyboardShortcutGroup
import android.view.KeyboardShortcutInfo
-import android.view.WindowManager
-import android.view.WindowManager.KeyboardShortcutsReceiver
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource
-import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.qualifiers.AppCategoriesShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.CurrentAppShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.InputShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts
import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.AppCategories
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.CurrentApp
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.InputMethodEditor
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.System
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active
-import com.android.systemui.keyboard.shortcut.shared.model.shortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.suspendCancellableCoroutine
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.withContext
@SysUISingleton
class ShortcutHelperCategoriesRepository
@Inject
constructor(
- private val systemShortcutsSource: SystemShortcutsSource,
- private val multitaskingShortcutsSource: MultitaskingShortcutsSource,
- private val windowManager: WindowManager,
- shortcutHelperStateRepository: ShortcutHelperStateRepository
+ private val context: Context,
+ @Background private val backgroundScope: CoroutineScope,
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
+ @SystemShortcuts private val systemShortcutsSource: KeyboardShortcutGroupsSource,
+ @MultitaskingShortcuts private val multitaskingShortcutsSource: KeyboardShortcutGroupsSource,
+ @AppCategoriesShortcuts private val appCategoriesShortcutsSource: KeyboardShortcutGroupsSource,
+ @InputShortcuts private val inputShortcutsSource: KeyboardShortcutGroupsSource,
+ @CurrentAppShortcuts private val currentAppShortcutsSource: KeyboardShortcutGroupsSource,
+ private val inputManager: InputManager,
+ stateRepository: ShortcutHelperStateRepository
) {
- val systemShortcutsCategory =
- shortcutHelperStateRepository.state.map {
- if (it is Active) systemShortcutsSource.systemShortcutsCategory() else null
+ private val activeInputDevice =
+ stateRepository.state.map {
+ if (it is Active) {
+ withContext(backgroundDispatcher) { inputManager.getInputDevice(it.deviceId) }
+ } else {
+ null
+ }
}
- val multitaskingShortcutsCategory =
- shortcutHelperStateRepository.state.map {
- if (it is Active) multitaskingShortcutsSource.multitaskingShortcutCategory() else null
- }
+ val categories: Flow<List<ShortcutCategory>> =
+ activeInputDevice
+ .map {
+ if (it == null) {
+ return@map emptyList()
+ }
+ return@map listOfNotNull(
+ fetchSystemShortcuts(it),
+ fetchMultiTaskingShortcuts(it),
+ fetchAppCategoriesShortcuts(it),
+ fetchImeShortcuts(it),
+ fetchCurrentAppShortcuts(it),
+ )
+ }
+ .stateIn(
+ scope = backgroundScope,
+ started = SharingStarted.Lazily,
+ initialValue = emptyList(),
+ )
+
+ private suspend fun fetchSystemShortcuts(inputDevice: InputDevice) =
+ toShortcutCategory(
+ inputDevice.keyCharacterMap,
+ System,
+ systemShortcutsSource.shortcutGroups(inputDevice.id),
+ keepIcons = true,
+ )
+
+ private suspend fun fetchMultiTaskingShortcuts(inputDevice: InputDevice) =
+ toShortcutCategory(
+ inputDevice.keyCharacterMap,
+ MultiTasking,
+ multitaskingShortcutsSource.shortcutGroups(inputDevice.id),
+ keepIcons = true,
+ )
+
+ private suspend fun fetchAppCategoriesShortcuts(inputDevice: InputDevice) =
+ toShortcutCategory(
+ inputDevice.keyCharacterMap,
+ AppCategories,
+ appCategoriesShortcutsSource.shortcutGroups(inputDevice.id),
+ keepIcons = true,
+ )
+
+ private suspend fun fetchImeShortcuts(inputDevice: InputDevice) =
+ toShortcutCategory(
+ inputDevice.keyCharacterMap,
+ InputMethodEditor,
+ inputShortcutsSource.shortcutGroups(inputDevice.id),
+ keepIcons = false,
+ )
- val imeShortcutsCategory =
- shortcutHelperStateRepository.state.map {
- if (it is Active) retrieveImeShortcuts(it.deviceId) else null
+ private suspend fun fetchCurrentAppShortcuts(inputDevice: InputDevice): ShortcutCategory? {
+ val shortcutGroups = currentAppShortcutsSource.shortcutGroups(inputDevice.id)
+ val categoryType = getCurrentAppShortcutCategoryType(shortcutGroups)
+ return if (categoryType == null) {
+ null
+ } else {
+ toShortcutCategory(
+ inputDevice.keyCharacterMap,
+ categoryType,
+ shortcutGroups,
+ keepIcons = false
+ )
}
+ }
- private suspend fun retrieveImeShortcuts(deviceId: Int): ShortcutCategory {
- return suspendCancellableCoroutine { continuation ->
- val shortcutsReceiver = KeyboardShortcutsReceiver { shortcutGroups ->
- continuation.resumeWith(Result.success(toShortcutCategory(shortcutGroups)))
- }
- windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, deviceId)
+ private fun getCurrentAppShortcutCategoryType(
+ shortcutGroups: List<KeyboardShortcutGroup>
+ ): ShortcutCategoryType? {
+ return if (shortcutGroups.isEmpty()) {
+ null
+ } else {
+ CurrentApp(packageName = shortcutGroups[0].packageName.toString())
}
}
- private fun toShortcutCategory(shortcutGroups: List<KeyboardShortcutGroup>) =
- shortcutCategory(ShortcutCategoryType.IME) {
- shortcutGroups.map { shortcutGroup ->
- subCategory(shortcutGroup.label.toString(), toShortcuts(shortcutGroup.items))
- }
+ private fun toShortcutCategory(
+ keyCharacterMap: KeyCharacterMap,
+ type: ShortcutCategoryType,
+ shortcutGroups: List<KeyboardShortcutGroup>,
+ keepIcons: Boolean,
+ ): ShortcutCategory? {
+ val subCategories =
+ shortcutGroups
+ .map { shortcutGroup ->
+ ShortcutSubCategory(
+ shortcutGroup.label.toString(),
+ toShortcuts(keyCharacterMap, shortcutGroup.items, keepIcons)
+ )
+ }
+ .filter { it.shortcuts.isNotEmpty() }
+ return if (subCategories.isEmpty()) {
+ Log.wtf(TAG, "Empty sub categories after converting $shortcutGroups")
+ null
+ } else {
+ ShortcutCategory(type, subCategories)
}
+ }
- private fun toShortcuts(infoList: List<KeyboardShortcutInfo>) =
- infoList.mapNotNull { toShortcut(it) }
+ private fun toShortcuts(
+ keyCharacterMap: KeyCharacterMap,
+ infoList: List<KeyboardShortcutInfo>,
+ keepIcons: Boolean,
+ ) = infoList.mapNotNull { toShortcut(keyCharacterMap, it, keepIcons) }
- private fun toShortcut(shortcutInfo: KeyboardShortcutInfo): Shortcut? {
- val shortcutCommand = toShortcutCommand(shortcutInfo)
- return if (shortcutCommand == null) null
- else Shortcut(label = shortcutInfo.label!!.toString(), commands = listOf(shortcutCommand))
+ private fun toShortcut(
+ keyCharacterMap: KeyCharacterMap,
+ shortcutInfo: KeyboardShortcutInfo,
+ keepIcon: Boolean,
+ ): Shortcut? {
+ val shortcutCommand = toShortcutCommand(keyCharacterMap, shortcutInfo) ?: return null
+ return Shortcut(
+ label = shortcutInfo.label!!.toString(),
+ icon = toShortcutIcon(keepIcon, shortcutInfo),
+ commands = listOf(shortcutCommand)
+ )
}
- private fun toShortcutCommand(info: KeyboardShortcutInfo): ShortcutCommand? {
- val keyCodes = mutableListOf<Int>()
+ private fun toShortcutIcon(
+ keepIcon: Boolean,
+ shortcutInfo: KeyboardShortcutInfo
+ ): ShortcutIcon? {
+ if (!keepIcon) {
+ return null
+ }
+ val icon = shortcutInfo.icon ?: return null
+ // For now only keep icons of type resource, which is what the "default apps" shortcuts
+ // provide.
+ if (icon.type != Icon.TYPE_RESOURCE || icon.resPackage.isNullOrEmpty() || icon.resId <= 0) {
+ return null
+ }
+ return ShortcutIcon(packageName = icon.resPackage, resourceId = icon.resId)
+ }
+
+ private fun toShortcutCommand(
+ keyCharacterMap: KeyCharacterMap,
+ info: KeyboardShortcutInfo
+ ): ShortcutCommand? {
+ val keys = mutableListOf<ShortcutKey>()
var remainingModifiers = info.modifiers
SUPPORTED_MODIFIERS.forEach { supportedModifier ->
if ((supportedModifier and remainingModifiers) != 0) {
- keyCodes += supportedModifier
+ keys += toShortcutKey(keyCharacterMap, supportedModifier) ?: return null
// "Remove" the modifier from the remaining modifiers
remainingModifiers = remainingModifiers and supportedModifier.inv()
}
}
if (remainingModifiers != 0) {
// There is a remaining modifier we don't support
+ Log.wtf(TAG, "Unsupported modifiers remaining: $remainingModifiers")
+ return null
+ }
+ if (info.keycode != 0 || info.baseCharacter > Char.MIN_VALUE) {
+ keys += toShortcutKey(keyCharacterMap, info.keycode, info.baseCharacter) ?: return null
+ }
+ if (keys.isEmpty()) {
+ Log.wtf(TAG, "No keys for $info")
return null
}
- keyCodes += info.keycode
- return ShortcutCommand(keyCodes)
+ return ShortcutCommand(keys)
+ }
+
+ private fun toShortcutKey(
+ keyCharacterMap: KeyCharacterMap,
+ keyCode: Int,
+ baseCharacter: Char = Char.MIN_VALUE,
+ ): ShortcutKey? {
+ val iconResId = ShortcutHelperKeys.keyIcons[keyCode]
+ if (iconResId != null) {
+ return ShortcutKey.Icon(iconResId)
+ }
+ if (baseCharacter > Char.MIN_VALUE) {
+ return ShortcutKey.Text(baseCharacter.uppercase())
+ }
+ val specialKeyLabel = ShortcutHelperKeys.specialKeyLabels[keyCode]
+ if (specialKeyLabel != null) {
+ val label = specialKeyLabel(context)
+ return ShortcutKey.Text(label)
+ }
+ val displayLabelCharacter = keyCharacterMap.getDisplayLabel(keyCode)
+ if (displayLabelCharacter.code != 0) {
+ return ShortcutKey.Text(displayLabelCharacter.toString())
+ }
+ Log.wtf(TAG, "Couldn't find label or icon for key: $keyCode")
+ return null
}
companion object {
+ private const val TAG = "SHCategoriesRepo"
+
private val SUPPORTED_MODIFIERS =
listOf(
KeyEvent.META_META_ON,
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
index 0aced8c95662..cbe6fc7c6026 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
@@ -222,7 +222,7 @@ object ShortcutHelperKeys {
{ context ->
context.getString(R.string.keyboard_key_forward_del)
},
- KEYCODE_ESCAPE to { "Esc" },
+ KEYCODE_ESCAPE to { context -> context.getString(R.string.keyboard_key_esc) },
KEYCODE_SYSRQ to { "SysRq" },
KEYCODE_BREAK to { "Break" },
KEYCODE_SCROLL_LOCK to { "Scroll Lock" },
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSource.kt
new file mode 100644
index 000000000000..d6c6d5b3a83c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSource.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.keyboard.shortcut.data.source
+
+import android.view.KeyboardShortcutGroup
+import android.view.WindowManager
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyboard.shortcut.extensions.copy
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.withContext
+
+class AppCategoriesShortcutsSource
+@Inject
+constructor(
+ private val windowManager: WindowManager,
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
+) : KeyboardShortcutGroupsSource {
+
+ override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> =
+ withContext(backgroundDispatcher) {
+ val group = windowManager.getApplicationLaunchKeyboardShortcuts(deviceId)
+ return@withContext if (group == null) {
+ emptyList()
+ } else {
+ val sortedShortcutItems = group.items.sortedBy { it.label!!.toString().lowercase() }
+ listOf(group.copy(items = sortedShortcutItems))
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/CurrentAppShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/CurrentAppShortcutsSource.kt
new file mode 100644
index 000000000000..7e6ed19d6070
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/CurrentAppShortcutsSource.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.keyboard.shortcut.data.source
+
+import android.view.KeyboardShortcutGroup
+import android.view.WindowManager
+import android.view.WindowManager.KeyboardShortcutsReceiver
+import javax.inject.Inject
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+class CurrentAppShortcutsSource @Inject constructor(private val windowManager: WindowManager) :
+ KeyboardShortcutGroupsSource {
+ override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> =
+ suspendCancellableCoroutine { continuation ->
+ val shortcutsReceiver = KeyboardShortcutsReceiver {
+ continuation.resumeWith(Result.success(it ?: emptyList()))
+ }
+ windowManager.requestAppKeyboardShortcuts(shortcutsReceiver, deviceId)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt
new file mode 100644
index 000000000000..1b2098650278
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt
@@ -0,0 +1,66 @@
+/*
+ * 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.keyboard.shortcut.data.source
+
+import android.content.res.Resources
+import android.view.KeyEvent.KEYCODE_SPACE
+import android.view.KeyEvent.META_CTRL_ON
+import android.view.KeyEvent.META_SHIFT_ON
+import android.view.KeyboardShortcutGroup
+import android.view.WindowManager
+import android.view.WindowManager.KeyboardShortcutsReceiver
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
+import com.android.systemui.res.R
+import javax.inject.Inject
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+class InputShortcutsSource
+@Inject
+constructor(@Main private val resources: Resources, private val windowManager: WindowManager) :
+ KeyboardShortcutGroupsSource {
+ override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> =
+ getInputLanguageShortcutGroup() + getImeShortcutGroup(deviceId)
+
+ private fun getInputLanguageShortcutGroup() =
+ listOf(
+ KeyboardShortcutGroup(
+ resources.getString(R.string.shortcut_helper_category_input),
+ inputLanguageShortcuts()
+ )
+ )
+
+ private fun inputLanguageShortcuts() =
+ listOf(
+ /* Switch input language (next language): Ctrl + Space */
+ shortcutInfo(resources.getString(R.string.input_switch_input_language_next)) {
+ command(META_CTRL_ON, KEYCODE_SPACE)
+ },
+ /* Switch previous language (next language): Ctrl + Shift + Space */
+ shortcutInfo(resources.getString(R.string.input_switch_input_language_previous)) {
+ command(META_CTRL_ON or META_SHIFT_ON, KEYCODE_SPACE)
+ }
+ )
+
+ private suspend fun getImeShortcutGroup(deviceId: Int): List<KeyboardShortcutGroup> =
+ suspendCancellableCoroutine { continuation ->
+ val shortcutsReceiver = KeyboardShortcutsReceiver {
+ continuation.resumeWith(Result.success(it ?: emptyList()))
+ }
+ windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, deviceId)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt
new file mode 100644
index 000000000000..39d03771ecf4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.keyboard.shortcut.data.source
+
+import android.view.KeyboardShortcutGroup
+
+interface KeyboardShortcutGroupsSource {
+
+ suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
index 7b64f872b064..eddac4d4ad73 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
@@ -25,53 +25,53 @@ import android.view.KeyEvent.META_ALT_ON
import android.view.KeyEvent.META_CTRL_ON
import android.view.KeyEvent.META_META_ON
import android.view.KeyEvent.META_SHIFT_ON
+import android.view.KeyboardShortcutGroup
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MULTI_TASKING
-import com.android.systemui.keyboard.shortcut.shared.model.shortcut
-import com.android.systemui.keyboard.shortcut.shared.model.shortcutCategory
+import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
import com.android.systemui.res.R
import javax.inject.Inject
-class MultitaskingShortcutsSource @Inject constructor(@Main private val resources: Resources) {
+class MultitaskingShortcutsSource @Inject constructor(@Main private val resources: Resources) :
+ KeyboardShortcutGroupsSource {
- fun multitaskingShortcutCategory() =
- shortcutCategory(MULTI_TASKING) {
- subCategory(
+ override suspend fun shortcutGroups(deviceId: Int) =
+ listOf(
+ KeyboardShortcutGroup(
resources.getString(R.string.shortcutHelper_category_recent_apps),
recentsShortcuts()
- )
- subCategory(
+ ),
+ KeyboardShortcutGroup(
resources.getString(R.string.shortcutHelper_category_split_screen),
splitScreenShortcuts()
)
- }
+ )
private fun splitScreenShortcuts() =
listOf(
// Enter Split screen with current app to RHS:
// - Meta + Ctrl + Right arrow
- shortcut(resources.getString(R.string.system_multitasking_rhs)) {
- command(META_META_ON, META_CTRL_ON, KEYCODE_DPAD_RIGHT)
+ shortcutInfo(resources.getString(R.string.system_multitasking_rhs)) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_RIGHT)
},
// Enter Split screen with current app to LHS:
// - Meta + Ctrl + Left arrow
- shortcut(resources.getString(R.string.system_multitasking_lhs)) {
- command(META_META_ON, META_CTRL_ON, KEYCODE_DPAD_LEFT)
+ shortcutInfo(resources.getString(R.string.system_multitasking_lhs)) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_LEFT)
},
// Switch from Split screen to full screen:
// - Meta + Ctrl + Up arrow
- shortcut(resources.getString(R.string.system_multitasking_full_screen)) {
- command(META_META_ON, META_CTRL_ON, KEYCODE_DPAD_UP)
+ shortcutInfo(resources.getString(R.string.system_multitasking_full_screen)) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_UP)
},
// Change split screen focus to RHS:
// - Meta + Alt + Right arrow
- shortcut(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
- command(META_META_ON, META_ALT_ON, KEYCODE_DPAD_RIGHT)
+ shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
+ command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_RIGHT)
},
// Change split screen focus to LHS:
// - Meta + Alt + Left arrow
- shortcut(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
- command(META_META_ON, META_ALT_ON, KEYCODE_DPAD_LEFT)
+ shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
+ command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_LEFT)
},
)
@@ -79,13 +79,13 @@ class MultitaskingShortcutsSource @Inject constructor(@Main private val resource
listOf(
// Cycle through recent apps (forward):
// - Alt + Tab
- shortcut(resources.getString(R.string.group_system_cycle_forward)) {
+ shortcutInfo(resources.getString(R.string.group_system_cycle_forward)) {
command(META_ALT_ON, KEYCODE_TAB)
},
// Cycle through recent apps (back):
// - Shift + Alt + Tab
- shortcut(resources.getString(R.string.group_system_cycle_back)) {
- command(META_SHIFT_ON, META_ALT_ON, KEYCODE_TAB)
+ shortcutInfo(resources.getString(R.string.group_system_cycle_back)) {
+ command(META_SHIFT_ON or META_ALT_ON, KEYCODE_TAB)
},
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt
index 51c67dfdcb4d..e55e339704ee 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt
@@ -31,73 +31,79 @@ import android.view.KeyEvent.KEYCODE_SLASH
import android.view.KeyEvent.KEYCODE_TAB
import android.view.KeyEvent.META_CTRL_ON
import android.view.KeyEvent.META_META_ON
+import android.view.KeyboardShortcutGroup
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.SYSTEM
-import com.android.systemui.keyboard.shortcut.shared.model.shortcut
-import com.android.systemui.keyboard.shortcut.shared.model.shortcutCategory
+import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
import com.android.systemui.res.R
import javax.inject.Inject
-class SystemShortcutsSource @Inject constructor(@Main private val resources: Resources) {
+class SystemShortcutsSource @Inject constructor(@Main private val resources: Resources) :
+ KeyboardShortcutGroupsSource {
- fun systemShortcutsCategory() =
- shortcutCategory(SYSTEM) {
- subCategory(
+ override suspend fun shortcutGroups(deviceId: Int) =
+ listOf(
+ KeyboardShortcutGroup(
resources.getString(R.string.shortcut_helper_category_system_controls),
systemControlsShortcuts()
- )
- subCategory(
+ ),
+ KeyboardShortcutGroup(
resources.getString(R.string.shortcut_helper_category_system_apps),
systemAppsShortcuts()
)
- }
+ )
private fun systemControlsShortcuts() =
listOf(
// Access list of all apps and search (i.e. Search/Launcher):
// - Meta
- shortcut(resources.getString(R.string.group_system_access_all_apps_search)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_all_apps_search)) {
command(META_META_ON)
},
// Access home screen:
// - Meta + H
// - Meta + Enter
- shortcut(resources.getString(R.string.group_system_access_home_screen)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_home_screen)) {
command(META_META_ON, KEYCODE_H)
+ },
+ shortcutInfo(resources.getString(R.string.group_system_access_home_screen)) {
command(META_META_ON, KEYCODE_ENTER)
},
// Overview of open apps:
// - Meta + Tab
- shortcut(resources.getString(R.string.group_system_overview_open_apps)) {
+ shortcutInfo(resources.getString(R.string.group_system_overview_open_apps)) {
command(META_META_ON, KEYCODE_TAB)
},
// Back: go back to previous state (back button)
// - Meta + Escape OR
// - Meta + Backspace OR
// - Meta + Left arrow
- shortcut(resources.getString(R.string.group_system_go_back)) {
+ shortcutInfo(resources.getString(R.string.group_system_go_back)) {
command(META_META_ON, KEYCODE_ESCAPE)
+ },
+ shortcutInfo(resources.getString(R.string.group_system_go_back)) {
command(META_META_ON, KEYCODE_DEL)
+ },
+ shortcutInfo(resources.getString(R.string.group_system_go_back)) {
command(META_META_ON, KEYCODE_DPAD_LEFT)
},
// Take a full screenshot:
// - Meta + Ctrl + S
- shortcut(resources.getString(R.string.group_system_full_screenshot)) {
- command(META_META_ON, META_CTRL_ON, KEYCODE_S)
+ shortcutInfo(resources.getString(R.string.group_system_full_screenshot)) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_S)
},
// Access list of system / apps shortcuts:
// - Meta + /
- shortcut(resources.getString(R.string.group_system_access_system_app_shortcuts)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_system_app_shortcuts)) {
command(META_META_ON, KEYCODE_SLASH)
},
// Access notification shade:
// - Meta + N
- shortcut(resources.getString(R.string.group_system_access_notification_shade)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_notification_shade)) {
command(META_META_ON, KEYCODE_N)
},
// Lock screen:
// - Meta + L
- shortcut(resources.getString(R.string.group_system_lock_screen)) {
+ shortcutInfo(resources.getString(R.string.group_system_lock_screen)) {
command(META_META_ON, KEYCODE_L)
},
)
@@ -106,17 +112,17 @@ class SystemShortcutsSource @Inject constructor(@Main private val resources: Res
listOf(
// Pull up Notes app for quick memo:
// - Meta + Ctrl + N
- shortcut(resources.getString(R.string.group_system_quick_memo)) {
- command(META_META_ON, META_CTRL_ON, KEYCODE_N)
+ shortcutInfo(resources.getString(R.string.group_system_quick_memo)) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_N)
},
// Access system settings:
// - Meta + I
- shortcut(resources.getString(R.string.group_system_access_system_settings)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_system_settings)) {
command(META_META_ON, KEYCODE_I)
},
// Access Assistant:
// - Meta + A
- shortcut(resources.getString(R.string.group_system_access_google_assistant)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_google_assistant)) {
command(META_META_ON, KEYCODE_A)
},
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
index 57d4b4a02fce..6f19561dd87b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
@@ -23,7 +23,6 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
@SysUISingleton
@@ -33,23 +32,12 @@ constructor(
categoriesRepository: ShortcutHelperCategoriesRepository,
) {
- private val systemsShortcutCategory = categoriesRepository.systemShortcutsCategory
- private val multitaskingShortcutsCategory = categoriesRepository.multitaskingShortcutsCategory
- private val imeShortcutsCategory =
- categoriesRepository.imeShortcutsCategory.map { groupSubCategoriesInCategory(it) }
-
val shortcutCategories: Flow<List<ShortcutCategory>> =
- combine(systemsShortcutCategory, multitaskingShortcutsCategory, imeShortcutsCategory) {
- shortcutCategories ->
- shortcutCategories.filterNotNull()
+ categoriesRepository.categories.map { categories ->
+ categories.map { category -> groupSubCategoriesInCategory(category) }
}
- private fun groupSubCategoriesInCategory(
- shortcutCategory: ShortcutCategory?
- ): ShortcutCategory? {
- if (shortcutCategory == null) {
- return null
- }
+ private fun groupSubCategoriesInCategory(shortcutCategory: ShortcutCategory): ShortcutCategory {
val subCategoriesWithGroupedShortcuts =
shortcutCategory.subCategories.map {
ShortcutSubCategory(
@@ -68,6 +56,10 @@ constructor(
.groupBy { it.label }
.entries
.map { (commonLabel, groupedShortcuts) ->
- Shortcut(label = commonLabel, commands = groupedShortcuts.flatMap { it.commands })
+ Shortcut(
+ label = commonLabel,
+ icon = groupedShortcuts.firstOrNull()?.icon,
+ commands = groupedShortcuts.flatMap { it.commands }
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/extensions/KeyboardShortcutGroupExtensions.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/extensions/KeyboardShortcutGroupExtensions.kt
new file mode 100644
index 000000000000..3a120bdcc9c0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/extensions/KeyboardShortcutGroupExtensions.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.keyboard.shortcut.extensions
+
+import android.view.KeyboardShortcutGroup
+import android.view.KeyboardShortcutInfo
+
+fun KeyboardShortcutGroup.copy(
+ label: CharSequence = getLabel(),
+ items: List<KeyboardShortcutInfo> = getItems(),
+ isSystemGroup: Boolean = isSystemGroup(),
+ packageName: CharSequence? = getPackageName(),
+) = KeyboardShortcutGroup(label, items, isSystemGroup).also { it.packageName = packageName }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/AppCategoriesShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/AppCategoriesShortcuts.kt
new file mode 100644
index 000000000000..b105ff67beaa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/AppCategoriesShortcuts.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class AppCategoriesShortcuts
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/CurrentAppShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/CurrentAppShortcuts.kt
new file mode 100644
index 000000000000..51631b11b27c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/CurrentAppShortcuts.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class CurrentAppShortcuts
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/InputShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/InputShortcuts.kt
new file mode 100644
index 000000000000..f8a4a49cc3ce
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/InputShortcuts.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class InputShortcuts
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/MultitaskingShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/MultitaskingShortcuts.kt
new file mode 100644
index 000000000000..479299c519c9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/MultitaskingShortcuts.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class MultitaskingShortcuts
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/SystemShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/SystemShortcuts.kt
new file mode 100644
index 000000000000..1bcc2b8568c6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/SystemShortcuts.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class SystemShortcuts
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt
index e5b870a983c6..5f8570cba7a6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt
@@ -16,13 +16,17 @@
package com.android.systemui.keyboard.shortcut.shared.model
-data class Shortcut(val label: String, val commands: List<ShortcutCommand>)
+data class Shortcut(
+ val label: String,
+ val commands: List<ShortcutCommand>,
+ val icon: ShortcutIcon? = null,
+)
class ShortcutBuilder(private val label: String) {
val commands = mutableListOf<ShortcutCommand>()
- fun command(vararg keyCodes: Int) {
- commands += ShortcutCommand(keyCodes.toList())
+ fun command(builder: ShortcutCommandBuilder.() -> Unit) {
+ commands += ShortcutCommandBuilder().apply(builder).build()
}
fun build() = Shortcut(label, commands)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
index 3ac7fa8f8ece..4eabefcd2d41 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
@@ -16,10 +16,16 @@
package com.android.systemui.keyboard.shortcut.shared.model
-enum class ShortcutCategoryType {
- SYSTEM,
- MULTI_TASKING,
- IME
+sealed interface ShortcutCategoryType {
+ data object System : ShortcutCategoryType
+
+ data object MultiTasking : ShortcutCategoryType
+
+ data object InputMethodEditor : ShortcutCategoryType
+
+ data object AppCategories : ShortcutCategoryType
+
+ data class CurrentApp(val packageName: String) : ShortcutCategoryType
}
data class ShortcutCategory(
@@ -30,8 +36,8 @@ data class ShortcutCategory(
class ShortcutCategoryBuilder(val type: ShortcutCategoryType) {
private val subCategories = mutableListOf<ShortcutSubCategory>()
- fun subCategory(label: String, shortcuts: List<Shortcut>) {
- subCategories += ShortcutSubCategory(label, shortcuts)
+ fun subCategory(label: String, builder: ShortcutSubCategoryBuilder.() -> Unit) {
+ subCategories += ShortcutSubCategoryBuilder(label).apply(builder).build()
}
fun build() = ShortcutCategory(type, subCategories)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCommand.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCommand.kt
index a98a8ffb7004..e5b8096f2403 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCommand.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCommand.kt
@@ -16,4 +16,23 @@
package com.android.systemui.keyboard.shortcut.shared.model
-data class ShortcutCommand(val keyCodes: List<Int>)
+import androidx.annotation.DrawableRes
+
+data class ShortcutCommand(val keys: List<ShortcutKey>)
+
+class ShortcutCommandBuilder {
+ private val keys = mutableListOf<ShortcutKey>()
+
+ fun key(text: String) {
+ keys += ShortcutKey.Text(text)
+ }
+
+ fun key(@DrawableRes drawableResId: Int) {
+ keys += ShortcutKey.Icon(drawableResId)
+ }
+
+ fun build() = ShortcutCommand(keys)
+}
+
+fun shortcutCommand(block: ShortcutCommandBuilder.() -> Unit) =
+ ShortcutCommandBuilder().apply(block).build()
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutIcon.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutIcon.kt
new file mode 100644
index 000000000000..8b720a5a44eb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutIcon.kt
@@ -0,0 +1,19 @@
+/*
+ * 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.keyboard.shortcut.shared.model
+
+data class ShortcutIcon(val packageName: String, val resourceId: Int)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutKey.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutKey.kt
new file mode 100644
index 000000000000..1abb78c54b99
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutKey.kt
@@ -0,0 +1,25 @@
+/*
+ * 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.keyboard.shortcut.shared.model
+
+import androidx.annotation.DrawableRes
+
+sealed interface ShortcutKey {
+ data class Text(val value: String) : ShortcutKey
+
+ data class Icon(@DrawableRes val drawableResId: Int) : ShortcutKey
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutSubCategory.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutSubCategory.kt
index 4545b4c5dd28..14016783a478 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutSubCategory.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutSubCategory.kt
@@ -17,3 +17,13 @@
package com.android.systemui.keyboard.shortcut.shared.model
data class ShortcutSubCategory(val label: String, val shortcuts: List<Shortcut>)
+
+class ShortcutSubCategoryBuilder(val label: String) {
+ private val shortcuts = mutableListOf<Shortcut>()
+
+ fun shortcut(label: String, builder: ShortcutBuilder.() -> Unit) {
+ shortcuts += ShortcutBuilder(label).apply(builder).build()
+ }
+
+ fun build() = ShortcutSubCategory(label, shortcuts)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
index 271e79b8d060..b4828624d29c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
@@ -16,8 +16,13 @@
package com.android.systemui.keyboard.shortcut.ui.composable
+import android.content.Context
+import android.content.pm.PackageManager.NameNotFoundException
+import android.graphics.drawable.Icon
+import android.util.Log
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateFloatAsState
+import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -43,12 +48,17 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.OpenInNew
+import androidx.compose.material.icons.filled.Apps
import androidx.compose.material.icons.filled.ExpandMore
+import androidx.compose.material.icons.filled.Keyboard
import androidx.compose.material.icons.filled.Search
+import androidx.compose.material.icons.filled.Tv
+import androidx.compose.material.icons.filled.VerticalSplit
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
+import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationDrawerItemColors
import androidx.compose.material3.NavigationDrawerItemDefaults
@@ -70,9 +80,10 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.graphicsLayer
-import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.role
@@ -82,20 +93,48 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastForEachIndexed
+import com.android.compose.ui.graphics.painter.rememberDrawablePainter
import com.android.compose.windowsizeclass.LocalWindowSizeClass
+import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
+import com.android.systemui.keyboard.shortcut.ui.model.IconSource
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState
import com.android.systemui.res.R
+import com.android.systemui.statusbar.phone.CentralSurfaces
@Composable
fun ShortcutHelper(
onKeyboardSettingsClicked: () -> Unit,
modifier: Modifier = Modifier,
- categories: List<ShortcutHelperCategory> = ShortcutHelperTemporaryData.categories,
+ shortcutsUiState: ShortcutsUiState,
useSinglePane: @Composable () -> Boolean = { shouldUseSinglePane() },
) {
- if (useSinglePane()) {
- ShortcutHelperSinglePane(modifier, categories, onKeyboardSettingsClicked)
- } else {
- ShortcutHelperTwoPane(modifier, categories, onKeyboardSettingsClicked)
+ when (shortcutsUiState) {
+ is ShortcutsUiState.Active -> {
+ if (useSinglePane()) {
+ ShortcutHelperSinglePane(
+ modifier,
+ shortcutsUiState.shortcutCategories,
+ shortcutsUiState.defaultSelectedCategory,
+ onKeyboardSettingsClicked
+ )
+ } else {
+ ShortcutHelperTwoPane(
+ modifier,
+ shortcutsUiState.shortcutCategories,
+ shortcutsUiState.defaultSelectedCategory,
+ onKeyboardSettingsClicked
+ )
+ }
+ }
+ is ShortcutsUiState.Inactive -> {
+ // No-op for now.
+ }
}
}
@@ -107,7 +146,8 @@ private fun shouldUseSinglePane() =
@Composable
private fun ShortcutHelperSinglePane(
modifier: Modifier = Modifier,
- categories: List<ShortcutHelperCategory>,
+ categories: List<ShortcutCategory>,
+ defaultSelectedCategory: ShortcutCategoryType,
onKeyboardSettingsClicked: () -> Unit,
) {
Column(
@@ -121,7 +161,7 @@ private fun ShortcutHelperSinglePane(
Spacer(modifier = Modifier.height(6.dp))
ShortcutsSearchBar()
Spacer(modifier = Modifier.height(16.dp))
- CategoriesPanelSinglePane(categories)
+ CategoriesPanelSinglePane(categories, defaultSelectedCategory)
Spacer(modifier = Modifier.weight(1f))
KeyboardSettings(onClick = onKeyboardSettingsClicked)
}
@@ -129,9 +169,11 @@ private fun ShortcutHelperSinglePane(
@Composable
private fun CategoriesPanelSinglePane(
- categories: List<ShortcutHelperCategory>,
+ categories: List<ShortcutCategory>,
+ defaultSelectedCategory: ShortcutCategoryType,
) {
- var expandedCategory by remember { mutableStateOf<ShortcutHelperCategory?>(null) }
+ val selectedCategory = categories.firstOrNull { it.type == defaultSelectedCategory }
+ var expandedCategory by remember { mutableStateOf(selectedCategory) }
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
categories.fastForEachIndexed { index, category ->
val isExpanded = expandedCategory == category
@@ -162,7 +204,7 @@ private fun CategoriesPanelSinglePane(
@Composable
private fun CategoryItemSinglePane(
- category: ShortcutHelperCategory,
+ category: ShortcutCategory,
isExpanded: Boolean,
onClick: () -> Unit,
shape: Shape,
@@ -177,9 +219,9 @@ private fun CategoryItemSinglePane(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth().heightIn(min = 88.dp).padding(horizontal = 16.dp)
) {
- Icon(category.icon, contentDescription = null)
+ ShortcutCategoryIcon(category.icon)
Spacer(modifier = Modifier.width(16.dp))
- Text(stringResource(category.labelResId))
+ Text(category.label(LocalContext.current))
Spacer(modifier = Modifier.weight(1f))
RotatingExpandCollapseIcon(isExpanded)
}
@@ -188,6 +230,68 @@ private fun CategoryItemSinglePane(
}
}
+private val ShortcutCategory.icon: IconSource
+ @Composable
+ get() =
+ when (type) {
+ ShortcutCategoryType.System -> IconSource(imageVector = Icons.Default.Tv)
+ ShortcutCategoryType.MultiTasking ->
+ IconSource(imageVector = Icons.Default.VerticalSplit)
+ ShortcutCategoryType.InputMethodEditor ->
+ IconSource(imageVector = Icons.Default.Keyboard)
+ ShortcutCategoryType.AppCategories -> IconSource(imageVector = Icons.Default.Apps)
+ is ShortcutCategoryType.CurrentApp -> {
+ val context = LocalContext.current
+ val iconDrawable = context.packageManager.getApplicationIcon(type.packageName)
+ IconSource(painter = rememberDrawablePainter(drawable = iconDrawable))
+ }
+ }
+
+@Composable
+fun ShortcutCategoryIcon(
+ source: IconSource,
+ contentDescription: String? = null,
+ modifier: Modifier = Modifier,
+ tint: Color = LocalContentColor.current
+) {
+ if (source.imageVector != null) {
+ Icon(source.imageVector, contentDescription, modifier, tint)
+ } else if (source.painter != null) {
+ Image(source.painter, contentDescription, modifier)
+ }
+}
+
+private fun ShortcutCategory.label(context: Context): String =
+ when (type) {
+ ShortcutCategoryType.System -> context.getString(R.string.shortcut_helper_category_system)
+ ShortcutCategoryType.MultiTasking ->
+ context.getString(R.string.shortcut_helper_category_multitasking)
+ ShortcutCategoryType.InputMethodEditor ->
+ context.getString(R.string.shortcut_helper_category_input)
+ ShortcutCategoryType.AppCategories ->
+ context.getString(R.string.shortcut_helper_category_app_shortcuts)
+ is ShortcutCategoryType.CurrentApp -> getApplicationLabelForCurrentApp(type, context)
+ }
+
+private fun getApplicationLabelForCurrentApp(
+ type: ShortcutCategoryType.CurrentApp,
+ context: Context
+): String {
+ val packageManagerForUser = CentralSurfaces.getPackageManagerForUser(context, context.userId)
+ return try {
+ val currentAppInfo =
+ packageManagerForUser.getApplicationInfoAsUser(
+ type.packageName,
+ /* flags = */ 0,
+ context.userId
+ )
+ packageManagerForUser.getApplicationLabel(currentAppInfo).toString()
+ } catch (e: NameNotFoundException) {
+ Log.wtf(ShortcutHelper.TAG, "Couldn't find app info by package name ${type.packageName}")
+ context.getString(R.string.shortcut_helper_category_current_app_shortcuts)
+ }
+}
+
@Composable
private fun RotatingExpandCollapseIcon(isExpanded: Boolean) {
val expandIconRotationDegrees by
@@ -219,7 +323,7 @@ private fun RotatingExpandCollapseIcon(isExpanded: Boolean) {
}
@Composable
-private fun ShortcutCategoryDetailsSinglePane(category: ShortcutHelperCategory) {
+private fun ShortcutCategoryDetailsSinglePane(category: ShortcutCategory) {
Column(Modifier.padding(horizontal = 16.dp)) {
category.subCategories.fastForEach { subCategory ->
ShortcutSubCategorySinglePane(subCategory)
@@ -228,7 +332,7 @@ private fun ShortcutCategoryDetailsSinglePane(category: ShortcutHelperCategory)
}
@Composable
-private fun ShortcutSubCategorySinglePane(subCategory: SubCategory) {
+private fun ShortcutSubCategorySinglePane(subCategory: ShortcutSubCategory) {
// This @Composable is expected to be in a Column.
SubCategoryTitle(subCategory.label)
subCategory.shortcuts.fastForEachIndexed { index, shortcut ->
@@ -251,10 +355,12 @@ private fun ShortcutSinglePane(shortcut: Shortcut) {
@Composable
private fun ShortcutHelperTwoPane(
modifier: Modifier = Modifier,
- categories: List<ShortcutHelperCategory>,
+ categories: List<ShortcutCategory>,
+ defaultSelectedCategory: ShortcutCategoryType,
onKeyboardSettingsClicked: () -> Unit,
) {
- var selectedCategory by remember { mutableStateOf(categories.first()) }
+ var selectedCategoryType by remember { mutableStateOf(defaultSelectedCategory) }
+ val selectedCategory = categories.first { it.type == selectedCategoryType }
Column(modifier = modifier.fillMaxSize().padding(start = 24.dp, end = 24.dp, top = 26.dp)) {
TitleBar()
Spacer(modifier = Modifier.height(12.dp))
@@ -262,8 +368,8 @@ private fun ShortcutHelperTwoPane(
StartSidePanel(
modifier = Modifier.fillMaxWidth(fraction = 0.32f),
categories = categories,
- selectedCategory = selectedCategory,
- onCategoryClicked = { selectedCategory = it },
+ selectedCategory = selectedCategoryType,
+ onCategoryClicked = { selectedCategoryType = it.type },
onKeyboardSettingsClicked = onKeyboardSettingsClicked,
)
Spacer(modifier = Modifier.width(24.dp))
@@ -273,7 +379,7 @@ private fun ShortcutHelperTwoPane(
}
@Composable
-private fun EndSidePanel(modifier: Modifier, category: ShortcutHelperCategory) {
+private fun EndSidePanel(modifier: Modifier, category: ShortcutCategory) {
LazyColumn(modifier.nestedScroll(rememberNestedScrollInteropConnection())) {
items(items = category.subCategories, key = { item -> item.label }) {
SubCategoryContainerDualPane(it)
@@ -283,7 +389,7 @@ private fun EndSidePanel(modifier: Modifier, category: ShortcutHelperCategory) {
}
@Composable
-private fun SubCategoryContainerDualPane(subCategory: SubCategory) {
+private fun SubCategoryContainerDualPane(subCategory: ShortcutSubCategory) {
Surface(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(28.dp),
@@ -314,17 +420,47 @@ private fun SubCategoryTitle(title: String) {
@Composable
private fun ShortcutViewDualPane(shortcut: Shortcut) {
Row(Modifier.padding(vertical = 16.dp)) {
- ShortcutDescriptionText(
- modifier = Modifier.weight(0.25f).align(Alignment.CenterVertically),
- shortcut = shortcut,
- )
+ Row(
+ modifier = Modifier.width(160.dp).align(Alignment.CenterVertically),
+ horizontalArrangement = Arrangement.spacedBy(16.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ if (shortcut.icon != null) {
+ ShortcutIcon(
+ shortcut.icon,
+ modifier = Modifier.size(36.dp),
+ )
+ }
+ ShortcutDescriptionText(
+ shortcut = shortcut,
+ )
+ }
+ Spacer(modifier = Modifier.width(16.dp))
ShortcutKeyCombinations(
- modifier = Modifier.weight(0.75f),
+ modifier = Modifier.weight(1f),
shortcut = shortcut,
)
}
}
+@Composable
+fun ShortcutIcon(
+ icon: ShortcutIcon,
+ modifier: Modifier = Modifier,
+ contentDescription: String? = null,
+) {
+ val context = LocalContext.current
+ val drawable =
+ remember(icon.packageName, icon.resourceId) {
+ Icon.createWithResource(icon.packageName, icon.resourceId).loadDrawable(context)
+ } ?: return
+ Image(
+ painter = rememberDrawablePainter(drawable),
+ contentDescription = contentDescription,
+ modifier = modifier,
+ )
+}
+
@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun ShortcutKeyCombinations(
@@ -343,16 +479,17 @@ private fun ShortcutKeyCombinations(
@Composable
private fun ShortcutCommand(command: ShortcutCommand) {
- // This @Composable is expected to be in a Row or FlowRow.
- command.keys.forEachIndexed { keyIndex, key ->
- if (keyIndex > 0) {
- Spacer(Modifier.width(4.dp))
- }
- ShortcutKeyContainer {
- if (key is ShortcutKey.Text) {
- ShortcutTextKey(key)
- } else if (key is ShortcutKey.Icon) {
- ShortcutIconKey(key)
+ Row {
+ command.keys.forEachIndexed { keyIndex, key ->
+ if (keyIndex > 0) {
+ Spacer(Modifier.width(4.dp))
+ }
+ ShortcutKeyContainer {
+ if (key is ShortcutKey.Text) {
+ ShortcutTextKey(key)
+ } else if (key is ShortcutKey.Icon) {
+ ShortcutIconKey(key)
+ }
}
}
}
@@ -384,7 +521,7 @@ private fun BoxScope.ShortcutTextKey(key: ShortcutKey.Text) {
@Composable
private fun BoxScope.ShortcutIconKey(key: ShortcutKey.Icon) {
Icon(
- imageVector = key.value,
+ painter = painterResource(key.drawableResId),
contentDescription = null,
modifier = Modifier.align(Alignment.Center).padding(6.dp)
)
@@ -418,10 +555,10 @@ private fun ShortcutDescriptionText(
@Composable
private fun StartSidePanel(
modifier: Modifier,
- categories: List<ShortcutHelperCategory>,
+ categories: List<ShortcutCategory>,
onKeyboardSettingsClicked: () -> Unit,
- selectedCategory: ShortcutHelperCategory,
- onCategoryClicked: (ShortcutHelperCategory) -> Unit,
+ selectedCategory: ShortcutCategoryType,
+ onCategoryClicked: (ShortcutCategory) -> Unit,
) {
Column(modifier) {
ShortcutsSearchBar()
@@ -434,16 +571,16 @@ private fun StartSidePanel(
@Composable
private fun CategoriesPanelTwoPane(
- categories: List<ShortcutHelperCategory>,
- selectedCategory: ShortcutHelperCategory,
- onCategoryClicked: (ShortcutHelperCategory) -> Unit
+ categories: List<ShortcutCategory>,
+ selectedCategory: ShortcutCategoryType,
+ onCategoryClicked: (ShortcutCategory) -> Unit
) {
Column {
categories.fastForEach {
CategoryItemTwoPane(
- label = stringResource(it.labelResId),
- icon = it.icon,
- selected = selectedCategory == it,
+ label = it.label(LocalContext.current),
+ iconSource = it.icon,
+ selected = selectedCategory == it.type,
onClick = { onCategoryClicked(it) }
)
}
@@ -453,7 +590,7 @@ private fun CategoriesPanelTwoPane(
@Composable
private fun CategoryItemTwoPane(
label: String,
- icon: ImageVector,
+ iconSource: IconSource,
selected: Boolean,
onClick: () -> Unit,
colors: NavigationDrawerItemColors =
@@ -467,9 +604,9 @@ private fun CategoryItemTwoPane(
color = colors.containerColor(selected).value,
) {
Row(Modifier.padding(horizontal = 24.dp), verticalAlignment = Alignment.CenterVertically) {
- Icon(
+ ShortcutCategoryIcon(
modifier = Modifier.size(24.dp),
- imageVector = icon,
+ source = iconSource,
contentDescription = null,
tint = colors.iconColor(selected).value
)
@@ -565,4 +702,6 @@ object ShortcutHelper {
object Dimensions {
val SinglePaneCategoryCornerRadius = 28.dp
}
+
+ internal const val TAG = "ShortcutHelperUI"
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelperTemporaryData.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelperTemporaryData.kt
deleted file mode 100644
index fa2388f6287d..000000000000
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelperTemporaryData.kt
+++ /dev/null
@@ -1,251 +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.keyboard.shortcut.ui.composable
-
-import androidx.annotation.StringRes
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Accessibility
-import androidx.compose.material.icons.filled.Apps
-import androidx.compose.material.icons.filled.ArrowBackIosNew
-import androidx.compose.material.icons.filled.Keyboard
-import androidx.compose.material.icons.filled.KeyboardCommandKey
-import androidx.compose.material.icons.filled.RadioButtonUnchecked
-import androidx.compose.material.icons.filled.Tv
-import androidx.compose.material.icons.filled.VerticalSplit
-import androidx.compose.ui.graphics.vector.ImageVector
-import com.android.systemui.res.R
-
-/** Temporary data classes and data below just to populate the UI. */
-data class ShortcutHelperCategory(
- @StringRes val labelResId: Int,
- val icon: ImageVector,
- val subCategories: List<SubCategory>,
-)
-
-data class SubCategory(
- val label: String,
- val shortcuts: List<Shortcut>,
-)
-
-data class Shortcut(val label: String, val commands: List<ShortcutCommand>)
-
-data class ShortcutCommand(val keys: List<ShortcutKey>)
-
-sealed interface ShortcutKey {
- data class Text(val value: String) : ShortcutKey
-
- data class Icon(val value: ImageVector) : ShortcutKey
-}
-
-// DSL Builder Functions
-private fun shortcutHelperCategory(
- labelResId: Int,
- icon: ImageVector,
- block: ShortcutHelperCategoryBuilder.() -> Unit
-): ShortcutHelperCategory = ShortcutHelperCategoryBuilder(labelResId, icon).apply(block).build()
-
-private fun ShortcutHelperCategoryBuilder.subCategory(
- label: String,
- block: SubCategoryBuilder.() -> Unit
-) {
- subCategories.add(SubCategoryBuilder(label).apply(block).build())
-}
-
-private fun SubCategoryBuilder.shortcut(label: String, block: ShortcutBuilder.() -> Unit) {
- shortcuts.add(ShortcutBuilder(label).apply(block).build())
-}
-
-private fun ShortcutBuilder.command(block: ShortcutCommandBuilder.() -> Unit) {
- commands.add(ShortcutCommandBuilder().apply(block).build())
-}
-
-private fun ShortcutCommandBuilder.key(value: String) {
- keys.add(ShortcutKey.Text(value))
-}
-
-private fun ShortcutCommandBuilder.key(value: ImageVector) {
- keys.add(ShortcutKey.Icon(value))
-}
-
-private class ShortcutHelperCategoryBuilder(
- private val labelResId: Int,
- private val icon: ImageVector
-) {
- val subCategories = mutableListOf<SubCategory>()
-
- fun build() = ShortcutHelperCategory(labelResId, icon, subCategories)
-}
-
-private class SubCategoryBuilder(private val label: String) {
- val shortcuts = mutableListOf<Shortcut>()
-
- fun build() = SubCategory(label, shortcuts)
-}
-
-private class ShortcutBuilder(private val label: String) {
- val commands = mutableListOf<ShortcutCommand>()
-
- fun build() = Shortcut(label, commands)
-}
-
-private class ShortcutCommandBuilder {
- val keys = mutableListOf<ShortcutKey>()
-
- fun build() = ShortcutCommand(keys)
-}
-
-object ShortcutHelperTemporaryData {
-
- // Some shortcuts and their strings below are made up just to populate the UI for now.
- // For this reason they are not in translatable resources yet.
- val categories =
- listOf(
- shortcutHelperCategory(R.string.shortcut_helper_category_system, Icons.Default.Tv) {
- subCategory("System controls") {
- shortcut("Go to home screen") {
- command { key(Icons.Default.RadioButtonUnchecked) }
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("H")
- }
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("Return")
- }
- }
- shortcut("View recent apps") {
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("Tab")
- }
- }
- shortcut("All apps search") {
- command { key(Icons.Default.KeyboardCommandKey) }
- }
- }
- subCategory("System apps") {
- shortcut("Go back") {
- command { key(Icons.Default.ArrowBackIosNew) }
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("Left arrow")
- }
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("ESC")
- }
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("Backspace")
- }
- }
- shortcut("View notifications") {
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("N")
- }
- }
- shortcut("Take a screenshot") {
- command { key(Icons.Default.KeyboardCommandKey) }
- command { key("CTRL") }
- command { key("S") }
- }
- shortcut("Open Settings") {
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("I")
- }
- }
- }
- },
- shortcutHelperCategory(
- R.string.shortcut_helper_category_multitasking,
- Icons.Default.VerticalSplit
- ) {
- subCategory("Multitasking & windows") {
- shortcut("Take a screenshot") {
- command { key(Icons.Default.KeyboardCommandKey) }
- command { key("CTRL") }
- command { key("S") }
- }
- }
- },
- shortcutHelperCategory(
- R.string.shortcut_helper_category_input,
- Icons.Default.Keyboard
- ) {
- subCategory("Input") {
- shortcut("Open Settings") {
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("I")
- }
- }
- shortcut("View notifications") {
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("N")
- }
- }
- }
- },
- shortcutHelperCategory(
- R.string.shortcut_helper_category_app_shortcuts,
- Icons.Default.Apps
- ) {
- subCategory("App shortcuts") {
- shortcut("Open Settings") {
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("I")
- }
- }
- shortcut("Go back") {
- command { key(Icons.Default.ArrowBackIosNew) }
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("Left arrow")
- }
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("ESC")
- }
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("Backspace")
- }
- }
- }
- },
- shortcutHelperCategory(
- R.string.shortcut_helper_category_a11y,
- Icons.Default.Accessibility
- ) {
- subCategory("Accessibility shortcuts") {
- shortcut("View recent apps") {
- command {
- key(Icons.Default.KeyboardCommandKey)
- key("Tab")
- }
- }
- shortcut("All apps search") {
- command { key(Icons.Default.KeyboardCommandKey) }
- }
- }
- }
- )
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/IconSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/IconSource.kt
new file mode 100644
index 000000000000..7fc0103d861f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/IconSource.kt
@@ -0,0 +1,22 @@
+/*
+ * 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.keyboard.shortcut.ui.model
+
+import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.graphics.vector.ImageVector
+
+data class IconSource(val imageVector: ImageVector? = null, val painter: Painter? = null)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutsUiState.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutsUiState.kt
new file mode 100644
index 000000000000..daafc3f53147
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutsUiState.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.keyboard.shortcut.ui.model
+
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+
+sealed interface ShortcutsUiState {
+
+ data class Active(
+ val shortcutCategories: List<ShortcutCategory>,
+ val defaultSelectedCategory: ShortcutCategoryType,
+ ) : ShortcutsUiState
+
+ data object Inactive : ShortcutsUiState
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
index 8706280df975..d0e3ab40f8d3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
@@ -26,8 +26,10 @@ import android.view.WindowInsets
import androidx.activity.BackEventCompat
import androidx.activity.ComponentActivity
import androidx.activity.OnBackPressedCallback
+import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.ComposeView
import androidx.core.view.updatePadding
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.android.compose.theme.PlatformTheme
@@ -78,7 +80,9 @@ constructor(
requireViewById<ComposeView>(R.id.shortcut_helper_compose_container).apply {
setContent {
PlatformTheme {
+ val shortcutsUiState by viewModel.shortcutsUiState.collectAsStateWithLifecycle()
ShortcutHelper(
+ shortcutsUiState = shortcutsUiState,
onKeyboardSettingsClicked = ::onKeyboardSettingsClicked,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
index 510e55262224..25574ea551b4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
@@ -17,27 +17,61 @@
package com.android.systemui.keyboard.shortcut.ui.viewmodel
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperCategoriesInteractor
import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperStateInteractor
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.CurrentApp
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
class ShortcutHelperViewModel
@Inject
constructor(
+ @Background private val backgroundScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
private val stateInteractor: ShortcutHelperStateInteractor,
+ categoriesInteractor: ShortcutHelperCategoriesInteractor,
) {
val shouldShow =
- stateInteractor.state
- .map { it is ShortcutHelperState.Active }
+ categoriesInteractor.shortcutCategories
+ .map { it.isNotEmpty() }
.distinctUntilChanged()
.flowOn(backgroundDispatcher)
+ val shortcutsUiState =
+ categoriesInteractor.shortcutCategories
+ .map {
+ if (it.isEmpty()) {
+ ShortcutsUiState.Inactive
+ } else {
+ ShortcutsUiState.Active(
+ shortcutCategories = it,
+ defaultSelectedCategory = getDefaultSelectedCategory(it),
+ )
+ }
+ }
+ .stateIn(
+ scope = backgroundScope,
+ started = SharingStarted.Lazily,
+ initialValue = ShortcutsUiState.Inactive
+ )
+
+ private fun getDefaultSelectedCategory(
+ categories: List<ShortcutCategory>
+ ): ShortcutCategoryType {
+ val currentAppShortcuts = categories.firstOrNull { it.type is CurrentApp }
+ return currentAppShortcuts?.type ?: categories.first().type
+ }
+
fun onViewClosed() {
stateInteractor.onViewClosed()
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index c4b70d8013bf..9f3311373709 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -81,6 +81,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardWakeDirectlyToGoneInteractor;
import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindParamsApplier;
import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindViewBinder;
import com.android.systemui.keyguard.ui.binder.WindowManagerLockscreenVisibilityViewBinder;
@@ -317,7 +318,7 @@ public class KeyguardService extends Service {
private final WindowManagerOcclusionManager mWmOcclusionManager;
private final KeyguardEnabledInteractor mKeyguardEnabledInteractor;
-
+ private final KeyguardWakeDirectlyToGoneInteractor mKeyguardWakeDirectlyToGoneInteractor;
private final Lazy<FoldGracePeriodProvider> mFoldGracePeriodProvider = new Lazy<>() {
@Override
public FoldGracePeriodProvider get() {
@@ -344,7 +345,8 @@ public class KeyguardService extends Service {
@Main Executor mainExecutor,
KeyguardInteractor keyguardInteractor,
KeyguardEnabledInteractor keyguardEnabledInteractor,
- Lazy<KeyguardStateCallbackStartable> keyguardStateCallbackStartableLazy) {
+ Lazy<KeyguardStateCallbackStartable> keyguardStateCallbackStartableLazy,
+ KeyguardWakeDirectlyToGoneInteractor keyguardWakeDirectlyToGoneInteractor) {
super();
mKeyguardViewMediator = keyguardViewMediator;
mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
@@ -372,6 +374,7 @@ public class KeyguardService extends Service {
mWmOcclusionManager = windowManagerOcclusionManager;
mKeyguardEnabledInteractor = keyguardEnabledInteractor;
+ mKeyguardWakeDirectlyToGoneInteractor = keyguardWakeDirectlyToGoneInteractor;
}
@Override
@@ -486,6 +489,7 @@ public class KeyguardService extends Service {
public void onDreamingStarted() {
trace("onDreamingStarted");
checkPermission();
+ mKeyguardWakeDirectlyToGoneInteractor.onDreamingStarted();
mKeyguardInteractor.setDreaming(true);
mKeyguardViewMediator.onDreamingStarted();
}
@@ -494,6 +498,7 @@ public class KeyguardService extends Service {
public void onDreamingStopped() {
trace("onDreamingStopped");
checkPermission();
+ mKeyguardWakeDirectlyToGoneInteractor.onDreamingStopped();
mKeyguardInteractor.setDreaming(false);
mKeyguardViewMediator.onDreamingStopped();
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 5f6fe1c2130d..d1a84632e0eb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -27,6 +27,7 @@ import android.os.DeadObjectException
import android.os.Handler
import android.os.PowerManager
import android.os.RemoteException
+import android.os.Trace
import android.util.Log
import android.view.RemoteAnimationTarget
import android.view.SurfaceControl
@@ -102,14 +103,14 @@ const val DISMISS_AMOUNT_EXIT_KEYGUARD_THRESHOLD = 0.3f
* swiped away via a touch gesture, or when it's flinging expanded/collapsed after a swipe.
*/
const val LEGACY_UNLOCK_ANIMATION_DURATION_MS = 200L
-const val UNLOCK_ANIMATION_DURATION_MS = 167L
+const val UNLOCK_ANIMATION_DURATION_MS = 300L
/**
* If there are two different wallpapers on home and lock screen, duration and delay of the lock
* wallpaper fade out.
*/
-const val LOCK_WALLPAPER_FADE_OUT_DURATION = 140L
-const val LOCK_WALLPAPER_FADE_OUT_START_DELAY = 0L
+const val LOCK_WALLPAPER_FADE_OUT_DURATION = 150L
+const val LOCK_WALLPAPER_FADE_OUT_START_DELAY = 150L
/**
* How long the in-window launcher icon animation takes. This is used if the launcher is underneath
@@ -166,7 +167,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
private val statusBarStateController: SysuiStatusBarStateController,
private val notificationShadeWindowController: NotificationShadeWindowController,
private val powerManager: PowerManager,
- private val wallpaperManager: WallpaperManager
+ private val wallpaperManager: WallpaperManager,
) : KeyguardStateController.Callback, ISysuiUnlockAnimationController.Stub() {
interface KeyguardUnlockAnimationListener {
@@ -379,16 +380,20 @@ class KeyguardUnlockAnimationController @Inject constructor(
else LAUNCHER_ICONS_ANIMATION_DURATION_MS
interpolator = if (fasterUnlockTransition()) Interpolators.LINEAR
else Interpolators.ALPHA_OUT
- if (fasterUnlockTransition()) startDelay = CANNED_UNLOCK_START_DELAY
addUpdateListener { valueAnimator: ValueAnimator ->
setWallpaperAppearAmount(
valueAnimator.animatedValue as Float, openingWallpaperTargets)
}
addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationStart(animation: Animator) {
+ super.onAnimationStart(animation)
+ Trace.asyncTraceBegin(Trace.TRACE_TAG_APP, "WallpaperAlphaAnimation", 0)
+ }
override fun onAnimationEnd(animation: Animator) {
Log.d(TAG, "wallpaperCannedUnlockAnimator#onAnimationEnd")
keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
false /* cancelled */)
+ Trace.asyncTraceEnd(Trace.TRACE_TAG_APP, "WallpaperAlphaAnimation", 0)
}
})
}
@@ -641,14 +646,12 @@ class KeyguardUnlockAnimationController @Inject constructor(
val isWakeAndUnlockNotFromDream = biometricUnlockControllerLazy.get().isWakeAndUnlock &&
biometricUnlockControllerLazy.get().mode != MODE_WAKE_AND_UNLOCK_FROM_DREAM
- val duration = if (fasterUnlockTransition()) UNLOCK_ANIMATION_DURATION_MS
- else LAUNCHER_ICONS_ANIMATION_DURATION_MS
listeners.forEach {
it.onUnlockAnimationStarted(
playingCannedUnlockAnimation /* playingCannedAnimation */,
isWakeAndUnlockNotFromDream /* isWakeAndUnlockNotFromDream */,
cannedUnlockStartDelayMs() /* unlockStartDelay */,
- duration /* unlockAnimationDuration */) }
+ LAUNCHER_ICONS_ANIMATION_DURATION_MS /* unlockAnimationDuration */) }
// Finish the keyguard remote animation if the dismiss amount has crossed the threshold.
// Check it here in case there is no more change to the dismiss amount after the last change
@@ -740,6 +743,10 @@ class KeyguardUnlockAnimationController @Inject constructor(
// As soon as the shade starts animating out of the way, start the canned unlock animation,
// which will finish keyguard exit when it completes. The in-window animations in the
// Launcher window will end on their own.
+ if (fasterUnlockTransition() && openingWallpaperTargets?.isNotEmpty() == true) {
+ fadeOutWallpaper()
+ }
+
handler.postDelayed({
if (keyguardViewMediator.get().isShowingAndNotOccluded &&
!keyguardStateController.isKeyguardGoingAway) {
@@ -748,9 +755,8 @@ class KeyguardUnlockAnimationController @Inject constructor(
return@postDelayed
}
- if ((openingWallpaperTargets?.isNotEmpty() == true)) {
+ if (openingWallpaperTargets?.isNotEmpty() == true) {
fadeInWallpaper()
- if (fasterUnlockTransition()) fadeOutWallpaper()
hideKeyguardViewAfterRemoteAnimation()
} else {
keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
@@ -1032,6 +1038,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
surfaceBehindAlphaAnimator.cancel()
surfaceBehindEntryAnimator.cancel()
wallpaperCannedUnlockAnimator.cancel()
+ if (fasterUnlockTransition()) wallpaperFadeOutUnlockAnimator.cancel()
// That target is no longer valid since the animation finished, null it out.
surfaceBehindRemoteAnimationTargets = null
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index 608e25a82eff..80cf4c50866c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -21,6 +21,7 @@ import android.content.Context
import android.view.LayoutInflater
import android.view.View
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.constraintlayout.widget.ConstraintSet
@@ -29,9 +30,9 @@ import androidx.constraintlayout.widget.ConstraintSet.END
import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import androidx.constraintlayout.widget.ConstraintSet.START
import androidx.constraintlayout.widget.ConstraintSet.TOP
+import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneTransitionLayout
-import com.android.compose.animation.scene.transitions
import com.android.internal.jank.InteractionJankMonitor
import com.android.keyguard.KeyguardStatusView
import com.android.keyguard.KeyguardStatusViewController
@@ -42,6 +43,7 @@ import com.android.systemui.CoreStartable
import com.android.systemui.biometrics.ui.binder.DeviceEntryUnlockTrackerViewBinder
import com.android.systemui.common.ui.ConfigurationState
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor
import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
@@ -73,6 +75,7 @@ import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
import dagger.Lazy
import java.util.Optional
import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -108,11 +111,11 @@ constructor(
private val clockInteractor: KeyguardClockInteractor,
private val keyguardViewMediator: KeyguardViewMediator,
private val deviceEntryUnlockTrackerViewBinder: Optional<DeviceEntryUnlockTrackerViewBinder>,
+ @Main private val mainDispatcher: CoroutineDispatcher,
) : CoreStartable {
private var rootViewHandle: DisposableHandle? = null
private var indicationAreaHandle: DisposableHandle? = null
- private val sceneKey = SceneKey("root-view-scene-key")
var keyguardStatusViewController: KeyguardStatusViewController? = null
get() {
@@ -215,6 +218,7 @@ constructor(
vibratorHelper,
falsingManager,
keyguardViewMediator,
+ mainDispatcher,
)
}
@@ -229,12 +233,10 @@ constructor(
setContent {
// STL is used solely to provide a SceneScope to enable us to invoke SceneScope
// composables.
- SceneTransitionLayout(
- currentScene = sceneKey,
- onChangeScene = {},
- transitions = transitions {},
- ) {
- scene(sceneKey) {
+ val currentScene = remember { SceneKey("root-view-scene-key") }
+ val state = remember { MutableSceneTransitionLayoutState(currentScene) }
+ SceneTransitionLayout(state) {
+ scene(currentScene) {
with(
LockscreenContent(
viewModel = viewModel,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 1ea5d1c00561..e46a7cbf9bb0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -78,7 +78,6 @@ import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
@@ -151,6 +150,7 @@ import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.log.SessionTracker;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.process.ProcessWrapper;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.settings.UserTracker;
@@ -360,6 +360,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
private final SecureSettings mSecureSettings;
private final SystemSettings mSystemSettings;
private final SystemClock mSystemClock;
+ private final ProcessWrapper mProcessWrapper;
private final SystemPropertiesHelper mSystemPropertiesHelper;
/**
@@ -1459,10 +1460,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
Lazy<ActivityTransitionAnimator> activityTransitionAnimator,
Lazy<ScrimController> scrimControllerLazy,
IActivityTaskManager activityTaskManagerService,
+ IStatusBarService statusBarService,
FeatureFlags featureFlags,
SecureSettings secureSettings,
SystemSettings systemSettings,
SystemClock systemClock,
+ ProcessWrapper processWrapper,
@Main CoroutineDispatcher mainDispatcher,
Lazy<DreamViewModel> dreamViewModel,
Lazy<CommunalTransitionViewModel> communalTransitionViewModel,
@@ -1487,9 +1490,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
mSecureSettings = secureSettings;
mSystemSettings = systemSettings;
mSystemClock = systemClock;
+ mProcessWrapper = processWrapper;
mSystemPropertiesHelper = systemPropertiesHelper;
- mStatusBarService = IStatusBarService.Stub.asInterface(
- ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+ mStatusBarService = statusBarService;
mKeyguardDisplayManager = keyguardDisplayManager;
mShadeController = shadeControllerLazy;
dumpManager.registerDumpable(this);
@@ -2722,13 +2725,13 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
if (mGoingToSleep) {
mUpdateMonitor.clearFingerprintRecognizedWhenKeyguardDone(currentUser);
Log.i(TAG, "Device is going to sleep, aborting keyguardDone");
- return;
- }
- setPendingLock(false); // user may have authenticated during the screen off animation
+ } else {
+ setPendingLock(false); // user may have authenticated during the screen off animation
- handleHide();
- mKeyguardInteractor.keyguardDoneAnimationsFinished();
- mUpdateMonitor.clearFingerprintRecognizedWhenKeyguardDone(currentUser);
+ handleHide();
+ mKeyguardInteractor.keyguardDoneAnimationsFinished();
+ mUpdateMonitor.clearFingerprintRecognizedWhenKeyguardDone(currentUser);
+ }
Trace.endSection();
}
@@ -2834,6 +2837,14 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
*/
private void handleShow(Bundle options) {
Trace.beginSection("KeyguardViewMediator#handleShow");
+ try {
+ handleShowInner(options);
+ } finally {
+ Trace.endSection();
+ }
+ }
+
+ private void handleShowInner(Bundle options) {
final boolean showUnlocked = options != null
&& options.getBoolean(OPTION_SHOW_DISMISSIBLE, false);
final int currentUser = mSelectedUserInteractor.getSelectedUserId();
@@ -2885,8 +2896,6 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
mKeyguardDisplayManager.show();
scheduleNonStrongBiometricIdleTimeout();
-
- Trace.endSection();
}
/**
@@ -3065,6 +3074,17 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) {
Trace.beginSection("KeyguardViewMediator#handleStartKeyguardExitAnimation");
+ try {
+ handleStartKeyguardExitAnimationInner(startTime, fadeoutDuration, apps, wallpapers,
+ nonApps, finishedCallback);
+ } finally {
+ Trace.endSection();
+ }
+ }
+
+ private void handleStartKeyguardExitAnimationInner(long startTime, long fadeoutDuration,
+ RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
+ RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) {
Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
+ " fadeoutDuration=" + fadeoutDuration);
synchronized (KeyguardViewMediator.this) {
@@ -3253,8 +3273,6 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
onKeyguardExitFinished();
}
}
-
- Trace.endSection();
}
private void onKeyguardExitFinished() {
@@ -3496,12 +3514,20 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// TODO (b/155663717) After restart, status bar will not properly hide home button
// unless disable is called to show un-hide it once first
if (forceClearFlags) {
- try {
- mStatusBarService.disableForUser(flags, mStatusBarDisableToken,
- mContext.getPackageName(),
- mSelectedUserInteractor.getSelectedUserId(true));
- } catch (RemoteException e) {
- Log.d(TAG, "Failed to force clear flags", e);
+ if (UserManager.isVisibleBackgroundUsersEnabled()
+ && !mProcessWrapper.isSystemUser() && !mProcessWrapper.isForegroundUser()) {
+ // TODO: b/341604160 - Support visible background users properly.
+ if (DEBUG) {
+ Log.d(TAG, "Status bar manager is disabled for visible background users");
+ }
+ } else {
+ try {
+ mStatusBarService.disableForUser(flags, mStatusBarDisableToken,
+ mContext.getPackageName(),
+ mSelectedUserInteractor.getSelectedUserId(true));
+ } catch (RemoteException e) {
+ Log.d(TAG, "Failed to force clear flags", e);
+ }
}
}
@@ -3525,6 +3551,14 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
}
if (!SceneContainerFlag.isEnabled()) {
+ if (UserManager.isVisibleBackgroundUsersEnabled()
+ && !mProcessWrapper.isSystemUser() && !mProcessWrapper.isForegroundUser()) {
+ // TODO: b/341604160 - Support visible background users properly.
+ if (DEBUG) {
+ Log.d(TAG, "Status bar manager is disabled for visible background users");
+ }
+ return;
+ }
try {
mStatusBarService.disableForUser(flags, mStatusBarDisableToken,
mContext.getPackageName(),
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
index 97ea16d7f8c8..b9e513586298 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
@@ -24,11 +24,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
-import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
-import com.android.systemui.keyguard.shared.model.TransitionState
-import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.utils.GlobalWindowManager
import javax.inject.Inject
@@ -52,24 +48,15 @@ constructor(
private val globalWindowManager: GlobalWindowManager,
@Application private val applicationScope: CoroutineScope,
@Background private val bgDispatcher: CoroutineDispatcher,
- private val sceneInteractor: SceneInteractor,
) : CoreStartable {
override fun start() {
Log.d(LOG_TAG, "Resource trimmer registered.")
applicationScope.launch(bgDispatcher) {
- // We drop 1 to avoid triggering on initial collect().
- if (SceneContainerFlag.isEnabled) {
- sceneInteractor.transitionState
- .filter { it.isIdle(Scenes.Gone) }
- .collect { onKeyguardGone() }
- } else {
- keyguardTransitionInteractor.transition(Edge.create(to = GONE)).collect {
- if (it.transitionState == TransitionState.FINISHED) {
- onKeyguardGone()
- }
- }
- }
+ keyguardTransitionInteractor
+ .isFinishedIn(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+ .filter { isOnGone -> isOnGone }
+ .collect { onKeyguardGone() }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index 15dac0981117..a43bfd3a8fff 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -23,6 +23,7 @@ import android.os.PowerManager;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.UiEventLogger;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardDisplayManager;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -64,6 +65,7 @@ import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAfforda
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransitionModule;
import com.android.systemui.log.SessionTracker;
import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.process.ProcessWrapper;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
@@ -158,10 +160,12 @@ public interface KeyguardModule {
Lazy<ActivityTransitionAnimator> activityTransitionAnimator,
Lazy<ScrimController> scrimControllerLazy,
IActivityTaskManager activityTaskManagerService,
+ IStatusBarService statusBarService,
FeatureFlags featureFlags,
SecureSettings secureSettings,
SystemSettings systemSettings,
SystemClock systemClock,
+ ProcessWrapper processWrapper,
@Main CoroutineDispatcher mainDispatcher,
Lazy<DreamViewModel> dreamViewModel,
Lazy<CommunalTransitionViewModel> communalTransitionViewModel,
@@ -206,10 +210,12 @@ public interface KeyguardModule {
activityTransitionAnimator,
scrimControllerLazy,
activityTaskManagerService,
+ statusBarService,
featureFlags,
secureSettings,
systemSettings,
systemClock,
+ processWrapper,
mainDispatcher,
dreamViewModel,
communalTransitionViewModel,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
index 9b5f4615a6d5..406b9f6e6a0d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
@@ -25,9 +25,8 @@ import android.provider.Settings.Global.ZEN_MODE_OFF
import android.provider.Settings.Secure.ZEN_DURATION_FOREVER
import android.provider.Settings.Secure.ZEN_DURATION_PROMPT
import android.service.notification.ZenModeConfig
-import com.android.settingslib.notification.EnableZenModeDialog
-import com.android.settingslib.notification.ZenModeDialogMetricsLogger
-import com.android.systemui.res.R
+import com.android.settingslib.notification.modes.EnableZenModeDialog
+import com.android.settingslib.notification.modes.ZenModeDialogMetricsLogger
import com.android.systemui.animation.Expandable
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
@@ -36,6 +35,7 @@ import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
+import com.android.systemui.res.R
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.policy.ZenModeController
import com.android.systemui.util.settings.SecureSettings
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
index e9bd88932c52..e6bab4c7edcf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
@@ -19,8 +19,9 @@ package com.android.systemui.keyguard.data.quickaffordance
import android.content.Context
import android.os.UserHandle
+import com.android.app.tracing.FlowTracing.tracedAwaitClose
+import com.android.app.tracing.FlowTracing.tracedConflatedCallbackFlow
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.settings.UserTracker
@@ -28,7 +29,6 @@ import com.android.systemui.shared.customization.data.content.CustomizationProvi
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -55,19 +55,20 @@ constructor(
private val userHandle: UserHandle,
) : KeyguardQuickAffordanceSelectionManager {
- private val userId: Flow<Int> = conflatedCallbackFlow {
- val callback =
- object : UserTracker.Callback {
- override fun onUserChanged(newUser: Int, userContext: Context) {
- trySendWithFailureLogging(newUser, TAG)
+ private val userId: Flow<Int> =
+ tracedConflatedCallbackFlow("userId") {
+ val callback =
+ object : UserTracker.Callback {
+ override fun onUserChanged(newUser: Int, userContext: Context) {
+ trySendWithFailureLogging(newUser, TAG)
+ }
}
- }
- userTracker.addCallback(callback) { it.run() }
- trySendWithFailureLogging(userTracker.userId, TAG)
+ userTracker.addCallback(callback) { it.run() }
+ trySendWithFailureLogging(userTracker.userId, TAG)
- awaitClose { userTracker.removeCallback(callback) }
- }
+ tracedAwaitClose("userId") { userTracker.removeCallback(callback) }
+ }
private val clientOrNull: StateFlow<CustomizationProviderClient?> =
userId
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
index 1fe94d5fa43b..a145214e5161 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
@@ -21,7 +21,6 @@ import android.content.Context
import android.media.AudioManager
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
-import com.android.systemui.res.R
import com.android.systemui.animation.Expandable
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.common.shared.model.ContentDescription
@@ -31,6 +30,7 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
+import com.android.systemui.res.R
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.RingerModeTracker
@@ -86,8 +86,8 @@ constructor(
audioManager.isVolumeFixed ->
ActivationState.NotSupported to R.string.volume_ringer_hint_mute
mode == AudioManager.RINGER_MODE_SILENT ->
- ActivationState.Active to R.string.volume_ringer_hint_mute
- else -> ActivationState.Inactive to R.string.volume_ringer_hint_unmute
+ ActivationState.Active to R.string.volume_ringer_hint_unmute
+ else -> ActivationState.Inactive to R.string.volume_ringer_hint_mute
}
KeyguardQuickAffordanceConfig.LockScreenState.Visible(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index 63dd255c5de4..ae751dbacd68 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -62,6 +62,7 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
/** Defines interface for classes that encapsulate application state for the keyguard. */
interface KeyguardRepository {
@@ -126,6 +127,30 @@ interface KeyguardRepository {
*/
val isKeyguardEnabled: StateFlow<Boolean>
+ /**
+ * Whether we can transition directly back to GONE from AOD/DOZING without any authentication
+ * events (such as a fingerprint wake and unlock), even though authentication would normally be
+ * required. This means that if you tap the screen or press the power button, you'll return
+ * directly to the unlocked app content without seeing the lockscreen, even if a secure
+ * authentication method (PIN/password/biometrics) is set.
+ *
+ * This is true in these cases:
+ * - The screen timed out, but the "lock after screen timeout" duration (default 5 seconds) has
+ * not yet elapsed.
+ * - The power button was pressed, but "power button instantly locks" is not enabled, and the
+ * "lock after screen timeout" duration has not elapsed.
+ *
+ * Note that this value specifically tells us if we can *ignore* authentication that would
+ * otherwise be required to transition from AOD/DOZING -> GONE. AOD/DOZING -> GONE is also
+ * possible if keyguard is disabled, either from an app request or because security is set to
+ * "none", but in that case, auth is not required so this boolean is not relevant.
+ *
+ * See [KeyguardWakeToGoneInteractor].
+ */
+ val canIgnoreAuthAndReturnToGone: StateFlow<Boolean>
+
+ fun setCanIgnoreAuthAndReturnToGone(canWake: Boolean)
+
/** Is the always-on display available to be used? */
val isAodAvailable: StateFlow<Boolean>
@@ -362,30 +387,8 @@ constructor(
override val topClippingBounds = MutableStateFlow<Int?>(null)
- override val isKeyguardShowing: Flow<Boolean> =
- conflatedCallbackFlow {
- val callback =
- object : KeyguardStateController.Callback {
- override fun onKeyguardShowingChanged() {
- trySendWithFailureLogging(
- keyguardStateController.isShowing,
- TAG,
- "updated isKeyguardShowing"
- )
- }
- }
-
- keyguardStateController.addCallback(callback)
- // Adding the callback does not send an initial update.
- trySendWithFailureLogging(
- keyguardStateController.isShowing,
- TAG,
- "initial isKeyguardShowing"
- )
-
- awaitClose { keyguardStateController.removeCallback(callback) }
- }
- .distinctUntilChanged()
+ override val isKeyguardShowing: MutableStateFlow<Boolean> =
+ MutableStateFlow(keyguardStateController.isShowing)
private val _isAodAvailable = MutableStateFlow(false)
override val isAodAvailable: StateFlow<Boolean> = _isAodAvailable.asStateFlow()
@@ -394,96 +397,26 @@ constructor(
_isAodAvailable.value = value
}
- override val isKeyguardOccluded: Flow<Boolean> =
- conflatedCallbackFlow {
- val callback =
- object : KeyguardStateController.Callback {
- override fun onKeyguardShowingChanged() {
- trySendWithFailureLogging(
- keyguardStateController.isOccluded,
- TAG,
- "updated isKeyguardOccluded"
- )
- }
- }
-
- keyguardStateController.addCallback(callback)
- // Adding the callback does not send an initial update.
- trySendWithFailureLogging(
- keyguardStateController.isOccluded,
- TAG,
- "initial isKeyguardOccluded"
- )
-
- awaitClose { keyguardStateController.removeCallback(callback) }
- }
- .distinctUntilChanged()
-
- override val isKeyguardDismissible: StateFlow<Boolean> =
- conflatedCallbackFlow {
- val callback =
- object : KeyguardStateController.Callback {
- override fun onUnlockedChanged() {
- trySendWithFailureLogging(
- keyguardStateController.isUnlocked,
- TAG,
- "updated isKeyguardDismissible due to onUnlockedChanged"
- )
- }
-
- override fun onKeyguardShowingChanged() {
- trySendWithFailureLogging(
- keyguardStateController.isUnlocked,
- TAG,
- "updated isKeyguardDismissible due to onKeyguardShowingChanged"
- )
- }
- }
-
- keyguardStateController.addCallback(callback)
- // Adding the callback does not send an initial update.
- trySendWithFailureLogging(
- keyguardStateController.isUnlocked,
- TAG,
- "initial isKeyguardUnlocked"
- )
+ override val isKeyguardOccluded: MutableStateFlow<Boolean> =
+ MutableStateFlow(keyguardStateController.isOccluded)
- awaitClose { keyguardStateController.removeCallback(callback) }
- }
- .distinctUntilChanged()
- .stateIn(
- scope,
- SharingStarted.Eagerly,
- initialValue = false,
- )
-
- override val isKeyguardGoingAway: Flow<Boolean> = conflatedCallbackFlow {
- val callback =
- object : KeyguardStateController.Callback {
- override fun onKeyguardGoingAwayChanged() {
- trySendWithFailureLogging(
- keyguardStateController.isKeyguardGoingAway,
- TAG,
- "updated isKeyguardGoingAway"
- )
- }
- }
-
- keyguardStateController.addCallback(callback)
- // Adding the callback does not send an initial update.
- trySendWithFailureLogging(
- keyguardStateController.isKeyguardGoingAway,
- TAG,
- "initial isKeyguardGoingAway"
- )
+ override val isKeyguardDismissible: MutableStateFlow<Boolean> =
+ MutableStateFlow(keyguardStateController.isUnlocked)
- awaitClose { keyguardStateController.removeCallback(callback) }
- }
+ override val isKeyguardGoingAway: MutableStateFlow<Boolean> =
+ MutableStateFlow(keyguardStateController.isKeyguardGoingAway)
private val _isKeyguardEnabled =
MutableStateFlow(!lockPatternUtils.isLockScreenDisabled(userTracker.userId))
override val isKeyguardEnabled: StateFlow<Boolean> = _isKeyguardEnabled.asStateFlow()
+ private val _canIgnoreAuthAndReturnToGone = MutableStateFlow(false)
+ override val canIgnoreAuthAndReturnToGone = _canIgnoreAuthAndReturnToGone.asStateFlow()
+
+ override fun setCanIgnoreAuthAndReturnToGone(canWakeToGone: Boolean) {
+ _canIgnoreAuthAndReturnToGone.value = canWakeToGone
+ }
+
private val _isDozing = MutableStateFlow(statusBarStateController.isDozing)
override val isDozing: StateFlow<Boolean> = _isDozing.asStateFlow()
@@ -669,6 +602,35 @@ constructor(
private val _isActiveDreamLockscreenHosted = MutableStateFlow(false)
override val isActiveDreamLockscreenHosted = _isActiveDreamLockscreenHosted.asStateFlow()
+ init {
+ val callback =
+ object : KeyguardStateController.Callback {
+ override fun onKeyguardShowingChanged() {
+ isKeyguardShowing.value = keyguardStateController.isShowing
+ isKeyguardOccluded.value = keyguardStateController.isOccluded
+ isKeyguardDismissible.value = keyguardStateController.isUnlocked
+ }
+
+ override fun onUnlockedChanged() {
+ isKeyguardDismissible.value = keyguardStateController.isUnlocked
+ }
+
+ override fun onKeyguardGoingAwayChanged() {
+ isKeyguardGoingAway.value = keyguardStateController.isKeyguardGoingAway
+ }
+ }
+
+ keyguardStateController.addCallback(callback)
+
+ scope
+ .launch {
+ isKeyguardShowing.collect {
+ // no-op to allow for callback removal
+ }
+ }
+ .invokeOnCompletion { keyguardStateController.removeCallback(callback) }
+ }
+
override fun setAnimateDozingTransitions(animate: Boolean) {
_animateBottomAreaDozingTransitions.value = animate
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
index 5573f0d5f644..b44a8cf70328 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
@@ -56,6 +56,7 @@ class FromAlternateBouncerTransitionInteractor
@Inject
constructor(
override val transitionRepository: KeyguardTransitionRepository,
+ override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
transitionInteractor: KeyguardTransitionInteractor,
@Background private val scope: CoroutineScope,
@Background bgDispatcher: CoroutineDispatcher,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
index 2a9ee9fb8779..893835a38c53 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
@@ -44,6 +44,7 @@ class FromAodTransitionInteractor
@Inject
constructor(
override val transitionRepository: KeyguardTransitionRepository,
+ override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
transitionInteractor: KeyguardTransitionInteractor,
@Background private val scope: CoroutineScope,
@Background bgDispatcher: CoroutineDispatcher,
@@ -52,6 +53,7 @@ constructor(
powerInteractor: PowerInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
val deviceEntryRepository: DeviceEntryRepository,
+ private val wakeToGoneInteractor: KeyguardWakeDirectlyToGoneInteractor,
) :
TransitionInteractor(
fromState = KeyguardState.AOD,
@@ -97,6 +99,7 @@ constructor(
keyguardInteractor.primaryBouncerShowing,
keyguardInteractor.isKeyguardOccluded,
canDismissLockscreen,
+ wakeToGoneInteractor.canWakeDirectlyToGone,
)
.collect {
(
@@ -106,6 +109,7 @@ constructor(
primaryBouncerShowing,
isKeyguardOccludedLegacy,
canDismissLockscreen,
+ canWakeDirectlyToGone,
) ->
if (!maybeHandleInsecurePowerGesture()) {
val shouldTransitionToLockscreen =
@@ -130,10 +134,11 @@ constructor(
val shouldTransitionToGone =
(!KeyguardWmStateRefactor.isEnabled && canDismissLockscreen) ||
- (KeyguardWmStateRefactor.isEnabled &&
- !deviceEntryRepository.isLockscreenEnabled())
+ (KeyguardWmStateRefactor.isEnabled && canWakeDirectlyToGone)
if (shouldTransitionToGone) {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ if (SceneContainerFlag.isEnabled) return@collect
startTransitionTo(
toState = KeyguardState.GONE,
)
@@ -194,6 +199,7 @@ constructor(
* PRIMARY_BOUNCER.
*/
private fun listenForAodToPrimaryBouncer() {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
if (SceneContainerFlag.isEnabled) return
scope.launch("$TAG#listenForAodToPrimaryBouncer") {
keyguardInteractor.primaryBouncerShowing
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index b423ed980060..cd28bec938b8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -17,8 +17,11 @@
package com.android.systemui.keyguard.domain.interactor
import android.animation.ValueAnimator
+import android.annotation.SuppressLint
+import android.app.DreamManager
import com.android.app.animation.Interpolators
import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -28,6 +31,8 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor
import com.android.systemui.keyguard.shared.model.BiometricUnlockMode.Companion.isWakeAndUnlock
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.util.kotlin.Utils.Companion.sample
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
@@ -44,6 +49,7 @@ class FromDozingTransitionInteractor
@Inject
constructor(
override val transitionRepository: KeyguardTransitionRepository,
+ override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
transitionInteractor: KeyguardTransitionInteractor,
@Background private val scope: CoroutineScope,
@Background bgDispatcher: CoroutineDispatcher,
@@ -51,8 +57,11 @@ constructor(
keyguardInteractor: KeyguardInteractor,
powerInteractor: PowerInteractor,
private val communalInteractor: CommunalInteractor,
+ private val communalSceneInteractor: CommunalSceneInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
val deviceEntryRepository: DeviceEntryRepository,
+ private val wakeToGoneInteractor: KeyguardWakeDirectlyToGoneInteractor,
+ private val dreamManager: DreamManager,
) :
TransitionInteractor(
fromState = KeyguardState.DOZING,
@@ -99,15 +108,20 @@ constructor(
biometricUnlockState,
) ->
if (isWakeAndUnlock(biometricUnlockState.mode)) {
- startTransitionTo(
- KeyguardState.GONE,
- ownerReason = "biometric wake and unlock",
- )
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ } else {
+ startTransitionTo(
+ KeyguardState.GONE,
+ ownerReason = "biometric wake and unlock",
+ )
+ }
}
}
}
}
+ @SuppressLint("MissingPermission")
private fun listenForDozingToAny() {
if (KeyguardWmStateRefactor.isEnabled) {
return
@@ -119,7 +133,8 @@ constructor(
.filterRelevantKeyguardStateAnd { isAwake -> isAwake }
.sample(
keyguardInteractor.isKeyguardOccluded,
- communalInteractor.isIdleOnCommunal,
+ communalInteractor.isCommunalAvailable,
+ communalSceneInteractor.isIdleOnCommunal,
canTransitionToGoneOnWake,
keyguardInteractor.primaryBouncerShowing,
)
@@ -127,29 +142,58 @@ constructor(
(
_,
occluded,
+ isCommunalAvailable,
isIdleOnCommunal,
canTransitionToGoneOnWake,
primaryBouncerShowing) ->
- startTransitionTo(
- if (!deviceEntryRepository.isLockscreenEnabled()) {
- KeyguardState.GONE
- } else if (canTransitionToGoneOnWake) {
- KeyguardState.GONE
- } else if (primaryBouncerShowing) {
- KeyguardState.PRIMARY_BOUNCER
- } else if (occluded) {
- KeyguardState.OCCLUDED
- } else if (isIdleOnCommunal) {
- KeyguardState.GLANCEABLE_HUB
+ if (!deviceEntryRepository.isLockscreenEnabled()) {
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ } else {
+ startTransitionTo(KeyguardState.GONE)
+ }
+ } else if (canTransitionToGoneOnWake) {
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ } else {
+ startTransitionTo(KeyguardState.GONE)
+ }
+ } else if (primaryBouncerShowing) {
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ } else {
+ startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
+ }
+ } else if (occluded) {
+ startTransitionTo(KeyguardState.OCCLUDED)
+ } else if (isIdleOnCommunal) {
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ } else {
+ startTransitionTo(KeyguardState.GLANCEABLE_HUB)
+ }
+ } else if (
+ powerInteractor.detailedWakefulness.value.lastWakeReason ==
+ WakeSleepReason.POWER_BUTTON &&
+ isCommunalAvailable &&
+ dreamManager.canStartDreaming(true)
+ ) {
+ // This case handles tapping the power button to transition through
+ // dream -> off -> hub.
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
} else {
- KeyguardState.LOCKSCREEN
+ startTransitionTo(KeyguardState.GLANCEABLE_HUB)
}
- )
+ } else {
+ startTransitionTo(KeyguardState.LOCKSCREEN)
+ }
}
}
}
/** Figure out what state to transition to when we awake from DOZING. */
+ @SuppressLint("MissingPermission")
private fun listenForWakeFromDozing() {
if (!KeyguardWmStateRefactor.isEnabled) {
return
@@ -159,40 +203,78 @@ constructor(
powerInteractor.detailedWakefulness
.filterRelevantKeyguardStateAnd { it.isAwake() }
.sample(
- communalInteractor.isIdleOnCommunal,
+ communalInteractor.isCommunalAvailable,
+ communalSceneInteractor.isIdleOnCommunal,
keyguardInteractor.biometricUnlockState,
- canTransitionToGoneOnWake,
+ wakeToGoneInteractor.canWakeDirectlyToGone,
keyguardInteractor.primaryBouncerShowing,
)
.collect {
(
_,
+ isCommunalAvailable,
isIdleOnCommunal,
biometricUnlockState,
- canDismissLockscreen,
+ canWakeDirectlyToGone,
primaryBouncerShowing) ->
if (
!maybeStartTransitionToOccludedOrInsecureCamera() &&
// Handled by dismissFromDozing().
!isWakeAndUnlock(biometricUnlockState.mode)
) {
- startTransitionTo(
- if (!KeyguardWmStateRefactor.isEnabled && canDismissLockscreen) {
- KeyguardState.GONE
- } else if (
- KeyguardWmStateRefactor.isEnabled &&
- !deviceEntryRepository.isLockscreenEnabled()
- ) {
- KeyguardState.GONE
- } else if (primaryBouncerShowing) {
- KeyguardState.PRIMARY_BOUNCER
- } else if (isIdleOnCommunal) {
- KeyguardState.GLANCEABLE_HUB
+ if (canWakeDirectlyToGone) {
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is
+ // needed
+ } else {
+ startTransitionTo(
+ KeyguardState.GONE,
+ ownerReason = "waking from dozing"
+ )
+ }
+ } else if (primaryBouncerShowing) {
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is
+ // needed
} else {
- KeyguardState.LOCKSCREEN
- },
- ownerReason = "waking from dozing"
- )
+ startTransitionTo(
+ KeyguardState.PRIMARY_BOUNCER,
+ ownerReason = "waking from dozing"
+ )
+ }
+ } else if (isIdleOnCommunal) {
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is
+ // needed
+ } else {
+ startTransitionTo(
+ KeyguardState.GLANCEABLE_HUB,
+ ownerReason = "waking from dozing"
+ )
+ }
+ } else if (
+ powerInteractor.detailedWakefulness.value.lastWakeReason ==
+ WakeSleepReason.POWER_BUTTON &&
+ isCommunalAvailable &&
+ dreamManager.canStartDreaming(true)
+ ) {
+ // This case handles tapping the power button to transition through
+ // dream -> off -> hub.
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is
+ // needed
+ } else {
+ startTransitionTo(
+ KeyguardState.GLANCEABLE_HUB,
+ ownerReason = "waking from dozing"
+ )
+ }
+ } else {
+ startTransitionTo(
+ KeyguardState.LOCKSCREEN,
+ ownerReason = "waking from dozing"
+ )
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt
index 47aa02a0be52..117dbcfe52c8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt
@@ -41,6 +41,7 @@ class FromDreamingLockscreenHostedTransitionInteractor
@Inject
constructor(
override val transitionRepository: KeyguardTransitionRepository,
+ override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
transitionInteractor: KeyguardTransitionInteractor,
@Background private val scope: CoroutineScope,
@Background bgDispatcher: CoroutineDispatcher,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
index 7fa197c11e57..453401d2aa7d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
@@ -19,10 +19,11 @@ package com.android.systemui.keyguard.domain.interactor
import android.animation.ValueAnimator
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launch
-import com.android.systemui.Flags.communalHub
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.keyguard.KeyguardWmStateRefactor
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.BiometricUnlockMode
@@ -37,24 +38,30 @@ import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch
+@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
class FromDreamingTransitionInteractor
@Inject
constructor(
override val transitionRepository: KeyguardTransitionRepository,
+ override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
transitionInteractor: KeyguardTransitionInteractor,
@Background private val scope: CoroutineScope,
@Background bgDispatcher: CoroutineDispatcher,
@Main mainDispatcher: CoroutineDispatcher,
keyguardInteractor: KeyguardInteractor,
private val glanceableHubTransitions: GlanceableHubTransitions,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
powerInteractor: PowerInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
+ private val deviceEntryInteractor: DeviceEntryInteractor,
) :
TransitionInteractor(
fromState = KeyguardState.DREAMING,
@@ -71,7 +78,7 @@ constructor(
listenForDreamingToOccluded()
listenForDreamingToGoneWhenDismissable()
listenForDreamingToGoneFromBiometricUnlock()
- listenForDreamingToLockscreen()
+ listenForDreamingToLockscreenOrGone()
listenForDreamingToAodOrDozing()
listenForTransitionToCamera(scope, keyguardInteractor)
listenForDreamingToGlanceableHub()
@@ -89,9 +96,9 @@ constructor(
}
private fun listenForDreamingToGlanceableHub() {
- if (!communalHub()) return
- if (SceneContainerFlag.isEnabled)
- return // TODO(b/336576536): Check if adaptation for scene framework is needed
+ if (!communalSettingsInteractor.isCommunalFlagEnabled()) return
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ if (SceneContainerFlag.isEnabled) return
scope.launch("$TAG#listenForDreamingToGlanceableHub", mainDispatcher) {
glanceableHubTransitions.listenForGlanceableHubTransition(
transitionOwnerName = TAG,
@@ -102,6 +109,8 @@ constructor(
}
private fun listenForDreamingToPrimaryBouncer() {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ if (SceneContainerFlag.isEnabled) return
scope.launch {
keyguardInteractor.primaryBouncerShowing
.sample(startedKeyguardTransitionStep, ::Pair)
@@ -129,17 +138,7 @@ constructor(
@OptIn(FlowPreview::class)
private fun listenForDreamingToOccluded() {
- if (KeyguardWmStateRefactor.isEnabled) {
- scope.launch {
- combine(
- keyguardInteractor.isDreaming,
- keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop,
- ::Pair
- )
- .filterRelevantKeyguardStateAnd { (isDreaming, _) -> !isDreaming }
- .collect { maybeStartTransitionToOccludedOrInsecureCamera() }
- }
- } else {
+ if (!KeyguardWmStateRefactor.isEnabled) {
scope.launch {
combine(
keyguardInteractor.isKeyguardOccluded,
@@ -165,21 +164,41 @@ constructor(
}
}
- private fun listenForDreamingToLockscreen() {
+ private fun listenForDreamingToLockscreenOrGone() {
if (!KeyguardWmStateRefactor.isEnabled) {
return
}
scope.launch {
- keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop
- .filterRelevantKeyguardStateAnd { onTop -> !onTop }
- .collect { startTransitionTo(KeyguardState.LOCKSCREEN) }
+ keyguardInteractor.isDreaming
+ .filter { !it }
+ .sample(deviceEntryInteractor.isUnlocked, ::Pair)
+ .collect { (_, dismissable) ->
+ // TODO(b/349837588): Add check for -> OCCLUDED.
+ if (dismissable) {
+ startTransitionTo(
+ KeyguardState.GONE,
+ ownerReason = "No longer dreaming; dismissable"
+ )
+ } else {
+ startTransitionTo(
+ KeyguardState.LOCKSCREEN,
+ ownerReason = "No longer dreaming"
+ )
+ }
+ }
}
}
private fun listenForDreamingToGoneWhenDismissable() {
- if (SceneContainerFlag.isEnabled)
+ if (SceneContainerFlag.isEnabled) {
return // TODO(b/336576536): Check if adaptation for scene framework is needed
+ }
+
+ if (KeyguardWmStateRefactor.isEnabled) {
+ return
+ }
+
scope.launch {
keyguardInteractor.isAbleToDream
.sampleCombine(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
index e516fa3c44bb..1a7012abdbe7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
@@ -19,7 +19,7 @@ package com.android.systemui.keyguard.domain.interactor
import android.animation.ValueAnimator
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launch
-import com.android.systemui.Flags
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -48,8 +48,10 @@ constructor(
@Main mainDispatcher: CoroutineDispatcher,
@Background bgDispatcher: CoroutineDispatcher,
private val glanceableHubTransitions: GlanceableHubTransitions,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
keyguardInteractor: KeyguardInteractor,
override val transitionRepository: KeyguardTransitionRepository,
+ override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
transitionInteractor: KeyguardTransitionInteractor,
powerInteractor: PowerInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
@@ -67,7 +69,7 @@ constructor(
override fun start() {
// TODO(b/336576536): Check if adaptation for scene framework is needed
if (SceneContainerFlag.isEnabled) return
- if (!Flags.communalHub()) {
+ if (!communalSettingsInteractor.isCommunalFlagEnabled()) {
return
}
listenForHubToLockscreenOrDreaming()
@@ -166,6 +168,8 @@ constructor(
}
private fun listenForHubToGone() {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ if (SceneContainerFlag.isEnabled) return
scope.launch {
keyguardInteractor.isKeyguardGoingAway
.filterRelevantKeyguardStateAnd { isKeyguardGoingAway -> isKeyguardGoingAway }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
index 07a2b0424aba..b084824cd348 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
@@ -45,6 +45,7 @@ class FromGoneTransitionInteractor
@Inject
constructor(
override val transitionRepository: KeyguardTransitionRepository,
+ override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
transitionInteractor: KeyguardTransitionInteractor,
@Background private val scope: CoroutineScope,
@Background bgDispatcher: CoroutineDispatcher,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 35a2d58816b4..5c7adf0c5a8a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -20,7 +20,7 @@ import android.animation.ValueAnimator
import android.util.MathUtils
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launch
-import com.android.systemui.Flags
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -57,6 +57,7 @@ class FromLockscreenTransitionInteractor
@Inject
constructor(
override val transitionRepository: KeyguardTransitionRepository,
+ override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
transitionInteractor: KeyguardTransitionInteractor,
@Background private val scope: CoroutineScope,
@Background bgDispatcher: CoroutineDispatcher,
@@ -65,6 +66,7 @@ constructor(
private val shadeRepository: ShadeRepository,
powerInteractor: PowerInteractor,
private val glanceableHubTransitions: GlanceableHubTransitions,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
private val swipeToDismissInteractor: SwipeToDismissInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
) :
@@ -128,7 +130,7 @@ constructor(
keyguardInteractor.isAbleToDream
.filterRelevantKeyguardState()
.sampleCombine(
- transitionInteractor.currentTransitionInfoInternal,
+ internalTransitionInteractor.currentTransitionInfoInternal,
finishedKeyguardState,
keyguardInteractor.isActiveDreamLockscreenHosted,
)
@@ -185,7 +187,7 @@ constructor(
shadeRepository.legacyShadeExpansion
.sampleCombine(
startedKeyguardTransitionStep,
- transitionInteractor.currentTransitionInfoInternal,
+ internalTransitionInteractor.currentTransitionInfoInternal,
keyguardInteractor.statusBarState,
keyguardInteractor.isKeyguardDismissible,
)
@@ -271,10 +273,9 @@ constructor(
}
private fun listenForLockscreenToGone() {
- if (KeyguardWmStateRefactor.isEnabled) {
- return
- }
-
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ if (SceneContainerFlag.isEnabled) return
+ if (KeyguardWmStateRefactor.isEnabled) return
scope.launch("$TAG#listenForLockscreenToGone") {
keyguardInteractor.isKeyguardGoingAway
.filterRelevantKeyguardStateAnd { isKeyguardGoingAway -> isKeyguardGoingAway }
@@ -288,6 +289,7 @@ constructor(
}
private fun listenForLockscreenToGoneDragging() {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
if (SceneContainerFlag.isEnabled) return
if (KeyguardWmStateRefactor.isEnabled) {
// When the refactor is enabled, we no longer use isKeyguardGoingAway.
@@ -348,7 +350,7 @@ constructor(
private fun listenForLockscreenToGlanceableHub() {
// TODO(b/336576536): Check if adaptation for scene framework is needed
if (SceneContainerFlag.isEnabled) return
- if (!Flags.communalHub()) {
+ if (!communalSettingsInteractor.isCommunalFlagEnabled()) {
return
}
scope.launch(mainDispatcher) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
index 86d4cfb916ed..f3ca9df6491c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
@@ -41,6 +41,7 @@ class FromOccludedTransitionInteractor
@Inject
constructor(
override val transitionRepository: KeyguardTransitionRepository,
+ override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
transitionInteractor: KeyguardTransitionInteractor,
@Background private val scope: CoroutineScope,
@Background bgDispatcher: CoroutineDispatcher,
@@ -70,6 +71,8 @@ constructor(
}
private fun listenForOccludedToPrimaryBouncer() {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ if (SceneContainerFlag.isEnabled) return
scope.launch {
keyguardInteractor.primaryBouncerShowing
.filterRelevantKeyguardStateAnd { isBouncerShowing -> isBouncerShowing }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
index f23b12f35977..24290881a0fb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
@@ -40,7 +40,6 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
@@ -50,6 +49,7 @@ class FromPrimaryBouncerTransitionInteractor
@Inject
constructor(
override val transitionRepository: KeyguardTransitionRepository,
+ override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
transitionInteractor: KeyguardTransitionInteractor,
@Background private val scope: CoroutineScope,
@Background bgDispatcher: CoroutineDispatcher,
@@ -80,25 +80,18 @@ constructor(
}
val surfaceBehindVisibility: Flow<Boolean?> =
- if (SceneContainerFlag.isEnabled) {
- // The edge Scenes.Bouncer <-> Scenes.Gone is handled by STL
- flowOf(null)
- } else {
- transitionInteractor
- .transition(
- edge = Edge.INVALID,
- edgeWithoutSceneContainer =
- Edge.create(from = KeyguardState.PRIMARY_BOUNCER, to = KeyguardState.GONE)
- )
- .map<TransitionStep, Boolean?> {
- it.value > TO_GONE_SURFACE_BEHIND_VISIBLE_THRESHOLD
- }
- .onStart {
- // Default to null ("don't care, use a reasonable default").
- emit(null)
- }
- .distinctUntilChanged()
- }
+ transitionInteractor
+ .transition(
+ edge = Edge.INVALID,
+ edgeWithoutSceneContainer =
+ Edge.create(from = KeyguardState.PRIMARY_BOUNCER, to = KeyguardState.GONE)
+ )
+ .map<TransitionStep, Boolean?> { it.value > TO_GONE_SURFACE_BEHIND_VISIBLE_THRESHOLD }
+ .onStart {
+ // Default to null ("don't care, use a reasonable default").
+ emit(null)
+ }
+ .distinctUntilChanged()
fun dismissPrimaryBouncer() {
scope.launch { startTransitionTo(KeyguardState.GONE) }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt
new file mode 100644
index 000000000000..a51421c10309
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.keyguard.domain.interactor
+
+import android.annotation.FloatRange
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.TransitionInfo
+import com.android.systemui.keyguard.shared.model.TransitionState
+import java.util.UUID
+import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
+
+/**
+ * This interactor provides direct access to [KeyguardTransitionRepository] internals and exposes
+ * functions to directly modify the transition state.
+ */
+@SysUISingleton
+class InternalKeyguardTransitionInteractor
+@Inject
+constructor(
+ private val repository: KeyguardTransitionRepository,
+) {
+
+ /**
+ * The [TransitionInfo] of the most recent call to
+ * [KeyguardTransitionRepository.startTransition].
+ *
+ * This should only be used by keyguard transition internals (From*TransitionInteractor and
+ * related classes). Other consumers of keyguard state in System UI should use
+ * [startedKeyguardState], [currentKeyguardState], and related flows.
+ *
+ * Keyguard internals use this to determine the most up-to-date KeyguardState that we've
+ * requested a transition to, even if the animator running the transition on the main thread has
+ * not yet emitted the STARTED TransitionStep.
+ *
+ * For example: if we're finished in GONE and press the power button twice very quickly, we may
+ * request a transition to AOD, but then receive the second power button press prior to the
+ * STARTED -> AOD transition step emitting. We still need the FromAodTransitionInteractor to
+ * request a transition from AOD -> LOCKSCREEN in response to the power press, even though the
+ * main thread animator hasn't emitted STARTED > AOD yet (which means [startedKeyguardState] is
+ * still GONE, which is not relevant to FromAodTransitionInteractor). In this case, the
+ * interactor can use this current transition info to determine that a STARTED -> AOD step
+ * *will* be emitted, and therefore that it can safely request an AOD -> LOCKSCREEN transition
+ * which will subsequently cancel GONE -> AOD.
+ */
+ internal val currentTransitionInfoInternal: StateFlow<TransitionInfo> =
+ repository.currentTransitionInfoInternal
+
+ suspend fun startTransition(info: TransitionInfo) = repository.startTransition(info)
+
+ fun updateTransition(
+ transitionId: UUID,
+ @FloatRange(from = 0.0, to = 1.0) value: Float,
+ state: TransitionState
+ ) = repository.updateTransition(transitionId, value, state)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
index 41c39597dc02..e2bb540f6645 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
@@ -19,7 +19,6 @@
package com.android.systemui.keyguard.domain.interactor
-import android.content.Context
import com.android.systemui.CoreStartable
import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
@@ -32,15 +31,12 @@ import com.android.systemui.keyguard.ui.view.layout.blueprints.DefaultKeyguardBl
import com.android.systemui.keyguard.ui.view.layout.blueprints.SplitShadeKeyguardBlueprint
import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Config
import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Type
-import com.android.systemui.keyguard.ui.view.layout.sections.ClockSection
import com.android.systemui.keyguard.ui.view.layout.sections.SmartspaceSection
import com.android.systemui.shade.domain.interactor.ShadeInteractor
-import com.android.systemui.shade.shared.model.ShadeMode
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
@@ -51,13 +47,10 @@ class KeyguardBlueprintInteractor
constructor(
private val keyguardBlueprintRepository: KeyguardBlueprintRepository,
@Application private val applicationScope: CoroutineScope,
- private val context: Context,
- private val shadeInteractor: ShadeInteractor,
- private val clockInteractor: KeyguardClockInteractor,
+ shadeInteractor: ShadeInteractor,
private val configurationInteractor: ConfigurationInteractor,
private val fingerprintPropertyInteractor: FingerprintPropertyInteractor,
private val smartspaceSection: SmartspaceSection,
- private val clockSection: ClockSection,
) : CoreStartable {
/** The current blueprint for the lockscreen. */
val blueprint: StateFlow<KeyguardBlueprint> = keyguardBlueprintRepository.blueprint
@@ -70,8 +63,8 @@ constructor(
/** Current BlueprintId */
val blueprintId =
- shadeInteractor.shadeMode.map { shadeMode ->
- val useSplitShade = shadeMode == ShadeMode.Split && !ComposeLockscreen.isEnabled
+ shadeInteractor.isShadeLayoutWide.map { isShadeLayoutWide ->
+ val useSplitShade = isShadeLayoutWide && !ComposeLockscreen.isEnabled
when {
useSplitShade -> SplitShadeKeyguardBlueprint.ID
else -> DefaultKeyguardBlueprint.DEFAULT
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
index 142b1a031277..c0049d4e2e6c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
@@ -31,7 +31,6 @@ import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.plugins.clocks.ClockId
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.domain.interactor.ShadeInteractor
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
import com.android.systemui.util.kotlin.combine
@@ -45,6 +44,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
private val TAG = KeyguardClockInteractor::class.simpleName
+
/** Manages and encapsulates the clock components of the lockscreen root view. */
@SysUISingleton
class KeyguardClockInteractor
@@ -77,16 +77,16 @@ constructor(
val clockSize: StateFlow<ClockSize> =
if (SceneContainerFlag.isEnabled) {
combine(
- shadeInteractor.shadeMode,
+ shadeInteractor.isShadeLayoutWide,
activeNotificationsInteractor.areAnyNotificationsPresent,
mediaCarouselInteractor.hasActiveMediaOrRecommendation,
keyguardInteractor.isDozing,
isOnAod,
- ) { shadeMode, hasNotifs, hasMedia, isDozing, isOnAod ->
+ ) { isShadeLayoutWide, hasNotifs, hasMedia, isDozing, isOnAod ->
return@combine when {
keyguardClockRepository.shouldForceSmallClock && !isOnAod -> ClockSize.SMALL
- shadeMode == ShadeMode.Single && (hasNotifs || hasMedia) -> ClockSize.SMALL
- shadeMode == ShadeMode.Single -> ClockSize.LARGE
+ !isShadeLayoutWide && (hasNotifs || hasMedia) -> ClockSize.SMALL
+ !isShadeLayoutWide -> ClockSize.LARGE
hasMedia && !isDozing -> ClockSize.SMALL
else -> ClockSize.LARGE
}
@@ -103,21 +103,21 @@ constructor(
val clockShouldBeCentered: Flow<Boolean> =
if (SceneContainerFlag.isEnabled) {
combine(
- shadeInteractor.shadeMode,
+ shadeInteractor.isShadeLayoutWide,
activeNotificationsInteractor.areAnyNotificationsPresent,
keyguardInteractor.isActiveDreamLockscreenHosted,
isOnAod,
headsUpNotificationInteractor.isHeadsUpOrAnimatingAway,
keyguardInteractor.isDozing,
) {
- shadeMode,
+ isShadeLayoutWide,
areAnyNotificationsPresent,
isActiveDreamLockscreenHosted,
isOnAod,
isHeadsUp,
isDozing ->
when {
- shadeMode != ShadeMode.Split -> true
+ !isShadeLayoutWide -> true
!areAnyNotificationsPresent -> true
isActiveDreamLockscreenHosted -> true
// Pulsing notification appears on the right. Move clock left to avoid overlap.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
index 1aac1c5940b3..f4d82659971d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt
@@ -25,9 +25,8 @@ import com.android.systemui.keyguard.shared.model.KeyguardDone
import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
-import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -35,6 +34,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNot
import kotlinx.coroutines.flow.map
@@ -51,7 +51,6 @@ constructor(
transitionInteractor: KeyguardTransitionInteractor,
val dismissInteractor: KeyguardDismissInteractor,
@Application private val applicationScope: CoroutineScope,
- sceneInteractor: SceneInteractor,
) {
val dismissAction: Flow<DismissAction> = repository.dismissAction
@@ -76,11 +75,10 @@ constructor(
)
private val finishedTransitionToGone: Flow<Unit> =
- if (SceneContainerFlag.isEnabled) {
- sceneInteractor.transitionState.filter { it.isIdle(Scenes.Gone) }.map {}
- } else {
- transitionInteractor.finishedKeyguardState.filter { it == GONE }.map {}
- }
+ transitionInteractor
+ .isFinishedIn(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+ .filter { it }
+ .map {}
val executeDismissAction: Flow<() -> KeyguardDone> =
merge(
@@ -90,12 +88,24 @@ constructor(
.sample(dismissAction)
.filterNot { it is DismissAction.None }
.map { it.onDismissAction }
+
val resetDismissAction: Flow<Unit> =
- transitionInteractor.finishedKeyguardTransitionStep
- .filter { it.to != ALTERNATE_BOUNCER && it.to != PRIMARY_BOUNCER && it.to != GONE }
- .sample(dismissAction)
- .filterNot { it is DismissAction.None }
- .map {} // map to Unit
+ combine(
+ transitionInteractor.isFinishedIn(
+ scene = Scenes.Gone,
+ stateWithoutSceneContainer = GONE
+ ),
+ transitionInteractor.isFinishedIn(
+ scene = Scenes.Bouncer,
+ stateWithoutSceneContainer = PRIMARY_BOUNCER
+ ),
+ transitionInteractor.isFinishedIn(state = ALTERNATE_BOUNCER)
+ ) { isOnGone, isOnBouncer, isOnAltBouncer ->
+ !isOnGone && !isOnBouncer && !isOnAltBouncer
+ }
+ .filter { it }
+ .sampleFilter(dismissAction) { it !is DismissAction.None }
+ .map {}
fun runDismissAnimationOnKeyguard(): Boolean {
return willAnimateDismissActionOnLockscreen.value
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt
index 8d683f0d4375..4aef8084e5e7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt
@@ -49,6 +49,7 @@ constructor(
val repository: KeyguardRepository,
val biometricSettingsRepository: BiometricSettingsRepository,
transitionInteractor: KeyguardTransitionInteractor,
+ internalTransitionInteractor: InternalKeyguardTransitionInteractor,
) {
/**
@@ -74,7 +75,7 @@ constructor(
// Whenever the keyguard is disabled...
.filter { enabled -> !enabled }
.sampleCombine(
- transitionInteractor.currentTransitionInfoInternal,
+ internalTransitionInteractor.currentTransitionInfoInternal,
biometricSettingsRepository.isCurrentUserInLockdown
)
.map { (_, transitionInfo, inLockdown) ->
@@ -89,17 +90,13 @@ constructor(
* GONE.
*/
scope.launch {
- repository.isKeyguardEnabled
- .filter { enabled -> !enabled }
- .sampleCombine(
- biometricSettingsRepository.isCurrentUserInLockdown,
- transitionInteractor.currentTransitionInfoInternal,
- )
- .collect { (_, inLockdown, currentTransitionInfo) ->
- if (currentTransitionInfo.to != KeyguardState.GONE && !inLockdown) {
+ if (!SceneContainerFlag.isEnabled) {
+ showKeyguardWhenReenabled
+ .filter { shouldDismiss -> shouldDismiss }
+ .collect {
transitionInteractor.startDismissKeyguardTransition("keyguard disabled")
}
- }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 22ab82b383a7..ec03a6d8121f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -23,9 +23,10 @@ import android.app.StatusBarManager
import android.graphics.Point
import android.util.MathUtils
import com.android.app.animation.Interpolators
+import com.android.app.tracing.FlowTracing.tracedAwaitClose
+import com.android.app.tracing.FlowTracing.tracedConflatedCallbackFlow
import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.common.shared.model.NotificationContainerBounds
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
@@ -57,7 +58,6 @@ import javax.inject.Inject
import javax.inject.Provider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -197,22 +197,22 @@ constructor(
val isActiveDreamLockscreenHosted: StateFlow<Boolean> = repository.isActiveDreamLockscreenHosted
/** Event for when the camera gesture is detected */
- val onCameraLaunchDetected: Flow<CameraLaunchSourceModel> = conflatedCallbackFlow {
- val callback =
- object : CommandQueue.Callbacks {
- override fun onCameraLaunchGestureDetected(source: Int) {
- trySendWithFailureLogging(
- cameraLaunchSourceIntToModel(source),
- TAG,
- "updated onCameraLaunchGestureDetected"
- )
+ val onCameraLaunchDetected: Flow<CameraLaunchSourceModel> =
+ tracedConflatedCallbackFlow("KeyguardInteractor#onCameraLaunchDetected") {
+ val callback =
+ object : CommandQueue.Callbacks {
+ override fun onCameraLaunchGestureDetected(source: Int) {
+ trySendWithFailureLogging(
+ cameraLaunchSourceIntToModel(source),
+ TAG,
+ "updated onCameraLaunchGestureDetected")
+ }
}
- }
- commandQueue.addCallback(callback)
+ commandQueue.addCallback(callback)
- awaitClose { commandQueue.removeCallback(callback) }
- }
+ tracedAwaitClose("onCameraLaunchDetected") { commandQueue.removeCallback(callback) }
+ }
/**
* Dozing and dreaming have overlapping events. If the doze state remains in FINISH, it means
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
index f3856710b1ed..7f1e881c0863 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
@@ -24,6 +24,7 @@ import com.android.systemui.keyguard.data.repository.KeyguardOcclusionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.util.kotlin.sample
import dagger.Lazy
import javax.inject.Inject
@@ -53,6 +54,7 @@ constructor(
private val repository: KeyguardOcclusionRepository,
private val powerInteractor: PowerInteractor,
private val transitionInteractor: KeyguardTransitionInteractor,
+ private val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
keyguardInteractor: KeyguardInteractor,
deviceUnlockedInteractor: Lazy<DeviceUnlockedInteractor>,
) {
@@ -78,7 +80,7 @@ constructor(
// *_BOUNCER -> LOCKSCREEN.
return powerInteractor.detailedWakefulness.value.powerButtonLaunchGestureTriggered &&
KeyguardState.deviceIsAsleepInState(
- transitionInteractor.currentTransitionInfoInternal.value.to
+ internalTransitionInteractor.currentTransitionInfoInternal.value.to
)
}
@@ -93,10 +95,15 @@ constructor(
// currently
// GONE, in which case we're going back to GONE and launching the insecure camera).
powerInteractor.detailedWakefulness
- .sample(transitionInteractor.currentKeyguardState, ::Pair)
- .map { (wakefulness, currentKeyguardState) ->
- wakefulness.powerButtonLaunchGestureTriggered &&
- currentKeyguardState != KeyguardState.GONE
+ .sample(
+ transitionInteractor.isFinishedIn(
+ scene = Scenes.Gone,
+ stateWithoutSceneContainer = KeyguardState.GONE,
+ ),
+ ::Pair
+ )
+ .map { (wakefulness, isOnGone) ->
+ wakefulness.powerButtonLaunchGestureTriggered && !isOnGone
},
// Emit false once that activity goes away.
isShowWhenLockedActivityOnTop.filter { !it }.map { false }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
index 82255a0c0d54..377a03edf88d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
@@ -19,9 +19,10 @@ package com.android.systemui.keyguard.domain.interactor
import android.content.Context
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.repository.KeyguardSurfaceBehindRepository
-import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor.Companion.isSurfaceVisible
+import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
import com.android.systemui.util.kotlin.sample
import com.android.systemui.util.kotlin.toPx
@@ -56,12 +57,18 @@ constructor(
*/
val viewParams: Flow<KeyguardSurfaceBehindModel> =
combine(
- transitionInteractor.startedKeyguardTransitionStep,
- transitionInteractor.currentKeyguardState,
+ transitionInteractor.isInTransition(
+ edge = Edge.create(to = Scenes.Gone),
+ edgeWithoutSceneContainer = Edge.create(to = KeyguardState.GONE),
+ ),
+ transitionInteractor.isFinishedIn(
+ scene = Scenes.Gone,
+ stateWithoutSceneContainer = KeyguardState.GONE,
+ ),
notificationLaunchInteractor.isLaunchAnimationRunning,
- ) { startedStep, currentState, notifAnimationRunning ->
+ ) { transitioningToGone, isOnGone, notifAnimationRunning ->
// If we're in transition to GONE, special unlock animation params apply.
- if (startedStep.to == KeyguardState.GONE && currentState != KeyguardState.GONE) {
+ if (transitioningToGone) {
if (notifAnimationRunning) {
// If the notification launch animation is running, leave the alpha at 0f.
// The ActivityLaunchAnimator will morph it from the notification at the
@@ -87,14 +94,14 @@ constructor(
animateFromTranslationY =
SURFACE_TRANSLATION_Y_DISTANCE_DP.toPx(context).toFloat(),
translationY = 0f,
- startVelocity = swipeToDismissInteractor.dismissFling.value?.velocity
- ?: 0f,
+ startVelocity =
+ swipeToDismissInteractor.dismissFling.value?.velocity ?: 0f,
)
}
}
// Default to the visibility of the current state, with no animations.
- KeyguardSurfaceBehindModel(alpha = if (isSurfaceVisible(currentState)) 1f else 0f)
+ KeyguardSurfaceBehindModel(alpha = if (isOnGone) 1f else 0f)
}
.distinctUntilChanged()
@@ -103,10 +110,14 @@ constructor(
*/
private val isNotificationLaunchAnimationRunningOnKeyguard =
notificationLaunchInteractor.isLaunchAnimationRunning
- .sample(transitionInteractor.finishedKeyguardState, ::Pair)
- .map { (animationRunning, finishedState) ->
- animationRunning && finishedState != KeyguardState.GONE
- }
+ .sample(
+ transitionInteractor.isFinishedIn(
+ scene = Scenes.Gone,
+ stateWithoutSceneContainer = KeyguardState.GONE,
+ ),
+ ::Pair
+ )
+ .map { (animationRunning, isOnGone) -> animationRunning && !isOnGone }
.onStart { emit(false) }
/**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt
index 5ad7762bb512..805dbb08d1ac 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt
@@ -22,7 +22,10 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
+import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
+import com.android.systemui.keyguard.shared.model.KeyguardState.OFF
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -40,6 +43,7 @@ constructor(
val deviceEntryInteractor: DeviceEntryInteractor,
val deviceProvisioningInteractor: DeviceProvisioningInteractor,
val keyguardTransitionInteractor: KeyguardTransitionInteractor,
+ val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
val repository: KeyguardTransitionRepository,
) : CoreStartable {
@@ -56,17 +60,7 @@ constructor(
override fun start() {
scope.launch {
- val state =
- if (showLockscreenOnBoot.first()) {
- KeyguardState.LOCKSCREEN
- } else {
- KeyguardState.GONE
- }
-
- if (
- keyguardTransitionInteractor.currentTransitionInfoInternal.value.from !=
- KeyguardState.OFF
- ) {
+ if (internalTransitionInteractor.currentTransitionInfoInternal.value.from != OFF) {
Log.e(
"KeyguardTransitionInteractor",
"showLockscreenOnBoot emitted, but we've already " +
@@ -74,7 +68,23 @@ constructor(
"transition, but this should not happen."
)
} else {
- repository.emitInitialStepsFromOff(state)
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Some part of the transition implemented for flag off is
+ // missing here. There are two things achieved with this:
+ // 1. Keyguard is hidden when the setup wizard is shown. This part is already
+ // implemented in scene container by disabling visibility instead of going
+ // to Gone. See [SceneContainerStartable.hydrateVisibility]. We might want
+ // to unify this logic here.
+ // 2. When the auth method is set to NONE device boots into Gone (Launcher).
+ // For this we would just need to call changeScene(Scene.Gone).
+ // Unfortunately STL doesn't seem to be initialized at this point, therefore
+ // it needs a different solution.
+ repository.emitInitialStepsFromOff(LOCKSCREEN)
+ } else {
+ repository.emitInitialStepsFromOff(
+ if (showLockscreenOnBoot.first()) LOCKSCREEN else GONE
+ )
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 37272dca911f..f9bfaff80090 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -17,7 +17,6 @@
package com.android.systemui.keyguard.domain.interactor
-import android.annotation.FloatRange
import android.annotation.SuppressLint
import android.util.Log
import com.android.compose.animation.scene.SceneKey
@@ -33,14 +32,12 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.KeyguardState.UNDEFINED
-import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.util.kotlin.pairwise
-import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -50,6 +47,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
@@ -75,7 +73,7 @@ constructor(
private val fromAlternateBouncerTransitionInteractor:
dagger.Lazy<FromAlternateBouncerTransitionInteractor>,
private val fromDozingTransitionInteractor: dagger.Lazy<FromDozingTransitionInteractor>,
- private val sceneInteractor: dagger.Lazy<SceneInteractor>,
+ private val sceneInteractor: SceneInteractor,
) {
private val transitionMap = mutableMapOf<Edge.StateToState, MutableSharedFlow<TransitionStep>>()
@@ -194,7 +192,7 @@ constructor(
fun SceneKey?.isLockscreenOrNull() = this == Scenes.Lockscreen || this == null
return@filter (fromScene.isLockscreenOrNull() && toScene.isLockscreenOrNull()) ||
- sceneInteractor.get().transitionState.value.isTransitioning(fromScene, toScene)
+ sceneInteractor.transitionState.value.isTransitioning(fromScene, toScene)
}
} else {
flow
@@ -228,7 +226,7 @@ constructor(
stateWithoutSceneContainer: KeyguardState,
): Flow<Float> {
return if (SceneContainerFlag.isEnabled) {
- sceneInteractor.get().transitionProgress(scene)
+ sceneInteractor.transitionProgress(scene)
} else {
transitionValue(stateWithoutSceneContainer)
}
@@ -383,33 +381,14 @@ constructor(
.distinctUntilChanged()
.stateIn(scope, SharingStarted.Eagerly, KeyguardState.OFF)
- /**
- * The [TransitionInfo] of the most recent call to
- * [KeyguardTransitionRepository.startTransition].
- *
- * This should only be used by keyguard transition internals (From*TransitionInteractor and
- * related classes). Other consumers of keyguard state in System UI should use
- * [startedKeyguardState], [currentKeyguardState], and related flows.
- *
- * Keyguard internals use this to determine the most up-to-date KeyguardState that we've
- * requested a transition to, even if the animator running the transition on the main thread has
- * not yet emitted the STARTED TransitionStep.
- *
- * For example: if we're finished in GONE and press the power button twice very quickly, we may
- * request a transition to AOD, but then receive the second power button press prior to the
- * STARTED -> AOD transition step emitting. We still need the FromAodTransitionInteractor to
- * request a transition from AOD -> LOCKSCREEN in response to the power press, even though the
- * main thread animator hasn't emitted STARTED > AOD yet (which means [startedKeyguardState] is
- * still GONE, which is not relevant to FromAodTransitionInteractor). In this case, the
- * interactor can use this current transition info to determine that a STARTED -> AOD step
- * *will* be emitted, and therefore that it can safely request an AOD -> LOCKSCREEN transition
- * which will subsequently cancel GONE -> AOD.
- */
- internal val currentTransitionInfoInternal: StateFlow<TransitionInfo> =
- repository.currentTransitionInfoInternal
-
- /** Whether we've currently STARTED a transition and haven't yet FINISHED it. */
- val isInTransitionToAnyState = isInTransitionWhere({ true }, { true })
+ val isInTransition =
+ combine(
+ isInTransitionWhere({ true }, { true }),
+ sceneInteractor.transitionState,
+ ) { isKeyguardTransitioning, sceneTransitionState ->
+ isKeyguardTransitioning ||
+ (SceneContainerFlag.isEnabled && sceneTransitionState.isTransitioning())
+ }
/**
* Called to start a transition that will ultimately dismiss the keyguard from the current
@@ -422,7 +401,7 @@ constructor(
// TODO(b/336576536): Check if adaptation for scene framework is needed
if (SceneContainerFlag.isEnabled) return
Log.d(TAG, "#startDismissKeyguardTransition(reason=$reason)")
- when (val startedState = currentTransitionInfoInternal.value.to) {
+ when (val startedState = repository.currentTransitionInfoInternal.value.to) {
LOCKSCREEN -> fromLockscreenTransitionInteractor.get().dismissKeyguard()
PRIMARY_BOUNCER -> fromPrimaryBouncerTransitionInteractor.get().dismissPrimaryBouncer()
ALTERNATE_BOUNCER ->
@@ -448,7 +427,7 @@ constructor(
fun isInTransition(edge: Edge, edgeWithoutSceneContainer: Edge? = null): Flow<Boolean> {
return if (SceneContainerFlag.isEnabled) {
if (edge.isSceneWildcardEdge()) {
- sceneInteractor.get().transitionState.map {
+ sceneInteractor.transitionState.map {
when (edge) {
is Edge.StateToState ->
throw IllegalStateException("Should not be reachable.")
@@ -469,30 +448,6 @@ constructor(
}
/**
- * Whether we're in a transition to a [KeyguardState] that matches the given predicate, but
- * haven't yet completed it.
- *
- * If you only care about a single state, instead use the optimized [isInTransition].
- */
- fun isInTransitionToStateWhere(
- stateMatcher: (KeyguardState) -> Boolean,
- ): Flow<Boolean> {
- return isInTransitionWhere(fromStatePredicate = { true }, toStatePredicate = stateMatcher)
- }
-
- /**
- * Whether we're in a transition out of a [KeyguardState] that matches the given predicate, but
- * haven't yet completed it.
- *
- * If you only care about a single state, instead use the optimized [isInTransition].
- */
- fun isInTransitionFromStateWhere(
- stateMatcher: (KeyguardState) -> Boolean,
- ): Flow<Boolean> {
- return isInTransitionWhere(fromStatePredicate = stateMatcher, toStatePredicate = { true })
- }
-
- /**
* Whether we're in a transition between two [KeyguardState]s that match the given predicates,
* but haven't yet completed it.
*
@@ -500,27 +455,15 @@ constructor(
* [isInTransition].
*/
fun isInTransitionWhere(
- fromStatePredicate: (KeyguardState) -> Boolean,
- toStatePredicate: (KeyguardState) -> Boolean,
- ): Flow<Boolean> {
- return isInTransitionWhere { from, to -> fromStatePredicate(from) && toStatePredicate(to) }
- }
-
- /**
- * Whether we're in a transition between two [KeyguardState]s that match the given predicates,
- * but haven't yet completed it.
- *
- * If you only care about a single state for both from and to, instead use the optimized
- * [isInTransition].
- */
- private fun isInTransitionWhere(
- fromToStatePredicate: (KeyguardState, KeyguardState) -> Boolean
+ fromStatePredicate: (KeyguardState) -> Boolean = { true },
+ toStatePredicate: (KeyguardState) -> Boolean = { true },
): Flow<Boolean> {
return repository.transitions
.filter { it.transitionState != TransitionState.CANCELED }
.mapLatest {
it.transitionState != TransitionState.FINISHED &&
- fromToStatePredicate(it.from, it.to)
+ fromStatePredicate(it.from) &&
+ toStatePredicate(it.to)
}
.distinctUntilChanged()
}
@@ -530,17 +473,21 @@ constructor(
return finishedKeyguardState.map { stateMatcher(it) }.distinctUntilChanged()
}
- /** Whether we've FINISHED a transition to a state that matches the given predicate. */
- fun isFinishedInState(state: KeyguardState): Flow<Boolean> {
- return finishedKeyguardState.map { it == state }.distinctUntilChanged()
+ fun isFinishedIn(scene: SceneKey, stateWithoutSceneContainer: KeyguardState): Flow<Boolean> {
+ return if (SceneContainerFlag.isEnabled) {
+ sceneInteractor.transitionState
+ .map { it.isIdle(scene) || it.isTransitioning(from = scene) }
+ .distinctUntilChanged()
+ } else {
+ isFinishedIn(stateWithoutSceneContainer)
+ }
}
- /**
- * Whether we've FINISHED a transition to a state that matches the given predicate. Consider
- * using [isFinishedInStateWhere] whenever possible instead
- */
- fun isFinishedInStateWhereValue(stateMatcher: (KeyguardState) -> Boolean) =
- stateMatcher(finishedKeyguardState.replayCache.last())
+ /** Whether we've FINISHED a transition to a state */
+ fun isFinishedIn(state: KeyguardState): Flow<Boolean> {
+ state.checkValidState()
+ return finishedKeyguardState.map { it == state }.distinctUntilChanged()
+ }
fun getCurrentState(): KeyguardState {
return currentKeyguardState.replayCache.last()
@@ -554,14 +501,6 @@ constructor(
return finishedKeyguardState.replayCache.last()
}
- suspend fun startTransition(info: TransitionInfo) = repository.startTransition(info)
-
- fun updateTransition(
- transitionId: UUID,
- @FloatRange(from = 0.0, to = 1.0) value: Float,
- state: TransitionState
- ) = repository.updateTransition(transitionId, value, state)
-
companion object {
private val TAG = KeyguardTransitionInteractor::class.simpleName
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt
new file mode 100644
index 000000000000..f0bf4029ab39
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt
@@ -0,0 +1,372 @@
+/*
+ * 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.keyguard.domain.interactor
+
+import android.annotation.SuppressLint
+import android.app.AlarmManager
+import android.app.PendingIntent
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.provider.Settings
+import android.provider.Settings.Secure
+import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.KeyguardViewMediator
+import com.android.systemui.keyguard.KeyguardWmStateRefactor
+import com.android.systemui.keyguard.data.repository.KeyguardRepository
+import com.android.systemui.keyguard.shared.model.BiometricUnlockMode
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.KeyguardState.Companion.deviceIsAsleepInState
+import com.android.systemui.keyguard.shared.model.KeyguardState.Companion.deviceIsAwakeInState
+import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason
+import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import com.android.systemui.util.kotlin.sample
+import com.android.systemui.util.settings.SecureSettings
+import com.android.systemui.util.settings.SystemSettings
+import com.android.systemui.util.time.SystemClock
+import javax.inject.Inject
+import kotlin.math.max
+import kotlin.math.min
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.distinctUntilChangedBy
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+/**
+ * Logic related to the ability to wake directly to GONE from asleep (AOD/DOZING), without going
+ * through LOCKSCREEN or a BOUNCER state.
+ *
+ * This is possible in the following scenarios:
+ * - The lockscreen is disabled, either from an app request (SUW does this), or by the security
+ * "None" setting.
+ * - A biometric authentication event occurred while we were asleep (fingerprint auth, etc). This
+ * specifically is referred to throughout the codebase as "wake and unlock".
+ * - The screen timed out, but the "lock after screen timeout" duration has not elapsed.
+ * - The power button was pressed, but "power button instantly locks" is disabled and the "lock
+ * after screen timeout" duration has not elapsed.
+ *
+ * In these cases, no (further) authentication is required, and we can transition directly from
+ * AOD/DOZING -> GONE.
+ */
+@SysUISingleton
+class KeyguardWakeDirectlyToGoneInteractor
+@Inject
+constructor(
+ @Application private val scope: CoroutineScope,
+ private val context: Context,
+ private val repository: KeyguardRepository,
+ private val systemClock: SystemClock,
+ private val alarmManager: AlarmManager,
+ private val transitionInteractor: KeyguardTransitionInteractor,
+ private val powerInteractor: PowerInteractor,
+ private val secureSettings: SecureSettings,
+ private val lockPatternUtils: LockPatternUtils,
+ private val systemSettings: SystemSettings,
+ private val selectedUserInteractor: SelectedUserInteractor,
+) {
+
+ /**
+ * Whether the lockscreen was disabled as of the last wake/sleep event, according to
+ * LockPatternUtils.
+ *
+ * This will always be true if [repository.isKeyguardServiceEnabled]=false, but it can also be
+ * true when the keyguard service is enabled if the lockscreen has been disabled via adb using
+ * the `adb shell locksettings set-disabled true` command, which is often done in tests.
+ *
+ * Unlike keyguardServiceEnabled, changes to this value should *not* immediately show or hide
+ * the keyguard. If the lockscreen is disabled in this way, it will just not show on the next
+ * sleep/wake.
+ */
+ private val isLockscreenDisabled: Flow<Boolean> =
+ powerInteractor.isAwake.map { isLockscreenDisabled() }
+
+ /**
+ * Whether we can wake from AOD/DOZING directly to GONE, bypassing LOCKSCREEN/BOUNCER states.
+ *
+ * This is possible in the following cases:
+ * - Keyguard is disabled, either from an app request or from security being set to "None".
+ * - We're wake and unlocking (fingerprint auth occurred while asleep).
+ * - We're allowed to ignore auth and return to GONE, due to timeouts not elapsing.
+ */
+ val canWakeDirectlyToGone =
+ combine(
+ repository.isKeyguardEnabled,
+ isLockscreenDisabled,
+ repository.biometricUnlockState,
+ repository.canIgnoreAuthAndReturnToGone,
+ ) {
+ keyguardEnabled,
+ isLockscreenDisabled,
+ biometricUnlockState,
+ canIgnoreAuthAndReturnToGone ->
+ (!keyguardEnabled || isLockscreenDisabled) ||
+ BiometricUnlockMode.isWakeAndUnlock(biometricUnlockState.mode) ||
+ canIgnoreAuthAndReturnToGone
+ }
+ .distinctUntilChanged()
+
+ /**
+ * Counter that is incremented every time we wake up or stop dreaming. Upon sleeping/dreaming,
+ * we put the current value of this counter into the intent extras of the timeout alarm intent.
+ * If this value has changed by the time we receive the intent, it is discarded since it's out
+ * of date.
+ */
+ var timeoutCounter = 0
+
+ var isAwake = false
+
+ private val broadcastReceiver: BroadcastReceiver =
+ object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ if (DELAYED_KEYGUARD_ACTION == intent.action) {
+ val sequence = intent.getIntExtra(SEQ_EXTRA_KEY, 0)
+ synchronized(this) {
+ if (timeoutCounter == sequence) {
+ // If the sequence # matches, we have not woken up or stopped dreaming
+ // since
+ // the alarm was set. That means this is still relevant - the lock
+ // timeout
+ // has elapsed, so let the repository know that we can no longer return
+ // to
+ // GONE without authenticating.
+ repository.setCanIgnoreAuthAndReturnToGone(false)
+ }
+ }
+ }
+ }
+ }
+
+ init {
+ setOrCancelAlarmFromWakefulness()
+ listenForWakeToClearCanIgnoreAuth()
+ registerBroadcastReceiver()
+ }
+
+ fun onDreamingStarted() {
+ // If we start dreaming while awake, lock after the normal timeout.
+ if (isAwake) {
+ setResetCanIgnoreAuthAlarm()
+ }
+ }
+
+ fun onDreamingStopped() {
+ // Cancel the timeout if we stop dreaming while awake.
+ if (isAwake) {
+ cancelCanIgnoreAuthAlarm()
+ }
+ }
+
+ private fun setOrCancelAlarmFromWakefulness() {
+ scope.launch {
+ powerInteractor.detailedWakefulness
+ .distinctUntilChangedBy { it.isAwake() }
+ .sample(transitionInteractor.currentKeyguardState, ::Pair)
+ .collect { (wakefulness, currentState) ->
+ // Save isAwake for use in onDreamingStarted/onDreamingStopped.
+ this@KeyguardWakeDirectlyToGoneInteractor.isAwake = wakefulness.isAwake()
+
+ // If we're sleeping from GONE, check the timeout and lock instantly settings.
+ // These are not relevant if we're coming from non-GONE states.
+ if (!isAwake && currentState == KeyguardState.GONE) {
+ val lockTimeoutDuration = getCanIgnoreAuthAndReturnToGoneDuration()
+
+ // If the screen timed out and went to sleep, and the lock timeout is > 0ms,
+ // then we can return to GONE until that duration elapses. If the power
+ // button was pressed but "instantly locks" is disabled, then we can also
+ // return to GONE until the timeout duration elapses.
+ if (
+ (wakefulness.lastSleepReason == WakeSleepReason.TIMEOUT &&
+ lockTimeoutDuration > 0) ||
+ (wakefulness.lastSleepReason == WakeSleepReason.POWER_BUTTON &&
+ !willLockImmediately())
+ ) {
+
+ // Let the repository know that we can return to GONE until we notify
+ // it otherwise.
+ repository.setCanIgnoreAuthAndReturnToGone(true)
+ setResetCanIgnoreAuthAlarm()
+ }
+ } else if (isAwake) {
+ // If we're waking up, ignore the alarm if it goes off since it's no longer
+ // relevant. Once a wake KeyguardTransition is started, we'll also clear the
+ // canIgnoreAuthAndReturnToGone value in listenForWakeToClearCanIgnoreAuth.
+ cancelCanIgnoreAuthAlarm()
+ }
+ }
+ }
+ }
+
+ /** Clears the canIgnoreAuthAndReturnToGone value upon waking. */
+ private fun listenForWakeToClearCanIgnoreAuth() {
+ scope.launch {
+ transitionInteractor
+ .isInTransitionWhere(
+ fromStatePredicate = { deviceIsAsleepInState(it) },
+ toStatePredicate = { deviceIsAwakeInState(it) },
+ )
+ .collect {
+ // This value is reset when the timeout alarm fires, but if the device is woken
+ // back up before then, it needs to be reset here. The alarm is cancelled
+ // immediately upon waking up, but since this value is used by keyguard
+ // transition internals to decide whether we can transition to GONE, wait until
+ // that decision is made before resetting it.
+ repository.setCanIgnoreAuthAndReturnToGone(false)
+ }
+ }
+ }
+
+ /**
+ * Registers the broadcast receiver to receive the alarm intent.
+ *
+ * TODO(b/351817381): Investigate using BroadcastDispatcher vs. ignoring this lint warning.
+ */
+ @SuppressLint("WrongConstant", "RegisterReceiverViaContext")
+ private fun registerBroadcastReceiver() {
+ val delayedActionFilter = IntentFilter()
+ delayedActionFilter.addAction(KeyguardViewMediator.DELAYED_KEYGUARD_ACTION)
+ // TODO(b/346803756): Listen for DELAYED_LOCK_PROFILE_ACTION.
+ delayedActionFilter.priority = IntentFilter.SYSTEM_HIGH_PRIORITY
+ context.registerReceiver(
+ broadcastReceiver,
+ delayedActionFilter,
+ SYSTEMUI_PERMISSION,
+ null /* scheduler */,
+ Context.RECEIVER_EXPORTED_UNAUDITED
+ )
+ }
+
+ /** Set an alarm for */
+ private fun setResetCanIgnoreAuthAlarm() {
+ if (!KeyguardWmStateRefactor.isEnabled) {
+ return
+ }
+
+ val intent =
+ Intent(DELAYED_KEYGUARD_ACTION).apply {
+ setPackage(context.packageName)
+ putExtra(SEQ_EXTRA_KEY, timeoutCounter)
+ addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+ }
+
+ val sender =
+ PendingIntent.getBroadcast(
+ context,
+ 0,
+ intent,
+ PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
+ )
+
+ val time = systemClock.elapsedRealtime() + getCanIgnoreAuthAndReturnToGoneDuration()
+ alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, sender)
+
+ // TODO(b/346803756): Migrate support for child profiles.
+ }
+
+ /**
+ * Cancel the timeout by incrementing the counter so that we ignore the intent when it's
+ * received.
+ */
+ private fun cancelCanIgnoreAuthAlarm() {
+ timeoutCounter++
+ }
+
+ /**
+ * Whether pressing the power button locks the device immediately; vs. waiting for a specified
+ * timeout first.
+ */
+ private fun willLockImmediately(
+ userId: Int = selectedUserInteractor.getSelectedUserId()
+ ): Boolean {
+ return lockPatternUtils.getPowerButtonInstantlyLocks(userId) ||
+ !lockPatternUtils.isSecure(userId)
+ }
+
+ /**
+ * Returns whether the lockscreen is disabled, either because the keyguard service is disabled
+ * or because an adb command has disabled the lockscreen.
+ */
+ private fun isLockscreenDisabled(
+ userId: Int = selectedUserInteractor.getSelectedUserId()
+ ): Boolean {
+ return lockPatternUtils.isLockScreenDisabled(userId)
+ }
+
+ /**
+ * Returns the duration within which we can return to GONE without auth after a screen timeout
+ * (or power button press, if lock instantly is disabled).
+ *
+ * This takes into account the user's settings as well as device policy maximums.
+ */
+ private fun getCanIgnoreAuthAndReturnToGoneDuration(
+ userId: Int = selectedUserInteractor.getSelectedUserId()
+ ): Long {
+ // The timeout duration from settings (Security > Device Unlock > Gear icon > "Lock after
+ // screen timeout".
+ val durationSetting: Long =
+ secureSettings
+ .getIntForUser(
+ Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
+ KEYGUARD_CAN_IGNORE_AUTH_DURATION,
+ userId
+ )
+ .toLong()
+
+ // Device policy maximum timeout.
+ val durationDevicePolicyMax =
+ lockPatternUtils.devicePolicyManager.getMaximumTimeToLock(null, userId)
+
+ return if (durationDevicePolicyMax <= 0) {
+ durationSetting
+ } else {
+ var displayTimeout =
+ systemSettings
+ .getIntForUser(
+ Settings.System.SCREEN_OFF_TIMEOUT,
+ KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT,
+ userId
+ )
+ .toLong()
+
+ // Ignore negative values. I don't know why this would be negative, but this check has
+ // been around since 2016 and I see no upside to removing it.
+ displayTimeout = max(displayTimeout, 0)
+
+ // Respect the shorter of: the device policy (maximum duration between last user action
+ // and fully locking) or the "Lock after screen timeout" setting.
+ max(min(durationDevicePolicyMax - displayTimeout, durationSetting), 0)
+ }
+ }
+
+ companion object {
+ private const val DELAYED_KEYGUARD_ACTION =
+ "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD"
+ private const val DELAYED_LOCK_PROFILE_ACTION =
+ "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_LOCK"
+ private const val SYSTEMUI_PERMISSION = "com.android.systemui.permission.SELF"
+ private const val SEQ_EXTRA_KEY = "count"
+
+ private const val KEYGUARD_CAN_IGNORE_AUTH_DURATION = 5000
+ private const val KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
index e14820714c9b..89c717892d0a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
@@ -25,6 +25,7 @@ import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.util.kotlin.sample
import java.util.UUID
import kotlinx.coroutines.CoroutineDispatcher
@@ -57,6 +58,8 @@ sealed class TransitionInteractor(
) {
val name = this::class.simpleName ?: "UnknownTransitionInteractor"
abstract val transitionRepository: KeyguardTransitionRepository
+ abstract val internalTransitionInteractor: InternalKeyguardTransitionInteractor
+
abstract fun start()
/* Use background dispatcher for all [KeyguardTransitionInteractor] flows. Necessary because
@@ -79,14 +82,15 @@ sealed class TransitionInteractor(
// a bugreport.
ownerReason: String = "",
): UUID? {
- if (fromState != transitionInteractor.currentTransitionInfoInternal.value.to) {
+ toState.checkValidState()
+ if (fromState != internalTransitionInteractor.currentTransitionInfoInternal.value.to) {
Log.e(
name,
"Ignoring startTransition: This interactor asked to transition from " +
"$fromState -> $toState, but we last transitioned to " +
- "${transitionInteractor.currentTransitionInfoInternal.value.to}, not " +
- "$fromState. This should never happen - check currentTransitionInfoInternal " +
- "or use filterRelevantKeyguardState before starting transitions."
+ "${internalTransitionInteractor.currentTransitionInfoInternal.value.to}, not" +
+ " $fromState. This should never happen - check currentTransitionInfoInternal" +
+ " or use filterRelevantKeyguardState before starting transitions."
)
if (fromState == transitionInteractor.finishedKeyguardState.replayCache.last()) {
@@ -164,6 +168,7 @@ sealed class TransitionInteractor(
*/
@Deprecated("Will be merged into maybeStartTransitionToOccludedOrInsecureCamera")
suspend fun maybeHandleInsecurePowerGesture(): Boolean {
+ if (SceneContainerFlag.isEnabled) return false
if (keyguardOcclusionInteractor.shouldTransitionFromPowerButtonGesture()) {
if (keyguardInteractor.isKeyguardDismissible.value) {
startTransitionTo(
@@ -238,12 +243,11 @@ sealed class TransitionInteractor(
* Whether we're in the KeyguardState relevant to this From*TransitionInteractor (which we know
* from [fromState]).
*
- * This uses [KeyguardTransitionInteractor.currentTransitionInfoInternal], which is more up to
- * date than [startedKeyguardState] as it does not wait for the emission of the first STARTED
- * step.
+ * This uses [currentTransitionInfoInternal], which is more up to date than
+ * [startedKeyguardState] as it does not wait for the emission of the first STARTED step.
*/
fun inOrTransitioningToRelevantKeyguardState(): Boolean {
- return transitionInteractor.currentTransitionInfoInternal.value.to == fromState
+ return internalTransitionInteractor.currentTransitionInfoInternal.value.to == fromState
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
index 069f65b4efa6..e1b333dd1d06 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
@@ -21,14 +21,17 @@ package com.android.systemui.keyguard.domain.interactor
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.BiometricUnlockMode
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.KeyguardState.Companion.deviceIsAsleepInState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
+import com.android.systemui.util.kotlin.Utils.Companion.toTriple
import com.android.systemui.util.kotlin.sample
import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import dagger.Lazy
@@ -41,11 +44,13 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
+@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
class WindowManagerLockscreenVisibilityInteractor
@Inject
constructor(
keyguardInteractor: KeyguardInteractor,
+ transitionRepository: KeyguardTransitionRepository,
transitionInteractor: KeyguardTransitionInteractor,
surfaceBehindInteractor: KeyguardSurfaceBehindInteractor,
fromLockscreenInteractor: FromLockscreenTransitionInteractor,
@@ -54,9 +59,15 @@ constructor(
notificationLaunchAnimationInteractor: NotificationLaunchAnimationInteractor,
sceneInteractor: Lazy<SceneInteractor>,
deviceEntryInteractor: Lazy<DeviceEntryInteractor>,
+ wakeToGoneInteractor: KeyguardWakeDirectlyToGoneInteractor,
) {
private val defaultSurfaceBehindVisibility =
- transitionInteractor.finishedKeyguardState.map(::isSurfaceVisible)
+ combine(
+ transitionInteractor.finishedKeyguardState,
+ wakeToGoneInteractor.canWakeDirectlyToGone,
+ ) { finishedState, canWakeDirectlyToGone ->
+ isSurfaceVisible(finishedState) || canWakeDirectlyToGone
+ }
/**
* Surface visibility provided by the From*TransitionInteractor responsible for the currently
@@ -71,6 +82,7 @@ constructor(
private val transitionSpecificSurfaceBehindVisibility: Flow<Boolean?> =
transitionInteractor.startedKeyguardTransitionStep
.flatMapLatest { startedStep ->
+ SceneContainerFlag.assertInLegacyMode()
when (startedStep.from) {
KeyguardState.LOCKSCREEN -> {
fromLockscreenInteractor.surfaceBehindVisibility
@@ -129,7 +141,7 @@ constructor(
}
}
} else {
- transitionInteractor.isInTransitionToAnyState.flatMapLatest { isInTransition ->
+ transitionInteractor.isInTransition.flatMapLatest { isInTransition ->
if (!isInTransition) {
defaultSurfaceBehindVisibility
} else {
@@ -203,26 +215,47 @@ constructor(
if (SceneContainerFlag.isEnabled) {
isDeviceNotEntered
} else {
- transitionInteractor.currentKeyguardState
- .sample(transitionInteractor.startedStepWithPrecedingStep, ::Pair)
- .map { (currentState, startedWithPrev) ->
- val startedFromStep = startedWithPrev?.previousValue
- val startedStep = startedWithPrev?.newValue
+ combine(
+ transitionInteractor.currentKeyguardState,
+ wakeToGoneInteractor.canWakeDirectlyToGone,
+ ::Pair
+ )
+ .sample(transitionInteractor.startedStepWithPrecedingStep, ::toTriple)
+ .map { (currentState, canWakeDirectlyToGone, startedWithPrev) ->
+ val startedFromStep = startedWithPrev.previousValue
+ val startedStep = startedWithPrev.newValue
val returningToGoneAfterCancellation =
- startedStep?.to == KeyguardState.GONE &&
- startedFromStep?.transitionState == TransitionState.CANCELED &&
+ startedStep.to == KeyguardState.GONE &&
+ startedFromStep.transitionState == TransitionState.CANCELED &&
startedFromStep.from == KeyguardState.GONE
- if (!returningToGoneAfterCancellation) {
- // By default, apply the lockscreen visibility of the current state.
- deviceEntryInteractor.get().isLockscreenEnabled() &&
- KeyguardState.lockscreenVisibleInState(currentState)
- } else {
- // If we're transitioning to GONE after a prior canceled transition from
- // GONE, then this is the camera launch transition from an asleep state back
- // to GONE. We don't want to show the lockscreen since we're aborting the
- // lock and going back to GONE.
+ val transitionInfo = transitionRepository.currentTransitionInfoInternal.value
+ val wakingDirectlyToGone =
+ deviceIsAsleepInState(transitionInfo.from) &&
+ transitionInfo.to == KeyguardState.GONE
+
+ if (returningToGoneAfterCancellation || wakingDirectlyToGone) {
+ // GONE -> AOD/DOZING (cancel) -> GONE is the camera launch transition,
+ // which means we never want to show the lockscreen throughout the
+ // transition. Same for waking directly to gone, due to the lockscreen being
+ // disabled or because the device was woken back up before the lock timeout
+ // duration elapsed.
KeyguardState.lockscreenVisibleInState(KeyguardState.GONE)
+ } else if (canWakeDirectlyToGone) {
+ // Never show the lockscreen if we can wake directly to GONE. This means
+ // that the lock timeout has not yet elapsed, or the keyguard is disabled.
+ // In either case, we don't show the activity lock screen until one of those
+ // conditions changes.
+ false
+ } else if (
+ currentState == KeyguardState.DREAMING &&
+ deviceEntryInteractor.get().isUnlocked.value
+ ) {
+ // Dreams dismiss keyguard and return to GONE if they can.
+ false
+ } else {
+ // Otherwise, use the visibility of the current state.
+ KeyguardState.lockscreenVisibleInState(currentState)
}
}
.distinctUntilChanged()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
index 9b3ba7d8feb0..324811443e9d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
@@ -23,6 +23,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.LockscreenSceneTransitionRepository
import com.android.systemui.keyguard.data.repository.LockscreenSceneTransitionRepository.Companion.DEFAULT_STATE
+import com.android.systemui.keyguard.domain.interactor.InternalKeyguardTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardState.UNDEFINED
@@ -67,7 +68,8 @@ import kotlinx.coroutines.launch
class LockscreenSceneTransitionInteractor
@Inject
constructor(
- val transitionInteractor: KeyguardTransitionInteractor,
+ private val transitionInteractor: KeyguardTransitionInteractor,
+ private val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
@Application private val applicationScope: CoroutineScope,
private val sceneInteractor: SceneInteractor,
private val repository: LockscreenSceneTransitionRepository,
@@ -123,7 +125,7 @@ constructor(
}
private fun finishCurrentTransition() {
- transitionInteractor.updateTransition(currentTransitionId!!, 1f, FINISHED)
+ internalTransitionInteractor.updateTransition(currentTransitionId!!, 1f, FINISHED)
resetTransitionData()
}
@@ -131,13 +133,13 @@ constructor(
val newTransition =
TransitionInfo(
ownerName = this::class.java.simpleName,
- from = transitionInteractor.currentTransitionInfoInternal.value.to,
+ from = internalTransitionInteractor.currentTransitionInfoInternal.value.to,
to = state,
animator = null,
modeOnCanceled = TransitionModeOnCanceled.REVERSE
)
- currentTransitionId = transitionInteractor.startTransition(newTransition)
- transitionInteractor.updateTransition(currentTransitionId!!, 1f, FINISHED)
+ currentTransitionId = internalTransitionInteractor.startTransition(newTransition)
+ internalTransitionInteractor.updateTransition(currentTransitionId!!, 1f, FINISHED)
resetTransitionData()
}
@@ -150,7 +152,8 @@ constructor(
private suspend fun handleTransition(transition: ObservableTransitionState.Transition) {
if (transition.fromScene == Scenes.Lockscreen) {
if (currentTransitionId != null) {
- val currentToState = transitionInteractor.currentTransitionInfoInternal.value.to
+ val currentToState =
+ internalTransitionInteractor.currentTransitionInfoInternal.value.to
if (currentToState == UNDEFINED) {
transitionKtfTo(transitionInteractor.getStartedFromState())
}
@@ -201,7 +204,7 @@ constructor(
}
private suspend fun startTransitionFromLockscreen() {
- val currentState = transitionInteractor.currentTransitionInfoInternal.value.to
+ val currentState = internalTransitionInteractor.currentTransitionInfoInternal.value.to
val newTransition =
TransitionInfo(
ownerName = this::class.java.simpleName,
@@ -217,12 +220,12 @@ constructor(
if (currentTransitionId != null) {
resetTransitionData()
}
- currentTransitionId = transitionInteractor.startTransition(transitionInfo)
+ currentTransitionId = internalTransitionInteractor.startTransition(transitionInfo)
}
private fun updateProgress(progress: Float) {
if (currentTransitionId == null) return
- transitionInteractor.updateTransition(
+ internalTransitionInteractor.updateTransition(
currentTransitionId!!,
progress.coerceIn(0f, 1f),
RUNNING
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
index 6a2bb5f51c5d..24db3c2c70a2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
@@ -15,7 +15,9 @@
*/
package com.android.systemui.keyguard.shared.model
+import android.util.Log
import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
/** List of all possible states to transition to/from */
@@ -59,6 +61,11 @@ enum class KeyguardState {
* The security screen prompt UI, containing PIN, Password, Pattern for the user to verify their
* credentials.
*/
+ @Deprecated(
+ "This state won't exist anymore when scene container gets enabled. If you are " +
+ "writing prod code today, make sure to either use flag aware APIs in " +
+ "[KeyguardTransitionInteractor] or flag appropriately with [SceneContainerFlag]."
+ )
PRIMARY_BOUNCER,
/**
* Device is actively displaying keyguard UI and is not in low-power mode. Device may be
@@ -70,12 +77,22 @@ enum class KeyguardState {
* hub UI. From this state, the user can swipe from the left edge to go back to the lock screen
* or dream, as well as swipe down for the notifications and up for the bouncer.
*/
+ @Deprecated(
+ "This state won't exist anymore when scene container gets enabled. If you are " +
+ "writing prod code today, make sure to either use flag aware APIs in " +
+ "[KeyguardTransitionInteractor] or flag appropriately with [SceneContainerFlag]."
+ )
GLANCEABLE_HUB,
/**
* Keyguard is no longer visible. In most cases the user has just authenticated and keyguard is
* being removed, but there are other cases where the user is swiping away keyguard, such as
* with SWIPE security method or face unlock without bypass.
*/
+ @Deprecated(
+ "This state won't exist anymore when scene container gets enabled. If you are " +
+ "writing prod code today, make sure to either use flag aware APIs in " +
+ "[KeyguardTransitionInteractor] or flag appropriately with [SceneContainerFlag]."
+ )
GONE,
/**
* Only used in scene framework. This means we are currently on any scene framework scene that
@@ -87,6 +104,22 @@ enum class KeyguardState {
/** An activity is displaying over the keyguard. */
OCCLUDED;
+ fun checkValidState() {
+ val isStateValid: Boolean
+ val isEnabled: String
+ if (SceneContainerFlag.isEnabled) {
+ isStateValid = this === mapToSceneContainerState()
+ isEnabled = "enabled"
+ } else {
+ isStateValid = this !== UNDEFINED
+ isEnabled = "disabled"
+ }
+
+ if (!isStateValid) {
+ Log.e("KeyguardState", "$this is not a valid state when scene container is $isEnabled")
+ }
+ }
+
fun mapToSceneContainerState(): KeyguardState {
return when (this) {
OFF,
@@ -125,20 +158,16 @@ enum class KeyguardState {
/** Whether the lockscreen is visible when we're FINISHED in the given state. */
fun lockscreenVisibleInState(state: KeyguardState): Boolean {
+ // TODO(b/349784682): Transform deprecated states for Flexiglass
return state != GONE
}
- /** Whether either of the bouncers are visible when we're FINISHED in the given state. */
- @JvmStatic
- fun isBouncerState(state: KeyguardState): Boolean {
- return state == PRIMARY_BOUNCER || state == ALTERNATE_BOUNCER
- }
-
/**
* Whether the device is awake ([PowerInteractor.isAwake]) when we're FINISHED in the given
* keyguard state.
*/
fun deviceIsAwakeInState(state: KeyguardState): Boolean {
+ state.checkValidState()
return when (state) {
OFF -> false
DOZING -> false
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt
index 1c7b4d996b36..76f7749754a2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt
@@ -38,7 +38,9 @@ import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.res.R
import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.util.kotlin.DisposableHandles
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
@@ -64,8 +66,9 @@ object DeviceEntryIconViewBinder {
falsingManager: FalsingManager,
vibratorHelper: VibratorHelper,
overrideColor: Color? = null,
- ) {
+ ): DisposableHandle {
DeviceEntryUdfpsRefactor.isUnexpectedlyInLegacyMode()
+ val disposables = DisposableHandles()
val longPressHandlingView = view.longPressHandlingView
val fgIconView = view.iconView
val bgView = view.bgView
@@ -83,118 +86,125 @@ object DeviceEntryIconViewBinder {
}
}
- view.repeatWhenAttached {
- // Repeat on CREATED so that the view will always observe the entire
- // GONE => AOD transition (even though the view may not be visible until the middle
- // of the transition.
- repeatOnLifecycle(Lifecycle.State.CREATED) {
- launch("$TAG#viewModel.isVisible") {
- viewModel.isVisible.collect { isVisible ->
- longPressHandlingView.isInvisible = !isVisible
+ disposables +=
+ view.repeatWhenAttached {
+ // Repeat on CREATED so that the view will always observe the entire
+ // GONE => AOD transition (even though the view may not be visible until the middle
+ // of the transition.
+ repeatOnLifecycle(Lifecycle.State.CREATED) {
+ launch("$TAG#viewModel.isVisible") {
+ viewModel.isVisible.collect { isVisible ->
+ longPressHandlingView.isInvisible = !isVisible
+ }
}
- }
- launch("$TAG#viewModel.isLongPressEnabled") {
- viewModel.isLongPressEnabled.collect { isEnabled ->
- longPressHandlingView.setLongPressHandlingEnabled(isEnabled)
+ launch("$TAG#viewModel.isLongPressEnabled") {
+ viewModel.isLongPressEnabled.collect { isEnabled ->
+ longPressHandlingView.setLongPressHandlingEnabled(isEnabled)
+ }
}
- }
- launch("$TAG#viewModel.isUdfpsSupported") {
- viewModel.isUdfpsSupported.collect { udfpsSupported ->
- longPressHandlingView.longPressDuration =
- if (udfpsSupported) {
- {
- view.resources
- .getInteger(R.integer.config_udfpsDeviceEntryIconLongPress)
- .toLong()
+ launch("$TAG#viewModel.isUdfpsSupported") {
+ viewModel.isUdfpsSupported.collect { udfpsSupported ->
+ longPressHandlingView.longPressDuration =
+ if (udfpsSupported) {
+ {
+ view.resources
+ .getInteger(
+ R.integer.config_udfpsDeviceEntryIconLongPress
+ )
+ .toLong()
+ }
+ } else {
+ {
+ view.resources
+ .getInteger(R.integer.config_lockIconLongPress)
+ .toLong()
+ }
}
- } else {
- {
- view.resources
- .getInteger(R.integer.config_lockIconLongPress)
- .toLong()
+ }
+ }
+ launch("$TAG#viewModel.accessibilityDelegateHint") {
+ viewModel.accessibilityDelegateHint.collect { hint ->
+ view.accessibilityHintType = hint
+ if (hint != DeviceEntryIconView.AccessibilityHintType.NONE) {
+ view.setOnClickListener {
+ vibratorHelper.performHapticFeedback(
+ view,
+ HapticFeedbackConstants.CONFIRM,
+ )
+ applicationScope.launch { viewModel.onUserInteraction() }
}
+ } else {
+ view.setOnClickListener(null)
}
+ }
}
- }
- launch("$TAG#viewModel.accessibilityDelegateHint") {
- viewModel.accessibilityDelegateHint.collect { hint ->
- view.accessibilityHintType = hint
- if (hint != DeviceEntryIconView.AccessibilityHintType.NONE) {
- view.setOnClickListener {
- vibratorHelper.performHapticFeedback(
- view,
- HapticFeedbackConstants.CONFIRM,
- )
- applicationScope.launch { viewModel.onUserInteraction() }
+ launch("$TAG#viewModel.useBackgroundProtection") {
+ viewModel.useBackgroundProtection.collect { useBackgroundProtection ->
+ if (useBackgroundProtection) {
+ bgView.visibility = View.VISIBLE
+ } else {
+ bgView.visibility = View.GONE
}
- } else {
- view.setOnClickListener(null)
}
}
- }
- launch("$TAG#viewModel.useBackgroundProtection") {
- viewModel.useBackgroundProtection.collect { useBackgroundProtection ->
- if (useBackgroundProtection) {
- bgView.visibility = View.VISIBLE
- } else {
- bgView.visibility = View.GONE
+ launch("$TAG#viewModel.burnInOffsets") {
+ viewModel.burnInOffsets.collect { burnInOffsets ->
+ view.translationX = burnInOffsets.x.toFloat()
+ view.translationY = burnInOffsets.y.toFloat()
+ view.aodFpDrawable.progress = burnInOffsets.progress
}
}
- }
- launch("$TAG#viewModel.burnInOffsets") {
- viewModel.burnInOffsets.collect { burnInOffsets ->
- view.translationX = burnInOffsets.x.toFloat()
- view.translationY = burnInOffsets.y.toFloat()
- view.aodFpDrawable.progress = burnInOffsets.progress
- }
- }
- launch("$TAG#viewModel.deviceEntryViewAlpha") {
- viewModel.deviceEntryViewAlpha.collect { alpha -> view.alpha = alpha }
+ launch("$TAG#viewModel.deviceEntryViewAlpha") {
+ viewModel.deviceEntryViewAlpha.collect { alpha -> view.alpha = alpha }
+ }
}
}
- }
- fgIconView.repeatWhenAttached {
- repeatOnLifecycle(Lifecycle.State.STARTED) {
- // Start with an empty state
- fgIconView.setImageState(StateSet.NOTHING, /* merge */ false)
- launch("$TAG#fpIconView.viewModel") {
- fgViewModel.viewModel.collect { viewModel ->
- fgIconView.setImageState(
- view.getIconState(viewModel.type, viewModel.useAodVariant),
- /* merge */ false
- )
- if (viewModel.type.contentDescriptionResId != -1) {
- fgIconView.contentDescription =
- fgIconView.resources.getString(
- viewModel.type.contentDescriptionResId
- )
+ disposables +=
+ fgIconView.repeatWhenAttached {
+ repeatOnLifecycle(Lifecycle.State.STARTED) {
+ // Start with an empty state
+ fgIconView.setImageState(StateSet.NOTHING, /* merge */ false)
+ launch("$TAG#fpIconView.viewModel") {
+ fgViewModel.viewModel.collect { viewModel ->
+ fgIconView.setImageState(
+ view.getIconState(viewModel.type, viewModel.useAodVariant),
+ /* merge */ false
+ )
+ if (viewModel.type.contentDescriptionResId != -1) {
+ fgIconView.contentDescription =
+ fgIconView.resources.getString(
+ viewModel.type.contentDescriptionResId
+ )
+ }
+ fgIconView.imageTintList =
+ ColorStateList.valueOf(overrideColor?.toArgb() ?: viewModel.tint)
+ fgIconView.setPadding(
+ viewModel.padding,
+ viewModel.padding,
+ viewModel.padding,
+ viewModel.padding,
+ )
}
- fgIconView.imageTintList =
- ColorStateList.valueOf(overrideColor?.toArgb() ?: viewModel.tint)
- fgIconView.setPadding(
- viewModel.padding,
- viewModel.padding,
- viewModel.padding,
- viewModel.padding,
- )
}
}
}
- }
- bgView.repeatWhenAttached {
- repeatOnLifecycle(Lifecycle.State.CREATED) {
- launch("$TAG#bgViewModel.alpha") {
- bgViewModel.alpha.collect { alpha -> bgView.alpha = alpha }
- }
- launch("$TAG#bgViewModel.color") {
- bgViewModel.color.collect { color ->
- bgView.imageTintList = ColorStateList.valueOf(color)
+ disposables +=
+ bgView.repeatWhenAttached {
+ repeatOnLifecycle(Lifecycle.State.CREATED) {
+ launch("$TAG#bgViewModel.alpha") {
+ bgViewModel.alpha.collect { alpha -> bgView.alpha = alpha }
+ }
+ launch("$TAG#bgViewModel.color") {
+ bgViewModel.color.collect { color ->
+ bgView.imageTintList = ColorStateList.valueOf(color)
+ }
}
}
}
- }
+
+ return disposables
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
index e0633807db88..ba9f01862e8e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
@@ -37,7 +37,9 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.clocks.AodClockBurnInModel
import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.util.kotlin.DisposableHandles
import com.android.systemui.util.ui.value
+import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
@@ -56,85 +58,94 @@ object KeyguardClockViewBinder {
keyguardClockInteractor: KeyguardClockInteractor,
blueprintInteractor: KeyguardBlueprintInteractor,
rootViewModel: KeyguardRootViewModel,
- ) {
- keyguardRootView.repeatWhenAttached {
- repeatOnLifecycle(Lifecycle.State.CREATED) {
- keyguardClockInteractor.clockEventController.registerListeners(keyguardRootView)
- }
- }
-
- keyguardRootView.repeatWhenAttached {
- repeatOnLifecycle(Lifecycle.State.CREATED) {
- launch {
- if (!MigrateClocksToBlueprint.isEnabled) return@launch
- viewModel.currentClock.collect { currentClock ->
- cleanupClockViews(currentClock, keyguardRootView, viewModel.burnInLayer)
- addClockViews(currentClock, keyguardRootView)
- updateBurnInLayer(keyguardRootView, viewModel, viewModel.clockSize.value)
- applyConstraints(clockSection, keyguardRootView, true)
- }
+ ): DisposableHandle {
+ val disposables = DisposableHandles()
+ disposables +=
+ keyguardRootView.repeatWhenAttached {
+ repeatOnLifecycle(Lifecycle.State.CREATED) {
+ keyguardClockInteractor.clockEventController.registerListeners(keyguardRootView)
}
+ }
- launch {
- if (!MigrateClocksToBlueprint.isEnabled) return@launch
- viewModel.clockSize.collect { clockSize ->
- updateBurnInLayer(keyguardRootView, viewModel, clockSize)
- blueprintInteractor.refreshBlueprint(Type.ClockSize)
+ disposables +=
+ keyguardRootView.repeatWhenAttached {
+ repeatOnLifecycle(Lifecycle.State.CREATED) {
+ launch {
+ if (!MigrateClocksToBlueprint.isEnabled) return@launch
+ viewModel.currentClock.collect { currentClock ->
+ cleanupClockViews(currentClock, keyguardRootView, viewModel.burnInLayer)
+ addClockViews(currentClock, keyguardRootView)
+ updateBurnInLayer(
+ keyguardRootView,
+ viewModel,
+ viewModel.clockSize.value
+ )
+ applyConstraints(clockSection, keyguardRootView, true)
+ }
}
- }
- launch {
- if (!MigrateClocksToBlueprint.isEnabled) return@launch
- viewModel.clockShouldBeCentered.collect {
- viewModel.currentClock.value?.let {
- // TODO(b/301502635): remove "!it.config.useCustomClockScene" when
- // migrate clocks to blueprint is fully rolled out
- if (
- it.largeClock.config.hasCustomPositionUpdatedAnimation &&
- !it.config.useCustomClockScene
- ) {
- blueprintInteractor.refreshBlueprint(Type.DefaultClockStepping)
- } else {
- blueprintInteractor.refreshBlueprint(Type.DefaultTransition)
- }
+ launch {
+ if (!MigrateClocksToBlueprint.isEnabled) return@launch
+ viewModel.clockSize.collect { clockSize ->
+ updateBurnInLayer(keyguardRootView, viewModel, clockSize)
+ blueprintInteractor.refreshBlueprint(Type.ClockSize)
}
}
- }
- launch {
- if (!MigrateClocksToBlueprint.isEnabled) return@launch
- combine(
- viewModel.hasAodIcons,
- rootViewModel.isNotifIconContainerVisible.map { it.value }
- ) { hasIcon, isVisible ->
- hasIcon && isVisible
- }
- .distinctUntilChanged()
- .collect { _ ->
+ launch {
+ if (!MigrateClocksToBlueprint.isEnabled) return@launch
+ viewModel.clockShouldBeCentered.collect {
viewModel.currentClock.value?.let {
- if (it.config.useCustomClockScene) {
+ // TODO(b/301502635): remove "!it.config.useCustomClockScene" when
+ // migrate clocks to blueprint is fully rolled out
+ if (
+ it.largeClock.config.hasCustomPositionUpdatedAnimation &&
+ !it.config.useCustomClockScene
+ ) {
+ blueprintInteractor.refreshBlueprint(Type.DefaultClockStepping)
+ } else {
blueprintInteractor.refreshBlueprint(Type.DefaultTransition)
}
}
}
- }
+ }
+
+ launch {
+ if (!MigrateClocksToBlueprint.isEnabled) return@launch
+ combine(
+ viewModel.hasAodIcons,
+ rootViewModel.isNotifIconContainerVisible.map { it.value }
+ ) { hasIcon, isVisible ->
+ hasIcon && isVisible
+ }
+ .distinctUntilChanged()
+ .collect { _ ->
+ viewModel.currentClock.value?.let {
+ if (it.config.useCustomClockScene) {
+ blueprintInteractor.refreshBlueprint(Type.DefaultTransition)
+ }
+ }
+ }
+ }
- launch {
- if (!MigrateClocksToBlueprint.isEnabled) return@launch
- rootViewModel.burnInModel.collect { burnInModel ->
- viewModel.currentClock.value?.let {
- it.largeClock.layout.applyAodBurnIn(
- AodClockBurnInModel(
- translationX = burnInModel.translationX.toFloat(),
- translationY = burnInModel.translationY.toFloat(),
- scale = burnInModel.scale
+ launch {
+ if (!MigrateClocksToBlueprint.isEnabled) return@launch
+ rootViewModel.burnInModel.collect { burnInModel ->
+ viewModel.currentClock.value?.let {
+ it.largeClock.layout.applyAodBurnIn(
+ AodClockBurnInModel(
+ translationX = burnInModel.translationX.toFloat(),
+ translationY = burnInModel.translationY.toFloat(),
+ scale = burnInModel.scale
+ )
)
- )
+ }
}
}
}
}
- }
+
+ return disposables
}
@VisibleForTesting
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 fc92afe17eff..f96f053b8da1 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
@@ -37,6 +37,7 @@ import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launch
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD
import com.android.systemui.Flags.newAodTransition
@@ -80,6 +81,7 @@ import com.android.systemui.util.ui.isAnimating
import com.android.systemui.util.ui.stopAnimating
import com.android.systemui.util.ui.value
import kotlin.math.min
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
@@ -110,6 +112,7 @@ object KeyguardRootViewBinder {
vibratorHelper: VibratorHelper?,
falsingManager: FalsingManager?,
keyguardViewMediator: KeyguardViewMediator?,
+ mainImmediateDispatcher: CoroutineDispatcher,
): DisposableHandle {
val disposables = DisposableHandles()
val childViews = mutableMapOf<Int, View>()
@@ -128,6 +131,30 @@ object KeyguardRootViewBinder {
val burnInParams = MutableStateFlow(BurnInParameters())
val viewState = ViewStateAccessor(alpha = { view.alpha })
+
+ disposables +=
+ view.repeatWhenAttached(mainImmediateDispatcher) {
+ repeatOnLifecycle(Lifecycle.State.CREATED) {
+ if (MigrateClocksToBlueprint.isEnabled) {
+ launch("$TAG#topClippingBounds") {
+ val clipBounds = Rect()
+ viewModel.topClippingBounds.collect { clipTop ->
+ if (clipTop == null) {
+ view.setClipBounds(null)
+ } else {
+ clipBounds.apply {
+ top = clipTop
+ left = view.getLeft()
+ right = view.getRight()
+ bottom = view.getBottom()
+ }
+ view.setClipBounds(clipBounds)
+ }
+ }
+ }
+ }
+ }
+ }
disposables +=
view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.CREATED) {
@@ -192,23 +219,6 @@ object KeyguardRootViewBinder {
}
launch {
- val clipBounds = Rect()
- viewModel.topClippingBounds.collect { clipTop ->
- if (clipTop == null) {
- view.setClipBounds(null)
- } else {
- clipBounds.apply {
- top = clipTop
- left = view.getLeft()
- right = view.getRight()
- bottom = view.getBottom()
- }
- view.setClipBounds(clipBounds)
- }
- }
- }
-
- launch {
viewModel.lockscreenStateAlpha(viewState).collect { alpha ->
childViews[statusViewId]?.alpha = alpha
}
@@ -267,6 +277,23 @@ object KeyguardRootViewBinder {
}
}
+ launch {
+ blueprintViewModel.currentTransition.collect { currentTransition ->
+ // When blueprint/clock transitions end (null), make sure NSSL is in
+ // the right place
+ if (currentTransition == null) {
+ childViews[nsslPlaceholderId]?.let { notificationListPlaceholder
+ ->
+ viewModel.onNotificationContainerBoundsChanged(
+ notificationListPlaceholder.top.toFloat(),
+ notificationListPlaceholder.bottom.toFloat(),
+ animate = true,
+ )
+ }
+ }
+ }
+ }
+
if (NotificationIconContainerRefactor.isEnabled) {
launch {
val iconsAppearTranslationPx =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
index 191056c5578a..8b74f5dc791d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
@@ -31,6 +31,7 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.shared.R as sharedR
+import kotlinx.coroutines.DisposableHandle
object KeyguardSmartspaceViewBinder {
@JvmStatic
@@ -39,8 +40,8 @@ object KeyguardSmartspaceViewBinder {
clockViewModel: KeyguardClockViewModel,
smartspaceViewModel: KeyguardSmartspaceViewModel,
blueprintInteractor: KeyguardBlueprintInteractor,
- ) {
- keyguardRootView.repeatWhenAttached {
+ ): DisposableHandle {
+ return keyguardRootView.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.CREATED) {
launch("$TAG#clockViewModel.hasCustomWeatherDataDisplay") {
if (!MigrateClocksToBlueprint.isEnabled) return@launch
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 4f0ac42a0e87..bc5b7b923082 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -394,6 +394,7 @@ constructor(
null, // device entry haptics not required for preview mode
null, // falsing manager not required for preview mode
null, // keyguard view mediator is not required for preview mode
+ mainDispatcher,
)
}
rootView.addView(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/SideFpsProgressBar.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/SideFpsProgressBar.kt
index 853f1769994e..1fd609dba637 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/SideFpsProgressBar.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/SideFpsProgressBar.kt
@@ -26,6 +26,7 @@ import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.WindowManager
import android.widget.ProgressBar
import androidx.core.view.isGone
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.res.R
import javax.inject.Inject
@@ -37,7 +38,7 @@ class SideFpsProgressBar
@Inject
constructor(
private val layoutInflater: LayoutInflater,
- private val windowManager: WindowManager,
+ private val windowManager: ViewCaptureAwareWindowManager,
) {
private var overlayView: View? = null
@@ -90,7 +91,7 @@ constructor(
) {
if (overlayView == null) {
overlayView = layoutInflater.inflate(R.layout.sidefps_progress_bar, null, false)
- windowManager.addView(overlayView, overlayViewParams)
+ windowManager.addView(requireNotNull(overlayView), overlayViewParams)
progressBar?.pivotX = 0.0f
progressBar?.pivotY = 0.0f
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AccessibilityActionsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AccessibilityActionsSection.kt
index 5e5330ebd6ec..717a89801ba4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AccessibilityActionsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AccessibilityActionsSection.kt
@@ -21,7 +21,7 @@ import android.content.Context
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
-import com.android.systemui.Flags
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.ui.binder.AccessibilityActionsViewBinder
import com.android.systemui.keyguard.ui.viewmodel.AccessibilityActionsViewModel
@@ -38,12 +38,13 @@ class AccessibilityActionsSection
@Inject
constructor(
private val context: Context,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
private val accessibilityActionsViewModel: AccessibilityActionsViewModel,
) : KeyguardSection() {
private var accessibilityActionsViewHandle: DisposableHandle? = null
override fun addViews(constraintLayout: ConstraintLayout) {
- if (!communalEnabled(context)) {
+ if (!communalSettingsInteractor.isCommunalFlagEnabled()) {
return
}
val view = View(constraintLayout.context).apply { id = R.id.accessibility_actions_view }
@@ -51,7 +52,7 @@ constructor(
}
override fun bindData(constraintLayout: ConstraintLayout) {
- if (!communalEnabled(context)) {
+ if (!communalSettingsInteractor.isCommunalFlagEnabled()) {
return
}
accessibilityActionsViewHandle =
@@ -100,7 +101,3 @@ constructor(
constraintLayout.removeView(R.id.accessibility_actions_view)
}
}
-
-private fun communalEnabled(context: Context): Boolean {
- return context.resources.getBoolean(R.bool.config_communalServiceEnabled) && Flags.communalHub()
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
index 0637bba9f1de..91e48b56b4f5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
@@ -48,6 +48,7 @@ import com.android.systemui.shared.R as sharedR
import com.android.systemui.util.ui.value
import dagger.Lazy
import javax.inject.Inject
+import kotlinx.coroutines.DisposableHandle
internal fun ConstraintSet.setVisibility(
views: Iterable<View>,
@@ -70,21 +71,24 @@ constructor(
val blueprintInteractor: Lazy<KeyguardBlueprintInteractor>,
private val rootViewModel: KeyguardRootViewModel,
) : KeyguardSection() {
+ private var disposableHandle: DisposableHandle? = null
+
override fun addViews(constraintLayout: ConstraintLayout) {}
override fun bindData(constraintLayout: ConstraintLayout) {
if (!MigrateClocksToBlueprint.isEnabled) {
return
}
-
- KeyguardClockViewBinder.bind(
- this,
- constraintLayout,
- keyguardClockViewModel,
- clockInteractor,
- blueprintInteractor.get(),
- rootViewModel,
- )
+ disposableHandle?.dispose()
+ disposableHandle =
+ KeyguardClockViewBinder.bind(
+ this,
+ constraintLayout,
+ keyguardClockViewModel,
+ clockInteractor,
+ blueprintInteractor.get(),
+ rootViewModel,
+ )
}
override fun applyConstraints(constraintSet: ConstraintSet) {
@@ -97,7 +101,13 @@ constructor(
}
}
- override fun removeViews(constraintLayout: ConstraintLayout) {}
+ override fun removeViews(constraintLayout: ConstraintLayout) {
+ if (!MigrateClocksToBlueprint.isEnabled) {
+ return
+ }
+
+ disposableHandle?.dispose()
+ }
private fun buildConstraints(
clock: ClockController,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
index e01f0a152b37..51230dd0a47c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
@@ -49,6 +49,7 @@ import com.android.systemui.statusbar.VibratorHelper
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.ExperimentalCoroutinesApi
/** Includes the device entry icon. */
@@ -70,6 +71,7 @@ constructor(
private val vibratorHelper: Lazy<VibratorHelper>,
) : KeyguardSection() {
private val deviceEntryIconViewId = R.id.device_entry_icon_view
+ private var disposableHandle: DisposableHandle? = null
override fun addViews(constraintLayout: ConstraintLayout) {
if (
@@ -97,15 +99,17 @@ constructor(
override fun bindData(constraintLayout: ConstraintLayout) {
if (DeviceEntryUdfpsRefactor.isEnabled) {
constraintLayout.findViewById<DeviceEntryIconView?>(deviceEntryIconViewId)?.let {
- DeviceEntryIconViewBinder.bind(
- applicationScope,
- it,
- deviceEntryIconViewModel.get(),
- deviceEntryForegroundViewModel.get(),
- deviceEntryBackgroundViewModel.get(),
- falsingManager.get(),
- vibratorHelper.get(),
- )
+ disposableHandle?.dispose()
+ disposableHandle =
+ DeviceEntryIconViewBinder.bind(
+ applicationScope,
+ it,
+ deviceEntryIconViewModel.get(),
+ deviceEntryForegroundViewModel.get(),
+ deviceEntryBackgroundViewModel.get(),
+ falsingManager.get(),
+ vibratorHelper.get(),
+ )
}
} else {
constraintLayout.findViewById<LockIconView?>(R.id.lock_icon_view)?.let {
@@ -178,6 +182,7 @@ constructor(
override fun removeViews(constraintLayout: ConstraintLayout) {
if (DeviceEntryUdfpsRefactor.isEnabled) {
constraintLayout.removeView(deviceEntryIconViewId)
+ disposableHandle?.dispose()
} else {
constraintLayout.removeView(R.id.lock_icon_view)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
index 8a751f05e102..55fc71823685 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
@@ -37,6 +37,7 @@ import com.android.systemui.shared.R as sharedR
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController
import dagger.Lazy
import javax.inject.Inject
+import kotlinx.coroutines.DisposableHandle
@SysUISingleton
open class SmartspaceSection
@@ -56,6 +57,7 @@ constructor(
private var smartspaceVisibilityListener: OnGlobalLayoutListener? = null
private var pastVisibility: Int = -1
+ private var disposableHandle: DisposableHandle? = null
override fun onRebuildBegin() {
smartspaceController.suppressDisconnects = true
@@ -96,12 +98,14 @@ constructor(
override fun bindData(constraintLayout: ConstraintLayout) {
if (!MigrateClocksToBlueprint.isEnabled) return
if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) return
- KeyguardSmartspaceViewBinder.bind(
- constraintLayout,
- keyguardClockViewModel,
- keyguardSmartspaceViewModel,
- blueprintInteractor.get(),
- )
+ disposableHandle?.dispose()
+ disposableHandle =
+ KeyguardSmartspaceViewBinder.bind(
+ constraintLayout,
+ keyguardClockViewModel,
+ keyguardSmartspaceViewModel,
+ blueprintInteractor.get(),
+ )
}
override fun applyConstraints(constraintSet: ConstraintSet) {
@@ -188,6 +192,8 @@ constructor(
}
smartspaceView?.viewTreeObserver?.removeOnGlobalLayoutListener(smartspaceVisibilityListener)
smartspaceVisibilityListener = null
+
+ disposableHandle?.dispose()
}
private fun updateVisibility(constraintSet: ConstraintSet) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
index caa043622e18..8485a265fc70 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
@@ -22,6 +22,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInte
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
+import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.ScrimAlpha
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -75,9 +76,12 @@ constructor(
return animationFlow
.setup(
duration = duration,
- // TODO(b/330311871): from can be PRIMARY_BOUNCER which would be a scene -> scene
- // transition
- edge = Edge.create(from = from, to = Scenes.Gone)
+ edge =
+ if (from == PRIMARY_BOUNCER) {
+ Edge.INVALID
+ } else {
+ Edge.create(from = from, to = Scenes.Gone)
+ }
)
.setupWithoutSceneContainer(
edge = Edge.create(from = from, to = GONE),
@@ -105,9 +109,12 @@ constructor(
animationFlow
.setup(
duration = duration,
- // TODO(b/330311871): from can be PRIMARY_BOUNCER which would be a scene ->
- // scene transition
- edge = Edge.create(from = fromState, to = Scenes.Gone),
+ edge =
+ if (fromState == PRIMARY_BOUNCER) {
+ Edge.INVALID
+ } else {
+ Edge.create(from = fromState, to = Scenes.Gone)
+ }
)
.setupWithoutSceneContainer(
edge = Edge.create(from = fromState, to = GONE),
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModel.kt
index 754ed6cc3327..1ee0368f15b1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModel.kt
@@ -25,6 +25,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
@@ -45,6 +46,13 @@ constructor(
edge = Edge.create(from = DREAMING, to = AOD),
)
+ /** Lockscreen views alpha */
+ val lockscreenAlpha: Flow<Float> =
+ transitionAnimation.sharedFlow(
+ duration = 300.milliseconds,
+ onStep = { it },
+ )
+
val deviceEntryBackgroundViewAlpha: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(0f)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt
index 8eab406a1273..6a3573ab0119 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt
@@ -23,7 +23,6 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
-import com.android.systemui.scene.shared.model.Scenes
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow
@@ -37,7 +36,7 @@ constructor(
private val transitionAnimation =
animationFlow
- .setup(duration = TO_GLANCEABLE_HUB_DURATION, edge = Edge.create(GONE, Scenes.Communal))
+ .setup(duration = TO_GLANCEABLE_HUB_DURATION, edge = Edge.INVALID)
.setupWithoutSceneContainer(edge = Edge.create(GONE, GLANCEABLE_HUB))
override val deviceEntryParentViewAlpha: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
index 573b75e623fb..73028c5cf496 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
@@ -30,7 +30,6 @@ import com.android.systemui.keyguard.shared.model.ClockSize
import com.android.systemui.keyguard.shared.model.ClockSizeSetting
import com.android.systemui.res.R
import com.android.systemui.shade.domain.interactor.ShadeInteractor
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel
import com.android.systemui.statusbar.ui.SystemBarUtilsProxy
import javax.inject.Inject
@@ -119,26 +118,25 @@ constructor(
combine(
isLargeClockVisible,
clockShouldBeCentered,
- shadeInteractor.shadeMode,
+ shadeInteractor.isShadeLayoutWide,
currentClock,
- ) { isLargeClockVisible, clockShouldBeCentered, shadeMode, currentClock ->
- val shouldUseSplitShade = shadeMode == ShadeMode.Split
+ ) { isLargeClockVisible, clockShouldBeCentered, isShadeLayoutWide, currentClock ->
if (currentClock?.config?.useCustomClockScene == true) {
when {
- shouldUseSplitShade && clockShouldBeCentered ->
+ isShadeLayoutWide && clockShouldBeCentered ->
ClockLayout.WEATHER_LARGE_CLOCK
- shouldUseSplitShade && isLargeClockVisible ->
+ isShadeLayoutWide && isLargeClockVisible ->
ClockLayout.SPLIT_SHADE_WEATHER_LARGE_CLOCK
- shouldUseSplitShade -> ClockLayout.SPLIT_SHADE_SMALL_CLOCK
+ isShadeLayoutWide -> ClockLayout.SPLIT_SHADE_SMALL_CLOCK
isLargeClockVisible -> ClockLayout.WEATHER_LARGE_CLOCK
else -> ClockLayout.SMALL_CLOCK
}
} else {
when {
- shouldUseSplitShade && clockShouldBeCentered -> ClockLayout.LARGE_CLOCK
- shouldUseSplitShade && isLargeClockVisible ->
+ isShadeLayoutWide && clockShouldBeCentered -> ClockLayout.LARGE_CLOCK
+ isShadeLayoutWide && isLargeClockVisible ->
ClockLayout.SPLIT_SHADE_LARGE_CLOCK
- shouldUseSplitShade -> ClockLayout.SPLIT_SHADE_SMALL_CLOCK
+ isShadeLayoutWide -> ClockLayout.SPLIT_SHADE_SMALL_CLOCK
isLargeClockVisible -> ClockLayout.LARGE_CLOCK
else -> ClockLayout.SMALL_CLOCK
}
@@ -164,7 +162,7 @@ constructor(
/** Calculates the top margin for the small clock. */
fun getSmallClockTopMargin(): Int {
val statusBarHeight = systemBarUtils.getStatusBarHeaderHeightKeyguard()
- return if (shadeInteractor.shadeMode.value == ShadeMode.Split) {
+ return if (shadeInteractor.isShadeLayoutWide.value) {
resources.getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin) -
if (ComposeLockscreen.isEnabled) statusBarHeight else 0
} else {
@@ -176,7 +174,7 @@ constructor(
val smallClockTopMargin =
combine(
configurationInteractor.onAnyConfigurationChange,
- shadeInteractor.shadeMode,
+ shadeInteractor.isShadeLayoutWide,
) { _, _ ->
getSmallClockTopMargin()
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
index c4383fc0857d..680f966708be 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
@@ -18,6 +18,7 @@
package com.android.systemui.keyguard.ui.viewmodel
import androidx.annotation.VisibleForTesting
+import com.android.app.tracing.FlowTracing.traceEmissionCount
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -229,7 +230,7 @@ constructor(
)
}
.distinctUntilChanged()
- }
+ }.traceEmissionCount({"QuickAfforcances#button${position.toSlotId()}"})
}
private fun KeyguardQuickAffordanceModel.toViewModel(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index d7ac976ec00f..350ceb47848f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -91,8 +91,9 @@ constructor(
private val dozingToGoneTransitionViewModel: DozingToGoneTransitionViewModel,
private val dozingToLockscreenTransitionViewModel: DozingToLockscreenTransitionViewModel,
private val dozingToOccludedTransitionViewModel: DozingToOccludedTransitionViewModel,
- private val dreamingToLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel,
+ private val dreamingToAodTransitionViewModel: DreamingToAodTransitionViewModel,
private val dreamingToGoneTransitionViewModel: DreamingToGoneTransitionViewModel,
+ private val dreamingToLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel,
private val glanceableHubToLockscreenTransitionViewModel:
GlanceableHubToLockscreenTransitionViewModel,
private val goneToAodTransitionViewModel: GoneToAodTransitionViewModel,
@@ -143,7 +144,7 @@ constructor(
private val isOnLockscreen: Flow<Boolean> =
combine(
- keyguardTransitionInteractor.isFinishedInState(LOCKSCREEN).onStart { emit(false) },
+ keyguardTransitionInteractor.isFinishedIn(LOCKSCREEN).onStart { emit(false) },
anyOf(
keyguardTransitionInteractor.isInTransition(Edge.create(to = LOCKSCREEN)),
keyguardTransitionInteractor.isInTransition(Edge.create(from = LOCKSCREEN)),
@@ -160,7 +161,7 @@ constructor(
edgeWithoutSceneContainer = Edge.create(from = LOCKSCREEN, to = GONE),
),
keyguardTransitionInteractor.isInTransition(
- edge = Edge.create(from = PRIMARY_BOUNCER, to = Scenes.Lockscreen),
+ edge = Edge.create(from = Scenes.Bouncer, to = LOCKSCREEN),
edgeWithoutSceneContainer =
Edge.create(from = PRIMARY_BOUNCER, to = LOCKSCREEN),
),
@@ -243,6 +244,7 @@ constructor(
dozingToGoneTransitionViewModel.lockscreenAlpha(viewState),
dozingToLockscreenTransitionViewModel.lockscreenAlpha,
dozingToOccludedTransitionViewModel.lockscreenAlpha(viewState),
+ dreamingToAodTransitionViewModel.lockscreenAlpha,
dreamingToGoneTransitionViewModel.lockscreenAlpha,
dreamingToLockscreenTransitionViewModel.lockscreenAlpha,
glanceableHubToLockscreenTransitionViewModel.keyguardAlpha,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
index 1de0abeb931b..4bfefda63466 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.ui.viewmodel
import android.content.res.Resources
+import com.android.compose.animation.scene.SceneKey
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.biometrics.AuthController
import com.android.systemui.dagger.SysUISingleton
@@ -25,15 +26,18 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteract
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.keyguard.shared.model.ClockSize
import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
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.combine
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
@@ -48,33 +52,14 @@ constructor(
val shadeInteractor: ShadeInteractor,
@Application private val applicationScope: CoroutineScope,
unfoldTransitionInteractor: UnfoldTransitionInteractor,
+ occlusionInteractor: SceneContainerOcclusionInteractor,
) {
@VisibleForTesting val clockSize = clockInteractor.clockSize
val isUdfpsVisible: Boolean
get() = authController.isUdfpsSupported
- val shouldUseSplitNotificationShade: StateFlow<Boolean> =
- shadeInteractor.shadeMode
- .map { it == ShadeMode.Split }
- .stateIn(
- scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = false,
- )
-
- val areNotificationsVisible: StateFlow<Boolean> =
- combine(
- clockSize,
- shouldUseSplitNotificationShade,
- ) { clockSize, shouldUseSplitNotificationShade ->
- clockSize == ClockSize.SMALL || shouldUseSplitNotificationShade
- }
- .stateIn(
- scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = false,
- )
+ val isShadeLayoutWide: StateFlow<Boolean> = shadeInteractor.isShadeLayoutWide
/** Amount of horizontal translation that should be applied to elements in the scene. */
val unfoldTranslations: StateFlow<UnfoldTranslations> =
@@ -93,6 +78,35 @@ constructor(
initialValue = UnfoldTranslations(),
)
+ /** Whether the content of the scene UI should be shown. */
+ val isContentVisible: StateFlow<Boolean> =
+ occlusionInteractor.isOccludingActivityShown
+ .map { !it }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = true,
+ )
+
+ /**
+ * Returns a flow that indicates whether lockscreen notifications should be rendered in the
+ * given [sceneKey].
+ */
+ fun areNotificationsVisible(sceneKey: SceneKey): Flow<Boolean> {
+ // `Scenes.NotificationsShade` renders its own separate notifications stack, so when it's
+ // open we avoid rendering the lockscreen notifications stack.
+ if (sceneKey == Scenes.NotificationsShade) {
+ return flowOf(false)
+ }
+
+ return combine(
+ clockSize,
+ shadeInteractor.isShadeLayoutWide,
+ ) { clockSize, isShadeLayoutWide ->
+ clockSize == ClockSize.SMALL || isShadeLayoutWide
+ }
+ }
+
fun getSmartSpacePaddingTop(resources: Resources): Int {
return if (clockSize.value == ClockSize.LARGE) {
resources.getDimensionPixelSize(R.dimen.keyguard_smartspace_top_offset) +
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt
index 754fb94a572e..9ec15dcff5f4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt
@@ -23,7 +23,6 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
-import com.android.systemui.scene.shared.model.Scenes
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@@ -33,10 +32,7 @@ class PrimaryBouncerToGlanceableHubTransitionViewModel
constructor(animationFlow: KeyguardTransitionAnimationFlow) : DeviceEntryIconTransition {
private val transitionAnimation =
animationFlow
- .setup(
- duration = TO_GLANCEABLE_HUB_DURATION,
- edge = Edge.create(PRIMARY_BOUNCER, Scenes.Communal)
- )
+ .setup(duration = TO_GLANCEABLE_HUB_DURATION, edge = Edge.INVALID)
.setupWithoutSceneContainer(edge = Edge.create(PRIMARY_BOUNCER, GLANCEABLE_HUB))
override val deviceEntryParentViewAlpha: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
index 7ae455818952..46ba5d13bb6d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
@@ -26,7 +26,6 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.ScrimAlpha
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.SysuiStatusBarStateController
import dagger.Lazy
import javax.inject.Inject
@@ -54,7 +53,7 @@ constructor(
animationFlow
.setup(
duration = TO_GONE_DURATION,
- edge = Edge.create(from = PRIMARY_BOUNCER, to = Scenes.Gone),
+ edge = Edge.INVALID,
)
.setupWithoutSceneContainer(
edge = Edge.create(from = PRIMARY_BOUNCER, to = GONE),
diff --git a/packages/SystemUI/src/com/android/systemui/log/SessionTracker.java b/packages/SystemUI/src/com/android/systemui/log/SessionTracker.java
index d848b431bcc9..e8ded03e3b38 100644
--- a/packages/SystemUI/src/com/android/systemui/log/SessionTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/log/SessionTracker.java
@@ -22,6 +22,7 @@ import static android.app.StatusBarManager.SESSION_KEYGUARD;
import android.annotation.Nullable;
import android.os.RemoteException;
+import android.os.UserManager;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -36,6 +37,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.CoreStartable;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.process.ProcessWrapper;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import java.io.PrintWriter;
@@ -63,6 +65,7 @@ public class SessionTracker implements CoreStartable {
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final KeyguardStateController mKeyguardStateController;
private final UiEventLogger mUiEventLogger;
+ private final ProcessWrapper mProcessWrapper;
private final Map<Integer, InstanceId> mSessionToInstanceId = new HashMap<>();
private boolean mKeyguardSessionStarted;
@@ -73,13 +76,15 @@ public class SessionTracker implements CoreStartable {
AuthController authController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
KeyguardStateController keyguardStateController,
- UiEventLogger uiEventLogger
+ UiEventLogger uiEventLogger,
+ ProcessWrapper processWrapper
) {
mStatusBarManagerService = statusBarService;
mAuthController = authController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mKeyguardStateController = keyguardStateController;
mUiEventLogger = uiEventLogger;
+ mProcessWrapper = processWrapper;
}
@Override
@@ -109,6 +114,16 @@ public class SessionTracker implements CoreStartable {
final InstanceId instanceId = mInstanceIdGenerator.newInstanceId();
mSessionToInstanceId.put(type, instanceId);
+
+ if (UserManager.isVisibleBackgroundUsersEnabled() && !mProcessWrapper.isSystemUser()
+ && !mProcessWrapper.isForegroundUser()) {
+ // TODO: b/341604160 - Support visible background users properly.
+ if (DEBUG) {
+ Log.d(TAG, "Status bar manager is disabled for visible background users");
+ }
+ return;
+ }
+
try {
if (DEBUG) {
Log.d(TAG, "Session start for [" + getString(type) + "] id=" + instanceId);
@@ -139,6 +154,14 @@ public class SessionTracker implements CoreStartable {
if (endSessionUiEvent != null) {
mUiEventLogger.log(endSessionUiEvent, instanceId);
}
+ if (UserManager.isVisibleBackgroundUsersEnabled() && !mProcessWrapper.isSystemUser()
+ && !mProcessWrapper.isForegroundUser()) {
+ // TODO: b/341604160 - Support visible background users properly.
+ if (DEBUG) {
+ Log.d(TAG, "Status bar manager is disabled for visible background users");
+ }
+ return;
+ }
mStatusBarManagerService.onSessionEnded(type, instanceId);
} catch (RemoteException e) {
Log.e(TAG, "Unable to send onSessionEnded for session="
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 52b0b87ddb58..d1c9b8ea1803 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -369,9 +369,9 @@ public class LogModule {
*/
@Provides
@SysUISingleton
- @MediaLoadingLog
- public static LogBuffer providesMediaLoadingLogBuffer(LogBufferFactory factory) {
- return factory.create("MediaLoadingLog", 20);
+ @MediaLog
+ public static LogBuffer providesMediaLogBuffer(LogBufferFactory factory) {
+ return factory.create("MediaLog", 20);
}
/** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/MediaLoadingLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaLog.kt
index 05e1b2e2cd23..d1dc6f394ee5 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/MediaLoadingLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaLog.kt
@@ -19,8 +19,5 @@ package com.android.systemui.log.dagger
import com.android.systemui.log.LogBuffer
import javax.inject.Qualifier
-/** A [LogBuffer] for [com.android.systemui.media.controls.domain.pipeline.MediaLoadingLogger] */
-@Qualifier
-@MustBeDocumented
-@Retention(AnnotationRetention.RUNTIME)
-annotation class MediaLoadingLog
+/** A [LogBuffer] for [com.android.systemui.media.controls.shared.MediaLogger] */
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class MediaLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java
index 939dab2ecefa..28bdbb25ea8c 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java
@@ -20,13 +20,14 @@ package com.android.systemui.log.dagger;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import com.android.systemui.log.LogBuffer;
+import com.android.systemui.navigationbar.views.NavigationBar;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import javax.inject.Qualifier;
-/** A {@link LogBuffer} for {@link com.android.systemui.navigationbar.NavigationBar}. */
+/** A {@link LogBuffer} for {@link NavigationBar}. */
@Qualifier
@Documented
@Retention(RUNTIME)
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java
index 46790a66cbb6..d09eeb2e8ad5 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java
@@ -19,13 +19,14 @@ package com.android.systemui.log.dagger;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import com.android.systemui.log.LogBuffer;
+import com.android.systemui.navigationbar.views.NavigationBar;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import javax.inject.Qualifier;
-/** A {@link LogBuffer} for {@link com.android.systemui.navigationbar.NavigationBar}. */
+/** A {@link LogBuffer} for {@link NavigationBar}. */
@Qualifier
@Documented
@Retention(RUNTIME)
diff --git a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
index 988fe640de2d..18a04ec60d56 100644
--- a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
@@ -158,7 +158,7 @@ public class NotificationPlayer implements OnCompletionListener, OnErrorListener
}
if (mp != null) {
if (DEBUG) {
- Log.d(mTag, "mPlayer.pause+release piid:" + player.getPlayerIId());
+ Log.d(mTag, "mp.pause+release piid:" + mp.getPlayerIId());
}
mp.pause();
try {
diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
index bda006915c94..e7c2a454e16c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
@@ -17,7 +17,6 @@
package com.android.systemui.media;
import android.annotation.Nullable;
-import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -124,13 +123,9 @@ public class RingtonePlayer implements CoreStartable {
boolean looping, @Nullable VolumeShaper.Configuration volumeShaperConfig)
throws RemoteException {
if (LOGD) {
- Log.d(TAG, "play(token=" + token + ", uri=" + uri
- + ", uid=" + Binder.getCallingUid()
- + ") uriUserId=" + ContentProvider.getUserIdFromUri(uri)
- + " callingUserId=" + Binder.getCallingUserHandle().getIdentifier());
+ Log.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid="
+ + Binder.getCallingUid() + ")");
}
- enforceUriUserId(uri);
-
Client client;
synchronized (mClients) {
client = mClients.get(token);
@@ -212,7 +207,6 @@ public class RingtonePlayer implements CoreStartable {
@Override
public String getTitle(Uri uri) {
- enforceUriUserId(uri);
final UserHandle user = Binder.getCallingUserHandle();
return Ringtone.getTitle(getContextForUser(user), uri,
false /*followSettingsUri*/, false /*allowRemote*/);
@@ -245,25 +239,6 @@ public class RingtonePlayer implements CoreStartable {
}
throw new SecurityException("Uri is not ringtone, alarm, or notification: " + uri);
}
-
- /**
- * Must be called from the Binder calling thread.
- * Ensures caller is from the same userId as the content they're trying to access.
- * @param uri the URI to check
- * @throws SecurityException when non-system call or userId in uri differs from the
- * caller's userId
- */
- private void enforceUriUserId(Uri uri) throws SecurityException {
- final int uriUserId = ContentProvider.getUserIdFromUri(uri);
- final int callerUserId = Binder.getCallingUserHandle().getIdentifier();
- // for a non-system call, verify the URI to play belongs to the same user as the caller
- if (UserHandle.isApp(Binder.getCallingUid()) && uriUserId != callerUserId) {
- throw new SecurityException("Illegal access to uri=" + uri
- + " content associated with user=" + uriUserId
- + ", request originates from user=" + callerUserId);
- }
- }
-
};
private Context getContextForUser(UserHandle user) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
index 803e7efa7f60..68f1af311b1b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
@@ -27,6 +27,7 @@ import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.media.controls.data.repository.MediaFilterRepository
+import com.android.systemui.media.controls.shared.MediaLogger
import com.android.systemui.media.controls.shared.model.EXTRA_KEY_TRIGGER_RESUME
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
@@ -70,7 +71,7 @@ constructor(
private val logger: MediaUiEventLogger,
private val mediaFlags: MediaFlags,
private val mediaFilterRepository: MediaFilterRepository,
- private val mediaLoadingLogger: MediaLoadingLogger,
+ private val mediaLogger: MediaLogger,
) : MediaDataManager.Listener {
/** Non-UI listeners to media changes. */
private val _listeners: MutableSet<MediaDataProcessor.Listener> = mutableSetOf()
@@ -118,7 +119,7 @@ constructor(
val isUpdate = mediaFilterRepository.addSelectedUserMediaEntry(data)
- mediaLoadingLogger.logMediaLoaded(data.instanceId, data.active, "loading media")
+ mediaLogger.logMediaLoaded(data.instanceId, data.active, "loading media")
mediaFilterRepository.addMediaDataLoadingState(
MediaDataLoadingModel.Loaded(data.instanceId),
isUpdate
@@ -189,7 +190,7 @@ constructor(
isSsReactivated = true
)
)
- mediaLoadingLogger.logMediaLoaded(
+ mediaLogger.logMediaLoaded(
mediaData.instanceId,
mediaData.active,
"reactivating media instead of smartspace"
@@ -226,7 +227,7 @@ constructor(
mediaFilterRepository.setRecommendationsLoadingState(
SmartspaceMediaLoadingModel.Loaded(key, shouldPrioritizeMutable)
)
- mediaLoadingLogger.logRecommendationLoaded(key, data.isActive, "loading recommendations")
+ mediaLogger.logRecommendationLoaded(key, data.isActive, "loading recommendations")
listeners.forEach { it.onSmartspaceMediaDataLoaded(key, data, shouldPrioritizeMutable) }
}
@@ -237,7 +238,7 @@ constructor(
mediaFilterRepository.addMediaDataLoadingState(
MediaDataLoadingModel.Removed(instanceId)
)
- mediaLoadingLogger.logMediaRemoved(instanceId, "removing media card")
+ mediaLogger.logMediaRemoved(instanceId, "removing media card")
// Only notify listeners if something actually changed
listeners.forEach { it.onMediaDataRemoved(key, userInitiated) }
}
@@ -253,11 +254,7 @@ constructor(
mediaFilterRepository.addMediaDataLoadingState(
MediaDataLoadingModel.Loaded(lastActiveId, immediately)
)
- mediaLoadingLogger.logMediaLoaded(
- lastActiveId,
- it.active,
- "expiring reactivated id"
- )
+ mediaLogger.logMediaLoaded(lastActiveId, it.active, "expiring reactivated id")
listeners.forEach { listener ->
getKey(lastActiveId)?.let { lastActiveKey ->
listener.onMediaDataLoaded(lastActiveKey, lastActiveKey, it, immediately)
@@ -278,11 +275,7 @@ constructor(
mediaFilterRepository.setRecommendationsLoadingState(
SmartspaceMediaLoadingModel.Removed(key, immediately)
)
- mediaLoadingLogger.logRecommendationRemoved(
- key,
- immediately,
- "removing recommendations card"
- )
+ mediaLogger.logRecommendationRemoved(key, immediately, "removing recommendations card")
listeners.forEach { it.onSmartspaceMediaDataRemoved(key, immediately) }
}
@@ -296,10 +289,7 @@ constructor(
mediaFilterRepository.addMediaDataLoadingState(
MediaDataLoadingModel.Removed(data.instanceId)
)
- mediaLoadingLogger.logMediaRemoved(
- data.instanceId,
- "Removing $key after profile change"
- )
+ mediaLogger.logMediaRemoved(data.instanceId, "Removing $key after profile change")
listeners.forEach { listener -> listener.onMediaDataRemoved(key, false) }
}
}
@@ -316,7 +306,7 @@ constructor(
mediaFilterRepository.addMediaDataLoadingState(
MediaDataLoadingModel.Removed(instanceId)
)
- mediaLoadingLogger.logMediaRemoved(instanceId, "Removing media after user change")
+ mediaLogger.logMediaRemoved(instanceId, "Removing media after user change")
getKey(instanceId)?.let {
listenersCopy.forEach { listener -> listener.onMediaDataRemoved(it, false) }
}
@@ -329,7 +319,7 @@ constructor(
MediaDataLoadingModel.Loaded(data.instanceId),
isUpdate
)
- mediaLoadingLogger.logMediaLoaded(
+ mediaLogger.logMediaLoaded(
data.instanceId,
data.active,
"Re-adding $key after user change"
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/MediaLogger.kt
index c6cfd659eed5..2b710b5a67b7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/MediaLogger.kt
@@ -14,18 +14,18 @@
* limitations under the License.
*/
-package com.android.systemui.media.controls.domain.pipeline
+package com.android.systemui.media.controls.shared
import com.android.internal.logging.InstanceId
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
-import com.android.systemui.log.dagger.MediaLoadingLog
+import com.android.systemui.log.dagger.MediaLog
import javax.inject.Inject
/** A buffered log for media loading events. */
@SysUISingleton
-class MediaLoadingLogger @Inject constructor(@MediaLoadingLog private val buffer: LogBuffer) {
+class MediaLogger @Inject constructor(@MediaLog private val buffer: LogBuffer) {
fun logMediaLoaded(instanceId: InstanceId, active: Boolean, reason: String) {
buffer.log(
@@ -78,7 +78,43 @@ class MediaLoadingLogger @Inject constructor(@MediaLoadingLog private val buffer
)
}
+ fun logMediaCardAdded(instanceId: InstanceId) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ { str1 = instanceId.toString() },
+ { "adding media card $str1 to carousel" }
+ )
+ }
+
+ fun logMediaCardRemoved(instanceId: InstanceId) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ { str1 = instanceId.toString() },
+ { "removing media card $str1 from carousel" }
+ )
+ }
+
+ fun logMediaRecommendationCardAdded(key: String) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ { str1 = key },
+ { "adding recommendation card $str1 to carousel" }
+ )
+ }
+
+ fun logMediaRecommendationCardRemoved(key: String) {
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ { str1 = key },
+ { "removing recommendation card $str1 from carousel" }
+ )
+ }
+
companion object {
- private const val TAG = "MediaLoadingLog"
+ private const val TAG = "MediaLog"
}
}
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 125f97375fea..46c5c188344e 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
@@ -662,13 +662,9 @@ constructor(
@VisibleForTesting
internal fun listenForAnyStateToGoneKeyguardTransition(scope: CoroutineScope): Job {
return scope.launch {
- if (SceneContainerFlag.isEnabled) {
- sceneInteractor.transitionState.filter { it.isIdle(Scenes.Gone) }
- } else {
- keyguardTransitionInteractor.transition(Edge.create(to = GONE)).filter {
- it.transitionState == TransitionState.FINISHED
- }
- }
+ keyguardTransitionInteractor
+ .isFinishedIn(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+ .filter { it }
.collect {
showMediaCarousel()
updateHostVisibility()
@@ -849,8 +845,25 @@ constructor(
commonViewModels.addAll(viewModels)
// Ensure we only show the needed UMOs in media carousel.
- val viewSet = viewModels.toHashSet()
- controllerByViewModel.filter { !viewSet.contains(it.key) }.forEach { onRemoved(it.key) }
+ val viewIds =
+ viewModels
+ .map { mediaCommonViewModel ->
+ when (mediaCommonViewModel) {
+ is MediaCommonViewModel.MediaControl ->
+ mediaCommonViewModel.instanceId.toString()
+ is MediaCommonViewModel.MediaRecommendations -> mediaCommonViewModel.key
+ }
+ }
+ .toHashSet()
+ controllerByViewModel
+ .filter {
+ when (val viewModel = it.key) {
+ is MediaCommonViewModel.MediaControl ->
+ !viewIds.contains(viewModel.instanceId.toString())
+ is MediaCommonViewModel.MediaRecommendations -> !viewIds.contains(viewModel.key)
+ }
+ }
+ .forEach { onRemoved(it.key) }
}
private suspend fun getMediaLockScreenSetting(): Boolean {
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 c453a212a3cd..e7f7171d5be3 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
@@ -23,6 +23,7 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.factory.MediaControlInteractorFactory
+import com.android.systemui.media.controls.shared.MediaLogger
import com.android.systemui.media.controls.shared.model.MediaCommonModel
import com.android.systemui.media.controls.util.MediaFlags
import com.android.systemui.media.controls.util.MediaUiEventLogger
@@ -52,6 +53,7 @@ constructor(
private val recommendationsViewModel: MediaRecommendationsViewModel,
private val logger: MediaUiEventLogger,
private val mediaFlags: MediaFlags,
+ private val mediaLogger: MediaLogger,
) {
val mediaItems: StateFlow<List<MediaCommonViewModel>> =
@@ -131,10 +133,14 @@ constructor(
instanceId = instanceId,
immediatelyUpdateUi = commonModel.mediaLoadedModel.immediatelyUpdateUi,
controlViewModel = createMediaControlViewModel(instanceId),
- onAdded = { onMediaControlAddedOrUpdated(it, commonModel) },
+ onAdded = {
+ mediaLogger.logMediaCardAdded(instanceId)
+ onMediaControlAddedOrUpdated(it, commonModel)
+ },
onRemoved = {
interactor.removeMediaControl(instanceId, delay = 0L)
mediaControlByInstanceId.remove(instanceId)
+ mediaLogger.logMediaCardRemoved(instanceId)
},
onUpdated = { onMediaControlAddedOrUpdated(it, commonModel) },
isMediaFromRec = commonModel.isMediaFromRec,
@@ -168,6 +174,9 @@ constructor(
mediaFlags.isPersistentSsCardEnabled(),
recsViewModel = recommendationsViewModel,
onAdded = { commonViewModel ->
+ mediaLogger.logMediaRecommendationCardAdded(
+ commonModel.recsLoadingModel.key
+ )
onMediaRecommendationAddedOrUpdated(
commonViewModel as MediaCommonViewModel.MediaRecommendations
)
@@ -215,6 +224,7 @@ constructor(
commonModel: MediaCommonModel.MediaRecommendations,
immediatelyRemove: Boolean
) {
+ mediaLogger.logMediaRecommendationCardRemoved(commonModel.recsLoadingModel.key)
if (immediatelyRemove || isReorderingAllowed()) {
interactor.dismissSmartspaceRecommendation(commonModel.recsLoadingModel.key, 0L)
mediaRecs = null
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionLog.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionLog.kt
new file mode 100644
index 000000000000..a80bc0975197
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionLog.kt
@@ -0,0 +1,25 @@
+/*
+ * 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.mediaprojection
+
+import javax.inject.Qualifier
+
+/** Logs for media projection related events. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class MediaProjectionLog
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionModule.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionModule.kt
index 34894599aaf9..7fd77a9bdb00 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionModule.kt
@@ -16,12 +16,25 @@
package com.android.systemui.mediaprojection
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogBufferFactory
import com.android.systemui.mediaprojection.data.repository.MediaProjectionManagerRepository
import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository
import dagger.Binds
import dagger.Module
+import dagger.Provides
@Module
interface MediaProjectionModule {
@Binds fun mediaRepository(impl: MediaProjectionManagerRepository): MediaProjectionRepository
+
+ companion object {
+ @Provides
+ @SysUISingleton
+ @MediaProjectionLog
+ fun provideMediaProjectionLogBuffer(factory: LogBufferFactory): LogBuffer {
+ return factory.create("MediaProjection", 50)
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/model/MediaProjectionState.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/model/MediaProjectionState.kt
index de300b2ff900..82b48251cc8a 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/model/MediaProjectionState.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/model/MediaProjectionState.kt
@@ -28,13 +28,25 @@ sealed interface MediaProjectionState {
*
* @property hostPackage the package name of the app that is receiving the content of the media
* projection (aka which app the phone screen contents are being sent to).
+ * @property hostDeviceName the name of the other device that's receiving the content of the
+ * media projection. Null if the media projection is going to this same device (e.g. another
+ * app is recording the screen).
*/
- sealed class Projecting(open val hostPackage: String) : MediaProjectionState {
+ sealed class Projecting(
+ open val hostPackage: String,
+ open val hostDeviceName: String?,
+ ) : MediaProjectionState {
/** The entire screen is being projected. */
- data class EntireScreen(override val hostPackage: String) : Projecting(hostPackage)
+ data class EntireScreen(
+ override val hostPackage: String,
+ override val hostDeviceName: String? = null,
+ ) : Projecting(hostPackage, hostDeviceName)
/** Only a single task is being projected. */
- data class SingleTask(override val hostPackage: String, val task: RunningTaskInfo) :
- Projecting(hostPackage)
+ data class SingleTask(
+ override val hostPackage: String,
+ override val hostDeviceName: String?,
+ val task: RunningTaskInfo,
+ ) : Projecting(hostPackage, hostDeviceName)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
index 8a9adc7a5c88..5704e8048b7d 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
@@ -17,10 +17,10 @@
package com.android.systemui.mediaprojection.data.repository
import android.app.ActivityManager.RunningTaskInfo
+import android.hardware.display.DisplayManager
import android.media.projection.MediaProjectionInfo
import android.media.projection.MediaProjectionManager
import android.os.Handler
-import android.util.Log
import android.view.ContentRecordingSession
import android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
@@ -28,6 +28,9 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.mediaprojection.MediaProjectionLog
import com.android.systemui.mediaprojection.MediaProjectionServiceHelper
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.taskswitcher.data.repository.TasksRepository
@@ -35,37 +38,49 @@ import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.stateIn
-import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@SysUISingleton
+@OptIn(ExperimentalCoroutinesApi::class)
class MediaProjectionManagerRepository
@Inject
constructor(
private val mediaProjectionManager: MediaProjectionManager,
+ private val displayManager: DisplayManager,
@Main private val handler: Handler,
@Application private val applicationScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
private val tasksRepository: TasksRepository,
private val mediaProjectionServiceHelper: MediaProjectionServiceHelper,
+ @MediaProjectionLog private val logger: LogBuffer,
) : MediaProjectionRepository {
override suspend fun switchProjectedTask(task: RunningTaskInfo) {
withContext(backgroundDispatcher) {
if (mediaProjectionServiceHelper.updateTaskRecordingSession(task.token)) {
- Log.d(TAG, "Successfully switched projected task")
+ logger.log(TAG, LogLevel.DEBUG, {}, { "Successfully switched projected task" })
} else {
- Log.d(TAG, "Failed to switch projected task")
+ logger.log(TAG, LogLevel.WARNING, {}, { "Failed to switch projected task" })
}
}
}
override suspend fun stopProjecting() {
- withContext(backgroundDispatcher) { mediaProjectionManager.stopActiveProjection() }
+ withContext(backgroundDispatcher) {
+ logger.log(
+ TAG,
+ LogLevel.DEBUG,
+ {},
+ { "Requesting MediaProjectionManager#stopActiveProjection" },
+ )
+ mediaProjectionManager.stopActiveProjection()
+ }
}
override val mediaProjectionState: Flow<MediaProjectionState> =
@@ -73,28 +88,65 @@ constructor(
val callback =
object : MediaProjectionManager.Callback() {
override fun onStart(info: MediaProjectionInfo?) {
- Log.d(TAG, "MediaProjectionManager.Callback#onStart")
- trySendWithFailureLogging(MediaProjectionState.NotProjecting, TAG)
+ logger.log(
+ TAG,
+ LogLevel.DEBUG,
+ {},
+ { "MediaProjectionManager.Callback#onStart" },
+ )
+ trySendWithFailureLogging(CallbackEvent.OnStart, TAG)
}
override fun onStop(info: MediaProjectionInfo?) {
- Log.d(TAG, "MediaProjectionManager.Callback#onStop")
- trySendWithFailureLogging(MediaProjectionState.NotProjecting, TAG)
+ logger.log(
+ TAG,
+ LogLevel.DEBUG,
+ {},
+ { "MediaProjectionManager.Callback#onStop" },
+ )
+ trySendWithFailureLogging(CallbackEvent.OnStop, TAG)
}
override fun onRecordingSessionSet(
info: MediaProjectionInfo,
session: ContentRecordingSession?
) {
- Log.d(TAG, "MediaProjectionManager.Callback#onSessionStarted: $session")
- launch {
- trySendWithFailureLogging(stateForSession(info, session), TAG)
- }
+ logger.log(
+ TAG,
+ LogLevel.DEBUG,
+ { str1 = session.toString() },
+ { "MediaProjectionManager.Callback#onSessionStarted: $str1" },
+ )
+ trySendWithFailureLogging(
+ CallbackEvent.OnRecordingSessionSet(info, session),
+ TAG,
+ )
}
}
mediaProjectionManager.addCallback(callback, handler)
awaitClose { mediaProjectionManager.removeCallback(callback) }
}
+ // When we get an #onRecordingSessionSet event, we need to do some work in the
+ // background before emitting the right state value. But when we get an #onStop
+ // event, we immediately know what state value to emit.
+ //
+ // Without `mapLatest`, this could be a problem if an #onRecordingSessionSet event
+ // comes in and then an #onStop event comes in shortly afterwards (b/352483752):
+ // 1. #onRecordingSessionSet -> start some work in the background
+ // 2. #onStop -> immediately emit "Not Projecting"
+ // 3. onRecordingSessionSet work finishes -> emit "Projecting"
+ //
+ // At step 3, we *shouldn't* emit "Projecting" because #onStop was the last callback
+ // event we received, so we should be "Not Projecting". This `mapLatest` ensures
+ // that if an #onStop event comes in, we cancel any ongoing work for
+ // #onRecordingSessionSet and we don't emit "Projecting".
+ .mapLatest {
+ when (it) {
+ is CallbackEvent.OnStart,
+ is CallbackEvent.OnStop -> MediaProjectionState.NotProjecting
+ is CallbackEvent.OnRecordingSessionSet -> stateForSession(it.info, it.session)
+ }
+ }
.stateIn(
scope = applicationScope,
started = SharingStarted.Lazily,
@@ -110,14 +162,36 @@ constructor(
}
val hostPackage = info.packageName
+ val hostDeviceName =
+ withContext(backgroundDispatcher) {
+ // If the projection is to a different device, then the session's display ID should
+ // identify the display associated with that different device.
+ displayManager.getDisplay(session.virtualDisplayId)?.name
+ }
+
if (session.contentToRecord == RECORD_CONTENT_DISPLAY || session.tokenToRecord == null) {
- return MediaProjectionState.Projecting.EntireScreen(hostPackage)
+ return MediaProjectionState.Projecting.EntireScreen(hostPackage, hostDeviceName)
}
val matchingTask =
tasksRepository.findRunningTaskFromWindowContainerToken(
checkNotNull(session.tokenToRecord)
- ) ?: return MediaProjectionState.Projecting.EntireScreen(hostPackage)
- return MediaProjectionState.Projecting.SingleTask(hostPackage, matchingTask)
+ ) ?: return MediaProjectionState.Projecting.EntireScreen(hostPackage, hostDeviceName)
+ return MediaProjectionState.Projecting.SingleTask(hostPackage, hostDeviceName, matchingTask)
+ }
+
+ /**
+ * Translates [MediaProjectionManager.Callback] events into objects so that we always maintain
+ * the correct callback ordering.
+ */
+ sealed interface CallbackEvent {
+ data object OnStart : CallbackEvent
+
+ data object OnStop : CallbackEvent
+
+ data class OnRecordingSessionSet(
+ val info: MediaProjectionInfo,
+ val session: ContentRecordingSession?,
+ ) : CallbackEvent
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt
index 6224170fd906..83f694bb1980 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt
@@ -104,7 +104,7 @@ abstract class BaseMediaProjectionPermissionDialogDelegate<T : AlertDialog>(
private fun initScreenShareSpinner() {
val adapter = OptionsAdapter(dialog.context.applicationContext, screenShareOptions)
- screenShareModeSpinner = dialog.requireViewById(R.id.screen_share_mode_spinner)
+ screenShareModeSpinner = dialog.requireViewById(R.id.screen_share_mode_options)
screenShareModeSpinner.adapter = adapter
screenShareModeSpinner.onItemSelectedListener = this
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt
index 8858041ae529..9ce8070131fa 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt
@@ -30,7 +30,7 @@ class MediaProjectionPermissionDialogDelegate(
private val onStartRecordingClicked: Consumer<MediaProjectionPermissionDialogDelegate>,
private val onCancelClicked: Runnable,
private val appName: String?,
- private val forceShowPartialScreenshare: Boolean,
+ forceShowPartialScreenshare: Boolean,
hostUid: Int,
mediaProjectionMetricsLogger: MediaProjectionMetricsLogger,
) :
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/IconLabelVisibilityLog.kt b/packages/SystemUI/src/com/android/systemui/mediarouter/MediaRouterLog.kt
index c92234c3e535..16bf0ffbf9e9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/IconLabelVisibilityLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediarouter/MediaRouterLog.kt
@@ -14,11 +14,12 @@
* limitations under the License.
*/
-package com.android.systemui.qs.panels.shared.model
+package com.android.systemui.mediarouter
import javax.inject.Qualifier
+/** Logs for events related to MediaRouter APIs. */
@Qualifier
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
-annotation class IconLabelVisibilityLog()
+annotation class MediaRouterLog
diff --git a/packages/SystemUI/src/com/android/systemui/mediarouter/MediaRouterModule.kt b/packages/SystemUI/src/com/android/systemui/mediarouter/MediaRouterModule.kt
new file mode 100644
index 000000000000..df5dae4dd33a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/mediarouter/MediaRouterModule.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.mediarouter
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogBufferFactory
+import com.android.systemui.mediarouter.data.repository.MediaRouterRepository
+import com.android.systemui.mediarouter.data.repository.MediaRouterRepositoryImpl
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+
+@Module
+interface MediaRouterModule {
+ @Binds fun mediaRouterRepository(impl: MediaRouterRepositoryImpl): MediaRouterRepository
+
+ companion object {
+ @Provides
+ @SysUISingleton
+ @MediaRouterLog
+ fun provideMediaRouterLogBuffer(factory: LogBufferFactory): LogBuffer {
+ return factory.create("MediaRouter", 50)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepository.kt b/packages/SystemUI/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepository.kt
new file mode 100644
index 000000000000..debb667bbb15
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepository.kt
@@ -0,0 +1,77 @@
+/*
+ * 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.mediarouter.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.mediarouter.MediaRouterLog
+import com.android.systemui.statusbar.policy.CastController
+import com.android.systemui.statusbar.policy.CastDevice
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.stateIn
+
+/** A repository for data coming from MediaRouter APIs. */
+interface MediaRouterRepository {
+ /** A list of the cast devices that MediaRouter is currently aware of. */
+ val castDevices: StateFlow<List<CastDevice>>
+
+ /** Stops the cast to the given device. */
+ fun stopCasting(device: CastDevice)
+}
+
+@SysUISingleton
+class MediaRouterRepositoryImpl
+@Inject
+constructor(
+ @Application private val scope: CoroutineScope,
+ private val castController: CastController,
+ @MediaRouterLog private val logger: LogBuffer,
+) : MediaRouterRepository {
+ override val castDevices: StateFlow<List<CastDevice>> =
+ conflatedCallbackFlow {
+ val callback = CastController.Callback { trySend(castController.castDevices) }
+ castController.addCallback(callback)
+ awaitClose { castController.removeCallback(callback) }
+ }
+ // The CastController.Callback is pretty noisy and sends the same values multiple times
+ // in a row, so use a distinctUntilChanged before logging.
+ .distinctUntilChanged()
+ .onEach { allDevices ->
+ val logString = allDevices.map { it.shortLogString }.toString()
+ logger.log(TAG, LogLevel.INFO, { str1 = logString }, { "All cast devices: $str1" })
+ }
+ .map { it.filter { device -> device.origin == CastDevice.CastOrigin.MediaRouter } }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), emptyList())
+
+ override fun stopCasting(device: CastDevice) {
+ castController.stopCasting(device)
+ }
+
+ companion object {
+ private const val TAG = "MediaRouterRepo"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
index 5084944685b6..42f66cca2522 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
+++ b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
@@ -18,12 +18,14 @@ package com.android.systemui.model
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.Flags.glanceableHubBackGesture
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING
+import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED
@@ -105,6 +107,10 @@ constructor(
{
it.scene == Scenes.Lockscreen && it.invisibleDueToOcclusion
},
+ SYSUI_STATE_COMMUNAL_HUB_SHOWING to
+ {
+ glanceableHubBackGesture() && it.scene == Scenes.Communal
+ }
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
index b39315575882..13a786a623dd 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
@@ -573,7 +573,7 @@ public final class NavBarHelper implements
}
}
- static @TransitionMode int transitionMode(boolean isTransient, int appearance) {
+ public static @TransitionMode int transitionMode(boolean isTransient, int appearance) {
final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_NAVIGATION_BARS;
if (isTransient) {
return MODE_SEMI_TRANSPARENT;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java
index 4f713d6ab7a4..abd8bb9c106e 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java
@@ -24,6 +24,7 @@ import android.os.Bundle;
import androidx.annotation.Nullable;
import com.android.systemui.dagger.qualifiers.DisplayId;
+import com.android.systemui.navigationbar.views.NavigationBar;
import dagger.BindsInstance;
import dagger.Subcomponent;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index c801662b2a66..49fa3ba2da61 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -20,6 +20,8 @@ import androidx.annotation.Nullable;
import com.android.internal.statusbar.RegisterStatusBarResult;
import com.android.systemui.shared.statusbar.phone.BarTransitions;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarView;
/** A controller to handle navigation bars. */
public interface NavigationBarController {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
index 06a78c59ef04..c392c2ff17f3 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
@@ -19,6 +19,8 @@ package com.android.systemui.navigationbar
import com.android.internal.statusbar.RegisterStatusBarResult
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.shared.statusbar.phone.BarTransitions
+import com.android.systemui.navigationbar.views.NavigationBar
+import com.android.systemui.navigationbar.views.NavigationBarView
import javax.inject.Inject
/** A no-op version of [NavigationBarController] for variants like Arc and TV. */
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
index f0207aa69bf9..1dbdec99a907 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
@@ -54,6 +54,8 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
index aab4feaff353..e2ba76141845 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
@@ -24,6 +24,8 @@ import android.view.WindowManager;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.navigationbar.views.NavigationBarFrame;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.res.R;
import dagger.Module;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index 18358a79cbca..d8c13b6e8f6d 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -33,6 +33,7 @@ import androidx.annotation.VisibleForTesting
import androidx.core.os.postDelayed
import androidx.core.view.isVisible
import androidx.dynamicanimation.animation.DynamicAnimation
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager
import com.android.internal.jank.Cuj
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.util.LatencyTracker
@@ -83,7 +84,7 @@ private const val DEBUG = false
class BackPanelController
internal constructor(
context: Context,
- private val windowManager: WindowManager,
+ private val windowManager: ViewCaptureAwareWindowManager,
private val viewConfiguration: ViewConfiguration,
private val mainHandler: Handler,
private val systemClock: SystemClock,
@@ -102,7 +103,7 @@ internal constructor(
class Factory
@Inject
constructor(
- private val windowManager: WindowManager,
+ private val windowManager: ViewCaptureAwareWindowManager,
private val viewConfiguration: ViewConfiguration,
@BackPanelUiThread private val uiThreadContext: UiThreadContext,
private val systemClock: SystemClock,
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 c9be9938ef74..947336d41590 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -91,6 +91,7 @@ import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.util.concurrency.BackPanelUiThread;
import com.android.systemui.util.concurrency.UiThreadContext;
@@ -297,6 +298,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
private Date mTmpLogDate = new Date();
private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
+ private final NotificationShadeWindowController mNotificationShadeWindowController;
private final NavigationEdgeBackPlugin.BackCallback mBackCallback =
new NavigationEdgeBackPlugin.BackCallback() {
@@ -423,7 +425,8 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
Optional<DesktopMode> desktopModeOptional,
FalsingManager falsingManager,
Provider<BackGestureTfClassifierProvider> backGestureTfClassifierProviderProvider,
- Provider<LightBarController> lightBarControllerProvider) {
+ Provider<LightBarController> lightBarControllerProvider,
+ NotificationShadeWindowController notificationShadeWindowController) {
mContext = context;
mDisplayId = context.getDisplayId();
mUiThreadContext = uiThreadContext;
@@ -479,6 +482,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
this::onNavigationSettingsChanged);
updateCurrentUserResources();
+ mNotificationShadeWindowController = notificationShadeWindowController;
}
public void setStateChangeCallback(Runnable callback) {
@@ -1297,6 +1301,9 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mBackAnimation.setPilferPointerCallback(() -> {
pilferPointers();
});
+ mBackAnimation.setTopUiRequestCallback(
+ (requestTopUi, tag) -> mUiThreadContext.getExecutor().execute(() ->
+ mNotificationShadeWindowController.setRequestTopUi(requestTopUi, tag)));
updateBackAnimationThresholds();
if (mLightBarControllerProvider.get() != null) {
mBackAnimation.setStatusBarCustomizer((appearance) -> {
@@ -1333,6 +1340,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
private final Provider<BackGestureTfClassifierProvider>
mBackGestureTfClassifierProviderProvider;
private final Provider<LightBarController> mLightBarControllerProvider;
+ private final NotificationShadeWindowController mNotificationShadeWindowController;
@Inject
public Factory(OverviewProxyService overviewProxyService,
@@ -1353,7 +1361,8 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
FalsingManager falsingManager,
Provider<BackGestureTfClassifierProvider>
backGestureTfClassifierProviderProvider,
- Provider<LightBarController> lightBarControllerProvider) {
+ Provider<LightBarController> lightBarControllerProvider,
+ NotificationShadeWindowController notificationShadeWindowController) {
mOverviewProxyService = overviewProxyService;
mSysUiState = sysUiState;
mPluginManager = pluginManager;
@@ -1372,6 +1381,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mFalsingManager = falsingManager;
mBackGestureTfClassifierProviderProvider = backGestureTfClassifierProviderProvider;
mLightBarControllerProvider = lightBarControllerProvider;
+ mNotificationShadeWindowController = notificationShadeWindowController;
}
/** Construct a {@link EdgeBackGestureHandler}. */
@@ -1396,7 +1406,8 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mDesktopModeOptional,
mFalsingManager,
mBackGestureTfClassifierProviderProvider,
- mLightBarControllerProvider));
+ mLightBarControllerProvider,
+ mNotificationShadeWindowController));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
index d1ce1f613044..1b985d20cf78 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
@@ -32,7 +32,7 @@ import android.view.animation.Interpolator;
import com.android.app.animation.Interpolators;
import com.android.settingslib.Utils;
-import com.android.systemui.navigationbar.buttons.ButtonInterface;
+import com.android.systemui.navigationbar.views.buttons.ButtonInterface;
import com.android.systemui.res.R;
public class NavigationHandle extends View implements ButtonInterface {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
index 89dce032c727..afdfa5932162 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
@@ -40,6 +40,8 @@ import static com.android.systemui.navigationbar.NavBarHelper.transitionMode;
import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
import static com.android.systemui.shared.recents.utilities.Utilities.isLargeScreen;
import static com.android.systemui.shared.rotation.RotationButtonController.DEBUG_ROTATION;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
@@ -48,8 +50,6 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_I
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
-import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE;
-import static com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG_WINDOW_STATE;
import static com.android.systemui.statusbar.phone.CentralSurfaces.dumpBarTransitions;
import static com.android.systemui.util.Utils.isGesturalModeOnDefaultDisplay;
@@ -97,6 +97,7 @@ import android.view.WindowInsetsController.Behavior;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.inputmethod.Flags;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.Nullable;
@@ -117,13 +118,17 @@ import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.NavBarHelper;
import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.DeadZone;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import com.android.systemui.navigationbar.gestural.QuickswitchOrientedNavHandle;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.buttons.NavBarButtonClickLogger;
+import com.android.systemui.navigationbar.views.buttons.NavbarOrientationTrackingLogger;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
@@ -1344,6 +1349,9 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
ButtonDispatcher imeSwitcherButton = mView.getImeSwitchButton();
imeSwitcherButton.setOnClickListener(this::onImeSwitcherClick);
+ if (Flags.imeSwitcherRevamp()) {
+ imeSwitcherButton.setOnLongClickListener(this::onImeSwitcherLongClick);
+ }
updateScreenPinningGestures();
}
@@ -1497,12 +1505,29 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
mCommandQueue.toggleRecentApps();
}
- private void onImeSwitcherClick(View v) {
+ @VisibleForTesting
+ void onImeSwitcherClick(View v) {
+ mNavBarButtonClickLogger.logImeSwitcherClick();
+ if (Flags.imeSwitcherRevamp()) {
+ mInputMethodManager.onImeSwitchButtonClickFromSystem(mDisplayId);
+ } else {
+ mInputMethodManager.showInputMethodPickerFromSystem(
+ true /* showAuxiliarySubtypes */, mDisplayId);
+ }
+ mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP);
+ }
+
+ @VisibleForTesting
+ boolean onImeSwitcherLongClick(View v) {
+ if (!Flags.imeSwitcherRevamp()) {
+ return false;
+ }
mNavBarButtonClickLogger.logImeSwitcherClick();
mInputMethodManager.showInputMethodPickerFromSystem(
true /* showAuxiliarySubtypes */, mDisplayId);
- mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP);
- };
+ mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_LONGPRESS);
+ return true;
+ }
private boolean onLongPressBackHome(View v) {
return onLongPressNavigationButtons(v, R.id.back, R.id.home);
@@ -1992,7 +2017,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
return mSamplingBounds;
}
- void setNavigationBarLumaSamplingEnabled(boolean enable) {
+ public void setNavigationBarLumaSamplingEnabled(boolean enable) {
if (enable) {
mRegionSamplingHelper.start(mSamplingBounds);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarFrame.java
index 6c531d8233f1..3388f93610bb 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarFrame.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.view.MotionEvent.ACTION_OUTSIDE;
@@ -26,7 +26,7 @@ import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;
-import com.android.systemui.navigationbar.buttons.DeadZone;
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
public class NavigationBarFrame extends FrameLayout {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java
index 2ae0709618d7..96b730c08397 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
@@ -36,10 +36,11 @@ import android.widget.Space;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
-import com.android.systemui.navigationbar.buttons.ReverseLinearLayout;
-import com.android.systemui.navigationbar.buttons.ReverseLinearLayout.ReverseRelativeLayout;
+import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout;
+import com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout.ReverseRelativeLayout;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.res.R;
import com.android.systemui.shared.system.QuickStepContract;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarTransitions.java
index 54425985cb8c..251745d2c0e6 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarTransitions.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
@@ -25,7 +25,7 @@ import android.util.SparseArray;
import android.view.View;
import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
import com.android.systemui.res.R;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.shared.statusbar.phone.BarTransitions;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
index 2c6e297b7879..1dbd500c15f1 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
@@ -14,12 +14,11 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.inputmethodservice.InputMethodService.canImeRenderGesturalNavButtons;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
-import static com.android.systemui.Flags.enableViewCaptureTracing;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SEARCH_DISABLED;
@@ -38,7 +37,6 @@ import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
-import android.media.permission.SafeCloseable;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.AttributeSet;
@@ -61,18 +59,18 @@ import android.widget.FrameLayout;
import androidx.annotation.Nullable;
import com.android.app.animation.Interpolators;
-import com.android.app.viewcapture.ViewCaptureFactory;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.Utils;
import com.android.systemui.Gefingerpoken;
import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.ContextualButton;
-import com.android.systemui.navigationbar.buttons.ContextualButtonGroup;
-import com.android.systemui.navigationbar.buttons.DeadZone;
-import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
-import com.android.systemui.navigationbar.buttons.NearestTouchFrame;
+import com.android.systemui.navigationbar.ScreenPinningNotify;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.ContextualButton;
+import com.android.systemui.navigationbar.views.buttons.ContextualButtonGroup;
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonDrawable;
+import com.android.systemui.navigationbar.views.buttons.NearestTouchFrame;
import com.android.systemui.recents.Recents;
import com.android.systemui.res.R;
import com.android.systemui.settings.DisplayTracker;
@@ -180,7 +178,6 @@ public class NavigationBarView extends FrameLayout {
private boolean mOverviewProxyEnabled;
private boolean mShowSwipeUpUi;
private UpdateActiveTouchRegionsCallback mUpdateActiveTouchRegionsCallback;
- private SafeCloseable mViewCaptureCloseable;
private class NavTransitionListener implements TransitionListener {
private boolean mBackTransitioning;
@@ -1081,10 +1078,6 @@ public class NavigationBarView extends FrameLayout {
}
updateNavButtonIcons();
- if (enableViewCaptureTracing()) {
- mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext())
- .startCapture(getRootView(), ".NavigationBarView");
- }
}
@Override
@@ -1097,9 +1090,6 @@ public class NavigationBarView extends FrameLayout {
mFloatingRotationButton.hide();
mRotationButtonController.unregisterListeners();
}
- if (mViewCaptureCloseable != null) {
- mViewCaptureCloseable.close();
- }
}
void dump(PrintWriter pw) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonDispatcher.java
index fc37b9f0979d..6799a4f33937 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonDispatcher.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import static com.android.app.animation.Interpolators.LINEAR;
@@ -25,8 +25,6 @@ import android.view.View;
import android.view.View.AccessibilityDelegate;
import android.view.ViewGroup;
-import com.android.systemui.navigationbar.NavBarButtonClickLogger;
-
import java.util.ArrayList;
/**
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonInterface.java
index 5f8fafd4ae4c..c1b4944d9295 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonInterface.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.annotation.Nullable;
import android.graphics.drawable.Drawable;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButton.java
index 517f8e7f0dac..5e6bfa820c4a 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButton.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.annotation.DrawableRes;
import android.annotation.IdRes;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButtonGroup.java
index 2ace303986fe..c68d25f93f5f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButtonGroup.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.annotation.IdRes;
import android.annotation.NonNull;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/DeadZone.java
index 8177fdec86e6..a6be314158ca 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/DeadZone.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.animation.ObjectAnimator;
import android.content.res.Resources;
@@ -27,7 +27,7 @@ import android.view.Surface;
import com.android.systemui.Dependency;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.res.R;
import javax.inject.Inject;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java
index 686faccc639a..072a4db8bfe8 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.animation.ArgbEvaluator;
import android.annotation.ColorInt;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java
index dbe87eafef7b..133d14ddb9f4 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.KeyEvent.KEYCODE_UNKNOWN;
@@ -59,7 +59,6 @@ import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.assist.AssistManager;
-import com.android.systemui.navigationbar.NavBarButtonClickLogger;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.res.R;
import com.android.systemui.shared.navigationbar.KeyButtonRipple;
@@ -113,6 +112,9 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
@UiEvent(doc = "The overview button was long-pressed in the navigation bar.")
NAVBAR_OVERVIEW_BUTTON_LONGPRESS(538),
+ @UiEvent(doc = "The ime switcher button was long-pressed in the navigation bar.")
+ NAVBAR_IME_SWITCHER_BUTTON_LONGPRESS(1799),
+
NONE(0); // an event we should not log
private final int mId;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarButtonClickLogger.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavBarButtonClickLogger.kt
index 408acf3ce1a1..ca5871807650 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarButtonClickLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavBarButtonClickLogger.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar
+package com.android.systemui.navigationbar.views.buttons
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavbarOrientationTrackingLogger.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt
index b1bd2863695a..a5ba17b98a40 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavbarOrientationTrackingLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar
+package com.android.systemui.navigationbar.views.buttons
import android.view.Surface
import com.android.systemui.log.LogBuffer
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java
index d780f7c11608..e1a1a9fef8c0 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.content.Context;
import android.content.res.Configuration;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ReverseLinearLayout.java
index f1e1366404a2..9d50bd661715 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ReverseLinearLayout.java
@@ -1,18 +1,20 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.annotation.Nullable;
import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
index de490a58a498..311cbfb7e632 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
@@ -96,12 +96,27 @@ constructor(
logDebug { "lockScreenState:isConfigSelected=$isConfigSelected" }
logDebug { "lockScreenState:isDefaultNotesAppSet=$isDefaultNotesAppSet" }
+ val isCustomLockScreenShortcutEnabled =
+ context.resources.getBoolean(R.bool.custom_lockscreen_shortcuts_enabled)
+ val isShortcutSelectedOrDefaultEnabled =
+ if (isCustomLockScreenShortcutEnabled) {
+ isConfigSelected
+ } else {
+ isStylusEverUsed
+ }
+ logDebug {
+ "lockScreenState:isCustomLockScreenShortcutEnabled=" +
+ isCustomLockScreenShortcutEnabled
+ }
+ logDebug {
+ "lockScreenState:isShortcutSelectedOrDefaultEnabled=" +
+ isShortcutSelectedOrDefaultEnabled
+ }
if (
isEnabled &&
isUserUnlocked &&
isDefaultNotesAppSet &&
- isConfigSelected &&
- isStylusEverUsed
+ isShortcutSelectedOrDefaultEnabled
) {
val contentDescription = ContentDescription.Resource(pickerNameResourceId)
val icon = Icon.Resource(pickerIconResourceId, contentDescription)
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleBackupHelper.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleBackupHelper.java
index d8c96dd182b4..eadbffe49495 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleBackupHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleBackupHelper.java
@@ -41,6 +41,8 @@ import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.Nullable;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.people.PeopleBackupFollowUpJob;
import com.android.systemui.people.SharedPreferencesHelper;
@@ -67,6 +69,7 @@ public class PeopleBackupHelper extends SharedPreferencesBackupHelper {
private final UserHandle mUserHandle;
private final PackageManager mPackageManager;
private final IPeopleManager mIPeopleManager;
+ @Nullable
private final AppWidgetManager mAppWidgetManager;
/**
@@ -404,6 +407,9 @@ public class PeopleBackupHelper extends SharedPreferencesBackupHelper {
private List<String> getExistingWidgetsForUser(int userId) {
List<String> existingWidgets = new ArrayList<>();
+ if (mAppWidgetManager == null) {
+ return existingWidgets;
+ }
int[] ids = mAppWidgetManager.getAppWidgetIds(
new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
for (int id : ids) {
@@ -491,7 +497,11 @@ public class PeopleBackupHelper extends SharedPreferencesBackupHelper {
/** Sends a broadcast to update the existing Conversation widgets. */
public static void updateWidgets(Context context) {
- int[] widgetIds = AppWidgetManager.getInstance(context)
+ AppWidgetManager manager = AppWidgetManager.getInstance(context);
+ if (manager == null) {
+ return;
+ }
+ int[] widgetIds = manager
.getAppWidgetIds(new ComponentName(context, PeopleSpaceWidgetProvider.class));
if (DEBUG) {
for (int id : widgetIds) {
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 0a880293ca76..b0de80c8d7bb 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -140,7 +140,7 @@ public class PeopleSpaceWidgetManager implements Dumpable {
private final Object mLock = new Object();
private final Context mContext;
private LauncherApps mLauncherApps;
- private AppWidgetManager mAppWidgetManager;
+ private Optional<AppWidgetManager> mAppWidgetManagerOptional;
private IPeopleManager mIPeopleManager;
private SharedPreferences mSharedPrefs;
private PeopleManager mPeopleManager;
@@ -183,8 +183,9 @@ public class PeopleSpaceWidgetManager implements Dumpable {
};
@Inject
- public PeopleSpaceWidgetManager(Context context, LauncherApps launcherApps,
- CommonNotifCollection notifCollection,
+ public PeopleSpaceWidgetManager(Context context,
+ Optional<AppWidgetManager> appWidgetManagerOptional,
+ LauncherApps launcherApps, CommonNotifCollection notifCollection,
PackageManager packageManager, Optional<Bubbles> bubblesOptional,
UserManager userManager, NotificationManager notificationManager,
BroadcastDispatcher broadcastDispatcher, @Background Executor bgExecutor,
@@ -192,7 +193,7 @@ public class PeopleSpaceWidgetManager implements Dumpable {
@NonNull KeyguardUpdateMonitor keyguardUpdateMonitor) {
if (DEBUG) Log.d(TAG, "constructor");
mContext = context;
- mAppWidgetManager = AppWidgetManager.getInstance(context);
+ mAppWidgetManagerOptional = appWidgetManagerOptional;
mIPeopleManager = IPeopleManager.Stub.asInterface(
ServiceManager.getService(Context.PEOPLE_SERVICE));
mLauncherApps = launcherApps;
@@ -266,14 +267,14 @@ public class PeopleSpaceWidgetManager implements Dumpable {
*/
@VisibleForTesting
PeopleSpaceWidgetManager(Context context,
- AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
+ Optional<AppWidgetManager> appWidgetManager, IPeopleManager iPeopleManager,
PeopleManager peopleManager, LauncherApps launcherApps,
CommonNotifCollection notifCollection, PackageManager packageManager,
Optional<Bubbles> bubblesOptional, UserManager userManager, BackupManager backupManager,
INotificationManager iNotificationManager, NotificationManager notificationManager,
@Background Executor executor, UserTracker userTracker) {
mContext = context;
- mAppWidgetManager = appWidgetManager;
+ mAppWidgetManagerOptional = appWidgetManager;
mIPeopleManager = iPeopleManager;
mPeopleManager = peopleManager;
mLauncherApps = launcherApps;
@@ -337,6 +338,10 @@ public class PeopleSpaceWidgetManager implements Dumpable {
/** Updates the current widget view with provided {@link PeopleSpaceTile}. */
private void updateAppWidgetViews(int appWidgetId, PeopleSpaceTile tile, Bundle options) {
+ if (mAppWidgetManagerOptional.isEmpty()) {
+ return;
+ }
+
PeopleTileKey key = getKeyFromStorageByWidgetId(appWidgetId);
if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + " for: " + key.toString());
@@ -349,7 +354,7 @@ public class PeopleSpaceWidgetManager implements Dumpable {
// Tell the AppWidgetManager to perform an update on the current app widget.
if (DEBUG) Log.d(TAG, "Calling update widget for widgetId: " + appWidgetId);
- mAppWidgetManager.updateAppWidget(appWidgetId, views);
+ mAppWidgetManagerOptional.get().updateAppWidget(appWidgetId, views);
}
/** Updates tile in app widget options and the current view. */
@@ -362,13 +367,17 @@ public class PeopleSpaceWidgetManager implements Dumpable {
/** Updates tile in app widget options and the current view. */
public void updateAppWidgetOptionsAndView(int appWidgetId, PeopleSpaceTile tile) {
+ if (mAppWidgetManagerOptional.isEmpty()) {
+ return;
+ }
+
if (tile == null) {
Log.w(TAG, "Storing null tile for widget " + appWidgetId);
}
synchronized (mTiles) {
mTiles.put(appWidgetId, tile);
}
- Bundle options = mAppWidgetManager.getAppWidgetOptions(appWidgetId);
+ Bundle options = mAppWidgetManagerOptional.get().getAppWidgetOptions(appWidgetId);
updateAppWidgetViews(appWidgetId, tile, options);
}
@@ -484,6 +493,10 @@ public class PeopleSpaceWidgetManager implements Dumpable {
private void updateWidgetsWithNotificationChangedInBackground(StatusBarNotification sbn,
PeopleSpaceUtils.NotificationAction action,
Collection<NotificationEntry> notifications) {
+ if (mAppWidgetManagerOptional.isEmpty()) {
+ return;
+ }
+
try {
PeopleTileKey key = new PeopleTileKey(
sbn.getShortcutId(), sbn.getUser().getIdentifier(), sbn.getPackageName());
@@ -491,7 +504,7 @@ public class PeopleSpaceWidgetManager implements Dumpable {
if (DEBUG) Log.d(TAG, "Sbn doesn't contain valid PeopleTileKey: " + key.toString());
return;
}
- int[] widgetIds = mAppWidgetManager.getAppWidgetIds(
+ int[] widgetIds = mAppWidgetManagerOptional.get().getAppWidgetIds(
new ComponentName(mContext, PeopleSpaceWidgetProvider.class)
);
if (widgetIds.length == 0) {
@@ -807,10 +820,14 @@ public class PeopleSpaceWidgetManager implements Dumpable {
UserHandle user,
NotificationChannel channel,
int modificationType) {
+ if (mAppWidgetManagerOptional.isEmpty()) {
+ return;
+ }
+
if (channel.isConversation()) {
mBgExecutor.execute(() -> {
if (mUserManager.isUserUnlocked(user)) {
- updateWidgets(mAppWidgetManager.getAppWidgetIds(
+ updateWidgets(mAppWidgetManagerOptional.get().getAppWidgetIds(
new ComponentName(mContext, PeopleSpaceWidgetProvider.class)
));
}
@@ -829,13 +846,18 @@ public class PeopleSpaceWidgetManager implements Dumpable {
// learning about the widget. If so, the widget adder should have populated options with
// PeopleTileKey arguments.
if (DEBUG) Log.d(TAG, "onAppWidgetOptionsChanged called for widget: " + appWidgetId);
+ if (mAppWidgetManagerOptional.isEmpty()) {
+ return;
+ }
+
PeopleTileKey optionsKey = AppWidgetOptionsHelper.getPeopleTileKeyFromBundle(newOptions);
if (PeopleTileKey.isValid(optionsKey)) {
if (DEBUG) {
Log.d(TAG, "PeopleTileKey was present in Options, shortcutId: "
+ optionsKey.getShortcutId());
}
- AppWidgetOptionsHelper.removePeopleTileKey(mAppWidgetManager, appWidgetId);
+ AppWidgetOptionsHelper.removePeopleTileKey(mAppWidgetManagerOptional.get(),
+ appWidgetId);
addNewWidget(appWidgetId, optionsKey);
}
// Update views for new widget dimensions.
@@ -1004,6 +1026,10 @@ public class PeopleSpaceWidgetManager implements Dumpable {
public boolean requestPinAppWidget(ShortcutInfo shortcutInfo, Bundle options) {
if (DEBUG) Log.d(TAG, "Requesting pin widget, shortcutId: " + shortcutInfo.getId());
+ if (mAppWidgetManagerOptional.isEmpty()) {
+ return false;
+ }
+
RemoteViews widgetPreview = getPreview(shortcutInfo.getId(),
shortcutInfo.getUserHandle(), shortcutInfo.getPackage(), options);
if (widgetPreview == null) {
@@ -1017,7 +1043,8 @@ public class PeopleSpaceWidgetManager implements Dumpable {
PeopleSpaceWidgetPinnedReceiver.getPendingIntent(mContext, shortcutInfo);
ComponentName componentName = new ComponentName(mContext, PeopleSpaceWidgetProvider.class);
- return mAppWidgetManager.requestPinAppWidget(componentName, extras, successCallback);
+ return mAppWidgetManagerOptional.get().requestPinAppWidget(componentName, extras,
+ successCallback);
}
/** Returns a list of map entries corresponding to user's priority conversations. */
@@ -1104,7 +1131,11 @@ public class PeopleSpaceWidgetManager implements Dumpable {
/** Updates any app widget to the current state, triggered by a broadcast update. */
@VisibleForTesting
void updateWidgetsFromBroadcastInBackground(String entryPoint) {
- int[] appWidgetIds = mAppWidgetManager.getAppWidgetIds(
+ if (mAppWidgetManagerOptional.isEmpty()) {
+ return;
+ }
+
+ int[] appWidgetIds = mAppWidgetManagerOptional.get().getAppWidgetIds(
new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
if (appWidgetIds == null) {
return;
@@ -1272,13 +1303,17 @@ public class PeopleSpaceWidgetManager implements Dumpable {
remapSharedFile(widgets);
remapFollowupFile(widgets);
- int[] widgetIds = mAppWidgetManager.getAppWidgetIds(
+ if (mAppWidgetManagerOptional.isEmpty()) {
+ return;
+ }
+
+ int[] widgetIds = mAppWidgetManagerOptional.get().getAppWidgetIds(
new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
Bundle b = new Bundle();
b.putBoolean(AppWidgetManager.OPTION_APPWIDGET_RESTORE_COMPLETED, true);
for (int id : widgetIds) {
if (DEBUG) Log.d(TAG, "Setting widget as restored, widget id:" + id);
- mAppWidgetManager.updateAppWidgetOptions(id, b);
+ mAppWidgetManagerOptional.get().updateAppWidgetOptions(id, b);
}
updateWidgets(widgetIds);
@@ -1437,14 +1472,15 @@ public class PeopleSpaceWidgetManager implements Dumpable {
@VisibleForTesting
void updateGeneratedPreviewForUser(UserHandle user) {
if (!generatedPreviews() || mUpdatedPreviews.get(user.getIdentifier())
- || !mUserManager.isUserUnlocked(user)) {
+ || !mUserManager.isUserUnlocked(user) || mAppWidgetManagerOptional.isEmpty()) {
return;
}
// The widget provider may be disabled on SystemUI implementers, e.g. TvSystemUI.
ComponentName provider = new ComponentName(mContext, PeopleSpaceWidgetProvider.class);
- List<AppWidgetProviderInfo> infos = mAppWidgetManager.getInstalledProvidersForPackage(
- mContext.getPackageName(), user);
+ List<AppWidgetProviderInfo> infos =
+ mAppWidgetManagerOptional.get().getInstalledProvidersForPackage(
+ mContext.getPackageName(), user);
if (infos.stream().noneMatch(info -> info.provider.equals(provider))) {
return;
}
@@ -1452,7 +1488,7 @@ public class PeopleSpaceWidgetManager implements Dumpable {
if (DEBUG) {
Log.d(TAG, "Updating People Space widget preview for user " + user.getIdentifier());
}
- boolean success = mAppWidgetManager.setWidgetPreview(
+ boolean success = mAppWidgetManagerOptional.get().setWidgetPreview(
provider, WIDGET_CATEGORY_HOME_SCREEN | WIDGET_CATEGORY_KEYGUARD,
new RemoteViews(mContext.getPackageName(),
R.layout.people_space_placeholder_layout));
diff --git a/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt b/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt
index 7505566898c0..776a8f47f056 100644
--- a/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt
+++ b/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt
@@ -54,7 +54,10 @@ enum class WakeSleepReason(
OTHER(isTouch = false, PowerManager.WAKE_REASON_UNKNOWN),
/** Device goes to sleep due to folding of a foldable device. */
- FOLD(isTouch = false, PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD);
+ FOLD(isTouch = false, PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD),
+
+ /** Device goes to sleep because it timed out. */
+ TIMEOUT(isTouch = false, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
companion object {
fun fromPowerManagerWakeReason(reason: Int): WakeSleepReason {
@@ -75,6 +78,7 @@ enum class WakeSleepReason(
fun fromPowerManagerSleepReason(reason: Int): WakeSleepReason {
return when (reason) {
PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON -> POWER_BUTTON
+ PowerManager.GO_TO_SLEEP_REASON_TIMEOUT -> TIMEOUT
PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD -> FOLD
else -> OTHER
}
diff --git a/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java
index b4cc196b89ed..294d0c75167a 100644
--- a/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java
@@ -16,6 +16,7 @@
package com.android.systemui.process;
+import android.app.ActivityManager;
import android.os.Process;
import android.os.UserHandle;
@@ -37,6 +38,13 @@ public class ProcessWrapper {
}
/**
+ * Returns {@code true} if the foreground user is running the current process.
+ */
+ public boolean isForegroundUser() {
+ return ActivityManager.getCurrentUser() == myUserHandle().getIdentifier();
+ }
+
+ /**
* Returns {@link UserHandle} as returned statically by {@link Process#myUserHandle()}.
*
* This should not be used to get the "current" user. This information only applies to the
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java b/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java
index 10c8e530553a..cf1dca3cbb23 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java
@@ -16,6 +16,8 @@
package com.android.systemui.qs;
+import android.content.res.Resources;
+
import com.android.systemui.statusbar.policy.CallbackController;
public interface ReduceBrightColorsController extends
@@ -27,6 +29,14 @@ public interface ReduceBrightColorsController extends
/** Sets the activation state of Reduce Bright Colors */
void setReduceBrightColorsActivated(boolean activated);
+ /** Sets whether Reduce Bright Colors is enabled */
+ void setReduceBrightColorsFeatureAvailable(boolean enabled);
+
+ /** Gets whether Reduce Bright Colors is enabled */
+ boolean isReduceBrightColorsFeatureAvailable();
+
+ /** Gets whether Reduce Bright Colors is being transitioned to Even Dimmer */
+ boolean isInUpgradeMode(Resources resources);
/**
* Listener invoked whenever the Reduce Bright Colors settings are changed.
*/
@@ -38,5 +48,12 @@ public interface ReduceBrightColorsController extends
*/
default void onActivated(boolean activated) {
}
+ /**
+ * Listener invoked when the feature enabled state changes.
+ *
+ * @param enabled {@code true} if Reduce Bright Colors feature is enabled.
+ */
+ default void onFeatureEnabledChanged(boolean enabled) {
+ }
}
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsControllerImpl.java
index 846d63f10875..4d6cf78610d9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsControllerImpl.java
@@ -19,6 +19,7 @@
package com.android.systemui.qs;
import android.content.Context;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.display.ColorDisplayManager;
import android.net.Uri;
@@ -47,6 +48,7 @@ public class ReduceBrightColorsControllerImpl implements
private final ContentObserver mContentObserver;
private final SecureSettings mSecureSettings;
private final ArrayList<ReduceBrightColorsController.Listener> mListeners = new ArrayList<>();
+ private boolean mAvailable = true;
@Inject
public ReduceBrightColorsControllerImpl(UserTracker userTracker,
@@ -75,12 +77,20 @@ public class ReduceBrightColorsControllerImpl implements
mCurrentUserTrackerCallback = new UserTracker.Callback() {
@Override
public void onUserChanged(int newUser, Context userContext) {
+ mAvailable = true;
synchronized (mListeners) {
if (mListeners.size() > 0) {
- mSecureSettings.unregisterContentObserverSync(mContentObserver);
- mSecureSettings.registerContentObserverForUserSync(
- Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
- false, mContentObserver, newUser);
+ if (com.android.systemui.Flags.registerContentObserversAsync()) {
+ mSecureSettings.unregisterContentObserverAsync(mContentObserver);
+ mSecureSettings.registerContentObserverForUserAsync(
+ Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
+ false, mContentObserver, newUser);
+ } else {
+ mSecureSettings.unregisterContentObserverSync(mContentObserver);
+ mSecureSettings.registerContentObserverForUserSync(
+ Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
+ false, mContentObserver, newUser);
+ }
}
}
}
@@ -94,9 +104,15 @@ public class ReduceBrightColorsControllerImpl implements
if (!mListeners.contains(listener)) {
mListeners.add(listener);
if (mListeners.size() == 1) {
- mSecureSettings.registerContentObserverForUserSync(
- Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
- false, mContentObserver, mUserTracker.getUserId());
+ if (com.android.systemui.Flags.registerContentObserversAsync()) {
+ mSecureSettings.registerContentObserverForUserAsync(
+ Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
+ false, mContentObserver, mUserTracker.getUserId());
+ } else {
+ mSecureSettings.registerContentObserverForUserSync(
+ Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
+ false, mContentObserver, mUserTracker.getUserId());
+ }
}
}
}
@@ -106,7 +122,11 @@ public class ReduceBrightColorsControllerImpl implements
public void removeCallback(@androidx.annotation.NonNull Listener listener) {
synchronized (mListeners) {
if (mListeners.remove(listener) && mListeners.size() == 0) {
- mSecureSettings.unregisterContentObserverSync(mContentObserver);
+ if (com.android.systemui.Flags.registerContentObserversAsync()) {
+ mSecureSettings.unregisterContentObserverAsync(mContentObserver);
+ } else {
+ mSecureSettings.unregisterContentObserverSync(mContentObserver);
+ }
}
}
}
@@ -121,10 +141,36 @@ public class ReduceBrightColorsControllerImpl implements
mManager.setReduceBrightColorsActivated(activated);
}
+ @Override
+ public void setReduceBrightColorsFeatureAvailable(boolean enabled) {
+ mAvailable = enabled;
+ dispatchOnEnabledChanged(enabled);
+ mAvailable = true;
+ }
+
+ @Override
+ public boolean isReduceBrightColorsFeatureAvailable() {
+ return mAvailable;
+ }
+
+ @Override
+ public boolean isInUpgradeMode(Resources resources) {
+ return com.android.server.display.feature.flags.Flags.evenDimmer()
+ && resources.getBoolean(
+ com.android.internal.R.bool.config_evenDimmerEnabled);
+ }
+
private void dispatchOnActivated(boolean activated) {
ArrayList<Listener> copy = new ArrayList<>(mListeners);
for (Listener l : copy) {
l.onActivated(activated);
}
}
+
+ private void dispatchOnEnabledChanged(boolean enabled) {
+ ArrayList<Listener> copy = new ArrayList<>(mListeners);
+ for (Listener l : copy) {
+ l.onFeatureEnabledChanged(enabled);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SettingObserver.java b/packages/SystemUI/src/com/android/systemui/qs/SettingObserver.java
index 6092348b964e..2287f4d68933 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SettingObserver.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SettingObserver.java
@@ -19,6 +19,7 @@ package com.android.systemui.qs;
import android.database.ContentObserver;
import android.os.Handler;
+import com.android.systemui.Flags;
import com.android.systemui.statusbar.policy.Listenable;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.settings.SettingsProxy;
@@ -74,10 +75,20 @@ public abstract class SettingObserver extends ContentObserver implements Listena
mListening = listening;
if (listening) {
mObservedValue = getValueFromProvider();
- mSettingsProxy.registerContentObserverSync(
- mSettingsProxy.getUriFor(mSettingName), false, this);
+ if (Flags.qsRegisterSettingObserverOnBgThread()) {
+ mSettingsProxy.registerContentObserverAsync(
+ mSettingsProxy.getUriFor(mSettingName), false, this,
+ () -> mObservedValue = getValueFromProvider());
+ } else {
+ mSettingsProxy.registerContentObserverSync(
+ mSettingsProxy.getUriFor(mSettingName), false, this);
+ }
} else {
- mSettingsProxy.unregisterContentObserverSync(this);
+ if (Flags.qsRegisterSettingObserverOnBgThread()) {
+ mSettingsProxy.unregisterContentObserverAsync(this);
+ } else {
+ mSettingsProxy.unregisterContentObserverSync(this);
+ }
mObservedValue = mDefaultValue;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index a45d6f63cd81..89f85ab14dd6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -32,6 +32,7 @@ import android.widget.Button;
import androidx.annotation.Nullable;
+import com.android.server.display.feature.flags.Flags;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.qs.QSTile;
@@ -116,6 +117,10 @@ public class TileQueryHelper {
final ArrayList<QSTile> tilesToAdd = new ArrayList<>();
possibleTiles.remove("cell");
possibleTiles.remove("wifi");
+ if (Flags.evenDimmer() && mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_evenDimmerEnabled)) {
+ possibleTiles.remove("reduce_brightness");
+ }
for (String spec : possibleTiles) {
// Only add current and stock tiles that can be created from QSFactoryImpl.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
index c2143619c1ad..78f4b4b32237 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
@@ -19,18 +19,17 @@ package com.android.systemui.qs.panels.dagger
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBufferFactory
+import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepository
+import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepositoryImpl
import com.android.systemui.qs.panels.data.repository.GridLayoutTypeRepository
import com.android.systemui.qs.panels.data.repository.GridLayoutTypeRepositoryImpl
-import com.android.systemui.qs.panels.data.repository.IconTilesRepository
-import com.android.systemui.qs.panels.data.repository.IconTilesRepositoryImpl
import com.android.systemui.qs.panels.domain.interactor.GridTypeConsistencyInteractor
import com.android.systemui.qs.panels.domain.interactor.InfiniteGridConsistencyInteractor
import com.android.systemui.qs.panels.domain.interactor.NoopGridConsistencyInteractor
-import com.android.systemui.qs.panels.shared.model.GridConsistencyLog
import com.android.systemui.qs.panels.shared.model.GridLayoutType
-import com.android.systemui.qs.panels.shared.model.IconLabelVisibilityLog
import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType
import com.android.systemui.qs.panels.shared.model.PaginatedGridLayoutType
+import com.android.systemui.qs.panels.shared.model.PanelsLog
import com.android.systemui.qs.panels.shared.model.PartitionedGridLayoutType
import com.android.systemui.qs.panels.shared.model.StretchedGridLayoutType
import com.android.systemui.qs.panels.ui.compose.GridLayout
@@ -53,7 +52,10 @@ import javax.inject.Named
@Module
interface PanelsModule {
- @Binds fun bindIconTilesRepository(impl: IconTilesRepositoryImpl): IconTilesRepository
+ @Binds
+ fun bindDefaultLargeTilesSpecsRepository(
+ impl: DefaultLargeTilesRepositoryImpl
+ ): DefaultLargeTilesRepository
@Binds
fun bindGridLayoutTypeRepository(impl: GridLayoutTypeRepositoryImpl): GridLayoutTypeRepository
@@ -74,7 +76,7 @@ interface PanelsModule {
@Binds
@PaginatedBaseLayoutType
- fun bindPaginatedBaseGridLayout(impl: PartitionedGridLayout): PaginatableGridLayout
+ fun bindPaginatedBaseGridLayout(impl: InfiniteGridLayout): PaginatableGridLayout
@Binds
@PaginatedBaseLayoutType
@@ -87,16 +89,9 @@ interface PanelsModule {
companion object {
@Provides
@SysUISingleton
- @GridConsistencyLog
- fun providesGridConsistencyLog(factory: LogBufferFactory): LogBuffer {
- return factory.create("GridConsistencyLog", 50)
- }
-
- @Provides
- @SysUISingleton
- @IconLabelVisibilityLog
- fun providesIconTileLabelVisibilityLog(factory: LogBufferFactory): LogBuffer {
- return factory.create("IconLabelVisibilityLog", 50)
+ @PanelsLog
+ fun providesPanelsLog(factory: LogBufferFactory): LogBuffer {
+ return factory.create("PanelsLog", 50)
}
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconTilesRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/DefaultLargeTilesRepository.kt
index 095bdf2ff5bd..9a1671df60e9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconTilesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/DefaultLargeTilesRepository.kt
@@ -20,25 +20,18 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.pipeline.shared.TileSpec
import javax.inject.Inject
-/** Repository for checking if a tile should be displayed as an icon. */
-interface IconTilesRepository {
- fun isIconTile(spec: TileSpec): Boolean
+/** Repository for the default set of [TileSpec] that should be displayed as large tiles. */
+interface DefaultLargeTilesRepository {
+ val defaultLargeTiles: Set<TileSpec>
}
@SysUISingleton
-class IconTilesRepositoryImpl @Inject constructor() : IconTilesRepository {
-
- override fun isIconTile(spec: TileSpec): Boolean {
- return !LARGE_TILES.contains(spec)
- }
-
- companion object {
- private val LARGE_TILES =
- setOf(
- TileSpec.create("internet"),
- TileSpec.create("bt"),
- TileSpec.create("dnd"),
- TileSpec.create("cast"),
- )
- }
+class DefaultLargeTilesRepositoryImpl @Inject constructor() : DefaultLargeTilesRepository {
+ override val defaultLargeTiles =
+ setOf(
+ TileSpec.create("internet"),
+ TileSpec.create("bt"),
+ TileSpec.create("dnd"),
+ TileSpec.create("cast"),
+ )
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepository.kt
index f3e5b8f0c214..971598dea0bd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepository.kt
@@ -20,6 +20,7 @@ import android.content.Context
import android.content.SharedPreferences
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.settings.UserFileManager
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.kotlin.SharedPreferencesExt.observe
@@ -40,6 +41,7 @@ class QSPreferencesRepository
constructor(
private val userFileManager: UserFileManager,
private val userRepository: UserRepository,
+ private val defaultLargeTilesRepository: DefaultLargeTilesRepository,
@Background private val backgroundDispatcher: CoroutineDispatcher,
) {
/** Whether to show the labels on icon tiles for the current user. */
@@ -51,6 +53,23 @@ constructor(
}
.flowOn(backgroundDispatcher)
+ /** Set of [TileSpec] to display as large tiles for the current user. */
+ val largeTilesSpecs: Flow<Set<TileSpec>> =
+ userRepository.selectedUserInfo
+ .flatMapLatest { userInfo ->
+ val prefs = getSharedPrefs(userInfo.id)
+ prefs.observe().emitOnStart().map {
+ prefs
+ .getStringSet(
+ LARGE_TILES_SPECS_KEY,
+ defaultLargeTilesRepository.defaultLargeTiles.map { it.spec }.toSet()
+ )
+ ?.map { TileSpec.create(it) }
+ ?.toSet() ?: defaultLargeTilesRepository.defaultLargeTiles
+ }
+ }
+ .flowOn(backgroundDispatcher)
+
/** Sets for the current user whether to show the labels on icon tiles. */
fun setShowLabels(showLabels: Boolean) {
with(getSharedPrefs(userRepository.getSelectedUserInfo().id)) {
@@ -58,6 +77,13 @@ constructor(
}
}
+ /** Sets for the current user the set of [TileSpec] to display as large tiles. */
+ fun setLargeTilesSpecs(specs: Set<TileSpec>) {
+ with(getSharedPrefs(userRepository.getSelectedUserInfo().id)) {
+ edit().putStringSet(LARGE_TILES_SPECS_KEY, specs.map { it.spec }.toSet()).apply()
+ }
+ }
+
private fun getSharedPrefs(userId: Int): SharedPreferences {
return userFileManager.getSharedPreferences(
FILE_NAME,
@@ -68,6 +94,7 @@ constructor(
companion object {
private const val ICON_LABELS_KEY = "show_icon_labels"
+ private const val LARGE_TILES_SPECS_KEY = "large_tiles_specs"
const val FILE_NAME = "quick_settings_prefs"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepository.kt
new file mode 100644
index 000000000000..f7c71ceb9e6c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepository.kt
@@ -0,0 +1,39 @@
+/*
+ * 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.qs.panels.data.repository
+
+import android.content.res.Resources
+import com.android.systemui.common.ui.data.repository.ConfigurationRepository
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.res.R
+import com.android.systemui.util.kotlin.emitOnStart
+import javax.inject.Inject
+import kotlinx.coroutines.flow.map
+
+@SysUISingleton
+class QuickQuickSettingsRowRepository
+@Inject
+constructor(
+ @Main private val resources: Resources,
+ configurationRepository: ConfigurationRepository,
+) {
+ val rows =
+ configurationRepository.onConfigurationChange.emitOnStart().map {
+ resources.getInteger(R.integer.quick_qs_panel_max_rows)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/StockTilesRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/StockTilesRepository.kt
index ec9d151a26d3..86a29f91e51c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/StockTilesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/StockTilesRepository.kt
@@ -17,6 +17,7 @@
package com.android.systemui.qs.panels.data.repository
import android.content.res.Resources
+import com.android.server.display.feature.flags.Flags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.qs.pipeline.shared.TileSpec
@@ -32,10 +33,15 @@ constructor(
/**
* List of stock platform tiles. All of the specs will be of type [TileSpec.PlatformTileSpec].
*/
+ val shouldRemoveRbcTile: Boolean =
+ Flags.evenDimmer() &&
+ resources.getBoolean(com.android.internal.R.bool.config_evenDimmerEnabled)
+
val stockTiles =
resources
.getString(R.string.quick_settings_tiles_stock)
.split(",")
+ .filterNot { shouldRemoveRbcTile && it.equals("reduce_brightness") }
.map(TileSpec::create)
.filterNot { it is TileSpec.Invalid }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractor.kt
index 7732092d6bcf..a2e7ea6fe797 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractor.kt
@@ -20,8 +20,8 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
-import com.android.systemui.qs.panels.shared.model.GridConsistencyLog
import com.android.systemui.qs.panels.shared.model.GridLayoutType
+import com.android.systemui.qs.panels.shared.model.PanelsLog
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
import javax.inject.Inject
@@ -39,7 +39,7 @@ constructor(
private val consistencyInteractors:
Map<GridLayoutType, @JvmSuppressWildcards GridTypeConsistencyInteractor>,
private val defaultConsistencyInteractor: GridTypeConsistencyInteractor,
- @GridConsistencyLog private val logBuffer: LogBuffer,
+ @PanelsLog private val logBuffer: LogBuffer,
@Application private val applicationScope: CoroutineScope,
) {
fun start() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractor.kt
index 6a899b07b2a0..fe4012787394 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractor.kt
@@ -20,7 +20,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
-import com.android.systemui.qs.panels.shared.model.IconLabelVisibilityLog
+import com.android.systemui.qs.panels.shared.model.PanelsLog
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -33,7 +33,7 @@ class IconLabelVisibilityInteractor
@Inject
constructor(
private val preferencesInteractor: QSPreferencesInteractor,
- @IconLabelVisibilityLog private val logBuffer: LogBuffer,
+ @PanelsLog private val logBuffer: LogBuffer,
@Application scope: CoroutineScope,
) {
val showLabels: StateFlow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractor.kt
index 524ea8b70100..b18358cedde7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractor.kt
@@ -17,12 +17,54 @@
package com.android.systemui.qs.panels.domain.interactor
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.panels.data.repository.IconTilesRepository
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepository
+import com.android.systemui.qs.panels.shared.model.PanelsLog
import com.android.systemui.qs.pipeline.shared.TileSpec
import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.stateIn
-/** Interactor for retrieving the list of [TileSpec] to be displayed as icons. */
+/** Interactor for retrieving the list of [TileSpec] to be displayed as icons and resizing icons. */
@SysUISingleton
-class IconTilesInteractor @Inject constructor(private val repo: IconTilesRepository) {
- fun isIconTile(spec: TileSpec): Boolean = repo.isIconTile(spec)
+class IconTilesInteractor
+@Inject
+constructor(
+ repo: DefaultLargeTilesRepository,
+ private val preferencesInteractor: QSPreferencesInteractor,
+ @PanelsLog private val logBuffer: LogBuffer,
+ @Application private val applicationScope: CoroutineScope
+) {
+
+ private val largeTilesSpecs =
+ preferencesInteractor.largeTilesSpecs
+ .onEach { logChange(it) }
+ .stateIn(applicationScope, SharingStarted.Eagerly, repo.defaultLargeTiles)
+
+ fun isIconTile(spec: TileSpec): Boolean = !largeTilesSpecs.value.contains(spec)
+
+ fun resize(spec: TileSpec, toIcon: Boolean) {
+ if (toIcon) {
+ preferencesInteractor.setLargeTilesSpecs(largeTilesSpecs.value - spec)
+ } else {
+ preferencesInteractor.setLargeTilesSpecs(largeTilesSpecs.value + spec)
+ }
+ }
+
+ private fun logChange(specs: Set<TileSpec>) {
+ logBuffer.log(
+ LOG_BUFFER_LARGE_TILES_SPECS_CHANGE_TAG,
+ LogLevel.DEBUG,
+ { str1 = specs.toString() },
+ { "Large tiles change: $str1" }
+ )
+ }
+
+ private companion object {
+ const val LOG_BUFFER_LARGE_TILES_SPECS_CHANGE_TAG = "LargeTilesSpecsChange"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSPreferencesInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSPreferencesInteractor.kt
index 811be80d23fa..854e23f16a13 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSPreferencesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSPreferencesInteractor.kt
@@ -18,14 +18,20 @@ package com.android.systemui.qs.panels.domain.interactor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.panels.data.repository.QSPreferencesRepository
+import com.android.systemui.qs.pipeline.shared.TileSpec
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@SysUISingleton
class QSPreferencesInteractor @Inject constructor(private val repo: QSPreferencesRepository) {
val showLabels: Flow<Boolean> = repo.showLabels
+ val largeTilesSpecs: Flow<Set<TileSpec>> = repo.largeTilesSpecs
fun setShowLabels(showLabels: Boolean) {
repo.setShowLabels(showLabels)
}
+
+ fun setLargeTilesSpecs(specs: Set<TileSpec>) {
+ repo.setLargeTilesSpecs(specs)
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractor.kt
new file mode 100644
index 000000000000..5f001df7a49e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractor.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.qs.panels.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.panels.data.repository.QuickQuickSettingsRowRepository
+import javax.inject.Inject
+
+@SysUISingleton
+class QuickQuickSettingsRowInteractor
+@Inject
+constructor(
+ quickQuickSettingsRowRepository: QuickQuickSettingsRowRepository,
+) {
+ val rows = quickQuickSettingsRowRepository.rows
+
+ val defaultRows = 2
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/GridConsistencyLog.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/PanelsLog.kt
index 884cde35a1aa..50cb3869f79e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/GridConsistencyLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/PanelsLog.kt
@@ -18,7 +18,4 @@ package com.android.systemui.qs.panels.shared.model
import javax.inject.Qualifier
-@Qualifier
-@MustBeDocumented
-@Retention(AnnotationRetention.RUNTIME)
-annotation class GridConsistencyLog()
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class PanelsLog()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
index 007ec3a911e1..782fb2ad25a0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
@@ -48,6 +48,9 @@ class DragAndDropState(
val sourceSpec: MutableState<TileSpec?>,
private val listState: EditTileListState
) {
+ val dragInProgress: Boolean
+ get() = sourceSpec.value != null
+
/** Returns index of the dragged tile if it's present in the list. Returns -1 if not. */
fun currentPosition(): Int {
return sourceSpec.value?.let { listState.indexOf(it) } ?: -1
@@ -65,6 +68,12 @@ class DragAndDropState(
sourceSpec.value?.let { listState.move(it, targetSpec) }
}
+ fun movedOutOfBounds() {
+ // Removing the tiles from the current tile grid if it moves out of bounds. This clears
+ // the spacer and makes it apparent that dropping the tile at that point would remove it.
+ sourceSpec.value?.let { listState.removeFromCurrent(it) }
+ }
+
fun onDrop() {
sourceSpec.value = null
}
@@ -112,6 +121,42 @@ fun Modifier.dragAndDropTile(
}
/**
+ * Registers a composable as a [DragAndDropTarget] to receive drop events. Use this outside the tile
+ * grid to catch out of bounds drops.
+ *
+ * @param dragAndDropState The [DragAndDropState] using the tiles list
+ * @param onDrop Action to be executed when a [TileSpec] is dropped on the composable
+ */
+@Composable
+fun Modifier.dragAndDropRemoveZone(
+ dragAndDropState: DragAndDropState,
+ onDrop: (TileSpec) -> Unit,
+): Modifier {
+ val target =
+ remember(dragAndDropState) {
+ object : DragAndDropTarget {
+ override fun onDrop(event: DragAndDropEvent): Boolean {
+ return dragAndDropState.sourceSpec.value?.let {
+ onDrop(it)
+ dragAndDropState.onDrop()
+ true
+ } ?: false
+ }
+
+ override fun onEntered(event: DragAndDropEvent) {
+ dragAndDropState.movedOutOfBounds()
+ }
+ }
+ }
+ return dragAndDropTarget(
+ shouldStartDragAndDrop = { event ->
+ event.mimeTypes().contains(QsDragAndDrop.TILESPEC_MIME_TYPE)
+ },
+ target = target,
+ )
+}
+
+/**
* Registers a tile list as a [DragAndDropTarget] to receive drop events. Use this on list
* containers to catch drops outside of tiles.
*
@@ -128,6 +173,10 @@ fun Modifier.dragAndDropTileList(
val target =
remember(dragAndDropState) {
object : DragAndDropTarget {
+ override fun onEnded(event: DragAndDropEvent) {
+ dragAndDropState.onDrop()
+ }
+
override fun onDrop(event: DragAndDropEvent): Boolean {
return dragAndDropState.sourceSpec.value?.let {
onDrop(it, dragAndDropState.currentPosition())
@@ -149,11 +198,13 @@ fun Modifier.dragAndDropTileList(
fun Modifier.dragAndDropTileSource(
tileSpec: TileSpec,
onTap: (TileSpec) -> Unit,
+ onDoubleTap: (TileSpec) -> Unit,
dragAndDropState: DragAndDropState
): Modifier {
return dragAndDropSource {
detectTapGestures(
onTap = { onTap(tileSpec) },
+ onDoubleTap = { onDoubleTap(tileSpec) },
onLongPress = {
dragAndDropState.onStarted(tileSpec)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
index 482c498d37d7..34876c4cf7f3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
@@ -46,6 +46,18 @@ class EditTileListState(tiles: List<EditTileViewModel>) {
tiles.apply { add(toIndex, removeAt(fromIndex).copy(isCurrent = isMovingToCurrent)) }
}
+ /**
+ * Sets the [TileSpec] as a non-current tile. Use this when a tile is dragged out of the current
+ * tile grid.
+ */
+ fun removeFromCurrent(tileSpec: TileSpec) {
+ val fromIndex = indexOf(tileSpec)
+ if (fromIndex >= 0 && fromIndex < tiles.size) {
+ // Mark the moving tile as non-current
+ tiles[fromIndex] = tiles[fromIndex].copy(isCurrent = false)
+ }
+ }
+
fun indexOf(tileSpec: TileSpec): Int {
return tiles.indexOfFirst { it.tileSpec == tileSpec }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt
index ea97f0de2bb8..add830e9760d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt
@@ -22,6 +22,7 @@ import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.dimensionResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -76,14 +77,18 @@ constructor(
onRemoveTile: (TileSpec) -> Unit,
) {
val columns by gridSizeViewModel.columns.collectAsStateWithLifecycle()
+ val isIcon: (TileSpec) -> Boolean by rememberUpdatedState { tileSpec ->
+ iconTilesViewModel.isIconTile(tileSpec)
+ }
DefaultEditTileGrid(
tiles = tiles,
- isIconOnly = iconTilesViewModel::isIconTile,
- columns = GridCells.Fixed(columns),
+ isIconOnly = isIcon,
+ columns = columns,
modifier = modifier,
onAddTile = onAddTile,
onRemoveTile = onRemoveTile,
+ onResize = iconTilesViewModel::resize,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt
index 092ad44d289b..6c84eddb5e38 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt
@@ -122,6 +122,9 @@ class PartitionedGridLayout @Inject constructor(private val viewModel: Partition
val addTileToEnd: (TileSpec) -> Unit by rememberUpdatedState {
onAddTile(it, CurrentTilesInteractor.POSITION_AT_END)
}
+ val onDoubleTap: (TileSpec) -> Unit by rememberUpdatedState { tileSpec ->
+ viewModel.resize(tileSpec, !viewModel.isIconTile(tileSpec))
+ }
val largeTileHeight = tileHeight()
val iconTileHeight = tileHeight(showLabels)
val tilePadding = dimensionResource(R.dimen.qs_tile_margin_vertical)
@@ -161,6 +164,7 @@ class PartitionedGridLayout @Inject constructor(private val viewModel: Partition
tilePadding = tilePadding,
onAdd = onAddTile,
onRemove = onRemoveTile,
+ onDoubleTap = onDoubleTap,
isIconOnly = viewModel::isIconTile,
columns = columns,
showLabels = showLabels,
@@ -173,6 +177,7 @@ class PartitionedGridLayout @Inject constructor(private val viewModel: Partition
tilePadding = tilePadding,
addTileToEnd = addTileToEnd,
onRemove = onRemoveTile,
+ onDoubleTap = onDoubleTap,
isIconOnly = viewModel::isIconTile,
showLabels = showLabels,
columns = columns,
@@ -203,6 +208,7 @@ class PartitionedGridLayout @Inject constructor(private val viewModel: Partition
tilePadding: Dp,
onAdd: (TileSpec, Int) -> Unit,
onRemove: (TileSpec) -> Unit,
+ onDoubleTap: (TileSpec) -> Unit,
isIconOnly: (TileSpec) -> Boolean,
showLabels: Boolean,
columns: Int,
@@ -224,6 +230,7 @@ class PartitionedGridLayout @Inject constructor(private val viewModel: Partition
tiles = largeTiles,
clickAction = ClickAction.REMOVE,
onClick = onRemove,
+ onDoubleTap = onDoubleTap,
isIconOnly = { false },
dragAndDropState = dragAndDropState,
acceptDrops = { !isIconOnly(it) },
@@ -244,6 +251,7 @@ class PartitionedGridLayout @Inject constructor(private val viewModel: Partition
tiles = smallTiles,
clickAction = ClickAction.REMOVE,
onClick = onRemove,
+ onDoubleTap = onDoubleTap,
isIconOnly = { true },
showLabels = showLabels,
dragAndDropState = dragAndDropState,
@@ -263,6 +271,7 @@ class PartitionedGridLayout @Inject constructor(private val viewModel: Partition
tilePadding: Dp,
addTileToEnd: (TileSpec) -> Unit,
onRemove: (TileSpec) -> Unit,
+ onDoubleTap: (TileSpec) -> Unit,
isIconOnly: (TileSpec) -> Boolean,
showLabels: Boolean,
columns: Int,
@@ -298,6 +307,7 @@ class PartitionedGridLayout @Inject constructor(private val viewModel: Partition
addTileToEnd,
isIconOnly,
dragAndDropState,
+ onDoubleTap = onDoubleTap,
acceptDrops = { true },
onDrop = onDrop,
)
@@ -309,8 +319,9 @@ class PartitionedGridLayout @Inject constructor(private val viewModel: Partition
ClickAction.ADD,
addTileToEnd,
isIconOnly,
+ dragAndDropState,
+ onDoubleTap = onDoubleTap,
showLabels = showLabels,
- dragAndDropState = dragAndDropState,
acceptDrops = { true },
onDrop = onDrop,
)
@@ -322,8 +333,9 @@ class PartitionedGridLayout @Inject constructor(private val viewModel: Partition
ClickAction.ADD,
addTileToEnd,
isIconOnly,
+ dragAndDropState,
+ onDoubleTap = onDoubleTap,
showLabels = showLabels,
- dragAndDropState = dragAndDropState,
acceptDrops = { true },
onDrop = onDrop,
)
@@ -360,11 +372,6 @@ class PartitionedGridLayout @Inject constructor(private val viewModel: Partition
}
}
- private fun gridHeight(nTiles: Int, tileHeight: Dp, columns: Int, padding: Dp): Dp {
- val rows = (nTiles + columns - 1) / columns
- return ((tileHeight + padding) * rows) - padding
- }
-
/** Fill up the rest of the row if it's not complete. */
private fun LazyGridScope.fillUpRow(nTiles: Int, columns: Int) {
if (nTiles % columns != 0) {
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
new file mode 100644
index 000000000000..9b4d10f27f9e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
@@ -0,0 +1,60 @@
+/*
+ * 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.qs.panels.ui.compose
+
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.GridItemSpan
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.dimensionResource
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.systemui.qs.panels.ui.viewmodel.QuickQuickSettingsViewModel
+import com.android.systemui.res.R
+
+@Composable
+fun QuickQuickSettings(
+ viewModel: QuickQuickSettingsViewModel,
+ modifier: Modifier = Modifier,
+) {
+ val sizedTiles by
+ viewModel.tileViewModels.collectAsStateWithLifecycle(initialValue = emptyList())
+ val tiles = sizedTiles.map { it.tile }
+
+ DisposableEffect(tiles) {
+ val token = Any()
+ tiles.forEach { it.startListening(token) }
+ onDispose { tiles.forEach { it.stopListening(token) } }
+ }
+ val columns by viewModel.columns.collectAsStateWithLifecycle()
+
+ TileLazyGrid(modifier = modifier, columns = GridCells.Fixed(columns)) {
+ items(
+ tiles.size,
+ key = { index -> sizedTiles[index].tile.spec.spec },
+ span = { index -> GridItemSpan(sizedTiles[index].width) }
+ ) { index ->
+ Tile(
+ tile = tiles[index],
+ iconOnly = sizedTiles[index].width == 1,
+ modifier = Modifier.height(dimensionResource(id = R.dimen.qs_tile_height))
+ )
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt
index 4a9010270ac5..3e48245a3d36 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt
@@ -100,10 +100,11 @@ constructor(
DefaultEditTileGrid(
tiles = tiles,
isIconOnly = iconTilesViewModel::isIconTile,
- columns = GridCells.Fixed(columns),
+ columns = columns,
modifier = modifier,
onAddTile = onAddTile,
onRemoveTile = onRemoveTile,
+ onResize = iconTilesViewModel::resize,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
index 0bb4cfa327a9..bd7956d7d3e1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
@@ -23,13 +23,19 @@ import android.service.quicksettings.Tile.STATE_ACTIVE
import android.service.quicksettings.Tile.STATE_INACTIVE
import android.text.TextUtils
import androidx.appcompat.content.res.AppCompatResources
+import androidx.compose.animation.AnimatedContent
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
import androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi
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.ExperimentalFoundationApi
import androidx.compose.foundation.Image
+import androidx.compose.foundation.LocalOverscrollConfiguration
import androidx.compose.foundation.basicMarquee
+import androidx.compose.foundation.border
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Arrangement.spacedBy
@@ -37,20 +43,31 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
+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.layout.wrapContentSize
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
+import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Clear
+import androidx.compose.material3.Icon
+import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -80,8 +97,9 @@ 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.plugins.qs.QSTile
+import com.android.systemui.qs.panels.shared.model.SizedTile
+import com.android.systemui.qs.panels.shared.model.TileRow
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.TileUiState
import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
import com.android.systemui.qs.panels.ui.viewmodel.toUiState
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
@@ -91,7 +109,6 @@ import com.android.systemui.res.R
import java.util.function.Supplier
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.mapLatest
object TileType
@@ -103,29 +120,27 @@ fun Tile(
showLabels: Boolean = false,
modifier: Modifier,
) {
- val state: TileUiState by
- tile.state
- .mapLatest { it.toUiState() }
- .collectAsStateWithLifecycle(tile.currentState.toUiState())
- val colors = TileDefaults.getColorForState(state.state)
+ val state by tile.state.collectAsStateWithLifecycle(tile.currentState)
+ val uiState = remember(state) { state.toUiState() }
+ val colors = TileDefaults.getColorForState(uiState.state)
TileContainer(
colors = colors,
showLabels = showLabels,
- label = state.label.toString(),
+ label = uiState.label,
iconOnly = iconOnly,
clickEnabled = true,
onClick = tile::onClick,
onLongClick = tile::onLongClick,
modifier = modifier,
) {
- val icon = getTileIcon(icon = state.icon)
+ val icon = getTileIcon(icon = uiState.icon)
if (iconOnly) {
TileIcon(icon = icon, color = colors.icon, modifier = Modifier.align(Alignment.Center))
} else {
LargeTileContent(
- label = state.label.toString(),
- secondaryLabel = state.secondaryLabel.toString(),
+ label = uiState.label,
+ secondaryLabel = uiState.secondaryLabel,
icon = icon,
colors = colors,
clickEnabled = true,
@@ -234,19 +249,26 @@ private fun LargeTileContent(
Text(
label,
color = colors.label,
- modifier = Modifier.basicMarquee(),
+ modifier = Modifier.tileMarquee(),
)
if (!TextUtils.isEmpty(secondaryLabel)) {
Text(
secondaryLabel ?: "",
color = colors.secondaryLabel,
- modifier = Modifier.basicMarquee(),
+ modifier = Modifier.tileMarquee(),
)
}
}
}
}
+private fun Modifier.tileMarquee(): Modifier {
+ return basicMarquee(
+ iterations = 1,
+ initialDelayMillis = 200,
+ )
+}
+
@Composable
fun TileLazyGrid(
modifier: Modifier = Modifier,
@@ -266,76 +288,263 @@ fun TileLazyGrid(
fun DefaultEditTileGrid(
tiles: List<EditTileViewModel>,
isIconOnly: (TileSpec) -> Boolean,
- columns: GridCells,
+ columns: Int,
modifier: Modifier,
onAddTile: (TileSpec, Int) -> Unit,
onRemoveTile: (TileSpec) -> Unit,
+ onResize: (TileSpec, Boolean) -> Unit,
) {
val currentListState = rememberEditListState(tiles)
val dragAndDropState = rememberDragAndDropState(currentListState)
-
val (currentTiles, otherTiles) = currentListState.tiles.partition { it.isCurrent }
- val (otherTilesStock, otherTilesCustom) =
- otherTiles
- .filter { !dragAndDropState.isMoving(it.tileSpec) }
- .partition { it.appName == null }
+
val addTileToEnd: (TileSpec) -> Unit by rememberUpdatedState {
onAddTile(it, CurrentTilesInteractor.POSITION_AT_END)
}
-
val onDropAdd: (TileSpec, Int) -> Unit by rememberUpdatedState { tileSpec, position ->
onAddTile(tileSpec, position)
}
- val onDropRemove: (TileSpec, Int) -> Unit by rememberUpdatedState { tileSpec, _ ->
- onRemoveTile(tileSpec)
+ val onDoubleTap: (TileSpec) -> Unit by rememberUpdatedState { tileSpec ->
+ onResize(tileSpec, !isIconOnly(tileSpec))
}
+ val tilePadding = dimensionResource(R.dimen.qs_tile_margin_vertical)
- TileLazyGrid(
- modifier = modifier.dragAndDropTileList(dragAndDropState, { true }, onDropAdd),
- columns = columns
+ CompositionLocalProvider(LocalOverscrollConfiguration provides null) {
+ Column(
+ verticalArrangement =
+ spacedBy(dimensionResource(id = R.dimen.qs_label_container_margin)),
+ modifier = modifier.fillMaxSize().verticalScroll(rememberScrollState())
+ ) {
+ AnimatedContent(
+ targetState = dragAndDropState.dragInProgress,
+ modifier = Modifier.wrapContentSize()
+ ) { dragIsInProgress ->
+ EditGridHeader(Modifier.dragAndDropRemoveZone(dragAndDropState, onRemoveTile)) {
+ if (dragIsInProgress) {
+ RemoveTileTarget()
+ } else {
+ Text(text = "Hold and drag to rearrange tiles.")
+ }
+ }
+ }
+
+ CurrentTilesGrid(
+ currentTiles,
+ columns,
+ tilePadding,
+ isIconOnly,
+ onRemoveTile,
+ onDoubleTap,
+ dragAndDropState,
+ onDropAdd,
+ )
+
+ // Hide available tiles when dragging
+ AnimatedVisibility(
+ visible = !dragAndDropState.dragInProgress,
+ enter = fadeIn(),
+ exit = fadeOut()
+ ) {
+ Column(
+ verticalArrangement =
+ spacedBy(dimensionResource(id = R.dimen.qs_label_container_margin)),
+ modifier = modifier.fillMaxSize()
+ ) {
+ EditGridHeader { Text(text = "Hold and drag to add tiles.") }
+
+ AvailableTileGrid(
+ otherTiles,
+ columns,
+ tilePadding,
+ addTileToEnd,
+ dragAndDropState,
+ )
+ }
+ }
+
+ // Drop zone to remove tiles dragged out of the tile grid
+ Spacer(
+ modifier =
+ Modifier.fillMaxWidth()
+ .weight(1f)
+ .dragAndDropRemoveZone(dragAndDropState, onRemoveTile)
+ )
+ }
+ }
+}
+
+@Composable
+private fun EditGridHeader(
+ modifier: Modifier = Modifier,
+ content: @Composable BoxScope.() -> Unit
+) {
+ CompositionLocalProvider(
+ LocalContentColor provides MaterialTheme.colorScheme.onBackground.copy(alpha = .5f)
) {
- // These Text are just placeholders to see the different sections. Not final UI.
- item(span = { GridItemSpan(maxLineSpan) }) { Text("Current tiles", color = Color.White) }
+ Box(
+ contentAlignment = Alignment.Center,
+ modifier = modifier.fillMaxWidth().height(TileDefaults.EditGridHeaderHeight)
+ ) {
+ content()
+ }
+ }
+}
- editTiles(
- currentTiles,
- ClickAction.REMOVE,
- onRemoveTile,
- isIconOnly,
- indicatePosition = true,
- dragAndDropState = dragAndDropState,
- acceptDrops = { true },
- onDrop = onDropAdd,
- )
+@Composable
+private fun RemoveTileTarget() {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = tileHorizontalArrangement(),
+ modifier =
+ Modifier.fillMaxHeight()
+ .border(1.dp, LocalContentColor.current, shape = TileDefaults.TileShape)
+ .padding(10.dp)
+ ) {
+ Icon(imageVector = Icons.Default.Clear, contentDescription = null)
+ Text(text = "Remove")
+ }
+}
- item(span = { GridItemSpan(maxLineSpan) }) { Text("Tiles to add", color = Color.White) }
+@Composable
+private fun CurrentTilesContainer(content: @Composable () -> Unit) {
+ Box(
+ Modifier.fillMaxWidth()
+ .border(
+ width = 1.dp,
+ color = MaterialTheme.colorScheme.onBackground.copy(alpha = .5f),
+ shape = RoundedCornerShape(48.dp),
+ )
+ .padding(dimensionResource(R.dimen.qs_tile_margin_vertical))
+ ) {
+ content()
+ }
+}
+
+@Composable
+private fun CurrentTilesGrid(
+ tiles: List<EditTileViewModel>,
+ columns: Int,
+ tilePadding: Dp,
+ isIconOnly: (TileSpec) -> Boolean,
+ onClick: (TileSpec) -> Unit,
+ onDoubleTap: (TileSpec) -> Unit,
+ dragAndDropState: DragAndDropState,
+ onDrop: (TileSpec, Int) -> Unit
+) {
+ val tileHeight = tileHeight()
+ val currentRows =
+ remember(tiles) {
+ calculateRows(
+ tiles.map {
+ SizedTile(
+ it,
+ if (isIconOnly(it.tileSpec)) {
+ 1
+ } else {
+ 2
+ }
+ )
+ },
+ columns
+ )
+ }
+ val currentGridHeight = gridHeight(currentRows, tileHeight, tilePadding)
+ // Current tiles
+ CurrentTilesContainer {
+ TileLazyGrid(
+ modifier =
+ Modifier.height(currentGridHeight)
+ .dragAndDropTileList(dragAndDropState, { true }, onDrop),
+ columns = GridCells.Fixed(columns)
+ ) {
+ editTiles(
+ tiles,
+ ClickAction.REMOVE,
+ onClick,
+ isIconOnly,
+ dragAndDropState,
+ onDoubleTap = onDoubleTap,
+ indicatePosition = true,
+ acceptDrops = { true },
+ onDrop = onDrop,
+ )
+ }
+ }
+}
+@Composable
+private fun AvailableTileGrid(
+ tiles: List<EditTileViewModel>,
+ columns: Int,
+ tilePadding: Dp,
+ onClick: (TileSpec) -> Unit,
+ dragAndDropState: DragAndDropState,
+) {
+ val (otherTilesStock, otherTilesCustom) =
+ tiles.filter { !dragAndDropState.isMoving(it.tileSpec) }.partition { it.appName == null }
+ val availableTileHeight = tileHeight(true)
+ val availableGridHeight = gridHeight(tiles.size, availableTileHeight, columns, tilePadding)
+
+ // Available tiles
+ TileLazyGrid(
+ modifier =
+ Modifier.height(availableGridHeight)
+ .dragAndDropTileList(dragAndDropState, { false }, { _, _ -> }),
+ columns = GridCells.Fixed(columns)
+ ) {
editTiles(
otherTilesStock,
ClickAction.ADD,
- addTileToEnd,
- isIconOnly,
+ onClick,
+ isIconOnly = { true },
dragAndDropState = dragAndDropState,
- acceptDrops = { true },
- onDrop = onDropRemove,
+ acceptDrops = { false },
+ showLabels = true,
)
-
- item(span = { GridItemSpan(maxLineSpan) }) {
- Text("Custom tiles to add", color = Color.White)
- }
-
editTiles(
otherTilesCustom,
ClickAction.ADD,
- addTileToEnd,
- isIconOnly,
+ onClick,
+ isIconOnly = { true },
dragAndDropState = dragAndDropState,
- acceptDrops = { true },
- onDrop = onDropRemove,
+ acceptDrops = { false },
+ showLabels = true,
)
}
}
+fun gridHeight(nTiles: Int, tileHeight: Dp, columns: Int, padding: Dp): Dp {
+ val rows = (nTiles + columns - 1) / columns
+ return gridHeight(rows, tileHeight, padding)
+}
+
+fun gridHeight(rows: Int, tileHeight: Dp, padding: Dp): Dp {
+ return ((tileHeight + padding) * rows) - padding
+}
+
+private fun calculateRows(tiles: List<SizedTile<EditTileViewModel>>, columns: Int): Int {
+ val row = TileRow<EditTileViewModel>(columns)
+ var count = 0
+
+ for (tile in tiles) {
+ if (row.maybeAddTile(tile)) {
+ if (row.isFull()) {
+ // Row is full, no need to stretch tiles
+ count += 1
+ row.clear()
+ }
+ } else {
+ count += 1
+ row.clear()
+ row.maybeAddTile(tile)
+ }
+ }
+ if (row.tiles.isNotEmpty()) {
+ count += 1
+ }
+ return count
+}
+
fun LazyGridScope.editTiles(
tiles: List<EditTileViewModel>,
clickAction: ClickAction,
@@ -343,7 +552,8 @@ fun LazyGridScope.editTiles(
isIconOnly: (TileSpec) -> Boolean,
dragAndDropState: DragAndDropState,
acceptDrops: (TileSpec) -> Boolean,
- onDrop: (TileSpec, Int) -> Unit,
+ onDoubleTap: (TileSpec) -> Unit = {},
+ onDrop: (TileSpec, Int) -> Unit = { _, _ -> },
showLabels: Boolean = false,
indicatePosition: Boolean = false,
) {
@@ -386,6 +596,7 @@ fun LazyGridScope.editTiles(
.dragAndDropTileSource(
viewModel.tileSpec,
onClick,
+ onDoubleTap,
dragAndDropState,
)
)
@@ -522,6 +733,7 @@ private data class TileColors(
private object TileDefaults {
val TileShape = CircleShape
val IconTileWithLabelHeight = 140.dp
+ val EditGridHeaderHeight = 60.dp
@Composable
fun activeTileColors(): TileColors =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
index 19b8c66983f9..ef2c8bfe0e4c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
@@ -27,6 +27,8 @@ import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor.Companion.POSITION_AT_END
import com.android.systemui.qs.pipeline.domain.interactor.MinimumTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
+import javax.inject.Inject
+import javax.inject.Named
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
@@ -37,22 +39,20 @@ import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
-import javax.inject.Inject
-import javax.inject.Named
@SysUISingleton
@OptIn(ExperimentalCoroutinesApi::class)
class EditModeViewModel
@Inject
constructor(
- private val editTilesListInteractor: EditTilesListInteractor,
- private val currentTilesInteractor: CurrentTilesInteractor,
- private val tilesAvailabilityInteractor: TilesAvailabilityInteractor,
- private val minTilesInteractor: MinimumTilesInteractor,
- @Named("Default") private val defaultGridLayout: GridLayout,
- @Application private val applicationScope: CoroutineScope,
- gridLayoutTypeInteractor: GridLayoutTypeInteractor,
- gridLayoutMap: Map<GridLayoutType, @JvmSuppressWildcards GridLayout>,
+ private val editTilesListInteractor: EditTilesListInteractor,
+ private val currentTilesInteractor: CurrentTilesInteractor,
+ private val tilesAvailabilityInteractor: TilesAvailabilityInteractor,
+ private val minTilesInteractor: MinimumTilesInteractor,
+ @Named("Default") private val defaultGridLayout: GridLayout,
+ @Application private val applicationScope: CoroutineScope,
+ gridLayoutTypeInteractor: GridLayoutTypeInteractor,
+ gridLayoutMap: Map<GridLayoutType, @JvmSuppressWildcards GridLayout>,
) {
private val _isEditing = MutableStateFlow(false)
@@ -93,10 +93,12 @@ constructor(
val editTilesData = editTilesListInteractor.getTilesToEdit()
// Query only the non current platform tiles, as any current tile is clearly
// available
- val unavailable = tilesAvailabilityInteractor.getUnavailableTiles(
- editTilesData.stockTiles.map { it.tileSpec }
- .minus(currentTilesInteractor.currentTilesSpecs.toSet())
- )
+ val unavailable =
+ tilesAvailabilityInteractor.getUnavailableTiles(
+ editTilesData.stockTiles
+ .map { it.tileSpec }
+ .minus(currentTilesInteractor.currentTilesSpecs.toSet())
+ )
currentTilesInteractor.currentTiles.map { tiles ->
val currentSpecs = tiles.map { it.spec }
val canRemoveTiles = currentSpecs.size > minimumTiles
@@ -106,28 +108,28 @@ constructor(
val nonCurrentTiles = allTiles.filter { it.tileSpec !in currentSpecs }
(currentTiles + nonCurrentTiles)
- .filterNot { it.tileSpec in unavailable }
- .map {
- val current = it.tileSpec in currentSpecs
- val availableActions = buildSet {
- if (current) {
- add(AvailableEditActions.MOVE)
- if (canRemoveTiles) {
- add(AvailableEditActions.REMOVE)
- }
- } else {
- add(AvailableEditActions.ADD)
+ .filterNot { it.tileSpec in unavailable }
+ .map {
+ val current = it.tileSpec in currentSpecs
+ val availableActions = buildSet {
+ if (current) {
+ add(AvailableEditActions.MOVE)
+ if (canRemoveTiles) {
+ add(AvailableEditActions.REMOVE)
}
+ } else {
+ add(AvailableEditActions.ADD)
}
- EditTileViewModel(
- it.tileSpec,
- it.icon,
- it.label,
- it.appName,
- current,
- availableActions
- )
}
+ EditTileViewModel(
+ it.tileSpec,
+ it.icon,
+ it.label,
+ it.appName,
+ current,
+ availableActions
+ )
+ }
}
} else {
emptyFlow()
@@ -144,14 +146,32 @@ constructor(
_isEditing.value = false
}
- /** Immediately moves [tileSpec] to [position]. */
- fun moveTile(tileSpec: TileSpec, position: Int) {
- throw NotImplementedError("This is not supported yet")
- }
-
- /** Immediately adds [tileSpec] to the current tiles at [position]. */
+ /**
+ * Immediately adds [tileSpec] to the current tiles at [position]. If the [tileSpec] was already
+ * present, it will be moved to the new position.
+ */
fun addTile(tileSpec: TileSpec, position: Int = POSITION_AT_END) {
- currentTilesInteractor.addTile(tileSpec, position)
+ val specs = currentTilesInteractor.currentTilesSpecs.toMutableList()
+ val currentPosition = specs.indexOf(tileSpec)
+
+ if (currentPosition != -1) {
+ // No operation needed if the element is already in the list at the right position
+ if (currentPosition == position) {
+ return
+ }
+ // Removing tile if it's present at a different position to insert it at the new index.
+ specs.removeAt(currentPosition)
+ }
+
+ if (position >= 0 && position < specs.size) {
+ specs.add(position, tileSpec)
+ } else {
+ specs.add(tileSpec)
+ }
+
+ // Setting the new tiles as one operation to avoid UI jank with tiles disappearing and
+ // reappearing
+ currentTilesInteractor.setTiles(specs)
}
/** Immediately removes [tileSpec] from the current tiles. */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconTilesViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconTilesViewModel.kt
index 117c85c9c3ba..8d2d74af5835 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconTilesViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconTilesViewModel.kt
@@ -23,10 +23,14 @@ import javax.inject.Inject
interface IconTilesViewModel {
fun isIconTile(spec: TileSpec): Boolean
+
+ fun resize(spec: TileSpec, toIcon: Boolean)
}
@SysUISingleton
class IconTilesViewModelImpl @Inject constructor(private val interactor: IconTilesInteractor) :
IconTilesViewModel {
override fun isIconTile(spec: TileSpec): Boolean = interactor.isIconTile(spec)
+
+ override fun resize(spec: TileSpec, toIcon: Boolean) = interactor.resize(spec, toIcon)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
new file mode 100644
index 000000000000..bb004946a4d1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.qs.panels.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.qs.panels.domain.interactor.QuickQuickSettingsRowInteractor
+import com.android.systemui.qs.panels.shared.model.SizedTile
+import com.android.systemui.qs.panels.shared.model.TileRow
+import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.stateIn
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class QuickQuickSettingsViewModel
+@Inject
+constructor(
+ tilesInteractor: CurrentTilesInteractor,
+ fixedColumnsSizeViewModel: FixedColumnsSizeViewModel,
+ quickQuickSettingsRowInteractor: QuickQuickSettingsRowInteractor,
+ private val iconTilesViewModel: IconTilesViewModel,
+ @Application private val applicationScope: CoroutineScope,
+) {
+
+ val columns = fixedColumnsSizeViewModel.columns
+
+ private val rows =
+ quickQuickSettingsRowInteractor.rows.stateIn(
+ applicationScope,
+ SharingStarted.WhileSubscribed(),
+ quickQuickSettingsRowInteractor.defaultRows
+ )
+
+ val tileViewModels: StateFlow<List<SizedTile<TileViewModel>>> =
+ columns
+ .flatMapLatest { columns ->
+ tilesInteractor.currentTiles.combine(rows, ::Pair).mapLatest { (tiles, rows) ->
+ tiles
+ .map { SizedTile(TileViewModel(it.tile, it.spec), it.spec.width) }
+ .let { splitInRowsSequence(it, columns).take(rows).toList().flatten() }
+ }
+ }
+ .stateIn(
+ applicationScope,
+ SharingStarted.WhileSubscribed(),
+ tilesInteractor.currentTiles.value
+ .map { SizedTile(TileViewModel(it.tile, it.spec), it.spec.width) }
+ .let {
+ splitInRowsSequence(it, columns.value).take(rows.value).toList().flatten()
+ }
+ )
+
+ private val TileSpec.width: Int
+ get() = if (iconTilesViewModel.isIconTile(this)) 1 else 2
+
+ companion object {
+ private fun splitInRowsSequence(
+ tiles: List<SizedTile<TileViewModel>>,
+ columns: Int,
+ ): Sequence<List<SizedTile<TileViewModel>>> = sequence {
+ val row = TileRow<TileViewModel>(columns)
+ for (tile in tiles) {
+ check(tile.width <= columns)
+ if (!row.maybeAddTile(tile)) {
+ // Couldn't add tile to previous row, create a row with the current tiles
+ // and start a new one
+ yield(row.tiles)
+ row.clear()
+ row.maybeAddTile(tile)
+ }
+ }
+ if (row.tiles.isNotEmpty()) {
+ yield(row.tiles)
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
index 578a292deb7c..4ec59c969a59 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
@@ -16,20 +16,22 @@
package com.android.systemui.qs.panels.ui.viewmodel
+import androidx.compose.runtime.Immutable
import com.android.systemui.plugins.qs.QSTile
import java.util.function.Supplier
+@Immutable
data class TileUiState(
- val label: CharSequence,
- val secondaryLabel: CharSequence,
+ val label: String,
+ val secondaryLabel: String,
val state: Int,
val icon: Supplier<QSTile.Icon>,
)
fun QSTile.State.toUiState(): TileUiState {
return TileUiState(
- label ?: "",
- secondaryLabel ?: "",
+ label?.toString() ?: "",
+ secondaryLabel?.toString() ?: "",
state,
icon?.let { Supplier { icon } } ?: iconSupplier,
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt
index 7505b90ee844..8578bb0ef9a1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt
@@ -16,6 +16,7 @@
package com.android.systemui.qs.panels.ui.viewmodel
+import androidx.compose.runtime.Immutable
import com.android.systemui.animation.Expandable
import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.qs.pipeline.shared.TileSpec
@@ -25,6 +26,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.onStart
+@Immutable
class TileViewModel(private val tile: QSTile, val spec: TileSpec) {
val state: Flow<QSTile.State> =
conflatedCallbackFlow {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddable.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddable.kt
index 9c1b85799648..4d823ab216f0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddable.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddable.kt
@@ -38,10 +38,11 @@ class ReduceBrightColorsAutoAddable
@Inject
constructor(
controller: ReduceBrightColorsController,
- @Named(RBC_AVAILABLE) private val available: Boolean,
+ @Named(RBC_AVAILABLE) private var available: Boolean,
) :
CallbackControllerAutoAddable<
- ReduceBrightColorsController.Listener, ReduceBrightColorsController
+ ReduceBrightColorsController.Listener,
+ ReduceBrightColorsController
>(controller) {
override val spec: TileSpec
@@ -50,10 +51,16 @@ constructor(
override fun ProducerScope<AutoAddSignal>.getCallback(): ReduceBrightColorsController.Listener {
return object : ReduceBrightColorsController.Listener {
override fun onActivated(activated: Boolean) {
- if (activated) {
+ if (activated && available) {
sendAdd()
}
}
+
+ override fun onFeatureEnabledChanged(enabled: Boolean) {
+ if (!enabled) {
+ available = false
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 44c846b5c631..6b3dfe1b90ad 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -93,6 +93,7 @@ constructor(
@VisibleForTesting internal const val TILE_STATE_RES_PREFIX = "tile_states_"
@VisibleForTesting internal const val LONG_PRESS_EFFECT_WIDTH_SCALE = 1.1f
@VisibleForTesting internal const val LONG_PRESS_EFFECT_HEIGHT_SCALE = 1.2f
+ internal val EMPTY_RECT = Rect()
}
private val icon: QSIconViewImpl = QSIconViewImpl(context)
@@ -386,6 +387,7 @@ constructor(
// The launch animation of a long-press effect did not reset the long-press effect so
// we must do it here
resetLongPressEffectProperties()
+ longPressEffect.resetState()
}
val actualHeight =
if (heightOverride != HeightOverrideable.NO_OVERRIDE) {
@@ -771,11 +773,14 @@ constructor(
lastIconTint = icon.getColor(state)
// Long-press effects
+ longPressEffect?.qsTile?.state?.handlesLongClick = state.handlesLongClick
if (
state.handlesLongClick &&
longPressEffect?.initializeEffect(longPressEffectDuration) == true
) {
showRippleEffect = false
+ longPressEffect.qsTile?.state?.state = lastState // Store the tile's state
+ longPressEffect.resetState()
initializeLongPressProperties(measuredHeight, measuredWidth)
} else {
// Long-press effects might have been enabled before but the new state does not
@@ -906,12 +911,13 @@ constructor(
}
override fun onActivityLaunchAnimationEnd() {
+ longPressEffect?.resetState()
if (longPressEffect != null && !haveLongPressPropertiesBeenReset) {
resetLongPressEffectProperties()
}
}
- fun prepareForLaunch() {
+ private fun prepareForLaunch() {
val startingHeight = initialLongPressProperties?.height?.toInt() ?: 0
val startingWidth = initialLongPressProperties?.width?.toInt() ?: 0
val deltaH = finalLongPressProperties?.height?.minus(startingHeight)?.toInt() ?: 0
@@ -922,7 +928,12 @@ constructor(
paddingForLaunch.bottom = deltaH / 2
}
- override fun getPaddingForLaunchAnimation(): Rect = paddingForLaunch
+ override fun getPaddingForLaunchAnimation(): Rect =
+ if (longPressEffect?.state == QSLongPressEffect.State.LONG_CLICKED) {
+ paddingForLaunch
+ } else {
+ EMPTY_RECT
+ }
fun updateLongPressEffectProperties(effectProgress: Float) {
if (!isLongClickable || longPressEffect == null) return
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
index f34389ec8cb5..53594bbb2c84 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
@@ -20,12 +20,14 @@ import com.android.systemui.res.R
/** Return the subtitle resource Id of the given tile. */
object SubtitleArrayMapping {
private val subtitleIdsMap: HashMap<String, Int> = HashMap()
+
init {
subtitleIdsMap["internet"] = R.array.tile_states_internet
subtitleIdsMap["wifi"] = R.array.tile_states_wifi
subtitleIdsMap["cell"] = R.array.tile_states_cell
subtitleIdsMap["battery"] = R.array.tile_states_battery
subtitleIdsMap["dnd"] = R.array.tile_states_dnd
+ subtitleIdsMap["modes"] = R.array.tile_states_modes
subtitleIdsMap["flashlight"] = R.array.tile_states_flashlight
subtitleIdsMap["rotation"] = R.array.tile_states_rotation
subtitleIdsMap["bt"] = R.array.tile_states_bt
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 4ebebeade1f4..bdf935ef420f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -42,7 +42,7 @@ import androidx.annotation.Nullable;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settingslib.notification.EnableZenModeDialog;
+import com.android.settingslib.notification.modes.EnableZenModeDialog;
import com.android.systemui.Prefs;
import com.android.systemui.animation.DialogCuj;
import com.android.systemui.animation.DialogTransitionAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt
new file mode 100644
index 000000000000..b91891cf7be0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt
@@ -0,0 +1,117 @@
+/*
+ * 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.qs.tiles
+
+import android.app.Flags
+import android.content.Intent
+import android.os.Handler
+import android.os.Looper
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.coroutineScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.internal.logging.MetricsLogger
+import com.android.systemui.animation.Expandable
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.qs.QSTile.BooleanState
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileDataInteractor
+import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
+import com.android.systemui.qs.tiles.impl.modes.ui.ModesTileMapper
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.res.R
+import javax.inject.Inject
+import kotlinx.coroutines.launch
+
+class ModesTile
+@Inject
+constructor(
+ host: QSHost,
+ uiEventLogger: QsEventLogger,
+ @Background backgroundLooper: Looper,
+ @Main mainHandler: Handler,
+ falsingManager: FalsingManager,
+ metricsLogger: MetricsLogger,
+ statusBarStateController: StatusBarStateController,
+ activityStarter: ActivityStarter,
+ qsLogger: QSLogger,
+ qsTileConfigProvider: QSTileConfigProvider,
+ dataInteractor: ModesTileDataInteractor,
+ private val tileMapper: ModesTileMapper,
+ private val userActionInteractor: ModesTileUserActionInteractor,
+) :
+ QSTileImpl<BooleanState>(
+ host,
+ uiEventLogger,
+ backgroundLooper,
+ mainHandler,
+ falsingManager,
+ metricsLogger,
+ statusBarStateController,
+ activityStarter,
+ qsLogger
+ ) {
+
+ private lateinit var tileState: QSTileState
+ private val config = qsTileConfigProvider.getConfig(TILE_SPEC)
+
+ init {
+ lifecycle.coroutineScope.launch {
+ lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
+ dataInteractor.tileData().collect { refreshState(it) }
+ }
+ }
+ }
+
+ override fun isAvailable(): Boolean = Flags.modesUi()
+
+ override fun getTileLabel(): CharSequence = tileState.label
+
+ override fun newTileState() = BooleanState()
+
+ override fun handleClick(expandable: Expandable?) {
+ // TODO(b/346519570) open dialog
+ }
+
+ override fun getLongClickIntent(): Intent = userActionInteractor.longClickIntent
+
+ override fun handleUpdateState(booleanState: BooleanState?, arg: Any?) {
+ if (arg is ModesTileModel) {
+ tileState = tileMapper.map(config, arg)
+
+ booleanState?.apply {
+ state = tileState.activationState.legacyState
+ icon = ResourceIcon.get(tileState.iconRes ?: R.drawable.qs_dnd_icon_off)
+ label = tileLabel
+ secondaryLabel = tileState.secondaryLabel
+ contentDescription = tileState.contentDescription
+ }
+ }
+ }
+
+ companion object {
+ const val TILE_SPEC = "modes"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
index 34723523b84f..af5b31180159 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
@@ -48,12 +48,13 @@ import javax.inject.Named;
/** Quick settings tile: Reduce Bright Colors **/
public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState>
- implements ReduceBrightColorsController.Listener{
+ implements ReduceBrightColorsController.Listener {
public static final String TILE_SPEC = "reduce_brightness";
- private final boolean mIsAvailable;
+ private boolean mIsAvailable;
private final ReduceBrightColorsController mReduceBrightColorsController;
private boolean mIsListening;
+ private final boolean mInUpgradeMode;
@Inject
public ReduceBrightColorsTile(
@@ -73,9 +74,11 @@ public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState>
statusBarStateController, activityStarter, qsLogger);
mReduceBrightColorsController = reduceBrightColorsController;
mReduceBrightColorsController.observe(getLifecycle(), this);
- mIsAvailable = isAvailable;
+ mInUpgradeMode = reduceBrightColorsController.isInUpgradeMode(mContext.getResources());
+ mIsAvailable = isAvailable || mInUpgradeMode;
}
+
@Override
public boolean isAvailable() {
return mIsAvailable;
@@ -93,12 +96,28 @@ public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState>
@Override
public Intent getLongClickIntent() {
- return new Intent(Settings.ACTION_REDUCE_BRIGHT_COLORS_SETTINGS);
+ return goToEvenDimmer() ? new Intent(Settings.ACTION_DISPLAY_SETTINGS) : new Intent(
+ Settings.ACTION_REDUCE_BRIGHT_COLORS_SETTINGS);
+ }
+
+ private boolean goToEvenDimmer() {
+ if (mInUpgradeMode) {
+ mHost.removeTile(getTileSpec());
+ mIsAvailable = false;
+ return true;
+ }
+ return false;
}
@Override
protected void handleClick(@Nullable Expandable expandable) {
- mReduceBrightColorsController.setReduceBrightColorsActivated(!mState.value);
+
+ if (goToEvenDimmer()) {
+ mActivityStarter.postStartActivityDismissingKeyguard(
+ new Intent(Settings.ACTION_DISPLAY_SETTINGS), 0);
+ } else {
+ mReduceBrightColorsController.setReduceBrightColorsActivated(!mState.value);
+ }
}
@Override
@@ -127,4 +146,9 @@ public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState>
public void onActivated(boolean activated) {
refreshState();
}
+
+ @Override
+ public void onFeatureEnabledChanged(boolean enabled) {
+ refreshState();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index df7430a0f729..158eb6eb5e89 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -65,6 +65,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
@@ -184,7 +185,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi
private GlobalSettings mGlobalSettings;
private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private ConnectivityManager.NetworkCallback mConnectivityManagerNetworkCallback;
- private WindowManager mWindowManager;
+ private ViewCaptureAwareWindowManager mWindowManager;
private ToastFactory mToastFactory;
private SignalDrawable mSignalDrawable;
private SignalDrawable mSecondarySignalDrawable; // For the secondary mobile data sub in DSDS
@@ -246,7 +247,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi
@Main Handler handler, @Main Executor mainExecutor,
BroadcastDispatcher broadcastDispatcher, KeyguardUpdateMonitor keyguardUpdateMonitor,
GlobalSettings globalSettings, KeyguardStateController keyguardStateController,
- WindowManager windowManager, ToastFactory toastFactory,
+ ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, ToastFactory toastFactory,
@Background Handler workerHandler,
CarrierConfigTracker carrierConfigTracker,
LocationController locationController,
@@ -278,7 +279,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi
mAccessPointController = accessPointController;
mWifiIconInjector = new WifiUtils.InternetIconInjector(mContext);
mConnectivityManagerNetworkCallback = new DataConnectivityListener();
- mWindowManager = windowManager;
+ mWindowManager = viewCaptureAwareWindowManager;
mToastFactory = toastFactory;
mSignalDrawable = new SignalDrawable(mContext);
mSecondarySignalDrawable = new SignalDrawable(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
index c971f547c302..edc49cac2f92 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
@@ -183,9 +183,9 @@ public class InternetDialogDelegate implements
Context context,
InternetDialogManager internetDialogManager,
InternetDialogController internetDialogController,
- @Assisted(ABOVE_STATUS_BAR) boolean canConfigMobileData,
- @Assisted(CAN_CONFIG_MOBILE_DATA) boolean canConfigWifi,
- @Assisted(CAN_CONFIG_WIFI) boolean aboveStatusBar,
+ @Assisted(CAN_CONFIG_MOBILE_DATA) boolean canConfigMobileData,
+ @Assisted(CAN_CONFIG_WIFI) boolean canConfigWifi,
+ @Assisted(ABOVE_STATUS_BAR) boolean aboveStatusBar,
@Assisted CoroutineScope coroutineScope,
UiEventLogger uiEventLogger,
DialogTransitionAnimator dialogTransitionAnimator,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSZenModeDialogMetricsLogger.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSZenModeDialogMetricsLogger.java
index 1b81a9947ee3..b3f66a6bf9dd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSZenModeDialogMetricsLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSZenModeDialogMetricsLogger.java
@@ -19,7 +19,7 @@ package com.android.systemui.qs.tiles.dialog;
import android.content.Context;
import com.android.internal.logging.UiEventLogger;
-import com.android.settingslib.notification.ZenModeDialogMetricsLogger;
+import com.android.settingslib.notification.modes.ZenModeDialogMetricsLogger;
import com.android.systemui.qs.QSDndEvent;
import com.android.systemui.qs.QSEvents;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt
new file mode 100644
index 000000000000..31e91aa8fe87
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt
@@ -0,0 +1,51 @@
+/*
+ * 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.qs.tiles.impl.modes.domain.interactor
+
+import android.app.Flags
+import android.os.UserHandle
+import com.android.settingslib.notification.data.repository.ZenModeRepository
+import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
+
+class ModesTileDataInteractor @Inject constructor(val zenModeRepository: ZenModeRepository) :
+ QSTileDataInteractor<ModesTileModel> {
+ private val zenModeActive =
+ zenModeRepository.modes
+ .map { modes -> modes.any { mode -> mode.isActive } }
+ .distinctUntilChanged()
+
+ override fun tileData(
+ user: UserHandle,
+ triggers: Flow<DataUpdateTrigger>
+ ): Flow<ModesTileModel> = tileData()
+
+ /**
+ * An adapted version of the base class' [tileData] method for use in an old-style tile.
+ *
+ * TODO(b/299909989): Remove after the transition.
+ */
+ fun tileData() = zenModeActive.map { ModesTileModel(isActivated = it) }
+
+ override fun availability(user: UserHandle): Flow<Boolean> = flowOf(Flags.modesUi())
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt
new file mode 100644
index 000000000000..fd1f3d8fb23a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt
@@ -0,0 +1,47 @@
+/*
+ * 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.qs.tiles.impl.modes.domain.interactor
+
+import android.content.Intent
+import android.provider.Settings
+import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.interactor.QSTileInput
+import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import javax.inject.Inject
+
+class ModesTileUserActionInteractor
+@Inject
+constructor(
+ private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler,
+) : QSTileUserActionInteractor<ModesTileModel> {
+ val longClickIntent = Intent(Settings.ACTION_ZEN_MODE_SETTINGS)
+
+ override suspend fun handleInput(input: QSTileInput<ModesTileModel>) {
+ with(input) {
+ when (action) {
+ is QSTileUserAction.Click -> {
+ // TODO(b/346519570) open dialog
+ }
+ is QSTileUserAction.LongClick -> {
+ qsTileIntentUserActionHandler.handle(action.expandable, longClickIntent)
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesTileModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesTileModel.kt
new file mode 100644
index 000000000000..e44413a962f4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesTileModel.kt
@@ -0,0 +1,18 @@
+/*
+ * 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.qs.tiles.impl.modes.domain.model
+data class ModesTileModel(val isActivated: Boolean)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt
new file mode 100644
index 000000000000..26b9a4c7f416
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.qs.tiles.impl.modes.ui
+
+import android.content.res.Resources
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.res.R
+import javax.inject.Inject
+
+class ModesTileMapper
+@Inject
+constructor(
+ @Main private val resources: Resources,
+ val theme: Resources.Theme,
+) : QSTileDataToStateMapper<ModesTileModel> {
+ override fun map(config: QSTileConfig, data: ModesTileModel): QSTileState =
+ QSTileState.build(resources, theme, config.uiConfig) {
+ iconRes =
+ if (data.isActivated) {
+ R.drawable.qs_dnd_icon_on
+ } else {
+ R.drawable.qs_dnd_icon_off
+ }
+ val icon =
+ Icon.Loaded(
+ resources.getDrawable(iconRes!!, theme),
+ contentDescription = null,
+ )
+ this.icon = { icon }
+ if (data.isActivated) {
+ activationState = QSTileState.ActivationState.ACTIVE
+ secondaryLabel = "Some modes enabled idk" // TODO(b/346519570)
+ } else {
+ activationState = QSTileState.ActivationState.INACTIVE
+ secondaryLabel = "Off" // TODO(b/346519570)
+ }
+ contentDescription = label
+ supportedActions =
+ setOf(
+ QSTileState.UserAction.CLICK,
+ QSTileState.UserAction.LONG_CLICK,
+ )
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt
index 98fd561b27d6..00b1e41461f5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt
@@ -23,13 +23,13 @@ import com.android.systemui.qs.dagger.QSFlagsModule.RBC_AVAILABLE
import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel
+import com.android.systemui.util.kotlin.isAvailable
import com.android.systemui.util.kotlin.isEnabled
import javax.inject.Inject
import javax.inject.Named
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
@@ -52,5 +52,7 @@ constructor(
.map { ReduceBrightColorsTileModel(it) }
.flowOn(bgCoroutineContext)
}
- override fun availability(user: UserHandle): Flow<Boolean> = flowOf(isAvailable)
+
+ override fun availability(user: UserHandle): Flow<Boolean> =
+ reduceBrightColorsController.isAvailable()
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt
index 14dbe0e8a69a..ed5e4fe74962 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt
@@ -17,7 +17,9 @@
package com.android.systemui.qs.tiles.impl.reducebrightness.domain.interactor
import android.content.Intent
+import android.content.res.Resources
import android.provider.Settings
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.qs.ReduceBrightColorsController
import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
import com.android.systemui.qs.tiles.base.interactor.QSTileInput
@@ -30,19 +32,40 @@ import javax.inject.Inject
class ReduceBrightColorsTileUserActionInteractor
@Inject
constructor(
+ @Main private val resources: Resources,
private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler,
private val reduceBrightColorsController: ReduceBrightColorsController,
) : QSTileUserActionInteractor<ReduceBrightColorsTileModel> {
+ val isInUpgradeMode: Boolean = reduceBrightColorsController.isInUpgradeMode(resources)
+
override suspend fun handleInput(input: QSTileInput<ReduceBrightColorsTileModel>): Unit =
with(input) {
when (action) {
is QSTileUserAction.Click -> {
+ if (isInUpgradeMode) {
+ reduceBrightColorsController.setReduceBrightColorsFeatureAvailable(false)
+ qsTileIntentUserActionHandler.handle(
+ action.expandable,
+ Intent(Settings.ACTION_DISPLAY_SETTINGS)
+ )
+ // TODO(b/349458355): show dialog
+ return@with
+ }
reduceBrightColorsController.setReduceBrightColorsActivated(
!input.data.isEnabled
)
}
is QSTileUserAction.LongClick -> {
+ if (isInUpgradeMode) {
+ reduceBrightColorsController.setReduceBrightColorsFeatureAvailable(false)
+ qsTileIntentUserActionHandler.handle(
+ action.expandable,
+ Intent(Settings.ACTION_DISPLAY_SETTINGS)
+ )
+ // TODO(b/349458355): show dialog
+ return@with
+ }
qsTileIntentUserActionHandler.handle(
action.expandable,
Intent(Settings.ACTION_REDUCE_BRIGHT_COLORS_SETTINGS)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
index a04fa3817493..6ccd169fd509 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
@@ -19,6 +19,7 @@ package com.android.systemui.qs.ui.viewmodel
import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.panels.ui.viewmodel.EditModeViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.QuickQuickSettingsViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
import javax.inject.Inject
@@ -29,4 +30,5 @@ constructor(
val brightnessSliderViewModel: BrightnessSliderViewModel,
val tileGridViewModel: TileGridViewModel,
val editModeViewModel: EditModeViewModel,
+ val quickQuickSettingsViewModel: QuickQuickSettingsViewModel,
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
index e395d30c0c19..66fcbacb0b8a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
@@ -20,42 +20,54 @@ import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
-import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.panels.ui.viewmodel.EditModeViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
-import com.android.systemui.qs.ui.adapter.QSSceneAdapter
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.model.ShadeAlignment
import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel
import javax.inject.Inject
-import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
/** Models UI state and handles user input for the Quick Settings Shade scene. */
@SysUISingleton
class QuickSettingsShadeSceneViewModel
@Inject
constructor(
- shadeInteractor: ShadeInteractor,
+ private val shadeInteractor: ShadeInteractor,
val overlayShadeViewModel: OverlayShadeViewModel,
- val brightnessSliderViewModel: BrightnessSliderViewModel,
- val tileGridViewModel: TileGridViewModel,
- val editModeViewModel: EditModeViewModel,
- val qsSceneAdapter: QSSceneAdapter,
+ val quickSettingsContainerViewModel: QuickSettingsContainerViewModel,
+ @Application applicationScope: CoroutineScope,
) {
+
+ val isEditing: StateFlow<Boolean> = quickSettingsContainerViewModel.editModeViewModel.isEditing
+
val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
- MutableStateFlow(
- mapOf(
- if (shadeInteractor.shadeAlignment == ShadeAlignment.Top) {
- Swipe.Up
- } else {
- Swipe.Down
- } to SceneFamilies.Home,
- Back to SceneFamilies.Home,
- )
+ isEditing
+ .map { editing -> destinations(editing) }
+ .stateIn(
+ applicationScope,
+ SharingStarted.WhileSubscribed(),
+ destinations(isEditing.value)
+ )
+
+ private fun destinations(editing: Boolean): Map<UserAction, UserActionResult> {
+ return buildMap {
+ put(
+ if (shadeInteractor.shadeAlignment == ShadeAlignment.Top) {
+ Swipe.Up
+ } else {
+ Swipe.Down
+ },
+ UserActionResult(SceneFamilies.Home)
)
- .asStateFlow()
+ if (!editing) {
+ put(Back, UserActionResult(SceneFamilies.Home))
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 4b82e0f96560..371707d78500 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -26,11 +26,13 @@ import static android.view.MotionEvent.ACTION_UP;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
+import static com.android.systemui.Flags.glanceableHubBackGesture;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_AWAKE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DOZING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DREAMING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE;
@@ -70,6 +72,7 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.accessibility.AccessibilityManager;
+import android.view.inputmethod.Flags;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.NonNull;
@@ -91,11 +94,11 @@ import com.android.systemui.keyguard.KeyguardWmStateRefactor;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager;
import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationBar;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarView;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
@@ -113,7 +116,7 @@ import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
import com.android.systemui.statusbar.policy.CallbackController;
import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellInterface;
import dagger.Lazy;
@@ -300,10 +303,29 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
public void onImeSwitcherPressed() {
// TODO(b/204901476) We're intentionally using the default display for now since
// Launcher/Taskbar isn't display aware.
+ if (Flags.imeSwitcherRevamp()) {
+ mContext.getSystemService(InputMethodManager.class)
+ .onImeSwitchButtonClickFromSystem(mDisplayTracker.getDefaultDisplayId());
+ } else {
+ mContext.getSystemService(InputMethodManager.class)
+ .showInputMethodPickerFromSystem(true /* showAuxiliarySubtypes */,
+ mDisplayTracker.getDefaultDisplayId());
+ }
+ mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP);
+ }
+
+ @Override
+ public void onImeSwitcherLongPress() {
+ if (!Flags.imeSwitcherRevamp()) {
+ return;
+ }
+ // TODO(b/204901476) We're intentionally using the default display for now since
+ // Launcher/Taskbar isn't display aware.
mContext.getSystemService(InputMethodManager.class)
.showInputMethodPickerFromSystem(true /* showAuxiliarySubtypes */,
mDisplayTracker.getDefaultDisplayId());
- mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP);
+ mUiEventLogger.log(
+ KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_LONGPRESS);
}
@Override
@@ -792,7 +814,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
private void onStatusBarStateChanged(boolean keyguardShowing, boolean keyguardOccluded,
boolean keyguardGoingAway, boolean bouncerShowing, boolean isDozing,
- boolean panelExpanded, boolean isDreaming) {
+ boolean panelExpanded, boolean isDreaming, boolean communalShowing) {
mSysUiState.setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
keyguardShowing && !keyguardOccluded)
.setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
@@ -802,6 +824,8 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
.setFlag(SYSUI_STATE_BOUNCER_SHOWING, bouncerShowing)
.setFlag(SYSUI_STATE_DEVICE_DOZING, isDozing)
.setFlag(SYSUI_STATE_DEVICE_DREAMING, isDreaming)
+ .setFlag(SYSUI_STATE_COMMUNAL_HUB_SHOWING,
+ glanceableHubBackGesture() && communalShowing)
.commitUpdate(mContext.getDisplayId());
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 2b717cb32533..8d0a386bc3b0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -57,8 +57,8 @@ import com.android.systemui.CoreStartable;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.res.R;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.system.QuickStepContract;
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
index 4a4c73ba9c81..98a61df4ca55 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
@@ -74,7 +74,7 @@ constructor(
when (intent?.action) {
ACTION_START -> {
bgExecutor.execute {
- traceurMessageSender.startTracing(issueRecordingState.traceType)
+ traceurMessageSender.startTracing(issueRecordingState.traceConfig)
}
issueRecordingState.isRecording = true
if (!issueRecordingState.recordScreen) {
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingState.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingState.kt
index b077349ade74..761290071177 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingState.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingState.kt
@@ -22,7 +22,8 @@ import com.android.systemui.recordissue.RecordIssueModule.Companion.TILE_SPEC
import com.android.systemui.res.R
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
-import com.android.traceur.TraceUtils.PresetTraceType
+import com.android.traceur.PresetTraceConfigs
+import com.android.traceur.TraceConfig
import java.util.concurrent.CopyOnWriteArrayList
import javax.inject.Inject
@@ -53,8 +54,8 @@ constructor(
get() = prefs.getInt(KEY_ISSUE_TYPE_RES, ISSUE_TYPE_NOT_SET)
set(value) = prefs.edit().putInt(KEY_ISSUE_TYPE_RES, value).apply()
- val traceType: PresetTraceType
- get() = ALL_ISSUE_TYPES[issueTypeRes] ?: PresetTraceType.UNSET
+ val traceConfig: TraceConfig
+ get() = ALL_ISSUE_TYPES[issueTypeRes] ?: PresetTraceConfigs.getDefaultConfig()
private val listeners = CopyOnWriteArrayList<Runnable>()
@@ -83,12 +84,12 @@ constructor(
const val KEY_ISSUE_TYPE_RES = "key_issueTypeRes"
const val ISSUE_TYPE_NOT_SET = -1
- val ALL_ISSUE_TYPES: Map<Int, PresetTraceType> =
+ val ALL_ISSUE_TYPES: Map<Int, TraceConfig?> =
hashMapOf(
- Pair(R.string.performance, PresetTraceType.PERFORMANCE),
- Pair(R.string.user_interface, PresetTraceType.UI),
- Pair(R.string.battery, PresetTraceType.BATTERY),
- Pair(R.string.thermal, PresetTraceType.THERMAL)
+ Pair(R.string.performance, PresetTraceConfigs.getPerformanceConfig()),
+ Pair(R.string.user_interface, PresetTraceConfigs.getUiConfig()),
+ Pair(R.string.battery, PresetTraceConfigs.getBatteryConfig()),
+ Pair(R.string.thermal, PresetTraceConfigs.getThermalConfig()),
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
index bbf4e51b35e9..8a51ad4cbd71 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
@@ -87,7 +87,10 @@ constructor(
setNegativeButton(R.string.cancel) { _, _ -> }
setPositiveButton(R.string.qs_record_issue_start) { _, _ -> onStarted.run() }
}
- bgExecutor.execute { traceurMessageSender.bindToTraceur(dialog.context) }
+ bgExecutor.execute {
+ traceurMessageSender.onBoundToTraceur.add { traceurMessageSender.getTags() }
+ traceurMessageSender.bindToTraceur(dialog.context)
+ }
}
override fun createDialog(): SystemUIDialog = factory.create(this)
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt
index 51744aa47c1a..a31a9ef26b16 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt
@@ -35,7 +35,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.traceur.FileSender
import com.android.traceur.MessageConstants
-import com.android.traceur.TraceUtils.PresetTraceType
+import com.android.traceur.TraceConfig
import javax.inject.Inject
private const val TAG = "TraceurMessageSender"
@@ -45,11 +45,15 @@ class TraceurMessageSender @Inject constructor(@Background private val backgroun
private var binder: Messenger? = null
private var isBound: Boolean = false
+ val onBoundToTraceur = mutableListOf<Runnable>()
+
private val traceurConnection =
object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
binder = Messenger(service)
isBound = true
+ onBoundToTraceur.forEach(Runnable::run)
+ onBoundToTraceur.clear()
}
override fun onServiceDisconnected(className: ComponentName) {
@@ -93,9 +97,9 @@ class TraceurMessageSender @Inject constructor(@Background private val backgroun
}
@WorkerThread
- fun startTracing(traceType: PresetTraceType) {
+ fun startTracing(traceType: TraceConfig) {
val data =
- Bundle().apply { putSerializable(MessageConstants.INTENT_EXTRA_TRACE_TYPE, traceType) }
+ Bundle().apply { putParcelable(MessageConstants.INTENT_EXTRA_TRACE_TYPE, traceType) }
notifyTraceur(MessageConstants.START_WHAT, data)
}
@@ -103,11 +107,17 @@ class TraceurMessageSender @Inject constructor(@Background private val backgroun
@WorkerThread
fun shareTraces(context: Context, screenRecord: Uri?) {
- val replyHandler = Messenger(TraceurMessageHandler(context, screenRecord, backgroundLooper))
+ val replyHandler = Messenger(ShareFilesHandler(context, screenRecord, backgroundLooper))
notifyTraceur(MessageConstants.SHARE_WHAT, replyTo = replyHandler)
}
@WorkerThread
+ fun getTags() {
+ val replyHandler = Messenger(TagsHandler(backgroundLooper))
+ notifyTraceur(MessageConstants.TAGS_WHAT, replyTo = replyHandler)
+ }
+
+ @WorkerThread
private fun notifyTraceur(what: Int, data: Bundle = Bundle(), replyTo: Messenger? = null) {
try {
binder!!.send(
@@ -122,7 +132,7 @@ class TraceurMessageSender @Inject constructor(@Background private val backgroun
}
}
- private class TraceurMessageHandler(
+ private class ShareFilesHandler(
private val context: Context,
private val screenRecord: Uri?,
looper: Looper,
@@ -154,4 +164,29 @@ class TraceurMessageSender @Inject constructor(@Background private val backgroun
context.startActivity(fileSharingIntent)
}
}
+
+ private class TagsHandler(looper: Looper) : Handler(looper) {
+
+ override fun handleMessage(msg: Message) {
+ if (MessageConstants.TAGS_WHAT == msg.what) {
+ val keys = msg.data.getStringArrayList(MessageConstants.BUNDLE_KEY_TAGS)
+ val values =
+ msg.data.getStringArrayList(MessageConstants.BUNDLE_KEY_TAG_DESCRIPTIONS)
+ if (keys == null || values == null) {
+ throw IllegalArgumentException(
+ "Neither keys: $keys, nor values: $values can " + "be null"
+ )
+ }
+
+ val tags = keys.zip(values).map { "${it.first}: ${it.second}" }.toSet()
+ Log.e(
+ TAG,
+ "These tags: $tags will be saved and used for the Custom Trace" +
+ " Config dialog in a future CL. This log will be removed."
+ )
+ } else {
+ throw IllegalArgumentException("received unknown msg.what: " + msg.what)
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
index 233e9b5bf818..2d510e1cb659 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
@@ -43,8 +43,14 @@ constructor(
sceneInteractor: SceneInteractor,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
) {
- /** Whether a show-when-locked activity is at the top of the current activity stack. */
- private val isOccludingActivityShown: StateFlow<Boolean> =
+ /**
+ * Whether a show-when-locked activity is at the top of the current activity stack.
+ *
+ * Note: this isn't enough to figure out whether the scene container UI should be invisible as
+ * that also depends on the things like the state of AOD and the current scene. If the code
+ * needs that, [invisibleDueToOcclusion] should be collected instead.
+ */
+ val isOccludingActivityShown: StateFlow<Boolean> =
keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
@@ -69,6 +75,9 @@ constructor(
/**
* Whether the scene container should become invisible due to "occlusion" by an in-foreground
* "show when locked" activity.
+ *
+ * Note: this returns `false` when an overlaid scene (like shade or QS) is shown above the
+ * occluding activity.
*/
val invisibleDueToOcclusion: StateFlow<Boolean> =
combine(
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index ef011945b5c8..5885193aa017 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -28,6 +28,7 @@ import com.android.systemui.scene.domain.resolver.SceneResolver
import com.android.systemui.scene.shared.logger.SceneLogger
import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.util.kotlin.getValue
import com.android.systemui.util.kotlin.pairwiseBy
import dagger.Lazy
import javax.inject.Inject
@@ -60,8 +61,8 @@ constructor(
private val repository: SceneContainerRepository,
private val logger: SceneLogger,
private val sceneFamilyResolvers: Lazy<Map<SceneKey, @JvmSuppressWildcards SceneResolver>>,
- private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
- private val keyguardEnabledInteractor: KeyguardEnabledInteractor,
+ private val deviceUnlockedInteractor: Lazy<DeviceUnlockedInteractor>,
+ private val keyguardEnabledInteractor: Lazy<KeyguardEnabledInteractor>,
) {
interface OnSceneAboutToChangeListener {
@@ -387,8 +388,8 @@ constructor(
val isChangeAllowed =
to != Scenes.Gone ||
inMidTransitionFromGone ||
- deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked ||
- !keyguardEnabledInteractor.isKeyguardEnabled.value
+ deviceUnlockedInteractor.get().deviceUnlockStatus.value.isUnlocked ||
+ !keyguardEnabledInteractor.get().isKeyguardEnabled.value
check(isChangeAllowed) {
"Cannot change to the Gone scene while the device is locked and not currently" +
" transitioning from Gone. Current transition state is ${transitionState.value}." +
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 1f4820aa8de6..8711e8878525 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
@@ -665,7 +665,7 @@ constructor(
keyguardEnabledInteractor.isKeyguardEnabled
.sample(
combine(
- deviceEntryInteractor.isInLockdown,
+ deviceUnlockedInteractor.isInLockdown,
deviceEntryInteractor.isDeviceEntered,
::Pair,
)
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
index 3dc207063060..46c586163ce8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
@@ -27,7 +27,6 @@ import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Process;
import android.os.UserHandle;
-import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -60,8 +59,6 @@ import javax.inject.Inject;
@SysUISingleton
public class RecordingController
implements CallbackController<RecordingController.RecordingStateChangeCallback> {
- private static final String TAG = "RecordingController";
-
private boolean mIsStarting;
private boolean mIsRecording;
private PendingIntent mStopIntent;
@@ -71,6 +68,7 @@ public class RecordingController
private final BroadcastDispatcher mBroadcastDispatcher;
private final FeatureFlags mFlags;
private final UserTracker mUserTracker;
+ private final RecordingControllerLogger mRecordingControllerLogger;
private final MediaProjectionMetricsLogger mMediaProjectionMetricsLogger;
private final ScreenCaptureDisabledDialogDelegate mScreenCaptureDisabledDialogDelegate;
private final ScreenRecordDialogDelegate.Factory mScreenRecordDialogFactory;
@@ -102,9 +100,10 @@ public class RecordingController
if (intent != null && INTENT_UPDATE_STATE.equals(intent.getAction())) {
if (intent.hasExtra(EXTRA_STATE)) {
boolean state = intent.getBooleanExtra(EXTRA_STATE, false);
+ mRecordingControllerLogger.logIntentStateUpdated(state);
updateState(state);
} else {
- Log.e(TAG, "Received update intent with no state");
+ mRecordingControllerLogger.logIntentMissingState();
}
}
}
@@ -120,6 +119,7 @@ public class RecordingController
FeatureFlags flags,
Lazy<ScreenCaptureDevicePolicyResolver> devicePolicyResolver,
UserTracker userTracker,
+ RecordingControllerLogger recordingControllerLogger,
MediaProjectionMetricsLogger mediaProjectionMetricsLogger,
ScreenCaptureDisabledDialogDelegate screenCaptureDisabledDialogDelegate,
ScreenRecordDialogDelegate.Factory screenRecordDialogFactory,
@@ -130,6 +130,7 @@ public class RecordingController
mDevicePolicyResolver = devicePolicyResolver;
mBroadcastDispatcher = broadcastDispatcher;
mUserTracker = userTracker;
+ mRecordingControllerLogger = recordingControllerLogger;
mMediaProjectionMetricsLogger = mediaProjectionMetricsLogger;
mScreenCaptureDisabledDialogDelegate = screenCaptureDisabledDialogDelegate;
mScreenRecordDialogFactory = screenRecordDialogFactory;
@@ -212,9 +213,9 @@ public class RecordingController
IntentFilter stateFilter = new IntentFilter(INTENT_UPDATE_STATE);
mBroadcastDispatcher.registerReceiver(mStateChangeReceiver, stateFilter, null,
UserHandle.ALL);
- Log.d(TAG, "sent start intent");
+ mRecordingControllerLogger.logSentStartIntent();
} catch (PendingIntent.CanceledException e) {
- Log.e(TAG, "Pending intent was cancelled: " + e.getMessage());
+ mRecordingControllerLogger.logPendingIntentCancelled(e);
}
}
};
@@ -227,9 +228,10 @@ public class RecordingController
*/
public void cancelCountdown() {
if (mCountDownTimer != null) {
+ mRecordingControllerLogger.logCountdownCancelled();
mCountDownTimer.cancel();
} else {
- Log.e(TAG, "Timer was null");
+ mRecordingControllerLogger.logCountdownCancelErrorNoTimer();
}
mIsStarting = false;
@@ -260,13 +262,14 @@ public class RecordingController
public void stopRecording() {
try {
if (mStopIntent != null) {
+ mRecordingControllerLogger.logRecordingStopped();
mStopIntent.send(mInteractiveBroadcastOption);
} else {
- Log.e(TAG, "Stop intent was null");
+ mRecordingControllerLogger.logRecordingStopErrorNoStopIntent();
}
updateState(false);
} catch (PendingIntent.CanceledException e) {
- Log.e(TAG, "Error stopping: " + e.getMessage());
+ mRecordingControllerLogger.logRecordingStopError(e);
}
}
@@ -275,6 +278,7 @@ public class RecordingController
* @param isRecording
*/
public synchronized void updateState(boolean isRecording) {
+ mRecordingControllerLogger.logStateUpdated(isRecording);
if (!isRecording && mIsRecording) {
// Unregister receivers if we have stopped recording
mUserTracker.removeCallback(mUserChangedCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingControllerLog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingControllerLog.kt
new file mode 100644
index 000000000000..dd2baef35bd5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingControllerLog.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.screenrecord
+
+import javax.inject.Qualifier
+
+/**
+ * Logs for screen record events. See [com.android.systemui.screenrecord.RecordingController] and
+ * [com.android.systemui.screenrecord.RecordingControllerLogger].
+ */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class RecordingControllerLog
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingControllerLogger.kt
new file mode 100644
index 000000000000..e16c010f32b4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingControllerLogger.kt
@@ -0,0 +1,77 @@
+/*
+ * 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.screenrecord
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import javax.inject.Inject
+
+/** Helper class for logging events to [RecordingControllerLog] from Java. */
+@SysUISingleton
+class RecordingControllerLogger
+@Inject
+constructor(
+ @RecordingControllerLog private val logger: LogBuffer,
+) {
+ fun logStateUpdated(isRecording: Boolean) =
+ logger.log(
+ TAG,
+ LogLevel.DEBUG,
+ { bool1 = isRecording },
+ { "Updating state. isRecording=$bool1" },
+ )
+
+ fun logIntentStateUpdated(isRecording: Boolean) =
+ logger.log(
+ TAG,
+ LogLevel.DEBUG,
+ { bool1 = isRecording },
+ { "Update intent has state. isRecording=$bool1" },
+ )
+
+ fun logIntentMissingState() =
+ logger.log(TAG, LogLevel.ERROR, {}, { "Received update intent with no state" })
+
+ fun logSentStartIntent() = logger.log(TAG, LogLevel.DEBUG, {}, { "Sent start intent" })
+
+ fun logPendingIntentCancelled(e: Exception) =
+ logger.log(TAG, LogLevel.ERROR, {}, { "Pending intent was cancelled" }, e)
+
+ fun logCountdownCancelled() =
+ logger.log(TAG, LogLevel.DEBUG, {}, { "Record countdown cancelled" })
+
+ fun logCountdownCancelErrorNoTimer() =
+ logger.log(TAG, LogLevel.ERROR, {}, { "Couldn't cancel countdown because timer was null" })
+
+ fun logRecordingStopped() = logger.log(TAG, LogLevel.DEBUG, {}, { "Stopping recording" })
+
+ fun logRecordingStopErrorNoStopIntent() =
+ logger.log(
+ TAG,
+ LogLevel.ERROR,
+ {},
+ { "Couldn't stop recording because stop intent was null" },
+ )
+
+ fun logRecordingStopError(e: Exception) =
+ logger.log(TAG, LogLevel.DEBUG, {}, { "Couldn't stop recording" }, e)
+
+ companion object {
+ private const val TAG = "RecordingController"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
index d7ddc507da82..a830e1bbfe72 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
@@ -16,6 +16,9 @@
package com.android.systemui.screenrecord
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogBufferFactory
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -53,7 +56,7 @@ interface ScreenRecordModule {
@IntoMap
@StringKey(SCREEN_RECORD_TILE_SPEC)
fun provideScreenRecordAvailabilityInteractor(
- impl: ScreenRecordTileDataInteractor
+ impl: ScreenRecordTileDataInteractor
): QSTileAvailabilityInteractor
companion object {
@@ -89,5 +92,12 @@ interface ScreenRecordModule {
stateInteractor,
mapper,
)
+
+ @Provides
+ @SysUISingleton
+ @RecordingControllerLog
+ fun provideRecordingControllerLogBuffer(factory: LogBufferFactory): LogBuffer {
+ return factory.create("RecordingControllerLog", 50)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionExecutor.kt
index 1868b4a29f20..54e0319da58f 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionExecutor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionExecutor.kt
@@ -40,7 +40,7 @@ constructor(
private val intentExecutor: ActionIntentExecutor,
@Application private val applicationScope: CoroutineScope,
@Assisted val window: Window,
- @Assisted val viewProxy: ScreenshotViewProxy,
+ @Assisted val viewProxy: ScreenshotShelfViewProxy,
@Assisted val finishDismiss: () -> Unit,
) {
@@ -109,7 +109,7 @@ constructor(
interface Factory {
fun create(
window: Window,
- viewProxy: ScreenshotViewProxy,
+ viewProxy: ScreenshotShelfViewProxy,
finishDismiss: (() -> Unit)
): ActionExecutor
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt
deleted file mode 100644
index 3d024a6a8ccf..000000000000
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt
+++ /dev/null
@@ -1,242 +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.screenshot
-
-import android.animation.Animator
-import android.app.Notification
-import android.content.Context
-import android.graphics.Bitmap
-import android.graphics.Rect
-import android.util.Log
-import android.view.KeyEvent
-import android.view.LayoutInflater
-import android.view.ScrollCaptureResponse
-import android.view.View
-import android.view.ViewTreeObserver
-import android.view.WindowInsets
-import android.window.OnBackInvokedCallback
-import android.window.OnBackInvokedDispatcher
-import androidx.appcompat.content.res.AppCompatResources
-import com.android.internal.logging.UiEventLogger
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.res.R
-import com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS
-import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER
-import com.android.systemui.screenshot.scroll.ScrollCaptureController
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
-
-/**
- * Legacy implementation of screenshot view methods. Just proxies the calls down into the original
- * ScreenshotView.
- */
-class LegacyScreenshotViewProxy
-@AssistedInject
-constructor(
- private val logger: UiEventLogger,
- flags: FeatureFlags,
- @Assisted private val context: Context,
- @Assisted private val displayId: Int
-) : ScreenshotViewProxy {
- override val view: ScreenshotView =
- LayoutInflater.from(context).inflate(R.layout.screenshot, null) as ScreenshotView
- override val screenshotPreview: View
- override var packageName: String = ""
- set(value) {
- field = value
- view.setPackageName(value)
- }
- override var callbacks: ScreenshotView.ScreenshotViewCallback? = null
- set(value) {
- field = value
- view.setCallbacks(value)
- }
- override var screenshot: ScreenshotData? = null
- set(value) {
- field = value
- value?.let {
- val badgeBg =
- AppCompatResources.getDrawable(context, R.drawable.overlay_badge_background)
- val user = it.userHandle
- if (badgeBg != null && user != null) {
- view.badgeScreenshot(context.packageManager.getUserBadgedIcon(badgeBg, user))
- }
- view.setScreenshot(it)
- }
- }
-
- override val isAttachedToWindow
- get() = view.isAttachedToWindow
- override val isDismissing
- get() = view.isDismissing
- override val isPendingSharedTransition
- get() = view.isPendingSharedTransition
-
- init {
- view.setUiEventLogger(logger)
- view.setDefaultDisplay(displayId)
- view.setFlags(flags)
- addPredictiveBackListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) }
- setOnKeyListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) }
- if (LogConfig.DEBUG_WINDOW) {
- Log.d(TAG, "adding OnComputeInternalInsetsListener")
- }
- view.viewTreeObserver.addOnComputeInternalInsetsListener(view)
- screenshotPreview = view.screenshotPreview
- }
-
- override fun reset() = view.reset()
- override fun updateInsets(insets: WindowInsets) = view.updateInsets(insets)
- override fun updateOrientation(insets: WindowInsets) = view.updateOrientation(insets)
-
- override fun createScreenshotDropInAnimation(screenRect: Rect, showFlash: Boolean): Animator =
- view.createScreenshotDropInAnimation(screenRect, showFlash)
-
- override fun addQuickShareChip(quickShareAction: Notification.Action) =
- view.addQuickShareChip(quickShareAction)
-
- override fun setChipIntents(imageData: ScreenshotController.SavedImageData) =
- view.setChipIntents(imageData)
-
- override fun requestDismissal(event: ScreenshotEvent?) {
- if (DEBUG_DISMISS) {
- Log.d(TAG, "screenshot dismissal requested")
- }
- // If we're already animating out, don't restart the animation
- if (view.isDismissing) {
- if (DEBUG_DISMISS) {
- Log.v(TAG, "Already dismissing, ignoring duplicate command $event")
- }
- return
- }
- event?.let { logger.log(event, 0, packageName) }
- view.animateDismissal()
- }
-
- override fun showScrollChip(packageName: String, onClick: Runnable) =
- view.showScrollChip(packageName, onClick)
-
- override fun hideScrollChip() = view.hideScrollChip()
-
- override fun prepareScrollingTransition(
- response: ScrollCaptureResponse,
- screenBitmap: Bitmap,
- newScreenshot: Bitmap,
- screenshotTakenInPortrait: Boolean,
- onTransitionPrepared: Runnable,
- ) {
- view.prepareScrollingTransition(
- response,
- screenBitmap,
- newScreenshot,
- screenshotTakenInPortrait
- )
- view.post { onTransitionPrepared.run() }
- }
-
- override fun startLongScreenshotTransition(
- transitionDestination: Rect,
- onTransitionEnd: Runnable,
- longScreenshot: ScrollCaptureController.LongScreenshot
- ) = view.startLongScreenshotTransition(transitionDestination, onTransitionEnd, longScreenshot)
-
- override fun restoreNonScrollingUi() = view.restoreNonScrollingUi()
-
- override fun fadeForSharedTransition() {} // unused
-
- override fun stopInputListening() = view.stopInputListening()
-
- override fun requestFocus() {
- view.requestFocus()
- }
-
- override fun announceForAccessibility(string: String) = view.announceForAccessibility(string)
-
- override fun prepareEntranceAnimation(runnable: Runnable) {
- view.viewTreeObserver.addOnPreDrawListener(
- object : ViewTreeObserver.OnPreDrawListener {
- override fun onPreDraw(): Boolean {
- if (LogConfig.DEBUG_WINDOW) {
- Log.d(TAG, "onPreDraw: startAnimation")
- }
- view.viewTreeObserver.removeOnPreDrawListener(this)
- runnable.run()
- return true
- }
- }
- )
- }
-
- private fun addPredictiveBackListener(onDismissRequested: (ScreenshotEvent) -> Unit) {
- val onBackInvokedCallback = OnBackInvokedCallback {
- if (LogConfig.DEBUG_INPUT) {
- Log.d(TAG, "Predictive Back callback dispatched")
- }
- onDismissRequested.invoke(SCREENSHOT_DISMISSED_OTHER)
- }
- view.addOnAttachStateChangeListener(
- object : View.OnAttachStateChangeListener {
- override fun onViewAttachedToWindow(v: View) {
- if (LogConfig.DEBUG_INPUT) {
- Log.d(TAG, "Registering Predictive Back callback")
- }
- view
- .findOnBackInvokedDispatcher()
- ?.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT,
- onBackInvokedCallback
- )
- }
-
- override fun onViewDetachedFromWindow(view: View) {
- if (LogConfig.DEBUG_INPUT) {
- Log.d(TAG, "Unregistering Predictive Back callback")
- }
- view
- .findOnBackInvokedDispatcher()
- ?.unregisterOnBackInvokedCallback(onBackInvokedCallback)
- }
- }
- )
- }
- private fun setOnKeyListener(onDismissRequested: (ScreenshotEvent) -> Unit) {
- view.setOnKeyListener(
- object : View.OnKeyListener {
- override fun onKey(view: View, keyCode: Int, event: KeyEvent): Boolean {
- if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
- if (LogConfig.DEBUG_INPUT) {
- Log.d(TAG, "onKeyEvent: $keyCode")
- }
- onDismissRequested.invoke(SCREENSHOT_DISMISSED_OTHER)
- return true
- }
- return false
- }
- }
- )
- }
-
- @AssistedFactory
- interface Factory : ScreenshotViewProxy.Factory {
- override fun getProxy(context: Context, displayId: Int): LegacyScreenshotViewProxy
- }
-
- companion object {
- private const val TAG = "LegacyScreenshotViewProxy"
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt
index 596046268984..474afa8bcb9d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt
@@ -137,7 +137,7 @@ constructor(
val offset = container.height + params.topMargin + params.bottomMargin
val anim = if (animateIn) ValueAnimator.ofFloat(0f, 1f) else ValueAnimator.ofFloat(1f, 0f)
with(anim) {
- duration = ScreenshotView.SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS
+ duration = MESSAGE_EXPANSION_DURATION_MS
interpolator = AccelerateDecelerateInterpolator()
addUpdateListener { valueAnimator: ValueAnimator ->
val interpolation = valueAnimator.animatedValue as Float
@@ -147,4 +147,8 @@ constructor(
}
return anim
}
+
+ companion object {
+ const val MESSAGE_EXPANSION_DURATION_MS: Long = 400
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index c87b1f526957..773900981759 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -20,7 +20,7 @@ import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
import static com.android.systemui.Flags.screenshotPrivateProfileAccessibilityAnnouncementFix;
-import static com.android.systemui.Flags.screenshotShelfUi2;
+import static com.android.systemui.Flags.screenshotSaveImageExporter;
import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM;
import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
import static com.android.systemui.screenshot.LogConfig.DEBUG_INPUT;
@@ -191,7 +191,7 @@ public class ScreenshotController implements ScreenshotHandler {
private final WindowContext mContext;
private final FeatureFlags mFlags;
- private final ScreenshotViewProxy mViewProxy;
+ private final ScreenshotShelfViewProxy mViewProxy;
private final ScreenshotNotificationsController mNotificationsController;
private final ScreenshotSmartActions mScreenshotSmartActions;
private final UiEventLogger mUiEventLogger;
@@ -231,13 +231,6 @@ public class ScreenshotController implements ScreenshotHandler {
private String mPackageName = "";
private final BroadcastReceiver mCopyBroadcastReceiver;
- // When false, the screenshot is taken without showing the ui. Note that this only applies to
- // external displays, as on the default one the UI should **always** be shown.
- // This is needed in case of screenshot during display mirroring, as adding another window to
- // the external display makes mirroring stop.
- // When there is a way to distinguish between displays that are mirroring or extending, this
- // can be removed and we can directly show the ui only in the extended case.
- private final Boolean mShowUIOnExternalDisplay;
/** Tracks config changes that require re-creating UI */
private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
ActivityInfo.CONFIG_ORIENTATION
@@ -253,7 +246,7 @@ public class ScreenshotController implements ScreenshotHandler {
Context context,
WindowManager windowManager,
FeatureFlags flags,
- ScreenshotViewProxy.Factory viewProxyFactory,
+ ScreenshotShelfViewProxy.Factory viewProxyFactory,
ScreenshotSmartActions screenshotSmartActions,
ScreenshotNotificationsController.Factory screenshotNotificationsControllerFactory,
UiEventLogger uiEventLogger,
@@ -273,8 +266,7 @@ public class ScreenshotController implements ScreenshotHandler {
MessageContainerController messageContainerController,
Provider<ScreenshotSoundController> screenshotSoundController,
AnnouncementResolver announcementResolver,
- @Assisted Display display,
- @Assisted boolean showUIOnExternalDisplay
+ @Assisted Display display
) {
mScreenshotSmartActions = screenshotSmartActions;
mNotificationsController = screenshotNotificationsControllerFactory.create(
@@ -348,7 +340,6 @@ public class ScreenshotController implements ScreenshotHandler {
mBroadcastDispatcher.registerReceiver(mCopyBroadcastReceiver, new IntentFilter(
ClipboardOverlayController.COPY_OVERLAY_ACTION), null, null,
Context.RECEIVER_NOT_EXPORTED, ClipboardOverlayController.SELF_PERMISSION);
- mShowUIOnExternalDisplay = showUIOnExternalDisplay;
}
@Override
@@ -382,7 +373,7 @@ public class ScreenshotController implements ScreenshotHandler {
Log.w(TAG, "User setup not complete, displaying toast only");
// User setup isn't complete, so we don't want to show any UI beyond a toast, as editing
// and sharing shouldn't be exposed to the user.
- saveScreenshotAndToast(screenshot.getUserHandle(), finisher);
+ saveScreenshotAndToast(screenshot, finisher);
return;
}
@@ -398,31 +389,23 @@ public class ScreenshotController implements ScreenshotHandler {
prepareViewForNewScreenshot(screenshot, oldPackageName);
- if (!shouldShowUi()) {
- saveScreenshotInWorkerThread(
- screenshot.getUserHandle(), finisher, this::logSuccessOnActionsReady,
- (ignored) -> {
- });
- return;
- }
-
final UUID requestId;
- if (screenshotShelfUi2()) {
- requestId = mActionsController.setCurrentScreenshot(screenshot);
- saveScreenshotInBackground(screenshot, requestId, finisher);
-
- if (screenshot.getTaskId() >= 0) {
- mAssistContentRequester.requestAssistContent(
- screenshot.getTaskId(),
- assistContent ->
- mActionsController.onAssistContent(requestId, assistContent));
- } else {
- mActionsController.onAssistContent(requestId, null);
+ requestId = mActionsController.setCurrentScreenshot(screenshot);
+ saveScreenshotInBackground(screenshot, requestId, finisher, result -> {
+ if (result.uri != null) {
+ ScreenshotSavedResult savedScreenshot = new ScreenshotSavedResult(
+ result.uri, screenshot.getUserOrDefault(), result.timestamp);
+ mActionsController.setCompletedScreenshot(requestId, savedScreenshot);
}
+ });
+
+ if (screenshot.getTaskId() >= 0) {
+ mAssistContentRequester.requestAssistContent(
+ screenshot.getTaskId(),
+ assistContent ->
+ mActionsController.onAssistContent(requestId, assistContent));
} else {
- requestId = UUID.randomUUID(); // passed through but unused for legacy UI
- saveScreenshotInWorkerThread(screenshot.getUserHandle(), finisher,
- this::showUiOnActionsReady, this::showUiOnQuickShareActionReady);
+ mActionsController.onAssistContent(requestId, null);
}
// The window is focusable by default
@@ -458,13 +441,6 @@ public class ScreenshotController implements ScreenshotHandler {
// ignore system bar insets for the purpose of window layout
mWindow.getDecorView().setOnApplyWindowInsetsListener(
(v, insets) -> WindowInsets.CONSUMED);
- if (!screenshotShelfUi2()) {
- mScreenshotHandler.cancelTimeout(); // restarted after animation
- }
- }
-
- private boolean shouldShowUi() {
- return mDisplay.getDisplayId() == Display.DEFAULT_DISPLAY || mShowUIOnExternalDisplay;
}
void prepareViewForNewScreenshot(@NonNull ScreenshotData screenshot, String oldPackageName) {
@@ -501,9 +477,6 @@ public class ScreenshotController implements ScreenshotHandler {
}
mViewProxy.setPackageName(mPackageName);
-
- mViewProxy.updateOrientation(
- mWindowManager.getCurrentWindowMetrics().getWindowInsets());
}
/**
@@ -515,11 +488,7 @@ public class ScreenshotController implements ScreenshotHandler {
}
boolean isPendingSharedTransition() {
- if (screenshotShelfUi2()) {
- return mActionExecutor.isPendingSharedTransition();
- } else {
- return mViewProxy.isPendingSharedTransition();
- }
+ return mActionExecutor.isPendingSharedTransition();
}
// Any cleanup needed when the service is being destroyed.
@@ -556,7 +525,7 @@ public class ScreenshotController implements ScreenshotHandler {
}
mMessageContainerController.setView(mViewProxy.getView());
- mViewProxy.setCallbacks(new ScreenshotView.ScreenshotViewCallback() {
+ mViewProxy.setCallbacks(new ScreenshotShelfViewProxy.ScreenshotViewCallback() {
@Override
public void onUserInteraction() {
if (DEBUG_INPUT) {
@@ -566,13 +535,6 @@ public class ScreenshotController implements ScreenshotHandler {
}
@Override
- public void onAction(Intent intent, UserHandle owner, boolean overrideTransition) {
- Pair<ActivityOptions, ExitTransitionCoordinator> exit = createWindowTransition();
- mActionIntentExecutor.launchIntentAsync(
- intent, owner, overrideTransition, exit.first, exit.second);
- }
-
- @Override
public void onDismiss() {
finishDismiss();
}
@@ -603,11 +565,7 @@ public class ScreenshotController implements ScreenshotHandler {
if (mConfigChanges.applyNewConfig(mContext.getResources())) {
// Hide the scroll chip until we know it's available in this
// orientation
- if (screenshotShelfUi2()) {
- mActionsController.onScrollChipInvalidated();
- } else {
- mViewProxy.hideScrollChip();
- }
+ mActionsController.onScrollChipInvalidated();
// Delay scroll capture eval a bit to allow the underlying activity
// to set up in the new orientation.
mScreenshotHandler.postDelayed(
@@ -640,13 +598,8 @@ public class ScreenshotController implements ScreenshotHandler {
(response) -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_IMPRESSION,
0, response.getPackageName());
- if (screenshotShelfUi2()) {
- mActionsController.onScrollChipReady(requestId,
- () -> onScrollButtonClicked(owner, response));
- } else {
- mViewProxy.showScrollChip(response.getPackageName(),
- () -> onScrollButtonClicked(owner, response));
- }
+ mActionsController.onScrollChipReady(requestId,
+ () -> onScrollButtonClicked(owner, response));
return Unit.INSTANCE;
}
);
@@ -715,11 +668,9 @@ public class ScreenshotController implements ScreenshotHandler {
mWindowManager.addView(decorView, mWindowLayoutParams);
decorView.requestApplyInsets();
- if (screenshotShelfUi2()) {
- ViewGroup layout = decorView.requireViewById(android.R.id.content);
- layout.setClipChildren(false);
- layout.setClipToPadding(false);
- }
+ ViewGroup layout = decorView.requireViewById(android.R.id.content);
+ layout.setClipChildren(false);
+ layout.setClipToPadding(false);
}
void removeWindow() {
@@ -749,29 +700,40 @@ public class ScreenshotController implements ScreenshotHandler {
* Save the bitmap but don't show the normal screenshot UI.. just a toast (or notification on
* failure).
*/
- private void saveScreenshotAndToast(UserHandle owner, Consumer<Uri> finisher) {
+ private void saveScreenshotAndToast(ScreenshotData screenshot, Consumer<Uri> finisher) {
// Play the shutter sound to notify that we've taken a screenshot
playCameraSoundIfNeeded();
- saveScreenshotInWorkerThread(
- owner,
- /* onComplete */ finisher,
- /* actionsReadyListener */ imageData -> {
- if (DEBUG_CALLBACK) {
- Log.d(TAG, "returning URI to finisher (Consumer<URI>): " + imageData.uri);
- }
- finisher.accept(imageData.uri);
- if (imageData.uri == null) {
- mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_NOT_SAVED, 0, mPackageName);
- mNotificationsController.notifyScreenshotError(
- R.string.screenshot_failed_to_save_text);
- } else {
- mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SAVED, 0, mPackageName);
- mScreenshotHandler.post(() -> Toast.makeText(mContext,
- R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show());
- }
- },
- null);
+ if (screenshotSaveImageExporter()) {
+ saveScreenshotInBackground(screenshot, UUID.randomUUID(), finisher, result -> {
+ if (result.uri != null) {
+ mScreenshotHandler.post(() -> Toast.makeText(mContext,
+ R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show());
+ }
+ });
+ } else {
+ saveScreenshotInWorkerThread(
+ screenshot.getUserHandle(),
+ /* onComplete */ finisher,
+ /* actionsReadyListener */ imageData -> {
+ if (DEBUG_CALLBACK) {
+ Log.d(TAG,
+ "returning URI to finisher (Consumer<URI>): " + imageData.uri);
+ }
+ finisher.accept(imageData.uri);
+ if (imageData.uri == null) {
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_NOT_SAVED, 0,
+ mPackageName);
+ mNotificationsController.notifyScreenshotError(
+ R.string.screenshot_failed_to_save_text);
+ } else {
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SAVED, 0, mPackageName);
+ mScreenshotHandler.post(() -> Toast.makeText(mContext,
+ R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show());
+ }
+ },
+ null);
+ }
}
/**
@@ -844,8 +806,8 @@ public class ScreenshotController implements ScreenshotHandler {
mScreenshotHandler.cancelTimeout();
}
- private void saveScreenshotInBackground(
- ScreenshotData screenshot, UUID requestId, Consumer<Uri> finisher) {
+ private void saveScreenshotInBackground(ScreenshotData screenshot, UUID requestId,
+ Consumer<Uri> finisher, Consumer<ImageExporter.Result> onResult) {
ListenableFuture<ImageExporter.Result> future = mImageExporter.export(mBgExecutor,
requestId, screenshot.getBitmap(), screenshot.getUserOrDefault(),
mDisplay.getDisplayId());
@@ -854,10 +816,7 @@ public class ScreenshotController implements ScreenshotHandler {
ImageExporter.Result result = future.get();
Log.d(TAG, "Saved screenshot: " + result);
logScreenshotResultStatus(result.uri, screenshot.getUserHandle());
- if (result.uri != null) {
- mActionsController.setCompletedScreenshot(requestId, new ScreenshotSavedResult(
- result.uri, screenshot.getUserOrDefault(), result.timestamp));
- }
+ onResult.accept(result);
if (DEBUG_CALLBACK) {
Log.d(TAG, "finished background processing, Calling (Consumer<Uri>) "
+ "finisher.accept(\"" + result.uri + "\"");
@@ -902,62 +861,6 @@ public class ScreenshotController implements ScreenshotHandler {
mSaveInBgTask.execute();
}
-
- /**
- * Sets up the action shade and its entrance animation, once we get the screenshot URI.
- */
- private void showUiOnActionsReady(ScreenshotController.SavedImageData imageData) {
- logSuccessOnActionsReady(imageData);
- mScreenshotHandler.resetTimeout();
-
- if (imageData.uri != null) {
- if (DEBUG_UI) {
- Log.d(TAG, "Showing UI actions");
- }
- if (!imageData.owner.equals(Process.myUserHandle())) {
- Log.d(TAG, "Screenshot saved to user " + imageData.owner + " as "
- + imageData.uri);
- }
- mScreenshotHandler.post(() -> {
- if (mScreenshotAnimation != null && mScreenshotAnimation.isRunning()) {
- mScreenshotAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mViewProxy.setChipIntents(imageData);
- }
- });
- } else {
- mViewProxy.setChipIntents(imageData);
- }
- });
- }
- }
-
- /**
- * Sets up the action shade and its entrance animation, once we get the Quick Share action data.
- */
- private void showUiOnQuickShareActionReady(ScreenshotController.QuickShareData quickShareData) {
- if (DEBUG_UI) {
- Log.d(TAG, "Showing UI for Quick Share action");
- }
- if (quickShareData.quickShareAction != null) {
- mScreenshotHandler.post(() -> {
- if (mScreenshotAnimation != null && mScreenshotAnimation.isRunning()) {
- mScreenshotAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mViewProxy.addQuickShareChip(quickShareData.quickShareAction);
- }
- });
- } else {
- mViewProxy.addQuickShareChip(quickShareData.quickShareAction);
- }
- });
- }
- }
-
/**
* Logs success/failure of the screenshot saving task, and shows an error if it failed.
*/
@@ -1053,9 +956,7 @@ public class ScreenshotController implements ScreenshotHandler {
* Creates an instance of the controller for that specific display.
*
* @param display display to capture
- * @param showUIOnExternalDisplay Whether the UI should be shown if this is an external
- * display.
*/
- ScreenshotController create(Display display, boolean showUIOnExternalDisplay);
+ ScreenshotController create(Display display);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
index 1b5fa345ebb4..50215af30ad4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
@@ -18,7 +18,6 @@ package com.android.systemui.screenshot
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
-import android.app.Notification
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Rect
@@ -45,7 +44,6 @@ import com.android.systemui.res.R
import com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS
import com.android.systemui.screenshot.LogConfig.DEBUG_INPUT
import com.android.systemui.screenshot.LogConfig.DEBUG_WINDOW
-import com.android.systemui.screenshot.ScreenshotController.SavedImageData
import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER
import com.android.systemui.screenshot.scroll.ScrollCaptureController
import com.android.systemui.screenshot.ui.ScreenshotAnimationController
@@ -70,13 +68,23 @@ constructor(
private val thumbnailObserver: ThumbnailObserver,
@Assisted private val context: Context,
@Assisted private val displayId: Int
-) : ScreenshotViewProxy {
- override val view: ScreenshotShelfView =
+) {
+
+ interface ScreenshotViewCallback {
+ fun onUserInteraction()
+
+ fun onDismiss()
+
+ /** DOWN motion event was observed outside of the touchable areas of this view. */
+ fun onTouchOutside()
+ }
+
+ val view: ScreenshotShelfView =
LayoutInflater.from(context).inflate(R.layout.screenshot_shelf, null) as ScreenshotShelfView
- override val screenshotPreview: View
- override var packageName: String = ""
- override var callbacks: ScreenshotView.ScreenshotViewCallback? = null
- override var screenshot: ScreenshotData? = null
+ val screenshotPreview: View
+ var packageName: String = ""
+ var callbacks: ScreenshotViewCallback? = null
+ var screenshot: ScreenshotData? = null
set(value) {
value?.let {
viewModel.setScreenshotBitmap(it.bitmap)
@@ -92,10 +100,11 @@ constructor(
field = value
}
- override val isAttachedToWindow
+ val isAttachedToWindow
get() = view.isAttachedToWindow
- override var isDismissing = false
- override var isPendingSharedTransition = false
+
+ var isDismissing = false
+ var isPendingSharedTransition = false
private val animationController = ScreenshotAnimationController(view, viewModel)
private var inputMonitor: InputMonitorCompat? = null
@@ -136,17 +145,17 @@ constructor(
)
}
- override fun reset() {
+ fun reset() {
animationController.cancel()
isPendingSharedTransition = false
viewModel.reset()
}
- override fun updateInsets(insets: WindowInsets) {
+
+ fun updateInsets(insets: WindowInsets) {
view.updateInsets(insets)
}
- override fun updateOrientation(insets: WindowInsets) {}
- override fun createScreenshotDropInAnimation(screenRect: Rect, showFlash: Boolean): Animator {
+ fun createScreenshotDropInAnimation(screenRect: Rect, showFlash: Boolean): Animator {
val entrance =
animationController.getEntranceAnimation(screenRect, showFlash) {
viewModel.setAnimationState(AnimationState.ENTRANCE_REVEAL)
@@ -164,11 +173,7 @@ constructor(
return entrance
}
- override fun addQuickShareChip(quickShareAction: Notification.Action) {}
-
- override fun setChipIntents(imageData: SavedImageData) {}
-
- override fun requestDismissal(event: ScreenshotEvent?) {
+ fun requestDismissal(event: ScreenshotEvent?) {
requestDismissal(event, null)
}
@@ -187,6 +192,7 @@ constructor(
override fun onAnimationStart(animator: Animator) {
isDismissing = true
}
+
override fun onAnimationEnd(animator: Animator) {
isDismissing = false
callbacks?.onDismiss()
@@ -196,11 +202,7 @@ constructor(
animator.start()
}
- override fun showScrollChip(packageName: String, onClick: Runnable) {}
-
- override fun hideScrollChip() {}
-
- override fun prepareScrollingTransition(
+ fun prepareScrollingTransition(
response: ScrollCaptureResponse,
screenBitmap: Bitmap, // unused
newScreenshot: Bitmap,
@@ -228,7 +230,7 @@ constructor(
return r
}
- override fun startLongScreenshotTransition(
+ fun startLongScreenshotTransition(
transitionDestination: Rect,
onTransitionEnd: Runnable,
longScreenshot: ScrollCaptureController.LongScreenshot,
@@ -243,27 +245,27 @@ constructor(
transitionAnimation.start()
}
- override fun restoreNonScrollingUi() {
+ fun restoreNonScrollingUi() {
viewModel.setScrollableRect(null)
viewModel.setScrollingScrimBitmap(null)
animationController.restoreUI()
callbacks?.onUserInteraction() // reset the timeout
}
- override fun stopInputListening() {
+ fun stopInputListening() {
inputMonitor?.dispose()
inputMonitor = null
inputEventReceiver?.dispose()
inputEventReceiver = null
}
- override fun requestFocus() {
+ fun requestFocus() {
view.requestFocus()
}
- override fun announceForAccessibility(string: String) = view.announceForAccessibility(string)
+ fun announceForAccessibility(string: String) = view.announceForAccessibility(string)
- override fun prepareEntranceAnimation(runnable: Runnable) {
+ fun prepareEntranceAnimation(runnable: Runnable) {
view.viewTreeObserver.addOnPreDrawListener(
object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
@@ -276,7 +278,7 @@ constructor(
)
}
- override fun fadeForSharedTransition() {
+ fun fadeForSharedTransition() {
animationController.fadeForSharedTransition()
}
@@ -349,7 +351,7 @@ constructor(
}
@AssistedFactory
- interface Factory : ScreenshotViewProxy.Factory {
- override fun getProxy(context: Context, displayId: Int): ScreenshotShelfViewProxy
+ interface Factory {
+ fun getProxy(context: Context, displayId: Int): ScreenshotShelfViewProxy
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
deleted file mode 100644
index 59e38a836258..000000000000
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ /dev/null
@@ -1,1126 +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.screenshot;
-
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
-
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_TAKE_SCREENSHOT;
-import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM;
-import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS;
-import static com.android.systemui.screenshot.LogConfig.DEBUG_INPUT;
-import static com.android.systemui.screenshot.LogConfig.DEBUG_SCROLL;
-import static com.android.systemui.screenshot.LogConfig.DEBUG_UI;
-import static com.android.systemui.screenshot.LogConfig.DEBUG_WINDOW;
-import static com.android.systemui.screenshot.LogConfig.logTag;
-import static com.android.systemui.screenshot.ScreenshotController.SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS;
-
-import static java.util.Objects.requireNonNull;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ValueAnimator;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.app.BroadcastOptions;
-import android.app.Notification;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BlendMode;
-import android.graphics.Color;
-import android.graphics.Insets;
-import android.graphics.Matrix;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
-import android.graphics.drawable.InsetDrawable;
-import android.graphics.drawable.LayerDrawable;
-import android.os.Bundle;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.MathUtils;
-import android.view.Choreographer;
-import android.view.Display;
-import android.view.DisplayCutout;
-import android.view.GestureDetector;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.ScrollCaptureResponse;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-import android.view.WindowMetrics;
-import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.widget.FrameLayout;
-import android.widget.HorizontalScrollView;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-import androidx.constraintlayout.widget.ConstraintLayout;
-
-import com.android.internal.jank.InteractionJankMonitor;
-import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.res.R;
-import com.android.systemui.screenshot.scroll.ScrollCaptureController;
-import com.android.systemui.shared.system.InputChannelCompat;
-import com.android.systemui.shared.system.InputMonitorCompat;
-import com.android.systemui.shared.system.QuickStepContract;
-
-import java.util.ArrayList;
-
-/**
- * Handles the visual elements and animations for the screenshot flow.
- */
-public class ScreenshotView extends FrameLayout implements
- ViewTreeObserver.OnComputeInternalInsetsListener {
-
- public interface ScreenshotViewCallback {
- void onUserInteraction();
-
- void onAction(Intent intent, UserHandle owner, boolean overrideTransition);
-
- void onDismiss();
-
- /** DOWN motion event was observed outside of the touchable areas of this view. */
- void onTouchOutside();
- }
-
- private static final String TAG = logTag(ScreenshotView.class);
-
- private static final long SCREENSHOT_FLASH_IN_DURATION_MS = 133;
- private static final long SCREENSHOT_FLASH_OUT_DURATION_MS = 217;
- // delay before starting to fade in dismiss button
- private static final long SCREENSHOT_TO_CORNER_DISMISS_DELAY_MS = 200;
- private static final long SCREENSHOT_TO_CORNER_X_DURATION_MS = 234;
- private static final long SCREENSHOT_TO_CORNER_Y_DURATION_MS = 500;
- private static final long SCREENSHOT_TO_CORNER_SCALE_DURATION_MS = 234;
- public static final long SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS = 400;
- private static final long SCREENSHOT_ACTIONS_ALPHA_DURATION_MS = 100;
- private static final float SCREENSHOT_ACTIONS_START_SCALE_X = .7f;
-
- private final Resources mResources;
- private final Interpolator mFastOutSlowIn;
- private final DisplayMetrics mDisplayMetrics;
- private final float mFixedSize;
- private final AccessibilityManager mAccessibilityManager;
- private final GestureDetector mSwipeDetector;
-
- private int mDefaultDisplay = Display.DEFAULT_DISPLAY;
- private int mNavMode;
- private boolean mOrientationPortrait;
- private boolean mDirectionLTR;
-
- private ImageView mScrollingScrim;
- private DraggableConstraintLayout mScreenshotStatic;
- private ImageView mScreenshotPreview;
- private ImageView mScreenshotBadge;
- private View mScreenshotPreviewBorder;
- private ImageView mScrollablePreview;
- private ImageView mScreenshotFlash;
- private ImageView mActionsContainerBackground;
- private HorizontalScrollView mActionsContainer;
- private LinearLayout mActionsView;
- private FrameLayout mDismissButton;
- private OverlayActionChip mShareChip;
- private OverlayActionChip mEditChip;
- private OverlayActionChip mScrollChip;
- private OverlayActionChip mQuickShareChip;
-
- private UiEventLogger mUiEventLogger;
- private ScreenshotViewCallback mCallbacks;
- private boolean mPendingSharedTransition;
- private InputMonitorCompat mInputMonitor;
- private InputChannelCompat.InputEventReceiver mInputEventReceiver;
- private boolean mShowScrollablePreview;
- private String mPackageName = "";
-
- private final ArrayList<OverlayActionChip> mSmartChips = new ArrayList<>();
- private PendingInteraction mPendingInteraction;
- // Should only be set/used if the SCREENSHOT_METADATA flag is set.
- private ScreenshotData mScreenshotData;
-
- private final InteractionJankMonitor mInteractionJankMonitor;
- private FeatureFlags mFlags;
- private final Bundle mInteractiveBroadcastOption;
-
- private enum PendingInteraction {
- PREVIEW,
- EDIT,
- SHARE,
- QUICK_SHARE
- }
-
- public ScreenshotView(Context context) {
- this(context, null);
- }
-
- public ScreenshotView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public ScreenshotView(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public ScreenshotView(
- Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- mResources = mContext.getResources();
- mInteractionJankMonitor = getInteractionJankMonitorInstance();
-
- BroadcastOptions options = BroadcastOptions.makeBasic();
- options.setInteractive(true);
- mInteractiveBroadcastOption = options.toBundle();
-
- mFixedSize = mResources.getDimensionPixelSize(R.dimen.overlay_x_scale);
-
- // standard material ease
- mFastOutSlowIn =
- AnimationUtils.loadInterpolator(mContext, android.R.interpolator.fast_out_slow_in);
-
- mDisplayMetrics = new DisplayMetrics();
- mContext.getDisplay().getRealMetrics(mDisplayMetrics);
-
- mAccessibilityManager = AccessibilityManager.getInstance(mContext);
-
- mSwipeDetector = new GestureDetector(mContext,
- new GestureDetector.SimpleOnGestureListener() {
- final Rect mActionsRect = new Rect();
-
- @Override
- public boolean onScroll(
- MotionEvent ev1, MotionEvent ev2, float distanceX, float distanceY) {
- mActionsContainer.getBoundsOnScreen(mActionsRect);
- // return true if we aren't in the actions bar, or if we are but it isn't
- // scrollable in the direction of movement
- return !mActionsRect.contains((int) ev2.getRawX(), (int) ev2.getRawY())
- || !mActionsContainer.canScrollHorizontally((int) distanceX);
- }
- });
- mSwipeDetector.setIsLongpressEnabled(false);
- addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View v) {
- startInputListening();
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- stopInputListening();
- }
- });
- }
-
- private InteractionJankMonitor getInteractionJankMonitorInstance() {
- return InteractionJankMonitor.getInstance();
- }
-
- public void hideScrollChip() {
- mScrollChip.setVisibility(View.GONE);
- }
-
- /**
- * Called to display the scroll action chip when support is detected.
- *
- * @param packageName the owning package of the window to be captured
- * @param onClick the action to take when the chip is clicked.
- */
- public void showScrollChip(String packageName, Runnable onClick) {
- if (DEBUG_SCROLL) {
- Log.d(TAG, "Showing Scroll option");
- }
- mScrollChip.setVisibility(VISIBLE);
- mScrollChip.setOnClickListener((v) -> onClick.run());
- }
-
- @Override // ViewTreeObserver.OnComputeInternalInsetsListener
- public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
- inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
- inoutInfo.touchableRegion.set(getTouchRegion(true));
- }
-
- private Region getSwipeRegion() {
- Region swipeRegion = new Region();
-
- final Rect tmpRect = new Rect();
- int swipePadding = (int) FloatingWindowUtil.dpToPx(
- mDisplayMetrics, DraggableConstraintLayout.SWIPE_PADDING_DP * -1);
- mScreenshotPreview.getBoundsOnScreen(tmpRect);
- tmpRect.inset(swipePadding, swipePadding);
- swipeRegion.op(tmpRect, Region.Op.UNION);
- mActionsContainerBackground.getBoundsOnScreen(tmpRect);
- tmpRect.inset(swipePadding, swipePadding);
- swipeRegion.op(tmpRect, Region.Op.UNION);
- mDismissButton.getBoundsOnScreen(tmpRect);
- swipeRegion.op(tmpRect, Region.Op.UNION);
-
- View messageContainer = findViewById(R.id.screenshot_message_container);
- if (messageContainer != null) {
- messageContainer.getBoundsOnScreen(tmpRect);
- swipeRegion.op(tmpRect, Region.Op.UNION);
- }
- View messageDismiss = findViewById(R.id.message_dismiss_button);
- if (messageDismiss != null) {
- messageDismiss.getBoundsOnScreen(tmpRect);
- swipeRegion.op(tmpRect, Region.Op.UNION);
- }
-
- return swipeRegion;
- }
-
- private Region getTouchRegion(boolean includeScrim) {
- Region touchRegion = getSwipeRegion();
-
- if (includeScrim && mScrollingScrim.getVisibility() == View.VISIBLE) {
- final Rect tmpRect = new Rect();
- mScrollingScrim.getBoundsOnScreen(tmpRect);
- touchRegion.op(tmpRect, Region.Op.UNION);
- }
-
- if (QuickStepContract.isGesturalMode(mNavMode)) {
- final WindowManager wm = mContext.getSystemService(WindowManager.class);
- final WindowMetrics windowMetrics = wm.getCurrentWindowMetrics();
- final Insets gestureInsets = windowMetrics.getWindowInsets().getInsets(
- WindowInsets.Type.systemGestures());
- // Receive touches in gesture insets such that they don't cause TOUCH_OUTSIDE
- Rect inset = new Rect(0, 0, gestureInsets.left, mDisplayMetrics.heightPixels);
- touchRegion.op(inset, Region.Op.UNION);
- inset.set(mDisplayMetrics.widthPixels - gestureInsets.right, 0,
- mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels);
- touchRegion.op(inset, Region.Op.UNION);
- }
- return touchRegion;
- }
-
- private void startInputListening() {
- stopInputListening();
- mInputMonitor = new InputMonitorCompat("Screenshot", mDefaultDisplay);
- mInputEventReceiver = mInputMonitor.getInputReceiver(
- Looper.getMainLooper(), Choreographer.getInstance(), ev -> {
- if (ev instanceof MotionEvent) {
- MotionEvent event = (MotionEvent) ev;
- if (event.getActionMasked() == MotionEvent.ACTION_DOWN
- && !getTouchRegion(false).contains(
- (int) event.getRawX(), (int) event.getRawY())) {
- mCallbacks.onTouchOutside();
- }
- }
- });
- }
-
- void stopInputListening() {
- if (mInputMonitor != null) {
- mInputMonitor.dispose();
- mInputMonitor = null;
- }
- if (mInputEventReceiver != null) {
- mInputEventReceiver.dispose();
- mInputEventReceiver = null;
- }
- }
-
- @Override // View
- protected void onFinishInflate() {
- super.onFinishInflate();
- mScrollingScrim = requireNonNull(findViewById(R.id.screenshot_scrolling_scrim));
- mScreenshotStatic = requireNonNull(findViewById(R.id.screenshot_static));
- mScreenshotPreview = requireNonNull(findViewById(R.id.screenshot_preview));
-
- mScreenshotPreviewBorder = requireNonNull(
- findViewById(R.id.screenshot_preview_border));
- mScreenshotPreview.setClipToOutline(true);
- mScreenshotBadge = requireNonNull(findViewById(R.id.screenshot_badge));
-
- mActionsContainerBackground = requireNonNull(findViewById(
- R.id.actions_container_background));
- mActionsContainer = requireNonNull(findViewById(R.id.actions_container));
- mActionsView = requireNonNull(findViewById(R.id.screenshot_actions));
- mDismissButton = requireNonNull(findViewById(R.id.screenshot_dismiss_button));
- mScrollablePreview = requireNonNull(findViewById(R.id.screenshot_scrollable_preview));
- mScreenshotFlash = requireNonNull(findViewById(R.id.screenshot_flash));
- mShareChip = requireNonNull(mActionsContainer.findViewById(R.id.screenshot_share_chip));
- mEditChip = requireNonNull(mActionsContainer.findViewById(R.id.screenshot_edit_chip));
- mScrollChip = requireNonNull(mActionsContainer.findViewById(R.id.screenshot_scroll_chip));
-
- setFocusable(true);
- mActionsContainer.setScrollX(0);
-
- mNavMode = getResources().getInteger(
- com.android.internal.R.integer.config_navBarInteractionMode);
- mOrientationPortrait =
- getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT;
- mDirectionLTR =
- getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
-
- // Get focus so that the key events go to the layout.
- setFocusableInTouchMode(true);
- requestFocus();
-
- mScreenshotStatic.setCallbacks(new DraggableConstraintLayout.SwipeDismissCallbacks() {
- @Override
- public void onInteraction() {
- mCallbacks.onUserInteraction();
- }
-
- @Override
- public void onSwipeDismissInitiated(Animator animator) {
- if (DEBUG_DISMISS) {
- Log.d(ScreenshotView.TAG, "dismiss triggered via swipe gesture");
- }
- mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SWIPE_DISMISSED, 0,
- mPackageName);
- }
-
- @Override
- public void onDismissComplete() {
- if (mInteractionJankMonitor.isInstrumenting(CUJ_TAKE_SCREENSHOT)) {
- mInteractionJankMonitor.end(CUJ_TAKE_SCREENSHOT);
- }
- mCallbacks.onDismiss();
- }
- });
- }
-
- View getScreenshotPreview() {
- return mScreenshotPreview;
- }
-
- void setUiEventLogger(UiEventLogger uiEventLogger) {
- mUiEventLogger = uiEventLogger;
- }
-
- void setCallbacks(ScreenshotViewCallback callbacks) {
- mCallbacks = callbacks;
- }
-
- void setFlags(FeatureFlags flags) {
- mFlags = flags;
- }
-
- void setScreenshot(Bitmap bitmap, Insets screenInsets) {
- mScreenshotPreview.setImageDrawable(createScreenDrawable(mResources, bitmap, screenInsets));
- }
-
- void setScreenshot(ScreenshotData screenshot) {
- mScreenshotData = screenshot;
- setScreenshot(screenshot.getBitmap(), screenshot.getInsets());
- mScreenshotPreview.setImageDrawable(createScreenDrawable(mResources, screenshot.getBitmap(),
- screenshot.getInsets()));
- }
-
- void setPackageName(String packageName) {
- mPackageName = packageName;
- }
-
- void setDefaultDisplay(int displayId) {
- mDefaultDisplay = displayId;
- }
-
- void updateInsets(WindowInsets insets) {
- int orientation = mContext.getResources().getConfiguration().orientation;
- mOrientationPortrait = (orientation == ORIENTATION_PORTRAIT);
- FrameLayout.LayoutParams p =
- (FrameLayout.LayoutParams) mScreenshotStatic.getLayoutParams();
- DisplayCutout cutout = insets.getDisplayCutout();
- Insets navBarInsets = insets.getInsets(WindowInsets.Type.navigationBars());
- if (cutout == null) {
- p.setMargins(0, 0, 0, navBarInsets.bottom);
- } else {
- Insets waterfall = cutout.getWaterfallInsets();
- if (mOrientationPortrait) {
- p.setMargins(
- waterfall.left,
- Math.max(cutout.getSafeInsetTop(), waterfall.top),
- waterfall.right,
- Math.max(cutout.getSafeInsetBottom(),
- Math.max(navBarInsets.bottom, waterfall.bottom)));
- } else {
- p.setMargins(
- Math.max(cutout.getSafeInsetLeft(), waterfall.left),
- waterfall.top,
- Math.max(cutout.getSafeInsetRight(), waterfall.right),
- Math.max(navBarInsets.bottom, waterfall.bottom));
- }
- }
- mScreenshotStatic.setLayoutParams(p);
- mScreenshotStatic.requestLayout();
- }
-
- void updateOrientation(WindowInsets insets) {
- int orientation = mContext.getResources().getConfiguration().orientation;
- mOrientationPortrait = (orientation == ORIENTATION_PORTRAIT);
- updateInsets(insets);
- ViewGroup.LayoutParams params = mScreenshotPreview.getLayoutParams();
- if (mOrientationPortrait) {
- params.width = (int) mFixedSize;
- params.height = LayoutParams.WRAP_CONTENT;
- mScreenshotPreview.setScaleType(ImageView.ScaleType.FIT_START);
- } else {
- params.width = LayoutParams.WRAP_CONTENT;
- params.height = (int) mFixedSize;
- mScreenshotPreview.setScaleType(ImageView.ScaleType.FIT_END);
- }
-
- mScreenshotPreview.setLayoutParams(params);
- }
-
- AnimatorSet createScreenshotDropInAnimation(Rect bounds, boolean showFlash) {
- if (DEBUG_ANIM) {
- Log.d(TAG, "createAnim: bounds=" + bounds + " showFlash=" + showFlash);
- }
-
- Rect targetPosition = new Rect();
- mScreenshotPreview.getHitRect(targetPosition);
-
- // ratio of preview width, end vs. start size
- float cornerScale =
- mFixedSize / (mOrientationPortrait ? bounds.width() : bounds.height());
- final float currentScale = 1 / cornerScale;
-
- AnimatorSet dropInAnimation = new AnimatorSet();
- ValueAnimator flashInAnimator = ValueAnimator.ofFloat(0, 1);
- flashInAnimator.setDuration(SCREENSHOT_FLASH_IN_DURATION_MS);
- flashInAnimator.setInterpolator(mFastOutSlowIn);
- flashInAnimator.addUpdateListener(animation ->
- mScreenshotFlash.setAlpha((float) animation.getAnimatedValue()));
-
- ValueAnimator flashOutAnimator = ValueAnimator.ofFloat(1, 0);
- flashOutAnimator.setDuration(SCREENSHOT_FLASH_OUT_DURATION_MS);
- flashOutAnimator.setInterpolator(mFastOutSlowIn);
- flashOutAnimator.addUpdateListener(animation ->
- mScreenshotFlash.setAlpha((float) animation.getAnimatedValue()));
-
- // animate from the current location, to the static preview location
- final PointF startPos = new PointF(bounds.centerX(), bounds.centerY());
- final PointF finalPos = new PointF(targetPosition.exactCenterX(),
- targetPosition.exactCenterY());
-
- // Shift to screen coordinates so that the animation runs on top of the entire screen,
- // including e.g. bars covering the display cutout.
- int[] locInScreen = mScreenshotPreview.getLocationOnScreen();
- startPos.offset(targetPosition.left - locInScreen[0], targetPosition.top - locInScreen[1]);
-
- if (DEBUG_ANIM) {
- Log.d(TAG, "toCorner: startPos=" + startPos);
- Log.d(TAG, "toCorner: finalPos=" + finalPos);
- }
-
- ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1);
- toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS);
-
- toCorner.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- mScreenshotPreview.setScaleX(currentScale);
- mScreenshotPreview.setScaleY(currentScale);
- mScreenshotPreview.setVisibility(View.VISIBLE);
- if (mAccessibilityManager.isEnabled()) {
- mDismissButton.setAlpha(0);
- mDismissButton.setVisibility(View.VISIBLE);
- }
- }
- });
-
- float xPositionPct =
- SCREENSHOT_TO_CORNER_X_DURATION_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS;
- float dismissPct =
- SCREENSHOT_TO_CORNER_DISMISS_DELAY_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS;
- float scalePct =
- SCREENSHOT_TO_CORNER_SCALE_DURATION_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS;
- toCorner.addUpdateListener(animation -> {
- float t = animation.getAnimatedFraction();
- if (t < scalePct) {
- float scale = MathUtils.lerp(
- currentScale, 1, mFastOutSlowIn.getInterpolation(t / scalePct));
- mScreenshotPreview.setScaleX(scale);
- mScreenshotPreview.setScaleY(scale);
- } else {
- mScreenshotPreview.setScaleX(1);
- mScreenshotPreview.setScaleY(1);
- }
-
- if (t < xPositionPct) {
- float xCenter = MathUtils.lerp(startPos.x, finalPos.x,
- mFastOutSlowIn.getInterpolation(t / xPositionPct));
- mScreenshotPreview.setX(xCenter - mScreenshotPreview.getWidth() / 2f);
- } else {
- mScreenshotPreview.setX(finalPos.x - mScreenshotPreview.getWidth() / 2f);
- }
- float yCenter = MathUtils.lerp(
- startPos.y, finalPos.y, mFastOutSlowIn.getInterpolation(t));
- mScreenshotPreview.setY(yCenter - mScreenshotPreview.getHeight() / 2f);
-
- if (t >= dismissPct) {
- mDismissButton.setAlpha((t - dismissPct) / (1 - dismissPct));
- float currentX = mScreenshotPreview.getX();
- float currentY = mScreenshotPreview.getY();
- mDismissButton.setY(currentY - mDismissButton.getHeight() / 2f);
- if (mDirectionLTR) {
- mDismissButton.setX(currentX + mScreenshotPreview.getWidth()
- - mDismissButton.getWidth() / 2f);
- } else {
- mDismissButton.setX(currentX - mDismissButton.getWidth() / 2f);
- }
- }
- });
-
- mScreenshotFlash.setAlpha(0f);
- mScreenshotFlash.setVisibility(View.VISIBLE);
-
- ValueAnimator borderFadeIn = ValueAnimator.ofFloat(0, 1);
- borderFadeIn.setDuration(100);
- borderFadeIn.addUpdateListener((animation) -> {
- float borderAlpha = animation.getAnimatedFraction();
- mScreenshotPreviewBorder.setAlpha(borderAlpha);
- mScreenshotBadge.setAlpha(borderAlpha);
- });
-
- if (showFlash) {
- dropInAnimation.play(flashOutAnimator).after(flashInAnimator);
- dropInAnimation.play(flashOutAnimator).with(toCorner);
- } else {
- dropInAnimation.play(toCorner);
- }
- dropInAnimation.play(borderFadeIn).after(toCorner);
-
- dropInAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationCancel(Animator animation) {
- mInteractionJankMonitor.cancel(CUJ_TAKE_SCREENSHOT);
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- InteractionJankMonitor.Configuration.Builder builder =
- InteractionJankMonitor.Configuration.Builder.withView(
- CUJ_TAKE_SCREENSHOT, mScreenshotPreview)
- .setTag("DropIn");
- mInteractionJankMonitor.begin(builder);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (DEBUG_ANIM) {
- Log.d(TAG, "drop-in animation ended");
- }
- mDismissButton.setOnClickListener(view -> {
- if (DEBUG_INPUT) {
- Log.d(TAG, "dismiss button clicked");
- }
- mUiEventLogger.log(
- ScreenshotEvent.SCREENSHOT_EXPLICIT_DISMISSAL, 0, mPackageName);
- animateDismissal();
- });
- mDismissButton.setAlpha(1);
- float dismissOffset = mDismissButton.getWidth() / 2f;
- float finalDismissX = mDirectionLTR
- ? finalPos.x - dismissOffset + bounds.width() * cornerScale / 2f
- : finalPos.x - dismissOffset - bounds.width() * cornerScale / 2f;
- mDismissButton.setX(finalDismissX);
- mDismissButton.setY(
- finalPos.y - dismissOffset - bounds.height() * cornerScale / 2f);
- mScreenshotPreview.setScaleX(1);
- mScreenshotPreview.setScaleY(1);
- mScreenshotPreview.setX(finalPos.x - mScreenshotPreview.getWidth() / 2f);
- mScreenshotPreview.setY(finalPos.y - mScreenshotPreview.getHeight() / 2f);
- requestLayout();
- mInteractionJankMonitor.end(CUJ_TAKE_SCREENSHOT);
- createScreenshotActionsShadeAnimation().start();
- }
- });
-
- return dropInAnimation;
- }
-
- ValueAnimator createScreenshotActionsShadeAnimation() {
- // By default the activities won't be able to start immediately; override this to keep
- // the same behavior as if started from a notification
- try {
- ActivityManager.getService().resumeAppSwitches();
- } catch (RemoteException e) {
- }
-
- ArrayList<OverlayActionChip> chips = new ArrayList<>();
-
- mShareChip.setContentDescription(mContext.getString(R.string.screenshot_share_description));
- mShareChip.setIcon(Icon.createWithResource(mContext, R.drawable.ic_screenshot_share), true);
- mShareChip.setOnClickListener(v -> {
- mShareChip.setIsPending(true);
- mEditChip.setIsPending(false);
- if (mQuickShareChip != null) {
- mQuickShareChip.setIsPending(false);
- }
- mPendingInteraction = PendingInteraction.SHARE;
- });
- chips.add(mShareChip);
-
- mEditChip.setContentDescription(
- mContext.getString(R.string.screenshot_edit_description));
- mEditChip.setIcon(Icon.createWithResource(mContext, R.drawable.ic_screenshot_edit),
- true);
- mEditChip.setOnClickListener(v -> {
- mEditChip.setIsPending(true);
- mShareChip.setIsPending(false);
- if (mQuickShareChip != null) {
- mQuickShareChip.setIsPending(false);
- }
- mPendingInteraction = PendingInteraction.EDIT;
- });
- chips.add(mEditChip);
-
- mScreenshotPreview.setOnClickListener(v -> {
- mShareChip.setIsPending(false);
- mEditChip.setIsPending(false);
- if (mQuickShareChip != null) {
- mQuickShareChip.setIsPending(false);
- }
- mPendingInteraction = PendingInteraction.PREVIEW;
- });
-
- mScrollChip.setText(mContext.getString(R.string.screenshot_scroll_label));
- mScrollChip.setIcon(Icon.createWithResource(mContext,
- R.drawable.ic_screenshot_scroll), true);
- chips.add(mScrollChip);
-
- // remove the margin from the last chip so that it's correctly aligned with the end
- LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)
- mActionsView.getChildAt(0).getLayoutParams();
- params.setMarginEnd(0);
- mActionsView.getChildAt(0).setLayoutParams(params);
-
- ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
- animator.setDuration(SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS);
- float alphaFraction = (float) SCREENSHOT_ACTIONS_ALPHA_DURATION_MS
- / SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS;
- mActionsContainer.setAlpha(0f);
- mActionsContainerBackground.setAlpha(0f);
- mActionsContainer.setVisibility(View.VISIBLE);
- mActionsContainerBackground.setVisibility(View.VISIBLE);
-
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationCancel(Animator animation) {
- mInteractionJankMonitor.cancel(CUJ_TAKE_SCREENSHOT);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- mInteractionJankMonitor.end(CUJ_TAKE_SCREENSHOT);
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- InteractionJankMonitor.Configuration.Builder builder =
- InteractionJankMonitor.Configuration.Builder.withView(
- CUJ_TAKE_SCREENSHOT, mScreenshotStatic)
- .setTag("Actions")
- .setTimeout(SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS);
- mInteractionJankMonitor.begin(builder);
- }
- });
-
- animator.addUpdateListener(animation -> {
- float t = animation.getAnimatedFraction();
- float containerAlpha = t < alphaFraction ? t / alphaFraction : 1;
- mActionsContainer.setAlpha(containerAlpha);
- mActionsContainerBackground.setAlpha(containerAlpha);
- float containerScale = SCREENSHOT_ACTIONS_START_SCALE_X
- + (t * (1 - SCREENSHOT_ACTIONS_START_SCALE_X));
- mActionsContainer.setScaleX(containerScale);
- mActionsContainerBackground.setScaleX(containerScale);
- for (OverlayActionChip chip : chips) {
- chip.setAlpha(t);
- chip.setScaleX(1 / containerScale); // invert to keep size of children constant
- }
- mActionsContainer.setScrollX(mDirectionLTR ? 0 : mActionsContainer.getWidth());
- mActionsContainer.setPivotX(mDirectionLTR ? 0 : mActionsContainer.getWidth());
- mActionsContainerBackground.setPivotX(
- mDirectionLTR ? 0 : mActionsContainerBackground.getWidth());
- });
- return animator;
- }
-
- void badgeScreenshot(@Nullable Drawable badge) {
- mScreenshotBadge.setImageDrawable(badge);
- mScreenshotBadge.setVisibility(badge != null ? View.VISIBLE : View.GONE);
- }
-
- void setChipIntents(ScreenshotController.SavedImageData imageData) {
- mShareChip.setOnClickListener(v -> {
- mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED, 0, mPackageName);
- prepareSharedTransition();
-
- Intent shareIntent = ActionIntentCreator.INSTANCE.createShareWithSubject(
- imageData.uri, imageData.subject);
- mCallbacks.onAction(shareIntent, imageData.owner, false);
-
- });
- mEditChip.setOnClickListener(v -> {
- mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED, 0, mPackageName);
- prepareSharedTransition();
- mCallbacks.onAction(
- ActionIntentCreator.INSTANCE.createEdit(imageData.uri, mContext),
- imageData.owner, true);
- });
- mScreenshotPreview.setOnClickListener(v -> {
- mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED, 0, mPackageName);
- prepareSharedTransition();
- mCallbacks.onAction(
- ActionIntentCreator.INSTANCE.createEdit(imageData.uri, mContext),
- imageData.owner, true);
- });
- if (mQuickShareChip != null) {
- if (imageData.quickShareAction != null) {
- mQuickShareChip.setPendingIntent(imageData.quickShareAction.actionIntent,
- () -> {
- mUiEventLogger.log(
- ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED, 0,
- mPackageName);
- animateDismissal();
- });
- } else {
- // hide chip and unset pending interaction if necessary, since we don't actually
- // have a useable quick share intent
- Log.wtf(TAG, "Showed quick share chip, but quick share intent was null");
- if (mPendingInteraction == PendingInteraction.QUICK_SHARE) {
- mPendingInteraction = null;
- }
- mQuickShareChip.setVisibility(GONE);
- }
- }
-
- if (mPendingInteraction != null) {
- switch (mPendingInteraction) {
- case PREVIEW:
- mScreenshotPreview.callOnClick();
- break;
- case SHARE:
- mShareChip.callOnClick();
- break;
- case EDIT:
- mEditChip.callOnClick();
- break;
- case QUICK_SHARE:
- mQuickShareChip.callOnClick();
- break;
- }
- } else {
- LayoutInflater inflater = LayoutInflater.from(mContext);
-
- for (Notification.Action smartAction : imageData.smartActions) {
- OverlayActionChip actionChip = (OverlayActionChip) inflater.inflate(
- R.layout.overlay_action_chip, mActionsView, false);
- actionChip.setText(smartAction.title);
- actionChip.setIcon(smartAction.getIcon(), false);
- actionChip.setPendingIntent(smartAction.actionIntent,
- () -> {
- mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED,
- 0, mPackageName);
- animateDismissal();
- });
- actionChip.setAlpha(1);
- mActionsView.addView(actionChip, mActionsView.getChildCount() - 1);
- mSmartChips.add(actionChip);
- }
- }
- }
-
- void addQuickShareChip(Notification.Action quickShareAction) {
- if (mQuickShareChip != null) {
- mSmartChips.remove(mQuickShareChip);
- mActionsView.removeView(mQuickShareChip);
- }
- if (mPendingInteraction == PendingInteraction.QUICK_SHARE) {
- mPendingInteraction = null;
- }
- if (mPendingInteraction == null) {
- LayoutInflater inflater = LayoutInflater.from(mContext);
- mQuickShareChip = (OverlayActionChip) inflater.inflate(
- R.layout.overlay_action_chip, mActionsView, false);
- mQuickShareChip.setText(quickShareAction.title);
- mQuickShareChip.setIcon(quickShareAction.getIcon(), false);
- mQuickShareChip.setOnClickListener(v -> {
- mShareChip.setIsPending(false);
- mEditChip.setIsPending(false);
- mQuickShareChip.setIsPending(true);
- mPendingInteraction = PendingInteraction.QUICK_SHARE;
- });
- mQuickShareChip.setAlpha(1);
- mActionsView.addView(mQuickShareChip);
- mSmartChips.add(mQuickShareChip);
- }
- }
-
- private Rect scrollableAreaOnScreen(ScrollCaptureResponse response) {
- Rect r = new Rect(response.getBoundsInWindow());
- Rect windowInScreen = response.getWindowBounds();
- r.offset(windowInScreen.left, windowInScreen.top);
- r.intersect(new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
- return r;
- }
-
- void startLongScreenshotTransition(Rect destination, Runnable onTransitionEnd,
- ScrollCaptureController.LongScreenshot longScreenshot) {
- mPendingSharedTransition = true;
- AnimatorSet animSet = new AnimatorSet();
-
- ValueAnimator scrimAnim = ValueAnimator.ofFloat(0, 1);
- scrimAnim.addUpdateListener(animation ->
- mScrollingScrim.setAlpha(1 - animation.getAnimatedFraction()));
-
- if (mShowScrollablePreview) {
- mScrollablePreview.setImageBitmap(longScreenshot.toBitmap());
- float startX = mScrollablePreview.getX();
- float startY = mScrollablePreview.getY();
- int[] locInScreen = mScrollablePreview.getLocationOnScreen();
- destination.offset((int) startX - locInScreen[0], (int) startY - locInScreen[1]);
- mScrollablePreview.setPivotX(0);
- mScrollablePreview.setPivotY(0);
- mScrollablePreview.setAlpha(1f);
- float currentScale = mScrollablePreview.getWidth() / (float) longScreenshot.getWidth();
- Matrix matrix = new Matrix();
- matrix.setScale(currentScale, currentScale);
- matrix.postTranslate(
- longScreenshot.getLeft() * currentScale,
- longScreenshot.getTop() * currentScale);
- mScrollablePreview.setImageMatrix(matrix);
- float destinationScale = destination.width() / (float) mScrollablePreview.getWidth();
-
- ValueAnimator previewAnim = ValueAnimator.ofFloat(0, 1);
- previewAnim.addUpdateListener(animation -> {
- float t = animation.getAnimatedFraction();
- float currScale = MathUtils.lerp(1, destinationScale, t);
- mScrollablePreview.setScaleX(currScale);
- mScrollablePreview.setScaleY(currScale);
- mScrollablePreview.setX(MathUtils.lerp(startX, destination.left, t));
- mScrollablePreview.setY(MathUtils.lerp(startY, destination.top, t));
- });
- ValueAnimator previewFadeAnim = ValueAnimator.ofFloat(1, 0);
- previewFadeAnim.addUpdateListener(animation ->
- mScrollablePreview.setAlpha(1 - animation.getAnimatedFraction()));
- animSet.play(previewAnim).with(scrimAnim).before(previewFadeAnim);
- previewAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- onTransitionEnd.run();
- }
- });
- } else {
- // if we switched orientations between the original screenshot and the long screenshot
- // capture, just fade out the scrim instead of running the preview animation
- animSet.play(scrimAnim);
- animSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- onTransitionEnd.run();
- }
- });
- }
- animSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mCallbacks.onDismiss();
- }
- });
- animSet.start();
- }
-
- void prepareScrollingTransition(ScrollCaptureResponse response, Bitmap screenBitmap,
- Bitmap newBitmap, boolean screenshotTakenInPortrait) {
- mShowScrollablePreview = (screenshotTakenInPortrait == mOrientationPortrait);
-
- mScrollingScrim.setImageBitmap(newBitmap);
- mScrollingScrim.setVisibility(View.VISIBLE);
-
- if (mShowScrollablePreview) {
- Rect scrollableArea = scrollableAreaOnScreen(response);
-
- float scale = mFixedSize
- / (mOrientationPortrait ? screenBitmap.getWidth() : screenBitmap.getHeight());
- ConstraintLayout.LayoutParams params =
- (ConstraintLayout.LayoutParams) mScrollablePreview.getLayoutParams();
-
- params.width = (int) (scale * scrollableArea.width());
- params.height = (int) (scale * scrollableArea.height());
- Matrix matrix = new Matrix();
- matrix.setScale(scale, scale);
- matrix.postTranslate(-scrollableArea.left * scale, -scrollableArea.top * scale);
-
- mScrollablePreview.setTranslationX(scale
- * (mDirectionLTR ? scrollableArea.left : scrollableArea.right - getWidth()));
- mScrollablePreview.setTranslationY(scale * scrollableArea.top);
- mScrollablePreview.setImageMatrix(matrix);
- mScrollablePreview.setImageBitmap(screenBitmap);
- mScrollablePreview.setVisibility(View.VISIBLE);
- }
- mDismissButton.setVisibility(View.GONE);
- mActionsContainer.setVisibility(View.GONE);
- // set these invisible, but not gone, so that the views are laid out correctly
- mActionsContainerBackground.setVisibility(View.INVISIBLE);
- mScreenshotPreviewBorder.setVisibility(View.INVISIBLE);
- mScreenshotPreview.setVisibility(View.INVISIBLE);
- mScrollingScrim.setImageTintBlendMode(BlendMode.SRC_ATOP);
- ValueAnimator anim = ValueAnimator.ofFloat(0, .3f);
- anim.addUpdateListener(animation -> mScrollingScrim.setImageTintList(
- ColorStateList.valueOf(Color.argb((float) animation.getAnimatedValue(), 0, 0, 0))));
- anim.setDuration(200);
- anim.start();
- }
-
- void restoreNonScrollingUi() {
- mScrollChip.setVisibility(View.GONE);
- mScrollablePreview.setVisibility(View.GONE);
- mScrollingScrim.setVisibility(View.GONE);
-
- if (mAccessibilityManager.isEnabled()) {
- mDismissButton.setVisibility(View.VISIBLE);
- }
- mActionsContainer.setVisibility(View.VISIBLE);
- mActionsContainerBackground.setVisibility(View.VISIBLE);
- mScreenshotPreviewBorder.setVisibility(View.VISIBLE);
- mScreenshotPreview.setVisibility(View.VISIBLE);
- // reset the timeout
- mCallbacks.onUserInteraction();
- }
-
- boolean isDismissing() {
- return mScreenshotStatic.isDismissing();
- }
-
- boolean isPendingSharedTransition() {
- return mPendingSharedTransition;
- }
-
- void animateDismissal() {
- mScreenshotStatic.dismiss();
- }
-
- void reset() {
- if (DEBUG_UI) {
- Log.d(TAG, "reset screenshot view");
- }
- mScreenshotStatic.cancelDismissal();
- if (DEBUG_WINDOW) {
- Log.d(TAG, "removing OnComputeInternalInsetsListener");
- }
- // Make sure we clean up the view tree observer
- getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
- // Clear any references to the bitmap
- mScreenshotPreview.setImageDrawable(null);
- mScreenshotPreview.setVisibility(View.INVISIBLE);
- mScreenshotPreview.setAlpha(1f);
- mScreenshotPreviewBorder.setAlpha(0);
- mScreenshotBadge.setAlpha(0f);
- mScreenshotBadge.setVisibility(View.GONE);
- mScreenshotBadge.setImageDrawable(null);
- mPendingSharedTransition = false;
- mActionsContainerBackground.setVisibility(View.INVISIBLE);
- mActionsContainer.setVisibility(View.GONE);
- mDismissButton.setVisibility(View.GONE);
- mScrollingScrim.setVisibility(View.GONE);
- mScrollablePreview.setVisibility(View.GONE);
- mScreenshotStatic.setTranslationX(0);
- mScreenshotPreview.setContentDescription(
- mContext.getResources().getString(R.string.screenshot_preview_description));
- mScreenshotPreview.setOnClickListener(null);
- mShareChip.setOnClickListener(null);
- mScrollingScrim.setVisibility(View.GONE);
- mEditChip.setOnClickListener(null);
- mShareChip.setIsPending(false);
- mEditChip.setIsPending(false);
- mPendingInteraction = null;
- for (OverlayActionChip chip : mSmartChips) {
- mActionsView.removeView(chip);
- }
- mSmartChips.clear();
- mQuickShareChip = null;
- setAlpha(1);
- mScreenshotStatic.setAlpha(1);
- mScreenshotData = null;
- }
-
- private void prepareSharedTransition() {
- mPendingSharedTransition = true;
- // fade out non-preview UI
- createScreenshotFadeDismissAnimation().start();
- }
-
- ValueAnimator createScreenshotFadeDismissAnimation() {
- ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1);
- alphaAnim.addUpdateListener(animation -> {
- float alpha = 1 - animation.getAnimatedFraction();
- mDismissButton.setAlpha(alpha);
- mActionsContainerBackground.setAlpha(alpha);
- mActionsContainer.setAlpha(alpha);
- mScreenshotPreviewBorder.setAlpha(alpha);
- mScreenshotBadge.setAlpha(alpha);
- });
- alphaAnim.setDuration(600);
- return alphaAnim;
- }
-
- /**
- * Create a drawable using the size of the bitmap and insets as the fractional inset parameters.
- */
- private static Drawable createScreenDrawable(Resources res, Bitmap bitmap, Insets insets) {
- int insettedWidth = bitmap.getWidth() - insets.left - insets.right;
- int insettedHeight = bitmap.getHeight() - insets.top - insets.bottom;
-
- BitmapDrawable bitmapDrawable = new BitmapDrawable(res, bitmap);
- if (insettedHeight == 0 || insettedWidth == 0 || bitmap.getWidth() == 0
- || bitmap.getHeight() == 0) {
- Log.e(TAG, "Can't create inset drawable, using 0 insets bitmap and insets create "
- + "degenerate region: " + bitmap.getWidth() + "x" + bitmap.getHeight() + " "
- + bitmapDrawable);
- return bitmapDrawable;
- }
-
- InsetDrawable insetDrawable = new InsetDrawable(bitmapDrawable,
- -1f * insets.left / insettedWidth,
- -1f * insets.top / insettedHeight,
- -1f * insets.right / insettedWidth,
- -1f * insets.bottom / insettedHeight);
-
- if (insets.left < 0 || insets.top < 0 || insets.right < 0 || insets.bottom < 0) {
- // Are any of the insets negative, meaning the bitmap is smaller than the bounds so need
- // to fill in the background of the drawable.
- return new LayerDrawable(new Drawable[]{
- new ColorDrawable(Color.BLACK), insetDrawable});
- } else {
- return insetDrawable;
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt
deleted file mode 100644
index df93a5e56c22..000000000000
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt
+++ /dev/null
@@ -1,76 +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.screenshot
-
-import android.animation.Animator
-import android.app.Notification
-import android.content.Context
-import android.graphics.Bitmap
-import android.graphics.Rect
-import android.view.ScrollCaptureResponse
-import android.view.View
-import android.view.ViewGroup
-import android.view.WindowInsets
-import com.android.systemui.screenshot.scroll.ScrollCaptureController
-
-/** Abstraction of the surface between ScreenshotController and ScreenshotView */
-interface ScreenshotViewProxy {
- val view: ViewGroup
- val screenshotPreview: View
-
- var packageName: String
- var callbacks: ScreenshotView.ScreenshotViewCallback?
- var screenshot: ScreenshotData?
-
- val isAttachedToWindow: Boolean
- val isDismissing: Boolean
- val isPendingSharedTransition: Boolean
-
- fun reset()
- fun updateInsets(insets: WindowInsets)
- fun updateOrientation(insets: WindowInsets)
- fun createScreenshotDropInAnimation(screenRect: Rect, showFlash: Boolean): Animator
- fun addQuickShareChip(quickShareAction: Notification.Action)
- fun setChipIntents(imageData: ScreenshotController.SavedImageData)
- fun requestDismissal(event: ScreenshotEvent?)
-
- fun showScrollChip(packageName: String, onClick: Runnable)
- fun hideScrollChip()
- fun prepareScrollingTransition(
- response: ScrollCaptureResponse,
- screenBitmap: Bitmap,
- newScreenshot: Bitmap,
- screenshotTakenInPortrait: Boolean,
- onTransitionPrepared: Runnable,
- )
- fun startLongScreenshotTransition(
- transitionDestination: Rect,
- onTransitionEnd: Runnable,
- longScreenshot: ScrollCaptureController.LongScreenshot
- )
- fun restoreNonScrollingUi()
- fun fadeForSharedTransition()
-
- fun stopInputListening()
- fun requestFocus()
- fun announceForAccessibility(string: String)
- fun prepareEntranceAnimation(runnable: Runnable)
-
- interface Factory {
- fun getProxy(context: Context, displayId: Int): ScreenshotViewProxy
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
index 2699657847b9..07f6e85cfad8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
@@ -219,7 +219,7 @@ constructor(
}
private fun getScreenshotController(display: Display): ScreenshotController {
- val controller = screenshotController ?: screenshotControllerFactory.create(display, false)
+ val controller = screenshotController ?: screenshotControllerFactory.create(display)
screenshotController = controller
return controller
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
index c4f6cd9aac29..8feefa4eca0f 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
@@ -62,6 +62,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLogger.UiEventEnum;
import com.android.settingslib.Utils;
import com.android.systemui.Flags;
+import com.android.systemui.log.DebugLogger;
import com.android.systemui.res.R;
import com.android.systemui.screenshot.scroll.CropView;
import com.android.systemui.settings.UserTracker;
@@ -307,13 +308,16 @@ public class AppClipsActivity extends ComponentActivity {
&& mViewModel.getBacklinksLiveData().getValue() != null) {
ClipData backlinksData = mViewModel.getBacklinksLiveData().getValue().getClipData();
data.putParcelable(EXTRA_CLIP_DATA, backlinksData);
+
+ DebugLogger.INSTANCE.logcatMessage(this,
+ () -> "setResultThenFinish: sending notes app ClipData");
}
try {
mResultReceiver.send(Activity.RESULT_OK, data);
logUiEvent(SCREENSHOT_FOR_NOTE_ACCEPTED);
} catch (Exception e) {
- Log.e(TAG, "Error while returning data to trampoline activity", e);
+ Log.e(TAG, "Error while sending data to trampoline activity", e);
}
// Nullify the ResultReceiver before finishing to avoid resending the result.
@@ -354,6 +358,7 @@ public class AppClipsActivity extends ComponentActivity {
}
} catch (Exception e) {
// Do nothing.
+ Log.e(TAG, "Error while sending trampoline activity error code: " + errorCode, e);
}
// Nullify the ResultReceiver to avoid resending the result.
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
index 0161f787b459..ef18fbe6db8b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
@@ -53,6 +53,7 @@ import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.qualifiers.Application;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.log.DebugLogger;
import com.android.systemui.notetask.NoteTaskController;
import com.android.systemui.notetask.NoteTaskEntryPoint;
import com.android.systemui.res.R;
@@ -265,11 +266,15 @@ public class AppClipsTrampolineActivity extends Activity {
if (statusCode == CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
Uri uri = resultData.getParcelable(EXTRA_SCREENSHOT_URI, Uri.class);
convertedData.setData(uri);
- }
- if (resultData.containsKey(EXTRA_CLIP_DATA)) {
- ClipData backlinksData = resultData.getParcelable(EXTRA_CLIP_DATA, ClipData.class);
- convertedData.setClipData(backlinksData);
+ if (resultData.containsKey(EXTRA_CLIP_DATA)) {
+ ClipData backlinksData = resultData.getParcelable(EXTRA_CLIP_DATA,
+ ClipData.class);
+ convertedData.setClipData(backlinksData);
+
+ DebugLogger.INSTANCE.logcatMessage(this,
+ () -> "onReceiveResult: sending notes app ClipData");
+ }
}
// Broadcast no longer required, setting it to null.
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
index d30d518f5777..bd9e295b58f8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
@@ -33,6 +33,7 @@ import android.content.ClipData;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.HardwareRenderer;
import android.graphics.RecordingCanvas;
@@ -54,6 +55,7 @@ import androidx.lifecycle.ViewModelProvider;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.log.DebugLogger;
import com.android.systemui.screenshot.AssistContentRequester;
import com.android.systemui.screenshot.ImageExporter;
@@ -143,6 +145,7 @@ final class AppClipsViewModel extends ViewModel {
* @param displayId id of the display to query tasks for Backlinks data
*/
void triggerBacklinks(Set<Integer> taskIdsToIgnore, int displayId) {
+ DebugLogger.INSTANCE.logcatMessage(this, () -> "Backlinks triggered");
mBgExecutor.execute(() -> {
ListenableFuture<InternalBacklinksData> backlinksData = getBacklinksData(
taskIdsToIgnore, displayId);
@@ -247,6 +250,10 @@ final class AppClipsViewModel extends ViewModel {
}
private boolean shouldIncludeTask(RootTaskInfo taskInfo, Set<Integer> taskIdsToIgnore) {
+ DebugLogger.INSTANCE.logcatMessage(this,
+ () -> String.format("shouldIncludeTask taskId %d; topActivity %s", taskInfo.taskId,
+ taskInfo.topActivity));
+
// Only consider tasks that shouldn't be ignored, are visible, running, and have a launcher
// icon. Furthermore, types such as launcher/home/dock/assistant are ignored.
return !taskIdsToIgnore.contains(taskInfo.taskId)
@@ -261,12 +268,18 @@ final class AppClipsViewModel extends ViewModel {
}
private boolean canAppStartThroughLauncher(String packageName) {
+ // Use Intent.resolveActivity API to check if the intent resolves as that is what Android
+ // uses internally when apps use Context.startActivity.
return getMainLauncherIntentForPackage(packageName).resolveActivity(mPackageManager)
!= null;
}
private ListenableFuture<InternalBacklinksData> getBacklinksDataForTaskId(
RootTaskInfo taskInfo) {
+ DebugLogger.INSTANCE.logcatMessage(this,
+ () -> String.format("getBacklinksDataForTaskId for taskId %d; topActivity %s",
+ taskInfo.taskId, taskInfo.topActivity));
+
SettableFuture<InternalBacklinksData> backlinksData = SettableFuture.create();
int taskId = taskInfo.taskId;
mAssistContentRequester.requestAssistContent(taskId, assistContent ->
@@ -295,6 +308,10 @@ final class AppClipsViewModel extends ViewModel {
*/
private InternalBacklinksData getBacklinksDataFromAssistContent(RootTaskInfo taskInfo,
@Nullable AssistContent content) {
+ DebugLogger.INSTANCE.logcatMessage(this,
+ () -> String.format("getBacklinksDataFromAssistContent taskId %d; topActivity %s",
+ taskInfo.taskId, taskInfo.topActivity));
+
String appName = getAppNameOfTask(taskInfo);
String packageName = taskInfo.topActivity.getPackageName();
Drawable appIcon = taskInfo.topActivityInfo.loadIcon(mPackageManager);
@@ -307,22 +324,34 @@ final class AppClipsViewModel extends ViewModel {
// First preference is given to app provided uri.
if (content.isAppProvidedWebUri()) {
+ DebugLogger.INSTANCE.logcatMessage(this,
+ () -> "getBacklinksDataFromAssistContent: app has provided a uri");
+
Uri uri = content.getWebUri();
Intent backlinksIntent = new Intent(ACTION_VIEW).setData(uri);
if (doesIntentResolveToSamePackage(backlinksIntent, packageName)) {
+ DebugLogger.INSTANCE.logcatMessage(this,
+ () -> "getBacklinksDataFromAssistContent: using app provided uri");
return new InternalBacklinksData(ClipData.newRawUri(appName, uri), appIcon);
}
}
// Second preference is given to app provided, hopefully deep-linking, intent.
if (content.isAppProvidedIntent()) {
+ DebugLogger.INSTANCE.logcatMessage(this,
+ () -> "getBacklinksDataFromAssistContent: app has provided an intent");
+
Intent backlinksIntent = content.getIntent();
if (doesIntentResolveToSamePackage(backlinksIntent, packageName)) {
+ DebugLogger.INSTANCE.logcatMessage(this,
+ () -> "getBacklinksDataFromAssistContent: using app provided intent");
return new InternalBacklinksData(ClipData.newIntent(appName, backlinksIntent),
appIcon);
}
}
+ DebugLogger.INSTANCE.logcatMessage(this,
+ () -> "getBacklinksDataFromAssistContent: using fallback");
return fallback;
}
@@ -340,10 +369,19 @@ final class AppClipsViewModel extends ViewModel {
return taskInfo.topActivityInfo.loadLabel(mPackageManager).toString();
}
- private Intent getMainLauncherIntentForPackage(String packageName) {
- return new Intent(ACTION_MAIN)
- .addCategory(CATEGORY_LAUNCHER)
- .setPackage(packageName);
+ private Intent getMainLauncherIntentForPackage(String pkgName) {
+ Intent intent = new Intent(ACTION_MAIN).addCategory(CATEGORY_LAUNCHER).setPackage(pkgName);
+
+ // Not all apps use DEFAULT_CATEGORY for their main launcher activity so the exact component
+ // needs to be queried and set on the Intent in order for note-taking apps to be able to
+ // start this intent. When starting an activity with an implicit intent, Android adds the
+ // DEFAULT_CATEGORY flag otherwise it fails to resolve the intent.
+ ResolveInfo resolvedActivity = mPackageManager.resolveActivity(intent, /* flags= */ 0);
+ if (resolvedActivity != null) {
+ intent.setComponent(resolvedActivity.getComponentInfo().getComponentName());
+ }
+
+ return intent;
}
/** Helper factory to help with injecting {@link AppClipsViewModel}. */
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java b/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
index 8235325fffad..682f848bfaad 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
@@ -16,23 +16,18 @@
package com.android.systemui.screenshot.dagger;
-import static com.android.systemui.Flags.screenshotShelfUi2;
-
import android.app.Service;
import android.view.accessibility.AccessibilityManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.screenshot.ImageCapture;
import com.android.systemui.screenshot.ImageCaptureImpl;
-import com.android.systemui.screenshot.LegacyScreenshotViewProxy;
import com.android.systemui.screenshot.ScreenshotPolicy;
import com.android.systemui.screenshot.ScreenshotPolicyImpl;
-import com.android.systemui.screenshot.ScreenshotShelfViewProxy;
import com.android.systemui.screenshot.ScreenshotSoundController;
import com.android.systemui.screenshot.ScreenshotSoundControllerImpl;
import com.android.systemui.screenshot.ScreenshotSoundProvider;
import com.android.systemui.screenshot.ScreenshotSoundProviderImpl;
-import com.android.systemui.screenshot.ScreenshotViewProxy;
import com.android.systemui.screenshot.TakeScreenshotExecutor;
import com.android.systemui.screenshot.TakeScreenshotExecutorImpl;
import com.android.systemui.screenshot.TakeScreenshotService;
@@ -95,15 +90,4 @@ public abstract class ScreenshotModule {
AccessibilityManager accessibilityManager) {
return new ScreenshotViewModel(accessibilityManager);
}
-
- @Provides
- static ScreenshotViewProxy.Factory providesScreenshotViewProxyFactory(
- ScreenshotShelfViewProxy.Factory shelfScreenshotViewProxyFactory,
- LegacyScreenshotViewProxy.Factory legacyScreenshotViewProxyFactory) {
- if (screenshotShelfUi2()) {
- return shelfScreenshotViewProxyFactory;
- } else {
- return legacyScreenshotViewProxyFactory;
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
index 498107624f9b..8e539499cb14 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
@@ -137,14 +137,24 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig
public void startObserving() {
if (!mObserving) {
mObserving = true;
- mSecureSettings.registerContentObserverForUserSync(
- BRIGHTNESS_MODE_URI,
- false, this, UserHandle.USER_ALL);
+ if (Flags.registerContentObserversAsync()) {
+ mSecureSettings.registerContentObserverForUserAsync(
+ BRIGHTNESS_MODE_URI,
+ false, this, UserHandle.USER_ALL);
+ } else {
+ mSecureSettings.registerContentObserverForUserSync(
+ BRIGHTNESS_MODE_URI,
+ false, this, UserHandle.USER_ALL);
+ }
}
}
public void stopObserving() {
- mSecureSettings.unregisterContentObserverSync(this);
+ if (Flags.registerContentObserversAsync()) {
+ mSecureSettings.unregisterContentObserverAsync(this);
+ } else {
+ mSecureSettings.unregisterContentObserverSync(this);
+ }
mObserving = false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 59c1592c1485..d870fe69463d 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -17,6 +17,7 @@
package com.android.systemui.shade
import android.content.Context
+import android.graphics.Insets
import android.graphics.Rect
import android.os.PowerManager
import android.os.SystemClock
@@ -25,6 +26,7 @@ import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
+import android.view.WindowInsets
import android.widget.FrameLayout
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.OnBackPressedDispatcherOwner
@@ -37,6 +39,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.compose.theme.PlatformTheme
import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.Flags.glanceableHubBackGesture
import com.android.systemui.ambient.touch.TouchMonitor
import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent
import com.android.systemui.communal.dagger.Communal
@@ -47,8 +50,6 @@ import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.util.CommunalColors
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
-import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -150,8 +151,6 @@ constructor(
/**
* True if either the primary or alternate bouncer are open, meaning the hub should not receive
* any touch input.
- *
- * Tracks [KeyguardTransitionInteractor.isFinishedInState] for [KeyguardState.isBouncerState].
*/
private var anyBouncerShowing = false
@@ -263,15 +262,33 @@ constructor(
// Run when the touch handling lifecycle is RESUMED, meaning the hub is visible and not
// occluded.
lifecycleRegistry.repeatOnLifecycle(Lifecycle.State.RESUMED) {
- val exclusionRect =
- Rect(
- 0,
- topEdgeSwipeRegionWidth,
- containerView.right,
- containerView.bottom - bottomEdgeSwipeRegionWidth
- )
+ // Avoid adding exclusion to right/left edges to allow back gestures.
+ val insets =
+ if (glanceableHubBackGesture()) {
+ containerView.rootWindowInsets.getInsets(WindowInsets.Type.systemGestures())
+ } else {
+ Insets.NONE
+ }
- containerView.systemGestureExclusionRects = listOf(exclusionRect)
+ containerView.systemGestureExclusionRects =
+ listOf(
+ // Only allow swipe up to bouncer and swipe down to shade in the very
+ // top/bottom to avoid conflicting with widgets in the hub grid.
+ Rect(
+ insets.left,
+ topEdgeSwipeRegionWidth,
+ containerView.right - insets.right,
+ containerView.bottom - bottomEdgeSwipeRegionWidth
+ ),
+ // Disable back gestures on the left side of the screen, to avoid
+ // conflicting with scene transitions.
+ Rect(
+ 0,
+ 0,
+ insets.right,
+ containerView.bottom,
+ )
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 6b4e44fed0cd..c1caeed05cb6 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -158,8 +158,8 @@ import com.android.systemui.media.controls.ui.controller.KeyguardMediaController
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.FalsingManager.FalsingTapListener;
@@ -1774,8 +1774,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
// the small clock here
// With migrateClocksToBlueprint, weather clock will have behaviors similar to other clocks
if (!MigrateClocksToBlueprint.isEnabled()) {
+ boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
if (mKeyguardStatusViewController.isLargeClockBlockingNotificationShelf()
- && hasVisibleNotifications() && isOnAod()) {
+ && hasVisibleNotifications() && (isOnAod() || bypassEnabled)) {
return SMALL;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index f67d0c185e0f..bc5cf2a87925 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -644,7 +644,8 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
mCurrentState.bouncerShowing,
mCurrentState.dozing,
mCurrentState.shadeOrQsExpanded,
- mCurrentState.dreaming);
+ mCurrentState.dreaming,
+ mCurrentState.communalVisible);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
index 4d43ad52019a..a4fed873362b 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
@@ -19,8 +19,6 @@ import android.content.Context
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.res.R
-import com.android.systemui.shade.shared.flag.DualShade
-import com.android.systemui.shade.shared.model.ShadeMode
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -105,18 +103,26 @@ interface ShadeRepository {
@Deprecated("Use ShadeInteractor.isQsBypassingShade instead")
val legacyExpandImmediate: StateFlow<Boolean>
- val shadeMode: StateFlow<ShadeMode>
-
/** Whether dual shade should be aligned to the bottom (true) or to the top (false). */
val isDualShadeAlignedToBottom: Boolean
+ /**
+ * Whether the shade layout should be wide (true) or narrow (false).
+ *
+ * In a wide layout, notifications and quick settings each take up only half the screen width
+ * (whether they are shown at the same time or not). In a narrow layout, they can each be as
+ * wide as the entire screen.
+ */
+ val isShadeLayoutWide: StateFlow<Boolean>
+
/** True when QS is taking up the entire screen, i.e. fully expanded on a non-unfolded phone. */
@Deprecated("Use ShadeInteractor instead") val legacyQsFullscreen: StateFlow<Boolean>
/** NPVC.mClosing as a flow. */
@Deprecated("Use ShadeAnimationInteractor instead") val legacyIsClosing: StateFlow<Boolean>
- fun setShadeMode(mode: ShadeMode)
+ /** Sets whether the shade layout should be wide (true) or narrow (false). */
+ fun setShadeLayoutWide(isShadeLayoutWide: Boolean)
/** Sets whether a closing animation is happening. */
@Deprecated("Use ShadeAnimationInteractor instead") fun setLegacyIsClosing(isClosing: Boolean)
@@ -183,6 +189,7 @@ interface ShadeRepository {
class ShadeRepositoryImpl @Inject constructor(@Application applicationContext: Context) :
ShadeRepository {
private val _qsExpansion = MutableStateFlow(0f)
+ @Deprecated("Use ShadeInteractor.qsExpansion instead")
override val qsExpansion: StateFlow<Float> = _qsExpansion.asStateFlow()
private val _lockscreenShadeExpansion = MutableStateFlow(0f)
@@ -204,6 +211,7 @@ class ShadeRepositoryImpl @Inject constructor(@Application applicationContext: C
@Deprecated("Use ShadeInteractor instead")
override val legacyShadeTracking: StateFlow<Boolean> = _legacyShadeTracking.asStateFlow()
+ @Deprecated("Use ShadeInteractor.isUserInteractingWithShade instead")
override val legacyLockscreenShadeTracking = MutableStateFlow(false)
private val _legacyQsTracking = MutableStateFlow(false)
@@ -227,20 +235,22 @@ class ShadeRepositoryImpl @Inject constructor(@Application applicationContext: C
@Deprecated("Use ShadeInteractor instead")
override val legacyQsFullscreen: StateFlow<Boolean> = _legacyQsFullscreen.asStateFlow()
- val _shadeMode = MutableStateFlow(if (DualShade.isEnabled) ShadeMode.Dual else ShadeMode.Single)
- override val shadeMode: StateFlow<ShadeMode> = _shadeMode.asStateFlow()
+ private val _isShadeLayoutWide = MutableStateFlow(false)
+ override val isShadeLayoutWide: StateFlow<Boolean> = _isShadeLayoutWide.asStateFlow()
override val isDualShadeAlignedToBottom =
applicationContext.resources.getBoolean(R.bool.config_dualShadeAlignedToBottom)
- override fun setShadeMode(shadeMode: ShadeMode) {
- _shadeMode.value = shadeMode
+ override fun setShadeLayoutWide(isShadeLayoutWide: Boolean) {
+ _isShadeLayoutWide.value = isShadeLayoutWide
}
+ @Deprecated("Use ShadeInteractor instead")
override fun setLegacyQsFullscreen(legacyQsFullscreen: Boolean) {
_legacyQsFullscreen.value = legacyQsFullscreen
}
+ @Deprecated("Use ShadeInteractor instead")
override fun setLegacyExpandImmediate(legacyExpandImmediate: Boolean) {
_legacyExpandImmediate.value = legacyExpandImmediate
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
index ef0a842ecc0c..45f359efbb7a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
@@ -52,9 +52,25 @@ interface ShadeInteractor : BaseShadeInteractor {
/** Are touches allowed on the notification panel? */
val isShadeTouchable: Flow<Boolean>
- /** Emits true if the shade can be expanded from QQS to QS and false otherwise. */
+ /** Whether the shade can be expanded from QQS to QS. */
val isExpandToQsEnabled: Flow<Boolean>
+ /**
+ * The version of the shade layout to use.
+ *
+ * Note: Most likely, you want to read [isShadeLayoutWide] instead of this.
+ */
+ val shadeMode: StateFlow<ShadeMode>
+
+ /**
+ * Whether the shade layout should be wide (true) or narrow (false).
+ *
+ * In a wide layout, notifications and quick settings each take up only half the screen width
+ * (whether they are shown at the same time or not). In a narrow layout, they can each be as
+ * wide as the entire screen.
+ */
+ val isShadeLayoutWide: StateFlow<Boolean>
+
/** How to align the shade content. */
val shadeAlignment: ShadeAlignment
}
@@ -113,8 +129,6 @@ interface BaseShadeInteractor {
* animating.
*/
val isUserInteractingWithQs: Flow<Boolean>
-
- val shadeMode: StateFlow<ShadeMode>
}
fun createAnyExpansionFlow(
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
index 6226d077b135..e77aca93aeca 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
@@ -47,5 +47,6 @@ class ShadeInteractorEmptyImpl @Inject constructor() : ShadeInteractor {
override val isShadeTouchable: Flow<Boolean> = inactiveFlowBoolean
override val isExpandToQsEnabled: Flow<Boolean> = inactiveFlowBoolean
override val shadeMode: StateFlow<ShadeMode> = MutableStateFlow(ShadeMode.Single)
+ override val isShadeLayoutWide: StateFlow<Boolean> = inactiveFlowBoolean
override val shadeAlignment: ShadeAlignment = ShadeAlignment.Top
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt
index 55f019b01164..684a4845144e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt
@@ -25,7 +25,9 @@ import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.shade.data.repository.ShadeRepository
+import com.android.systemui.shade.shared.flag.DualShade
import com.android.systemui.shade.shared.model.ShadeAlignment
+import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepository
import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.policy.data.repository.UserSetupRepository
@@ -60,8 +62,7 @@ constructor(
) : ShadeInteractor, BaseShadeInteractor by baseShadeInteractor {
override val isShadeEnabled: StateFlow<Boolean> =
disableFlagsRepository.disableFlags
- .map { isDisabledByFlags -> isDisabledByFlags.isShadeEnabled() }
- .distinctUntilChanged()
+ .map { it.isShadeEnabled() }
.stateIn(scope, SharingStarted.Eagerly, initialValue = false)
override val isQsEnabled: StateFlow<Boolean> =
@@ -102,6 +103,17 @@ constructor(
}
}
+ override val isShadeLayoutWide: StateFlow<Boolean> = shadeRepository.isShadeLayoutWide
+
+ override val shadeMode: StateFlow<ShadeMode> =
+ isShadeLayoutWide
+ .map(this::determineShadeMode)
+ .stateIn(
+ scope,
+ SharingStarted.Eagerly,
+ initialValue = determineShadeMode(isShadeLayoutWide.value)
+ )
+
override val shadeAlignment: ShadeAlignment =
if (shadeRepository.isDualShadeAlignedToBottom) {
ShadeAlignment.Bottom
@@ -125,4 +137,12 @@ constructor(
disableFlags.isQuickSettingsEnabled() &&
!isDozing
}
+
+ private fun determineShadeMode(isShadeLayoutWide: Boolean): ShadeMode {
+ return when {
+ DualShade.isEnabled -> ShadeMode.Dual
+ isShadeLayoutWide -> ShadeMode.Split
+ else -> ShadeMode.Single
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt
index 7d46d2ba17da..f39ee9afd039 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt
@@ -21,7 +21,6 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.shade.data.repository.ShadeRepository
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -105,8 +104,6 @@ constructor(
override val isUserInteractingWithQs: Flow<Boolean> =
userInteractingFlow(repository.legacyQsTracking, repository.qsExpansion)
- override val shadeMode: StateFlow<ShadeMode> = repository.shadeMode
-
/**
* Return a flow for whether a user is interacting with an expandable shade component using
* tracking and expansion flows. NOTE: expansion must be a `StateFlow` to guarantee that
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
index d5b4f4d7e623..b2142a515923 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
@@ -22,8 +22,6 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.SceneFamilies
-import com.android.systemui.shade.data.repository.ShadeRepository
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import javax.inject.Inject
@@ -45,10 +43,7 @@ constructor(
@Application scope: CoroutineScope,
sceneInteractor: SceneInteractor,
sharedNotificationContainerInteractor: SharedNotificationContainerInteractor,
- shadeRepository: ShadeRepository,
) : BaseShadeInteractor {
- override val shadeMode: StateFlow<ShadeMode> = shadeRepository.shadeMode
-
override val shadeExpansion: StateFlow<Float> =
sceneBasedExpansion(sceneInteractor, SceneFamilies.NotifShade)
.stateIn(scope, SharingStarted.Eagerly, 0f)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
index 354d379d2ea2..5eb3a1cc1348 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
@@ -29,8 +29,6 @@ import com.android.systemui.shade.ShadeExpansionStateManager
import com.android.systemui.shade.TouchLogger.Companion.logTouchesTo
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
-import com.android.systemui.shade.shared.flag.DualShade
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.shade.transition.ScrimShadeTransitionController
import com.android.systemui.statusbar.PulseExpansionHandler
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
@@ -40,7 +38,6 @@ import javax.inject.Provider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
@@ -63,7 +60,7 @@ constructor(
) : CoreStartable {
override fun start() {
- hydrateShadeMode()
+ hydrateShadeLayoutWidth()
hydrateShadeExpansionStateManager()
logTouchesTo(touchLog)
scrimShadeTransitionController.init()
@@ -86,22 +83,17 @@ constructor(
}
}
- private fun hydrateShadeMode() {
- if (DualShade.isEnabled) {
- shadeRepository.setShadeMode(ShadeMode.Dual)
- return
- }
+ private fun hydrateShadeLayoutWidth() {
applicationScope.launch {
configurationRepository.onAnyConfigurationChange
// Force initial collection.
.onStart { emit(Unit) }
- .map { applicationContext.resources }
- .map { resources ->
- splitShadeStateController.shouldUseSplitNotificationShade(resources)
- }
- .collect { isSplitShade ->
- shadeRepository.setShadeMode(
- if (isSplitShade) ShadeMode.Split else ShadeMode.Single
+ .collect {
+ val resources = applicationContext.resources
+ // The configuration for 'shouldUseSplitNotificationShade' dictates the width of
+ // the shade in both split-shade and dual-shade modes.
+ shadeRepository.setShadeLayoutWide(
+ splitShadeStateController.shouldUseSplitNotificationShade(resources)
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt b/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt
index 8214a24a9a38..a8199a402ef1 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt
@@ -29,6 +29,8 @@ sealed interface ShadeMode {
/**
* The split shade where, on large screens and unfolded foldables, the QS and notification parts
* are placed side-by-side and expand/collapse as a single panel.
+ *
+ * Note: This isn't the only mode where the shade is wide.
*/
data object Split : ShadeMode
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
index 2f58b35ae182..ea4e065be84b 100644
--- a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
@@ -18,51 +18,35 @@ package com.android.systemui.smartspace.dagger
import com.android.systemui.plugins.BcSmartspaceDataPlugin
import com.android.systemui.smartspace.SmartspacePrecondition
import com.android.systemui.smartspace.SmartspaceTargetFilter
-import com.android.systemui.smartspace.data.repository.SmartspaceRepositoryModule
import com.android.systemui.smartspace.preconditions.LockscreenPrecondition
import dagger.Binds
import dagger.BindsOptionalOf
import dagger.Module
import javax.inject.Named
-@Module(subcomponents = [SmartspaceViewComponent::class],
- includes = [SmartspaceRepositoryModule::class])
+@Module(subcomponents = [SmartspaceViewComponent::class])
abstract class SmartspaceModule {
@Module
companion object {
- /**
- * The BcSmartspaceDataProvider for dreams.
- */
+ /** The BcSmartspaceDataProvider for dreams. */
const val DREAM_SMARTSPACE_DATA_PLUGIN = "dreams_smartspace_data_plugin"
- /**
- * The BcSmartspaceDataPlugin for the standalone weather on dream.
- */
+ /** The BcSmartspaceDataPlugin for the standalone weather on dream. */
const val DREAM_WEATHER_SMARTSPACE_DATA_PLUGIN = "dream_weather_smartspace_data_plugin"
- /**
- * The target filter for smartspace over lockscreen.
- */
+ /** The target filter for smartspace over lockscreen. */
const val LOCKSCREEN_SMARTSPACE_TARGET_FILTER = "lockscreen_smartspace_target_filter"
- /**
- * The precondition for smartspace over lockscreen
- */
+ /** The precondition for smartspace over lockscreen */
const val LOCKSCREEN_SMARTSPACE_PRECONDITION = "lockscreen_smartspace_precondition"
- /**
- * The BcSmartspaceDataPlugin for the standalone date (+alarm+dnd).
- */
+ /** The BcSmartspaceDataPlugin for the standalone date (+alarm+dnd). */
const val DATE_SMARTSPACE_DATA_PLUGIN = "date_smartspace_data_plugin"
- /**
- * The BcSmartspaceDataPlugin for the standalone weather.
- */
+ /** The BcSmartspaceDataPlugin for the standalone weather. */
const val WEATHER_SMARTSPACE_DATA_PLUGIN = "weather_smartspace_data_plugin"
- /**
- * The BcSmartspaceDataProvider for the glanceable hub.
- */
+ /** The BcSmartspaceDataProvider for the glanceable hub. */
const val GLANCEABLE_HUB_SMARTSPACE_DATA_PLUGIN = "glanceable_hub_smartspace_data_plugin"
}
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/data/repository/SmartspaceRepository.kt b/packages/SystemUI/src/com/android/systemui/smartspace/data/repository/SmartspaceRepository.kt
deleted file mode 100644
index 52a1c1555591..000000000000
--- a/packages/SystemUI/src/com/android/systemui/smartspace/data/repository/SmartspaceRepository.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.systemui.smartspace.data.repository
-
-import android.app.smartspace.SmartspaceTarget
-import android.os.Parcelable
-import android.widget.RemoteViews
-import com.android.systemui.communal.smartspace.CommunalSmartspaceController
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.plugins.BcSmartspaceDataPlugin
-import java.util.concurrent.Executor
-import javax.inject.Inject
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.onCompletion
-import kotlinx.coroutines.flow.onStart
-
-interface SmartspaceRepository {
- /** Whether [RemoteViews] are passed through smartspace targets. */
- val isSmartspaceRemoteViewsEnabled: Boolean
-
- /** Smartspace targets for the communal surface. */
- val communalSmartspaceTargets: Flow<List<SmartspaceTarget>>
-}
-
-@SysUISingleton
-class SmartspaceRepositoryImpl
-@Inject
-constructor(
- private val communalSmartspaceController: CommunalSmartspaceController,
- @Main private val uiExecutor: Executor,
-) : SmartspaceRepository, BcSmartspaceDataPlugin.SmartspaceTargetListener {
-
- override val isSmartspaceRemoteViewsEnabled: Boolean
- get() = android.app.smartspace.flags.Flags.remoteViews()
-
- private val _communalSmartspaceTargets: MutableStateFlow<List<SmartspaceTarget>> =
- MutableStateFlow(emptyList())
- override val communalSmartspaceTargets: Flow<List<SmartspaceTarget>> =
- _communalSmartspaceTargets
- .onStart {
- uiExecutor.execute {
- communalSmartspaceController.addListener(
- listener = this@SmartspaceRepositoryImpl
- )
- }
- }
- .onCompletion {
- uiExecutor.execute {
- communalSmartspaceController.removeListener(
- listener = this@SmartspaceRepositoryImpl
- )
- }
- }
-
- override fun onSmartspaceTargetsUpdated(targetsNullable: MutableList<out Parcelable>?) {
- targetsNullable?.let { targets ->
- _communalSmartspaceTargets.value = targets.filterIsInstance<SmartspaceTarget>()
- }
- ?: run { _communalSmartspaceTargets.value = emptyList() }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java b/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java
index abf258c44556..693cc4a659c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java
@@ -485,9 +485,8 @@ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Ca
final boolean intersectsTopCutout = topDisplayCutout.intersects(
width - (windowWidth / 2), 0,
width + (windowWidth / 2), topDisplayCutout.bottom);
- if (mClingWindow != null &&
- (windowWidth < 0 || (width > 0 && intersectsTopCutout))) {
- final View iconView = mClingWindow.findViewById(R.id.immersive_cling_icon);
+ if (windowWidth < 0 || (width > 0 && intersectsTopCutout)) {
+ final View iconView = findViewById(R.id.immersive_cling_icon);
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)
iconView.getLayoutParams();
lp.topMargin = topDisplayCutout.bottom;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
index 342ec0dc228d..c997ac5ad9df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar;
import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+import static com.android.systemui.Flags.fetchBookmarksXmlKeyboardShortcuts;
import static com.android.systemui.Flags.validateKeyboardShortcutHelperIconUri;
import android.annotation.NonNull;
@@ -149,7 +150,7 @@ public final class KeyboardShortcutListSearch {
private KeyCharacterMap mBackupKeyCharacterMap;
@VisibleForTesting
- KeyboardShortcutListSearch(Context context, WindowManager windowManager) {
+ KeyboardShortcutListSearch(Context context, WindowManager windowManager, int deviceId) {
this.mContext = new ContextThemeWrapper(
context, R.style.KeyboardShortcutHelper);
this.mPackageManager = AppGlobals.getPackageManager();
@@ -159,12 +160,12 @@ public final class KeyboardShortcutListSearch {
this.mWindowManager = mContext.getSystemService(WindowManager.class);
}
loadResources(this.mContext);
- createHardcodedShortcuts();
+ createHardcodedShortcuts(deviceId);
}
- private static KeyboardShortcutListSearch getInstance(Context context) {
+ private static KeyboardShortcutListSearch getInstance(Context context, int deviceId) {
if (sInstance == null) {
- sInstance = new KeyboardShortcutListSearch(context, null);
+ sInstance = new KeyboardShortcutListSearch(context, null, deviceId);
}
return sInstance;
}
@@ -176,7 +177,7 @@ public final class KeyboardShortcutListSearch {
if (sInstance != null && !sInstance.mContext.equals(context)) {
dismiss();
}
- getInstance(context).showKeyboardShortcuts(deviceId);
+ getInstance(context, deviceId).showKeyboardShortcuts(deviceId);
}
}
@@ -274,7 +275,8 @@ public final class KeyboardShortcutListSearch {
context.getString(R.string.keyboard_key_button_template, "Mode"));
mSpecialCharacterNames.put(
KeyEvent.KEYCODE_FORWARD_DEL, context.getString(R.string.keyboard_key_forward_del));
- mSpecialCharacterNames.put(KeyEvent.KEYCODE_ESCAPE, "Esc");
+ mSpecialCharacterNames.put(
+ KeyEvent.KEYCODE_ESCAPE, context.getString(R.string.keyboard_key_esc));
mSpecialCharacterNames.put(KeyEvent.KEYCODE_SYSRQ, "SysRq");
mSpecialCharacterNames.put(KeyEvent.KEYCODE_BREAK, "Break");
mSpecialCharacterNames.put(KeyEvent.KEYCODE_SCROLL_LOCK, "Scroll Lock");
@@ -366,7 +368,7 @@ public final class KeyboardShortcutListSearch {
KeyEvent.META_META_ON, context.getDrawable(R.drawable.ic_ksh_key_meta));
}
- private void createHardcodedShortcuts() {
+ private void createHardcodedShortcuts(int deviceId) {
// Add system shortcuts
mKeySearchResultMap.put(SHORTCUT_SYSTEM_INDEX, true);
mSystemGroup.add(getMultiMappingSystemShortcuts(mContext));
@@ -376,7 +378,7 @@ public final class KeyboardShortcutListSearch {
mInputGroup.add(getMultiMappingInputShortcuts(mContext));
// Add open apps shortcuts
final List<KeyboardShortcutMultiMappingGroup> appShortcuts =
- Arrays.asList(getDefaultMultiMappingApplicationShortcuts());
+ Arrays.asList(getDefaultMultiMappingApplicationShortcuts(deviceId));
if (appShortcuts != null && !appShortcuts.isEmpty()) {
mOpenAppsGroup = appShortcuts;
mKeySearchResultMap.put(SHORTCUT_OPENAPPS_INDEX, true);
@@ -738,35 +740,50 @@ public final class KeyboardShortcutListSearch {
shortcutMultiMappingInfoList);
}
- private KeyboardShortcutMultiMappingGroup getDefaultMultiMappingApplicationShortcuts() {
- final int userId = mContext.getUserId();
- PackageInfo assistPackageInfo = getAssistPackageInfo(mContext, mPackageManager, userId);
- CharSequence categoryTitle =
- mContext.getString(R.string.keyboard_shortcut_group_applications);
+ private KeyboardShortcutMultiMappingGroup getDefaultMultiMappingApplicationShortcuts(
+ int deviceId) {
List<ShortcutMultiMappingInfo> shortcutMultiMappingInfos = new ArrayList<>();
-
- String[] intentCategories = {
- Intent.CATEGORY_APP_BROWSER,
- Intent.CATEGORY_APP_CONTACTS,
- Intent.CATEGORY_APP_EMAIL,
- Intent.CATEGORY_APP_CALENDAR,
- Intent.CATEGORY_APP_MAPS,
- Intent.CATEGORY_APP_MUSIC,
- Intent.CATEGORY_APP_MESSAGING,
- Intent.CATEGORY_APP_CALCULATOR,
-
- };
- String[] shortcutLabels = {
- mContext.getString(R.string.keyboard_shortcut_group_applications_browser),
- mContext.getString(R.string.keyboard_shortcut_group_applications_contacts),
- mContext.getString(R.string.keyboard_shortcut_group_applications_email),
- mContext.getString(R.string.keyboard_shortcut_group_applications_calendar),
- mContext.getString(R.string.keyboard_shortcut_group_applications_maps),
- mContext.getString(R.string.keyboard_shortcut_group_applications_music),
- mContext.getString(R.string.keyboard_shortcut_group_applications_sms),
- mContext.getString(R.string.keyboard_shortcut_group_applications_calculator)
- };
- int[] keyCodes = {
+ CharSequence categoryTitle;
+ if (fetchBookmarksXmlKeyboardShortcuts()) {
+ KeyboardShortcutGroup apps =
+ mWindowManager.getApplicationLaunchKeyboardShortcuts(deviceId);
+ List<KeyboardShortcutMultiMappingGroup> shortcuts =
+ reMapToKeyboardShortcutMultiMappingGroup(Arrays.asList(apps));
+ for (KeyboardShortcutMultiMappingGroup group : shortcuts) {
+ for (ShortcutMultiMappingInfo keyboardShortcutInfo : group.getItems()) {
+ shortcutMultiMappingInfos.add(keyboardShortcutInfo);
+ }
+ }
+ categoryTitle = apps.getLabel();
+ } else {
+ // Show shortcuts based on AOSP bookmarks.xml
+ categoryTitle = mContext.getString(R.string.keyboard_shortcut_group_applications);
+ final int userId = mContext.getUserId();
+ PackageInfo assistPackageInfo =
+ getAssistPackageInfo(mContext, mPackageManager, userId);
+
+ String[] intentCategories = {
+ Intent.CATEGORY_APP_BROWSER,
+ Intent.CATEGORY_APP_CONTACTS,
+ Intent.CATEGORY_APP_EMAIL,
+ Intent.CATEGORY_APP_CALENDAR,
+ Intent.CATEGORY_APP_MAPS,
+ Intent.CATEGORY_APP_MUSIC,
+ Intent.CATEGORY_APP_MESSAGING,
+ Intent.CATEGORY_APP_CALCULATOR,
+ };
+ String[] shortcutLabels = {
+ mContext.getString(R.string.keyboard_shortcut_group_applications_browser),
+ mContext.getString(R.string.keyboard_shortcut_group_applications_contacts),
+ mContext.getString(R.string.keyboard_shortcut_group_applications_email),
+ mContext.getString(R.string.keyboard_shortcut_group_applications_calendar),
+ mContext.getString(R.string.keyboard_shortcut_group_applications_maps),
+ mContext.getString(R.string.keyboard_shortcut_group_applications_music),
+ mContext.getString(R.string.keyboard_shortcut_group_applications_sms),
+ mContext.getString(R.string.keyboard_shortcut_group_applications_calculator)
+ };
+
+ int[] keyCodes = {
KeyEvent.KEYCODE_B,
KeyEvent.KEYCODE_C,
KeyEvent.KEYCODE_E,
@@ -775,52 +792,44 @@ public final class KeyboardShortcutListSearch {
KeyEvent.KEYCODE_P,
KeyEvent.KEYCODE_S,
KeyEvent.KEYCODE_U,
- };
+ };
- // Assist.
- if (assistPackageInfo != null) {
+ // Assist.
if (assistPackageInfo != null) {
- final Icon assistIcon = Icon.createWithResource(
- assistPackageInfo.applicationInfo.packageName,
- assistPackageInfo.applicationInfo.icon);
- CharSequence assistLabel =
- mContext.getString(R.string.keyboard_shortcut_group_applications_assist);
- KeyboardShortcutInfo assistShortcutInfo = new KeyboardShortcutInfo(
- assistLabel,
- assistIcon,
- KeyEvent.KEYCODE_A,
- KeyEvent.META_META_ON);
- shortcutMultiMappingInfos.add(
- new ShortcutMultiMappingInfo(
- assistLabel,
- assistIcon,
- Arrays.asList(new ShortcutKeyGroup(assistShortcutInfo, null))));
+ if (assistPackageInfo != null) {
+ final Icon assistIcon = Icon.createWithResource(
+ assistPackageInfo.applicationInfo.packageName,
+ assistPackageInfo.applicationInfo.icon);
+ CharSequence assistLabel = mContext.getString(
+ R.string.keyboard_shortcut_group_applications_assist);
+ KeyboardShortcutInfo assistShortcutInfo = new KeyboardShortcutInfo(
+ assistLabel,
+ assistIcon,
+ KeyEvent.KEYCODE_A,
+ KeyEvent.META_META_ON);
+ shortcutMultiMappingInfos.add(
+ new ShortcutMultiMappingInfo(
+ assistLabel,
+ assistIcon,
+ Arrays.asList(new ShortcutKeyGroup(assistShortcutInfo, null))));
+ }
}
- }
- // Browser (Chrome as default): Meta + B
- // Contacts: Meta + C
- // Email (Gmail as default): Meta + E
- // Gmail: Meta + G
- // Calendar: Meta + K
- // Maps: Meta + M
- // Music: Meta + P
- // SMS: Meta + S
- // Calculator: Meta + U
- for (int i = 0; i < shortcutLabels.length; i++) {
- final Icon icon = getIconForIntentCategory(intentCategories[i], userId);
- if (icon != null) {
- CharSequence label =
- shortcutLabels[i];
- KeyboardShortcutInfo keyboardShortcutInfo = new KeyboardShortcutInfo(
- label,
- icon,
- keyCodes[i],
- KeyEvent.META_META_ON);
- List<ShortcutKeyGroup> shortcutKeyGroups =
- Arrays.asList(new ShortcutKeyGroup(keyboardShortcutInfo, null));
- shortcutMultiMappingInfos.add(
- new ShortcutMultiMappingInfo(label, icon, shortcutKeyGroups));
+ for (int i = 0; i < shortcutLabels.length; i++) {
+ final Icon icon = getIconForIntentCategory(intentCategories[i], userId);
+ if (icon != null) {
+ CharSequence label =
+ shortcutLabels[i];
+ KeyboardShortcutInfo keyboardShortcutInfo = new KeyboardShortcutInfo(
+ label,
+ icon,
+ keyCodes[i],
+ KeyEvent.META_META_ON);
+ List<ShortcutKeyGroup> shortcutKeyGroups =
+ Arrays.asList(new ShortcutKeyGroup(keyboardShortcutInfo, null));
+ shortcutMultiMappingInfos.add(
+ new ShortcutMultiMappingInfo(label, icon, shortcutKeyGroups));
+ }
}
}
@@ -1220,7 +1229,8 @@ public final class KeyboardShortcutListSearch {
String shortcutKeyString = null;
Drawable shortcutKeyDrawable = null;
if (info.getBaseCharacter() > Character.MIN_VALUE) {
- shortcutKeyString = String.valueOf(info.getBaseCharacter());
+ shortcutKeyString = String.valueOf(info.getBaseCharacter())
+ .toUpperCase(Locale.getDefault());
} else if (mSpecialCharacterNames.get(info.getKeycode()) != null) {
shortcutKeyString = mSpecialCharacterNames.get(info.getKeycode());
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
index 6ee13c3b1801..766c391b14d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
@@ -20,6 +20,7 @@ import static android.content.Context.LAYOUT_INFLATER_SERVICE;
import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+import static com.android.systemui.Flags.fetchBookmarksXmlKeyboardShortcuts;
import static com.android.systemui.Flags.validateKeyboardShortcutHelperIconUri;
import android.annotation.NonNull;
@@ -75,6 +76,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.Locale;
/**
* Contains functionality for handling keyboard shortcuts.
@@ -133,6 +135,7 @@ public final class KeyboardShortcuts {
@Nullable private List<KeyboardShortcutGroup> mReceivedAppShortcutGroups = null;
@Nullable private List<KeyboardShortcutGroup> mReceivedImeShortcutGroups = null;
+ @Nullable private KeyboardShortcutGroup mDefaultApplicationShortcuts = null;
@VisibleForTesting
KeyboardShortcuts(Context context, WindowManager windowManager) {
@@ -259,7 +262,8 @@ public final class KeyboardShortcuts {
context.getString(R.string.keyboard_key_button_template, "Mode"));
mSpecialCharacterNames.put(
KeyEvent.KEYCODE_FORWARD_DEL, context.getString(R.string.keyboard_key_forward_del));
- mSpecialCharacterNames.put(KeyEvent.KEYCODE_ESCAPE, "Esc");
+ mSpecialCharacterNames.put(
+ KeyEvent.KEYCODE_ESCAPE, context.getString(R.string.keyboard_key_esc));
mSpecialCharacterNames.put(KeyEvent.KEYCODE_SYSRQ, "SysRq");
mSpecialCharacterNames.put(KeyEvent.KEYCODE_BREAK, "Break");
mSpecialCharacterNames.put(KeyEvent.KEYCODE_SCROLL_LOCK, "Scroll Lock");
@@ -389,6 +393,7 @@ public final class KeyboardShortcuts {
mReceivedAppShortcutGroups = null;
mReceivedImeShortcutGroups = null;
+ mDefaultApplicationShortcuts = getDefaultApplicationShortcuts(deviceId);
mWindowManager.requestAppKeyboardShortcuts(
result -> {
mBackgroundHandler.post(() -> {
@@ -442,10 +447,8 @@ public final class KeyboardShortcuts {
mReceivedAppShortcutGroups = null;
mReceivedImeShortcutGroups = null;
- final KeyboardShortcutGroup defaultAppShortcuts =
- getDefaultApplicationShortcuts();
- if (defaultAppShortcuts != null) {
- shortcutGroups.add(defaultAppShortcuts);
+ if (mDefaultApplicationShortcuts != null) {
+ shortcutGroups.add(mDefaultApplicationShortcuts);
}
shortcutGroups.add(getSystemShortcuts());
showKeyboardShortcutsDialog(shortcutGroups);
@@ -498,7 +501,7 @@ public final class KeyboardShortcuts {
return systemGroup;
}
- private KeyboardShortcutGroup getDefaultApplicationShortcuts() {
+ private KeyboardShortcutGroup getDefaultApplicationShortcuts(int deviceId) {
final int userId = mContext.getUserId();
List<KeyboardShortcutInfo> keyboardShortcutInfoAppItems = new ArrayList<>();
@@ -523,70 +526,82 @@ public final class KeyboardShortcuts {
keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
mContext.getString(R.string.keyboard_shortcut_group_applications_assist),
assistIcon,
- KeyEvent.KEYCODE_UNKNOWN,
+ KeyEvent.KEYCODE_A,
KeyEvent.META_META_ON));
}
}
- // Browser.
- final Icon browserIcon = getIconForIntentCategory(Intent.CATEGORY_APP_BROWSER, userId);
- if (browserIcon != null) {
- keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
- mContext.getString(R.string.keyboard_shortcut_group_applications_browser),
- browserIcon,
- KeyEvent.KEYCODE_B,
- KeyEvent.META_META_ON));
- }
+ CharSequence categoryTitle;
+ if (fetchBookmarksXmlKeyboardShortcuts()) {
+ KeyboardShortcutGroup apps =
+ mWindowManager.getApplicationLaunchKeyboardShortcuts(deviceId);
+ categoryTitle = apps.getLabel();
+ keyboardShortcutInfoAppItems.addAll(apps.getItems());
+ } else {
+ categoryTitle = mContext.getString(R.string.keyboard_shortcut_group_applications);
+ // Browser.
+ final Icon browserIcon = getIconForIntentCategory(Intent.CATEGORY_APP_BROWSER, userId);
+ if (browserIcon != null) {
+ keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_browser),
+ browserIcon,
+ KeyEvent.KEYCODE_B,
+ KeyEvent.META_META_ON));
+ }
- // Contacts.
- final Icon contactsIcon = getIconForIntentCategory(Intent.CATEGORY_APP_CONTACTS, userId);
- if (contactsIcon != null) {
- keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
- mContext.getString(R.string.keyboard_shortcut_group_applications_contacts),
- contactsIcon,
- KeyEvent.KEYCODE_C,
- KeyEvent.META_META_ON));
- }
+ // Contacts.
+ final Icon contactsIcon = getIconForIntentCategory(
+ Intent.CATEGORY_APP_CONTACTS, userId);
+ if (contactsIcon != null) {
+ keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_contacts),
+ contactsIcon,
+ KeyEvent.KEYCODE_C,
+ KeyEvent.META_META_ON));
+ }
- // Email.
- final Icon emailIcon = getIconForIntentCategory(Intent.CATEGORY_APP_EMAIL, userId);
- if (emailIcon != null) {
- keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
- mContext.getString(R.string.keyboard_shortcut_group_applications_email),
- emailIcon,
- KeyEvent.KEYCODE_E,
- KeyEvent.META_META_ON));
- }
+ // Email.
+ final Icon emailIcon = getIconForIntentCategory(Intent.CATEGORY_APP_EMAIL, userId);
+ if (emailIcon != null) {
+ keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_email),
+ emailIcon,
+ KeyEvent.KEYCODE_E,
+ KeyEvent.META_META_ON));
+ }
- // Messaging.
- final Icon messagingIcon = getIconForIntentCategory(Intent.CATEGORY_APP_MESSAGING, userId);
- if (messagingIcon != null) {
- keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
- mContext.getString(R.string.keyboard_shortcut_group_applications_sms),
- messagingIcon,
- KeyEvent.KEYCODE_S,
- KeyEvent.META_META_ON));
- }
+ // Messaging.
+ final Icon messagingIcon = getIconForIntentCategory(
+ Intent.CATEGORY_APP_MESSAGING, userId);
+ if (messagingIcon != null) {
+ keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_sms),
+ messagingIcon,
+ KeyEvent.KEYCODE_S,
+ KeyEvent.META_META_ON));
+ }
- // Music.
- final Icon musicIcon = getIconForIntentCategory(Intent.CATEGORY_APP_MUSIC, userId);
- if (musicIcon != null) {
- keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
- mContext.getString(R.string.keyboard_shortcut_group_applications_music),
- musicIcon,
- KeyEvent.KEYCODE_P,
- KeyEvent.META_META_ON));
- }
+ // Music.
+ final Icon musicIcon = getIconForIntentCategory(Intent.CATEGORY_APP_MUSIC, userId);
+ if (musicIcon != null) {
+ keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_music),
+ musicIcon,
+ KeyEvent.KEYCODE_P,
+ KeyEvent.META_META_ON));
+ }
- // Calendar.
- final Icon calendarIcon = getIconForIntentCategory(Intent.CATEGORY_APP_CALENDAR, userId);
- if (calendarIcon != null) {
- keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
- mContext.getString(R.string.keyboard_shortcut_group_applications_calendar),
- calendarIcon,
- KeyEvent.KEYCODE_K,
- KeyEvent.META_META_ON));
+ // Calendar.
+ final Icon calendarIcon = getIconForIntentCategory(
+ Intent.CATEGORY_APP_CALENDAR, userId);
+ if (calendarIcon != null) {
+ keyboardShortcutInfoAppItems.add(new KeyboardShortcutInfo(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_calendar),
+ calendarIcon,
+ KeyEvent.KEYCODE_K,
+ KeyEvent.META_META_ON));
+ }
}
final int itemsSize = keyboardShortcutInfoAppItems.size();
@@ -597,7 +612,7 @@ public final class KeyboardShortcuts {
// Sorts by label, case insensitive with nulls and/or empty labels last.
Collections.sort(keyboardShortcutInfoAppItems, mApplicationItemsComparator);
return new KeyboardShortcutGroup(
- mContext.getString(R.string.keyboard_shortcut_group_applications),
+ categoryTitle,
keyboardShortcutInfoAppItems,
true);
}
@@ -776,7 +791,8 @@ public final class KeyboardShortcuts {
String shortcutKeyString = null;
Drawable shortcutKeyDrawable = null;
if (info.getBaseCharacter() > Character.MIN_VALUE) {
- shortcutKeyString = String.valueOf(info.getBaseCharacter());
+ shortcutKeyString = String.valueOf(info.getBaseCharacter())
+ .toUpperCase(Locale.getDefault());
} else if (mSpecialCharacterNames.get(info.getKeycode()) != null) {
shortcutKeyString = mSpecialCharacterNames.get(info.getKeycode());
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 89b7ccf09013..0957e5a5df35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -51,6 +51,7 @@ import com.android.systemui.deviceentry.shared.model.DeviceUnlockStatus;
import com.android.systemui.keyguard.MigrateClocksToBlueprint;
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
+import com.android.systemui.keyguard.shared.model.KeyguardState;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.res.R;
import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor;
@@ -203,7 +204,9 @@ public class StatusBarStateControllerImpl implements
@Override
public void start() {
mJavaAdapter.alwaysCollectFlow(
- mKeyguardTransitionInteractorLazy.get().isFinishedInState(GONE),
+ mKeyguardTransitionInteractorLazy.get().isFinishedIn(
+ /* scene */ Scenes.Gone,
+ /* stateWithoutSceneContainer */ GONE),
(Boolean isFinishedInState) -> {
if (isFinishedInState) {
setLeaveOpenOnKeyguardHide(false);
@@ -221,6 +224,10 @@ public class StatusBarStateControllerImpl implements
mSceneContainerOcclusionInteractorLazy.get().getInvisibleDueToOcclusion(),
this::calculateStateFromSceneFramework),
this::onStatusBarStateChanged);
+
+ mJavaAdapter.alwaysCollectFlow(
+ mKeyguardTransitionInteractorLazy.get().transitionValue(KeyguardState.AOD),
+ this::onAodKeyguardStateTransitionValueChanged);
}
}
@@ -691,6 +698,14 @@ public class StatusBarStateControllerImpl implements
updateStateAndNotifyListeners(newState);
}
+ private void onAodKeyguardStateTransitionValueChanged(float value) {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
+ return;
+ }
+
+ setDozeAmountInternal(value);
+ }
+
private static final Map<SceneKey, Integer> sStatusBarStateByLockedSceneKey = Map.of(
Scenes.Lockscreen, StatusBarState.KEYGUARD,
Scenes.Bouncer, StatusBarState.KEYGUARD,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsLog.kt
new file mode 100644
index 000000000000..ecb628674352
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsLog.kt
@@ -0,0 +1,25 @@
+/*
+ * 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.chips
+
+import javax.inject.Qualifier
+
+/** Logs for events related to the status bar chips. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class StatusBarChipsLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsModule.kt
new file mode 100644
index 000000000000..173ff37cc3b8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsModule.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.chips
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogBufferFactory
+import dagger.Module
+import dagger.Provides
+
+@Module
+abstract class StatusBarChipsModule {
+ companion object {
+ @Provides
+ @SysUISingleton
+ @StatusBarChipsLog
+ fun provideChipsLogBuffer(factory: LogBufferFactory): LogBuffer {
+ return factory.create("StatusBarChips", 200)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
index 7e9acafa0bff..eaefc111ae3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
@@ -17,15 +17,36 @@
package com.android.systemui.statusbar.chips.call.domain.interactor
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.OngoingCallRepository
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.stateIn
/** Interactor for the ongoing phone call chip shown in the status bar. */
@SysUISingleton
class CallChipInteractor
@Inject
constructor(
+ @Application private val scope: CoroutineScope,
repository: OngoingCallRepository,
+ @StatusBarChipsLog private val logger: LogBuffer,
) {
- val ongoingCallState = repository.ongoingCallState
+ val ongoingCallState: StateFlow<OngoingCallModel> =
+ repository.ongoingCallState
+ .onEach {
+ logger.log(TAG, LogLevel.INFO, { str1 = it::class.simpleName }, { "State: $str1" })
+ }
+ .stateIn(scope, SharingStarted.Lazily, OngoingCallModel.NoCall)
+
+ companion object {
+ private const val TAG = "OngoingCall"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
index ed1756aff8c1..11ccdff687a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
@@ -23,8 +23,11 @@ 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.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
import com.android.systemui.statusbar.chips.call.domain.interactor.CallChipInteractor
import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
@@ -48,6 +51,7 @@ constructor(
interactor: CallChipInteractor,
systemClock: SystemClock,
private val activityStarter: ActivityStarter,
+ @StatusBarChipsLog private val logger: LogBuffer,
) : OngoingActivityChipViewModel {
override val chip: StateFlow<OngoingActivityChipModel> =
interactor.ongoingCallState
@@ -86,9 +90,9 @@ constructor(
}
return View.OnClickListener { view ->
+ logger.log(TAG, LogLevel.INFO, {}, { "Chip clicked" })
val backgroundView =
view.requireViewById<ChipBackgroundContainer>(R.id.ongoing_activity_chip_background)
- // TODO(b/332662551): Log the click event.
// This mimics OngoingCallController#updateChipClickListener.
activityStarter.postStartActivityDismissingKeyguard(
state.intent,
@@ -108,5 +112,6 @@ constructor(
R.string.ongoing_phone_call_content_description,
),
)
+ private const val TAG = "CallVM"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt
new file mode 100644
index 000000000000..7c95f1e42080
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt
@@ -0,0 +1,73 @@
+/*
+ * 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.chips.casttootherdevice.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.mediarouter.data.repository.MediaRouterRepository
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.model.MediaRouterCastModel
+import com.android.systemui.statusbar.policy.CastDevice
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * Interactor for MediaRouter events, used to show the cast-audio-to-other-device chip in the status
+ * bar.
+ */
+@SysUISingleton
+class MediaRouterChipInteractor
+@Inject
+constructor(
+ @Application private val scope: CoroutineScope,
+ private val mediaRouterRepository: MediaRouterRepository,
+ @StatusBarChipsLog private val logger: LogBuffer,
+) {
+ private val activeCastDevice: StateFlow<CastDevice?> =
+ mediaRouterRepository.castDevices
+ .map { allDevices -> allDevices.firstOrNull { it.isCasting } }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+
+ /** The current casting state, according to MediaRouter APIs. */
+ val mediaRouterCastingState: StateFlow<MediaRouterCastModel> =
+ activeCastDevice
+ .map {
+ if (it != null) {
+ logger.log(TAG, LogLevel.INFO, { str1 = it.name }, { "State: Casting($str1)" })
+ MediaRouterCastModel.Casting(deviceName = it.name)
+ } else {
+ logger.log(TAG, LogLevel.INFO, {}, { "State: DoingNothing" })
+ MediaRouterCastModel.DoingNothing
+ }
+ }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), MediaRouterCastModel.DoingNothing)
+
+ /** Stops the currently active MediaRouter cast. */
+ fun stopCasting() {
+ activeCastDevice.value?.let { mediaRouterRepository.stopCasting(it) }
+ }
+
+ companion object {
+ private const val TAG = "MediaRouter"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/model/MediaRouterCastModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/model/MediaRouterCastModel.kt
new file mode 100644
index 000000000000..1f84d7cb60b4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/model/MediaRouterCastModel.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.chips.casttootherdevice.domain.model
+
+/** Represents the current casting state, according to MediaRouter APIs. */
+sealed interface MediaRouterCastModel {
+ /** MediaRouter isn't aware of any active cast. */
+ data object DoingNothing : MediaRouterCastModel
+
+ /**
+ * MediaRouter has an active cast.
+ *
+ * @property deviceName the name of the device receiving the cast.
+ */
+ data class Casting(val deviceName: String?) : MediaRouterCastModel
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegate.kt
new file mode 100644
index 000000000000..bafec38efe9d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegate.kt
@@ -0,0 +1,90 @@
+/*
+ * 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.chips.casttootherdevice.ui.view
+
+import android.content.Context
+import android.os.Bundle
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.CastToOtherDeviceChipViewModel.Companion.CAST_TO_OTHER_DEVICE_ICON
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
+import com.android.systemui.statusbar.phone.SystemUIDialog
+
+/** A dialog that lets the user stop an ongoing cast-screen-to-other-device event. */
+class EndCastScreenToOtherDeviceDialogDelegate(
+ private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+ private val context: Context,
+ private val stopAction: () -> Unit,
+ private val state: ProjectionChipModel.Projecting,
+) : SystemUIDialog.Delegate {
+ override fun createDialog(): SystemUIDialog {
+ return endMediaProjectionDialogHelper.createDialog(this)
+ }
+
+ override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
+ with(dialog) {
+ setIcon(CAST_TO_OTHER_DEVICE_ICON)
+ setTitle(R.string.cast_to_other_device_stop_dialog_title)
+ setMessage(getMessage())
+ // No custom on-click, because the dialog will automatically be dismissed when the
+ // button is clicked anyway.
+ setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
+ setPositiveButton(R.string.cast_to_other_device_stop_dialog_button) { _, _ ->
+ stopAction.invoke()
+ }
+ }
+ }
+
+ private fun getMessage(): String {
+ val hostDeviceName = state.projectionState.hostDeviceName
+ return if (state.projectionState is MediaProjectionState.Projecting.SingleTask) {
+ val appBeingSharedName =
+ endMediaProjectionDialogHelper.getAppName(state.projectionState)
+ if (appBeingSharedName != null && hostDeviceName != null) {
+ context.getString(
+ R.string.cast_to_other_device_stop_dialog_message_specific_app_with_device,
+ appBeingSharedName,
+ hostDeviceName,
+ )
+ } else if (appBeingSharedName != null) {
+ context.getString(
+ R.string.cast_to_other_device_stop_dialog_message_specific_app,
+ appBeingSharedName,
+ )
+ } else if (hostDeviceName != null) {
+ context.getString(
+ R.string.cast_to_other_device_stop_dialog_message_generic_with_device,
+ hostDeviceName,
+ )
+ } else {
+ context.getString(R.string.cast_to_other_device_stop_dialog_message_generic)
+ }
+ } else {
+ if (hostDeviceName != null) {
+ context.getString(
+ R.string.cast_to_other_device_stop_dialog_message_entire_screen_with_device,
+ hostDeviceName,
+ )
+ } else {
+ context.getString(
+ R.string.cast_to_other_device_stop_dialog_message_entire_screen,
+ )
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegate.kt
index bc0f49218a75..7dc9b255badc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegate.kt
@@ -16,35 +16,42 @@
package com.android.systemui.statusbar.chips.casttootherdevice.ui.view
+import android.content.Context
import android.os.Bundle
import com.android.systemui.res.R
import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.CastToOtherDeviceChipViewModel.Companion.CAST_TO_OTHER_DEVICE_ICON
-import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
import com.android.systemui.statusbar.phone.SystemUIDialog
-/** A dialog that lets the user stop an ongoing cast-screen-to-other-device event. */
-class EndCastToOtherDeviceDialogDelegate(
+/**
+ * A dialog that lets the user stop an ongoing cast-to-other-device event. The user could be casting
+ * their screen, or just casting their audio. This dialog uses generic strings to handle both cases
+ * well.
+ */
+class EndGenericCastToOtherDeviceDialogDelegate(
private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+ private val context: Context,
+ private val deviceName: String?,
private val stopAction: () -> Unit,
- private val state: ProjectionChipModel.Projecting,
) : SystemUIDialog.Delegate {
override fun createDialog(): SystemUIDialog {
return endMediaProjectionDialogHelper.createDialog(this)
}
override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
+ val message =
+ if (deviceName != null) {
+ context.getString(
+ R.string.cast_to_other_device_stop_dialog_message_generic_with_device,
+ deviceName,
+ )
+ } else {
+ context.getString(R.string.cast_to_other_device_stop_dialog_message_generic)
+ }
with(dialog) {
setIcon(CAST_TO_OTHER_DEVICE_ICON)
setTitle(R.string.cast_to_other_device_stop_dialog_title)
- setMessage(
- endMediaProjectionDialogHelper.getDialogMessage(
- state.projectionState,
- genericMessageResId = R.string.cast_to_other_device_stop_dialog_message,
- specificAppMessageResId =
- R.string.cast_to_other_device_stop_dialog_message_specific_app,
- )
- )
+ setMessage(message)
// No custom on-click, because the dialog will automatically be dismissed when the
// button is clicked anyway.
setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
index 73ccaab68ae9..afa9ccefab86 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
@@ -16,14 +16,20 @@
package com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel
+import android.content.Context
import androidx.annotation.DrawableRes
-import com.android.systemui.animation.DialogTransitionAnimator
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.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndCastToOtherDeviceDialogDelegate
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor.MediaRouterChipInteractor
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.model.MediaRouterCastModel
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndCastScreenToOtherDeviceDialogDelegate
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndGenericCastToOtherDeviceDialogDelegate
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractor
import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
@@ -36,27 +42,35 @@ import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
/**
- * View model for the cast-to-other-device chip, shown when sharing your phone screen content to a
- * different device. (Triggered from the Quick Settings Cast tile or from the Settings app.)
+ * View model for the cast-to-other-device chip, shown when a user is sharing content to a different
+ * device. (Triggered from the Quick Settings Cast tile or from the Settings app.) The content could
+ * either be the user's screen, or just the user's audio.
*/
@SysUISingleton
class CastToOtherDeviceChipViewModel
@Inject
constructor(
@Application private val scope: CoroutineScope,
+ private val context: Context,
private val mediaProjectionChipInteractor: MediaProjectionChipInteractor,
+ private val mediaRouterChipInteractor: MediaRouterChipInteractor,
private val systemClock: SystemClock,
- private val dialogTransitionAnimator: DialogTransitionAnimator,
private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+ @StatusBarChipsLog private val logger: LogBuffer,
) : OngoingActivityChipViewModel {
- override val chip: StateFlow<OngoingActivityChipModel> =
- // TODO(b/342169876): The MediaProjection APIs are not invoked for certain
- // cast-to-other-device events, like audio-only casting. We should also listen to
- // MediaRouter APIs to cover all cast events.
+ /**
+ * The cast chip to show, based only on MediaProjection API events.
+ *
+ * This chip will only be [OngoingActivityChipModel.Shown] when the user is casting their
+ * *screen*. If the user is only casting audio, this chip will be
+ * [OngoingActivityChipModel.Hidden].
+ */
+ private val projectionChip: StateFlow<OngoingActivityChipModel> =
mediaProjectionChipInteractor.projection
.map { projectionModel ->
when (projectionModel) {
@@ -65,7 +79,7 @@ constructor(
if (projectionModel.type != ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE) {
OngoingActivityChipModel.Hidden
} else {
- createCastToOtherDeviceChip(projectionModel)
+ createCastScreenToOtherDeviceChip(projectionModel)
}
}
}
@@ -73,44 +87,152 @@ constructor(
// See b/347726238.
.stateIn(scope, SharingStarted.Lazily, OngoingActivityChipModel.Hidden)
+ /**
+ * The cast chip to show, based only on MediaRouter API events.
+ *
+ * This chip will be [OngoingActivityChipModel.Shown] when the user is casting their screen *or*
+ * their audio.
+ *
+ * The MediaProjection APIs are not invoked for casting *only audio* to another device because
+ * MediaProjection is only concerned with *screen* sharing (see b/342169876). We listen to
+ * MediaRouter APIs here to cover audio-only casting.
+ *
+ * Note that this means we will start showing the cast chip before the casting actually starts,
+ * for **both** audio-only casting and screen casting. MediaRouter is aware of all
+ * cast-to-other-device events, and MediaRouter immediately marks a device as "connecting" once
+ * a user selects what device they'd like to cast to, even if they haven't hit "Start casting"
+ * yet. All of SysUI considers "connecting" devices to be casting (see
+ * [com.android.systemui.statusbar.policy.CastDevice.isCasting]), so the chip will follow the
+ * same convention and start showing once a device is selected. See b/269975671.
+ */
+ private val routerChip =
+ mediaRouterChipInteractor.mediaRouterCastingState
+ .map { routerModel ->
+ when (routerModel) {
+ is MediaRouterCastModel.DoingNothing -> OngoingActivityChipModel.Hidden
+ is MediaRouterCastModel.Casting -> {
+ // A consequence of b/269975671 is that MediaRouter will mark a device as
+ // casting before casting has actually started. To alleviate this bug a bit,
+ // we won't show a timer for MediaRouter events. That way, we won't show a
+ // timer if cast hasn't actually started.
+ //
+ // This does mean that the audio-only casting chip will *never* show a
+ // timer, because audio-only casting never activates the MediaProjection
+ // APIs and those are the only cast APIs that show a timer.
+ createIconOnlyCastChip(routerModel.deviceName)
+ }
+ }
+ }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
+
+ override val chip: StateFlow<OngoingActivityChipModel> =
+ combine(projectionChip, routerChip) { projection, router ->
+ logger.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ str1 = projection.logName
+ str2 = router.logName
+ },
+ { "projectionChip=$str1 > routerChip=$str2" }
+ )
+
+ // A consequence of b/269975671 is that MediaRouter and MediaProjection APIs fire at
+ // different times when *screen* casting:
+ //
+ // 1. When the user chooses what device to cast to, the MediaRouter APIs mark the
+ // device as casting (even though casting hasn't actually started yet). At this
+ // point, `routerChip` is [OngoingActivityChipModel.Shown] but `projectionChip` is
+ // [OngoingActivityChipModel.Hidden], and we'll show the router chip.
+ //
+ // 2. Once casting has actually started, the MediaProjection APIs become aware of
+ // the device. At this point, both `routerChip` and `projectionChip` are
+ // [OngoingActivityChipModel.Shown].
+ //
+ // Because the MediaProjection APIs have activated, we know that the user is screen
+ // casting (not audio casting). We need to switch to using `projectionChip` because
+ // that chip will show information specific to screen casting. The `projectionChip`
+ // will also show a timer, as opposed to `routerChip`'s icon-only display.
+ if (projection is OngoingActivityChipModel.Shown) {
+ projection
+ } else {
+ router
+ }
+ }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
+
/** Stops the currently active projection. */
private fun stopProjecting() {
+ logger.log(TAG, LogLevel.INFO, {}, { "Stop casting requested (projection)" })
mediaProjectionChipInteractor.stopProjecting()
}
- private fun createCastToOtherDeviceChip(
+ /** Stops the currently active media route. */
+ private fun stopMediaRouterCasting() {
+ logger.log(TAG, LogLevel.INFO, {}, { "Stop casting requested (router)" })
+ mediaRouterChipInteractor.stopCasting()
+ }
+
+ private fun createCastScreenToOtherDeviceChip(
state: ProjectionChipModel.Projecting,
): OngoingActivityChipModel.Shown {
return OngoingActivityChipModel.Shown.Timer(
icon =
Icon.Resource(
CAST_TO_OTHER_DEVICE_ICON,
- // Note: This string is "Casting screen", which is okay right now because this
- // chip does not currently support audio-only casting. If the chip starts
- // supporting audio-only casting (see b/342169876), update the content
- // description to just "Casting".
+ // This string is "Casting screen"
ContentDescription.Resource(
- R.string.cast_to_other_device_chip_accessibility_label,
+ R.string.cast_screen_to_other_device_chip_accessibility_label,
),
),
colors = ColorsModel.Red,
// TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
startTimeMs = systemClock.elapsedRealtime(),
createDialogLaunchOnClickListener(
- createCastToOtherDeviceDialogDelegate(state),
- dialogTransitionAnimator,
+ createCastScreenToOtherDeviceDialogDelegate(state),
+ logger,
+ TAG,
+ ),
+ )
+ }
+
+ private fun createIconOnlyCastChip(deviceName: String?): OngoingActivityChipModel.Shown {
+ return OngoingActivityChipModel.Shown.IconOnly(
+ icon =
+ Icon.Resource(
+ CAST_TO_OTHER_DEVICE_ICON,
+ // This string is just "Casting"
+ ContentDescription.Resource(R.string.accessibility_casting),
+ ),
+ colors = ColorsModel.Red,
+ createDialogLaunchOnClickListener(
+ createGenericCastToOtherDeviceDialogDelegate(deviceName),
+ logger,
+ TAG,
),
)
}
- private fun createCastToOtherDeviceDialogDelegate(state: ProjectionChipModel.Projecting) =
- EndCastToOtherDeviceDialogDelegate(
+ private fun createCastScreenToOtherDeviceDialogDelegate(
+ state: ProjectionChipModel.Projecting,
+ ) =
+ EndCastScreenToOtherDeviceDialogDelegate(
endMediaProjectionDialogHelper,
+ context,
stopAction = this::stopProjecting,
state,
)
+ private fun createGenericCastToOtherDeviceDialogDelegate(deviceName: String?) =
+ EndGenericCastToOtherDeviceDialogDelegate(
+ endMediaProjectionDialogHelper,
+ context,
+ deviceName,
+ stopAction = this::stopMediaRouterCasting,
+ )
+
companion object {
@DrawableRes val CAST_TO_OTHER_DEVICE_ICON = R.drawable.ic_cast_connected
+ private const val TAG = "CastToOtherVM"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
index 20ebae72e01d..191c221f43c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
@@ -19,8 +19,11 @@ package com.android.systemui.statusbar.chips.mediaprojection.domain.interactor
import android.content.pm.PackageManager
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
import com.android.systemui.util.Utils
import javax.inject.Inject
@@ -45,12 +48,16 @@ constructor(
@Application private val scope: CoroutineScope,
private val mediaProjectionRepository: MediaProjectionRepository,
private val packageManager: PackageManager,
+ @StatusBarChipsLog private val logger: LogBuffer,
) {
val projection: StateFlow<ProjectionChipModel> =
mediaProjectionRepository.mediaProjectionState
.map { state ->
when (state) {
- is MediaProjectionState.NotProjecting -> ProjectionChipModel.NotProjecting
+ is MediaProjectionState.NotProjecting -> {
+ logger.log(TAG, LogLevel.INFO, {}, { "State: NotProjecting" })
+ ProjectionChipModel.NotProjecting
+ }
is MediaProjectionState.Projecting -> {
val type =
if (isProjectionToOtherDevice(state.hostPackage)) {
@@ -58,6 +65,16 @@ constructor(
} else {
ProjectionChipModel.Type.SHARE_TO_APP
}
+ logger.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ str1 = type.name
+ str2 = state.hostPackage
+ str3 = state.hostDeviceName
+ },
+ { "State: Projecting(type=$str1 hostPackage=$str2 hostDevice=$str3)" }
+ )
ProjectionChipModel.Projecting(type, state)
}
}
@@ -81,4 +98,8 @@ constructor(
// marked as going to a different device, even if that isn't always true. See b/321078669.
return Utils.isHeadlessRemoteDisplayProvider(packageManager, packageName)
}
+
+ companion object {
+ private const val TAG = "MediaProjection"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelper.kt
index 402306a12144..600436557efb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelper.kt
@@ -16,13 +16,8 @@
package com.android.systemui.statusbar.chips.mediaprojection.ui.view
-import android.annotation.StringRes
import android.app.ActivityManager
-import android.content.Context
import android.content.pm.PackageManager
-import android.text.Html
-import android.text.Html.FROM_HTML_MODE_LEGACY
-import android.text.TextUtils
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.statusbar.phone.SystemUIDialog
@@ -35,63 +30,38 @@ class EndMediaProjectionDialogHelper
constructor(
private val dialogFactory: SystemUIDialog.Factory,
private val packageManager: PackageManager,
- private val context: Context
) {
/** Creates a new [SystemUIDialog] using the given delegate. */
fun createDialog(delegate: SystemUIDialog.Delegate): SystemUIDialog {
return dialogFactory.create(delegate)
}
- /** See other [getDialogMessage]. */
- fun getDialogMessage(
- state: MediaProjectionState.Projecting,
- @StringRes genericMessageResId: Int,
- @StringRes specificAppMessageResId: Int,
- ): CharSequence {
+ fun getAppName(state: MediaProjectionState.Projecting): CharSequence? {
val specificTaskInfo =
if (state is MediaProjectionState.Projecting.SingleTask) {
state.task
} else {
null
}
- return getDialogMessage(specificTaskInfo, genericMessageResId, specificAppMessageResId)
+ return getAppName(specificTaskInfo)
+ }
+
+ fun getAppName(specificTaskInfo: ActivityManager.RunningTaskInfo?): CharSequence? {
+ val packageName = specificTaskInfo?.baseIntent?.component?.packageName ?: return null
+ return getAppName(packageName)
}
/**
- * Returns the message to show in the dialog based on the specific media projection state.
- *
- * @param genericMessageResId a res ID for a more generic "end projection" message
- * @param specificAppMessageResId a res ID for an "end projection" message that also lets us
- * specify which app is currently being projected.
+ * Returns the human-readable application name for the given package, or null if it couldn't be
+ * found for any reason.
*/
- fun getDialogMessage(
- specificTaskInfo: ActivityManager.RunningTaskInfo?,
- @StringRes genericMessageResId: Int,
- @StringRes specificAppMessageResId: Int,
- ): CharSequence {
- if (specificTaskInfo == null) {
- return context.getString(genericMessageResId)
- }
- val packageName =
- specificTaskInfo.baseIntent.component?.packageName
- ?: return context.getString(genericMessageResId)
+ fun getAppName(packageName: String): CharSequence? {
return try {
val appInfo = packageManager.getApplicationInfo(packageName, 0)
- val appName = appInfo.loadLabel(packageManager)
- getSpecificAppMessageText(specificAppMessageResId, appName)
+ appInfo.loadLabel(packageManager)
} catch (e: PackageManager.NameNotFoundException) {
// TODO(b/332662551): Log this error.
- context.getString(genericMessageResId)
+ null
}
}
-
- private fun getSpecificAppMessageText(
- @StringRes specificAppMessageResId: Int,
- appName: CharSequence,
- ): CharSequence {
- // https://developer.android.com/guide/topics/resources/string-resource#StylingWithHTML
- val escapedAppName = TextUtils.htmlEncode(appName.toString())
- val text = context.getString(specificAppMessageResId, escapedAppName)
- return Html.fromHtml(text, FROM_HTML_MODE_LEGACY)
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
index 43b1d1681a4c..28a8385e5f77 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
@@ -18,10 +18,13 @@ package com.android.systemui.statusbar.chips.screenrecord.domain.interactor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository
import com.android.systemui.screenrecord.data.model.ScreenRecordModel
import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
import com.android.systemui.statusbar.chips.screenrecord.domain.model.ScreenRecordChipModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -39,6 +42,7 @@ constructor(
@Application private val scope: CoroutineScope,
private val screenRecordRepository: ScreenRecordRepository,
private val mediaProjectionRepository: MediaProjectionRepository,
+ @StatusBarChipsLog private val logger: LogBuffer,
) {
val screenRecordState: StateFlow<ScreenRecordChipModel> =
// ScreenRecordRepository has the main "is the screen being recorded?" state, and
@@ -49,9 +53,19 @@ constructor(
mediaProjectionRepository.mediaProjectionState,
) { screenRecordState, mediaProjectionState ->
when (screenRecordState) {
- is ScreenRecordModel.DoingNothing -> ScreenRecordChipModel.DoingNothing
- is ScreenRecordModel.Starting ->
+ is ScreenRecordModel.DoingNothing -> {
+ logger.log(TAG, LogLevel.INFO, {}, { "State: DoingNothing" })
+ ScreenRecordChipModel.DoingNothing
+ }
+ is ScreenRecordModel.Starting -> {
+ logger.log(
+ TAG,
+ LogLevel.INFO,
+ { long1 = screenRecordState.millisUntilStarted },
+ { "State: Starting($long1)" }
+ )
ScreenRecordChipModel.Starting(screenRecordState.millisUntilStarted)
+ }
is ScreenRecordModel.Recording -> {
val recordedTask =
if (
@@ -61,6 +75,12 @@ constructor(
} else {
null
}
+ logger.log(
+ TAG,
+ LogLevel.INFO,
+ { str1 = recordedTask?.baseIntent?.component?.packageName },
+ { "State: Recording(taskPackage=$str1)" }
+ )
ScreenRecordChipModel.Recording(recordedTask)
}
}
@@ -71,4 +91,8 @@ constructor(
fun stopRecording() {
scope.launch { screenRecordRepository.stopRecording() }
}
+
+ companion object {
+ private const val TAG = "ScreenRecord"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegate.kt
index 9adbff9d304a..1eca827d55c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegate.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.chips.screenrecord.ui.view
import android.app.ActivityManager
+import android.content.Context
import android.os.Bundle
import com.android.systemui.res.R
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
@@ -26,6 +27,7 @@ import com.android.systemui.statusbar.phone.SystemUIDialog
/** A dialog that lets the user stop an ongoing screen recording. */
class EndScreenRecordingDialogDelegate(
private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+ val context: Context,
private val stopAction: () -> Unit,
private val recordedTask: ActivityManager.RunningTaskInfo?,
) : SystemUIDialog.Delegate {
@@ -35,16 +37,18 @@ class EndScreenRecordingDialogDelegate(
}
override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
+ val appName = endMediaProjectionDialogHelper.getAppName(recordedTask)
+ val message =
+ if (appName != null) {
+ context.getString(R.string.screenrecord_stop_dialog_message_specific_app, appName)
+ } else {
+ context.getString(R.string.screenrecord_stop_dialog_message)
+ }
+
with(dialog) {
setIcon(ScreenRecordChipViewModel.ICON)
setTitle(R.string.screenrecord_stop_dialog_title)
- setMessage(
- endMediaProjectionDialogHelper.getDialogMessage(
- recordedTask,
- genericMessageResId = R.string.screenrecord_stop_dialog_message,
- specificAppMessageResId = R.string.screenrecord_stop_dialog_message_specific_app
- )
- )
+ setMessage(message)
// No custom on-click, because the dialog will automatically be dismissed when the
// button is clicked anyway.
setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
index 53679f1c0a6c..0c349810257a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
@@ -17,14 +17,17 @@
package com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel
import android.app.ActivityManager
+import android.content.Context
import androidx.annotation.DrawableRes
-import com.android.systemui.animation.DialogTransitionAnimator
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.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
import com.android.systemui.res.R
import com.android.systemui.screenrecord.data.model.ScreenRecordModel.Starting.Companion.toCountdownSeconds
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.ScreenRecordChipInteractor
import com.android.systemui.statusbar.chips.screenrecord.domain.model.ScreenRecordChipModel
@@ -47,10 +50,11 @@ class ScreenRecordChipViewModel
@Inject
constructor(
@Application private val scope: CoroutineScope,
+ private val context: Context,
private val interactor: ScreenRecordChipInteractor,
private val systemClock: SystemClock,
private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
- private val dialogTransitionAnimator: DialogTransitionAnimator,
+ @StatusBarChipsLog private val logger: LogBuffer,
) : OngoingActivityChipViewModel {
override val chip: StateFlow<OngoingActivityChipModel> =
interactor.screenRecordState
@@ -76,7 +80,8 @@ constructor(
startTimeMs = systemClock.elapsedRealtime(),
createDialogLaunchOnClickListener(
createDelegate(state.recordedTask),
- dialogTransitionAnimator,
+ logger,
+ TAG,
),
)
}
@@ -90,12 +95,19 @@ constructor(
): EndScreenRecordingDialogDelegate {
return EndScreenRecordingDialogDelegate(
endMediaProjectionDialogHelper,
- stopAction = interactor::stopRecording,
+ context,
+ stopAction = this::stopRecording,
recordedTask,
)
}
+ private fun stopRecording() {
+ logger.log(TAG, LogLevel.INFO, {}, { "Stop recording requested" })
+ interactor.stopRecording()
+ }
+
companion object {
@DrawableRes val ICON = R.drawable.ic_screenrecord
+ private const val TAG = "ScreenRecordVM"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt
index 7e7ef402b226..564f20e4b596 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt
@@ -16,7 +16,9 @@
package com.android.systemui.statusbar.chips.sharetoapp.ui.view
+import android.content.Context
import android.os.Bundle
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.res.R
import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
@@ -26,6 +28,7 @@ import com.android.systemui.statusbar.phone.SystemUIDialog
/** A dialog that lets the user stop an ongoing share-screen-to-app event. */
class EndShareToAppDialogDelegate(
private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+ private val context: Context,
private val stopAction: () -> Unit,
private val state: ProjectionChipModel.Projecting,
) : SystemUIDialog.Delegate {
@@ -37,13 +40,7 @@ class EndShareToAppDialogDelegate(
with(dialog) {
setIcon(SHARE_TO_APP_ICON)
setTitle(R.string.share_to_app_stop_dialog_title)
- setMessage(
- endMediaProjectionDialogHelper.getDialogMessage(
- state.projectionState,
- genericMessageResId = R.string.share_to_app_stop_dialog_message,
- specificAppMessageResId = R.string.share_to_app_stop_dialog_message_specific_app
- )
- )
+ setMessage(getMessage())
// No custom on-click, because the dialog will automatically be dismissed when the
// button is clicked anyway.
setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
@@ -52,4 +49,32 @@ class EndShareToAppDialogDelegate(
}
}
}
+
+ private fun getMessage(): String {
+ return if (state.projectionState is MediaProjectionState.Projecting.SingleTask) {
+ // If a single app is being shared, use the name of the app being shared in the dialog
+ val appBeingSharedName =
+ endMediaProjectionDialogHelper.getAppName(state.projectionState)
+ if (appBeingSharedName != null) {
+ context.getString(
+ R.string.share_to_app_stop_dialog_message_single_app_specific,
+ appBeingSharedName,
+ )
+ } else {
+ context.getString(R.string.share_to_app_stop_dialog_message_single_app_generic)
+ }
+ } else {
+ // Otherwise, use the name of the app *receiving* the share
+ val hostAppName =
+ endMediaProjectionDialogHelper.getAppName(state.projectionState.hostPackage)
+ if (hostAppName != null) {
+ context.getString(
+ R.string.share_to_app_stop_dialog_message_entire_screen_with_host_app,
+ hostAppName
+ )
+ } else {
+ context.getString(R.string.share_to_app_stop_dialog_message_entire_screen)
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
index 8aef5a4e7629..ddebd3a0e3c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
@@ -16,13 +16,16 @@
package com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel
+import android.content.Context
import androidx.annotation.DrawableRes
-import com.android.systemui.animation.DialogTransitionAnimator
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.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractor
import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
@@ -48,10 +51,11 @@ class ShareToAppChipViewModel
@Inject
constructor(
@Application private val scope: CoroutineScope,
+ private val context: Context,
private val mediaProjectionChipInteractor: MediaProjectionChipInteractor,
private val systemClock: SystemClock,
- private val dialogTransitionAnimator: DialogTransitionAnimator,
private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+ @StatusBarChipsLog private val logger: LogBuffer,
) : OngoingActivityChipViewModel {
override val chip: StateFlow<OngoingActivityChipModel> =
mediaProjectionChipInteractor.projection
@@ -72,6 +76,7 @@ constructor(
/** Stops the currently active projection. */
private fun stopProjecting() {
+ logger.log(TAG, LogLevel.INFO, {}, { "Stop sharing requested" })
mediaProjectionChipInteractor.stopProjecting()
}
@@ -87,21 +92,20 @@ constructor(
colors = ColorsModel.Red,
// TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
startTimeMs = systemClock.elapsedRealtime(),
- createDialogLaunchOnClickListener(
- createShareToAppDialogDelegate(state),
- dialogTransitionAnimator
- ),
+ createDialogLaunchOnClickListener(createShareToAppDialogDelegate(state), logger, TAG),
)
}
private fun createShareToAppDialogDelegate(state: ProjectionChipModel.Projecting) =
EndShareToAppDialogDelegate(
endMediaProjectionDialogHelper,
+ context,
stopAction = this::stopProjecting,
state,
)
companion object {
@DrawableRes val SHARE_TO_APP_ICON = R.drawable.ic_present_to_all
+ private const val TAG = "ShareToAppVM"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
index e8d895c3c266..40f86f924cd5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
@@ -21,8 +21,13 @@ import com.android.systemui.common.shared.model.Icon
/** Model representing the display of an ongoing activity as a chip in the status bar. */
sealed class OngoingActivityChipModel {
+ /** Condensed name representing the model, used for logs. */
+ abstract val logName: String
+
/** This chip shouldn't be shown. */
- data object Hidden : OngoingActivityChipModel()
+ data object Hidden : OngoingActivityChipModel() {
+ override val logName = "Hidden"
+ }
/** This chip should be shown with the given information. */
abstract class Shown(
@@ -42,7 +47,9 @@ sealed class OngoingActivityChipModel {
override val icon: Icon,
override val colors: ColorsModel,
override val onClickListener: View.OnClickListener?,
- ) : Shown(icon, colors, onClickListener)
+ ) : Shown(icon, colors, onClickListener) {
+ override val logName = "Shown.Icon"
+ }
/** The chip shows a timer, counting up from [startTimeMs]. */
data class Timer(
@@ -59,7 +66,9 @@ sealed class OngoingActivityChipModel {
*/
val startTimeMs: Long,
override val onClickListener: View.OnClickListener?,
- ) : Shown(icon, colors, onClickListener)
+ ) : Shown(icon, colors, onClickListener) {
+ override val logName = "Shown.Timer"
+ }
/**
* This chip shows a countdown using [secondsUntilStarted]. Used to inform users that an
@@ -69,6 +78,8 @@ sealed class OngoingActivityChipModel {
override val colors: ColorsModel,
/** The number of seconds until an event is started. */
val secondsUntilStarted: Long,
- ) : Shown(icon = null, colors, onClickListener = null)
+ ) : Shown(icon = null, colors, onClickListener = null) {
+ override val logName = "Shown.Countdown"
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt
index 0dbf5d613038..ee010f7a818b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt
@@ -17,10 +17,10 @@
package com.android.systemui.statusbar.chips.ui.viewmodel
import android.view.View
-import com.android.systemui.animation.DialogTransitionAnimator
-import com.android.systemui.res.R
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
-import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.phone.SystemUIDialog
import kotlinx.coroutines.flow.StateFlow
@@ -36,19 +36,13 @@ interface OngoingActivityChipViewModel {
/** Creates a chip click listener that launches a dialog created by [dialogDelegate]. */
fun createDialogLaunchOnClickListener(
dialogDelegate: SystemUIDialog.Delegate,
- dialogTransitionAnimator: DialogTransitionAnimator,
+ @StatusBarChipsLog logger: LogBuffer,
+ tag: String,
): View.OnClickListener {
- return View.OnClickListener { view ->
+ return View.OnClickListener { _ ->
+ logger.log(tag, LogLevel.INFO, {}, { "Chip clicked" })
val dialog = dialogDelegate.createDialog()
- val launchableView =
- view.requireViewById<ChipBackgroundContainer>(
- R.id.ongoing_activity_chip_background
- )
- // TODO(b/343699052): This makes a beautiful animate-in, but the
- // animate-out looks odd because the dialog animates back into the chip
- // but then the chip disappears. If we aren't able to address
- // b/343699052 in time for launch, we should just use `dialog.show`.
- dialogTransitionAnimator.showFromView(dialog, launchableView)
+ dialog.show()
}
}
}
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 9c8086fd073d..15c348ed2f67 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
@@ -18,6 +18,9 @@ package com.android.systemui.statusbar.chips.ui.viewmodel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
import com.android.systemui.statusbar.chips.call.ui.viewmodel.CallChipViewModel
import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.CastToOtherDeviceChipViewModel
import com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel.ScreenRecordChipViewModel
@@ -45,6 +48,7 @@ constructor(
shareToAppChipViewModel: ShareToAppChipViewModel,
castToOtherDeviceChipViewModel: CastToOtherDeviceChipViewModel,
callChipViewModel: CallChipViewModel,
+ @StatusBarChipsLog private val logger: LogBuffer,
) {
/**
* A flow modeling the chip that should be shown in the status bar after accounting for possibly
@@ -60,6 +64,17 @@ constructor(
castToOtherDeviceChipViewModel.chip,
callChipViewModel.chip,
) { screenRecord, shareToApp, castToOtherDevice, call ->
+ logger.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ str1 = screenRecord.logName
+ str2 = shareToApp.logName
+ str3 = castToOtherDevice.logName
+ },
+ { "Chips: ScreenRecord=$str1 > ShareToApp=$str2 > CastToOther=$str3..." },
+ )
+ logger.log(TAG, LogLevel.INFO, { str1 = call.logName }, { "... > Call=$str1" })
// This `when` statement shows the priority order of the chips
when {
// Screen recording also activates the media projection APIs, so whenever the
@@ -76,4 +91,8 @@ constructor(
// for those timers to get reset for any reason. So, as soon as any subscriber has
// requested the chip information, we need to maintain it forever. See b/347726238.
.stateIn(scope, SharingStarted.Lazily, OngoingActivityChipModel.Hidden)
+
+ companion object {
+ private const val TAG = "ChipsViewModel"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
index ca7308161e14..9ca110e8c561 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
@@ -23,6 +23,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac
import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@@ -90,17 +91,22 @@ constructor(
/** Occlusion state to apply whenever a keyguard transition is FINISHED. */
private val occlusionStateFromFinishedStep =
- keyguardTransitionInteractor.finishedKeyguardTransitionStep
- .sample(keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop, ::Pair)
- .map { (finishedStep, showWhenLockedOnTop) ->
+ combine(
+ keyguardTransitionInteractor.isFinishedIn(
+ scene = Scenes.Gone,
+ stateWithoutSceneContainer = KeyguardState.GONE,
+ ),
+ keyguardTransitionInteractor.isFinishedIn(KeyguardState.OCCLUDED),
+ keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop,
+ ::Triple
+ )
+ .map { (isOnGone, isOnOccluded, showWhenLockedOnTop) ->
// If we're FINISHED in OCCLUDED, we want to render as occluded. We also need to
// remain occluded if a SHOW_WHEN_LOCKED activity is on the top of the task stack,
// and we're in any state other than GONE. This is necessary, for example, when we
// transition from OCCLUDED to a bouncer state. Otherwise, we should not be
// occluded.
- val occluded =
- finishedStep.to == KeyguardState.OCCLUDED ||
- (showWhenLockedOnTop && finishedStep.to != KeyguardState.GONE)
+ val occluded = isOnOccluded || (showWhenLockedOnTop && !isOnGone)
OccludedState(occluded = occluded, animate = false)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
index f62b24aa96a3..3dcaff3de35a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
@@ -21,6 +21,7 @@ import android.provider.DeviceConfig
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_USE_PEOPLE_FILTERING
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.collection.NotificationClassificationFlag
import com.android.systemui.statusbar.notification.shared.NotificationMinimalismPrototype
import com.android.systemui.statusbar.notification.shared.PriorityPeopleSection
import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
@@ -51,7 +52,8 @@ constructor(val proxy: DeviceConfigProxy, val context: Context) {
}
fun getNotificationBuckets(): IntArray {
- if (PriorityPeopleSection.isEnabled || NotificationMinimalismPrototype.V2.isEnabled) {
+ if (PriorityPeopleSection.isEnabled || NotificationMinimalismPrototype.V2.isEnabled
+ || NotificationClassificationFlag.isEnabled) {
// We don't need this list to be adaptive, it can be the superset of all features.
return PriorityBucket.getAllInOrder()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 0bb18d704ac7..9240c1c7a113 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -469,10 +469,24 @@ constructor(
get() = state
override fun onPanelExpansionChanged(event: ShadeExpansionChangeEvent) {
- val collapsedEnough = event.fraction <= 0.9f
- if (collapsedEnough != this.collapsedEnoughToHide) {
- val couldShowPulsingHuns = canShowPulsingHuns
- this.collapsedEnoughToHide = collapsedEnough
+ val fraction = event.fraction
+
+ val wasCollapsedEnoughToHide = collapsedEnoughToHide
+ val isCollapsedEnoughToHide = fraction <= 0.9f
+
+ if (isCollapsedEnoughToHide != wasCollapsedEnoughToHide) {
+ val couldShowPulsingHuns = this.canShowPulsingHuns
+ this.collapsedEnoughToHide = isCollapsedEnoughToHide
+ val canShowPulsingHuns = this.canShowPulsingHuns
+
+ logger.logOnPanelExpansionChanged(
+ fraction,
+ wasCollapsedEnoughToHide,
+ isCollapsedEnoughToHide,
+ couldShowPulsingHuns,
+ canShowPulsingHuns
+ )
+
if (couldShowPulsingHuns && !canShowPulsingHuns) {
updateNotificationVisibility(animate = true, increaseSpeed = true)
headsUpManager.releaseAllImmediately()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
index 9619bea5efd4..752ec2d2840c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
@@ -182,6 +182,31 @@ constructor(@NotificationLockscreenLog private val buffer: LogBuffer) {
)
}
+ fun logOnPanelExpansionChanged(
+ fraction: Float,
+ wasCollapsedEnoughToHide: Boolean,
+ isCollapsedEnoughToHide: Boolean,
+ couldShowPulsingHuns: Boolean,
+ canShowPulsingHuns: Boolean
+ ) {
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ double1 = fraction.toDouble()
+ bool1 = wasCollapsedEnoughToHide
+ bool2 = isCollapsedEnoughToHide
+ bool3 = couldShowPulsingHuns
+ bool4 = canShowPulsingHuns
+ },
+ {
+ "onPanelExpansionChanged($double1):" +
+ " collapsedEnoughToHide: $bool1 -> $bool2," +
+ " canShowPulsingHuns: $bool3 -> $bool4"
+ }
+ )
+ }
+
fun logSetWakingUp(wakingUp: Boolean, requestDelayedAnimation: Boolean) {
buffer.log(
TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationClassificationFlag.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationClassificationFlag.kt
new file mode 100644
index 000000000000..139347c86d54
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationClassificationFlag.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.notification.collection
+
+import android.service.notification.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/**
+ * Helper for android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION
+ */
+@Suppress("NOTHING_TO_INLINE")
+object NotificationClassificationFlag {
+ const val FLAG_NAME = Flags.FLAG_NOTIFICATION_CLASSIFICATION
+
+ /** A token used for dependency declaration */
+ val token: FlagToken
+ get() = FlagToken(FLAG_NAME, isEnabled)
+
+ /** Are sections sorted by time? */
+ @JvmStatic
+ inline val isEnabled
+ get() = Flags.notificationClassification()
+
+ /**
+ * Called to ensure code is only run when the flag is enabled. This protects users from the
+ * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+ * build to ensure that the refactor author catches issues in testing.
+ */
+ @JvmStatic
+ inline fun isUnexpectedlyInLegacyMode() =
+ RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+ /**
+ * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+ * the flag is enabled to ensure that the refactor author catches issues in testing.
+ */
+ @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/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index f98a88f5328b..e48c28d3f3ee 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
@@ -698,7 +698,7 @@ public final class NotificationEntry extends ListEntry implements NotificationRo
}
public void setHeadsUpIsVisible() {
- if (row != null) row.setHeadsUpIsVisible();
+ if (row != null) row.markHeadsUpSeen();
}
//TODO: i'm imagining a world where this isn't just the row, but I could be rwong
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinator.kt
new file mode 100644
index 000000000000..244c5946c21e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinator.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.notification.collection.coordinator
+
+import android.app.NotificationChannel.NEWS_ID
+import android.app.NotificationChannel.PROMOTIONS_ID
+import android.app.NotificationChannel.RECS_ID
+import android.app.NotificationChannel.SOCIAL_MEDIA_ID
+import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
+import com.android.systemui.statusbar.notification.collection.render.NodeController
+import com.android.systemui.statusbar.notification.dagger.NewsHeader
+import com.android.systemui.statusbar.notification.dagger.PromoHeader
+import com.android.systemui.statusbar.notification.dagger.RecsHeader
+import com.android.systemui.statusbar.notification.dagger.SocialHeader
+import com.android.systemui.statusbar.notification.stack.BUCKET_NEWS
+import com.android.systemui.statusbar.notification.stack.BUCKET_PROMO
+import com.android.systemui.statusbar.notification.stack.BUCKET_RECS
+import com.android.systemui.statusbar.notification.stack.BUCKET_SOCIAL
+import javax.inject.Inject
+
+/**
+ * Coordinator for sections derived from NotificationAssistantService classification.
+ */
+@CoordinatorScope
+class BundleCoordinator @Inject constructor(
+ @NewsHeader private val newsHeaderController: NodeController,
+ @SocialHeader private val socialHeaderController: NodeController,
+ @RecsHeader private val recsHeaderController: NodeController,
+ @PromoHeader private val promoHeaderController: NodeController,
+) : Coordinator {
+
+ val newsSectioner =
+ object : NotifSectioner("News", BUCKET_NEWS) {
+ override fun isInSection(entry: ListEntry): Boolean {
+ return entry.representativeEntry?.channel?.id == NEWS_ID
+ }
+
+ override fun getHeaderNodeController(): NodeController? {
+ return newsHeaderController
+ }
+ }
+
+ val socialSectioner =
+ object : NotifSectioner("Social", BUCKET_SOCIAL) {
+ override fun isInSection(entry: ListEntry): Boolean {
+ return entry.representativeEntry?.channel?.id == SOCIAL_MEDIA_ID
+ }
+
+ override fun getHeaderNodeController(): NodeController? {
+ return socialHeaderController
+ }
+ }
+
+ val recsSectioner =
+ object : NotifSectioner("Recommendations", BUCKET_RECS) {
+ override fun isInSection(entry: ListEntry): Boolean {
+ return entry.representativeEntry?.channel?.id == RECS_ID
+ }
+
+ override fun getHeaderNodeController(): NodeController? {
+ return recsHeaderController
+ }
+ }
+
+ val promoSectioner =
+ object : NotifSectioner("Promotions", BUCKET_PROMO) {
+ override fun isInSection(entry: ListEntry): Boolean {
+ return entry.representativeEntry?.channel?.id == PROMOTIONS_ID
+ }
+
+ override fun getHeaderNodeController(): NodeController? {
+ return promoHeaderController
+ }
+ }
+
+ override fun attach(pipeline: NotifPipeline) {
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
index 5a1146d2472f..55c6790d4fb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.statusbar.notification.collection.coordinator
import android.app.NotificationManager
@@ -27,9 +25,10 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.data.repository.KeyguardRepository
-import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.expansionChanges
import com.android.systemui.statusbar.notification.collection.GroupEntry
@@ -58,7 +57,6 @@ import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
@@ -89,7 +87,7 @@ constructor(
private val headsUpManager: HeadsUpManager,
private val keyguardNotificationVisibilityProvider: KeyguardNotificationVisibilityProvider,
private val keyguardRepository: KeyguardRepository,
- private val keyguardTransitionRepository: KeyguardTransitionRepository,
+ private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val logger: KeyguardCoordinatorLogger,
@Application private val scope: CoroutineScope,
private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
@@ -126,8 +124,12 @@ constructor(
private suspend fun trackSeenNotifications() {
// Whether or not keyguard is visible (or occluded).
val isKeyguardPresent: Flow<Boolean> =
- keyguardTransitionRepository.transitions
- .map { step -> step.to != KeyguardState.GONE }
+ keyguardTransitionInteractor
+ .transitionValue(
+ scene = Scenes.Gone,
+ stateWithoutSceneContainer = KeyguardState.GONE,
+ )
+ .map { it == 0f }
.distinctUntilChanged()
.onEach { trackingUnseen -> logger.logTrackingUnseen(trackingUnseen) }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
index e41352254bac..e0389820aedf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
@@ -17,10 +17,7 @@ package com.android.systemui.statusbar.notification.collection.coordinator
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
-import com.android.systemui.statusbar.notification.collection.NotifPipeline
-import com.android.systemui.statusbar.notification.collection.PipelineDumpable
-import com.android.systemui.statusbar.notification.collection.PipelineDumper
-import com.android.systemui.statusbar.notification.collection.SortBySectionTimeFlag
+import com.android.systemui.statusbar.notification.collection.*
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
@@ -69,6 +66,7 @@ constructor(
dismissibilityCoordinator: DismissibilityCoordinator,
dreamCoordinator: DreamCoordinator,
statsLoggerCoordinator: NotificationStatsLoggerCoordinator,
+ bundleCoordinator: BundleCoordinator,
) : NotifCoordinators {
private val mCoreCoordinators: MutableList<CoreCoordinator> = ArrayList()
@@ -132,6 +130,12 @@ constructor(
mOrderedSections.add(conversationCoordinator.peopleSilentSectioner) // People Silent
}
mOrderedSections.add(rankingCoordinator.alertingSectioner) // Alerting
+ if (NotificationClassificationFlag.isEnabled) {
+ mOrderedSections.add(bundleCoordinator.newsSectioner);
+ mOrderedSections.add(bundleCoordinator.socialSectioner);
+ mOrderedSections.add(bundleCoordinator.recsSectioner);
+ mOrderedSections.add(bundleCoordinator.promoSectioner);
+ }
mOrderedSections.add(rankingCoordinator.silentSectioner) // Silent
mOrderedSections.add(rankingCoordinator.minimizedSectioner) // Minimized
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt
index f166d32812ae..5adf31b75fa7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt
@@ -13,18 +13,12 @@ class VisualStabilityProvider @Inject constructor() {
/** The subset of active listeners which are temporary (will be removed after called) */
private val temporaryListeners = ArraySet<OnReorderingAllowedListener>()
- private val banListeners = ListenerSet<OnReorderingBannedListener>()
-
var isReorderingAllowed = true
set(value) {
if (field != value) {
field = value
if (value) {
notifyReorderingAllowed()
- } else {
- banListeners.forEach { listener ->
- listener.onReorderingBanned()
- }
}
}
}
@@ -44,10 +38,6 @@ class VisualStabilityProvider @Inject constructor() {
allListeners.addIfAbsent(listener)
}
- fun addPersistentReorderingBannedListener(listener: OnReorderingBannedListener) {
- banListeners.addIfAbsent(listener)
- }
-
/** Add a listener which will be removed when it is called. */
fun addTemporaryReorderingAllowedListener(listener: OnReorderingAllowedListener) {
// Only add to the temporary set if it was added to the global set
@@ -67,8 +57,3 @@ class VisualStabilityProvider @Inject constructor() {
fun interface OnReorderingAllowedListener {
fun onReorderingAllowed()
}
-
-fun interface OnReorderingBannedListener {
- fun onReorderingBanned()
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
index ca43591e0776..e661090011c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
@@ -80,6 +80,50 @@ object NotificationSectionHeadersModule {
.build()
@Provides
+ @NewsHeader
+ @SysUISingleton
+ @JvmStatic fun providesNewsHeaderSubcomponent(
+ builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+ ) = builder.get()
+ .nodeLabel("news header")
+ .headerText(com.android.internal.R.string.news_notification_channel_label)
+ .clickIntentAction(Settings.ACTION_NOTIFICATION_SETTINGS)
+ .build()
+
+ @Provides
+ @SocialHeader
+ @SysUISingleton
+ @JvmStatic fun providesSocialHeaderSubcomponent(
+ builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+ ) = builder.get()
+ .nodeLabel("social header")
+ .headerText(com.android.internal.R.string.social_notification_channel_label)
+ .clickIntentAction(Settings.ACTION_NOTIFICATION_SETTINGS)
+ .build()
+
+ @Provides
+ @RecsHeader
+ @SysUISingleton
+ @JvmStatic fun providesRecsHeaderSubcomponent(
+ builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+ ) = builder.get()
+ .nodeLabel("recs header")
+ .headerText(com.android.internal.R.string.recs_notification_channel_label)
+ .clickIntentAction(Settings.ACTION_NOTIFICATION_SETTINGS)
+ .build()
+
+ @Provides
+ @PromoHeader
+ @SysUISingleton
+ @JvmStatic fun providesPromoHeaderSubcomponent(
+ builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+ ) = builder.get()
+ .nodeLabel("promo header")
+ .headerText(com.android.internal.R.string.promotional_notification_channel_label)
+ .clickIntentAction(Settings.ACTION_NOTIFICATION_SETTINGS)
+ .build()
+
+ @Provides
@SilentHeader
@JvmStatic fun providesSilentHeaderNodeController(
@SilentHeader subcomponent: SectionHeaderControllerSubcomponent
@@ -126,6 +170,54 @@ object NotificationSectionHeadersModule {
@JvmStatic fun providesIncomingHeaderController(
@IncomingHeader subcomponent: SectionHeaderControllerSubcomponent
) = subcomponent.headerController
+
+ @Provides
+ @NewsHeader
+ @JvmStatic fun providesNewsHeaderNodeController(
+ @NewsHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.nodeController
+
+ @Provides
+ @NewsHeader
+ @JvmStatic fun providesNewsHeaderController(
+ @NewsHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.headerController
+
+ @Provides
+ @SocialHeader
+ @JvmStatic fun providesSocialHeaderNodeController(
+ @SocialHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.nodeController
+
+ @Provides
+ @SocialHeader
+ @JvmStatic fun providesSocialHeaderController(
+ @SocialHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.headerController
+
+ @Provides
+ @RecsHeader
+ @JvmStatic fun providesRecsHeaderNodeController(
+ @RecsHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.nodeController
+
+ @Provides
+ @RecsHeader
+ @JvmStatic fun providesRecsHeaderController(
+ @RecsHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.headerController
+
+ @Provides
+ @PromoHeader
+ @JvmStatic fun providesPromoHeaderNodeController(
+ @PromoHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.nodeController
+
+ @Provides
+ @PromoHeader
+ @JvmStatic fun providesPromoHeaderController(
+ @PromoHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.headerController
}
@Subcomponent(modules = [ SectionHeaderBindingModule::class ])
@@ -183,3 +275,19 @@ annotation class HeaderClickAction
@Scope
@Retention(AnnotationRetention.BINARY)
annotation class SectionHeaderScope
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class NewsHeader
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class SocialHeader
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class RecsHeader
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class PromoHeader \ No newline at end of file
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 762c9a14d40e..ca5f49d28823 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
@@ -18,12 +18,14 @@ package com.android.systemui.statusbar.notification.dagger;
import android.app.NotificationManager;
import android.content.Context;
+import android.os.Handler;
import android.service.notification.NotificationListenerService;
import com.android.internal.jank.InteractionJankMonitor;
-import com.android.settingslib.statusbar.notification.data.repository.ZenModeRepository;
-import com.android.settingslib.statusbar.notification.data.repository.ZenModeRepositoryImpl;
-import com.android.settingslib.statusbar.notification.domain.interactor.NotificationsSoundPolicyInteractor;
+import com.android.settingslib.notification.data.repository.ZenModeRepository;
+import com.android.settingslib.notification.data.repository.ZenModeRepositoryImpl;
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor;
+import com.android.settingslib.notification.modes.ZenModesBackend;
import com.android.systemui.CoreStartable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Application;
@@ -283,9 +285,12 @@ public interface NotificationsModule {
Context context,
NotificationManager notificationManager,
@Application CoroutineScope coroutineScope,
- @Background CoroutineContext coroutineContext) {
+ @Background CoroutineContext coroutineContext,
+ @Background Handler handler
+ ) {
return new ZenModeRepositoryImpl(context, notificationManager,
- coroutineScope, coroutineContext);
+ ZenModesBackend.getInstance(context), context.getContentResolver(),
+ coroutineScope, coroutineContext, handler);
}
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt
index e9306a5bd209..069ae9381012 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt
@@ -41,4 +41,7 @@ interface HeadsUpRepository {
val activeHeadsUpRows: Flow<Set<HeadsUpRowRepository>>
fun setHeadsUpAnimatingAway(animatingAway: Boolean)
+
+ /** Snooze the currently pinned HUN. */
+ fun snooze()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
index 4a6553f724c2..bf44b9f3cf78 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
@@ -25,6 +25,7 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.data.repository.HeadsUpRepository
import com.android.systemui.statusbar.notification.data.repository.HeadsUpRowRepository
import com.android.systemui.statusbar.notification.shared.HeadsUpRowKey
+import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -46,37 +47,54 @@ constructor(
val topHeadsUpRow: Flow<HeadsUpRowKey?> = headsUpRepository.topHeadsUpRow
/** Set of currently pinned top-level heads up rows to be displayed. */
- val pinnedHeadsUpRows: Flow<Set<HeadsUpRowKey>> =
- headsUpRepository.activeHeadsUpRows.flatMapLatest { repositories ->
- if (repositories.isNotEmpty()) {
- val toCombine: List<Flow<Pair<HeadsUpRowRepository, Boolean>>> =
- repositories.map { repo -> repo.isPinned.map { isPinned -> repo to isPinned } }
- combine(toCombine) { pairs ->
- pairs.filter { (_, isPinned) -> isPinned }.map { (repo, _) -> repo }.toSet()
+ val pinnedHeadsUpRows: Flow<Set<HeadsUpRowKey>> by lazy {
+ if (NotificationsHeadsUpRefactor.isUnexpectedlyInLegacyMode()) {
+ flowOf(emptySet())
+ } else {
+ headsUpRepository.activeHeadsUpRows.flatMapLatest { repositories ->
+ if (repositories.isNotEmpty()) {
+ val toCombine: List<Flow<Pair<HeadsUpRowRepository, Boolean>>> =
+ repositories.map { repo ->
+ repo.isPinned.map { isPinned -> repo to isPinned }
+ }
+ combine(toCombine) { pairs ->
+ pairs.filter { (_, isPinned) -> isPinned }.map { (repo, _) -> repo }.toSet()
+ }
+ } else {
+ // if the set is empty, there are no flows to combine
+ flowOf(emptySet())
}
- } else {
- // if the set is empty, there are no flows to combine
- flowOf(emptySet())
}
}
+ }
/** Are there any pinned heads up rows to display? */
- val hasPinnedRows: Flow<Boolean> =
- headsUpRepository.activeHeadsUpRows.flatMapLatest { rows ->
- if (rows.isNotEmpty()) {
- combine(rows.map { it.isPinned }) { pins -> pins.any { it } }
- } else {
- // if the set is empty, there are no flows to combine
- flowOf(false)
+ val hasPinnedRows: Flow<Boolean> by lazy {
+ if (NotificationsHeadsUpRefactor.isUnexpectedlyInLegacyMode()) {
+ flowOf(false)
+ } else {
+ headsUpRepository.activeHeadsUpRows.flatMapLatest { rows ->
+ if (rows.isNotEmpty()) {
+ combine(rows.map { it.isPinned }) { pins -> pins.any { it } }
+ } else {
+ // if the set is empty, there are no flows to combine
+ flowOf(false)
+ }
}
}
+ }
- val isHeadsUpOrAnimatingAway: Flow<Boolean> =
- combine(hasPinnedRows, headsUpRepository.isHeadsUpAnimatingAway) {
- hasPinnedRows,
- animatingAway ->
- hasPinnedRows || animatingAway
+ val isHeadsUpOrAnimatingAway: Flow<Boolean> by lazy {
+ if (NotificationsHeadsUpRefactor.isUnexpectedlyInLegacyMode()) {
+ flowOf(false)
+ } else {
+ combine(hasPinnedRows, headsUpRepository.isHeadsUpAnimatingAway) {
+ hasPinnedRows,
+ animatingAway ->
+ hasPinnedRows || animatingAway
+ }
}
+ }
private val canShowHeadsUp: Flow<Boolean> =
combine(
@@ -94,17 +112,29 @@ constructor(
}
}
- val showHeadsUpStatusBar: Flow<Boolean> =
- combine(hasPinnedRows, canShowHeadsUp) { hasPinnedRows, canShowHeadsUp ->
- hasPinnedRows && canShowHeadsUp
+ val showHeadsUpStatusBar: Flow<Boolean> by lazy {
+ if (NotificationsHeadsUpRefactor.isUnexpectedlyInLegacyMode()) {
+ flowOf(false)
+ } else {
+ combine(hasPinnedRows, canShowHeadsUp) { hasPinnedRows, canShowHeadsUp ->
+ hasPinnedRows && canShowHeadsUp
+ }
}
+ }
fun headsUpRow(key: HeadsUpRowKey): HeadsUpRowInteractor =
HeadsUpRowInteractor(key as HeadsUpRowRepository)
+
fun elementKeyFor(key: HeadsUpRowKey) = (key as HeadsUpRowRepository).elementKey
+
fun setHeadsUpAnimatingAway(animatingAway: Boolean) {
headsUpRepository.setHeadsUpAnimatingAway(animatingAway)
}
+
+ /** Snooze the currently pinned HUN. */
+ fun snooze() {
+ headsUpRepository.snooze()
+ }
}
class HeadsUpRowInteractor(repository: HeadsUpRowRepository)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
index 5e91786e4160..e04e0facc766 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
@@ -39,6 +39,7 @@ import android.os.SystemProperties
import android.provider.Settings
import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED
import android.provider.Settings.Global.HEADS_UP_OFF
+import android.service.notification.Flags
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage
@@ -221,6 +222,15 @@ class HunGroupAlertBehaviorSuppressor() :
entry.sbn.let { it.isGroup && it.notification.suppressAlertingDueToGrouping() }
}
+class HunSilentNotificationSuppressor() :
+ VisualInterruptionFilter(
+ types = setOf(PEEK, PULSE),
+ reason = "notification isSilent"
+ ) {
+ override fun shouldSuppress(entry: NotificationEntry) =
+ entry.sbn.let { Flags.notificationSilentFlag() && it.notification.isSilent }
+}
+
class HunJustLaunchedFsiSuppressor() :
VisualInterruptionFilter(types = setOf(PEEK, PULSE), reason = "just launched FSI") {
override fun shouldSuppress(entry: NotificationEntry) = entry.hasJustLaunchedFullScreenIntent()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/FullScreenIntentDecisionProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/FullScreenIntentDecisionProvider.kt
index b77748e2990b..576c7ad2ca3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/FullScreenIntentDecisionProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/FullScreenIntentDecisionProvider.kt
@@ -39,6 +39,7 @@ import com.android.systemui.statusbar.notification.interruption.FullScreenIntent
import com.android.systemui.statusbar.notification.interruption.FullScreenIntentDecisionProvider.DecisionImpl.NO_FSI_SUPPRESSED_ONLY_BY_DND
import com.android.systemui.statusbar.notification.interruption.FullScreenIntentDecisionProvider.DecisionImpl.NO_FSI_SUPPRESSIVE_BUBBLE_METADATA
import com.android.systemui.statusbar.notification.interruption.FullScreenIntentDecisionProvider.DecisionImpl.NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR
+import com.android.systemui.statusbar.notification.interruption.FullScreenIntentDecisionProvider.DecisionImpl.NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_NO_HUN_OR_KEYGUARD
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_SUPPRESSIVE_BUBBLE_METADATA
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR
@@ -94,6 +95,7 @@ class FullScreenIntentDecisionProvider(
uiEventId = FSI_SUPPRESSED_SUPPRESSIVE_BUBBLE_METADATA,
eventLogData = EventLogData("274759612", "bubbleMetadata")
),
+ NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION(false, "suppressive setSilent notification"),
NO_FSI_PACKAGE_SUSPENDED(false, "package suspended"),
FSI_DEVICE_NOT_INTERACTIVE(true, "device is not interactive"),
FSI_DEVICE_DREAMING(true, "device is dreaming"),
@@ -154,6 +156,12 @@ class FullScreenIntentDecisionProvider(
return NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR
}
+ if (android.service.notification.Flags.notificationSilentFlag()) {
+ if (sbn.notification.isSilent) {
+ return NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION
+ }
+ }
+
val bubbleMetadata = notification.bubbleMetadata
if (bubbleMetadata != null && bubbleMetadata.isNotificationSuppressed) {
return NO_FSI_SUPPRESSIVE_BUBBLE_METADATA
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
index a2f97bdbc7a1..e9efa56399b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
@@ -193,6 +193,14 @@ class NotificationInterruptLogger @Inject constructor(
})
}
+ fun logNoAlertingSilentNotification(entry: NotificationEntry) {
+ buffer.log(TAG, DEBUG, {
+ str1 = entry.logKey
+ }, {
+ "No alerting: suppressed due to silent notification: $str1"
+ })
+ }
+
fun logNoAlertingSuppressedBy(
entry: NotificationEntry,
suppressor: NotificationInterruptSuppressor,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
index c084482bec9d..2b027907fa62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
@@ -67,6 +67,11 @@ public interface NotificationInterruptStateProvider {
*/
NO_FSI_SUPPRESSIVE_BUBBLE_METADATA(false),
/**
+ * Notification should not FSI due to being explicitly silent.
+ * see {@link android.app.Notification#isSilent}
+ */
+ NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION(false),
+ /**
* Device screen is off, so the FSI should launch.
*/
FSI_DEVICE_NOT_INTERACTIVE(true),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
index fea360d4e02a..450067a969e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
@@ -295,8 +295,17 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
// b/231322873: Detect and report an event when a notification has both an FSI and a
// suppressive groupAlertBehavior, and now correctly block the FSI from firing.
return getDecisionGivenSuppression(
- FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR,
+ FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR,
+ suppressedByDND);
+ }
+
+ // If the notification is explicitly silent, block FSI and warn.
+ if (android.service.notification.Flags.notificationSilentFlag()) {
+ if (sbn.getNotification().isSilent()) {
+ return getDecisionGivenSuppression(
+ FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION,
suppressedByDND);
+ }
}
// If the notification has suppressive BubbleMetadata, block FSI and warn.
@@ -587,8 +596,18 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
StatusBarNotification sbn = entry.getSbn();
// Don't alert notifications that are suppressed due to group alert behavior
+ if (android.service.notification.Flags.notificationSilentFlag()) {
+ if (sbn.getNotification().isSilent()) {
+ if (log) {
+ mLogger.logNoAlertingSilentNotification(entry);
+ }
+ return false;
+ }
+ }
+
if (sbn.isGroup() && sbn.getNotification().suppressAlertingDueToGrouping()) {
- if (log) mLogger.logNoAlertingGroupAlertBehavior(entry);
+ if (log)
+ mLogger.logNoAlertingGroupAlertBehavior(entry);
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
index 96f94ca2a254..1c476ce0362b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
@@ -176,6 +176,7 @@ constructor(
addFilter(BubbleNotAllowedSuppressor())
addFilter(BubbleNoMetadataSuppressor())
addFilter(HunGroupAlertBehaviorSuppressor())
+ addFilter(HunSilentNotificationSuppressor())
addFilter(HunJustLaunchedFsiSuppressor())
addFilter(AlertAppSuspendedSuppressor())
addFilter(AlertKeyguardVisibilitySuppressor(keyguardNotificationVisibilityProvider))
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java
index 9e0dd8fc4d92..175512336b8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java
@@ -20,9 +20,13 @@ import static com.android.systemui.statusbar.notification.stack.NotificationPrio
import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_FOREGROUND_SERVICE;
import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_HEADS_UP;
import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_MEDIA_CONTROLS;
+import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_NEWS;
import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_PEOPLE;
import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_PRIORITY_PEOPLE;
+import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_PROMO;
+import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_RECS;
import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT;
+import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SOCIAL;
import android.annotation.Nullable;
import android.service.notification.StatusBarNotification;
@@ -135,6 +139,10 @@ public interface NotificationPanelLogger {
return Notifications.Notification.SECTION_PEOPLE;
case BUCKET_ALERTING: return Notifications.Notification.SECTION_ALERTING;
case BUCKET_SILENT: return Notifications.Notification.SECTION_SILENT;
+ case BUCKET_NEWS: return Notifications.Notification.SECTION_NEWS;
+ case BUCKET_SOCIAL: return Notifications.Notification.SECTION_SOCIAL;
+ case BUCKET_RECS: return Notifications.Notification.SECTION_RECS;
+ case BUCKET_PROMO: return Notifications.Notification.SECTION_PROMO;
}
return Notifications.Notification.SECTION_UNKNOWN;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto
index c2ab2758dd74..ce4356ae6c2b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto
@@ -43,6 +43,13 @@ message Notification {
SECTION_ALERTING = 4;
SECTION_SILENT = 5;
SECTION_FOREGROUND_SERVICE = 6;
+ SECTION_PRIORITY_PEOPLE = 7;
+ SECTION_TOP_ONGOING = 8;
+ SECTION_TOP_UNSEEN = 9;
+ SECTION_NEWS = 10;
+ SECTION_SOCIAL = 11;
+ SECTION_RECS = 12;
+ SECTION_PROMO = 13;
}
optional NotificationSection section = 6;
}
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 4a043d3617c3..1cbb16e3983a 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
@@ -104,6 +104,7 @@ import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderVi
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.NotificationContentAlphaOptimization;
+import com.android.systemui.statusbar.notification.shared.TransparentHeaderFix;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
@@ -370,12 +371,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
setUserExpanded(nowExpanded);
}
- if (ExpandHeadsUpOnInlineReply.isEnabled() && mExpandable) {
- // it is triggered by the user.
- // So, mHasUserChangedExpansion should be marked true.
- mHasUserChangedExpansion = true;
- }
-
notifyHeightChanged(/* needsAnimation= */ true);
mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded);
if (shouldLogExpandClickMetric) {
@@ -864,8 +859,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
@Override
- public void setHeadsUpIsVisible() {
- super.setHeadsUpIsVisible();
+ public void markHeadsUpSeen() {
+ super.markHeadsUpSeen();
mMustStayOnScreen = false;
}
@@ -1584,6 +1579,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
/* headerView= */ headerView,
/* onClickListener= */ mExpandClickListener
);
+ if (TransparentHeaderFix.isEnabled()) {
+ updateBackgroundForGroupState();
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 2af119f98f4a..6becbd295264 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -637,7 +637,10 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro
return false;
}
- public void setHeadsUpIsVisible() {
+ /**
+ * Called, when the notification has been seen by the user in the heads up state.
+ */
+ public void markHeadsUpSeen() {
}
public boolean showingPulsing() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RichOngoingNotificationContentExtractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RichOngoingNotificationContentExtractor.kt
index b5ea861c19a6..b8af3698fb63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RichOngoingNotificationContentExtractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RichOngoingNotificationContentExtractor.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.row
import android.app.Notification
+import android.app.Notification.RichOngoingStyle
import android.app.PendingIntent
import android.content.Context
import android.util.Log
@@ -68,12 +69,14 @@ class RichOngoingNotificationContentExtractorImpl @Inject constructor() :
builder: Notification.Builder,
systemUIContext: Context,
packageContext: Context
- ): RichOngoingContentModel? =
+ ): RichOngoingContentModel? {
+ if (builder.style !is RichOngoingStyle) return null
+
try {
val sbn = entry.sbn
val notification = sbn.notification
val icon = IconModel(notification.smallIcon)
- if (sbn.packageName == "com.google.android.deskclock") {
+ return if (sbn.packageName == "com.google.android.deskclock") {
when (notification.channelId) {
"Timers v2" -> {
parseTimerNotification(notification, icon)
@@ -90,8 +93,9 @@ class RichOngoingNotificationContentExtractorImpl @Inject constructor() :
} else null
} catch (e: Exception) {
Log.e("RONs", "Error parsing RON", e)
- null
+ return null
}
+ }
/**
* FOR PROTOTYPING ONLY: create a RON TimerContentModel using the time information available
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/TransparentHeaderFix.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/TransparentHeaderFix.kt
new file mode 100644
index 000000000000..0b01510baec4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/TransparentHeaderFix.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.notification.shared
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the notification transparent header fix flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object TransparentHeaderFix {
+ /** The aconfig flag name */
+ const val FLAG_NAME = Flags.FLAG_NOTIFICATION_TRANSPARENT_HEADER_FIX
+
+ /** A token used for dependency declaration */
+ val token: FlagToken
+ get() = FlagToken(FLAG_NAME, isEnabled)
+
+ /** Is the flag enabled */
+ @JvmStatic
+ inline val isEnabled
+ get() = Flags.notificationTransparentHeaderFix()
+
+ /**
+ * Called to ensure code is only run when the flag is enabled. This protects users from the
+ * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+ * build to ensure that the refactor author catches issues in testing.
+ */
+ @JvmStatic
+ inline fun isUnexpectedlyInLegacyMode() =
+ RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+ /**
+ * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+ * the flag is enabled to ensure that the refactor author catches issues in testing.
+ */
+ @JvmStatic
+ inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
index d1e5ab04a630..83de2265b98e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
@@ -176,7 +176,7 @@ public class ExpandableViewState extends ViewState {
expandableView.setInShelf(inShelf);
if (headsUpIsVisible) {
- expandableView.setHeadsUpIsVisible();
+ expandableView.markHeadsUpSeen();
}
}
}
@@ -231,7 +231,7 @@ public class ExpandableViewState extends ViewState {
expandableView.setInShelf(this.inShelf);
if (headsUpIsVisible) {
- expandableView.setHeadsUpIsVisible();
+ expandableView.markHeadsUpSeen();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt
index fabb696d9182..f4a452784267 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt
@@ -20,6 +20,10 @@ import android.annotation.IntDef
BUCKET_PRIORITY_PEOPLE,
BUCKET_PEOPLE,
BUCKET_ALERTING,
+ BUCKET_NEWS,
+ BUCKET_SOCIAL,
+ BUCKET_RECS,
+ BUCKET_PROMO,
BUCKET_SILENT
]
)
@@ -35,6 +39,10 @@ annotation class PriorityBucket {
BUCKET_PRIORITY_PEOPLE,
BUCKET_PEOPLE,
BUCKET_ALERTING,
+ BUCKET_NEWS,
+ BUCKET_SOCIAL,
+ BUCKET_RECS,
+ BUCKET_PROMO,
BUCKET_SILENT,
)
}
@@ -49,4 +57,9 @@ const val BUCKET_FOREGROUND_SERVICE = 3
const val BUCKET_PRIORITY_PEOPLE = 7
const val BUCKET_PEOPLE = 4
const val BUCKET_ALERTING = 5
+const val BUCKET_NEWS = 10
+const val BUCKET_SOCIAL = 11
+const val BUCKET_RECS = 12
+const val BUCKET_PROMO = 13
const val BUCKET_SILENT = 6
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index 3400ad107133..7441c7058d7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -22,12 +22,10 @@ import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.media.controls.ui.controller.KeyguardMediaController
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.SourceType
+import com.android.systemui.statusbar.notification.collection.NotificationClassificationFlag
import com.android.systemui.statusbar.notification.collection.render.MediaContainerController
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController
-import com.android.systemui.statusbar.notification.dagger.AlertingHeader
-import com.android.systemui.statusbar.notification.dagger.IncomingHeader
-import com.android.systemui.statusbar.notification.dagger.PeopleHeader
-import com.android.systemui.statusbar.notification.dagger.SilentHeader
+import com.android.systemui.statusbar.notification.dagger.*
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
@@ -51,7 +49,11 @@ internal constructor(
@IncomingHeader private val incomingHeaderController: SectionHeaderController,
@PeopleHeader private val peopleHeaderController: SectionHeaderController,
@AlertingHeader private val alertingHeaderController: SectionHeaderController,
- @SilentHeader private val silentHeaderController: SectionHeaderController
+ @SilentHeader private val silentHeaderController: SectionHeaderController,
+ @NewsHeader private val newsHeaderController: SectionHeaderController,
+ @SocialHeader private val socialHeaderController: SectionHeaderController,
+ @RecsHeader private val recsHeaderController: SectionHeaderController,
+ @PromoHeader private val promoHeaderController: SectionHeaderController
) : SectionProvider {
private val configurationListener =
@@ -84,6 +86,22 @@ internal constructor(
val mediaControlsView: MediaContainerView?
get() = mediaContainerController.mediaContainerView
+ @VisibleForTesting
+ val newsHeaderView: SectionHeaderView?
+ get() = newsHeaderController.headerView
+
+ @VisibleForTesting
+ val socialHeaderView: SectionHeaderView?
+ get() = socialHeaderController.headerView
+
+ @VisibleForTesting
+ val recsHeaderView: SectionHeaderView?
+ get() = recsHeaderController.headerView
+
+ @VisibleForTesting
+ val promoHeaderView: SectionHeaderView?
+ get() = promoHeaderController.headerView
+
/** Must be called before use. */
fun initialize(parent: NotificationStackScrollLayout) {
check(!initialized) { "NotificationSectionsManager already initialized" }
@@ -107,15 +125,24 @@ internal constructor(
incomingHeaderController.reinflateView(parent)
mediaContainerController.reinflateView(parent)
keyguardMediaController.attachSinglePaneContainer(mediaControlsView)
+ if (NotificationClassificationFlag.isEnabled) {
+ newsHeaderController.reinflateView(parent)
+ socialHeaderController.reinflateView(parent)
+ recsHeaderController.reinflateView(parent)
+ promoHeaderController.reinflateView(parent)
+ }
}
override fun beginsSection(view: View, previous: View?): Boolean =
view === silentHeaderView ||
- view === mediaControlsView ||
- view === peopleHeaderView ||
- view === alertingHeaderView ||
- view === incomingHeaderView ||
- getBucket(view) != getBucket(previous)
+ view === mediaControlsView ||
+ view === peopleHeaderView ||
+ view === alertingHeaderView ||
+ view === incomingHeaderView ||
+ (NotificationClassificationFlag.isEnabled && (view === newsHeaderView
+ || view === socialHeaderView || view === recsHeaderView
+ || view === promoHeaderView)) ||
+ getBucket(view) != getBucket(previous)
private fun getBucket(view: View?): Int? =
when {
@@ -124,6 +151,10 @@ internal constructor(
view === mediaControlsView -> BUCKET_MEDIA_CONTROLS
view === peopleHeaderView -> BUCKET_PEOPLE
view === alertingHeaderView -> BUCKET_ALERTING
+ view === newsHeaderView -> BUCKET_NEWS
+ view === socialHeaderView -> BUCKET_SOCIAL
+ view === recsHeaderView -> BUCKET_RECS
+ view === promoHeaderView -> BUCKET_PROMO
view is ExpandableNotificationRow -> view.entry.bucket
else -> null
}
@@ -255,6 +286,12 @@ internal constructor(
peopleHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
silentHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
alertingHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
+ if (NotificationClassificationFlag.isEnabled) {
+ newsHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
+ socialHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
+ recsHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
+ promoHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
+ }
}
companion object {
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 715c6e65d1de..2081adc076d1 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
@@ -715,6 +715,7 @@ public class NotificationStackScrollLayout
}
public float getNotificationSquishinessFraction() {
+ SceneContainerFlag.assertInLegacyMode();
return mStackScrollAlgorithm.getNotificationSquishinessFraction(mAmbientState);
}
@@ -860,7 +861,7 @@ public class NotificationStackScrollLayout
/* label= */ "getHeight() - mKeyguardBottomPadding = " + y);
}
- y = getHeight() - getEmptyBottomMargin();
+ y = getHeight() - getEmptyBottomMarginInternal();
drawDebugInfo(canvas, y, Color.GREEN,
/* label= */ "getHeight() - getEmptyBottomMargin() = " + y);
@@ -1270,7 +1271,7 @@ public class NotificationStackScrollLayout
private void updateAlgorithmLayoutMinHeight() {
mAmbientState.setLayoutMinHeight(mQsFullScreen || isHeadsUpTransition()
- ? getLayoutMinHeight() : 0);
+ ? getLayoutMinHeightInternal() : 0);
}
/**
@@ -1444,7 +1445,7 @@ public class NotificationStackScrollLayout
} else {
if (mQsExpansionFraction <= 0 && !shouldSkipHeightUpdate()) {
final float endHeight = updateStackEndHeight(
- getHeight(), getEmptyBottomMargin(), getTopPadding());
+ getHeight(), getEmptyBottomMarginInternal(), getTopPadding());
updateStackHeight(endHeight, fraction);
} else {
// Always updateStackHeight to prevent jumps in the stack height when this fraction
@@ -1617,7 +1618,7 @@ public class NotificationStackScrollLayout
float appear;
float expandAmount;
if (mKeyguardBypassEnabled && onKeyguard()) {
- appear = calculateAppearFractionBypass();
+ appear = calculateAppearFractionBypassInternal();
expandAmount = getPulseHeight();
} else {
appear = MathUtils.saturate(calculateAppearFraction(mExpandedHeight));
@@ -1642,6 +1643,7 @@ public class NotificationStackScrollLayout
* Return the height of the content ignoring the footer.
*/
public int getIntrinsicContentHeight() {
+ SceneContainerFlag.assertInLegacyMode();
return (int) mIntrinsicContentHeight;
}
@@ -2373,6 +2375,11 @@ public class NotificationStackScrollLayout
* @return the first child which has visibility unequal to GONE
*/
public ExpandableView getFirstChildNotGone() {
+ SceneContainerFlag.assertInLegacyMode();
+ return getFirstChildNotGoneInternal();
+ }
+
+ private ExpandableView getFirstChildNotGoneInternal() {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
@@ -2432,6 +2439,7 @@ public class NotificationStackScrollLayout
* @return the number of children which have visibility unequal to GONE
*/
public int getNotGoneChildCount() {
+ SceneContainerFlag.assertInLegacyMode();
int childCount = getChildCount();
int count = 0;
for (int i = 0; i < childCount; i++) {
@@ -2443,8 +2451,9 @@ public class NotificationStackScrollLayout
return count;
}
- private void updateContentHeight() {
- final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
+ @VisibleForTesting
+ void updateContentHeight() {
+ final float scrimTopPadding = getScrimTopPaddingOrZero();
final int shelfIntrinsicHeight = mShelf != null ? mShelf.getIntrinsicHeight() : 0;
final int footerIntrinsicHeight = mFooterView != null ? mFooterView.getIntrinsicHeight() : 0;
final float height =
@@ -2641,7 +2650,7 @@ public class NotificationStackScrollLayout
*/
public void updateTopPadding(float qsHeight, boolean animate) {
int topPadding = (int) qsHeight;
- int minStackHeight = getLayoutMinHeight();
+ int minStackHeight = getLayoutMinHeightInternal();
if (topPadding + minStackHeight > getHeight()) {
mTopPaddingOverflow = topPadding + minStackHeight - getHeight();
} else {
@@ -2657,6 +2666,11 @@ public class NotificationStackScrollLayout
}
public int getLayoutMinHeight() {
+ SceneContainerFlag.assertInLegacyMode();
+ return getLayoutMinHeightInternal();
+ }
+
+ private int getLayoutMinHeightInternal() {
if (isHeadsUpTransition()) {
ExpandableNotificationRow trackedHeadsUpRow = mAmbientState.getTrackedHeadsUpRow();
if (trackedHeadsUpRow.isAboveShelf()) {
@@ -2949,7 +2963,7 @@ public class NotificationStackScrollLayout
return view.getHeight();
}
- public int getPositionInLinearLayout(View requestedView) {
+ private int getPositionInLinearLayout(View requestedView) {
ExpandableNotificationRow childInGroup = null;
ExpandableNotificationRow requestedRow = null;
if (isChildInGroup(requestedView)) {
@@ -2958,7 +2972,7 @@ public class NotificationStackScrollLayout
childInGroup = (ExpandableNotificationRow) requestedView;
requestedView = requestedRow = childInGroup.getNotificationParent();
}
- final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
+ final float scrimTopPadding = getScrimTopPaddingOrZero();
int position = (int) scrimTopPadding;
int visibleIndex = -1;
ExpandableView lastVisibleChild = null;
@@ -2988,6 +3002,17 @@ public class NotificationStackScrollLayout
return 0;
}
+ /**
+ * Returns the top scrim padding, or zero if the SceneContainer flag is enabled.
+ */
+ private int getScrimTopPaddingOrZero() {
+ if (SceneContainerFlag.isEnabled()) {
+ // the scrim padding is set on the notification placeholder
+ return 0;
+ }
+ return mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
+ }
+
@Override
public void onViewAdded(View child) {
super.onViewAdded(child);
@@ -3418,7 +3443,7 @@ public class NotificationStackScrollLayout
* @return Whether a y coordinate is inside the content.
*/
public boolean isInContentBounds(float y) {
- return y < getHeight() - getEmptyBottomMargin();
+ return y < getHeight() - getEmptyBottomMarginInternal();
}
private float getTouchSlop(MotionEvent event) {
@@ -3494,11 +3519,18 @@ public class NotificationStackScrollLayout
// Only when scene container is enabled, mark that we are being dragged so that we start
// dispatching the rest of the gesture to scene container.
void startOverscrollAfterExpanding() {
- SceneContainerFlag.isUnexpectedlyInLegacyMode();
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
getExpandHelper().finishExpanding();
setIsBeingDragged(true);
}
+ // Only when scene container is enabled, mark that we are being dragged so that we start
+ // dispatching the rest of the gesture to scene container.
+ void startDraggingOnHun() {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+ setIsBeingDragged(true);
+ }
+
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
if (!isScrollingEnabled()
@@ -4044,10 +4076,16 @@ public class NotificationStackScrollLayout
}
boolean isScrolledToBottom() {
+ SceneContainerFlag.assertInLegacyMode();
return mScrollAdapter.isScrolledToBottom();
}
int getEmptyBottomMargin() {
+ SceneContainerFlag.assertInLegacyMode();
+ return getEmptyBottomMarginInternal();
+ }
+
+ private int getEmptyBottomMarginInternal() {
int contentHeight;
if (mShouldUseSplitNotificationShade) {
// When in split shade and there are no notifications, the height can be too low, as
@@ -4230,7 +4268,7 @@ public class NotificationStackScrollLayout
private void updateScrollPositionOnExpandInBottom(ExpandableView view) {
if (view instanceof ExpandableNotificationRow row && !onKeyguard()) {
// TODO: once we're recycling this will need to check the adapter position of the child
- if (row.isUserLocked() && row != getFirstChildNotGone()) {
+ if (row.isUserLocked() && row != getFirstChildNotGoneInternal()) {
if (row.isSummaryWithChildren()) {
return;
}
@@ -4517,7 +4555,7 @@ public class NotificationStackScrollLayout
// clipped when pulsing
float ownTranslationZ = 0;
if (mKeyguardBypassEnabled && mAmbientState.isHiddenAtAll()) {
- ExpandableView firstChildNotGone = getFirstChildNotGone();
+ ExpandableView firstChildNotGone = getFirstChildNotGoneInternal();
if (firstChildNotGone != null && firstChildNotGone.showingPulsing()) {
ownTranslationZ = firstChildNotGone.getTranslationZ();
}
@@ -4665,10 +4703,12 @@ public class NotificationStackScrollLayout
}
public int getEmptyShadeViewHeight() {
+ SceneContainerFlag.assertInLegacyMode();
return mEmptyShadeView.getHeight();
}
public float getBottomMostNotificationBottom() {
+ SceneContainerFlag.assertInLegacyMode();
final int count = getChildCount();
float max = 0;
for (int childIdx = 0; childIdx < count; childIdx++) {
@@ -5091,6 +5131,7 @@ public class NotificationStackScrollLayout
}
public float getOpeningHeight() {
+ SceneContainerFlag.assertInLegacyMode();
if (mEmptyShadeView.getVisibility() == GONE) {
return getMinExpansionHeight();
} else {
@@ -5547,6 +5588,11 @@ public class NotificationStackScrollLayout
}
public float calculateAppearFractionBypass() {
+ SceneContainerFlag.assertInLegacyMode();
+ return calculateAppearFractionBypassInternal();
+ }
+
+ private float calculateAppearFractionBypassInternal() {
float pulseHeight = getPulseHeight();
// The total distance required to fully reveal the header
float totalDistance = getIntrinsicPadding();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 12f8f6996cb6..a072ea6ec3eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -59,6 +59,7 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.view.OneShotPreDrawListener;
import com.android.systemui.Dumpable;
import com.android.systemui.ExpandHelper;
@@ -126,6 +127,7 @@ import com.android.systemui.statusbar.notification.row.NotificationSnooze;
import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor;
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
+import com.android.systemui.statusbar.phone.HeadsUpNotificationViewControllerEmptyImpl;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -168,6 +170,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
private final NotificationVisibilityProvider mVisibilityProvider;
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
private final HeadsUpManager mHeadsUpManager;
+ private HeadsUpTouchHelper mHeadsUpTouchHelper;
private final NotificationRoundnessManager mNotificationRoundnessManager;
private final TunerService mTunerService;
private final DeviceProvisionedController mDeviceProvisionedController;
@@ -706,6 +709,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
NotificationVisibilityProvider visibilityProvider,
NotificationWakeUpCoordinator wakeUpCoordinator,
HeadsUpManager headsUpManager,
+ Provider<IStatusBarService> statusBarService,
NotificationRoundnessManager notificationRoundnessManager,
TunerService tunerService,
DeviceProvisionedController deviceProvisionedController,
@@ -758,6 +762,14 @@ public class NotificationStackScrollLayoutController implements Dumpable {
mVisibilityProvider = visibilityProvider;
mWakeUpCoordinator = wakeUpCoordinator;
mHeadsUpManager = headsUpManager;
+ if (SceneContainerFlag.isEnabled()) {
+ mHeadsUpTouchHelper = new HeadsUpTouchHelper(
+ mHeadsUpManager,
+ statusBarService.get(),
+ getHeadsUpCallback(),
+ new HeadsUpNotificationViewControllerEmptyImpl()
+ );
+ }
mNotificationRoundnessManager = notificationRoundnessManager;
mTunerService = tunerService;
mDeviceProvisionedController = deviceProvisionedController;
@@ -992,6 +1004,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
public int getRight() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getRight();
}
@@ -1003,6 +1016,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
* @return the left of the view.
*/
public int getLeft() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getLeft();
}
@@ -1010,6 +1024,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
* @return the top of the view.
*/
public int getTop() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getTop();
}
@@ -1017,6 +1032,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
* @return the bottom of the view.
*/
public int getBottom() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getBottom();
}
@@ -1146,6 +1162,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
public int getIntrinsicContentHeight() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getIntrinsicContentHeight();
}
@@ -1204,6 +1221,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
public float getX() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getX();
}
@@ -1212,14 +1230,17 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
public float getWidth() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getWidth();
}
public float getOpeningHeight() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getOpeningHeight();
}
public float getBottomMostNotificationBottom() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getBottomMostNotificationBottom();
}
@@ -1254,10 +1275,12 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
public float getNotificationSquishinessFraction() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getNotificationSquishinessFraction();
}
public float calculateAppearFractionBypass() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.calculateAppearFractionBypass();
}
@@ -1267,22 +1290,27 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
public boolean isScrolledToBottom() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.isScrolledToBottom();
}
public int getNotGoneChildCount() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getNotGoneChildCount();
}
public float getIntrinsicPadding() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getIntrinsicPadding();
}
public float getLayoutMinHeight() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getLayoutMinHeight();
}
public int getEmptyBottomMargin() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getEmptyBottomMargin();
}
@@ -1295,6 +1323,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
public float getEmptyShadeViewHeight() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getEmptyShadeViewHeight();
}
@@ -1462,6 +1491,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
public boolean isShowingEmptyShadeView() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.isEmptyShadeViewVisible();
}
@@ -1590,6 +1620,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
public ExpandableView getFirstChildNotGone() {
+ SceneContainerFlag.assertInLegacyMode();
return mView.getFirstChildNotGone();
}
@@ -1609,10 +1640,6 @@ public class NotificationStackScrollLayoutController implements Dumpable {
return mView.getTransientView(i);
}
- public int getPositionInLinearLayout(ExpandableView row) {
- return mView.getPositionInLinearLayout(row);
- }
-
public NotificationStackScrollLayout getView() {
return mView;
}
@@ -1705,6 +1732,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
public boolean isLongPressInProgress() {
+ SceneContainerFlag.assertInLegacyMode();
return mLongPressedView != null;
}
@@ -1714,6 +1742,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
* from the keyguard host to the quick settings one.
*/
public int getFullShadeTransitionInset() {
+ SceneContainerFlag.assertInLegacyMode();
MediaContainerView view = mKeyguardMediaController.getSinglePaneContainer();
if (view == null || view.getHeight() == 0
|| mStatusBarStateController.getState() != KEYGUARD) {
@@ -2000,6 +2029,14 @@ public class NotificationStackScrollLayoutController implements Dumpable {
&& !mView.isExpandingNotification()) {
scrollWantsIt = mView.onInterceptTouchEventScroll(ev);
}
+ boolean hunWantsIt = false;
+ if (shouldHeadsUpHandleTouch()) {
+ hunWantsIt = mHeadsUpTouchHelper.onInterceptTouchEvent(ev);
+ if (hunWantsIt) {
+ mView.startDraggingOnHun();
+ mHeadsUpManager.unpinAll(true);
+ }
+ }
boolean swipeWantsIt = false;
if (mLongPressedView == null && !mView.isBeingDragged()
&& !mView.isExpandingNotification()
@@ -2029,7 +2066,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
&& ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
mJankMonitor.begin(mView, CUJ_NOTIFICATION_SHADE_SCROLL_FLING);
}
- return swipeWantsIt || scrollWantsIt || expandWantsIt || longPressWantsIt;
+ return swipeWantsIt || scrollWantsIt || expandWantsIt || longPressWantsIt || hunWantsIt;
}
@Override
@@ -2081,6 +2118,10 @@ public class NotificationStackScrollLayoutController implements Dumpable {
&& !expandingNotification && !mView.getDisallowScrollingInThisMotion()) {
scrollerWantsIt = mView.onScrollTouch(ev);
}
+ boolean hunWantsIt = false;
+ if (shouldHeadsUpHandleTouch()) {
+ hunWantsIt = mHeadsUpTouchHelper.onTouchEvent(ev);
+ }
// Check if we need to clear any snooze leavebehinds
if (guts != null && !NotificationSwipeHelper.isTouchInView(ev, guts)
@@ -2101,7 +2142,8 @@ public class NotificationStackScrollLayoutController implements Dumpable {
mView.setCheckForLeaveBehind(true);
}
traceJankOnTouchEvent(ev.getActionMasked(), scrollerWantsIt);
- return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || longPressWantsIt;
+ return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || longPressWantsIt
+ || hunWantsIt;
}
private void traceJankOnTouchEvent(int action, boolean scrollerWantsIt) {
@@ -2128,6 +2170,11 @@ public class NotificationStackScrollLayoutController implements Dumpable {
break;
}
}
+
+ private boolean shouldHeadsUpHandleTouch() {
+ return SceneContainerFlag.isEnabled() && mLongPressedView == null
+ && !mSwipeHelper.isSwiping();
+ }
}
private class NotifStackControllerImpl implements NotifStackController {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index ee7b5c48a3e7..4282fa25a4eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -487,11 +487,8 @@ public class StackScrollAlgorithm {
// expanded. Consider updating these states in updateContentView instead so that we don't
// have to recalculate in every frame.
float currentY = -ambientState.getScrollY();
- if (!ambientState.isOnKeyguard()
- || (ambientState.isBypassEnabled() && ambientState.isPulseExpanding())) {
- // add top padding at the start as long as we're not on the lock screen
- currentY += mNotificationScrimPadding;
- }
+ // add top padding at the start as long as we're not on the lock screen
+ currentY += getScrimTopPaddingOrZero(ambientState);
state.firstViewInShelf = null;
for (int i = 0; i < state.visibleChildren.size(); i++) {
final ExpandableView view = state.visibleChildren.get(i);
@@ -548,11 +545,9 @@ public class StackScrollAlgorithm {
*/
protected void updatePositionsForState(StackScrollAlgorithmState algorithmState,
AmbientState ambientState) {
- if (!ambientState.isOnKeyguard()
- || (ambientState.isBypassEnabled() && ambientState.isPulseExpanding())) {
- algorithmState.mCurrentYPosition += mNotificationScrimPadding;
- algorithmState.mCurrentExpandedYPosition += mNotificationScrimPadding;
- }
+ float scrimTopPadding = getScrimTopPaddingOrZero(ambientState);
+ algorithmState.mCurrentYPosition += scrimTopPadding;
+ algorithmState.mCurrentExpandedYPosition += scrimTopPadding;
int childCount = algorithmState.visibleChildren.size();
for (int i = 0; i < childCount; i++) {
@@ -580,9 +575,7 @@ public class StackScrollAlgorithm {
&& algorithmState.firstViewInShelf != null;
final float shelfHeight = showingShelf ? ambientState.getShelf().getIntrinsicHeight() : 0f;
- final float scrimPadding = ambientState.isOnKeyguard()
- && (!ambientState.isBypassEnabled() || !ambientState.isPulseExpanding())
- ? 0 : mNotificationScrimPadding;
+ final float scrimPadding = getScrimTopPaddingOrZero(ambientState);
final float stackHeight = ambientState.getStackHeight() - shelfHeight - scrimPadding;
final float stackEndHeight = ambientState.getStackEndHeight() - shelfHeight - scrimPadding;
@@ -594,6 +587,21 @@ public class StackScrollAlgorithm {
return stackHeight / stackEndHeight;
}
+ /**
+ * Returns the top scrim padding, or zero if the SceneContainer flag is enabled.
+ */
+ private float getScrimTopPaddingOrZero(AmbientState ambientState) {
+ if (SceneContainerFlag.isEnabled()) {
+ // the scrim padding is set on the notification placeholder
+ return 0f;
+ }
+
+ boolean shouldUsePadding =
+ !ambientState.isOnKeyguard()
+ || (ambientState.isBypassEnabled() && ambientState.isPulseExpanding());
+ return shouldUsePadding ? mNotificationScrimPadding : 0f;
+ }
+
private boolean hasNonClearableNotifs(StackScrollAlgorithmState algorithmState) {
for (int i = 0; i < algorithmState.visibleChildren.size(); i++) {
View child = algorithmState.visibleChildren.get(i);
@@ -664,6 +672,7 @@ public class StackScrollAlgorithm {
float viewEnd = stackTop + viewState.getYTranslation() + viewState.height;
maybeUpdateHeadsUpIsVisible(viewState, ambientState.isShadeExpanded(),
view.mustStayOnScreen(),
+ // TODO(b/332574413) use the position from the HeadsUpNotificationPlaceholder
/* topVisible= */ viewState.getYTranslation() >= mNotificationScrimPadding,
viewEnd, /* hunMax */ ambientState.getMaxHeadsUpTranslation()
);
@@ -891,6 +900,7 @@ public class StackScrollAlgorithm {
// Ensure that the heads up is always visible even when scrolled off.
// NSSL y starts at top of screen in non-split-shade, but below the qs offset
// in split shade, so we only need to inset by the scrim padding in split shade.
+ // TODO(b/332574413) get the clamp inset from HeadsUpNotificationPlaceholder
final float clampInset = ambientState.getUseSplitShade()
? mNotificationScrimPadding : mQuickQsOffsetHeight;
clampHunToTop(clampInset, ambientState.getStackTranslation(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index 497ffcab32f2..05415503675c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -20,9 +20,9 @@ import android.view.View
import android.view.WindowInsets
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.Flags.communalHub
import com.android.systemui.common.ui.view.onApplyWindowInsets
import com.android.systemui.common.ui.view.onLayoutChanged
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
@@ -38,12 +38,14 @@ import com.android.systemui.util.kotlin.DisposableHandles
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
/** Binds the shared notification container to its view-model. */
+@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
class SharedNotificationContainerBinder
@Inject
@@ -51,6 +53,7 @@ constructor(
private val controller: NotificationStackScrollLayoutController,
private val notificationStackSizeCalculator: NotificationStackSizeCalculator,
private val notificationScrollViewBinder: NotificationScrollViewBinder,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
@Main private val mainImmediateDispatcher: CoroutineDispatcher,
) {
@@ -162,7 +165,7 @@ constructor(
}
}
- if (communalHub()) {
+ if (communalSettingsInteractor.isCommunalFlagEnabled()) {
launch {
viewModel.glanceableHubAlpha.collect {
controller.setMaxAlphaForGlanceableHub(it)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
index b54f9c4c6d32..5fba615e020b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
@@ -275,13 +275,7 @@ constructor(
if (NotificationsHeadsUpRefactor.isUnexpectedlyInLegacyMode()) {
flowOf(false)
} else {
- combine(
- notificationStackInteractor.isShowingOnLockscreen,
- shadeInteractor.isShadeFullyCollapsed
- ) { (isKeyguardShowing, isShadeFullyCollapsed) ->
- !isKeyguardShowing && isShadeFullyCollapsed
- }
- .dumpWhileCollecting("headsUpAnimationsEnabled")
+ flowOf(true).dumpWhileCollecting("headsUpAnimationsEnabled")
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
index 08e81d556216..1a7bc169ea2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
@@ -23,6 +23,7 @@ import com.android.systemui.flags.Flags
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
+import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimRounding
@@ -43,6 +44,7 @@ constructor(
private val interactor: NotificationStackAppearanceInteractor,
shadeInteractor: ShadeInteractor,
private val shadeSceneViewModel: ShadeSceneViewModel,
+ private val headsUpNotificationInteractor: HeadsUpNotificationInteractor,
featureFlags: FeatureFlagsClassic,
) : FlowDumperImpl(dumpManager) {
/** DEBUG: whether the placeholder should be made slightly visible for positional debugging. */
@@ -74,6 +76,10 @@ constructor(
/** Whether or not the notification scrim should be clickable. */
val isClickable: StateFlow<Boolean> = shadeSceneViewModel.isClickable
+ /** True when a HUN is pinned or animating away. */
+ val isHeadsUpOrAnimatingAway: Flow<Boolean> =
+ headsUpNotificationInteractor.isHeadsUpOrAnimatingAway
+
/** Corner rounding of the stack */
val shadeScrimRounding: Flow<ShadeScrimRounding> =
interactor.shadeScrimRounding.dumpWhileCollecting("shadeScrimRounding")
@@ -103,6 +109,16 @@ constructor(
fun setScrolledToTop(scrolledToTop: Boolean) {
interactor.setScrolledToTop(scrolledToTop)
}
+
+ /** Sets whether the heads up notification is animating away. */
+ fun setHeadsUpAnimatingAway(animatingAway: Boolean) {
+ headsUpNotificationInteractor.setHeadsUpAnimatingAway(animatingAway)
+ }
+
+ /** Snooze the currently pinned HUN. */
+ fun snoozeHun() {
+ headsUpNotificationInteractor.snooze()
+ }
}
// Expansion fraction thresholds (between 0-1f) at which the corresponding value should be
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 8e58ffbb399e..99f7a75676e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -141,6 +141,7 @@ constructor(
private val communalSceneInteractor: CommunalSceneInteractor,
unfoldTransitionInteractor: UnfoldTransitionInteractor,
) : FlowDumperImpl(dumpManager) {
+ // TODO(b/349784682): Transform deprecated states for Flexiglass
private val statesForConstrainedNotifications: Set<KeyguardState> =
setOf(AOD, LOCKSCREEN, DOZING, ALTERNATE_BOUNCER, PRIMARY_BOUNCER)
private val statesForHiddenKeyguard: Set<KeyguardState> = setOf(GONE, OCCLUDED)
@@ -186,7 +187,6 @@ constructor(
interactor.configurationBasedDimensions
.map {
when {
- !it.useSplitShade -> 0
it.useLargeScreenHeader -> it.marginTopLargeScreen
else -> it.marginTop
}
@@ -287,7 +287,7 @@ constructor(
/** Are we on the dream without the shade/qs? */
private val isDreamingWithoutShade: Flow<Boolean> =
combine(
- keyguardTransitionInteractor.isFinishedInState(DREAMING),
+ keyguardTransitionInteractor.isFinishedIn(DREAMING),
isAnyExpanded,
) { isDreaming, isAnyExpanded ->
isDreaming && !isAnyExpanded
@@ -372,7 +372,7 @@ constructor(
paddingTopDimen,
interactor.topPosition
.sampleCombine(
- keyguardTransitionInteractor.isInTransitionToAnyState,
+ keyguardTransitionInteractor.isInTransition,
shadeInteractor.qsExpansion,
)
.onStart { emit(Triple(0f, false, 0f)) }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt
index 52cb48be041f..8d73983e4053 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt
@@ -51,8 +51,8 @@ constructor(private val viewModel: NotificationListViewModel) {
}
removed.forEach { key ->
val row = obtainView(key)
- parentView.generateHeadsUpAnimation(row, /* isHeadsUp = */ false)
- row.setHeadsUpIsVisible()
+ parentView.generateHeadsUpAnimation(row, /* isHeadsUp= */ false)
+ row.markHeadsUpSeen()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 91b5d0be6f04..a5388564d5fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -414,6 +414,14 @@ public class AutoTileManager implements UserAwareController {
}
}
+ @Override
+ public void onFeatureEnabledChanged(boolean enabled) {
+ if (!enabled) {
+ mHost.removeTile(BRIGHTNESS);
+ mHandler.post(() -> mReduceBrightColorsController.removeCallback(this));
+ }
+ }
+
private void addReduceBrightColorsTile() {
if (mAutoTracker.isAdded(BRIGHTNESS)) return;
mHost.addTile(BRIGHTNESS);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 97b6f95ef3c4..6f29f618ee0d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -53,11 +53,14 @@ import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.keyguard.domain.interactor.BiometricUnlockInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.shared.model.BiometricUnlockSource;
+import com.android.systemui.keyguard.shared.model.Edge;
import com.android.systemui.keyguard.shared.model.KeyguardState;
+import com.android.systemui.keyguard.shared.model.TransitionState;
import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.model.Scenes;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.VibratorHelper;
@@ -327,14 +330,17 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
mSelectedUserInteractor = selectedUserInteractor;
mKeyguardTransitionInteractor = keyguardTransitionInteractor;
javaAdapter.alwaysCollectFlow(
- keyguardTransitionInteractor.getStartedKeyguardTransitionStep(),
- this::consumeTransitionStepOnStartedKeyguardState);
+ keyguardTransitionInteractor.transition(
+ /* edge */ Edge.create(Scenes.Gone, null),
+ /* edgeWithoutSceneContainer */ Edge.create(
+ KeyguardState.GONE, (KeyguardState) null)),
+ this::consumeFromGoneTransitions);
dumpManager.registerDumpable(this);
}
@VisibleForTesting
- protected void consumeTransitionStepOnStartedKeyguardState(TransitionStep transitionStep) {
- if (transitionStep.getFrom() == KeyguardState.GONE) {
+ protected void consumeFromGoneTransitions(TransitionStep transitionStep) {
+ if (transitionStep.getTransitionState() == TransitionState.STARTED) {
mBiometricUnlockInteractor.setBiometricUnlockState(MODE_NONE, null);
}
}
@@ -363,10 +369,12 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
private void releaseBiometricWakeLock() {
if (mWakeLock != null) {
+ Trace.beginSection("release wake-and-unlock");
mHandler.removeCallbacks(mReleaseBiometricWakeLockRunnable);
mLogger.i("releasing biometric wakelock");
mWakeLock.release();
mWakeLock = null;
+ Trace.endSection();
}
}
@@ -392,7 +400,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
}
mWakeLock = mPowerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, BIOMETRIC_WAKE_LOCK_NAME);
- Trace.beginSection("acquiring wake-and-unlock");
+ Trace.beginSection("acquire wake-and-unlock");
mWakeLock.acquire();
Trace.endSection();
mLogger.i("biometric acquired, grabbing biometric wakelock");
@@ -406,14 +414,13 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
public void onBiometricDetected(int userId, BiometricSourceType biometricSourceType,
boolean isStrongBiometric) {
Trace.beginSection("BiometricUnlockController#onBiometricDetected");
- if (mUpdateMonitor.isGoingToSleep()) {
- Trace.endSection();
- return;
+ if (!mUpdateMonitor.isGoingToSleep()) {
+ startWakeAndUnlock(
+ MODE_SHOW_BOUNCER,
+ BiometricUnlockSource.Companion.fromBiometricSourceType(biometricSourceType)
+ );
}
- startWakeAndUnlock(
- MODE_SHOW_BOUNCER,
- BiometricUnlockSource.Companion.fromBiometricSourceType(biometricSourceType)
- );
+ Trace.endSection();
}
@Override
@@ -445,6 +452,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
} else {
mLogger.d("onBiometricUnlocked aborted by bypass controller");
}
+ Trace.endSection();
}
/**
@@ -473,6 +481,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
@WakeAndUnlockMode int mode,
BiometricUnlockSource biometricUnlockSource
) {
+ Trace.beginSection("BiometricUnlockController#startWakeAndUnlock");
mLogger.logStartWakeAndUnlock(mode);
boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
mMode = mode;
@@ -495,9 +504,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
"android.policy:BIOMETRIC"
);
}
- Trace.beginSection("release wake-and-unlock");
releaseBiometricWakeLock();
- Trace.endSection();
};
final boolean wakeInKeyguard = mMode == MODE_WAKE_AND_UNLOCK_FROM_DREAM
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index 0a02381da4d5..a0d4ca268e8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -41,7 +41,7 @@ import com.android.systemui.Dumpable;
import com.android.systemui.animation.ActivityTransitionAnimator;
import com.android.systemui.animation.RemoteAnimationRunnerCompat;
import com.android.systemui.display.data.repository.DisplayMetricsRepository;
-import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.qs.QSPanelController;
import com.android.systemui.shared.statusbar.phone.BarTransitions;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
index 3bc8e2748a79..88d3e0718fa6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
@@ -20,7 +20,7 @@ import android.view.MotionEvent
import androidx.lifecycle.LifecycleRegistry
import com.android.keyguard.AuthKeyguardMessageArea
import com.android.systemui.animation.ActivityTransitionAnimator
-import com.android.systemui.navigationbar.NavigationBarView
+import com.android.systemui.navigationbar.views.NavigationBarView
import com.android.systemui.plugins.ActivityStarter.OnDismissAction
import com.android.systemui.qs.QSPanelController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
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 491db307ae63..462ae7ab39cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -146,7 +146,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.keyguard.ui.binder.LightRevealScrimViewBinder;
import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.notetask.NoteTaskController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index a11cbc3bf231..98869bef5bf0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -37,6 +37,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.Dumpable;
+import com.android.systemui.Flags;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
@@ -54,6 +55,7 @@ import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.unfold.FoldAodAnimationController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
+import com.android.systemui.util.settings.SecureSettings;
import java.io.PrintWriter;
import java.util.Optional;
@@ -86,6 +88,7 @@ public class DozeParameters implements
private final FoldAodAnimationController mFoldAodAnimationController;
private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private final UserTracker mUserTracker;
+ private final SecureSettings mSecureSettings;
private boolean mDozeAlwaysOn;
private boolean mControlScreenOffAnimation;
@@ -130,7 +133,8 @@ public class DozeParameters implements
ConfigurationController configurationController,
StatusBarStateController statusBarStateController,
UserTracker userTracker,
- DozeInteractor dozeInteractor) {
+ DozeInteractor dozeInteractor,
+ SecureSettings secureSettings) {
mResources = resources;
mAmbientDisplayConfiguration = ambientDisplayConfiguration;
mAlwaysOnPolicy = alwaysOnDisplayPolicy;
@@ -144,6 +148,7 @@ public class DozeParameters implements
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
mUserTracker = userTracker;
mDozeInteractor = dozeInteractor;
+ mSecureSettings = secureSettings;
keyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
tunerService.addTunable(
@@ -160,7 +165,8 @@ public class DozeParameters implements
mFoldAodAnimationController.addCallback(this);
}
- SettingsObserver quickPickupSettingsObserver = new SettingsObserver(context, handler);
+ SettingsObserver quickPickupSettingsObserver =
+ new SettingsObserver(context, handler, mSecureSettings);
quickPickupSettingsObserver.observe();
batteryController.addCallback(new BatteryStateChangeCallback() {
@@ -479,18 +485,36 @@ public class DozeParameters implements
Settings.Secure.getUriFor(Settings.Secure.DOZE_ALWAYS_ON);
private final Context mContext;
- SettingsObserver(Context context, Handler handler) {
+ private final Handler mHandler;
+ private final SecureSettings mSecureSettings;
+
+ SettingsObserver(Context context, Handler handler, SecureSettings secureSettings) {
super(handler);
mContext = context;
+ mHandler = handler;
+ mSecureSettings = secureSettings;
}
void observe() {
- ContentResolver resolver = mContext.getContentResolver();
- resolver.registerContentObserver(mQuickPickupGesture, false, this,
- UserHandle.USER_ALL);
- resolver.registerContentObserver(mPickupGesture, false, this, UserHandle.USER_ALL);
- resolver.registerContentObserver(mAlwaysOnEnabled, false, this, UserHandle.USER_ALL);
- update(null);
+ if (Flags.registerContentObserversAsync()) {
+ mSecureSettings.registerContentObserverForUserAsync(mQuickPickupGesture,
+ this, UserHandle.USER_ALL);
+ mSecureSettings.registerContentObserverForUserAsync(mPickupGesture,
+ this, UserHandle.USER_ALL);
+ mSecureSettings.registerContentObserverForUserAsync(mAlwaysOnEnabled,
+ this, UserHandle.USER_ALL,
+ // The register calls are called in order, so this ensures that update()
+ // is called after them all and value retrieval isn't racy.
+ () -> mHandler.post(() -> update(null)));
+ } else {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(mQuickPickupGesture, false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(mPickupGesture, false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(mAlwaysOnEnabled, false, this,
+ UserHandle.USER_ALL);
+ update(null);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index 330383ff03af..a32d5fef58eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -29,8 +29,10 @@ import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
+import androidx.annotation.MainThread;
import androidx.annotation.Nullable;
+import com.android.app.tracing.TraceUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.assist.AssistManager;
@@ -61,6 +63,8 @@ import com.android.systemui.util.IListenerSet;
import dagger.Lazy;
+import kotlin.Unit;
+
import kotlinx.coroutines.ExperimentalCoroutinesApi;
import javax.inject.Inject;
@@ -109,7 +113,7 @@ public final class DozeServiceHost implements DozeHost {
private CentralSurfaces mCentralSurfaces;
private boolean mAlwaysOnSuppressed;
private boolean mPulsePending;
- private DozeInteractor mDozeInteractor;
+ private final DozeInteractor mDozeInteractor;
@Inject
public DozeServiceHost(DozeLog dozeLog, PowerManager powerManager,
@@ -337,13 +341,17 @@ public final class DozeServiceHost implements DozeHost {
}
@Override
+ @MainThread
public void dozeTimeTick() {
- mDozeInteractor.dozeTimeTick();
- mShadeLockscreenInteractor.dozeTimeTick();
- mAuthController.dozeTimeTick();
- if (mAmbientIndicationContainer instanceof DozeReceiver) {
- ((DozeReceiver) mAmbientIndicationContainer).dozeTimeTick();
- }
+ TraceUtils.trace("DozeServiceHost#dozeTimeTick", () -> {
+ mDozeInteractor.dozeTimeTick();
+ mShadeLockscreenInteractor.dozeTimeTick();
+ mAuthController.dozeTimeTick();
+ if (mAmbientIndicationContainer instanceof DozeReceiver) {
+ ((DozeReceiver) mAmbientIndicationContainer).dozeTimeTick();
+ }
+ return Unit.INSTANCE;
+ });
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 4ce901030e57..a2e44dffb767 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -31,7 +31,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.policy.SystemBarUtils;
import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
@@ -40,7 +39,6 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener;
-import com.android.systemui.statusbar.notification.collection.provider.OnReorderingBannedListener;
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.data.repository.HeadsUpRepository;
@@ -88,7 +86,7 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements
private final List<OnHeadsUpPhoneListenerChange> mHeadsUpPhoneListeners = new ArrayList<>();
private final VisualStabilityProvider mVisualStabilityProvider;
- private AvalancheController mAvalancheController;
+ private final AvalancheController mAvalancheController;
// TODO(b/328393698) move the topHeadsUpRow logic to an interactor
private final MutableStateFlow<HeadsUpRowRepository> mTopHeadsUpRow =
@@ -107,7 +105,6 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements
private int mStatusBarState;
private AnimationStateHandler mAnimationStateHandler;
- private Handler mBgHandler;
private int mHeadsUpInset;
// Used for determining the region for touch interaction
@@ -152,8 +149,7 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements
UiEventLogger uiEventLogger,
JavaAdapter javaAdapter,
ShadeInteractor shadeInteractor,
- AvalancheController avalancheController,
- @Background Handler bgHandler) {
+ AvalancheController avalancheController) {
super(context, logger, handler, globalSettings, systemClock, executor,
accessibilityManagerWrapper, uiEventLogger, avalancheController);
Resources resources = mContext.getResources();
@@ -163,7 +159,6 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements
mGroupMembershipManager = groupMembershipManager;
mVisualStabilityProvider = visualStabilityProvider;
mAvalancheController = avalancheController;
- mBgHandler = bgHandler;
updateResources();
configurationController.addCallback(new ConfigurationController.ConfigurationListener() {
@Override
@@ -176,11 +171,8 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements
updateResources();
}
});
- if (!NotificationsHeadsUpRefactor.isEnabled()) {
- javaAdapter.alwaysCollectFlow(shadeInteractor.isAnyExpanded(),
+ javaAdapter.alwaysCollectFlow(shadeInteractor.isAnyExpanded(),
this::onShadeOrQsExpanded);
- }
- mVisualStabilityProvider.addPersistentReorderingBannedListener(mOnReorderingBannedListener);
}
public void setAnimationStateHandler(AnimationStateHandler handler) {
@@ -275,10 +267,9 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements
}
private void onShadeOrQsExpanded(Boolean isExpanded) {
- NotificationsHeadsUpRefactor.assertInLegacyMode();
if (isExpanded != mIsExpanded) {
mIsExpanded = isExpanded;
- if (isExpanded) {
+ if (!NotificationsHeadsUpRefactor.isEnabled() && isExpanded) {
mHeadsUpAnimatingAway.setValue(false);
}
}
@@ -388,8 +379,6 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements
private final OnReorderingAllowedListener mOnReorderingAllowedListener = () -> {
mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(false);
- mAvalancheController.setEnableAtRuntime(true);
-
for (NotificationEntry entry : mEntriesToRemoveWhenReorderingAllowed) {
if (isHeadsUpEntry(entry.getKey())) {
// Maybe the heads-up was removed already
@@ -400,32 +389,6 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements
mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(true);
};
- private final OnReorderingBannedListener mOnReorderingBannedListener = () -> {
- if (mAvalancheController != null) {
- // Waiting HUNs in AvalancheController are still promoted to the HUN section and thus
- // seen in open shade; clear them so we don't show them again when the shade closes and
- // reordering is allowed again.
- int waitingKeysSize = mAvalancheController.getWaitingKeys().size();
- mBgHandler.post(() -> {
- // Do this in the background to avoid missing frames when closing the shade
- mAvalancheController.logDroppedHuns(waitingKeysSize);
- });
- mAvalancheController.clearNext();
-
- // In open shade the first HUN is pinned, and visual stability logic prevents us from
- // unpinning this first HUN as long as the shade remains open. AvalancheController only
- // shows the next HUN when the currently showing HUN is unpinned, so we must disable
- // throttling here so that the incoming HUN stream is not forever paused. This is reset
- // when reorder becomes allowed.
- mAvalancheController.setEnableAtRuntime(false);
-
- // Note that we cannot do the above when
- // 1) the remove runnable runs because its delay means it may not run before shade close
- // 2) reordering is allowed again (when shade closes) because the HUN appear animation
- // will have started by then
- }
- };
-
///////////////////////////////////////////////////////////////////////////////////////////////
// HeadsUpManager utility (protected) methods overrides:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpNotificationViewControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpNotificationViewControllerEmptyImpl.kt
new file mode 100644
index 000000000000..9f76429bd6a5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpNotificationViewControllerEmptyImpl.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.phone
+
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.phone.HeadsUpTouchHelper.HeadsUpNotificationViewController
+
+/** Empty impl of [HeadsUpNotificationViewController] for use with Scene Container */
+class HeadsUpNotificationViewControllerEmptyImpl : HeadsUpNotificationViewController {
+ override fun setHeadsUpDraggingStartingHeight(startHeight: Int) {}
+
+ override fun setTrackedHeadsUp(expandableNotificationRow: ExpandableNotificationRow?) {}
+
+ override fun startExpand(
+ newX: Float,
+ newY: Float,
+ startTracking: Boolean,
+ expandedHeight: Float
+ ) {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 198272e9b162..26bd7ac74d97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -23,6 +23,7 @@ import android.view.ViewConfiguration;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.Gefingerpoken;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
@@ -122,9 +123,13 @@ public class HeadsUpTouchHelper implements Gefingerpoken {
+ mPickedChild.getTranslationY());
mPanel.setHeadsUpDraggingStartingHeight(startHeight);
mPanel.startExpand(x, y, true /* startTracking */, startHeight);
- // This call needs to be after the expansion start otherwise we will get a
- // flicker of one frame as it's not expanded yet.
- mHeadsUpManager.unpinAll(true);
+
+ if (!SceneContainerFlag.isEnabled()) {
+ // This call needs to be after the expansion start otherwise we will get a
+ // flicker of one frame as it's not expanded yet.
+ mHeadsUpManager.unpinAll(true);
+ }
+
clearNotificationEffects();
endMotion();
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index 97791acfb43a..316e1f13bc2b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -22,6 +22,7 @@ import android.content.res.Resources
import android.hardware.biometrics.BiometricSourceType
import android.provider.Settings
import com.android.app.tracing.ListenersTracing.forEachTraced
+import com.android.app.tracing.coroutines.launch
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -159,7 +160,7 @@ class KeyguardBypassController @Inject constructor(
}
fun listenForQsExpandedChange() =
- applicationScope.launch {
+ applicationScope.launch("listenForQsExpandedChange") {
shadeInteractorLazy.get().qsExpansion.map { it > 0f }.distinctUntilChanged()
.collect { isQsExpanded ->
val changed = qsExpanded != isQsExpanded
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
index bcb613fe2b8c..e69a78fb14fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
@@ -33,13 +33,13 @@ import android.view.View
import android.view.WindowManager
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.ActivityIntentHelper
-import com.android.systemui.Flags.communalHub
import com.android.systemui.Flags.mediaLockscreenLaunchAnimation
import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.animation.DelegateTransitionAnimatorController
import com.android.systemui.assist.AssistManager
import com.android.systemui.camera.CameraIntents
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.DisplayId
@@ -94,6 +94,7 @@ constructor(
private val activityIntentHelper: ActivityIntentHelper,
@Main private val mainExecutor: DelayableExecutor,
private val communalSceneInteractor: CommunalSceneInteractor,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
) : ActivityStarterInternal {
private val centralSurfaces: CentralSurfaces?
get() = centralSurfacesOptLazy.get().getOrNull()
@@ -276,10 +277,11 @@ constructor(
statusBarController
}
+ val isCommunalDismissLaunch = isCommunalWidgetLaunch() && !actuallyShowOverLockscreen
// If we animate, don't collapse the shade and defer the keyguard dismiss (in case we
// run the animation on the keyguard). The animation will take care of (instantly)
// collapsing the shade and hiding the keyguard once it is done.
- val collapse = dismissShade && !animate
+ val collapse = (dismissShade || isCommunalDismissLaunch) && !animate
val runnable = Runnable {
try {
activityTransitionAnimator.startPendingIntentWithAnimation(
@@ -338,8 +340,9 @@ constructor(
postOnUiThread(delay = 0) {
executeRunnableDismissingKeyguard(
runnable = runnable,
- afterKeyguardGone = willLaunchResolverActivity,
dismissShade = collapse,
+ afterKeyguardGone = willLaunchResolverActivity,
+ deferred = isCommunalDismissLaunch,
willAnimateOnKeyguard = animate,
customMessage = customMessage,
)
@@ -461,7 +464,9 @@ constructor(
override fun onDismiss(): Boolean {
if (runnable != null) {
if (
- keyguardStateController.isShowing && keyguardStateController.isOccluded
+ keyguardStateController.isShowing &&
+ keyguardStateController.isOccluded &&
+ !isCommunalWidgetLaunch()
) {
statusBarKeyguardViewManagerLazy
.get()
@@ -473,17 +478,10 @@ constructor(
if (dismissShade) {
shadeControllerLazy.get().collapseShadeForActivityStart()
}
- if (communalHub()) {
- communalSceneInteractor.changeSceneForActivityStartOnDismissKeyguard()
- }
return deferred
}
override fun willRunAnimationOnKeyguard(): Boolean {
- if (communalHub() && communalSceneInteractor.isIdleOnCommunal.value) {
- // Override to false when launching activity over the hub that requires auth
- return false
- }
return willAnimateOnKeyguard
}
}
@@ -564,7 +562,7 @@ constructor(
override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) {
super.onTransitionAnimationStart(isExpandingFullyAbove)
- if (communalHub()) {
+ if (communalSettingsInteractor.isCommunalFlagEnabled()) {
communalSceneInteractor.snapToScene(
CommunalScenes.Blank,
ActivityTransitionAnimator.TIMINGS.totalDuration
@@ -639,7 +637,8 @@ constructor(
showOverLockscreen: Boolean,
): Boolean {
// TODO(b/294418322): always support launch animations when occluded.
- val ignoreOcclusion = showOverLockscreen && mediaLockscreenLaunchAnimation()
+ val ignoreOcclusion =
+ (showOverLockscreen && mediaLockscreenLaunchAnimation()) || isCommunalWidgetLaunch()
if (keyguardStateController.isOccluded && !ignoreOcclusion) {
return false
}
@@ -659,6 +658,12 @@ constructor(
return shouldAnimateLaunch(isActivityIntent, false)
}
+ private fun isCommunalWidgetLaunch(): Boolean {
+ return communalSettingsInteractor.isCommunalFlagEnabled() &&
+ communalSceneInteractor.isCommunalVisible.value &&
+ communalSceneInteractor.isLaunchingWidget.value
+ }
+
private fun postOnUiThread(delay: Int = 0, runnable: Runnable) {
mainExecutor.executeDelayed(runnable, delay.toLong())
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 9cece762c7e5..069c6241491c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -76,6 +76,7 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.scene.shared.model.Scenes;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.shade.ShadeViewController;
+import com.android.systemui.shade.shared.flag.DualShade;
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
import com.android.systemui.statusbar.notification.stack.ViewState;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -87,6 +88,7 @@ import com.android.systemui.util.wakelock.WakeLock;
import com.android.systemui.wallpapers.data.repository.WallpaperRepository;
import kotlinx.coroutines.CoroutineDispatcher;
+import kotlinx.coroutines.ExperimentalCoroutinesApi;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -101,6 +103,7 @@ import javax.inject.Inject;
* security method gets shown).
*/
@SysUISingleton
+@ExperimentalCoroutinesApi
public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dumpable,
CoreStartable {
@@ -471,6 +474,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
// PRIMARY_BOUNCER->GONE
collectFlow(behindScrim, mKeyguardTransitionInteractor.transition(
+ Edge.Companion.getINVALID(),
Edge.Companion.create(PRIMARY_BOUNCER, GONE)),
mBouncerToGoneTransition, mMainDispatcher);
collectFlow(behindScrim, mPrimaryBouncerToGoneTransitionViewModel.getScrimAlpha(),
@@ -999,7 +1003,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
if (!mScreenOffAnimationController.shouldExpandNotifications()
&& !mAnimatingPanelExpansionOnUnlock
&& !occluding) {
- if (mTransparentScrimBackground) {
+ if (mTransparentScrimBackground || DualShade.isEnabled()) {
mBehindAlpha = 0;
mNotificationsAlpha = 0;
} else if (mClipsQsScrim) {
@@ -1051,7 +1055,12 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
behindAlpha = 0f;
}
mInFrontAlpha = mState.getFrontAlpha();
- if (mClipsQsScrim) {
+ if (DualShade.isEnabled() && mState == ScrimState.SHADE_LOCKED) {
+ mBehindAlpha = 0;
+ mNotificationsTint = Color.TRANSPARENT;
+ mNotificationsAlpha = 0;
+ mBehindTint = Color.TRANSPARENT;
+ } else if (mClipsQsScrim) {
mNotificationsAlpha = behindAlpha;
mNotificationsTint = behindTint;
mBehindAlpha = 1;
@@ -1105,8 +1114,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
}
private Pair<Integer, Float> calculateBackStateForState(ScrimState state) {
- // Either darken of make the scrim transparent when you
- // pull down the shade
+ // Either darken or make the scrim transparent when pulling down the shade.
float interpolatedFract = getInterpolatedFraction();
float stateBehind = mClipsQsScrim ? state.getNotifAlpha() : state.getBehindAlpha();
@@ -1201,11 +1209,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
return true;
}
- if (mState == ScrimState.PULSING) {
- return true;
- }
-
- return false;
+ return mState == ScrimState.PULSING;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index b40bf56ee66e..96127b633f70 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -63,6 +63,7 @@ import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
import com.android.systemui.bouncer.ui.BouncerView;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor;
import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dreams.DreamOverlayStateController;
@@ -77,9 +78,9 @@ import com.android.systemui.keyguard.shared.model.Edge;
import com.android.systemui.keyguard.shared.model.KeyguardDone;
import com.android.systemui.keyguard.shared.model.KeyguardState;
import com.android.systemui.keyguard.shared.model.TransitionStep;
-import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.TaskbarDelegate;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
@@ -167,6 +168,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private final BouncerView mPrimaryBouncerView;
private final Lazy<ShadeController> mShadeController;
private final Lazy<SceneInteractor> mSceneInteractorLazy;
+ private final Lazy<DeviceEntryInteractor> mDeviceEntryInteractorLazy;
private Job mListenForAlternateBouncerTransitionSteps = null;
private Job mListenForKeyguardAuthenticatedBiometricsHandled = null;
@@ -395,7 +397,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
Lazy<KeyguardSurfaceBehindInteractor> surfaceBehindInteractor,
JavaAdapter javaAdapter,
Lazy<SceneInteractor> sceneInteractorLazy,
- StatusBarKeyguardViewManagerInteractor statusBarKeyguardViewManagerInteractor
+ StatusBarKeyguardViewManagerInteractor statusBarKeyguardViewManagerInteractor,
+ Lazy<DeviceEntryInteractor> deviceEntryInteractorLazy
) {
mContext = context;
mViewMediatorCallback = callback;
@@ -430,6 +433,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mJavaAdapter = javaAdapter;
mSceneInteractorLazy = sceneInteractorLazy;
mStatusBarKeyguardViewManagerInteractor = statusBarKeyguardViewManagerInteractor;
+ mDeviceEntryInteractorLazy = deviceEntryInteractorLazy;
}
KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@@ -735,6 +739,11 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
* {@see KeyguardBouncer#show(boolean, boolean)}
*/
public void showBouncer(boolean scrimmed) {
+ if (SceneContainerFlag.isEnabled()) {
+ mDeviceEntryInteractorLazy.get().attemptDeviceEntry();
+ return;
+ }
+
if (DeviceEntryUdfpsRefactor.isEnabled()) {
if (mAlternateBouncerInteractor.canShowAlternateBouncerForFingerprint()) {
Log.d(TAG, "showBouncer:alternateBouncer.forceShow()");
@@ -777,8 +786,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
hideAlternateBouncer(false);
if (mKeyguardStateController.isShowing() && !isBouncerShowing()) {
if (SceneContainerFlag.isEnabled()) {
- mSceneInteractorLazy.get().changeScene(
- Scenes.Bouncer, "StatusBarKeyguardViewManager.showPrimaryBouncer");
+ mDeviceEntryInteractorLazy.get().attemptDeviceEntry();
} else {
mPrimaryBouncerInteractor.show(scrimmed);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
index da91d6a05d6b..6ac7f11d3ad8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
@@ -26,5 +26,5 @@ public interface StatusBarWindowCallback {
*/
void onStateChanged(boolean keyguardShowing, boolean keyguardOccluded,
boolean keyguardGoingAway, boolean bouncerShowing, boolean isDozing,
- boolean panelExpanded, boolean isDreaming);
+ boolean panelExpanded, boolean isDreaming, boolean communalShowing);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
index 2c4848776b66..f81b952ee3b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
@@ -18,7 +18,13 @@ package com.android.systemui.statusbar.phone.ongoingcall.shared.model
import android.app.PendingIntent
-/** Represents the state of any ongoing calls. */
+/**
+ * Represents the state of any ongoing calls.
+ *
+ * TODO(b/332662551): If there's an ongoing call but the user has the call app open, then we use the
+ * NoCall model, *not* the InCall model, which is confusing when looking at the logs. We may want
+ * to make that more clear, either with better logging or different models.
+ */
sealed interface OngoingCallModel {
/** There is no ongoing call. */
data object NoCall : OngoingCallModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
index 507759c037ba..68163b28dd09 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
@@ -325,7 +325,7 @@ class MobileIconInteractorImpl(
}
.stateIn(scope, SharingStarted.WhileSubscribed(), true)
- private val shownLevel: StateFlow<Int> =
+ private val cellularShownLevel: StateFlow<Int> =
combine(
level,
isInService,
@@ -337,15 +337,19 @@ class MobileIconInteractorImpl(
}
.stateIn(scope, SharingStarted.WhileSubscribed(), 0)
+ // Satellite level is unaffected by the isInService or inflateSignalStrength properties
+ // See b/346904529 for details
+ private val satelliteShownLevel: StateFlow<Int> = level
+
private val cellularIcon: Flow<SignalIconModel.Cellular> =
combine(
- shownLevel,
+ cellularShownLevel,
numberOfLevels,
showExclamationMark,
carrierNetworkChangeActive,
- ) { shownLevel, numberOfLevels, showExclamationMark, carrierNetworkChange ->
+ ) { cellularShownLevel, numberOfLevels, showExclamationMark, carrierNetworkChange ->
SignalIconModel.Cellular(
- shownLevel,
+ cellularShownLevel,
numberOfLevels,
showExclamationMark,
carrierNetworkChange,
@@ -353,7 +357,7 @@ class MobileIconInteractorImpl(
}
private val satelliteIcon: Flow<SignalIconModel.Satellite> =
- shownLevel.map {
+ satelliteShownLevel.map {
SignalIconModel.Satellite(
level = it,
icon =
@@ -365,7 +369,7 @@ class MobileIconInteractorImpl(
override val signalLevelIcon: StateFlow<SignalIconModel> = run {
val initial =
SignalIconModel.Cellular(
- shownLevel.value,
+ cellularShownLevel.value,
numberOfLevels.value,
showExclamationMark.value,
carrierNetworkChangeActive.value,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
index dbe54f346072..40799583a7b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
@@ -15,12 +15,14 @@
*/
package com.android.systemui.statusbar.policy
+import android.os.Handler
import android.util.Log
import androidx.annotation.VisibleForTesting
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
import com.android.systemui.statusbar.policy.BaseHeadsUpManager.HeadsUpEntry
@@ -35,11 +37,13 @@ import javax.inject.Inject
@SysUISingleton
class AvalancheController
@Inject
-constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger) : Dumpable {
+constructor(dumpManager: DumpManager,
+ private val uiEventLogger: UiEventLogger,
+ @Background private val bgHandler: Handler
+) : Dumpable {
private val tag = "AvalancheController"
private val debug = Compile.IS_DEBUG && Log.isLoggable(tag, Log.DEBUG)
- var enableAtRuntime = true
// HUN showing right now, in the floating state where full shade is hidden, on launcher or AOD
@VisibleForTesting var headsUpEntryShowing: HeadsUpEntry? = null
@@ -82,17 +86,17 @@ constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger)
dumpManager.registerNormalDumpable(tag, /* module */ this)
}
- fun isEnabled() : Boolean {
- return NotificationThrottleHun.isEnabled && enableAtRuntime
- }
-
fun getShowingHunKey(): String {
return getKey(headsUpEntryShowing)
}
/** Run or delay Runnable for given HeadsUpEntry */
- fun update(entry: HeadsUpEntry?, runnable: Runnable, label: String) {
- if (!isEnabled()) {
+ fun update(entry: HeadsUpEntry?, runnable: Runnable?, label: String) {
+ if (runnable == null) {
+ log { "Runnable is NULL, stop update." }
+ return
+ }
+ if (!NotificationThrottleHun.isEnabled) {
runnable.run()
return
}
@@ -147,8 +151,12 @@ constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger)
* Run or ignore Runnable for given HeadsUpEntry. If entry was never shown, ignore and delete
* all Runnables associated with that entry.
*/
- fun delete(entry: HeadsUpEntry?, runnable: Runnable, label: String) {
- if (!isEnabled()) {
+ fun delete(entry: HeadsUpEntry?, runnable: Runnable?, label: String) {
+ if (runnable == null) {
+ log { "Runnable is NULL, stop delete." }
+ return
+ }
+ if (!NotificationThrottleHun.isEnabled) {
runnable.run()
return
}
@@ -189,7 +197,7 @@ constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger)
* BaseHeadsUpManager.HeadsUpEntry.calculateFinishTime to shorten display duration.
*/
fun getDurationMs(entry: HeadsUpEntry, autoDismissMs: Int): Int {
- if (!isEnabled()) {
+ if (!NotificationThrottleHun.isEnabled) {
// Use default duration, like we did before AvalancheController existed
return autoDismissMs
}
@@ -238,7 +246,7 @@ constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger)
/** Return true if entry is waiting to show. */
fun isWaiting(key: String): Boolean {
- if (!isEnabled()) {
+ if (!NotificationThrottleHun.isEnabled) {
return false
}
for (entry in nextMap.keys) {
@@ -251,7 +259,7 @@ constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger)
/** Return list of keys for huns waiting */
fun getWaitingKeys(): MutableList<String> {
- if (!isEnabled()) {
+ if (!NotificationThrottleHun.isEnabled) {
return mutableListOf()
}
val keyList = mutableListOf<String>()
@@ -262,7 +270,7 @@ constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger)
}
fun getWaitingEntry(key: String): HeadsUpEntry? {
- if (!isEnabled()) {
+ if (!NotificationThrottleHun.isEnabled) {
return null
}
for (headsUpEntry in nextMap.keys) {
@@ -274,7 +282,7 @@ constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger)
}
fun getWaitingEntryList(): List<HeadsUpEntry> {
- if (!isEnabled()) {
+ if (!NotificationThrottleHun.isEnabled) {
return mutableListOf()
}
return nextMap.keys.toList()
@@ -315,7 +323,7 @@ constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger)
// Remove runnable labels for dropped huns
val listToDrop = nextList.subList(1, nextList.size)
- logDroppedHuns(listToDrop.size)
+ logDroppedHunsInBackground(listToDrop.size)
if (debug) {
// Clear runnable labels
@@ -332,10 +340,13 @@ constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger)
showNow(headsUpEntryShowing!!, headsUpEntryShowingRunnableList)
}
- fun logDroppedHuns(numDropped: Int) {
- for (n in 1..numDropped) {
- uiEventLogger.log(ThrottleEvent.AVALANCHE_THROTTLING_HUN_DROPPED)
- }
+ fun logDroppedHunsInBackground(numDropped: Int) {
+ bgHandler.post(Runnable {
+ // Do this in the background to avoid missing frames when closing the shade
+ for (n in 1..numDropped) {
+ uiEventLogger.log(ThrottleEvent.AVALANCHE_THROTTLING_HUN_DROPPED)
+ }
+ })
}
fun clearNext() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 6012ecd5a7f7..775f34d54e3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -250,6 +250,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
mLevel = (int) (100f
* intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
/ intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
+ int previousPluggedChargingSource = mPluggedChargingSource;
mPluggedChargingSource = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
mPluggedIn = mPluggedChargingSource != 0;
final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
@@ -276,7 +277,9 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
mIsBatteryDefender = isBatteryDefender;
fireIsBatteryDefenderChanged();
}
-
+ if (mPluggedChargingSource != previousPluggedChargingSource) {
+ updatePowerSave();
+ }
fireBatteryLevelChanged();
} else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
updatePowerSave();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index 45cb52a8b1ad..7b82b565fc4d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -26,7 +26,6 @@ import android.media.projection.MediaProjectionInfo;
import android.media.projection.MediaProjectionManager;
import android.os.Handler;
import android.util.ArrayMap;
-import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -46,11 +45,11 @@ import javax.inject.Inject;
/** Platform implementation of the cast controller. **/
@SysUISingleton
public class CastControllerImpl implements CastController {
- public static final String TAG = "CastController";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final String TAG = "CastController";
private final Context mContext;
private final PackageManager mPackageManager;
+ private final CastControllerLogger mLogger;
@GuardedBy("mCallbacks")
private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
private final MediaRouter mMediaRouter;
@@ -67,20 +66,22 @@ public class CastControllerImpl implements CastController {
public CastControllerImpl(
Context context,
PackageManager packageManager,
- DumpManager dumpManager) {
+ DumpManager dumpManager,
+ CastControllerLogger logger) {
mContext = context;
mPackageManager = packageManager;
+ mLogger = logger;
mMediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
mMediaRouter.setRouterGroupId(MediaRouter.MIRRORING_GROUP_ID);
mProjectionManager = (MediaProjectionManager)
context.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
mProjection = mProjectionManager.getActiveProjectionInfo();
mProjectionManager.addCallback(mProjectionCallback, new Handler());
- dumpManager.registerDumpable(TAG, this);
- if (DEBUG) Log.d(TAG, "new CastController()");
+ dumpManager.registerNormalDumpable(TAG, this);
}
- public void dump(PrintWriter pw, String[] args) {
+ @Override
+ public void dump(PrintWriter pw, @NonNull String[] args) {
pw.println("CastController state:");
pw.print(" mDiscovering="); pw.println(mDiscovering);
pw.print(" mCallbackRegistered="); pw.println(mCallbackRegistered);
@@ -88,7 +89,7 @@ public class CastControllerImpl implements CastController {
pw.print(" mRoutes.size="); pw.println(mRoutes.size());
for (int i = 0; i < mRoutes.size(); i++) {
final RouteInfo route = mRoutes.valueAt(i);
- pw.print(" "); pw.println(routeToString(route));
+ pw.print(" "); pw.println(CastControllerLogger.Companion.toLogString(route));
}
pw.print(" mProjection="); pw.println(mProjection);
}
@@ -119,7 +120,7 @@ public class CastControllerImpl implements CastController {
synchronized (mDiscoveringLock) {
if (mDiscovering == request) return;
mDiscovering = request;
- if (DEBUG) Log.d(TAG, "setDiscovering: " + request);
+ mLogger.logDiscovering(request);
handleDiscoveryChangeLocked();
}
}
@@ -166,7 +167,8 @@ public class CastControllerImpl implements CastController {
CastDevice.Companion.toCastDevice(
mProjection,
mContext,
- mPackageManager));
+ mPackageManager,
+ mLogger));
}
}
@@ -177,22 +179,24 @@ public class CastControllerImpl implements CastController {
public void startCasting(CastDevice device) {
if (device == null || device.getTag() == null) return;
final RouteInfo route = (RouteInfo) device.getTag();
- if (DEBUG) Log.d(TAG, "startCasting: " + routeToString(route));
+ mLogger.logStartCasting(route);
mMediaRouter.selectRoute(ROUTE_TYPE_REMOTE_DISPLAY, route);
}
@Override
public void stopCasting(CastDevice device) {
+ // TODO(b/332662551): Convert Logcat to LogBuffer.
final boolean isProjection = device.getTag() instanceof MediaProjectionInfo;
- if (DEBUG) Log.d(TAG, "stopCasting isProjection=" + isProjection);
+ mLogger.logStopCasting(isProjection);
if (isProjection) {
final MediaProjectionInfo projection = (MediaProjectionInfo) device.getTag();
if (Objects.equals(mProjectionManager.getActiveProjectionInfo(), projection)) {
mProjectionManager.stopActiveProjection();
} else {
- Log.w(TAG, "Projection is no longer active: " + projection);
+ mLogger.logStopCastingNoProjection(projection);
}
} else {
+ mLogger.logStopCastingMediaRouter();
mMediaRouter.getFallbackRoute().select();
}
}
@@ -217,7 +221,7 @@ public class CastControllerImpl implements CastController {
}
}
if (changed) {
- if (DEBUG) Log.d(TAG, "setProjection: " + oldProjection + " -> " + mProjection);
+ mLogger.logSetProjection(oldProjection, mProjection);
fireOnCastDevicesChanged();
}
}
@@ -264,42 +268,30 @@ public class CastControllerImpl implements CastController {
callback.onCastDevicesChanged();
}
- private static String routeToString(RouteInfo route) {
- if (route == null) return null;
- final StringBuilder sb = new StringBuilder().append(route.getName()).append('/')
- .append(route.getDescription()).append('@').append(route.getDeviceAddress())
- .append(",status=").append(route.getStatus());
- if (route.isDefault()) sb.append(",default");
- if (route.isEnabled()) sb.append(",enabled");
- if (route.isConnecting()) sb.append(",connecting");
- if (route.isSelected()) sb.append(",selected");
- return sb.append(",id=").append(route.getTag()).toString();
- }
-
private final MediaRouter.SimpleCallback mMediaCallback = new MediaRouter.SimpleCallback() {
@Override
public void onRouteAdded(MediaRouter router, RouteInfo route) {
- if (DEBUG) Log.d(TAG, "onRouteAdded: " + routeToString(route));
+ mLogger.logRouteAdded(route);
updateRemoteDisplays();
}
@Override
public void onRouteChanged(MediaRouter router, RouteInfo route) {
- if (DEBUG) Log.d(TAG, "onRouteChanged: " + routeToString(route));
+ mLogger.logRouteChanged(route);
updateRemoteDisplays();
}
@Override
public void onRouteRemoved(MediaRouter router, RouteInfo route) {
- if (DEBUG) Log.d(TAG, "onRouteRemoved: " + routeToString(route));
+ mLogger.logRouteRemoved(route);
updateRemoteDisplays();
}
@Override
public void onRouteSelected(MediaRouter router, int type, RouteInfo route) {
- if (DEBUG) Log.d(TAG, "onRouteSelected(" + type + "): " + routeToString(route));
+ mLogger.logRouteSelected(route, type);
updateRemoteDisplays();
}
@Override
public void onRouteUnselected(MediaRouter router, int type, RouteInfo route) {
- if (DEBUG) Log.d(TAG, "onRouteUnselected(" + type + "): " + routeToString(route));
+ mLogger.logRouteUnselected(route, type);
updateRemoteDisplays();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerLogger.kt
new file mode 100644
index 000000000000..9a3a244c6157
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerLogger.kt
@@ -0,0 +1,141 @@
+/*
+ * 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.policy
+
+import android.media.MediaRouter.RouteInfo
+import android.media.projection.MediaProjectionInfo
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.core.MessageInitializer
+import com.android.systemui.log.core.MessagePrinter
+import com.android.systemui.statusbar.policy.dagger.CastControllerLog
+import javax.inject.Inject
+
+/** Helper class for logging events to [CastControllerLog] from Java. */
+@SysUISingleton
+class CastControllerLogger
+@Inject
+constructor(
+ @CastControllerLog val logger: LogBuffer,
+) {
+ /** Passthrough to [logger]. */
+ inline fun log(
+ tag: String,
+ level: LogLevel,
+ messageInitializer: MessageInitializer,
+ noinline messagePrinter: MessagePrinter,
+ exception: Throwable? = null,
+ ) {
+ logger.log(tag, level, messageInitializer, messagePrinter, exception)
+ }
+
+ fun logDiscovering(isDiscovering: Boolean) =
+ logger.log(TAG, LogLevel.DEBUG, { bool1 = isDiscovering }, { "setDiscovering: $bool1" })
+
+ fun logStartCasting(route: RouteInfo) =
+ logger.log(TAG, LogLevel.DEBUG, { str1 = route.toLogString() }, { "startCasting: $str1" })
+
+ fun logStopCasting(isProjection: Boolean) =
+ logger.log(
+ TAG,
+ LogLevel.DEBUG,
+ { bool1 = isProjection },
+ { "stopCasting. isProjection=$bool1" },
+ )
+
+ fun logStopCastingNoProjection(projection: MediaProjectionInfo) =
+ logger.log(
+ TAG,
+ LogLevel.WARNING,
+ { str1 = projection.toString() },
+ { "stopCasting failed because projection is no longer active: $str1" },
+ )
+
+ fun logStopCastingMediaRouter() =
+ logger.log(
+ TAG,
+ LogLevel.DEBUG,
+ {},
+ { "stopCasting is selecting fallback route in MediaRouter" },
+ )
+
+ fun logSetProjection(oldInfo: MediaProjectionInfo?, newInfo: MediaProjectionInfo?) =
+ logger.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = oldInfo.toString()
+ str2 = newInfo.toString()
+ },
+ { "setProjection: $str1 -> $str2" },
+ )
+
+ fun logRouteAdded(route: RouteInfo) =
+ logger.log(TAG, LogLevel.DEBUG, { str1 = route.toLogString() }, { "onRouteAdded: $str1" })
+
+ fun logRouteChanged(route: RouteInfo) =
+ logger.log(TAG, LogLevel.DEBUG, { str1 = route.toLogString() }, { "onRouteChanged: $str1" })
+
+ fun logRouteRemoved(route: RouteInfo) =
+ logger.log(TAG, LogLevel.DEBUG, { str1 = route.toLogString() }, { "onRouteRemoved: $str1" })
+
+ fun logRouteSelected(route: RouteInfo, type: Int) =
+ logger.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = route.toLogString()
+ int1 = type
+ },
+ { "onRouteSelected($int1): $str1" },
+ )
+
+ fun logRouteUnselected(route: RouteInfo, type: Int) =
+ logger.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = route.toLogString()
+ int1 = type
+ },
+ { "onRouteUnselected($int1): $str1" },
+ )
+
+ companion object {
+ @JvmStatic
+ fun RouteInfo?.toLogString(): String? {
+ if (this == null) return null
+ val sb =
+ StringBuilder()
+ .append(name)
+ .append('/')
+ .append(description)
+ .append('@')
+ .append(deviceAddress)
+ .append(",status=")
+ .append(status)
+ if (isDefault) sb.append(",default")
+ if (isEnabled) sb.append(",enabled")
+ if (isConnecting) sb.append(",connecting")
+ if (isSelected) sb.append(",selected")
+ return sb.append(",id=").append(this.tag).toString()
+ }
+
+ private const val TAG = "CastController"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastDevice.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastDevice.kt
index 5fc160bd5da3..a787f7e09f0d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastDevice.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastDevice.kt
@@ -20,7 +20,7 @@ import android.content.pm.PackageManager
import android.media.MediaRouter
import android.media.projection.MediaProjectionInfo
import android.text.TextUtils
-import android.util.Log
+import com.android.systemui.log.core.LogLevel
import com.android.systemui.res.R
import com.android.systemui.util.Utils
@@ -38,6 +38,9 @@ data class CastDevice(
) {
val isCasting = state == CastState.Connecting || state == CastState.Connected
+ val shortLogString: String =
+ "CastDevice(id=$id name=$name description=$description state=$state origin=$origin)"
+
companion object {
/** Creates a [CastDevice] based on the provided information from MediaRouter. */
fun MediaRouter.RouteInfo.toCastDevice(context: Context): CastDevice {
@@ -61,11 +64,12 @@ data class CastDevice(
/** Creates a [CastDevice] based on the provided information from MediaProjection. */
fun MediaProjectionInfo.toCastDevice(
context: Context,
- packageManager: PackageManager
+ packageManager: PackageManager,
+ logger: CastControllerLogger,
): CastDevice {
return CastDevice(
id = this.packageName,
- name = getAppName(this.packageName, packageManager),
+ name = getAppName(this.packageName, packageManager, logger),
description = context.getString(R.string.quick_settings_casting),
state = CastState.Connected,
tag = this,
@@ -73,7 +77,11 @@ data class CastDevice(
)
}
- private fun getAppName(packageName: String, packageManager: PackageManager): String {
+ private fun getAppName(
+ packageName: String,
+ packageManager: PackageManager,
+ logger: CastControllerLogger,
+ ): String {
if (Utils.isHeadlessRemoteDisplayProvider(packageManager, packageName)) {
return ""
}
@@ -83,9 +91,20 @@ data class CastDevice(
if (!TextUtils.isEmpty(label)) {
return label.toString()
}
- Log.w(CastControllerImpl.TAG, "No label found for package: $packageName")
+ logger.log(
+ "#getAppName",
+ LogLevel.WARNING,
+ { str1 = packageName },
+ { "No label found for package: $str1" },
+ )
} catch (e: PackageManager.NameNotFoundException) {
- Log.w(CastControllerImpl.TAG, "Error getting appName for package: $packageName", e)
+ logger.log(
+ "#getAppName",
+ LogLevel.WARNING,
+ { str1 = packageName },
+ { "Error getting appName for package=$str1" },
+ e,
+ )
}
return packageName
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
index 2ce2bc83aa25..cf9a78f1c11c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
@@ -29,6 +29,7 @@ import com.android.systemui.qs.tiles.DndTile
import com.android.systemui.qs.tiles.FlashlightTile
import com.android.systemui.qs.tiles.LocationTile
import com.android.systemui.qs.tiles.MicrophoneToggleTile
+import com.android.systemui.qs.tiles.ModesTile
import com.android.systemui.qs.tiles.UiModeNightTile
import com.android.systemui.qs.tiles.WorkModeTile
import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
@@ -45,6 +46,10 @@ import com.android.systemui.qs.tiles.impl.location.domain.LocationTileMapper
import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileDataInteractor
import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileUserActionInteractor
import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
+import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileDataInteractor
+import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
+import com.android.systemui.qs.tiles.impl.modes.ui.ModesTileMapper
import com.android.systemui.qs.tiles.impl.sensorprivacy.SensorPrivacyToggleTileDataInteractor
import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.SensorPrivacyToggleTileUserActionInteractor
import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
@@ -75,6 +80,12 @@ interface PolicyModule {
/** Inject DndTile into tileMap in QSModule */
@Binds @IntoMap @StringKey(DndTile.TILE_SPEC) fun bindDndTile(dndTile: DndTile): QSTileImpl<*>
+ /** Inject ModesTile into tileMap in QSModule */
+ @Binds
+ @IntoMap
+ @StringKey(ModesTile.TILE_SPEC)
+ fun bindModesTile(modesTile: ModesTile): QSTileImpl<*>
+
/** Inject WorkModeTile into tileMap in QSModule */
@Binds
@IntoMap
@@ -85,35 +96,35 @@ interface PolicyModule {
@IntoMap
@StringKey(FLASHLIGHT_TILE_SPEC)
fun provideAirplaneModeAvailabilityInteractor(
- impl: FlashlightTileDataInteractor
+ impl: FlashlightTileDataInteractor
): QSTileAvailabilityInteractor
@Binds
@IntoMap
@StringKey(LOCATION_TILE_SPEC)
fun provideLocationAvailabilityInteractor(
- impl: LocationTileDataInteractor
+ impl: LocationTileDataInteractor
): QSTileAvailabilityInteractor
@Binds
@IntoMap
@StringKey(ALARM_TILE_SPEC)
fun provideAlarmAvailabilityInteractor(
- impl: AlarmTileDataInteractor
+ impl: AlarmTileDataInteractor
): QSTileAvailabilityInteractor
@Binds
@IntoMap
@StringKey(UIMODENIGHT_TILE_SPEC)
fun provideUiModeNightAvailabilityInteractor(
- impl: UiModeNightTileDataInteractor
+ impl: UiModeNightTileDataInteractor
): QSTileAvailabilityInteractor
@Binds
@IntoMap
@StringKey(WORK_MODE_TILE_SPEC)
fun provideWorkModeAvailabilityInteractor(
- impl: WorkModeTileDataInteractor
+ impl: WorkModeTileDataInteractor
): QSTileAvailabilityInteractor
companion object {
@@ -125,6 +136,7 @@ interface PolicyModule {
const val CAMERA_TOGGLE_TILE_SPEC = "cameratoggle"
const val MIC_TOGGLE_TILE_SPEC = "mictoggle"
const val DND_TILE_SPEC = "dnd"
+ const val MODES_TILE_SPEC = "modes"
/** Inject flashlight config */
@Provides
@@ -327,7 +339,7 @@ interface PolicyModule {
@IntoMap
@StringKey(CAMERA_TOGGLE_TILE_SPEC)
fun provideCameraToggleAvailabilityInteractor(
- factory: SensorPrivacyToggleTileDataInteractor.Factory
+ factory: SensorPrivacyToggleTileDataInteractor.Factory
): QSTileAvailabilityInteractor {
return factory.create(CAMERA)
}
@@ -369,12 +381,11 @@ interface PolicyModule {
@IntoMap
@StringKey(MIC_TOGGLE_TILE_SPEC)
fun provideMicToggleModeAvailabilityInteractor(
- factory: SensorPrivacyToggleTileDataInteractor.Factory
+ factory: SensorPrivacyToggleTileDataInteractor.Factory
): QSTileAvailabilityInteractor {
return factory.create(MICROPHONE)
}
-
/** Inject microphone toggle config */
@Provides
@IntoMap
@@ -389,6 +400,37 @@ interface PolicyModule {
),
instanceId = uiEventLogger.getNewInstanceId(),
)
+
+ @Provides
+ @IntoMap
+ @StringKey(MODES_TILE_SPEC)
+ fun provideModesTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+ QSTileConfig(
+ tileSpec = TileSpec.create(MODES_TILE_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = R.drawable.qs_dnd_icon_off,
+ labelRes = R.string.quick_settings_modes_label,
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ )
+
+ /** Inject ModesTile into tileViewModelMap in QSModule */
+ @Provides
+ @IntoMap
+ @StringKey(MODES_TILE_SPEC)
+ fun provideModesTileViewModel(
+ factory: QSTileViewModelFactory.Static<ModesTileModel>,
+ mapper: ModesTileMapper,
+ stateInteractor: ModesTileDataInteractor,
+ userActionInteractor: ModesTileUserActionInteractor
+ ): QSTileViewModel =
+ factory.create(
+ TileSpec.create(MODES_TILE_SPEC),
+ userActionInteractor,
+ stateInteractor,
+ mapper,
+ )
}
/** Inject FlashlightTile into tileMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt
index d120a1bd3840..72d093c65a91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt
@@ -22,10 +22,10 @@ interface SplitShadeStateController {
/** Returns true if the device should use the split notification shade. */
@Deprecated(
- message = "This is deprecated, please use ShadeInteractor#isSplitShade instead",
+ message = "This is deprecated, please use ShadeInteractor#shadeMode instead",
replaceWith =
ReplaceWith(
- "shadeInteractor.isSplitShade",
+ "shadeInteractor.shadeMode",
"com.android.systemui.shade.domain.interactor.ShadeInteractor",
),
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/CastControllerLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/CastControllerLog.kt
new file mode 100644
index 000000000000..23aade6e6c17
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/CastControllerLog.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.statusbar.policy.dagger
+
+import javax.inject.Qualifier
+
+/**
+ * Logs for cast events. See [com.android.systemui.statusbar.policy.CastControllerImpl] and
+ * [com.android.systemui.statusbar.policy.CastControllerLogger].
+ */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class CastControllerLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
index e08e4d70a18e..71bcdfcba049 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
@@ -228,4 +228,12 @@ public interface StatusBarPolicyModule {
static LogBuffer provideBatteryControllerLog(LogBufferFactory factory) {
return factory.create(BatteryControllerLogger.TAG, 30);
}
+
+ /** Provides a log buffer for CastControllerImpl */
+ @Provides
+ @SysUISingleton
+ @CastControllerLog
+ static LogBuffer provideCastControllerLog(LogBufferFactory factory) {
+ return factory.create("CastControllerLog", 50);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
index f5d7d0029e90..e4d06681d439 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
@@ -17,7 +17,7 @@
package com.android.systemui.statusbar.policy.domain.interactor
import android.provider.Settings
-import com.android.settingslib.statusbar.notification.data.repository.ZenModeRepository
+import com.android.settingslib.notification.data.repository.ZenModeRepository
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
index 3e0118007c3c..4869114bc565 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
@@ -20,7 +20,8 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.shared.model.StatusBarState
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.domain.interactor.KeyguardStatusBarInteractor
import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
import com.android.systemui.statusbar.policy.BatteryController
@@ -48,6 +49,7 @@ class KeyguardStatusBarViewModel
constructor(
@Application scope: CoroutineScope,
headsUpNotificationInteractor: HeadsUpNotificationInteractor,
+ sceneInteractor: SceneInteractor,
keyguardInteractor: KeyguardInteractor,
keyguardStatusBarInteractor: KeyguardStatusBarInteractor,
batteryController: BatteryController,
@@ -55,11 +57,11 @@ constructor(
/** True if this view should be visible and false otherwise. */
val isVisible: StateFlow<Boolean> =
combine(
+ sceneInteractor.currentScene,
keyguardInteractor.isDozing,
- keyguardInteractor.statusBarState,
headsUpNotificationInteractor.showHeadsUpStatusBar,
- ) { isDozing, statusBarState, showHeadsUpStatusBar ->
- !isDozing && statusBarState == StatusBarState.KEYGUARD && !showHeadsUpStatusBar
+ ) { currentScene, isDozing, showHeadsUpStatusBar ->
+ currentScene == Scenes.Lockscreen && !isDozing && !showHeadsUpStatusBar
}
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 4963aae08ab7..c7fc44513473 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -202,8 +202,8 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
}
boolean currentUser = userId == mUserTracker.getUserId();
boolean isAsleep = themeOverlayControllerWakefulnessDeprecation()
- ? mKeyguardTransitionInteractor.isFinishedInStateWhereValue(
- KeyguardState.Companion::deviceIsAsleepInState)
+ ? KeyguardState.Companion.deviceIsAsleepInState(
+ mKeyguardTransitionInteractor.getFinishedState())
: mWakefulnessLifecycle.getWakefulness() != WAKEFULNESS_ASLEEP;
if (currentUser && !mAcceptColorEvents && isAsleep) {
@@ -525,7 +525,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
if (themeOverlayControllerWakefulnessDeprecation()) {
mJavaAdapter.alwaysCollectFlow(
- mKeyguardTransitionInteractor.isFinishedInState(KeyguardState.DOZING),
+ mKeyguardTransitionInteractor.isFinishedIn(KeyguardState.DOZING),
isFinishedInDozing -> {
if (isFinishedInDozing) whenAsleepHandler.run();
});
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/GestureViewModelFactory.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/GestureViewModelFactory.kt
deleted file mode 100644
index 504bd5fbcb42..000000000000
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/GestureViewModelFactory.kt
+++ /dev/null
@@ -1,39 +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.touchpad.tutorial.ui
-
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
-
-sealed class GestureTutorialViewModel : ViewModel()
-
-class BackGestureTutorialViewModel : GestureTutorialViewModel()
-
-class HomeGestureTutorialViewModel : GestureTutorialViewModel()
-
-class GestureViewModelFactory : ViewModelProvider.Factory {
-
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return when (modelClass) {
- BackGestureTutorialViewModel::class.java -> BackGestureTutorialViewModel()
- HomeGestureTutorialViewModel::class.java -> HomeGestureTutorialViewModel()
- else -> error("Unknown ViewModel class: ${modelClass.name}")
- }
- as T
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/BackGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
index 2460761c8592..396c6b82639e 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/BackGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
@@ -14,12 +14,14 @@
* limitations under the License.
*/
-package com.android.systemui.touchpad.tutorial.ui.view
+package com.android.systemui.touchpad.tutorial.ui.composable
import androidx.activity.compose.BackHandler
+import androidx.annotation.StringRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
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.Spacer
@@ -31,29 +33,67 @@ import androidx.compose.foundation.layout.width
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
+import androidx.compose.ui.input.pointer.pointerInteropFilter
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.android.systemui.res.R
+import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGesture.BACK
+import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureHandler
+@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun BackGestureTutorialScreen(
onDoneButtonClicked: () -> Unit,
onBack: () -> Unit,
- modifier: Modifier = Modifier,
) {
- BackHandler { onBack() }
+ BackHandler(onBack = onBack)
+ var gestureDone by remember { mutableStateOf(false) }
+ val swipeDistanceThresholdPx =
+ with(LocalContext.current) {
+ resources.getDimensionPixelSize(
+ com.android.internal.R.dimen.system_gestures_distance_threshold
+ )
+ }
+ val gestureHandler =
+ remember(swipeDistanceThresholdPx) {
+ TouchpadGestureHandler(BACK, swipeDistanceThresholdPx, onDone = { gestureDone = true })
+ }
+ Box(
+ modifier =
+ Modifier.fillMaxSize()
+ // we need to use pointerInteropFilter because some info about touchpad gestures is
+ // only available in MotionEvent
+ .pointerInteropFilter(onTouchEvent = gestureHandler::onMotionEvent)
+ ) {
+ GestureTutorialContent(gestureDone, onDoneButtonClicked)
+ }
+}
+
+@Composable
+private fun GestureTutorialContent(gestureDone: Boolean, onDoneButtonClicked: () -> Unit) {
Column(
verticalArrangement = Arrangement.Center,
modifier =
- modifier
+ Modifier.fillMaxSize()
.background(color = MaterialTheme.colorScheme.surfaceContainer)
.padding(start = 48.dp, top = 124.dp, end = 48.dp, bottom = 48.dp)
- .fillMaxSize()
) {
Row(modifier = Modifier.fillMaxWidth().weight(1f)) {
- TutorialDescription(modifier = Modifier.weight(1f))
+ TutorialDescription(
+ titleTextId =
+ if (gestureDone) R.string.touchpad_tutorial_gesture_done
+ else R.string.touchpad_back_gesture_action_title,
+ bodyTextId = R.string.touchpad_back_gesture_guidance,
+ modifier = Modifier.weight(1f)
+ )
Spacer(modifier = Modifier.width(76.dp))
TutorialAnimation(modifier = Modifier.weight(1f).padding(top = 24.dp))
}
@@ -62,17 +102,15 @@ fun BackGestureTutorialScreen(
}
@Composable
-fun TutorialDescription(modifier: Modifier = Modifier) {
+fun TutorialDescription(
+ @StringRes titleTextId: Int,
+ @StringRes bodyTextId: Int,
+ modifier: Modifier = Modifier
+) {
Column(verticalArrangement = Arrangement.Top, modifier = modifier) {
- Text(
- text = stringResource(id = R.string.touchpad_back_gesture_action_title),
- style = MaterialTheme.typography.displayLarge
- )
+ Text(text = stringResource(id = titleTextId), style = MaterialTheme.typography.displayLarge)
Spacer(modifier = Modifier.height(16.dp))
- Text(
- text = stringResource(id = R.string.touchpad_back_gesture_guidance),
- style = MaterialTheme.typography.bodyLarge
- )
+ Text(text = stringResource(id = bodyTextId), style = MaterialTheme.typography.bodyLarge)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialComponents.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialComponents.kt
index 16fa91d59ea5..f2276c8be71d 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialComponents.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialComponents.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.touchpad.tutorial.ui.view
+package com.android.systemui.touchpad.tutorial.ui.composable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialSelectionScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt
index 877bbe18fc43..14355fa18335 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialSelectionScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.touchpad.tutorial.ui.view
+package com.android.systemui.touchpad.tutorial.ui.composable
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt
new file mode 100644
index 000000000000..1fa7a0c44171
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.touchpad.tutorial.ui.gesture
+
+import android.view.MotionEvent
+import kotlin.math.abs
+
+/**
+ * Monitor for touchpad gestures that calls [gestureDoneCallback] when gesture was successfully
+ * done. All tracked motion events should be passed to [processTouchpadEvent]
+ */
+interface TouchpadGestureMonitor {
+
+ val gestureDistanceThresholdPx: Int
+ val gestureDoneCallback: () -> Unit
+
+ fun processTouchpadEvent(event: MotionEvent)
+}
+
+class BackGestureMonitor(
+ override val gestureDistanceThresholdPx: Int,
+ override val gestureDoneCallback: () -> Unit
+) : TouchpadGestureMonitor {
+
+ private var xStart = 0f
+
+ override fun processTouchpadEvent(event: MotionEvent) {
+ val action = event.actionMasked
+ when (action) {
+ MotionEvent.ACTION_DOWN -> {
+ if (isThreeFingerTouchpadSwipe(event)) {
+ xStart = event.x
+ }
+ }
+ MotionEvent.ACTION_UP -> {
+ if (isThreeFingerTouchpadSwipe(event)) {
+ val distance = abs(event.x - xStart)
+ if (distance >= gestureDistanceThresholdPx) {
+ gestureDoneCallback()
+ }
+ }
+ }
+ }
+ }
+
+ private fun isThreeFingerTouchpadSwipe(event: MotionEvent): Boolean {
+ return event.classification == MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE &&
+ event.getAxisValue(MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT) == 3f
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGesture.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGesture.kt
new file mode 100644
index 000000000000..4ae9c7b2426c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGesture.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.touchpad.tutorial.ui.gesture
+
+enum class TouchpadGesture {
+ BACK,
+ HOME;
+
+ fun toMonitor(
+ swipeDistanceThresholdPx: Int,
+ gestureDoneCallback: () -> Unit
+ ): TouchpadGestureMonitor {
+ return when (this) {
+ BACK -> BackGestureMonitor(swipeDistanceThresholdPx, gestureDoneCallback)
+ else -> throw IllegalArgumentException("Not implemented yet")
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt
new file mode 100644
index 000000000000..dc8471c3248a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.touchpad.tutorial.ui.gesture
+
+import android.view.InputDevice
+import android.view.MotionEvent
+
+/**
+ * Allows listening to touchpadGesture and calling onDone when gesture was triggered. Can have all
+ * motion events passed to [onMotionEvent] and will filter touchpad events accordingly
+ */
+class TouchpadGestureHandler(
+ touchpadGesture: TouchpadGesture,
+ swipeDistanceThresholdPx: Int,
+ onDone: () -> Unit
+) {
+
+ private val gestureRecognition =
+ touchpadGesture.toMonitor(swipeDistanceThresholdPx, gestureDoneCallback = onDone)
+
+ fun onMotionEvent(event: MotionEvent): Boolean {
+ // events from touchpad have SOURCE_MOUSE and not SOURCE_TOUCHPAD because of legacy reasons
+ val isFromTouchpad =
+ event.isFromSource(InputDevice.SOURCE_MOUSE) &&
+ event.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER
+ val buttonClick =
+ event.actionMasked == MotionEvent.ACTION_DOWN &&
+ event.isButtonPressed(MotionEvent.BUTTON_PRIMARY)
+ return if (isFromTouchpad && !buttonClick) {
+ gestureRecognition.processTouchpadEvent(event)
+ true
+ } else {
+ false
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
index 0c5c1874db8a..088a8fd95e60 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
@@ -17,6 +17,7 @@
package com.android.systemui.touchpad.tutorial.ui.view
import android.os.Bundle
+import android.view.WindowManager
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
@@ -25,14 +26,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.lifecycle.Lifecycle.State.STARTED
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import androidx.lifecycle.viewmodel.compose.viewModel
import com.android.compose.theme.PlatformTheme
-import com.android.systemui.touchpad.tutorial.ui.GestureViewModelFactory
-import com.android.systemui.touchpad.tutorial.ui.HomeGestureTutorialViewModel
-import com.android.systemui.touchpad.tutorial.ui.Screen.BACK_GESTURE
-import com.android.systemui.touchpad.tutorial.ui.Screen.HOME_GESTURE
-import com.android.systemui.touchpad.tutorial.ui.Screen.TUTORIAL_SELECTION
-import com.android.systemui.touchpad.tutorial.ui.TouchpadTutorialViewModel
+import com.android.systemui.touchpad.tutorial.ui.composable.BackGestureTutorialScreen
+import com.android.systemui.touchpad.tutorial.ui.composable.TutorialSelectionScreen
+import com.android.systemui.touchpad.tutorial.ui.viewmodel.Screen.BACK_GESTURE
+import com.android.systemui.touchpad.tutorial.ui.viewmodel.Screen.HOME_GESTURE
+import com.android.systemui.touchpad.tutorial.ui.viewmodel.Screen.TUTORIAL_SELECTION
+import com.android.systemui.touchpad.tutorial.ui.viewmodel.TouchpadTutorialViewModel
import javax.inject.Inject
class TouchpadTutorialActivity
@@ -47,6 +47,8 @@ constructor(
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent { PlatformTheme { TouchpadTutorialScreen(vm) { finish() } } }
+ // required to handle 3+ fingers on touchpad
+ window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY)
}
override fun onResume() {
@@ -74,13 +76,8 @@ fun TouchpadTutorialScreen(vm: TouchpadTutorialViewModel, closeTutorial: () -> U
BACK_GESTURE ->
BackGestureTutorialScreen(
onDoneButtonClicked = { vm.goTo(TUTORIAL_SELECTION) },
- onBack = { vm.goTo(TUTORIAL_SELECTION) }
+ onBack = { vm.goTo(TUTORIAL_SELECTION) },
)
- HOME_GESTURE -> HomeGestureTutorialScreen()
+ HOME_GESTURE -> {}
}
}
-
-@Composable
-fun HomeGestureTutorialScreen() {
- val vm = viewModel<HomeGestureTutorialViewModel>(factory = GestureViewModelFactory())
-}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialViewModel.kt
index 9e6553a4b234..11984af0281a 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialViewModel.kt
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.systemui.touchpad.tutorial.ui
+package com.android.systemui.touchpad.tutorial.ui.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.android.systemui.touchpad.tutorial.domain.interactor.TouchpadGesturesInteractor
+import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
-import javax.inject.Inject
class TouchpadTutorialViewModel(private val gesturesInteractor: TouchpadGesturesInteractor) :
ViewModel() {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
index ec6f86297bae..fb4023575f37 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
@@ -14,18 +14,18 @@
package com.android.systemui.tuner;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_CODE_END;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_CODE_START;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_IMAGE_DELIM;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.MENU_IME_ROTATE;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAVSPACE;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_LEFT;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_RIGHT;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_VIEWS;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractButton;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractImage;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractKeycode;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY_CODE_END;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY_CODE_START;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY_IMAGE_DELIM;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.MENU_IME_ROTATE;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAVSPACE;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAV_BAR_LEFT;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAV_BAR_RIGHT;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAV_BAR_VIEWS;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.extractButton;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.extractImage;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.extractKeycode;
import android.annotation.Nullable;
import android.app.AlertDialog;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
deleted file mode 100644
index d54c07c87b40..000000000000
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.tuner;
-
-import android.util.DisplayMetrics;
-import android.view.View;
-import android.view.WindowManager;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.tuner.TunerService.Tunable;
-
-import javax.inject.Inject;
-
-/**
- * Version of Space that can be resized by a tunable setting.
- */
-public class TunablePadding implements Tunable {
-
- public static final int FLAG_START = 1;
- public static final int FLAG_END = 2;
- public static final int FLAG_TOP = 4;
- public static final int FLAG_BOTTOM = 8;
-
- private final int mFlags;
- private final View mView;
- private final int mDefaultSize;
- private final float mDensity;
- private final TunerService mTunerService;
-
- private TunablePadding(String key, int def, int flags, View view, TunerService tunerService) {
- mDefaultSize = def;
- mFlags = flags;
- mView = view;
- DisplayMetrics metrics = new DisplayMetrics();
- view.getContext().getSystemService(WindowManager.class)
- .getDefaultDisplay().getMetrics(metrics);
- mDensity = metrics.density;
- mTunerService = tunerService;
- mTunerService.addTunable(this, key);
- }
-
- @Override
- public void onTuningChanged(String key, String newValue) {
- int dimen = mDefaultSize;
- if (newValue != null) {
- try {
- dimen = (int) (Integer.parseInt(newValue) * mDensity);
- } catch (NumberFormatException ex) {}
- }
- int left = mView.isLayoutRtl() ? FLAG_END : FLAG_START;
- int right = mView.isLayoutRtl() ? FLAG_START : FLAG_END;
- mView.setPadding(getPadding(dimen, left), getPadding(dimen, FLAG_TOP),
- getPadding(dimen, right), getPadding(dimen, FLAG_BOTTOM));
- }
-
- private int getPadding(int dimen, int flag) {
- return ((mFlags & flag) != 0) ? dimen : 0;
- }
-
- public void destroy() {
- mTunerService.removeTunable(this);
- }
-
- /**
- * Exists for easy injecting in tests.
- */
- @SysUISingleton
- public static class TunablePaddingService {
-
- private final TunerService mTunerService;
-
- /**
- */
- @Inject
- public TunablePaddingService(TunerService tunerService) {
- mTunerService = tunerService;
- }
-
- public TunablePadding add(View view, String key, int defaultSize, int flags) {
- if (view == null) {
- throw new IllegalArgumentException();
- }
- return new TunablePadding(key, defaultSize, flags, view, mTunerService);
- }
- }
-
- public static TunablePadding addTunablePadding(View view, String key, int defaultSize,
- int flags) {
- return Dependency.get(TunablePaddingService.class).add(view, key, defaultSize, flags);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt b/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
index ec7aabb58b49..f2132248e4f7 100644
--- a/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
@@ -20,6 +20,7 @@ import android.graphics.Rect
import android.util.IndentingPrintWriter
import android.view.View
import android.view.ViewGroup
+import dagger.Lazy
import java.io.PrintWriter
/** [Sequence] that yields all of the direct children of this [ViewGroup] */
@@ -56,3 +57,8 @@ val View.boundsOnScreen: Rect
getBoundsOnScreen(bounds)
return bounds
}
+
+/** Extension method to convert [dagger.Lazy] to [kotlin.Lazy] for object of any class [T]. */
+fun <T> Lazy<T>.toKotlinLazy(): kotlin.Lazy<T> {
+ return lazy { this.get() }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java b/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java
index 9c8a481fcb76..501fee629e10 100644
--- a/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java
+++ b/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java
@@ -20,15 +20,15 @@ import com.android.systemui.util.RingerModeTracker;
import com.android.systemui.util.RingerModeTrackerImpl;
import com.android.systemui.util.animation.data.repository.AnimationStatusRepository;
import com.android.systemui.util.animation.data.repository.AnimationStatusRepositoryImpl;
+import com.android.systemui.util.icons.AppCategoryIconProvider;
+import com.android.systemui.util.icons.AppCategoryIconProviderImpl;
import com.android.systemui.util.wrapper.UtilWrapperModule;
import dagger.Binds;
import dagger.Module;
/** Dagger Module for code in the util package. */
-@Module(includes = {
- UtilWrapperModule.class
- })
+@Module(includes = {UtilWrapperModule.class})
public interface UtilModule {
/** */
@Binds
@@ -37,4 +37,8 @@ public interface UtilModule {
@Binds
AnimationStatusRepository provideAnimationStatus(
AnimationStatusRepositoryImpl ringerModeTrackerImpl);
+
+ /** */
+ @Binds
+ AppCategoryIconProvider appCategoryIconProvider(AppCategoryIconProviderImpl impl);
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/icons/AppCategoryIconProvider.kt b/packages/SystemUI/src/com/android/systemui/util/icons/AppCategoryIconProvider.kt
new file mode 100644
index 000000000000..6e3f8f16b623
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/icons/AppCategoryIconProvider.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.util.icons
+
+import android.content.Intent
+import android.content.pm.PackageInfo
+import android.content.pm.PackageManager
+import android.graphics.drawable.Icon
+import android.os.RemoteException
+import android.util.Log
+import com.android.systemui.assist.AssistManager
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.shared.system.PackageManagerWrapper
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.withContext
+
+interface AppCategoryIconProvider {
+ /** Returns the [Icon] of the default assistant app, if it exists. */
+ suspend fun assistantAppIcon(): Icon?
+
+ /**
+ * Returns the [Icon] of the default app of [category], if it exists. Category can be for
+ * example [Intent.CATEGORY_APP_EMAIL] or [Intent.CATEGORY_APP_CALCULATOR].
+ */
+ suspend fun categoryAppIcon(category: String): Icon?
+}
+
+class AppCategoryIconProviderImpl
+@Inject
+constructor(
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
+ private val assistManager: AssistManager,
+ private val packageManager: PackageManager,
+ private val packageManagerWrapper: PackageManagerWrapper,
+) : AppCategoryIconProvider {
+
+ override suspend fun assistantAppIcon(): Icon? {
+ val assistInfo = assistManager.assistInfo ?: return null
+ return getPackageIcon(assistInfo.packageName)
+ }
+
+ override suspend fun categoryAppIcon(category: String): Icon? {
+ val intent = Intent(Intent.ACTION_MAIN).apply { addCategory(category) }
+ val packageInfo = getPackageInfo(intent) ?: return null
+ return getPackageIcon(packageInfo.packageName)
+ }
+
+ private suspend fun getPackageInfo(intent: Intent): PackageInfo? =
+ withContext(backgroundDispatcher) {
+ val packageName =
+ packageManagerWrapper
+ .resolveActivity(/* intent= */ intent, /* flags= */ 0)
+ ?.activityInfo
+ ?.packageName ?: return@withContext null
+ return@withContext getPackageInfo(packageName)
+ }
+
+ private suspend fun getPackageIcon(packageName: String): Icon? {
+ val appInfo = getPackageInfo(packageName)?.applicationInfo ?: return null
+ return if (appInfo.icon != 0) {
+ Icon.createWithResource(appInfo.packageName, appInfo.icon)
+ } else {
+ null
+ }
+ }
+
+ private suspend fun getPackageInfo(packageName: String): PackageInfo? =
+ withContext(backgroundDispatcher) {
+ try {
+ return@withContext packageManager.getPackageInfo(packageName, /* flags= */ 0)
+ } catch (e: RemoteException) {
+ Log.e(TAG, "Failed to retrieve package info for $packageName")
+ return@withContext null
+ }
+ }
+
+ companion object {
+ private const val TAG = "DefaultAppsIconProvider"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
index 8c46f9af04e5..28ac2c0e8283 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
@@ -106,3 +106,13 @@ fun <A, B, C, R> combineFlows(
): Flow<R> {
return combine(flow1, flow2, flow3, trifunction)
}
+
+fun <T1, T2, T3, T4, R> combineFlows(
+ flow: Flow<T1>,
+ flow2: Flow<T2>,
+ flow3: Flow<T3>,
+ flow4: Flow<T4>,
+ transform: (T1, T2, T3, T4) -> R
+): Flow<R> {
+ return combine(flow, flow2, flow3, flow4, transform)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/ReduceBrightColorsControllerExt.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/ReduceBrightColorsControllerExt.kt
index ee00e8b04ef1..e6e2a0767012 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/ReduceBrightColorsControllerExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/ReduceBrightColorsControllerExt.kt
@@ -35,3 +35,17 @@ fun ReduceBrightColorsController.isEnabled(): Flow<Boolean> {
}
.onStart { emit(isReduceBrightColorsActivated) }
}
+
+fun ReduceBrightColorsController.isAvailable(): Flow<Boolean> {
+ return conflatedCallbackFlow {
+ val callback =
+ object : ReduceBrightColorsController.Listener {
+ override fun onFeatureEnabledChanged(enabled: Boolean) {
+ trySend(enabled)
+ }
+ }
+ addCallback(callback)
+ awaitClose { removeCallback(callback) }
+ }
+ .onStart { emit(isReduceBrightColorsFeatureAvailable) }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/SettingsSingleThreadBackground.java b/packages/SystemUI/src/com/android/systemui/util/kotlin/SettingsSingleThreadBackground.java
new file mode 100644
index 000000000000..e13981dfe5c7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/SettingsSingleThreadBackground.java
@@ -0,0 +1,34 @@
+/*
+ * 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.util.kotlin;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/**
+ * This is a background executor/dispatcher which guarantees that **within that instance**,
+ * operations will execute in the same order as they were dispatched.
+ * This is useful for background operations like register/unregister where ordering is important.
+ */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface SettingsSingleThreadBackground { }
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
index b836016eb2ef..a03221e03467 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
@@ -16,6 +16,7 @@
package com.android.systemui.util.kotlin
+import android.os.Handler
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
@@ -23,15 +24,16 @@ import com.android.systemui.dagger.qualifiers.Tracing
import com.android.systemui.dagger.qualifiers.UiBackground
import dagger.Module
import dagger.Provides
-import java.util.concurrent.Executor
-import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.android.asCoroutineDispatcher
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.newFixedThreadPoolContext
import kotlinx.coroutines.plus
+import java.util.concurrent.Executor
+import kotlin.coroutines.CoroutineContext
private const val LIMIT_BACKGROUND_DISPATCHER_THREADS = true
@@ -78,6 +80,14 @@ class SysUICoroutinesModule {
}
@Provides
+ @SysUISingleton
+ @SettingsSingleThreadBackground
+ fun settingsBgDispatcher(@Background bgHandler: Handler): CoroutineDispatcher {
+ // Handlers are guaranteed to be sequential so we use that one for now.
+ return bgHandler.asCoroutineDispatcher("SettingsBg")
+ }
+
+ @Provides
@Background
@SysUISingleton
fun bgCoroutineContext(
diff --git a/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java b/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java
index 64f8246118c8..a58a264c8348 100644
--- a/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java
@@ -27,6 +27,7 @@ import android.util.Log;
import androidx.annotation.NonNull;
+import com.android.app.tracing.TraceStateLogger;
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dump.DumpManager;
@@ -41,11 +42,11 @@ import javax.inject.Named;
/**
* The {@link PersistentConnectionManager} is responsible for maintaining a connection to a
* {@link ObservableServiceConnection}.
+ *
* @param <T> The transformed connection type handled by the service.
*/
public class PersistentConnectionManager<T> implements Dumpable {
private static final String TAG = "PersistentConnManager";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final SystemClock mSystemClock;
private final DelayableExecutor mBgExecutor;
@@ -55,6 +56,7 @@ public class PersistentConnectionManager<T> implements Dumpable {
private final Observer mObserver;
private final DumpManager mDumpManager;
private final String mDumpsysName;
+ private final TraceStateLogger mConnectionReasonLogger;
private int mReconnectAttempts = 0;
private Runnable mCurrentReconnectCancelable;
@@ -64,36 +66,52 @@ public class PersistentConnectionManager<T> implements Dumpable {
private final Runnable mConnectRunnable = new Runnable() {
@Override
public void run() {
+ mConnectionReasonLogger.log("ConnectionReasonRetry");
mCurrentReconnectCancelable = null;
mConnection.bind();
}
};
- private final Observer.Callback mObserverCallback = () -> initiateConnectionAttempt();
+ private final Observer.Callback mObserverCallback = () -> initiateConnectionAttempt(
+ "ConnectionReasonObserver");
private final ObservableServiceConnection.Callback<T> mConnectionCallback =
new ObservableServiceConnection.Callback<>() {
- private long mStartTime;
-
- @Override
- public void onConnected(ObservableServiceConnection connection, Object proxy) {
- mStartTime = mSystemClock.currentTimeMillis();
- }
-
- @Override
- public void onDisconnected(ObservableServiceConnection connection, int reason) {
- // Do not attempt to reconnect if we were manually unbound
- if (reason == ObservableServiceConnection.DISCONNECT_REASON_UNBIND) {
- return;
- }
-
- if (mSystemClock.currentTimeMillis() - mStartTime > mMinConnectionDuration) {
- initiateConnectionAttempt();
- } else {
- scheduleConnectionAttempt();
- }
- }
- };
+ private long mStartTime = -1;
+
+ @Override
+ public void onConnected(ObservableServiceConnection connection, Object proxy) {
+ mStartTime = mSystemClock.currentTimeMillis();
+ }
+
+ @Override
+ public void onDisconnected(ObservableServiceConnection connection, int reason) {
+ // Do not attempt to reconnect if we were manually unbound
+ if (reason == ObservableServiceConnection.DISCONNECT_REASON_UNBIND) {
+ return;
+ }
+
+ if (mStartTime <= 0) {
+ Log.e(TAG, "onDisconnected called with invalid connection start time: "
+ + mStartTime);
+ return;
+ }
+
+ final float connectionDuration = mSystemClock.currentTimeMillis() - mStartTime;
+ // Reset the start time.
+ mStartTime = -1;
+
+ if (connectionDuration > mMinConnectionDuration) {
+ Log.i(TAG, "immediately reconnecting since service was connected for "
+ + connectionDuration
+ + "ms which is longer than the min duration of "
+ + mMinConnectionDuration + "ms");
+ initiateConnectionAttempt("ConnectionReasonMinDurationMet");
+ } else {
+ scheduleConnectionAttempt();
+ }
+ }
+ };
@Inject
public PersistentConnectionManager(
@@ -112,6 +130,7 @@ public class PersistentConnectionManager<T> implements Dumpable {
mObserver = observer;
mDumpManager = dumpManager;
mDumpsysName = TAG + "#" + dumpsysName;
+ mConnectionReasonLogger = new TraceStateLogger(mDumpsysName);
mMaxReconnectAttempts = maxReconnectAttempts;
mBaseReconnectDelayMs = baseReconnectDelayMs;
@@ -125,7 +144,7 @@ public class PersistentConnectionManager<T> implements Dumpable {
mDumpManager.registerCriticalDumpable(mDumpsysName, this);
mConnection.addCallback(mConnectionCallback);
mObserver.addCallback(mObserverCallback);
- initiateConnectionAttempt();
+ initiateConnectionAttempt("ConnectionReasonStart");
}
/**
@@ -140,6 +159,7 @@ public class PersistentConnectionManager<T> implements Dumpable {
/**
* Add a callback to the {@link ObservableServiceConnection}.
+ *
* @param callback The callback to add.
*/
public void addConnectionCallback(ObservableServiceConnection.Callback<T> callback) {
@@ -148,6 +168,7 @@ public class PersistentConnectionManager<T> implements Dumpable {
/**
* Remove a callback from the {@link ObservableServiceConnection}.
+ *
* @param callback The callback to remove.
*/
public void removeConnectionCallback(ObservableServiceConnection.Callback<T> callback) {
@@ -163,10 +184,10 @@ public class PersistentConnectionManager<T> implements Dumpable {
mConnection.dump(pw);
}
- private void initiateConnectionAttempt() {
+ private void initiateConnectionAttempt(String reason) {
+ mConnectionReasonLogger.log(reason);
// Reset attempts
mReconnectAttempts = 0;
-
// The first attempt is always a direct invocation rather than delayed.
mConnection.bind();
}
@@ -179,20 +200,15 @@ public class PersistentConnectionManager<T> implements Dumpable {
}
if (mReconnectAttempts >= mMaxReconnectAttempts) {
- if (DEBUG) {
- Log.d(TAG, "exceeded max connection attempts.");
- }
+ Log.d(TAG, "exceeded max connection attempts.");
return;
}
final long reconnectDelayMs =
(long) Math.scalb(mBaseReconnectDelayMs, mReconnectAttempts);
- if (DEBUG) {
- Log.d(TAG,
- "scheduling connection attempt in " + reconnectDelayMs + "milliseconds");
- }
-
+ Log.d(TAG,
+ "scheduling connection attempt in " + reconnectDelayMs + "milliseconds");
mCurrentReconnectCancelable = mBgExecutor.executeDelayed(mConnectRunnable,
reconnectDelayMs);
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
index 42389f0ae627..816f55db65a0 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
@@ -23,16 +23,23 @@ import android.content.ContentResolver;
import android.net.Uri;
import android.provider.Settings;
+import com.android.systemui.util.kotlin.SettingsSingleThreadBackground;
+
+import kotlinx.coroutines.CoroutineDispatcher;
+
import javax.inject.Inject;
// use UserHandle.USER_SYSTEM everywhere
@SuppressLint("StaticSettingsProvider")
class GlobalSettingsImpl implements GlobalSettings {
private final ContentResolver mContentResolver;
+ private final CoroutineDispatcher mBgDispatcher;
@Inject
- GlobalSettingsImpl(ContentResolver contentResolver) {
+ GlobalSettingsImpl(ContentResolver contentResolver,
+ @SettingsSingleThreadBackground CoroutineDispatcher bgDispatcher) {
mContentResolver = contentResolver;
+ mBgDispatcher = bgDispatcher;
}
@Override
@@ -46,6 +53,11 @@ class GlobalSettingsImpl implements GlobalSettings {
}
@Override
+ public CoroutineDispatcher getBackgroundDispatcher() {
+ return mBgDispatcher;
+ }
+
+ @Override
public String getString(String name) {
return Settings.Global.getString(mContentResolver, name);
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
index 6532ce8ddf7d..9c98f43e2501 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
@@ -23,17 +23,23 @@ import android.provider.Settings;
import androidx.annotation.NonNull;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.util.kotlin.SettingsSingleThreadBackground;
import javax.inject.Inject;
+import kotlinx.coroutines.CoroutineDispatcher;
+
class SecureSettingsImpl implements SecureSettings {
private final ContentResolver mContentResolver;
private final UserTracker mUserTracker;
+ private final CoroutineDispatcher mBgDispatcher;
@Inject
- SecureSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
+ SecureSettingsImpl(ContentResolver contentResolver, UserTracker userTracker,
+ @SettingsSingleThreadBackground CoroutineDispatcher bgDispatcher) {
mContentResolver = contentResolver;
mUserTracker = userTracker;
+ mBgDispatcher = bgDispatcher;
}
@Override
@@ -52,6 +58,11 @@ class SecureSettingsImpl implements SecureSettings {
}
@Override
+ public CoroutineDispatcher getBackgroundDispatcher() {
+ return mBgDispatcher;
+ }
+
+ @Override
public String getStringForUser(String name, int userHandle) {
return Settings.Secure.getStringForUser(mContentResolver, name,
getRealUserHandle(userHandle));
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
index d92127cf97cb..b5934ec680d3 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
@@ -19,7 +19,13 @@ import android.content.ContentResolver
import android.database.ContentObserver
import android.net.Uri
import android.provider.Settings.SettingNotFoundException
+import androidx.annotation.AnyThread
+import androidx.annotation.WorkerThread
import com.android.app.tracing.TraceUtils.trace
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
/**
* Used to interact with mainly with Settings.Global, but can also be used for Settings.System and
@@ -40,39 +46,194 @@ interface SettingsProxy {
fun getContentResolver(): ContentResolver
/**
+ * Returns the background [CoroutineDispatcher] that the async APIs will use for a specific
+ * implementation.
+ */
+ val backgroundDispatcher: CoroutineDispatcher
+
+ /**
* Construct the content URI for a particular name/value pair, useful for monitoring changes
* with a ContentObserver.
*
* @param name to look up in the table
* @return the corresponding content URI, or null if not present
*/
- fun getUriFor(name: String): Uri
+ @AnyThread fun getUriFor(name: String): Uri
/**
- * Convenience wrapper around [ContentResolver.registerContentObserver].'
- *
+ * Registers listener for a given content observer <b>while blocking the current thread</b>.
* Implicitly calls [getUriFor] on the passed in name.
+ *
+ * This should not be called from the main thread, use [registerContentObserver] or
+ * [registerContentObserverAsync] instead.
*/
+ @WorkerThread
fun registerContentObserverSync(name: String, settingsObserver: ContentObserver) {
registerContentObserverSync(getUriFor(name), settingsObserver)
}
- /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+ * registration happens on a worker thread. Caller may wrap the API in an async block if they
+ * wish to synchronize execution.
+ */
+ suspend fun registerContentObserver(name: String, settingsObserver: ContentObserver) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverSync(getUriFor(name), settingsObserver)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage.
+ */
+ @AnyThread
+ fun registerContentObserverAsync(name: String, settingsObserver: ContentObserver) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(getUriFor(name), settingsObserver)
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage. After registration is
+ * complete, the callback block is called on the <b>background thread</b> to allow for update of
+ * value.
+ */
+ @AnyThread
+ fun registerContentObserverAsync(
+ name: String,
+ settingsObserver: ContentObserver,
+ @WorkerThread registered: Runnable
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(getUriFor(name), settingsObserver)
+ registered.run()
+ }
+
+ /**
+ * Registers listener for a given content observer <b>while blocking the current thread</b>.
+ *
+ * This should not be called from the main thread, use [registerContentObserver] or
+ * [registerContentObserverAsync] instead.
+ */
+ @WorkerThread
fun registerContentObserverSync(uri: Uri, settingsObserver: ContentObserver) =
registerContentObserverSync(uri, false, settingsObserver)
/**
* Convenience wrapper around [ContentResolver.registerContentObserver].'
*
+ * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+ * registration happens on a worker thread. Caller may wrap the API in an async block if they
+ * wish to synchronize execution.
+ */
+ suspend fun registerContentObserver(uri: Uri, settingsObserver: ContentObserver) {
+ withContext(backgroundDispatcher) { registerContentObserverSync(uri, settingsObserver) }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage.
+ */
+ @AnyThread
+ fun registerContentObserverAsync(uri: Uri, settingsObserver: ContentObserver) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(uri, settingsObserver)
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage. After registration is
+ * complete, the callback block is called on the <b>background thread</b> to allow for update of
+ * value.
+ */
+ @AnyThread
+ fun registerContentObserverAsync(
+ uri: Uri,
+ settingsObserver: ContentObserver,
+ @WorkerThread registered: Runnable
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(uri, settingsObserver)
+ registered.run()
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
* Implicitly calls [getUriFor] on the passed in name.
*/
+ @WorkerThread
fun registerContentObserverSync(
name: String,
notifyForDescendants: Boolean,
settingsObserver: ContentObserver
) = registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
- /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+ * registration happens on a worker thread. Caller may wrap the API in an async block if they
+ * wish to synchronize execution.
+ */
+ suspend fun registerContentObserver(
+ name: String,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage.
+ */
+ @AnyThread
+ fun registerContentObserverAsync(
+ name: String,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage. After registration is
+ * complete, the callback block is called on the <b>background thread</b> to allow for update of
+ * value.
+ */
+ @AnyThread
+ fun registerContentObserverAsync(
+ name: String,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver,
+ @WorkerThread registered: Runnable
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
+ registered.run()
+ }
+
+ /**
+ * Registers listener for a given content observer <b>while blocking the current thread</b>.
+ *
+ * This should not be called from the main thread, use [registerContentObserver] or
+ * [registerContentObserverAsync] instead.
+ */
+ @WorkerThread
fun registerContentObserverSync(
uri: Uri,
notifyForDescendants: Boolean,
@@ -84,7 +245,64 @@ interface SettingsProxy {
}
}
- /** See [ContentResolver.unregisterContentObserver]. */
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+ * registration happens on a worker thread. Caller may wrap the API in an async block if they
+ * wish to synchronize execution.
+ */
+ suspend fun registerContentObserver(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverSync(uri, notifyForDescendants, settingsObserver)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage.
+ */
+ @AnyThread
+ fun registerContentObserverAsync(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(uri, notifyForDescendants, settingsObserver)
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage. After registration is
+ * complete, the callback block is called on the <b>background thread</b> to allow for update of
+ * value.
+ */
+ @AnyThread
+ fun registerContentObserverAsync(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver,
+ @WorkerThread registered: Runnable
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(uri, notifyForDescendants, settingsObserver)
+ registered.run()
+ }
+
+ /**
+ * Unregisters the given content observer <b>while blocking the current thread</b>.
+ *
+ * This should not be called from the main thread, use [unregisterContentObserver] or
+ * [unregisterContentObserverAsync] instead.
+ */
+ @WorkerThread
fun unregisterContentObserverSync(settingsObserver: ContentObserver) {
trace({ "SP#unregisterObserver" }) {
getContentResolver().unregisterContentObserver(settingsObserver)
@@ -92,6 +310,27 @@ interface SettingsProxy {
}
/**
+ * Convenience wrapper around [ContentResolver.unregisterContentObserver].'
+ *
+ * API corresponding to [unregisterContentObserver] for Java usage to ensure that
+ * [ContentObserver] un-registration happens on a worker thread. Caller may wrap the API in an
+ * async block if they wish to synchronize execution.
+ */
+ suspend fun unregisterContentObserver(settingsObserver: ContentObserver) {
+ withContext(backgroundDispatcher) { unregisterContentObserverSync(settingsObserver) }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.unregisterContentObserver].'
+ *
+ * API corresponding to [unregisterContentObserver] for Java usage to ensure that
+ * [ContentObserver] registration happens on a worker thread.
+ */
+ @AnyThread
+ fun unregisterContentObserverAsync(settingsObserver: ContentObserver) =
+ CoroutineScope(backgroundDispatcher).launch { unregisterContentObserver(settingsObserver) }
+
+ /**
* Look up a name in the database.
*
* @param name to look up in the table
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
index 658b2992bfad..406d95bd8fd1 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
@@ -23,17 +23,23 @@ import android.provider.Settings;
import androidx.annotation.NonNull;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.util.kotlin.SettingsSingleThreadBackground;
import javax.inject.Inject;
+import kotlinx.coroutines.CoroutineDispatcher;
+
class SystemSettingsImpl implements SystemSettings {
private final ContentResolver mContentResolver;
private final UserTracker mUserTracker;
+ private final CoroutineDispatcher mBgCoroutineDispatcher;
@Inject
- SystemSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
+ SystemSettingsImpl(ContentResolver contentResolver, UserTracker userTracker,
+ @SettingsSingleThreadBackground CoroutineDispatcher bgDispatcher) {
mContentResolver = contentResolver;
mUserTracker = userTracker;
+ mBgCoroutineDispatcher = bgDispatcher;
}
@Override
@@ -52,6 +58,11 @@ class SystemSettingsImpl implements SystemSettings {
}
@Override
+ public CoroutineDispatcher getBackgroundDispatcher() {
+ return mBgCoroutineDispatcher;
+ }
+
+ @Override
public String getStringForUser(String name, int userHandle) {
return Settings.System.getStringForUser(mContentResolver, name,
getRealUserHandle(userHandle));
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt b/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
index ed65f1ae1667..848a6e691082 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
@@ -16,6 +16,8 @@
package com.android.systemui.util.settings
import android.annotation.UserIdInt
+import android.annotation.WorkerThread
+import android.content.ContentResolver
import android.database.ContentObserver
import android.net.Uri
import android.os.UserHandle
@@ -26,6 +28,9 @@ import com.android.systemui.util.settings.SettingsProxy.Companion.parseFloat
import com.android.systemui.util.settings.SettingsProxy.Companion.parseFloatOrThrow
import com.android.systemui.util.settings.SettingsProxy.Companion.parseLongOrThrow
import com.android.systemui.util.settings.SettingsProxy.Companion.parseLongOrUseDefault
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
/**
* Used to interact with per-user Settings.Secure and Settings.System settings (but not
@@ -62,11 +67,24 @@ interface UserSettingsProxy : SettingsProxy {
} else userTracker.userId
}
+ @WorkerThread
override fun registerContentObserverSync(uri: Uri, settingsObserver: ContentObserver) {
registerContentObserverForUserSync(uri, settingsObserver, userId)
}
+ override suspend fun registerContentObserver(uri: Uri, settingsObserver: ContentObserver) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(uri, settingsObserver, userId)
+ }
+ }
+
+ override fun registerContentObserverAsync(uri: Uri, settingsObserver: ContentObserver) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(uri, settingsObserver, userId)
+ }
+
/** Convenience wrapper around [ContentResolver.registerContentObserver].' */
+ @WorkerThread
override fun registerContentObserverSync(
uri: Uri,
notifyForDescendants: Boolean,
@@ -75,11 +93,36 @@ interface UserSettingsProxy : SettingsProxy {
registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
}
+ override suspend fun registerContentObserver(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserverForUser] for Java usage.
+ */
+ override fun registerContentObserverAsync(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
+ }
+
/**
* Convenience wrapper around [ContentResolver.registerContentObserver]
*
* Implicitly calls [getUriFor] on the passed in name.
*/
+ @WorkerThread
fun registerContentObserverForUserSync(
name: String,
settingsObserver: ContentObserver,
@@ -88,7 +131,39 @@ interface UserSettingsProxy : SettingsProxy {
registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
}
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserverForUser] to ensure that
+ * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+ * async block if they wish to synchronize execution.
+ */
+ suspend fun registerContentObserverForUser(
+ name: String,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(name, settingsObserver, userHandle)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserverForUser] for Java usage.
+ */
+ fun registerContentObserverForUserAsync(
+ name: String,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
+ }
+
/** Convenience wrapper around [ContentResolver.registerContentObserver] */
+ @WorkerThread
fun registerContentObserverForUserSync(
uri: Uri,
settingsObserver: ContentObserver,
@@ -98,10 +173,60 @@ interface UserSettingsProxy : SettingsProxy {
}
/**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserverForUser] to ensure that
+ * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+ * async block if they wish to synchronize execution.
+ */
+ suspend fun registerContentObserverForUser(
+ uri: Uri,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserverForUser] for Java usage.
+ */
+ fun registerContentObserverForUserAsync(
+ uri: Uri,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserverForUser] for Java usage. After registration is
+ * complete, the callback block is called on the <b>background thread</b> to allow for update of
+ * value.
+ */
+ fun registerContentObserverForUserAsync(
+ uri: Uri,
+ settingsObserver: ContentObserver,
+ userHandle: Int,
+ @WorkerThread registered: Runnable
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+ registered.run()
+ }
+
+ /**
* Convenience wrapper around [ContentResolver.registerContentObserver]
*
* Implicitly calls [getUriFor] on the passed in name.
*/
+ @WorkerThread
fun registerContentObserverForUserSync(
name: String,
notifyForDescendants: Boolean,
@@ -116,7 +241,52 @@ interface UserSettingsProxy : SettingsProxy {
)
}
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserverForUser] to ensure that
+ * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+ * async block if they wish to synchronize execution.
+ */
+ suspend fun registerContentObserverForUser(
+ name: String,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(
+ name,
+ notifyForDescendants,
+ settingsObserver,
+ userHandle
+ )
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserverForUser] for Java usage.
+ */
+ fun registerContentObserverForUserAsync(
+ name: String,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) {
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(
+ getUriFor(name),
+ notifyForDescendants,
+ settingsObserver,
+ userHandle
+ )
+ }
+ }
+
/** Convenience wrapper around [ContentResolver.registerContentObserver] */
+ @WorkerThread
fun registerContentObserverForUserSync(
uri: Uri,
notifyForDescendants: Boolean,
@@ -136,6 +306,49 @@ interface UserSettingsProxy : SettingsProxy {
}
/**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserverForUser] to ensure that
+ * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+ * async block if they wish to synchronize execution.
+ */
+ suspend fun registerContentObserverForUser(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(
+ uri,
+ notifyForDescendants,
+ settingsObserver,
+ getRealUserHandle(userHandle)
+ )
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserverForUser] for Java usage.
+ */
+ fun registerContentObserverForUserAsync(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(
+ uri,
+ notifyForDescendants,
+ settingsObserver,
+ userHandle
+ )
+ }
+
+ /**
* Look up a name in the database.
*
* @param name to look up in the table
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
index bd698ab8ad5c..bb230e6b0305 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
@@ -30,21 +30,31 @@ import android.content.IntentFilter;
import android.media.AudioManager;
import android.provider.Settings;
import android.util.Log;
+import android.util.Pair;
import android.view.KeyEvent;
import android.view.WindowManager;
+import androidx.annotation.VisibleForTesting;
+
import com.android.internal.annotations.GuardedBy;
import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.Flags;
+import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.plugins.VolumeDialog;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.util.NotificationChannels;
import com.android.systemui.util.concurrency.DelayableExecutor;
+import com.google.common.collect.ImmutableList;
+
import dagger.assisted.Assisted;
import dagger.assisted.AssistedFactory;
import dagger.assisted.AssistedInject;
+import java.util.Optional;
+
/**
* A class that implements the three Computed Sound Dose-related warnings defined in
* {@link AudioManager}:
@@ -75,6 +85,9 @@ public class CsdWarningDialog extends SystemUIDialog
private static final int KEY_CONFIRM_ALLOWED_AFTER_MS = 1000; // milliseconds
// time after which action is taken when the user hasn't ack'd or dismissed the dialog
public static final int NO_ACTION_TIMEOUT_MS = 5000;
+ // Notification dismiss intent
+ private static final String DISMISS_CSD_NOTIFICATION =
+ "com.android.systemui.volume.DISMISS_CSD_NOTIFICATION";
private final Context mContext;
private final AudioManager mAudioManager;
@@ -95,21 +108,32 @@ public class CsdWarningDialog extends SystemUIDialog
private long mShowTime;
+ @VisibleForTesting public int mCachedMediaStreamVolume;
+ private Optional<ImmutableList<Pair<String, Intent>>> mActionIntents;
+ private final BroadcastDispatcher mBroadcastDispatcher;
+
/**
* To inject dependencies and allow for easier testing
*/
@AssistedFactory
public interface Factory {
- /**
- * Create a dialog object
- */
- CsdWarningDialog create(int csdWarning, Runnable onCleanup);
+ /** Create a dialog object */
+ CsdWarningDialog create(
+ int csdWarning,
+ Runnable onCleanup,
+ Optional<ImmutableList<Pair<String, Intent>>> actionIntents);
}
@AssistedInject
- public CsdWarningDialog(@Assisted @AudioManager.CsdWarning int csdWarning, Context context,
- AudioManager audioManager, NotificationManager notificationManager,
- @Background DelayableExecutor delayableExecutor, @Assisted Runnable onCleanup) {
+ public CsdWarningDialog(
+ @Assisted @AudioManager.CsdWarning int csdWarning,
+ Context context,
+ AudioManager audioManager,
+ NotificationManager notificationManager,
+ @Background DelayableExecutor delayableExecutor,
+ @Assisted Runnable onCleanup,
+ @Assisted Optional<ImmutableList<Pair<String, Intent>>> actionIntents,
+ BroadcastDispatcher broadcastDispatcher) {
super(context);
mCsdWarning = csdWarning;
mContext = context;
@@ -118,7 +142,8 @@ public class CsdWarningDialog extends SystemUIDialog
mOnCleanup = onCleanup;
mDelayableExecutor = delayableExecutor;
-
+ mActionIntents = actionIntents;
+ mBroadcastDispatcher = broadcastDispatcher;
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
setShowForAllUsers(true);
setMessage(mContext.getString(getStringForWarning(csdWarning)));
@@ -133,14 +158,17 @@ public class CsdWarningDialog extends SystemUIDialog
Context.RECEIVER_EXPORTED_UNAUDITED);
if (csdWarning == AudioManager.CSD_WARNING_DOSE_REACHED_1X) {
- mNoUserActionRunnable = () -> {
- if (mCsdWarning == AudioManager.CSD_WARNING_DOSE_REACHED_1X) {
- // unlike on the 5x dose repeat, level is only reduced to RS1 when the warning
- // is not acknowledged quickly enough
- mAudioManager.lowerVolumeToRs1();
- sendNotification(/*for5XCsd=*/false);
- }
- };
+ mNoUserActionRunnable =
+ () -> {
+ if (mCsdWarning == AudioManager.CSD_WARNING_DOSE_REACHED_1X) {
+ // unlike on the 5x dose repeat, level is only reduced to RS1 when the
+ // warning is not acknowledged quickly enough
+ mCachedMediaStreamVolume =
+ mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+ mAudioManager.lowerVolumeToRs1();
+ sendNotification(/* for5XCsd= */ false);
+ }
+ };
} else {
mNoUserActionRunnable = null;
}
@@ -242,6 +270,38 @@ public class CsdWarningDialog extends SystemUIDialog
}
};
+ @VisibleForTesting
+ public final BroadcastReceiver mReceiverUndo =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Flags.sounddoseCustomization()
+ && VolumeDialog.ACTION_VOLUME_UNDO.equals(intent.getAction())) {
+ if (D.BUG) Log.d(TAG, "Received ACTION_VOLUME_UNDO");
+ mAudioManager.setStreamVolume(
+ AudioManager.STREAM_MUSIC,
+ mCachedMediaStreamVolume,
+ AudioManager.FLAG_SHOW_UI);
+ mNotificationManager.cancel(
+ SystemMessageProto.SystemMessage.NOTE_CSD_LOWER_AUDIO);
+ destroy();
+ }
+ }
+ };
+
+ @VisibleForTesting
+ public final BroadcastReceiver mReceiverDismissNotification =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Flags.sounddoseCustomization()
+ && DISMISS_CSD_NOTIFICATION.equals(intent.getAction())) {
+ if (D.BUG) Log.d(TAG, "Received DISMISS_CSD_NOTIFICATION");
+ destroy();
+ }
+ }
+ };
+
private @StringRes int getStringForWarning(@AudioManager.CsdWarning int csdWarning) {
switch (csdWarning) {
case AudioManager.CSD_WARNING_DOSE_REACHED_1X:
@@ -259,7 +319,7 @@ public class CsdWarningDialog extends SystemUIDialog
Log.w(TAG, "Notification dose repeat 5x is not shown for " + mCsdWarning);
return;
}
-
+ mCachedMediaStreamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
mAudioManager.lowerVolumeToRs1();
sendNotification(/*for5XCsd=*/true);
}
@@ -288,7 +348,62 @@ public class CsdWarningDialog extends SystemUIDialog
.setAutoCancel(true)
.setCategory(Notification.CATEGORY_SYSTEM);
+ if (Flags.sounddoseCustomization()
+ && mActionIntents.isPresent()
+ && !mActionIntents.get().isEmpty()) {
+ ImmutableList<Pair<String, Intent>> actionIntentsList = mActionIntents.get();
+ for (Pair<String, Intent> intentPair : actionIntentsList) {
+ if (intentPair != null && intentPair.first != null && intentPair.second != null) {
+ PendingIntent pendingActionIntent =
+ PendingIntent.getBroadcast(mContext, 0, intentPair.second,
+ FLAG_IMMUTABLE);
+ builder.addAction(0, intentPair.first, pendingActionIntent);
+ // Register receiver to undo volume only when
+ // notification conaining the undo action would be sent.
+ if (intentPair.first == mContext.getString(R.string.volume_undo_action)) {
+ final IntentFilter filterUndo = new IntentFilter(
+ VolumeDialog.ACTION_VOLUME_UNDO);
+ mBroadcastDispatcher.registerReceiver(mReceiverUndo,
+ filterUndo,
+ /* executor = default */ null,
+ /* user = default */ null,
+ Context.RECEIVER_NOT_EXPORTED,
+ /* permission = default */ null);
+
+ // Register receiver to learn if notification has been dismissed.
+ // This is required to unregister receivers to prevent leak.
+ Intent dismissIntent = new Intent(DISMISS_CSD_NOTIFICATION)
+ .setPackage(mContext.getPackageName());
+ PendingIntent pendingDismissIntent = PendingIntent.getBroadcast(mContext,
+ 0, dismissIntent, FLAG_IMMUTABLE);
+ mBroadcastDispatcher.registerReceiver(mReceiverDismissNotification,
+ new IntentFilter(DISMISS_CSD_NOTIFICATION),
+ /* executor = default */ null,
+ /* user = default */ null,
+ Context.RECEIVER_NOT_EXPORTED,
+ /* permission = default */ null);
+ builder.setDeleteIntent(pendingDismissIntent);
+ }
+ }
+ }
+ }
+
mNotificationManager.notify(SystemMessageProto.SystemMessage.NOTE_CSD_LOWER_AUDIO,
builder.build());
}
+
+ /**
+ * Unregister the Undo action receiver when the notification is dismissed.
+ * Unregister cannot happen when CsdWarning dialog is dismissed
+ * as the notification lifecycle would be longer.
+ */
+ @VisibleForTesting
+ public void destroy() {
+ if (Flags.sounddoseCustomization()
+ && mActionIntents.isPresent()
+ && !mActionIntents.get().isEmpty()) {
+ mBroadcastDispatcher.unregisterReceiver(mReceiverUndo);
+ mBroadcastDispatcher.unregisterReceiver(mReceiverDismissNotification);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeControllerCollector.kt b/packages/SystemUI/src/com/android/systemui/volume/VolumeControllerCollector.kt
new file mode 100644
index 000000000000..68591910031d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeControllerCollector.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.volume
+
+import android.media.IVolumeController
+import com.android.settingslib.media.data.repository.VolumeControllerEvent
+import com.android.systemui.dagger.qualifiers.Application
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.launch
+
+/**
+ * This class is a bridge between
+ * [com.android.settingslib.volume.data.repository.AudioRepository.volumeControllerEvents] and the
+ * old code that uses [IVolumeController] interface directly.
+ */
+class VolumeControllerCollector
+@Inject
+constructor(@Application private val coroutineScope: CoroutineScope) {
+
+ /** Collects [Flow] of [VolumeControllerEvent] into [IVolumeController]. */
+ fun collectToController(
+ eventsFlow: Flow<VolumeControllerEvent>,
+ controller: IVolumeController
+ ) =
+ coroutineScope.launch {
+ eventsFlow.collect { event ->
+ when (event) {
+ is VolumeControllerEvent.VolumeChanged ->
+ controller.volumeChanged(event.streamType, event.flags)
+ VolumeControllerEvent.Dismiss -> controller.dismiss()
+ is VolumeControllerEvent.DisplayCsdWarning ->
+ controller.displayCsdWarning(event.csdWarning, event.displayDurationMs)
+ is VolumeControllerEvent.DisplaySafeVolumeWarning ->
+ controller.displaySafeVolumeWarning(event.flags)
+ is VolumeControllerEvent.MasterMuteChanged ->
+ controller.masterMuteChanged(event.flags)
+ is VolumeControllerEvent.SetA11yMode -> controller.setA11yMode(event.mode)
+ is VolumeControllerEvent.SetLayoutDirection ->
+ controller.setLayoutDirection(event.layoutDirection)
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 795d427b43bf..6b02e1ada491 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -50,6 +50,7 @@ import android.app.KeyguardManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
@@ -77,6 +78,7 @@ import android.provider.Settings;
import android.provider.Settings.Global;
import android.text.InputFilter;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseBooleanArray;
import android.view.ContextThemeWrapper;
@@ -140,11 +142,14 @@ import com.android.systemui.volume.domain.interactor.VolumePanelNavigationIntera
import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag;
import com.android.systemui.volume.ui.navigation.VolumeNavigator;
+import com.google.common.collect.ImmutableList;
+
import dagger.Lazy;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.function.Consumer;
/**
@@ -315,6 +320,9 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
private final com.android.systemui.util.time.SystemClock mSystemClock;
private final VolumePanelFlag mVolumePanelFlag;
private final VolumeDialogInteractor mInteractor;
+ // Optional actions for soundDose
+ private Optional<ImmutableList<Pair<String, Intent>>> mCsdWarningNotificationActions =
+ Optional.of(ImmutableList.of());
public VolumeDialogImpl(
Context context,
@@ -2198,6 +2206,11 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
rescheduleTimeoutH();
}
+ public void setCsdWarningNotificationActionIntents(
+ ImmutableList<Pair<String, Intent>> actionIntent) {
+ mCsdWarningNotificationActions = Optional.of(actionIntent);
+ }
+
@VisibleForTesting void showCsdWarningH(int csdWarning, int durationMs) {
synchronized (mSafetyWarningLock) {
@@ -2212,7 +2225,8 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
recheckH(null);
};
- mCsdDialog = mCsdWarningDialogFactory.create(csdWarning, cleanUp);
+ mCsdDialog = mCsdWarningDialogFactory.create(
+ csdWarning, cleanUp, mCsdWarningNotificationActions);
mCsdDialog.show();
}
recheckH(null);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
index 2e7b05a5422f..eb2f71a1cd7d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
@@ -20,7 +20,7 @@ import android.content.ContentResolver
import android.content.Context
import android.media.AudioManager
import com.android.settingslib.bluetooth.LocalBluetoothManager
-import com.android.settingslib.statusbar.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
import com.android.settingslib.volume.data.repository.AudioRepository
import com.android.settingslib.volume.data.repository.AudioRepositoryImpl
import com.android.settingslib.volume.data.repository.AudioSharingRepository
@@ -73,10 +73,19 @@ interface AudioModule {
@Provides
@SysUISingleton
fun provideAudioSharingRepository(
+ @Application context: Context,
+ contentResolver: ContentResolver,
localBluetoothManager: LocalBluetoothManager?,
+ @Application coroutineScope: CoroutineScope,
@Background coroutineContext: CoroutineContext,
): AudioSharingRepository =
- AudioSharingRepositoryImpl(localBluetoothManager, coroutineContext)
+ AudioSharingRepositoryImpl(
+ context,
+ contentResolver,
+ localBluetoothManager,
+ coroutineScope,
+ coroutineContext
+ )
@Provides
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioSharingEmptyImplModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioSharingEmptyImplModule.kt
new file mode 100644
index 000000000000..29040923a2cc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioSharingEmptyImplModule.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.volume.dagger
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.volume.domain.interactor.AudioSharingInteractor
+import com.android.systemui.volume.domain.interactor.AudioSharingInteractorEmptyImpl
+import dagger.Module
+import dagger.Provides
+
+/** Dagger module for empty audio sharing impl for unnecessary volume overlay */
+@Module
+interface AudioSharingEmptyImplModule {
+
+ companion object {
+ @Provides
+ @SysUISingleton
+ fun provideAudioSharingInteractor(): AudioSharingInteractor =
+ AudioSharingInteractorEmptyImpl()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioSharingModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioSharingModule.kt
new file mode 100644
index 000000000000..9f1e60e855e2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioSharingModule.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.volume.dagger
+
+import com.android.settingslib.volume.data.repository.AudioSharingRepository
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.volume.domain.interactor.AudioSharingInteractor
+import com.android.systemui.volume.domain.interactor.AudioSharingInteractorImpl
+import dagger.Module
+import dagger.Provides
+import kotlinx.coroutines.CoroutineScope
+
+/** Dagger module for audio sharing code in the volume package */
+@Module
+interface AudioSharingModule {
+
+ companion object {
+ @Provides
+ @SysUISingleton
+ fun provideAudioSharingInteractor(
+ @Application coroutineScope: CoroutineScope,
+ repository: AudioSharingRepository
+ ): AudioSharingInteractor = AudioSharingInteractorImpl(coroutineScope, repository)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
index 5420988b8faf..ebb9ce9909bd 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
@@ -59,6 +59,7 @@ import dagger.multibindings.IntoSet;
@Module(
includes = {
AudioModule.class,
+ AudioSharingModule.class,
AncModule.class,
CaptioningModule.class,
MediaDevicesModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractor.kt
new file mode 100644
index 000000000000..4d29788edf68
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractor.kt
@@ -0,0 +1,90 @@
+/*
+ * 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.volume.domain.interactor
+
+import android.bluetooth.BluetoothCsipSetCoordinator
+import androidx.annotation.IntRange
+import com.android.settingslib.volume.data.repository.AudioSharingRepository
+import com.android.settingslib.volume.data.repository.AudioSharingRepository.Companion.AUDIO_SHARING_VOLUME_MAX
+import com.android.settingslib.volume.data.repository.AudioSharingRepository.Companion.AUDIO_SHARING_VOLUME_MIN
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.launch
+
+interface AudioSharingInteractor {
+ /** Audio sharing secondary headset volume changes. */
+ val volume: Flow<Int?>
+
+ /** Audio sharing secondary headset min volume. */
+ val volumeMin: Int
+
+ /** Audio sharing secondary headset max volume. */
+ val volumeMax: Int
+
+ /** Set the volume of the secondary headset in audio sharing. */
+ fun setStreamVolume(
+ @IntRange(from = AUDIO_SHARING_VOLUME_MIN.toLong(), to = AUDIO_SHARING_VOLUME_MAX.toLong())
+ level: Int
+ )
+}
+
+@SysUISingleton
+class AudioSharingInteractorImpl
+@Inject
+constructor(
+ @Application private val coroutineScope: CoroutineScope,
+ private val audioSharingRepository: AudioSharingRepository
+) : AudioSharingInteractor {
+
+ override val volume: Flow<Int?> =
+ combine(audioSharingRepository.secondaryGroupId, audioSharingRepository.volumeMap) {
+ secondaryGroupId,
+ volumeMap ->
+ if (secondaryGroupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) null
+ else volumeMap.getOrDefault(secondaryGroupId, DEFAULT_VOLUME)
+ }
+
+ override val volumeMin: Int = AUDIO_SHARING_VOLUME_MIN
+
+ override val volumeMax: Int = AUDIO_SHARING_VOLUME_MAX
+
+ override fun setStreamVolume(level: Int) {
+ coroutineScope.launch { audioSharingRepository.setSecondaryVolume(level) }
+ }
+
+ private companion object {
+ const val DEFAULT_VOLUME = 20
+ }
+}
+
+@SysUISingleton
+class AudioSharingInteractorEmptyImpl : AudioSharingInteractor {
+ override val volume: Flow<Int?> = emptyFlow()
+ override val volumeMin: Int = EMPTY_VOLUME
+ override val volumeMax: Int = EMPTY_VOLUME
+
+ override fun setStreamVolume(level: Int) {}
+
+ private companion object {
+ const val EMPTY_VOLUME = 0
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index 8457bdb2d0ff..45799b255630 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -261,7 +261,7 @@ public class BubblesManager {
// Store callback in a field so it won't get GC'd
mStatusBarWindowCallback =
(keyguardShowing, keyguardOccluded, keyguardGoingAway, bouncerShowing, isDozing,
- panelExpanded, isDreaming) -> {
+ panelExpanded, isDreaming, communalShowing) -> {
if (panelExpanded != mPanelExpanded) {
mPanelExpanded = panelExpanded;
mBubbles.onNotificationPanelExpandedChanged(panelExpanded);
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 3f1ec85ae99a..ec9b5cfbdeb2 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -20,9 +20,8 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_B
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
@@ -67,7 +66,6 @@ import com.android.wm.shell.onehanded.OneHandedEventCallback;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.onehanded.OneHandedUiEventLogger;
import com.android.wm.shell.pip.Pip;
-import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.recents.RecentTasks;
import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.sysui.ShellInterface;
@@ -251,25 +249,7 @@ public final class WMShell implements
pip.showPictureInPictureMenu();
}
});
- pip.registerPipTransitionCallback(
- new PipTransitionController.PipTransitionCallback() {
- @Override
- public void onPipTransitionStarted(int direction, Rect pipBounds) {
- mSysUiState.setFlag(SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING, true)
- .commitUpdate(mDisplayTracker.getDefaultDisplayId());
- }
-
- @Override
- public void onPipTransitionFinished(int direction) {
- mSysUiState.setFlag(SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING, false)
- .commitUpdate(mDisplayTracker.getDefaultDisplayId());
- }
- @Override
- public void onPipTransitionCanceled(int direction) {
- // No op.
- }
- }, mSysUiMainExecutor);
mSysUiState.addCallback(sysUiStateFlag -> {
mIsSysUiStateValid = (sysUiStateFlag & INVALID_SYSUI_STATE_MASK) == 0;
pip.onSystemUiStateChanged(mIsSysUiStateValid, sysUiStateFlag);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/TestableWindowManager.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/TestableWindowManager.java
index b23dfdc68a87..859517839388 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/TestableWindowManager.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/TestableWindowManager.java
@@ -21,6 +21,7 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.os.IBinder;
import android.view.Display;
+import android.view.KeyboardShortcutGroup;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
@@ -55,6 +56,11 @@ public class TestableWindowManager implements WindowManager {
}
@Override
+ public KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId) {
+ return mWindowManager.getApplicationLaunchKeyboardShortcuts(deviceId);
+ }
+
+ @Override
public Region getCurrentImeTouchRegion() {
return mWindowManager.getCurrentImeTouchRegion();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
index c30bedde557d..12140b58936b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
@@ -288,7 +288,7 @@ public class MenuViewLayerTest extends SysuiTestCase {
mockActivityQuery(true);
mMenuViewLayer.dispatchAccessibilityAction(R.id.action_edit);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mSpyContext).startActivity(intentCaptor.capture());
+ verify(mSpyContext).startActivityAsUser(intentCaptor.capture(), eq(UserHandle.CURRENT));
assertThat(intentCaptor.getValue().getAction()).isEqualTo(
mMenuViewLayer.getIntentForEditScreen().getAction());
}
@@ -299,6 +299,7 @@ public class MenuViewLayerTest extends SysuiTestCase {
mockActivityQuery(false);
mMenuViewLayer.dispatchAccessibilityAction(R.id.action_edit);
verify(mSpyContext, never()).startActivity(any());
+ verify(mSpyContext, never()).startActivityAsUser(any(), any());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
index 8f7dc7cf109b..5ea5c2189560 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
@@ -16,8 +16,9 @@
package com.android.systemui.accessibility.hearingaid;
+import static android.bluetooth.BluetoothHapClient.PRESET_INDEX_UNAVAILABLE;
+
import static com.android.systemui.accessibility.hearingaid.HearingDevicesDialogDelegate.LIVE_CAPTION_INTENT;
-import static com.android.systemui.statusbar.phone.SystemUIDialog.DEFAULT_DISMISS_ON_DEVICE_LOCK;
import static com.google.common.truth.Truth.assertThat;
@@ -26,9 +27,13 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHapPresetInfo;
+import android.bluetooth.BluetoothProfile;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -42,6 +47,7 @@ import android.provider.Settings;
import android.testing.TestableLooper;
import android.view.View;
import android.widget.LinearLayout;
+import android.widget.Spinner;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -86,14 +92,15 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
public MockitoRule mockito = MockitoJUnit.rule();
private static final String DEVICE_ADDRESS = "AA:BB:CC:DD:EE:FF";
+ private static final String DEVICE_NAME = "test_name";
private static final String TEST_PKG = "pkg";
private static final String TEST_CLS = "cls";
private static final ComponentName TEST_COMPONENT = new ComponentName(TEST_PKG, TEST_CLS);
private static final String TEST_LABEL = "label";
+ private static final int TEST_PRESET_INDEX = 1;
+ private static final String TEST_PRESET_NAME = "test_preset";
@Mock
- private SystemUIDialog.Factory mSystemUIDialogFactory;
- @Mock
private SystemUIDialogManager mSystemUIDialogManager;
@Mock
private SysUiState mSysUiState;
@@ -118,6 +125,8 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
@Mock
private CachedBluetoothDevice mCachedDevice;
@Mock
+ private BluetoothDevice mDevice;
+ @Mock
private DeviceItem mHearingDeviceItem;
@Mock
private PackageManager mPackageManager;
@@ -125,7 +134,10 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
private ActivityInfo mActivityInfo;
@Mock
private Drawable mDrawable;
+ @Mock
+ private HearingDevicesPresetsController mPresetsController;
private SystemUIDialog mDialog;
+ private SystemUIDialog.Factory mDialogFactory;
private HearingDevicesDialogDelegate mDialogDelegate;
private TestableLooper mTestableLooper;
private final List<CachedBluetoothDevice> mDevices = new ArrayList<>();
@@ -141,23 +153,23 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
when(mSysUiState.setFlag(anyLong(), anyBoolean())).thenReturn(mSysUiState);
+ when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mDevice.isConnected()).thenReturn(true);
+ when(mCachedDevice.getDevice()).thenReturn(mDevice);
when(mCachedDevice.getAddress()).thenReturn(DEVICE_ADDRESS);
+ when(mCachedDevice.getName()).thenReturn(DEVICE_NAME);
+ when(mCachedDevice.isActiveDevice(BluetoothProfile.HEARING_AID)).thenReturn(true);
+ when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
+ when(mCachedDevice.isConnectedHapClientDevice()).thenReturn(true);
when(mHearingDeviceItem.getCachedBluetoothDevice()).thenReturn(mCachedDevice);
- mContext.setMockPackageManager(mPackageManager);
-
- setUpPairNewDeviceDialog();
- when(mSystemUIDialogFactory.create(any(SystemUIDialog.Delegate.class)))
- .thenReturn(mDialog);
- }
-
- @Test
- public void createDialog_dialogShown() {
- assertThat(mDialogDelegate.createDialog()).isEqualTo(mDialog);
+ mContext.setMockPackageManager(mPackageManager);
+ mDevices.add(mCachedDevice);
}
@Test
public void clickPairNewDeviceButton_intentActionMatch() {
+ setUpPairNewDeviceDialog();
mDialog.show();
getPairNewDeviceButton(mDialog).performClick();
@@ -185,6 +197,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
@Test
public void onDeviceItemOnClicked_connectedDevice_disconnect() {
+ setUpDeviceListDialog();
when(mHearingDeviceItem.getType()).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE);
mDialogDelegate.onDeviceItemOnClicked(mHearingDeviceItem, new View(mContext));
@@ -231,50 +244,100 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
assertThat(relatedToolsView.getChildCount()).isEqualTo(2);
}
+ @Test
+ public void showDialog_noPreset_presetGone() {
+ when(mPresetsController.getAllPresetInfo()).thenReturn(new ArrayList<>());
+ when(mPresetsController.getActivePresetIndex()).thenReturn(PRESET_INDEX_UNAVAILABLE);
+
+ setUpDeviceListDialog();
+ mDialog.show();
+
+ Spinner spinner = (Spinner) getPresetSpinner(mDialog);
+ assertThat(spinner.getVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void showDialog_presetExist_presetSelected() {
+ BluetoothHapPresetInfo info = getTestPresetInfo();
+ when(mPresetsController.getAllPresetInfo()).thenReturn(List.of(info));
+ when(mPresetsController.getActivePresetIndex()).thenReturn(TEST_PRESET_INDEX);
+
+ setUpDeviceListDialog();
+ mDialog.show();
+
+ Spinner spinner = (Spinner) getPresetSpinner(mDialog);
+ assertThat(spinner.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(spinner.getSelectedItemPosition()).isEqualTo(0);
+ }
+
+ @Test
+ public void onActiveDeviceChanged_presetExist_presetSelected() {
+ setUpDeviceListDialog();
+ mDialog.show();
+ BluetoothHapPresetInfo info = getTestPresetInfo();
+ when(mPresetsController.getAllPresetInfo()).thenReturn(List.of(info));
+ when(mPresetsController.getActivePresetIndex()).thenReturn(TEST_PRESET_INDEX);
+
+ mDialogDelegate.onActiveDeviceChanged(mCachedDevice, BluetoothProfile.LE_AUDIO);
+ mTestableLooper.processAllMessages();
+
+ Spinner spinner = (Spinner) getPresetSpinner(mDialog);
+ assertThat(spinner.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(spinner.getSelectedItemPosition()).isEqualTo(0);
+ }
+
+
+
private void setUpPairNewDeviceDialog() {
+ mDialogFactory = new SystemUIDialog.Factory(
+ mContext,
+ mSystemUIDialogManager,
+ mSysUiState,
+ getFakeBroadcastDispatcher(),
+ mDialogTransitionAnimator
+ );
mDialogDelegate = new HearingDevicesDialogDelegate(
mContext,
true,
- mSystemUIDialogFactory,
+ mDialogFactory,
mActivityStarter,
mDialogTransitionAnimator,
mLocalBluetoothManager,
new Handler(mTestableLooper.getLooper()),
mAudioManager
);
- mDialog = new SystemUIDialog(
+
+ mDialog = mDialogDelegate.createDialog();
+ }
+
+ private void setUpDeviceListDialog() {
+ mDialogFactory = new SystemUIDialog.Factory(
mContext,
- 0,
- DEFAULT_DISMISS_ON_DEVICE_LOCK,
mSystemUIDialogManager,
mSysUiState,
getFakeBroadcastDispatcher(),
- mDialogTransitionAnimator,
- mDialogDelegate
+ mDialogTransitionAnimator
);
- }
-
- private void setUpDeviceListDialog() {
mDialogDelegate = new HearingDevicesDialogDelegate(
mContext,
false,
- mSystemUIDialogFactory,
+ mDialogFactory,
mActivityStarter,
mDialogTransitionAnimator,
mLocalBluetoothManager,
new Handler(mTestableLooper.getLooper()),
mAudioManager
);
- mDialog = new SystemUIDialog(
- mContext,
- 0,
- DEFAULT_DISMISS_ON_DEVICE_LOCK,
- mSystemUIDialogManager,
- mSysUiState,
- getFakeBroadcastDispatcher(),
- mDialogTransitionAnimator,
- mDialogDelegate
- );
+
+ mDialog = mDialogDelegate.createDialog();
+ mDialogDelegate.setHearingDevicesPresetsController(mPresetsController);
+ }
+
+ private BluetoothHapPresetInfo getTestPresetInfo() {
+ BluetoothHapPresetInfo info = mock(BluetoothHapPresetInfo.class);
+ when(info.getName()).thenReturn(TEST_PRESET_NAME);
+ when(info.getIndex()).thenReturn(TEST_PRESET_INDEX);
+ return info;
}
private View getPairNewDeviceButton(SystemUIDialog dialog) {
@@ -285,6 +348,10 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
return dialog.requireViewById(R.id.related_tools_container);
}
+ private View getPresetSpinner(SystemUIDialog dialog) {
+ return dialog.requireViewById(R.id.preset_spinner);
+ }
+
@After
public void reset() {
if (mDialogDelegate != null) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 9a99ed7bb512..1e3ee280204b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -27,6 +27,7 @@ import android.hardware.biometrics.PromptContentViewWithMoreOptionsButton
import android.hardware.biometrics.PromptInfo
import android.hardware.biometrics.PromptVerticalListContentView
import android.hardware.face.FaceSensorPropertiesInternal
+import android.hardware.fingerprint.FingerprintManager
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
import android.os.Handler
import android.os.IBinder
@@ -88,9 +89,8 @@ import org.mockito.Mockito.eq
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
-import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever
-
+import org.mockito.junit.MockitoJUnit
private const val OP_PACKAGE_NAME = "biometric.testapp"
@@ -99,33 +99,21 @@ private const val OP_PACKAGE_NAME = "biometric.testapp"
@SmallTest
open class AuthContainerViewTest : SysuiTestCase() {
- @JvmField @Rule
- var mockitoRule = MockitoJUnit.rule()
-
- @Mock
- lateinit var callback: AuthDialogCallback
- @Mock
- lateinit var userManager: UserManager
- @Mock
- lateinit var lockPatternUtils: LockPatternUtils
- @Mock
- lateinit var wakefulnessLifecycle: WakefulnessLifecycle
- @Mock
- lateinit var panelInteractionDetector: AuthDialogPanelInteractionDetector
- @Mock
- lateinit var windowToken: IBinder
- @Mock
- lateinit var interactionJankMonitor: InteractionJankMonitor
- @Mock
- lateinit var vibrator: VibratorHelper
- @Mock
- lateinit var udfpsUtils: UdfpsUtils
- @Mock
- lateinit var authController: AuthController
- @Mock
- lateinit var selectedUserInteractor: SelectedUserInteractor
- @Mock
- private lateinit var packageManager: PackageManager
+ @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
+
+ @Mock lateinit var callback: AuthDialogCallback
+ @Mock lateinit var userManager: UserManager
+ @Mock lateinit var fingerprintManager: FingerprintManager
+ @Mock lateinit var lockPatternUtils: LockPatternUtils
+ @Mock lateinit var wakefulnessLifecycle: WakefulnessLifecycle
+ @Mock lateinit var panelInteractionDetector: AuthDialogPanelInteractionDetector
+ @Mock lateinit var windowToken: IBinder
+ @Mock lateinit var interactionJankMonitor: InteractionJankMonitor
+ @Mock lateinit var vibrator: VibratorHelper
+ @Mock lateinit var udfpsUtils: UdfpsUtils
+ @Mock lateinit var authController: AuthController
+ @Mock lateinit var selectedUserInteractor: SelectedUserInteractor
+ @Mock private lateinit var packageManager: PackageManager
@Mock private lateinit var activityTaskManager: ActivityTaskManager
private lateinit var displayRepository: FakeDisplayRepository
@@ -141,11 +129,12 @@ open class AuthContainerViewTest : SysuiTestCase() {
private val fingerprintRepository = FakeFingerprintPropertyRepository()
private val displayStateRepository = FakeDisplayStateRepository()
private val credentialInteractor = FakeCredentialInteractor()
- private val bpCredentialInteractor = PromptCredentialInteractor(
- Dispatchers.Main.immediate,
- biometricPromptRepository,
- credentialInteractor,
- )
+ private val bpCredentialInteractor =
+ PromptCredentialInteractor(
+ Dispatchers.Main.immediate,
+ biometricPromptRepository,
+ credentialInteractor,
+ )
private val promptSelectorInteractor by lazy {
PromptSelectorInteractorImpl(
fingerprintRepository,
@@ -166,22 +155,26 @@ open class AuthContainerViewTest : SysuiTestCase() {
displayStateInteractor =
DisplayStateInteractorImpl(
- testScope.backgroundScope,
- mContext,
- fakeExecutor,
- displayStateRepository,
- displayRepository,
+ testScope.backgroundScope,
+ mContext,
+ fakeExecutor,
+ displayStateRepository,
+ displayRepository,
)
udfpsOverlayInteractor =
- UdfpsOverlayInteractor(
- context,
- authController,
- selectedUserInteractor,
- testScope.backgroundScope,
- )
+ UdfpsOverlayInteractor(
+ context,
+ authController,
+ selectedUserInteractor,
+ fingerprintManager,
+ testScope.backgroundScope,
+ )
biometricStatusInteractor =
- BiometricStatusInteractorImpl(activityTaskManager, biometricStatusRepository,
- fingerprintRepository)
+ BiometricStatusInteractorImpl(
+ activityTaskManager,
+ biometricStatusRepository,
+ fingerprintRepository
+ )
iconProvider = IconProvider(context)
// Set up default logo icon
whenever(packageManager.getApplicationIcon(OP_PACKAGE_NAME)).thenReturn(defaultLogoIcon)
@@ -198,10 +191,8 @@ open class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testNotifiesAnimatedIn() {
initializeFingerprintContainer()
- verify(callback).onDialogAnimatedIn(
- authContainer?.requestId ?: 0L,
- true /* startFingerprintNow */
- )
+ verify(callback)
+ .onDialogAnimatedIn(authContainer?.requestId ?: 0L, true /* startFingerprintNow */)
}
@Test
@@ -246,10 +237,8 @@ open class AuthContainerViewTest : SysuiTestCase() {
waitForIdleSync()
// attaching the view resets the state and allows this to happen again
- verify(callback).onDialogAnimatedIn(
- authContainer?.requestId ?: 0L,
- true /* startFingerprintNow */
- )
+ verify(callback)
+ .onDialogAnimatedIn(authContainer?.requestId ?: 0L, true /* startFingerprintNow */)
}
@Test
@@ -274,10 +263,8 @@ open class AuthContainerViewTest : SysuiTestCase() {
// the first time is triggered by initializeFingerprintContainer()
// the second time was triggered by dismissWithoutCallback()
- verify(callback, times(2)).onDialogAnimatedIn(
- authContainer?.requestId ?: 0L,
- true /* startFingerprintNow */
- )
+ verify(callback, times(2))
+ .onDialogAnimatedIn(authContainer?.requestId ?: 0L, true /* startFingerprintNow */)
}
@Test
@@ -288,18 +275,18 @@ open class AuthContainerViewTest : SysuiTestCase() {
verify(panelInteractionDetector).disable()
}
-
@Test
fun testActionAuthenticated_sendsDismissedAuthenticated() {
val container = initializeFingerprintContainer()
container.mBiometricCallback.onAuthenticated()
waitForIdleSync()
- verify(callback).onDismissed(
+ verify(callback)
+ .onDismissed(
eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
eq<ByteArray?>(null), /* credentialAttestation */
eq(authContainer?.requestId ?: 0L)
- )
+ )
assertThat(container.parent).isNull()
}
@@ -309,15 +296,17 @@ open class AuthContainerViewTest : SysuiTestCase() {
container.mBiometricCallback.onUserCanceled()
waitForIdleSync()
- verify(callback).onSystemEvent(
+ verify(callback)
+ .onSystemEvent(
eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL),
eq(authContainer?.requestId ?: 0L)
- )
- verify(callback).onDismissed(
+ )
+ verify(callback)
+ .onDismissed(
eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
eq<ByteArray?>(null), /* credentialAttestation */
eq(authContainer?.requestId ?: 0L)
- )
+ )
assertThat(container.parent).isNull()
}
@@ -327,19 +316,21 @@ open class AuthContainerViewTest : SysuiTestCase() {
container.mBiometricCallback.onButtonNegative()
waitForIdleSync()
- verify(callback).onDismissed(
+ verify(callback)
+ .onDismissed(
eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
eq<ByteArray?>(null), /* credentialAttestation */
eq(authContainer?.requestId ?: 0L)
- )
+ )
assertThat(container.parent).isNull()
}
@Test
fun testActionTryAgain_sendsTryAgain() {
- val container = initializeFingerprintContainer(
- authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK
- )
+ val container =
+ initializeFingerprintContainer(
+ authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK
+ )
container.mBiometricCallback.onButtonTryAgain()
waitForIdleSync()
@@ -352,21 +343,24 @@ open class AuthContainerViewTest : SysuiTestCase() {
container.mBiometricCallback.onError()
waitForIdleSync()
- verify(callback).onDismissed(
+ verify(callback)
+ .onDismissed(
eq(AuthDialogCallback.DISMISSED_ERROR),
eq<ByteArray?>(null), /* credentialAttestation */
eq(authContainer?.requestId ?: 0L)
- )
+ )
assertThat(authContainer!!.parent).isNull()
}
@Ignore("b/279650412")
@Test
fun testActionUseDeviceCredential_sendsOnDeviceCredentialPressed() {
- val container = initializeFingerprintContainer(
- authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK or
- BiometricManager.Authenticators.DEVICE_CREDENTIAL
- )
+ val container =
+ initializeFingerprintContainer(
+ authenticators =
+ BiometricManager.Authenticators.BIOMETRIC_WEAK or
+ BiometricManager.Authenticators.DEVICE_CREDENTIAL
+ )
container.mBiometricCallback.onUseDeviceCredential()
waitForIdleSync()
@@ -376,10 +370,12 @@ open class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testAnimateToCredentialUI_invokesStartTransitionToCredentialUI() {
- val container = initializeFingerprintContainer(
- authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK or
- BiometricManager.Authenticators.DEVICE_CREDENTIAL
- )
+ val container =
+ initializeFingerprintContainer(
+ authenticators =
+ BiometricManager.Authenticators.BIOMETRIC_WEAK or
+ BiometricManager.Authenticators.DEVICE_CREDENTIAL
+ )
container.animateToCredentialUI(false)
waitForIdleSync()
@@ -395,10 +391,12 @@ open class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testAnimateToCredentialUI_rotateCredentialUI() {
- val container = initializeFingerprintContainer(
- authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK or
- BiometricManager.Authenticators.DEVICE_CREDENTIAL
- )
+ val container =
+ initializeFingerprintContainer(
+ authenticators =
+ BiometricManager.Authenticators.BIOMETRIC_WEAK or
+ BiometricManager.Authenticators.DEVICE_CREDENTIAL
+ )
container.animateToCredentialUI(false)
waitForIdleSync()
@@ -437,13 +435,12 @@ open class AuthContainerViewTest : SysuiTestCase() {
mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT)
var isButtonClicked = false
val contentView =
- PromptContentViewWithMoreOptionsButton.Builder()
- .setMoreOptionsButtonListener(
- fakeExecutor) { _, _ -> isButtonClicked = true }
- .build()
+ PromptContentViewWithMoreOptionsButton.Builder()
+ .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> isButtonClicked = true }
+ .build()
val container =
- initializeFingerprintContainer(contentViewWithMoreOptionsButton = contentView)
+ initializeFingerprintContainer(contentViewWithMoreOptionsButton = contentView)
waitForIdleSync()
@@ -461,9 +458,9 @@ open class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testShowCredentialUI_withDescription() {
val container =
- initializeFingerprintContainer(
- authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
- )
+ initializeFingerprintContainer(
+ authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
+ )
waitForIdleSync()
assertThat(container.hasCredentialView()).isTrue()
@@ -475,10 +472,10 @@ open class AuthContainerViewTest : SysuiTestCase() {
mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP)
mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT)
val container =
- initializeFingerprintContainer(
- authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
- verticalListContentView = PromptVerticalListContentView.Builder().build()
- )
+ initializeFingerprintContainer(
+ authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
+ verticalListContentView = PromptVerticalListContentView.Builder().build()
+ )
// Two-step credential view should show -
// 1. biometric prompt without sensor 2. credential view ui
waitForIdleSync()
@@ -497,14 +494,14 @@ open class AuthContainerViewTest : SysuiTestCase() {
mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP)
mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT)
val contentView =
- PromptContentViewWithMoreOptionsButton.Builder()
- .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> }
- .build()
+ PromptContentViewWithMoreOptionsButton.Builder()
+ .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> }
+ .build()
val container =
- initializeFingerprintContainer(
- authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
- contentViewWithMoreOptionsButton = contentView
- )
+ initializeFingerprintContainer(
+ authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
+ contentViewWithMoreOptionsButton = contentView
+ )
waitForIdleSync()
assertThat(container.hasCredentialView()).isTrue()
@@ -514,13 +511,13 @@ open class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testCredentialViewUsesEffectiveUserId() {
whenever(userManager.getCredentialOwnerProfile(anyInt())).thenReturn(200)
- whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(200))).thenReturn(
- DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
- )
+ whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(200)))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
- val container = initializeFingerprintContainer(
- authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
- )
+ val container =
+ initializeFingerprintContainer(
+ authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
+ )
waitForIdleSync()
assertThat(container.hasCredentialPatternView()).isTrue()
@@ -531,9 +528,8 @@ open class AuthContainerViewTest : SysuiTestCase() {
fun testCredentialUI_disablesClickingOnBackground() {
val container = initializeCredentialPasswordContainer()
assertThat(container.hasBiometricPrompt()).isFalse()
- assertThat(
- container.findViewById<View>(R.id.background)?.isImportantForAccessibility
- ).isFalse()
+ assertThat(container.findViewById<View>(R.id.background)?.isImportantForAccessibility)
+ .isFalse()
container.findViewById<View>(R.id.background)?.performClick()
waitForIdleSync()
@@ -552,7 +548,7 @@ open class AuthContainerViewTest : SysuiTestCase() {
fun testLayoutParams_hasShowWhenLockedFlag() {
val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
assertThat((layoutParams.flags and WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED) != 0)
- .isTrue()
+ .isTrue()
}
@Test
@@ -590,20 +586,20 @@ open class AuthContainerViewTest : SysuiTestCase() {
}
private fun initializeCredentialPasswordContainer(
- addToView: Boolean = true,
+ addToView: Boolean = true,
): TestAuthContainerView {
whenever(userManager.getCredentialOwnerProfile(anyInt())).thenReturn(20)
- whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(20))).thenReturn(
- DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
- )
+ whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(20)))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
// In the credential view, clicking on the background (to cancel authentication) is not
// valid. Thus, the listener should be null, and it should not be in the accessibility
// hierarchy.
- val container = initializeFingerprintContainer(
+ val container =
+ initializeFingerprintContainer(
authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
addToView = addToView,
- )
+ )
waitForIdleSync()
assertThat(container.hasCredentialPasswordView()).isTrue()
@@ -615,26 +611,28 @@ open class AuthContainerViewTest : SysuiTestCase() {
addToView: Boolean = true,
verticalListContentView: PromptVerticalListContentView? = null,
contentViewWithMoreOptionsButton: PromptContentViewWithMoreOptionsButton? = null,
- ) = initializeContainer(
- TestAuthContainerView(
- authenticators = authenticators,
- fingerprintProps = fingerprintSensorPropertiesInternal(),
+ ) =
+ initializeContainer(
+ TestAuthContainerView(
+ authenticators = authenticators,
+ fingerprintProps = fingerprintSensorPropertiesInternal(),
verticalListContentView = verticalListContentView,
- ),
- addToView
- )
+ ),
+ addToView
+ )
private fun initializeCoexContainer(
authenticators: Int = BiometricManager.Authenticators.BIOMETRIC_WEAK,
addToView: Boolean = true
- ) = initializeContainer(
- TestAuthContainerView(
- authenticators = authenticators,
- fingerprintProps = fingerprintSensorPropertiesInternal(),
- faceProps = faceSensorPropertiesInternal()
- ),
- addToView
- )
+ ) =
+ initializeContainer(
+ TestAuthContainerView(
+ authenticators = authenticators,
+ fingerprintProps = fingerprintSensorPropertiesInternal(),
+ faceProps = faceSensorPropertiesInternal()
+ ),
+ addToView
+ )
private fun initializeContainer(
view: TestAuthContainerView,
@@ -655,47 +653,50 @@ open class AuthContainerViewTest : SysuiTestCase() {
faceProps: List<FaceSensorPropertiesInternal> = listOf(),
verticalListContentView: PromptVerticalListContentView? = null,
contentViewWithMoreOptionsButton: PromptContentViewWithMoreOptionsButton? = null,
- ) : AuthContainerView(
- Config().apply {
- mContext = this@AuthContainerViewTest.context
- mCallback = callback
- mSensorIds = (fingerprintProps.map { it.sensorId } +
- faceProps.map { it.sensorId }).toIntArray()
- mSkipAnimation = true
- mPromptInfo = PromptInfo().apply {
- this.authenticators = authenticators
- if (verticalListContentView != null) {
- this.contentView = verticalListContentView
- } else if (contentViewWithMoreOptionsButton != null) {
- this.contentView = contentViewWithMoreOptionsButton
- }
- }
- mOpPackageName = OP_PACKAGE_NAME
- },
- testScope.backgroundScope,
- fingerprintProps,
- faceProps,
- wakefulnessLifecycle,
- panelInteractionDetector,
- userManager,
- lockPatternUtils,
- interactionJankMonitor,
- { promptSelectorInteractor },
- PromptViewModel(
- displayStateInteractor,
- promptSelectorInteractor,
- context,
- udfpsOverlayInteractor,
- biometricStatusInteractor,
- udfpsUtils,
- iconProvider,
- activityTaskManager
- ),
- { credentialViewModel },
- Handler(TestableLooper.get(this).looper),
- fakeExecutor,
- vibrator
- ) {
+ ) :
+ AuthContainerView(
+ Config().apply {
+ mContext = this@AuthContainerViewTest.context
+ mCallback = callback
+ mSensorIds =
+ (fingerprintProps.map { it.sensorId } + faceProps.map { it.sensorId })
+ .toIntArray()
+ mSkipAnimation = true
+ mPromptInfo =
+ PromptInfo().apply {
+ this.authenticators = authenticators
+ if (verticalListContentView != null) {
+ this.contentView = verticalListContentView
+ } else if (contentViewWithMoreOptionsButton != null) {
+ this.contentView = contentViewWithMoreOptionsButton
+ }
+ }
+ mOpPackageName = OP_PACKAGE_NAME
+ },
+ testScope.backgroundScope,
+ fingerprintProps,
+ faceProps,
+ wakefulnessLifecycle,
+ panelInteractionDetector,
+ userManager,
+ lockPatternUtils,
+ interactionJankMonitor,
+ { promptSelectorInteractor },
+ PromptViewModel(
+ displayStateInteractor,
+ promptSelectorInteractor,
+ context,
+ udfpsOverlayInteractor,
+ biometricStatusInteractor,
+ udfpsUtils,
+ iconProvider,
+ activityTaskManager
+ ),
+ { credentialViewModel },
+ Handler(TestableLooper.get(this).looper),
+ fakeExecutor,
+ vibrator
+ ) {
override fun postOnAnimation(runnable: Runnable) {
runnable.run()
}
@@ -717,8 +718,10 @@ open class AuthContainerViewTest : SysuiTestCase() {
val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
val lpFlags = layoutParams.flags
- assertThat((lpFlags and WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS)
- != 0).isTrue()
+ assertThat(
+ (lpFlags and WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) != 0
+ )
+ .isTrue()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDebouncerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDebouncerTest.kt
new file mode 100644
index 000000000000..baef620ad556
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDebouncerTest.kt
@@ -0,0 +1,221 @@
+/*
+ * 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.biometrics
+
+import android.hardware.biometrics.BiometricFaceConstants
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@TestableLooper.RunWithLooper
+class FaceHelpMessageDebouncerTest : SysuiTestCase() {
+ private lateinit var underTest: FaceHelpMessageDebouncer
+ private val window = 9L
+ private val startWindow = 4L
+ private val shownFaceMessageFrequencyBoost = 2
+
+ @Before
+ fun setUp() {
+ underTest =
+ FaceHelpMessageDebouncer(
+ window = window,
+ startWindow = startWindow,
+ shownFaceMessageFrequencyBoost = shownFaceMessageFrequencyBoost,
+ )
+ }
+
+ @Test
+ fun getMessageBeforeStartWindow_null() {
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE,
+ "testTooClose",
+ 0
+ )
+ )
+ assertThat(underTest.getMessageToShow(0)).isNull()
+ }
+
+ @Test
+ fun getMessageAfterStartWindow() {
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE,
+ "tooClose",
+ 0
+ )
+ )
+
+ assertThat(underTest.getMessageToShow(startWindow)?.msgId)
+ .isEqualTo(BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE)
+ assertThat(underTest.getMessageToShow(startWindow)?.msg).isEqualTo("tooClose")
+ }
+
+ @Test
+ fun getMessageAfterMessagesCleared_null() {
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE,
+ "tooClose",
+ 0
+ )
+ )
+ underTest.startNewFaceAuthSession(0)
+
+ assertThat(underTest.getMessageToShow(startWindow)).isNull()
+ }
+
+ @Test
+ fun messagesBeforeWindowRemoved() {
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE,
+ "tooClose",
+ 0
+ )
+ )
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE,
+ "tooClose",
+ 0
+ )
+ )
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE,
+ "tooClose",
+ window - 1
+ )
+ )
+ val lastMessage =
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT,
+ "tooBright",
+ window
+ )
+ underTest.addMessage(lastMessage)
+
+ assertThat(underTest.getMessageToShow(window + 1)).isEqualTo(lastMessage)
+ }
+
+ @Test
+ fun getMessageTieGoesToMostRecent() {
+ for (i in 1..window step 2) {
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE,
+ "tooClose",
+ i
+ )
+ )
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT,
+ "tooBright",
+ i + 1
+ )
+ )
+ }
+
+ assertThat(underTest.getMessageToShow(window)?.msgId)
+ .isEqualTo(BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT)
+ assertThat(underTest.getMessageToShow(window)?.msg).isEqualTo("tooBright")
+ }
+
+ @Test
+ fun boostCurrentlyShowingMessage() {
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT,
+ "tooBright",
+ 0
+ )
+ )
+
+ val lastMessageShown = underTest.getMessageToShow(startWindow)
+ assertThat(lastMessageShown?.msgId)
+ .isEqualTo(BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT)
+
+ for (i in 1..<shownFaceMessageFrequencyBoost) {
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE,
+ "tooClose",
+ startWindow
+ )
+ )
+ }
+
+ // although technically there's a different msgId with a higher frequency count now, the
+ // shownFaceMessageFrequencyBoost causes the last message shown to get a "boost"
+ // to keep showing
+ assertThat(underTest.getMessageToShow(startWindow)).isEqualTo(lastMessageShown)
+ }
+
+ @Test
+ fun overcomeBoostedCurrentlyShowingMessage() {
+ // Comments are assuming shownFaceMessageFrequencyBoost = 2
+ // [B], weights: B=1
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT,
+ "tooBright",
+ 0
+ )
+ )
+
+ // [B], showing messageB, weights: B=3
+ val messageB = underTest.getMessageToShow(startWindow)
+
+ // [B, C, C], showing messageB, weights: B=3, C=2
+ for (i in 1..shownFaceMessageFrequencyBoost) {
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE,
+ "tooClose",
+ startWindow
+ )
+ )
+ }
+ // messageB is getting boosted to continue to show
+ assertThat(underTest.getMessageToShow(startWindow)).isEqualTo(messageB)
+
+ // receive one more FACE_ACQUIRED_TOO_CLOSE acquired info to pass the boost
+ // [C, C, C], showing messageB, weights: B=2, C=3
+ underTest.addMessage(
+ HelpFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE,
+ "tooClose",
+ startWindow
+ )
+ )
+
+ // Now FACE_ACQUIRED_TOO_CLOSE has surpassed the boosted messageB frequency
+ // [C, C, C], showing messageC, weights: C=5
+ assertThat(underTest.getMessageToShow(startWindow)?.msgId)
+ .isEqualTo(BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
index a58efd3224a4..30207bb310ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
@@ -23,15 +23,22 @@ 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.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.display.data.repository.DeviceStateRepository
import com.android.systemui.display.data.repository.fakeDeviceStateRepository
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
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.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -61,10 +68,11 @@ class LogContextInteractorImplTest : SysuiTestCase() {
fun setup() {
interactor =
LogContextInteractorImpl(
- testScope.backgroundScope,
- deviceStateRepository,
- kosmos.keyguardTransitionInteractor,
- udfpsOverlayInteractor,
+ applicationScope = testScope.backgroundScope,
+ deviceStateRepository = deviceStateRepository,
+ keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
+ udfpsOverlayInteractor = udfpsOverlayInteractor,
+ deviceEntryInteractor = { kosmos.deviceEntryInteractor },
)
}
@@ -135,7 +143,57 @@ class LogContextInteractorImplTest : SysuiTestCase() {
}
@Test
- fun displayStateChanges() =
+ @EnableSceneContainer
+ fun displayStateChanges_withSceneContainer() =
+ testScope.runTest {
+ val displayState = collectLastValue(interactor.displayState)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.OFF)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_NO_UI)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.DOZING)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_NO_UI)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.DREAMING)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_SCREENSAVER)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.AOD)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_AOD)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.ALTERNATE_BOUNCER)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.LOCKSCREEN)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.OCCLUDED)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+ // Unlock the device.
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ runCurrent()
+ kosmos.sceneInteractor.snapToScene(Scenes.Gone, "")
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.GONE)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_UNKNOWN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.UNDEFINED)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_UNKNOWN)
+
+ // Relock the device
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "")
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.AOD)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_AOD)
+ }
+
+ @Test
+ @DisableSceneContainer
+ fun displayStateChanges_withoutSceneContainer() =
testScope.runTest {
val displayState = collectLastValue(interactor.displayState)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
index 3d63c5b6d0f8..13f2c7212e36 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.biometrics.domain.interactor
import android.graphics.Rect
+import android.hardware.fingerprint.FingerprintManager
import android.view.MotionEvent
import android.view.Surface
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -51,6 +52,7 @@ class UdfpsOverlayInteractorTest : SysuiTestCase() {
private lateinit var testScope: TestScope
+ @Mock private lateinit var fingerprintManager: FingerprintManager
@Mock private lateinit var authController: AuthController
@Captor private lateinit var authControllerCallback: ArgumentCaptor<AuthController.Callback>
@@ -111,6 +113,7 @@ class UdfpsOverlayInteractorTest : SysuiTestCase() {
context,
authController,
selectedUserInteractor,
+ fingerprintManager,
testScope.backgroundScope
)
testScope.runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index 97f5efcf4c5f..677d1fdaa01d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -1799,8 +1799,10 @@ internal data class TestCase(
when {
fingerprint != null && face != null -> "coex"
fingerprint != null && fingerprint.isAnySidefpsType -> "fingerprint only, sideFps"
- fingerprint != null && !fingerprint.isAnySidefpsType ->
- "fingerprint only, non-sideFps"
+ fingerprint != null && fingerprint.isAnyUdfpsType -> "fingerprint only, udfps"
+ fingerprint != null &&
+ fingerprint.sensorType == FingerprintSensorProperties.TYPE_REAR ->
+ "fingerprint only, rearFps"
face != null -> "face only"
else -> "?"
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupHelperTest.kt
index 7094848e3127..e60848bb6bc3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupHelperTest.kt
@@ -120,11 +120,26 @@ class CommunalBackupHelperTest : SysuiTestCase() {
private fun setUpDatabase(): List<FakeWidgetMetadata> {
return listOf(
- FakeWidgetMetadata(11, "com.android.fakePackage1/fakeWidget1", 3),
- FakeWidgetMetadata(12, "com.android.fakePackage2/fakeWidget2", 2),
- FakeWidgetMetadata(13, "com.android.fakePackage3/fakeWidget3", 1),
+ FakeWidgetMetadata(
+ widgetId = 11,
+ componentName = "com.android.fakePackage1/fakeWidget1",
+ rank = 3,
+ userSerialNumber = 0,
+ ),
+ FakeWidgetMetadata(
+ widgetId = 12,
+ componentName = "com.android.fakePackage2/fakeWidget2",
+ rank = 2,
+ userSerialNumber = 0,
+ ),
+ FakeWidgetMetadata(
+ widgetId = 13,
+ componentName = "com.android.fakePackage3/fakeWidget3",
+ rank = 1,
+ userSerialNumber = 10,
+ ),
)
- .onEach { dao.addWidget(it.widgetId, it.componentName, it.rank) }
+ .onEach { dao.addWidget(it.widgetId, it.componentName, it.rank, it.userSerialNumber) }
}
private fun getBackupDataInputStream(): BackupDataInputStream {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupUtilsTest.kt
index cde7a0ed1bd4..983a43561590 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupUtilsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupUtilsTest.kt
@@ -66,11 +66,28 @@ class CommunalBackupUtilsTest : SysuiTestCase() {
// Set up database
val expectedWidgets =
listOf(
- FakeWidgetMetadata(11, "com.android.fakePackage1/fakeWidget1", 3),
- FakeWidgetMetadata(12, "com.android.fakePackage2/fakeWidget2", 2),
- FakeWidgetMetadata(13, "com.android.fakePackage3/fakeWidget3", 1),
+ FakeWidgetMetadata(
+ widgetId = 11,
+ componentName = "com.android.fakePackage1/fakeWidget1",
+ rank = 3,
+ userSerialNumber = 0,
+ ),
+ FakeWidgetMetadata(
+ widgetId = 12,
+ componentName = "com.android.fakePackage2/fakeWidget2",
+ rank = 2,
+ userSerialNumber = 0,
+ ),
+ FakeWidgetMetadata(
+ widgetId = 13,
+ componentName = "com.android.fakePackage3/fakeWidget3",
+ rank = 1,
+ userSerialNumber = 10,
+ ),
)
- expectedWidgets.forEach { dao.addWidget(it.widgetId, it.componentName, it.rank) }
+ expectedWidgets.forEach {
+ dao.addWidget(it.widgetId, it.componentName, it.rank, it.userSerialNumber)
+ }
// Get communal hub state
val state = underTest.getCommunalHubState()
@@ -128,7 +145,12 @@ class CommunalBackupUtilsTest : SysuiTestCase() {
assertThat(underTest.fileExists()).isFalse()
}
- data class FakeWidgetMetadata(val widgetId: Int, val componentName: String, val rank: Int)
+ data class FakeWidgetMetadata(
+ val widgetId: Int,
+ val componentName: String,
+ val rank: Int,
+ val userSerialNumber: Int,
+ )
companion object {
/**
@@ -140,7 +162,8 @@ class CommunalBackupUtilsTest : SysuiTestCase() {
{ actual, expected ->
actual?.widgetId == expected?.widgetId &&
actual?.componentName == expected?.componentName &&
- actual?.rank == expected?.rank
+ actual?.rank == expected?.rank &&
+ actual?.userSerialNumber == expected?.userSerialNumber
},
"represents",
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/data/db/CommunalDatabaseMigrationsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/data/db/CommunalDatabaseMigrationsTest.kt
new file mode 100644
index 000000000000..eb0ab782ae3f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/communal/data/db/CommunalDatabaseMigrationsTest.kt
@@ -0,0 +1,149 @@
+/*
+ * 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.communal.data.db
+
+import androidx.room.testing.MigrationTestHelper
+import androidx.sqlite.db.SupportSQLiteDatabase
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.lifecycle.InstantTaskExecutorRule
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CommunalDatabaseMigrationsTest : SysuiTestCase() {
+
+ @JvmField @Rule val instantTaskExecutor = InstantTaskExecutorRule()
+
+ @get:Rule
+ val migrationTestHelper =
+ MigrationTestHelper(
+ InstrumentationRegistry.getInstrumentation(),
+ CommunalDatabase::class.java.canonicalName,
+ )
+
+ @Test
+ fun migrate1To2() {
+ // Create a communal database in version 1
+ val databaseV1 = migrationTestHelper.createDatabase(DATABASE_NAME, version = 1)
+
+ // Populate some fake data
+ val fakeWidgetsV1 =
+ listOf(
+ FakeCommunalWidgetItemV1(1, "test_widget_1", 11),
+ FakeCommunalWidgetItemV1(2, "test_widget_2", 12),
+ FakeCommunalWidgetItemV1(3, "test_widget_3", 13),
+ )
+ databaseV1.insertWidgetsV1(fakeWidgetsV1)
+
+ // Verify fake widgets populated
+ databaseV1.verifyWidgetsV1(fakeWidgetsV1)
+
+ // Run migration and get database V2, the migration test helper verifies that the schema is
+ // updated correctly
+ val databaseV2 =
+ migrationTestHelper.runMigrationsAndValidate(
+ name = DATABASE_NAME,
+ version = 2,
+ validateDroppedTables = false,
+ CommunalDatabase.MIGRATION_1_2,
+ )
+
+ // Verify data is migrated correctly
+ databaseV2.verifyWidgetsV2(fakeWidgetsV1.map { it.getV2() })
+ }
+
+ private fun SupportSQLiteDatabase.insertWidgetsV1(widgets: List<FakeCommunalWidgetItemV1>) {
+ widgets.forEach { widget ->
+ execSQL(
+ "INSERT INTO communal_widget_table(widget_id, component_name, item_id) " +
+ "VALUES(${widget.widgetId}, '${widget.componentName}', ${widget.itemId})"
+ )
+ }
+ }
+
+ private fun SupportSQLiteDatabase.verifyWidgetsV1(widgets: List<FakeCommunalWidgetItemV1>) {
+ val cursor = query("SELECT * FROM communal_widget_table")
+ assertThat(cursor.moveToFirst()).isTrue()
+
+ widgets.forEach { widget ->
+ assertThat(cursor.getInt(cursor.getColumnIndex("widget_id"))).isEqualTo(widget.widgetId)
+ assertThat(cursor.getString(cursor.getColumnIndex("component_name")))
+ .isEqualTo(widget.componentName)
+ assertThat(cursor.getInt(cursor.getColumnIndex("item_id"))).isEqualTo(widget.itemId)
+
+ cursor.moveToNext()
+ }
+
+ // Verify there is no more columns
+ assertThat(cursor.isAfterLast).isTrue()
+ }
+
+ private fun SupportSQLiteDatabase.verifyWidgetsV2(widgets: List<FakeCommunalWidgetItemV2>) {
+ val cursor = query("SELECT * FROM communal_widget_table")
+ assertThat(cursor.moveToFirst()).isTrue()
+
+ widgets.forEach { widget ->
+ assertThat(cursor.getInt(cursor.getColumnIndex("widget_id"))).isEqualTo(widget.widgetId)
+ assertThat(cursor.getString(cursor.getColumnIndex("component_name")))
+ .isEqualTo(widget.componentName)
+ assertThat(cursor.getInt(cursor.getColumnIndex("item_id"))).isEqualTo(widget.itemId)
+ assertThat(cursor.getInt(cursor.getColumnIndex("user_serial_number")))
+ .isEqualTo(widget.userSerialNumber)
+
+ cursor.moveToNext()
+ }
+
+ // Verify there is no more columns
+ assertThat(cursor.isAfterLast).isTrue()
+ }
+
+ /**
+ * Returns the expected data after migration from V1 to V2, which is simply that the new user
+ * serial number field is now set to [CommunalWidgetItem.USER_SERIAL_NUMBER_UNDEFINED].
+ */
+ private fun FakeCommunalWidgetItemV1.getV2(): FakeCommunalWidgetItemV2 {
+ return FakeCommunalWidgetItemV2(
+ widgetId,
+ componentName,
+ itemId,
+ CommunalWidgetItem.USER_SERIAL_NUMBER_UNDEFINED,
+ )
+ }
+
+ private data class FakeCommunalWidgetItemV1(
+ val widgetId: Int,
+ val componentName: String,
+ val itemId: Int,
+ )
+
+ private data class FakeCommunalWidgetItemV2(
+ val widgetId: Int,
+ val componentName: String,
+ val itemId: Int,
+ val userSerialNumber: Int,
+ )
+
+ companion object {
+ private const val DATABASE_NAME = "communal_db"
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/data/db/CommunalWidgetDaoTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/data/db/CommunalWidgetDaoTest.kt
index f77c7a672ae3..d6705085eafd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/data/db/CommunalWidgetDaoTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/communal/data/db/CommunalWidgetDaoTest.kt
@@ -67,11 +67,12 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
@Test
fun addWidget_readValueInDb() =
testScope.runTest {
- val (widgetId, provider, priority) = widgetInfo1
+ val (widgetId, provider, priority, userSerialNumber) = widgetInfo1
communalWidgetDao.addWidget(
widgetId = widgetId,
provider = provider,
priority = priority,
+ userSerialNumber = userSerialNumber,
)
val entry = communalWidgetDao.getWidgetByIdNow(id = 1)
assertThat(entry).isEqualTo(communalWidgetItemEntry1)
@@ -80,11 +81,12 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
@Test
fun deleteWidget_notInDb_returnsFalse() =
testScope.runTest {
- val (widgetId, provider, priority) = widgetInfo1
+ val (widgetId, provider, priority, userSerialNumber) = widgetInfo1
communalWidgetDao.addWidget(
widgetId = widgetId,
provider = provider,
priority = priority,
+ userSerialNumber = userSerialNumber,
)
assertThat(communalWidgetDao.deleteWidgetById(widgetId = 123)).isFalse()
}
@@ -95,11 +97,12 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
val widgetsToAdd = listOf(widgetInfo1, widgetInfo2)
val widgets = collectLastValue(communalWidgetDao.getWidgets())
widgetsToAdd.forEach {
- val (widgetId, provider, priority) = it
+ val (widgetId, provider, priority, userSerialNumber) = it
communalWidgetDao.addWidget(
widgetId = widgetId,
provider = provider,
priority = priority,
+ userSerialNumber = userSerialNumber
)
}
assertThat(widgets())
@@ -118,11 +121,12 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
val widgets = collectLastValue(communalWidgetDao.getWidgets())
widgetsToAdd.forEach {
- val (widgetId, provider, priority) = it
+ val (widgetId, provider, priority, userSerialNumber) = it
communalWidgetDao.addWidget(
widgetId = widgetId,
provider = provider,
priority = priority,
+ userSerialNumber = userSerialNumber,
)
}
assertThat(widgets())
@@ -144,11 +148,12 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
val widgets = collectLastValue(communalWidgetDao.getWidgets())
widgetsToAdd.forEach {
- val (widgetId, provider, priority) = it
+ val (widgetId, provider, priority, userSerialNumber) = it
communalWidgetDao.addWidget(
widgetId = widgetId,
provider = provider,
priority = priority,
+ userSerialNumber = userSerialNumber,
)
}
assertThat(widgets())
@@ -180,11 +185,12 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
val widgets = collectLastValue(communalWidgetDao.getWidgets())
existingWidgets.forEach {
- val (widgetId, provider, priority) = it
+ val (widgetId, provider, priority, userSerialNumber) = it
communalWidgetDao.addWidget(
widgetId = widgetId,
provider = provider,
priority = priority,
+ userSerialNumber = userSerialNumber,
)
}
assertThat(widgets())
@@ -212,6 +218,7 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
widgetId = widgetInfo3.widgetId,
provider = widgetInfo3.provider,
priority = 2,
+ userSerialNumber = widgetInfo3.userSerialNumber,
)
assertThat(widgets())
.containsExactly(
@@ -246,6 +253,7 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
widgetId = fakeWidget.widgetId,
componentName = fakeWidget.componentName,
itemId = rank.uid,
+ userSerialNumber = fakeWidget.userSerialNumber,
)
expected[rank] = widget
}
@@ -258,13 +266,15 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
widgetId = metadata.widgetId,
provider = metadata.provider,
priority = priority ?: metadata.priority,
+ userSerialNumber = metadata.userSerialNumber,
)
}
data class FakeWidgetMetadata(
val widgetId: Int,
val provider: ComponentName,
- val priority: Int
+ val priority: Int,
+ val userSerialNumber: Int,
)
companion object {
@@ -272,19 +282,22 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
FakeWidgetMetadata(
widgetId = 1,
provider = ComponentName("pk_name", "cls_name_1"),
- priority = 1
+ priority = 1,
+ userSerialNumber = 0,
)
val widgetInfo2 =
FakeWidgetMetadata(
widgetId = 2,
provider = ComponentName("pk_name", "cls_name_2"),
- priority = 2
+ priority = 2,
+ userSerialNumber = 0,
)
val widgetInfo3 =
FakeWidgetMetadata(
widgetId = 3,
provider = ComponentName("pk_name", "cls_name_3"),
- priority = 3
+ priority = 3,
+ userSerialNumber = 10,
)
val communalItemRankEntry1 = CommunalItemRank(uid = 1L, rank = widgetInfo1.priority)
val communalItemRankEntry2 = CommunalItemRank(uid = 2L, rank = widgetInfo2.priority)
@@ -295,6 +308,7 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
widgetId = widgetInfo1.widgetId,
componentName = widgetInfo1.provider.flattenToString(),
itemId = communalItemRankEntry1.uid,
+ userSerialNumber = widgetInfo1.userSerialNumber,
)
val communalWidgetItemEntry2 =
CommunalWidgetItem(
@@ -302,6 +316,7 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
widgetId = widgetInfo2.widgetId,
componentName = widgetInfo2.provider.flattenToString(),
itemId = communalItemRankEntry2.uid,
+ userSerialNumber = widgetInfo2.userSerialNumber,
)
val communalWidgetItemEntry3 =
CommunalWidgetItem(
@@ -309,6 +324,7 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
widgetId = widgetInfo3.widgetId,
componentName = widgetInfo3.provider.flattenToString(),
itemId = communalItemRankEntry3.uid,
+ userSerialNumber = widgetInfo3.userSerialNumber,
)
val fakeState =
CommunalHubState().apply {
@@ -318,11 +334,13 @@ class CommunalWidgetDaoTest : SysuiTestCase() {
widgetId = 1
componentName = "pk_name/fake_widget_1"
rank = 1
+ userSerialNumber = 0
},
CommunalHubState.CommunalWidgetItem().apply {
widgetId = 2
componentName = "pk_name/fake_widget_2"
rank = 2
+ userSerialNumber = 10
},
)
.toTypedArray()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
index 431fef65e95b..6fd866066879 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
@@ -24,6 +24,7 @@ import android.hardware.fingerprint.FingerprintManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.FaceHelpMessageDebouncer
import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
import com.android.systemui.biometrics.domain.faceHelpMessageDeferral
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
@@ -45,6 +46,7 @@ import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
@@ -264,11 +266,20 @@ class BiometricMessageInteractorTest : SysuiTestCase() {
biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
- // WHEN authentication status help
+ // WHEN authentication status help past debouncer
+ faceAuthRepository.setAuthenticationStatus(
+ HelpFaceAuthenticationStatus(
+ msg = "Move left",
+ msgId = FACE_ACQUIRED_TOO_RIGHT,
+ createdAt = 0L,
+ )
+ )
+ runCurrent()
faceAuthRepository.setAuthenticationStatus(
HelpFaceAuthenticationStatus(
msg = "Move left",
msgId = FACE_ACQUIRED_TOO_RIGHT,
+ createdAt = FaceHelpMessageDebouncer.DEFAULT_WINDOW_MS,
)
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
index 529cd6ea8ddc..0b7a3ed3a7c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
@@ -90,6 +90,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
private val keyguardUpdateMonitor = kosmos.keyguardUpdateMonitor
private val faceWakeUpTriggersConfig = kosmos.fakeFaceWakeUpTriggersConfig
private val trustManager = kosmos.trustManager
+ private val deviceEntryFaceAuthStatusInteractor = kosmos.deviceEntryFaceAuthStatusInteractor
@Before
fun setup() {
@@ -112,6 +113,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
powerInteractor,
fakeBiometricSettingsRepository,
trustManager,
+ deviceEntryFaceAuthStatusInteractor,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorTest.kt
new file mode 100644
index 000000000000..6022d9cfcbfd
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorTest.kt
@@ -0,0 +1,160 @@
+/*
+ * 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.deviceentry.domain.interactor
+
+import android.hardware.biometrics.BiometricFaceConstants
+import android.hardware.face.FaceManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.FaceHelpMessageDebouncer.Companion.DEFAULT_WINDOW_MS
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.shared.model.AcquiredFaceAuthenticationStatus
+import com.android.systemui.deviceentry.shared.model.ErrorFaceAuthenticationStatus
+import com.android.systemui.deviceentry.shared.model.FailedFaceAuthenticationStatus
+import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus
+import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DeviceEntryFaceAuthStatusInteractorTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope: TestScope = kosmos.testScope
+ private lateinit var underTest: DeviceEntryFaceAuthStatusInteractor
+ private val ignoreHelpMessageId = 1
+
+ @Before
+ fun setup() {
+ overrideResource(
+ R.array.config_face_acquire_device_entry_ignorelist,
+ intArrayOf(ignoreHelpMessageId)
+ )
+ underTest = kosmos.deviceEntryFaceAuthStatusInteractor
+ }
+
+ @Test
+ fun successAuthenticationStatus() =
+ testScope.runTest {
+ val authenticationStatus by collectLastValue(underTest.authenticationStatus)
+ val successStatus =
+ SuccessFaceAuthenticationStatus(
+ successResult = mock(FaceManager.AuthenticationResult::class.java)
+ )
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(successStatus)
+ assertThat(authenticationStatus).isEqualTo(successStatus)
+ }
+
+ @Test
+ fun acquiredFaceAuthenticationStatus() =
+ testScope.runTest {
+ val authenticationStatus by collectLastValue(underTest.authenticationStatus)
+ val acquiredStatus = AcquiredFaceAuthenticationStatus(acquiredInfo = 0)
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(acquiredStatus)
+ assertThat(authenticationStatus).isEqualTo(acquiredStatus)
+ }
+
+ @Test
+ fun failedFaceAuthenticationStatus() =
+ testScope.runTest {
+ val authenticationStatus by collectLastValue(underTest.authenticationStatus)
+ val failedStatus = FailedFaceAuthenticationStatus()
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(failedStatus)
+ assertThat(authenticationStatus).isEqualTo(failedStatus)
+ }
+
+ @Test
+ fun errorFaceAuthenticationStatus() =
+ testScope.runTest {
+ val authenticationStatus by collectLastValue(underTest.authenticationStatus)
+ val errorStatus = ErrorFaceAuthenticationStatus(0, "test")
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(errorStatus)
+ assertThat(authenticationStatus).isEqualTo(errorStatus)
+ }
+
+ @Test
+ fun firstHelpFaceAuthenticationStatus_noUpdate() =
+ testScope.runTest {
+ val authenticationStatus by collectLastValue(underTest.authenticationStatus)
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(
+ AcquiredFaceAuthenticationStatus(
+ BiometricFaceConstants.FACE_ACQUIRED_START,
+ createdAt = 0
+ )
+ )
+ val helpMessage = HelpFaceAuthenticationStatus(0, "test", 1)
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(helpMessage)
+ assertThat(authenticationStatus).isNull()
+ }
+
+ @Test
+ fun helpFaceAuthenticationStatus_afterWindow() =
+ testScope.runTest {
+ val authenticationStatus by collectLastValue(underTest.authenticationStatus)
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(
+ HelpFaceAuthenticationStatus(0, "test1", 0)
+ )
+ runCurrent()
+ val helpMessage = HelpFaceAuthenticationStatus(0, "test2", DEFAULT_WINDOW_MS)
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(helpMessage)
+ runCurrent()
+ assertThat(authenticationStatus).isEqualTo(helpMessage)
+ }
+
+ @Test
+ fun helpFaceAuthenticationStatus_onlyIgnoredHelpMessages_afterWindow() =
+ testScope.runTest {
+ val authenticationStatus by collectLastValue(underTest.authenticationStatus)
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(
+ HelpFaceAuthenticationStatus(ignoreHelpMessageId, "ignoredMsg", 0)
+ )
+ runCurrent()
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(
+ HelpFaceAuthenticationStatus(ignoreHelpMessageId, "ignoredMsg", DEFAULT_WINDOW_MS)
+ )
+ runCurrent()
+ assertThat(authenticationStatus).isNull()
+ }
+
+ @Test
+ fun helpFaceAuthenticationStatus_afterWindow_onIgnoredMessage_showsOtherMessageInstead() =
+ testScope.runTest {
+ val authenticationStatus by collectLastValue(underTest.authenticationStatus)
+ val validHelpMessage = HelpFaceAuthenticationStatus(0, "validHelpMsg", 0)
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(validHelpMessage)
+ runCurrent()
+ // help message that should be ignored
+ kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(
+ HelpFaceAuthenticationStatus(ignoreHelpMessageId, "ignoredMsg", DEFAULT_WINDOW_MS)
+ )
+ runCurrent()
+ assertThat(authenticationStatus).isEqualTo(validHelpMessage)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
index 1c327aff9a3d..20cb1e129f49 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
@@ -20,6 +20,7 @@ import android.hardware.display.DisplayManager
import android.os.Looper
import android.testing.TestableLooper
import android.view.Display
+import android.view.Display.DEFAULT_DISPLAY
import android.view.Display.TYPE_EXTERNAL
import android.view.Display.TYPE_INTERNAL
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -27,7 +28,6 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.FlowValue
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.kotlinArgumentCaptor
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -45,6 +45,7 @@ import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
+import org.mockito.kotlin.eq
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@@ -58,13 +59,15 @@ class DisplayRepositoryTest : SysuiTestCase() {
private val testHandler = FakeHandler(Looper.getMainLooper())
private val testScope = TestScope(UnconfinedTestDispatcher())
+ private val defaultDisplay =
+ display(type = TYPE_INTERNAL, id = DEFAULT_DISPLAY, state = Display.STATE_ON)
private lateinit var displayRepository: DisplayRepositoryImpl
@Before
fun setup() {
- setDisplays(emptyList())
- setAllDisplaysIncludingDisabled()
+ setDisplays(listOf(defaultDisplay))
+ setAllDisplaysIncludingDisabled(DEFAULT_DISPLAY)
displayRepository =
DisplayRepositoryImpl(
displayManager,
@@ -81,7 +84,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
testScope.runTest {
val value by latestDisplayFlowValue()
- assertThat(value).isEmpty()
+ assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY)
verify(displayManager).registerDisplayListener(any(), eq(testHandler), anyLong())
}
@@ -91,7 +94,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
testScope.runTest {
val value by latestDisplayFlowValue()
- assertThat(value).isEmpty()
+ assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY)
verify(displayManager).registerDisplayListener(any(), eq(testHandler), anyLong())
}
@@ -103,14 +106,14 @@ class DisplayRepositoryTest : SysuiTestCase() {
testScope.runTest {
val firstSubscriber by latestDisplayFlowValue()
- assertThat(firstSubscriber).isEmpty()
+ assertThat(firstSubscriber).hasSize(1) // Default display only
verify(displayManager, times(1))
.registerDisplayListener(displayListener.capture(), eq(testHandler), anyLong())
val innerScope = TestScope()
innerScope.runTest {
val secondSubscriber by latestDisplayFlowValue()
- assertThat(secondSubscriber).isEmpty()
+ assertThat(secondSubscriber).hasSize(1)
// No new registration, just the precedent one.
verify(displayManager, times(1))
@@ -120,7 +123,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
// Let's make sure it has *NOT* been unregistered, as there is still a subscriber.
setDisplays(1)
sendOnDisplayAdded(1)
- assertThat(firstSubscriber?.ids()).containsExactly(1)
+ assertThat(firstSubscriber?.ids()).contains(1)
}
// All subscribers are done, unregister should have been called.
@@ -135,7 +138,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
setDisplays(1)
sendOnDisplayAdded(1)
- assertThat(value?.ids()).containsExactly(1)
+ assertThat(value?.ids()).contains(1)
}
@Test
@@ -152,7 +155,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
setDisplays(1, 2, 3)
sendOnDisplayRemoved(4)
- assertThat(value?.ids()).containsExactly(1, 2, 3)
+ assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY, 1, 2, 3)
}
@Test
@@ -168,7 +171,7 @@ class DisplayRepositoryTest : SysuiTestCase() {
displayListener.value.onDisplayChanged(4)
- assertThat(value?.ids()).containsExactly(1, 2, 3, 4)
+ assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY, 1, 2, 3, 4)
}
@Test
@@ -433,39 +436,24 @@ class DisplayRepositoryTest : SysuiTestCase() {
fun defaultDisplayOff_changes() =
testScope.runTest {
val defaultDisplayOff by latestDefaultDisplayOffFlowValue()
- setDisplays(
- listOf(
- display(
- type = TYPE_INTERNAL,
- id = Display.DEFAULT_DISPLAY,
- state = Display.STATE_OFF
- )
- )
- )
- displayListener.value.onDisplayChanged(Display.DEFAULT_DISPLAY)
+
+ whenever(defaultDisplay.state).thenReturn(Display.STATE_OFF)
+ displayListener.value.onDisplayChanged(DEFAULT_DISPLAY)
assertThat(defaultDisplayOff).isTrue()
- setDisplays(
- listOf(
- display(
- type = TYPE_INTERNAL,
- id = Display.DEFAULT_DISPLAY,
- state = Display.STATE_ON
- )
- )
- )
- displayListener.value.onDisplayChanged(Display.DEFAULT_DISPLAY)
+ whenever(defaultDisplay.state).thenReturn(Display.STATE_ON)
+ displayListener.value.onDisplayChanged(DEFAULT_DISPLAY)
assertThat(defaultDisplayOff).isFalse()
}
@Test
fun displayFlow_startsWithDefaultDisplayBeforeAnyEvent() =
testScope.runTest {
- setDisplays(Display.DEFAULT_DISPLAY)
+ setDisplays(DEFAULT_DISPLAY)
val value by latestDisplayFlowValue()
- assertThat(value?.ids()).containsExactly(Display.DEFAULT_DISPLAY)
+ assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY)
}
private fun Iterable<Display>.ids(): List<Int> = map { it.displayId }
@@ -552,7 +540,10 @@ class DisplayRepositoryTest : SysuiTestCase() {
}
private fun setAllDisplaysIncludingDisabled(vararg ids: Int) {
- val displays = ids.map { display(type = TYPE_EXTERNAL, id = it) }.toTypedArray()
+ val displays =
+ (ids.toSet() - DEFAULT_DISPLAY) // Default display always added.
+ .map { display(type = TYPE_EXTERNAL, id = it) }
+ .toTypedArray() + defaultDisplay
whenever(
displayManager.getDisplays(
eq(DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)
@@ -565,6 +556,8 @@ class DisplayRepositoryTest : SysuiTestCase() {
}
private fun setDisplays(vararg ids: Int) {
- setDisplays(ids.map { display(type = TYPE_EXTERNAL, id = it) })
+ // DEFAULT_DISPLAY always there
+ val idsToSet = ids.toSet() + DEFAULT_DISPLAY
+ setDisplays(idsToSet.map { display(type = TYPE_EXTERNAL, id = it) })
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
index e2cca3873bf7..ae635b8cbfd4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
@@ -41,7 +41,6 @@ import android.media.AudioManager;
import android.os.Handler;
import android.os.UserManager;
import android.provider.Settings;
-import android.service.dreams.IDreamManager;
import android.testing.TestableLooper;
import android.view.GestureDetector;
import android.view.IWindowManager;
@@ -106,7 +105,6 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
@Mock private GlobalActions.GlobalActionsManager mWindowManagerFuncs;
@Mock private AudioManager mAudioManager;
- @Mock private IDreamManager mDreamManager;
@Mock private DevicePolicyManager mDevicePolicyManager;
@Mock private LockPatternUtils mLockPatternUtils;
@Mock private BroadcastDispatcher mBroadcastDispatcher;
@@ -165,7 +163,6 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
mGlobalActionsDialogLite = new GlobalActionsDialogLite(mContext,
mWindowManagerFuncs,
mAudioManager,
- mDreamManager,
mDevicePolicyManager,
mLockPatternUtils,
mBroadcastDispatcher,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
index 53bcf865b829..361e768a5b51 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
@@ -20,6 +20,7 @@ package com.android.systemui.keyboard.data.repository
import android.hardware.input.InputManager
import android.hardware.input.InputManager.KeyboardBacklightListener
import android.hardware.input.KeyboardBacklightState
+import android.testing.TestableLooper
import android.view.InputDevice
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -27,11 +28,13 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.FlowValue
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository
import com.android.systemui.keyboard.data.model.Keyboard
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.mockito.whenever
+import com.android.systemui.utils.os.FakeHandler
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -53,6 +56,7 @@ import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
+@TestableLooper.RunWithLooper
@RunWith(AndroidJUnit4::class)
class KeyboardRepositoryTest : SysuiTestCase() {
@@ -63,6 +67,7 @@ class KeyboardRepositoryTest : SysuiTestCase() {
private lateinit var underTest: KeyboardRepository
private lateinit var dispatcher: CoroutineDispatcher
+ private lateinit var inputDeviceRepo: InputDeviceRepository
private lateinit var testScope: TestScope
@Before
@@ -75,7 +80,9 @@ class KeyboardRepositoryTest : SysuiTestCase() {
}
dispatcher = StandardTestDispatcher()
testScope = TestScope(dispatcher)
- underTest = KeyboardRepositoryImpl(testScope.backgroundScope, dispatcher, inputManager)
+ val handler = FakeHandler(TestableLooper.get(this).looper)
+ inputDeviceRepo = InputDeviceRepository(handler, testScope.backgroundScope, inputManager)
+ underTest = KeyboardRepositoryImpl(dispatcher, inputManager, inputDeviceRepo)
}
@Test
@@ -363,6 +370,7 @@ class KeyboardRepositoryTest : SysuiTestCase() {
private val maxBrightnessLevel: Int
) : KeyboardBacklightState() {
override fun getBrightnessLevel() = brightnessLevel
+
override fun getMaxBrightnessLevel() = maxBrightnessLevel
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt
index 6985439f0552..14837f219862 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt
@@ -16,18 +16,18 @@
package com.android.systemui.keyboard.shortcut.data.repository
-import android.view.KeyEvent
-import android.view.KeyboardShortcutGroup
-import android.view.KeyboardShortcutInfo
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.keyboard.shortcut.shared.model.Shortcut
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
-import com.android.systemui.keyboard.shortcut.shared.model.shortcutCategory
+import com.android.systemui.keyboard.shortcut.data.source.FakeKeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts
+import com.android.systemui.keyboard.shortcut.shortcutHelperAppCategoriesShortcutsSource
import com.android.systemui.keyboard.shortcut.shortcutHelperCategoriesRepository
+import com.android.systemui.keyboard.shortcut.shortcutHelperCurrentAppShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperInputShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperMultiTaskingShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperSystemShortcutsSource
import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
@@ -36,95 +36,55 @@ import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class ShortcutHelperCategoriesRepositoryTest : SysuiTestCase() {
- @OptIn(ExperimentalCoroutinesApi::class)
- private val kosmos = testKosmos().also { it.testDispatcher = UnconfinedTestDispatcher() }
+
+ private val fakeSystemSource = FakeKeyboardShortcutGroupsSource()
+ private val fakeMultiTaskingSource = FakeKeyboardShortcutGroupsSource()
+
+ private val kosmos =
+ testKosmos().also {
+ it.testDispatcher = UnconfinedTestDispatcher()
+ it.shortcutHelperSystemShortcutsSource = fakeSystemSource
+ it.shortcutHelperMultiTaskingShortcutsSource = fakeMultiTaskingSource
+ it.shortcutHelperAppCategoriesShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ it.shortcutHelperInputShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ it.shortcutHelperCurrentAppShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ }
+
private val repo = kosmos.shortcutHelperCategoriesRepository
private val helper = kosmos.shortcutHelperTestHelper
private val testScope = kosmos.testScope
- @Test
- fun stateActive_imeShortcuts_shortcutInfoCorrectlyConverted() =
- testScope.runTest {
- helper.setImeShortcuts(imeShortcutsGroupWithPreviousLanguageSwitchShortcut)
- val imeShortcutCategory by collectLastValue(repo.imeShortcutsCategory)
-
- helper.showFromActivity()
-
- assertThat(imeShortcutCategory)
- .isEqualTo(expectedImeShortcutCategoryWithPreviousLanguageSwitchShortcut)
- }
+ @Before
+ fun setUp() {
+ fakeSystemSource.setGroups(TestShortcuts.systemGroups)
+ fakeMultiTaskingSource.setGroups(TestShortcuts.multitaskingGroups)
+ }
@Test
- fun stateActive_imeShortcuts_discardUnsupportedShortcutInfoModifiers() =
+ fun categories_multipleSubscribers_replaysExistingValueToNewSubscribers() =
testScope.runTest {
- helper.setImeShortcuts(imeShortcutsGroupWithUnsupportedShortcutModifiers)
- val imeShortcutCategory by collectLastValue(repo.imeShortcutsCategory)
-
+ fakeSystemSource.setGroups(TestShortcuts.systemGroups)
+ fakeMultiTaskingSource.setGroups(TestShortcuts.multitaskingGroups)
helper.showFromActivity()
-
- assertThat(imeShortcutCategory)
- .isEqualTo(expectedImeShortcutCategoryWithDiscardedUnsupportedShortcuts)
+ val firstCategories by collectLastValue(repo.categories)
+
+ // Intentionally change shortcuts now. This simulates "current app" shortcuts changing
+ // when our helper is shown.
+ // We still want to return the shortcuts that were returned before our helper was
+ // showing.
+ fakeSystemSource.setGroups(emptyList())
+
+ val secondCategories by collectLastValue(repo.categories)
+ // Make sure the second subscriber receives the same value as the first subscriber, even
+ // though fetching shortcuts again would have returned a new result.
+ assertThat(secondCategories).isEqualTo(firstCategories)
}
-
- private val switchToPreviousLanguageCommand =
- ShortcutCommand(
- listOf(KeyEvent.META_CTRL_ON, KeyEvent.META_SHIFT_ON, KeyEvent.KEYCODE_SPACE)
- )
-
- private val expectedImeShortcutCategoryWithDiscardedUnsupportedShortcuts =
- shortcutCategory(ShortcutCategoryType.IME) { subCategory("input", emptyList()) }
-
- private val switchToPreviousLanguageKeyboardShortcutInfo =
- KeyboardShortcutInfo(
- /* label = */ "switch to previous language",
- /* keycode = */ switchToPreviousLanguageCommand.keyCodes[2],
- /* modifiers = */ switchToPreviousLanguageCommand.keyCodes[0] or
- switchToPreviousLanguageCommand.keyCodes[1],
- )
-
- private val expectedImeShortcutCategoryWithPreviousLanguageSwitchShortcut =
- shortcutCategory(ShortcutCategoryType.IME) {
- subCategory(
- "input",
- listOf(
- Shortcut(
- switchToPreviousLanguageKeyboardShortcutInfo.label!!.toString(),
- listOf(switchToPreviousLanguageCommand)
- )
- )
- )
- }
-
- private val imeShortcutsGroupWithPreviousLanguageSwitchShortcut =
- listOf(
- KeyboardShortcutGroup(
- "input",
- listOf(
- switchToPreviousLanguageKeyboardShortcutInfo,
- )
- )
- )
-
- private val shortcutInfoWithUnsupportedModifier =
- KeyboardShortcutInfo(
- /* label = */ "unsupported shortcut",
- /* keycode = */ KeyEvent.KEYCODE_SPACE,
- /* modifiers = */ 32
- )
-
- private val imeShortcutsGroupWithUnsupportedShortcutModifiers =
- listOf(
- KeyboardShortcutGroup(
- "input",
- listOf(
- shortcutInfoWithUnsupportedModifier,
- )
- )
- )
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperStateRepositoryTest.kt
index 3caa8f6cd138..0b4e6a289f0e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperStateRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperStateRepositoryTest.kt
@@ -65,17 +65,6 @@ class ShortcutHelperStateRepositoryTest : SysuiTestCase() {
}
@Test
- fun state_activeThroughActivity_virtualKeyboardActive_emitsActiveWithVirtualDeviceId() =
- testScope.runTest {
- val state by collectLastValue(repo.state)
-
- fakeInputManager.addVirtualKeyboard()
- helper.showFromActivity()
-
- assertThat(state).isEqualTo(ShortcutHelperState.Active(VIRTUAL_KEYBOARD))
- }
-
- @Test
fun state_activeThroughActivity_physicalKeyboardActive_emitsActiveWithDeviceId() =
testScope.runTest {
val deviceId = 456
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSourceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSourceTest.kt
new file mode 100644
index 000000000000..5d592087527c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSourceTest.kt
@@ -0,0 +1,81 @@
+/*
+ * 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.keyboard.shortcut.data.source
+
+import android.view.KeyEvent
+import android.view.KeyboardShortcutGroup
+import android.view.KeyboardShortcutInfo
+import android.view.mockWindowManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AppCategoriesShortcutsSourceTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val mockWindowManager = kosmos.mockWindowManager
+ private val source =
+ AppCategoriesShortcutsSource(kosmos.mockWindowManager, kosmos.testDispatcher)
+
+ private var appCategoriesGroup: KeyboardShortcutGroup? = null
+
+ @Before
+ fun setUp() {
+ whenever(mockWindowManager.getApplicationLaunchKeyboardShortcuts(TEST_DEVICE_ID))
+ .thenAnswer { appCategoriesGroup }
+ }
+
+ @Test
+ fun shortcutGroups_nullResult_returnsEmptyList() =
+ testScope.runTest {
+ appCategoriesGroup = null
+
+ assertThat(source.shortcutGroups(TEST_DEVICE_ID)).isEmpty()
+ }
+
+ @Test
+ fun shortcutGroups_returnsSortedList() =
+ testScope.runTest {
+ val testItems =
+ listOf(
+ KeyboardShortcutInfo("Info 2", KeyEvent.KEYCODE_E, KeyEvent.META_META_ON),
+ KeyboardShortcutInfo("Info 1", KeyEvent.KEYCODE_E, KeyEvent.META_META_ON),
+ KeyboardShortcutInfo("Info 3", KeyEvent.KEYCODE_E, KeyEvent.META_META_ON),
+ )
+ appCategoriesGroup = KeyboardShortcutGroup("Test Group", testItems)
+
+ val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items
+ val shortcutLabels = shortcuts.map { it.label.toString() }
+ assertThat(shortcutLabels).containsExactly("Info 1", "Info 2", "Info 3").inOrder()
+ }
+
+ companion object {
+ private const val TEST_DEVICE_ID = 123
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
new file mode 100644
index 000000000000..c9c39b3ebf66
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
@@ -0,0 +1,290 @@
+/*
+ * 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.keyboard.shortcut.data.source
+
+import android.view.KeyEvent
+import android.view.KeyboardShortcutGroup
+import android.view.KeyboardShortcutInfo
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
+import com.android.systemui.keyboard.shortcut.shared.model.shortcut
+import com.android.systemui.res.R
+
+object TestShortcuts {
+
+ private val shortcutInfoWithRepeatedLabel =
+ KeyboardShortcutInfo(
+ /* label = */ "Shortcut with repeated label",
+ /* keycode = */ KeyEvent.KEYCODE_H,
+ /* modifiers = */ KeyEvent.META_META_ON,
+ )
+
+ private val shortcutInfoWithRepeatedLabelAlternate =
+ KeyboardShortcutInfo(
+ /* label = */ shortcutInfoWithRepeatedLabel.label,
+ /* keycode = */ KeyEvent.KEYCODE_L,
+ /* modifiers = */ KeyEvent.META_META_ON,
+ )
+
+ private val shortcutInfoWithRepeatedLabelSecondAlternate =
+ KeyboardShortcutInfo(
+ /* label = */ shortcutInfoWithRepeatedLabel.label,
+ /* keycode = */ KeyEvent.KEYCODE_M,
+ /* modifiers = */ KeyEvent.META_SHIFT_ON,
+ )
+
+ private val shortcutWithGroupedRepeatedLabel =
+ shortcut(shortcutInfoWithRepeatedLabel.label!!.toString()) {
+ command {
+ key(R.drawable.ic_ksh_key_meta)
+ key("H")
+ }
+ command {
+ key(R.drawable.ic_ksh_key_meta)
+ key("L")
+ }
+ command {
+ key("Shift")
+ key("M")
+ }
+ }
+
+ private val standardShortcutInfo1 =
+ KeyboardShortcutInfo(
+ /* label = */ "Standard shortcut 1",
+ /* keycode = */ KeyEvent.KEYCODE_N,
+ /* modifiers = */ KeyEvent.META_META_ON,
+ )
+
+ private val standardShortcut1 =
+ shortcut(standardShortcutInfo1.label!!.toString()) {
+ command {
+ key(R.drawable.ic_ksh_key_meta)
+ key("N")
+ }
+ }
+
+ private val standardShortcutInfo2 =
+ KeyboardShortcutInfo(
+ /* label = */ "Standard shortcut 2",
+ /* keycode = */ KeyEvent.KEYCODE_Z,
+ /* modifiers = */ KeyEvent.META_ALT_ON or KeyEvent.META_SHIFT_ON,
+ )
+
+ private val standardShortcut2 =
+ shortcut(standardShortcutInfo2.label!!.toString()) {
+ command {
+ key("Alt")
+ key("Shift")
+ key("Z")
+ }
+ }
+
+ private val standardShortcutInfo3 =
+ KeyboardShortcutInfo(
+ /* label = */ "Standard shortcut 3",
+ /* keycode = */ KeyEvent.KEYCODE_J,
+ /* modifiers = */ KeyEvent.META_CTRL_ON,
+ )
+
+ private val standardShortcut3 =
+ shortcut(standardShortcutInfo3.label!!.toString()) {
+ command {
+ key("Ctrl")
+ key("J")
+ }
+ }
+
+ private val shortcutInfoWithUnsupportedModifiers =
+ KeyboardShortcutInfo(
+ /* label = */ "Shortcut with unsupported modifiers",
+ /* keycode = */ KeyEvent.KEYCODE_A,
+ /* modifiers = */ KeyEvent.META_META_ON or KeyEvent.KEYCODE_SPACE,
+ )
+
+ private val groupWithRepeatedShortcutLabels =
+ KeyboardShortcutGroup(
+ "Group with duplicate labels",
+ listOf(
+ shortcutInfoWithRepeatedLabel,
+ shortcutInfoWithRepeatedLabelAlternate,
+ shortcutInfoWithRepeatedLabelSecondAlternate
+ )
+ )
+
+ private val subCategoryWithGroupedRepeatedShortcutLabels =
+ ShortcutSubCategory(
+ label = groupWithRepeatedShortcutLabels.label!!.toString(),
+ shortcuts = listOf(shortcutWithGroupedRepeatedLabel)
+ )
+
+ private val groupWithStandardShortcutInfo =
+ KeyboardShortcutGroup("Standard group", listOf(standardShortcutInfo1))
+
+ private val subCategoryWithStandardShortcut =
+ ShortcutSubCategory(
+ label = groupWithStandardShortcutInfo.label!!.toString(),
+ shortcuts = listOf(standardShortcut1)
+ )
+
+ private val groupWithOnlyUnsupportedModifierShortcut =
+ KeyboardShortcutGroup(
+ "Group with unsupported modifiers",
+ listOf(shortcutInfoWithUnsupportedModifiers)
+ )
+
+ private val groupWithSupportedAndUnsupportedModifierShortcut =
+ KeyboardShortcutGroup(
+ "Group with mix of supported and not supported modifiers",
+ listOf(standardShortcutInfo3, shortcutInfoWithUnsupportedModifiers)
+ )
+
+ private val switchToNextLanguageShortcut =
+ shortcut("Switch to next language") {
+ command {
+ key("Ctrl")
+ key("Space")
+ }
+ }
+
+ private val switchToPreviousLanguageShortcut =
+ shortcut("Switch to previous language") {
+ command {
+ key("Ctrl")
+ key("Shift")
+ key("Space")
+ }
+ }
+
+ private val subCategoryForInputLanguageSwitchShortcuts =
+ ShortcutSubCategory(
+ "Input",
+ listOf(switchToNextLanguageShortcut, switchToPreviousLanguageShortcut)
+ )
+
+ private val subCategoryWithUnsupportedShortcutsRemoved =
+ ShortcutSubCategory(
+ groupWithSupportedAndUnsupportedModifierShortcut.label!!.toString(),
+ listOf(standardShortcut3)
+ )
+
+ private val standardGroup1 =
+ KeyboardShortcutGroup(
+ "Standard group 1",
+ listOf(standardShortcutInfo1, standardShortcutInfo2, standardShortcutInfo3)
+ )
+
+ private val standardPackageName1 = "standard.app.group1"
+
+ private val standardAppGroup1 =
+ KeyboardShortcutGroup(
+ "Standard app group 1",
+ listOf(standardShortcutInfo1, standardShortcutInfo2, standardShortcutInfo3)
+ )
+ .apply { packageName = standardPackageName1 }
+
+ private val standardSubCategory1 =
+ ShortcutSubCategory(
+ standardGroup1.label!!.toString(),
+ listOf(standardShortcut1, standardShortcut2, standardShortcut3)
+ )
+
+ private val standardGroup2 =
+ KeyboardShortcutGroup(
+ "Standard group 2",
+ listOf(standardShortcutInfo3, standardShortcutInfo2, standardShortcutInfo1)
+ )
+
+ private val standardSubCategory2 =
+ ShortcutSubCategory(
+ standardGroup2.label!!.toString(),
+ listOf(standardShortcut3, standardShortcut2, standardShortcut1)
+ )
+ private val standardGroup3 =
+ KeyboardShortcutGroup(
+ "Standard group 3",
+ listOf(standardShortcutInfo2, standardShortcutInfo1)
+ )
+
+ private val standardSubCategory3 =
+ ShortcutSubCategory(
+ standardGroup3.label!!.toString(),
+ listOf(standardShortcut2, standardShortcut1)
+ )
+ val imeGroups = listOf(standardGroup1, standardGroup2, standardGroup3)
+ val imeCategory =
+ ShortcutCategory(
+ type = ShortcutCategoryType.InputMethodEditor,
+ subCategories =
+ listOf(
+ subCategoryForInputLanguageSwitchShortcuts,
+ standardSubCategory1,
+ standardSubCategory2,
+ standardSubCategory3
+ )
+ )
+
+ val currentAppGroups = listOf(standardAppGroup1)
+ val currentAppPackageName = standardPackageName1
+
+ val systemGroups = listOf(standardGroup3, standardGroup2, standardGroup1)
+ val systemCategory =
+ ShortcutCategory(
+ type = ShortcutCategoryType.System,
+ subCategories = listOf(standardSubCategory3, standardSubCategory2, standardSubCategory1)
+ )
+
+ val multitaskingGroups = listOf(standardGroup2, standardGroup1)
+ val multitaskingCategory =
+ ShortcutCategory(
+ type = ShortcutCategoryType.MultiTasking,
+ subCategories = listOf(standardSubCategory2, standardSubCategory1)
+ )
+
+ val groupsWithDuplicateShortcutLabels =
+ listOf(groupWithRepeatedShortcutLabels, groupWithStandardShortcutInfo)
+
+ val subCategoriesWithGroupedDuplicatedShortcutLabels =
+ listOf(subCategoryWithGroupedRepeatedShortcutLabels, subCategoryWithStandardShortcut)
+
+ val imeSubCategoriesWithGroupedDuplicatedShortcutLabels =
+ listOf(
+ subCategoryForInputLanguageSwitchShortcuts,
+ subCategoryWithGroupedRepeatedShortcutLabels,
+ subCategoryWithStandardShortcut
+ )
+
+ val groupsWithUnsupportedModifier =
+ listOf(
+ groupWithStandardShortcutInfo,
+ groupWithOnlyUnsupportedModifierShortcut,
+ groupWithSupportedAndUnsupportedModifierShortcut
+ )
+
+ val subCategoriesWithUnsupportedModifiersRemoved =
+ listOf(subCategoryWithStandardShortcut, subCategoryWithUnsupportedShortcutsRemoved)
+
+ val imeSubCategoriesWithUnsupportedModifiersRemoved =
+ listOf(
+ subCategoryForInputLanguageSwitchShortcuts,
+ subCategoryWithStandardShortcut,
+ subCategoryWithUnsupportedShortcutsRemoved
+ )
+
+ val groupsWithOnlyUnsupportedModifiers = listOf(groupWithOnlyUnsupportedModifierShortcut)
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
index 5c7ce3ef1009..57c8b444b922 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
@@ -16,18 +16,19 @@
package com.android.systemui.keyboard.shortcut.domain.interactor
-import android.view.KeyEvent
-import android.view.KeyboardShortcutGroup
-import android.view.KeyboardShortcutInfo
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.keyboard.shortcut.data.source.FakeKeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
-import com.android.systemui.keyboard.shortcut.shared.model.shortcut
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.InputMethodEditor
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.System
+import com.android.systemui.keyboard.shortcut.shortcutHelperAppCategoriesShortcutsSource
import com.android.systemui.keyboard.shortcut.shortcutHelperCategoriesInteractor
+import com.android.systemui.keyboard.shortcut.shortcutHelperCurrentAppShortcutsSource
import com.android.systemui.keyboard.shortcut.shortcutHelperMultiTaskingShortcutsSource
import com.android.systemui.keyboard.shortcut.shortcutHelperSystemShortcutsSource
import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
@@ -38,6 +39,7 @@ import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -45,13 +47,28 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
+ private val systemShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ private val multitaskingShortcutsSource = FakeKeyboardShortcutGroupsSource()
@OptIn(ExperimentalCoroutinesApi::class)
- private val kosmos = testKosmos().also { it.testDispatcher = UnconfinedTestDispatcher() }
+ private val kosmos =
+ testKosmos().also {
+ it.testDispatcher = UnconfinedTestDispatcher()
+ it.shortcutHelperSystemShortcutsSource = systemShortcutsSource
+ it.shortcutHelperMultiTaskingShortcutsSource = multitaskingShortcutsSource
+ it.shortcutHelperAppCategoriesShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ it.shortcutHelperCurrentAppShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ }
+
private val testScope = kosmos.testScope
private val interactor = kosmos.shortcutHelperCategoriesInteractor
private val helper = kosmos.shortcutHelperTestHelper
- private val systemShortcutsSource = kosmos.shortcutHelperSystemShortcutsSource
- private val multitaskingShortcutsSource = kosmos.shortcutHelperMultiTaskingShortcutsSource
+
+ @Before
+ fun setShortcuts() {
+ helper.setImeShortcuts(TestShortcuts.imeGroups)
+ systemShortcutsSource.setGroups(TestShortcuts.systemGroups)
+ multitaskingShortcutsSource.setGroups(TestShortcuts.multitaskingGroups)
+ }
@Test
fun categories_emptyByDefault() =
@@ -64,16 +81,15 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
@Test
fun categories_stateActive_emitsAllCategoriesInOrder() =
testScope.runTest {
- helper.setImeShortcuts(imeShortcutGroups)
val categories by collectLastValue(interactor.shortcutCategories)
helper.showFromActivity()
assertThat(categories)
.containsExactly(
- systemShortcutsSource.systemShortcutsCategory(),
- multitaskingShortcutsSource.multitaskingShortcutCategory(),
- imeShortcutCategory
+ TestShortcuts.systemCategory,
+ TestShortcuts.multitaskingCategory,
+ TestShortcuts.imeCategory,
)
.inOrder()
}
@@ -88,164 +104,162 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
assertThat(categories).isEmpty()
}
- fun categories_stateActive_emitsGroupedShortcuts() =
+ @Test
+ fun categories_stateActive_imeShortcutsWithDuplicateLabels_emitsGroupedShortcuts() =
testScope.runTest {
- helper.setImeShortcuts(imeShortcutsGroupsWithDuplicateLabels)
+ helper.setImeShortcuts(TestShortcuts.groupsWithDuplicateShortcutLabels)
+
val categories by collectLastValue(interactor.shortcutCategories)
helper.showFromActivity()
assertThat(categories)
.containsExactly(
- systemShortcutsSource.systemShortcutsCategory(),
- multitaskingShortcutsSource.multitaskingShortcutCategory(),
- expectedGroupedShortcutCategories
+ TestShortcuts.systemCategory,
+ TestShortcuts.multitaskingCategory,
+ ShortcutCategory(
+ type = InputMethodEditor,
+ subCategories =
+ TestShortcuts.imeSubCategoriesWithGroupedDuplicatedShortcutLabels
+ ),
)
+ .inOrder()
}
- private val switchToNextLanguageShortcut =
- shortcut(label = "switch to next language") {
- command(KeyEvent.META_CTRL_ON, KeyEvent.KEYCODE_SPACE)
- }
+ @Test
+ fun categories_stateActive_systemShortcutsWithDuplicateLabels_emitsGroupedShortcuts() =
+ testScope.runTest {
+ systemShortcutsSource.setGroups(TestShortcuts.groupsWithDuplicateShortcutLabels)
+
+ val categories by collectLastValue(interactor.shortcutCategories)
- private val switchToNextLanguageKeyboardShortcutInfo =
- KeyboardShortcutInfo(
- /* label = */ switchToNextLanguageShortcut.label,
- /* keycode = */ switchToNextLanguageShortcut.commands[0].keyCodes[1],
- /* modifiers = */ switchToNextLanguageShortcut.commands[0].keyCodes[0],
- )
+ helper.showFromActivity()
- private val switchToNextLanguageShortcutAlternative =
- shortcut("switch to next language") {
- command(KeyEvent.META_CTRL_ON, KeyEvent.KEYCODE_SPACE)
+ assertThat(categories)
+ .containsExactly(
+ ShortcutCategory(
+ type = System,
+ subCategories =
+ TestShortcuts.subCategoriesWithGroupedDuplicatedShortcutLabels
+ ),
+ TestShortcuts.multitaskingCategory,
+ TestShortcuts.imeCategory,
+ )
+ .inOrder()
}
- private val switchToNextLanguageKeyboardShortcutInfoAlternative =
- KeyboardShortcutInfo(
- /* label = */ switchToNextLanguageShortcutAlternative.label,
- /* keycode = */ switchToNextLanguageShortcutAlternative.commands[0].keyCodes[1],
- /* modifiers = */ switchToNextLanguageShortcutAlternative.commands[0].keyCodes[0],
- )
-
- private val switchToPreviousLanguageShortcut =
- shortcut("switch to previous language") {
- command(
- KeyEvent.META_SHIFT_ON,
- KeyEvent.KEYCODE_SPACE,
- )
- }
+ @Test
+ fun categories_stateActive_multiTaskingShortcutsWithDuplicateLabels_emitsGroupedShortcuts() =
+ testScope.runTest {
+ multitaskingShortcutsSource.setGroups(TestShortcuts.groupsWithDuplicateShortcutLabels)
- private val switchToPreviousLanguageKeyboardShortcutInfo =
- KeyboardShortcutInfo(
- /* label = */ switchToPreviousLanguageShortcut.label,
- /* keycode = */ switchToPreviousLanguageShortcut.commands[0].keyCodes[1],
- /* modifiers = */ switchToPreviousLanguageShortcut.commands[0].keyCodes[0],
- )
-
- private val switchToPreviousLanguageShortcutAlternative =
- shortcut("switch to previous language") {
- command(
- KeyEvent.META_SHIFT_ON,
- KeyEvent.KEYCODE_SPACE,
- )
- }
+ val categories by collectLastValue(interactor.shortcutCategories)
- private val switchToPreviousLanguageKeyboardShortcutInfoAlternative =
- KeyboardShortcutInfo(
- /* label = */ switchToPreviousLanguageShortcutAlternative.label,
- /* keycode = */ switchToPreviousLanguageShortcutAlternative.commands[0].keyCodes[1],
- /* modifiers = */ switchToPreviousLanguageShortcutAlternative.commands[0].keyCodes[0],
- )
+ helper.showFromActivity()
- private val showOnscreenKeyboardShortcut =
- shortcut(label = "Show on-screen keyboard") {
- command(KeyEvent.META_ALT_ON, KeyEvent.KEYCODE_K)
+ assertThat(categories)
+ .containsExactly(
+ TestShortcuts.systemCategory,
+ ShortcutCategory(
+ type = MultiTasking,
+ subCategories =
+ TestShortcuts.subCategoriesWithGroupedDuplicatedShortcutLabels
+ ),
+ TestShortcuts.imeCategory,
+ )
+ .inOrder()
}
- private val showOnScreenKeyboardShortcutInfo =
- KeyboardShortcutInfo(
- /* label = */ showOnscreenKeyboardShortcut.label,
- /* keycode = */ showOnscreenKeyboardShortcut.commands[0].keyCodes[1],
- /* modifiers = */ showOnscreenKeyboardShortcut.commands[0].keyCodes[0],
- )
-
- private val accessClipboardShortcut =
- shortcut(label = "Access clipboard") { command(KeyEvent.META_ALT_ON, KeyEvent.KEYCODE_V) }
-
- private val accessClipboardShortcutInfo =
- KeyboardShortcutInfo(
- /* label = */ accessClipboardShortcut.label,
- /* keycode = */ accessClipboardShortcut.commands[0].keyCodes[1],
- /* modifiers = */ accessClipboardShortcut.commands[0].keyCodes[0],
- )
-
- private val imeShortcutGroups =
- listOf(
- KeyboardShortcutGroup(
- /* label = */ "input",
- /* shortcutInfoList = */ listOf(
- switchToNextLanguageKeyboardShortcutInfo,
- switchToPreviousLanguageKeyboardShortcutInfo
+ @Test
+ fun categories_stateActive_imeShortcutsWithUnsupportedModifiers_discardUnsupported() =
+ testScope.runTest {
+ helper.setImeShortcuts(TestShortcuts.groupsWithUnsupportedModifier)
+ val categories by collectLastValue(interactor.shortcutCategories)
+
+ helper.showFromActivity()
+
+ assertThat(categories)
+ .containsExactly(
+ TestShortcuts.systemCategory,
+ TestShortcuts.multitaskingCategory,
+ ShortcutCategory(
+ type = InputMethodEditor,
+ subCategories =
+ TestShortcuts.imeSubCategoriesWithUnsupportedModifiersRemoved
+ ),
)
- )
- )
-
- private val imeShortcutCategory =
- ShortcutCategory(
- type = ShortcutCategoryType.IME,
- subCategories =
- listOf(
- ShortcutSubCategory(
- imeShortcutGroups[0].label.toString(),
- listOf(switchToNextLanguageShortcut, switchToPreviousLanguageShortcut)
- )
+ .inOrder()
+ }
+
+ @Test
+ fun categories_stateActive_systemShortcutsWithUnsupportedModifiers_discardUnsupported() =
+ testScope.runTest {
+ systemShortcutsSource.setGroups(TestShortcuts.groupsWithUnsupportedModifier)
+ val categories by collectLastValue(interactor.shortcutCategories)
+
+ helper.showFromActivity()
+
+ assertThat(categories)
+ .containsExactly(
+ ShortcutCategory(
+ type = System,
+ subCategories = TestShortcuts.subCategoriesWithUnsupportedModifiersRemoved
+ ),
+ TestShortcuts.multitaskingCategory,
+ TestShortcuts.imeCategory,
)
- )
-
- private val imeShortcutsGroupsWithDuplicateLabels =
- listOf(
- KeyboardShortcutGroup(
- "input",
- listOf(
- switchToNextLanguageKeyboardShortcutInfo,
- switchToNextLanguageKeyboardShortcutInfoAlternative,
- switchToPreviousLanguageKeyboardShortcutInfo,
- switchToPreviousLanguageKeyboardShortcutInfoAlternative
+ .inOrder()
+ }
+
+ @Test
+ fun categories_stateActive_multitaskingShortcutsWithUnsupportedModifiers_discardUnsupported() =
+ testScope.runTest {
+ multitaskingShortcutsSource.setGroups(TestShortcuts.groupsWithUnsupportedModifier)
+ val categories by collectLastValue(interactor.shortcutCategories)
+
+ helper.showFromActivity()
+
+ assertThat(categories)
+ .containsExactly(
+ TestShortcuts.systemCategory,
+ ShortcutCategory(
+ type = MultiTasking,
+ subCategories = TestShortcuts.subCategoriesWithUnsupportedModifiersRemoved
+ ),
+ TestShortcuts.imeCategory,
)
- ),
- KeyboardShortcutGroup(
- "Gboard",
- listOf(
- showOnScreenKeyboardShortcutInfo,
- accessClipboardShortcutInfo,
+ .inOrder()
+ }
+
+ @Test
+ fun categories_stateActive_systemShortcutsWithOnlyUnsupportedModifiers_discardsCategory() =
+ testScope.runTest {
+ systemShortcutsSource.setGroups(TestShortcuts.groupsWithOnlyUnsupportedModifiers)
+ val categories by collectLastValue(interactor.shortcutCategories)
+
+ helper.showFromActivity()
+
+ assertThat(categories)
+ .containsExactly(
+ TestShortcuts.multitaskingCategory,
+ TestShortcuts.imeCategory,
)
- )
- )
-
- private val expectedGroupedShortcutCategories =
- ShortcutCategory(
- type = ShortcutCategoryType.IME,
- subCategories =
- listOf(
- ShortcutSubCategory(
- imeShortcutsGroupsWithDuplicateLabels[0].label.toString(),
- listOf(
- switchToNextLanguageShortcut.copy(
- commands =
- switchToNextLanguageShortcut.commands +
- switchToNextLanguageShortcutAlternative.commands
- ),
- switchToPreviousLanguageShortcut.copy(
- commands =
- switchToPreviousLanguageShortcut.commands +
- switchToPreviousLanguageShortcutAlternative.commands
- )
- ),
- ),
- ShortcutSubCategory(
- imeShortcutsGroupsWithDuplicateLabels[1].label.toString(),
- listOf(showOnscreenKeyboardShortcut, accessClipboardShortcut),
- )
+ .inOrder()
+ }
+
+ @Test
+ fun categories_stateActive_multitaskingShortcutsWitOnlyUnsupportedModifiers_discardsCategory() =
+ testScope.runTest {
+ multitaskingShortcutsSource.setGroups(TestShortcuts.groupsWithOnlyUnsupportedModifiers)
+ val categories by collectLastValue(interactor.shortcutCategories)
+
+ helper.showFromActivity()
+
+ assertThat(categories)
+ .containsExactly(
+ TestShortcuts.systemCategory,
+ TestShortcuts.imeCategory,
)
- )
+ .inOrder()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperActivityStarterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperActivityStarterTest.kt
index 0757ea156bbf..f8e2f47f939a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperActivityStarterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperActivityStarterTest.kt
@@ -20,8 +20,15 @@ import android.content.Intent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.keyboard.shortcut.data.source.FakeKeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts
import com.android.systemui.keyboard.shortcut.fakeShortcutHelperStartActivity
import com.android.systemui.keyboard.shortcut.shortcutHelperActivityStarter
+import com.android.systemui.keyboard.shortcut.shortcutHelperAppCategoriesShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperCurrentAppShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperInputShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperMultiTaskingShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperSystemShortcutsSource
import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
import com.android.systemui.keyboard.shortcut.ui.view.ShortcutHelperActivity
import com.android.systemui.kosmos.Kosmos
@@ -32,6 +39,7 @@ import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -40,10 +48,18 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ShortcutHelperActivityStarterTest : SysuiTestCase() {
+ private val fakeSystemSource = FakeKeyboardShortcutGroupsSource()
+ private val fakeMultiTaskingSource = FakeKeyboardShortcutGroupsSource()
+
private val kosmos =
Kosmos().also {
it.testCase = this
it.testDispatcher = UnconfinedTestDispatcher()
+ it.shortcutHelperSystemShortcutsSource = fakeSystemSource
+ it.shortcutHelperMultiTaskingShortcutsSource = fakeMultiTaskingSource
+ it.shortcutHelperAppCategoriesShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ it.shortcutHelperInputShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ it.shortcutHelperCurrentAppShortcutsSource = FakeKeyboardShortcutGroupsSource()
}
private val testScope = kosmos.testScope
@@ -51,6 +67,12 @@ class ShortcutHelperActivityStarterTest : SysuiTestCase() {
private val fakeStartActivity = kosmos.fakeShortcutHelperStartActivity
private val starter = kosmos.shortcutHelperActivityStarter
+ @Before
+ fun setUp() {
+ fakeSystemSource.setGroups(TestShortcuts.systemGroups)
+ fakeMultiTaskingSource.setGroups(TestShortcuts.multitaskingGroups)
+ }
+
@Test
fun start_doesNotStartByDefault() =
testScope.runTest {
@@ -70,13 +92,30 @@ class ShortcutHelperActivityStarterTest : SysuiTestCase() {
}
@Test
+ fun start_onToggle_noShortcuts_doesNotStartActivity() =
+ testScope.runTest {
+ fakeSystemSource.setGroups(emptyList())
+ fakeMultiTaskingSource.setGroups(emptyList())
+
+ starter.start()
+
+ testHelper.toggle(deviceId = 456)
+
+ assertThat(fakeStartActivity.startIntents).isEmpty()
+ }
+
+ @Test
fun start_onToggle_multipleTimesStartsActivityOnlyWhenNotStarted() =
testScope.runTest {
starter.start()
+ // Starts
testHelper.toggle(deviceId = 456)
+ // Stops
testHelper.toggle(deviceId = 456)
+ // Starts again
testHelper.toggle(deviceId = 456)
+ // Stops
testHelper.toggle(deviceId = 456)
verifyShortcutHelperActivityStarted(numTimes = 2)
@@ -93,6 +132,18 @@ class ShortcutHelperActivityStarterTest : SysuiTestCase() {
}
@Test
+ fun start_onRequestShowShortcuts_noShortcuts_doesNotStartActivity() =
+ testScope.runTest {
+ fakeSystemSource.setGroups(emptyList())
+ fakeMultiTaskingSource.setGroups(emptyList())
+ starter.start()
+
+ testHelper.showFromActivity()
+
+ assertThat(fakeStartActivity.startIntents).isEmpty()
+ }
+
+ @Test
fun start_onRequestShowShortcuts_multipleTimes_startsActivityOnlyOnce() =
testScope.runTest {
starter.start()
@@ -109,13 +160,21 @@ class ShortcutHelperActivityStarterTest : SysuiTestCase() {
testScope.runTest {
starter.start()
+ // No-op. Already hidden.
testHelper.hideFromActivity()
+ // No-op. Already hidden.
testHelper.hideForSystem()
+ // Show 1st time.
testHelper.toggle(deviceId = 987)
+ // No-op. Already shown.
testHelper.showFromActivity()
+ // Hidden.
testHelper.hideFromActivity()
+ // No-op. Already hidden.
testHelper.hideForSystem()
+ // Show 2nd time.
testHelper.toggle(deviceId = 456)
+ // No-op. Already shown.
testHelper.showFromActivity()
verifyShortcutHelperActivityStarted(numTimes = 2)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
index c985199a97a7..69fc463a576a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
@@ -21,8 +21,17 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
+import com.android.systemui.keyboard.shortcut.data.source.FakeKeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.CurrentApp
+import com.android.systemui.keyboard.shortcut.shortcutHelperAppCategoriesShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperCurrentAppShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperInputShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperMultiTaskingShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperSystemShortcutsSource
import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
import com.android.systemui.keyboard.shortcut.shortcutHelperViewModel
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testDispatcher
@@ -33,6 +42,7 @@ import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -41,10 +51,19 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ShortcutHelperViewModelTest : SysuiTestCase() {
+ private val fakeSystemSource = FakeKeyboardShortcutGroupsSource()
+ private val fakeMultiTaskingSource = FakeKeyboardShortcutGroupsSource()
+ private val fakeCurrentAppsSource = FakeKeyboardShortcutGroupsSource()
+
private val kosmos =
Kosmos().also {
it.testCase = this
it.testDispatcher = UnconfinedTestDispatcher()
+ it.shortcutHelperSystemShortcutsSource = fakeSystemSource
+ it.shortcutHelperMultiTaskingShortcutsSource = fakeMultiTaskingSource
+ it.shortcutHelperAppCategoriesShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ it.shortcutHelperInputShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ it.shortcutHelperCurrentAppShortcutsSource = fakeCurrentAppsSource
}
private val testScope = kosmos.testScope
@@ -52,6 +71,12 @@ class ShortcutHelperViewModelTest : SysuiTestCase() {
private val sysUiState = kosmos.sysUiState
private val viewModel = kosmos.shortcutHelperViewModel
+ @Before
+ fun setUp() {
+ fakeSystemSource.setGroups(TestShortcuts.systemGroups)
+ fakeMultiTaskingSource.setGroups(TestShortcuts.multitaskingGroups)
+ }
+
@Test
fun shouldShow_falseByDefault() =
testScope.runTest {
@@ -163,4 +188,47 @@ class ShortcutHelperViewModelTest : SysuiTestCase() {
assertThat(sysUiState.isFlagEnabled(SYSUI_STATE_SHORTCUT_HELPER_SHOWING)).isFalse()
}
+
+ @Test
+ fun shortcutsUiState_inactiveByDefault() =
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutsUiState)
+
+ assertThat(uiState).isEqualTo(ShortcutsUiState.Inactive)
+ }
+
+ @Test
+ fun shortcutsUiState_featureActive_emitsActive() =
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutsUiState)
+
+ testHelper.showFromActivity()
+
+ assertThat(uiState).isInstanceOf(ShortcutsUiState.Active::class.java)
+ }
+
+ @Test
+ fun shortcutsUiState_featureActive_emitsActiveWithFirstCategorySelectedByDefault() =
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutsUiState)
+
+ testHelper.showFromActivity()
+
+ val activeUiState = uiState as ShortcutsUiState.Active
+ assertThat(activeUiState.defaultSelectedCategory)
+ .isEqualTo(activeUiState.shortcutCategories.first().type)
+ }
+
+ @Test
+ fun shortcutsUiState_featureActive_emitsActiveWithCurrentAppsCategorySelectedWhenPresent() =
+ testScope.runTest {
+ fakeCurrentAppsSource.setGroups(TestShortcuts.currentAppGroups)
+ val uiState by collectLastValue(viewModel.shortcutsUiState)
+
+ testHelper.showFromActivity()
+
+ val activeUiState = uiState as ShortcutsUiState.Active
+ assertThat(activeUiState.defaultSelectedCategory)
+ .isEqualTo(CurrentApp(TestShortcuts.currentAppPackageName))
+ }
}
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 03afcb77d88f..e68a4a57de75 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -77,6 +77,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.foldables.FoldGracePeriodProvider;
import com.android.internal.logging.InstanceId;
import com.android.internal.logging.UiEventLogger;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardDisplayManager;
import com.android.keyguard.KeyguardSecurityView;
@@ -101,6 +102,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.log.SessionTracker;
import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.process.ProcessWrapper;
import com.android.systemui.scene.FakeWindowRootViewComponent;
import com.android.systemui.scene.ui.view.WindowRootView;
import com.android.systemui.settings.UserTracker;
@@ -188,6 +190,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock ActivityTransitionAnimator mActivityTransitionAnimator;
private @Mock ScrimController mScrimController;
private @Mock IActivityTaskManager mActivityTaskManagerService;
+ private @Mock IStatusBarService mStatusBarService;
private @Mock SysuiColorExtractor mColorExtractor;
private @Mock AuthController mAuthController;
private @Mock ShadeExpansionStateManager mShadeExpansionStateManager;
@@ -211,6 +214,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock SystemSettings mSystemSettings;
private @Mock SecureSettings mSecureSettings;
private @Mock AlarmManager mAlarmManager;
+ private @Mock ProcessWrapper mProcessWrapper;
private FakeSystemClock mSystemClock;
private final FakeWallpaperRepository mWallpaperRepository = new FakeWallpaperRepository();
@@ -247,6 +251,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
.thenReturn(mock(Flow.class));
when(mSelectedUserInteractor.getSelectedUserId()).thenReturn(mDefaultUserId);
when(mSelectedUserInteractor.getSelectedUserId(anyBoolean())).thenReturn(mDefaultUserId);
+ when(mProcessWrapper.isSystemUser()).thenReturn(true);
mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(
mContext,
new FakeWindowRootViewComponent.Factory(mock(WindowRootView.class)),
@@ -1225,10 +1230,12 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
() -> mActivityTransitionAnimator,
() -> mScrimController,
mActivityTaskManagerService,
+ mStatusBarService,
mFeatureFlags,
mSecureSettings,
mSystemSettings,
mSystemClock,
+ mProcessWrapper,
mDispatcher,
() -> mDreamViewModel,
() -> mCommunalTransitionViewModel,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
index 144e634ae519..23fd997c02e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
@@ -18,7 +18,6 @@ import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.se
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.setSceneTransition
-import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.android.systemui.utils.GlobalWindowManager
@@ -64,7 +63,6 @@ class ResourceTrimmerTest : SysuiTestCase() {
globalWindowManager = globalWindowManager,
applicationScope = testScope.backgroundScope,
bgDispatcher = kosmos.testDispatcher,
- sceneInteractor = kosmos.sceneInteractor,
)
resourceTrimmer.start()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
index 42ab25fcd9bd..032794c43f08 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
@@ -56,6 +56,7 @@ import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
+import org.junit.Ignore
import org.junit.runner.RunWith
import org.mockito.Mockito.reset
import org.mockito.Mockito.spy
@@ -97,6 +98,7 @@ class FromDreamingTransitionInteractorTest : SysuiTestCase() {
@Test
@EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ @Ignore("Until b/349837588 is fixed")
fun testTransitionToOccluded_ifDreamEnds_occludingActivityOnTop() =
testScope.runTest {
kosmos.fakeKeyguardRepository.setDreaming(true)
@@ -156,6 +158,7 @@ class FromDreamingTransitionInteractorTest : SysuiTestCase() {
reset(transitionRepository)
kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = false)
+ kosmos.fakeKeyguardRepository.setDreaming(false)
runCurrent()
assertThat(transitionRepository)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt
index 459e41d7dbc0..ea5a41f6fd5c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt
@@ -18,25 +18,22 @@ package com.android.systemui.keyguard.domain.interactor
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.SysUITestModule
import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
-import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
import com.android.systemui.coroutines.collectValues
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyguard.data.repository.FakeKeyguardSurfaceBehindRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.data.repository.InWindowLauncherUnlockAnimationRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.inWindowLauncherUnlockAnimationRepository
+import com.android.systemui.keyguard.data.repository.keyguardSurfaceBehindRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.util.mockTopActivityClassName
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
import com.android.systemui.shared.system.ActivityManagerWrapper
-import com.android.systemui.user.domain.UserDomainLayerModule
-import dagger.BindsInstance
-import dagger.Component
+import com.android.systemui.shared.system.activityManagerWrapper
+import com.android.systemui.testKosmos
import junit.framework.Assert.assertEquals
-import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -49,10 +46,16 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidJUnit4::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
- private lateinit var underTest: InWindowLauncherUnlockAnimationInteractor
-
- private lateinit var testComponent: TestComponent
- private lateinit var testScope: TestScope
+ private val kosmos = testKosmos()
+ private val underTest =
+ InWindowLauncherUnlockAnimationInteractor(
+ kosmos.inWindowLauncherUnlockAnimationRepository,
+ kosmos.applicationCoroutineScope,
+ kosmos.keyguardTransitionInteractor,
+ { kosmos.keyguardSurfaceBehindRepository },
+ kosmos.activityManagerWrapper,
+ )
+ private val testScope = kosmos.testScope
private lateinit var transitionRepository: FakeKeyguardTransitionRepository
@Mock private lateinit var activityManagerWrapper: ActivityManagerWrapper
@@ -62,19 +65,9 @@ class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
fun setUp() {
MockitoAnnotations.initMocks(this)
- testComponent =
- DaggerInWindowLauncherUnlockAnimationInteractorTest_TestComponent.factory()
- .create(
- test = this,
- mocks =
- TestMocksModule(
- activityManagerWrapper = activityManagerWrapper,
- ),
- )
- underTest = testComponent.underTest
- testScope = testComponent.testScope
- transitionRepository = testComponent.transitionRepository
+ transitionRepository = kosmos.fakeKeyguardTransitionRepository
+ activityManagerWrapper = kosmos.activityManagerWrapper
activityManagerWrapper.mockTopActivityClassName(launcherClassName)
}
@@ -92,7 +85,7 @@ class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
)
// Put launcher on top
- testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+ kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
launcherClassName
)
activityManagerWrapper.mockTopActivityClassName(launcherClassName)
@@ -175,7 +168,7 @@ class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
)
// Put not launcher on top
- testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+ kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
launcherClassName
)
activityManagerWrapper.mockTopActivityClassName("not_launcher")
@@ -252,7 +245,7 @@ class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
)
// Put launcher on top
- testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+ kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
launcherClassName
)
activityManagerWrapper.mockTopActivityClassName(launcherClassName)
@@ -296,7 +289,7 @@ class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
)
// Put Launcher on top and begin transitioning to GONE.
- testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+ kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
launcherClassName
)
activityManagerWrapper.mockTopActivityClassName(launcherClassName)
@@ -316,7 +309,7 @@ class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
values
)
- testComponent.surfaceBehindRepository.setSurfaceRemoteAnimationTargetAvailable(true)
+ kosmos.keyguardSurfaceBehindRepository.setSurfaceRemoteAnimationTargetAvailable(true)
runCurrent()
assertEquals(
@@ -360,7 +353,7 @@ class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
)
// Put Launcher on top and begin transitioning to GONE.
- testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+ kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
launcherClassName
)
activityManagerWrapper.mockTopActivityClassName(launcherClassName)
@@ -402,7 +395,7 @@ class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
)
// Put Launcher on top and begin transitioning to GONE.
- testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+ kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
launcherClassName
)
activityManagerWrapper.mockTopActivityClassName(launcherClassName)
@@ -427,7 +420,7 @@ class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
to = KeyguardState.AOD,
)
)
- testComponent.surfaceBehindRepository.setSurfaceRemoteAnimationTargetAvailable(true)
+ kosmos.keyguardSurfaceBehindRepository.setSurfaceRemoteAnimationTargetAvailable(true)
runCurrent()
assertEquals(
@@ -437,29 +430,4 @@ class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
values
)
}
-
- @SysUISingleton
- @Component(
- modules =
- [
- SysUITestModule::class,
- BiometricsDomainLayerModule::class,
- UserDomainLayerModule::class,
- ]
- )
- interface TestComponent {
- val underTest: InWindowLauncherUnlockAnimationInteractor
- val testScope: TestScope
- val transitionRepository: FakeKeyguardTransitionRepository
- val surfaceBehindRepository: FakeKeyguardSurfaceBehindRepository
- val inWindowLauncherUnlockAnimationRepository: InWindowLauncherUnlockAnimationRepository
-
- @Component.Factory
- interface Factory {
- fun create(
- @BindsInstance test: SysuiTestCase,
- mocks: TestMocksModule,
- ): TestComponent
- }
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
index f0ad5103e9a6..59f16d70fab5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
@@ -36,7 +36,6 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.clocks.ClockConfig
import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.whenever
@@ -84,7 +83,7 @@ class KeyguardBlueprintInteractorTest : SysuiTestCase() {
fun testAppliesDefaultBlueprint() {
testScope.runTest {
val blueprintId by collectLastValue(underTest.blueprintId)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Single)
+ kosmos.shadeRepository.setShadeLayoutWide(false)
configurationRepository.onConfigurationChange()
runCurrent()
@@ -98,7 +97,7 @@ class KeyguardBlueprintInteractorTest : SysuiTestCase() {
fun testAppliesSplitShadeBlueprint() {
testScope.runTest {
val blueprintId by collectLastValue(underTest.blueprintId)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
configurationRepository.onConfigurationChange()
runCurrent()
@@ -112,7 +111,7 @@ class KeyguardBlueprintInteractorTest : SysuiTestCase() {
fun testDoesNotApplySplitShadeBlueprint() {
testScope.runTest {
val blueprintId by collectLastValue(underTest.blueprintId)
- kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
+ kosmos.shadeRepository.setShadeLayoutWide(true)
clockRepository.setCurrentClock(clockController)
configurationRepository.onConfigurationChange()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
index 974e3bb133d8..8bc0a6040e12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
@@ -31,7 +31,6 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.setSceneTransition
-import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -75,7 +74,6 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
transitionInteractor = kosmos.keyguardTransitionInteractor,
dismissInteractor = dismissInteractorWithDependencies.interactor,
applicationScope = testScope.backgroundScope,
- sceneInteractor = kosmos.sceneInteractor,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
index f32e7757328f..c9871f1e4e1e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
@@ -21,6 +21,9 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel
@@ -28,12 +31,18 @@ import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.util.mockTopActivityClassName
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.Transition
+import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shared.system.ActivityManagerWrapper
import com.android.systemui.shared.system.activityManagerWrapper
import com.android.systemui.statusbar.notification.domain.interactor.notificationLaunchAnimationInteractor
import com.android.systemui.testKosmos
import com.android.systemui.util.assertValuesMatch
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
+import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -44,16 +53,22 @@ import org.junit.runner.RunWith
@kotlinx.coroutines.ExperimentalCoroutinesApi
class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
private val kosmos = testKosmos()
- private val testScope = kosmos.testScope
- private val underTest = kosmos.keyguardSurfaceBehindInteractor
- private val transitionRepository = kosmos.fakeKeyguardTransitionRepository
- private val inWindowUnlockInteractor = kosmos.inWindowLauncherUnlockAnimationInteractor
- private val activityManagerWrapper = kosmos.activityManagerWrapper
+ private lateinit var testScope: TestScope
+ private lateinit var underTest: KeyguardSurfaceBehindInteractor
+ private lateinit var transitionRepository: FakeKeyguardTransitionRepository
+ private lateinit var inWindowUnlockInteractor: InWindowLauncherUnlockAnimationInteractor
+ private lateinit var activityManagerWrapper: ActivityManagerWrapper
private val LAUNCHER_ACTIVITY_NAME = "launcher"
@Before
fun setUp() {
+ testScope = kosmos.testScope
+ underTest = kosmos.keyguardSurfaceBehindInteractor
+ transitionRepository = kosmos.fakeKeyguardTransitionRepository
+ inWindowUnlockInteractor = kosmos.inWindowLauncherUnlockAnimationInteractor
+ activityManagerWrapper = kosmos.activityManagerWrapper
+
inWindowUnlockInteractor.setLauncherActivityClass(LAUNCHER_ACTIVITY_NAME)
// Default to having something other than Launcher on top.
@@ -61,6 +76,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
}
@Test
+ @DisableSceneContainer
fun testSurfaceBehindModel_toAppSurface() =
testScope.runTest {
val values by collectValues(underTest.viewParams)
@@ -136,6 +152,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
}
@Test
+ @DisableSceneContainer
fun testSurfaceBehindModel_toLauncher() =
testScope.runTest {
val values by collectValues(underTest.viewParams)
@@ -196,6 +213,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
}
@Test
+ @DisableSceneContainer
fun testSurfaceBehindModel_fromNotificationLaunch() =
testScope.runTest {
val values by collectValues(underTest.viewParams)
@@ -230,6 +248,105 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
}
@Test
+ @EnableSceneContainer
+ fun testSurfaceBehindModel_toAppSurface_scene_container() =
+ testScope.runTest {
+ val values by collectValues(underTest.viewParams)
+ runCurrent()
+
+ assertThat(values)
+ .containsExactly(
+ // We're initialized in LOCKSCREEN.
+ KeyguardSurfaceBehindModel(alpha = 0f),
+ )
+
+ kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
+
+ values.assertValuesMatch(
+ { it == KeyguardSurfaceBehindModel(alpha = 0f) },
+ // Once we start a transition to GONE, we should fade in and translate up. The exact
+ // start value depends on screen density, so just look for != 0.
+ {
+ it.animateFromAlpha == 0f &&
+ it.alpha == 1f &&
+ it.animateFromTranslationY != 0f &&
+ it.translationY == 0f
+ }
+ )
+
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
+
+ values.assertValuesMatch(
+ { it == KeyguardSurfaceBehindModel(alpha = 0f) },
+ {
+ it.animateFromAlpha == 0f &&
+ it.alpha == 1f &&
+ it.animateFromTranslationY != 0f &&
+ it.translationY == 0f
+ },
+ // Once the current state is GONE, we should default to alpha = 1f.
+ { it == KeyguardSurfaceBehindModel(alpha = 1f) }
+ )
+ }
+
+ @Test
+ @EnableSceneContainer
+ fun testSurfaceBehindModel_toLauncher_scene_container() =
+ testScope.runTest {
+ val values by collectValues(underTest.viewParams)
+ activityManagerWrapper.mockTopActivityClassName(LAUNCHER_ACTIVITY_NAME)
+ runCurrent()
+
+ assertThat(values)
+ .containsExactly(
+ // We're initialized in LOCKSCREEN.
+ KeyguardSurfaceBehindModel(alpha = 0f),
+ )
+ .inOrder()
+
+ kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
+
+ assertThat(values)
+ .containsExactly(
+ KeyguardSurfaceBehindModel(alpha = 0f),
+ // We should instantly set alpha = 1, with no animations, when Launcher is
+ // behind
+ // the keyguard since we're playing in-window animations.
+ KeyguardSurfaceBehindModel(alpha = 1f),
+ )
+ .inOrder()
+
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
+
+ assertThat(values)
+ .containsExactly(
+ KeyguardSurfaceBehindModel(alpha = 0f),
+ // Should have remained at alpha = 1f through the entire animation.
+ KeyguardSurfaceBehindModel(alpha = 1f),
+ )
+ .inOrder()
+ }
+
+ @Test
+ @EnableSceneContainer
+ fun testSurfaceBehindModel_fromNotificationLaunch_scene_container() =
+ testScope.runTest {
+ val values by collectValues(underTest.viewParams)
+ runCurrent()
+
+ kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(true)
+ runCurrent()
+
+ kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
+
+ values.assertValuesMatch(
+ // We should be at alpha = 0f during the animation.
+ { it == KeyguardSurfaceBehindModel(alpha = 0f) },
+ )
+ }
+
+ @Test
+ @DisableSceneContainer
fun notificationLaunchFromLockscreen_isAnimatingSurfaceTrue() =
testScope.runTest {
val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
@@ -253,6 +370,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
}
@Test
+ @DisableSceneContainer
fun notificationLaunchFromGone_isAnimatingSurfaceFalse() =
testScope.runTest {
val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
@@ -276,6 +394,7 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
}
@Test
+ @DisableSceneContainer
fun notificationLaunchFalse_isAnimatingSurfaceFalse() =
testScope.runTest {
val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
@@ -297,4 +416,44 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
runCurrent()
assertThat(isAnimatingSurface).isFalse()
}
+
+ @Test
+ @EnableSceneContainer
+ fun notificationLaunchFromLockscreen_isAnimatingSurfaceTrue_scene_container() =
+ testScope.runTest {
+ val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
+
+ kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
+ kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(true)
+ runCurrent()
+
+ assertThat(isAnimatingSurface).isTrue()
+ }
+
+ @Test
+ @EnableSceneContainer
+ fun notificationLaunchFromGone_isAnimatingSurfaceFalse_scene_container() =
+ testScope.runTest {
+ val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
+
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
+ kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(true)
+ runCurrent()
+ assertThat(isAnimatingSurface).isFalse()
+
+ kosmos.setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen))
+ assertThat(isAnimatingSurface).isFalse()
+ }
+
+ @Test
+ @EnableSceneContainer
+ fun notificationLaunchFalse_isAnimatingSurfaceFalse_scene_container() =
+ testScope.runTest {
+ val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
+
+ kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
+ kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(false)
+ runCurrent()
+ assertThat(isAnimatingSurface).isFalse()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index 246cfbfbea68..fc3b35d637f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -30,11 +30,12 @@ import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepositor
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
-import com.android.systemui.dock.fakeDockManager
import com.android.systemui.flags.BrokenWithSceneContainer
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
import com.android.systemui.flags.andSceneContainer
+import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeCommandQueue
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
@@ -124,7 +125,6 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
private val powerInteractor by lazy { kosmos.powerInteractor }
private val communalInteractor by lazy { kosmos.communalInteractor }
- private val dockManager by lazy { kosmos.fakeDockManager }
companion object {
@JvmStatic
@@ -145,6 +145,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
whenever(keyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(PIN)
mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB)
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
if (!SceneContainerFlag.isEnabled) {
mSetFlagsRule.disableFlags(
Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR,
@@ -583,6 +584,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
}
@Test
+ @DisableSceneContainer
fun dozingToPrimaryBouncer() =
testScope.runTest {
// GIVEN a prior transition has run to DOZING
@@ -597,8 +599,8 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
assertThat(transitionRepository)
.startedTransition(
- to = KeyguardState.PRIMARY_BOUNCER,
from = KeyguardState.DOZING,
+ to = KeyguardState.PRIMARY_BOUNCER,
animatorAssertion = { it.isNotNull() }
)
@@ -633,6 +635,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
}
@Test
+ @DisableSceneContainer
fun dozingToGlanceableHub() =
testScope.runTest {
// GIVEN a prior transition has run to DOZING
@@ -654,8 +657,8 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
assertThat(transitionRepository)
.startedTransition(
- to = KeyguardState.GLANCEABLE_HUB,
from = KeyguardState.DOZING,
+ to = KeyguardState.GLANCEABLE_HUB,
animatorAssertion = { it.isNotNull() }
)
@@ -1314,6 +1317,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
}
@Test
+ @DisableSceneContainer
fun occludedToPrimaryBouncer() =
testScope.runTest {
// GIVEN a prior transition has run to OCCLUDED
@@ -1452,6 +1456,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
}
@Test
+ @DisableSceneContainer
fun dreamingToPrimaryBouncer() =
testScope.runTest {
// GIVEN a prior transition has run to DREAMING
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt
new file mode 100644
index 000000000000..7e249e8c179d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt
@@ -0,0 +1,378 @@
+/*
+ * 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.keyguard.domain.interactor
+
+import android.app.AlarmManager
+import android.app.admin.alarmManager
+import android.app.admin.devicePolicyManager
+import android.content.BroadcastReceiver
+import android.content.Intent
+import android.content.mockedContext
+import android.os.PowerManager
+import android.os.UserHandle
+import android.platform.test.annotations.EnableFlags
+import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.widget.lockPatternUtils
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.BiometricUnlockMode
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
+import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.testKosmos
+import com.android.systemui.util.settings.fakeSettings
+import junit.framework.Assert.assertEquals
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyLong
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() {
+
+ private var lastRegisteredBroadcastReceiver: BroadcastReceiver? = null
+ private val kosmos =
+ testKosmos().apply {
+ whenever(mockedContext.user).thenReturn(mock<UserHandle>())
+ doAnswer { invocation ->
+ lastRegisteredBroadcastReceiver = invocation.arguments[0] as BroadcastReceiver
+ }
+ .whenever(mockedContext)
+ .registerReceiver(any(), any(), any(), any(), any())
+ }
+
+ private val testScope = kosmos.testScope
+ private val underTest = kosmos.keyguardWakeDirectlyToGoneInteractor
+ private val lockPatternUtils = kosmos.lockPatternUtils
+ private val repository = kosmos.fakeKeyguardRepository
+ private val transitionRepository = kosmos.fakeKeyguardTransitionRepository
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ fun testCanWakeDirectlyToGone_keyguardServiceEnabledThenDisabled() =
+ testScope.runTest {
+ val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+ assertEquals(
+ listOf(
+ false, // Defaults to false.
+ ),
+ canWake
+ )
+
+ repository.setKeyguardEnabled(false)
+ runCurrent()
+
+ assertEquals(
+ listOf(
+ false, // Default to false.
+ true, // True now that keyguard service is disabled
+ ),
+ canWake
+ )
+
+ repository.setKeyguardEnabled(true)
+ runCurrent()
+
+ assertEquals(
+ listOf(
+ false,
+ true,
+ false,
+ ),
+ canWake
+ )
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ fun testCanWakeDirectlyToGone_lockscreenDisabledThenEnabled() =
+ testScope.runTest {
+ val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+ assertEquals(
+ listOf(
+ false, // Defaults to false.
+ ),
+ canWake
+ )
+
+ whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true)
+ runCurrent()
+
+ assertEquals(
+ listOf(
+ // Still false - isLockScreenDisabled only causes canWakeDirectlyToGone to
+ // update on the next wake/sleep event.
+ false,
+ ),
+ canWake
+ )
+
+ kosmos.powerInteractor.setAsleepForTest()
+ runCurrent()
+
+ assertEquals(
+ listOf(
+ false,
+ // True since we slept after setting isLockScreenDisabled=true
+ true,
+ ),
+ canWake
+ )
+
+ kosmos.powerInteractor.setAwakeForTest()
+ runCurrent()
+
+ kosmos.powerInteractor.setAsleepForTest()
+ runCurrent()
+
+ assertEquals(
+ listOf(
+ false,
+ true,
+ ),
+ canWake
+ )
+
+ whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false)
+ kosmos.powerInteractor.setAwakeForTest()
+ runCurrent()
+
+ assertEquals(
+ listOf(
+ false,
+ true,
+ false,
+ ),
+ canWake
+ )
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ fun testCanWakeDirectlyToGone_wakeAndUnlock() =
+ testScope.runTest {
+ val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+ assertEquals(
+ listOf(
+ false, // Defaults to false.
+ ),
+ canWake
+ )
+
+ repository.setBiometricUnlockState(BiometricUnlockMode.WAKE_AND_UNLOCK)
+ runCurrent()
+
+ assertEquals(listOf(false, true), canWake)
+
+ repository.setBiometricUnlockState(BiometricUnlockMode.NONE)
+ runCurrent()
+
+ assertEquals(listOf(false, true, false), canWake)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ fun testCanWakeDirectlyToGone_andSetsAlarm_ifPowerButtonDoesNotLockImmediately() =
+ testScope.runTest {
+ val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+ assertEquals(
+ listOf(
+ false, // Defaults to false.
+ ),
+ canWake
+ )
+
+ repository.setCanIgnoreAuthAndReturnToGone(true)
+ runCurrent()
+
+ assertEquals(listOf(false, true), canWake)
+
+ repository.setCanIgnoreAuthAndReturnToGone(false)
+ runCurrent()
+
+ assertEquals(listOf(false, true, false), canWake)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ fun testSetsCanIgnoreAuth_andSetsAlarm_whenTimingOut() =
+ testScope.runTest {
+ val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+ assertEquals(
+ listOf(
+ false, // Defaults to false.
+ ),
+ canWake
+ )
+
+ whenever(kosmos.devicePolicyManager.getMaximumTimeToLock(eq(null), anyInt()))
+ .thenReturn(-1)
+ kosmos.fakeSettings.putInt(Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 500)
+
+ transitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ testScope,
+ )
+
+ kosmos.powerInteractor.setAsleepForTest(
+ sleepReason = PowerManager.GO_TO_SLEEP_REASON_TIMEOUT
+ )
+ runCurrent()
+
+ assertEquals(
+ listOf(
+ false,
+ true,
+ ),
+ canWake
+ )
+
+ verify(kosmos.alarmManager)
+ .setExactAndAllowWhileIdle(
+ eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+ anyLong(),
+ any(),
+ )
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ fun testCancelsFirstAlarm_onWake_withSecondAlarmSet() =
+ testScope.runTest {
+ val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+ assertEquals(
+ listOf(
+ false, // Defaults to false.
+ ),
+ canWake
+ )
+
+ whenever(kosmos.devicePolicyManager.getMaximumTimeToLock(eq(null), anyInt()))
+ .thenReturn(-1)
+ kosmos.fakeSettings.putInt(Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 500)
+
+ transitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ testScope,
+ )
+
+ kosmos.powerInteractor.setAsleepForTest(
+ sleepReason = PowerManager.GO_TO_SLEEP_REASON_TIMEOUT
+ )
+ transitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.AOD,
+ testScope = testScope,
+ )
+ runCurrent()
+
+ assertEquals(
+ listOf(
+ false,
+ // Timed out, so we can ignore auth/return to GONE.
+ true,
+ ),
+ canWake
+ )
+
+ verify(kosmos.alarmManager)
+ .setExactAndAllowWhileIdle(
+ eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+ anyLong(),
+ any(),
+ )
+
+ kosmos.powerInteractor.setAwakeForTest()
+ transitionRepository.sendTransitionSteps(
+ from = KeyguardState.AOD,
+ to = KeyguardState.GONE,
+ testScope = testScope,
+ )
+ runCurrent()
+
+ assertEquals(
+ listOf(
+ false,
+ true,
+ // Should be canceled by the wakeup, but there would still be an
+ // alarm in flight that should be canceled.
+ false,
+ ),
+ canWake
+ )
+
+ kosmos.powerInteractor.setAsleepForTest(
+ sleepReason = PowerManager.GO_TO_SLEEP_REASON_TIMEOUT
+ )
+ runCurrent()
+
+ assertEquals(
+ listOf(
+ false,
+ true,
+ false,
+ // Back to sleep.
+ true,
+ ),
+ canWake
+ )
+
+ // Simulate the first sleep's alarm coming in.
+ lastRegisteredBroadcastReceiver?.onReceive(
+ kosmos.mockedContext,
+ Intent("com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD")
+ )
+ runCurrent()
+
+ // It should not have any effect.
+ assertEquals(
+ listOf(
+ false,
+ true,
+ false,
+ true,
+ ),
+ canWake
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt
index c7f44164e582..0cfc20d7bbd8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt
@@ -18,17 +18,15 @@ package com.android.systemui.keyguard.ui.binder
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.SysUITestModule
import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
-import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.inWindowLauncherUnlockAnimationInteractor
import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager
+import com.android.systemui.keyguard.ui.viewmodel.InWindowLauncherAnimationViewModel
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
import com.android.systemui.shared.system.smartspace.ILauncherUnlockAnimationController
-import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
-import dagger.BindsInstance
-import dagger.Component
-import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -45,10 +43,9 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidJUnit4::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class InWindowLauncherUnlockAnimationManagerTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
private lateinit var underTest: InWindowLauncherUnlockAnimationManager
-
- private lateinit var testComponent: TestComponent
- private lateinit var testScope: TestScope
+ private val testScope = kosmos.testScope
@Mock private lateinit var launcherUnlockAnimationController: ILauncherUnlockAnimationController
@@ -56,14 +53,14 @@ class InWindowLauncherUnlockAnimationManagerTest : SysuiTestCase() {
fun setUp() {
MockitoAnnotations.initMocks(this)
- testComponent =
- DaggerInWindowLauncherUnlockAnimationManagerTest_TestComponent.factory()
- .create(
- test = this,
- )
- underTest = testComponent.underTest
- testScope = testComponent.testScope
-
+ underTest =
+ InWindowLauncherUnlockAnimationManager(
+ kosmos.inWindowLauncherUnlockAnimationInteractor,
+ InWindowLauncherAnimationViewModel(
+ kosmos.inWindowLauncherUnlockAnimationInteractor
+ ),
+ kosmos.applicationCoroutineScope
+ )
underTest.setLauncherUnlockController("launcherClass", launcherUnlockAnimationController)
}
@@ -114,25 +111,4 @@ class InWindowLauncherUnlockAnimationManagerTest : SysuiTestCase() {
verifyNoMoreInteractions(launcherUnlockAnimationController)
}
-
- @SysUISingleton
- @Component(
- modules =
- [
- SysUITestModule::class,
- BiometricsDomainLayerModule::class,
- UserDomainLayerModule::class,
- ]
- )
- interface TestComponent {
- val underTest: InWindowLauncherUnlockAnimationManager
- val testScope: TestScope
-
- @Component.Factory
- interface Factory {
- fun create(
- @BindsInstance test: SysuiTestCase,
- ): TestComponent
- }
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
index 4a39a9b2e801..6e381caf5124 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
@@ -39,7 +39,6 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationsKeyguardInteractor
import com.android.systemui.statusbar.policy.fakeConfigurationController
import com.android.systemui.statusbar.ui.fakeSystemBarUtilsProxy
@@ -48,6 +47,7 @@ import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -57,6 +57,7 @@ import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
import org.mockito.MockitoAnnotations
+@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
@SmallTest
class ClockSectionTest : SysuiTestCase() {
@@ -127,7 +128,7 @@ class ClockSectionTest : SysuiTestCase() {
fun testApplyDefaultConstraints_LargeClock_SplitShade() =
kosmos.testScope.runTest {
with(kosmos) {
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
keyguardClockInteractor.setClockSize(ClockSize.LARGE)
advanceUntilIdle()
}
@@ -143,11 +144,11 @@ class ClockSectionTest : SysuiTestCase() {
fun testApplyDefaultConstraints_LargeClock_NonSplitShade() =
kosmos.testScope.runTest {
with(kosmos) {
- val collectedShadeMode by collectLastValue(shadeRepository.shadeMode)
+ val isShadeLayoutWide by collectLastValue(shadeRepository.isShadeLayoutWide)
val isLargeClockVisible by
collectLastValue(keyguardClockViewModel.isLargeClockVisible)
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
keyguardClockInteractor.setClockSize(ClockSize.LARGE)
fakeKeyguardRepository.setClockShouldBeCentered(true)
notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
@@ -168,11 +169,11 @@ class ClockSectionTest : SysuiTestCase() {
kosmos.testScope.runTest {
with(kosmos) {
DIMENSION_BY_IDENTIFIER = listOf() // Remove Smartspace from mock
- val collectedShadeMode by collectLastValue(shadeRepository.shadeMode)
+ val isShadeLayoutWide by collectLastValue(shadeRepository.isShadeLayoutWide)
val isLargeClockVisible by
collectLastValue(keyguardClockViewModel.isLargeClockVisible)
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
keyguardClockInteractor.setClockSize(ClockSize.LARGE)
fakeKeyguardRepository.setClockShouldBeCentered(true)
notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
@@ -193,11 +194,11 @@ class ClockSectionTest : SysuiTestCase() {
kosmos.testScope.runTest {
with(kosmos) {
DIMENSION_BY_IDENTIFIER = listOf() // Remove Smartspace from mock
- val collectedShadeMode by collectLastValue(shadeRepository.shadeMode)
+ val isShadeLayoutWide by collectLastValue(shadeRepository.isShadeLayoutWide)
val isLargeClockVisible by
collectLastValue(keyguardClockViewModel.isLargeClockVisible)
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
keyguardClockInteractor.setClockSize(ClockSize.LARGE)
fakeKeyguardRepository.setClockShouldBeCentered(true)
notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
@@ -217,11 +218,11 @@ class ClockSectionTest : SysuiTestCase() {
fun testApplyDefaultConstraints_SmallClock_SplitShade() =
kosmos.testScope.runTest {
with(kosmos) {
- val collectedShadeMode by collectLastValue(shadeRepository.shadeMode)
+ val isShadeLayoutWide by collectLastValue(shadeRepository.isShadeLayoutWide)
val isLargeClockVisible by
collectLastValue(keyguardClockViewModel.isLargeClockVisible)
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
keyguardClockInteractor.setClockSize(ClockSize.SMALL)
fakeKeyguardRepository.setClockShouldBeCentered(true)
notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
@@ -241,11 +242,11 @@ class ClockSectionTest : SysuiTestCase() {
fun testApplyDefaultConstraints_SmallClock_NonSplitShade() =
kosmos.testScope.runTest {
with(kosmos) {
- val collectedShadeMode by collectLastValue(shadeRepository.shadeMode)
+ val isShadeLayoutWide by collectLastValue(shadeRepository.isShadeLayoutWide)
val isLargeClockVisible by
collectLastValue(keyguardClockViewModel.isLargeClockVisible)
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
keyguardClockInteractor.setClockSize(ClockSize.SMALL)
fakeKeyguardRepository.setClockShouldBeCentered(true)
notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
@@ -334,7 +335,7 @@ class ClockSectionTest : SysuiTestCase() {
}
companion object {
- private val SMART_SPACE_DATE_WEATHER_HEIGHT = 10
- private val ENHANCED_SMART_SPACE_HEIGHT = 11
+ private const val SMART_SPACE_DATE_WEATHER_HEIGHT = 10
+ private const val ENHANCED_SMART_SPACE_HEIGHT = 11
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
index 40663ceb2ad2..17e1b53a3ba9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
@@ -38,7 +38,6 @@ import com.android.systemui.plugins.clocks.ClockFaceConfig
import com.android.systemui.plugins.clocks.ClockFaceController
import com.android.systemui.res.R
import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.ui.fakeSystemBarUtilsProxy
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.whenever
@@ -88,7 +87,7 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
val currentClockLayout by collectLastValue(underTest.currentClockLayout)
with(kosmos) {
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
keyguardRepository.setClockShouldBeCentered(true)
keyguardClockRepository.setClockSize(ClockSize.LARGE)
}
@@ -103,7 +102,7 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
val currentClockLayout by collectLastValue(underTest.currentClockLayout)
with(kosmos) {
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
keyguardRepository.setClockShouldBeCentered(false)
keyguardClockRepository.setClockSize(ClockSize.LARGE)
}
@@ -118,7 +117,7 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
val currentClockLayout by collectLastValue(underTest.currentClockLayout)
with(kosmos) {
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
keyguardRepository.setClockShouldBeCentered(false)
keyguardClockRepository.setClockSize(ClockSize.SMALL)
}
@@ -133,7 +132,7 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
val currentClockLayout by collectLastValue(underTest.currentClockLayout)
with(kosmos) {
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
keyguardClockRepository.setClockSize(ClockSize.SMALL)
}
@@ -146,7 +145,7 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
val currentClockLayout by collectLastValue(underTest.currentClockLayout)
with(kosmos) {
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
keyguardClockRepository.setClockSize(ClockSize.LARGE)
}
@@ -234,7 +233,7 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
fun testSmallClockTop_splitShade_composeLockscreenOn() =
testScope.runTest {
with(kosmos) {
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
fakeSystemBarUtilsProxy.fakeKeyguardStatusBarHeight = KEYGUARD_STATUS_BAR_HEIGHT
}
@@ -249,7 +248,7 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
fun testSmallClockTop_splitShade_composeLockscreenOff() =
testScope.runTest {
with(kosmos) {
- shadeRepository.setShadeMode(ShadeMode.Split)
+ shadeRepository.setShadeLayoutWide(true)
fakeSystemBarUtilsProxy.fakeKeyguardStatusBarHeight = KEYGUARD_STATUS_BAR_HEIGHT
}
@@ -262,7 +261,7 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
fun testSmallClockTop_nonSplitShade_composeLockscreenOn() =
testScope.runTest {
with(kosmos) {
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
fakeSystemBarUtilsProxy.fakeKeyguardStatusBarHeight = KEYGUARD_STATUS_BAR_HEIGHT
}
@@ -275,7 +274,7 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
fun testSmallClockTop_nonSplitShade_composeLockscreenOff() =
testScope.runTest {
with(kosmos) {
- shadeRepository.setShadeMode(ShadeMode.Single)
+ shadeRepository.setShadeLayoutWide(false)
fakeSystemBarUtilsProxy.fakeKeyguardStatusBarHeight = KEYGUARD_STATUS_BAR_HEIGHT
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/SessionTrackerTest.java b/packages/SystemUI/tests/src/com/android/systemui/log/SessionTrackerTest.java
index fbeb6d8d0a6f..732bef1f9803 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/SessionTrackerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/SessionTrackerTest.java
@@ -44,6 +44,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
+import com.android.systemui.process.ProcessWrapper;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
@@ -68,6 +69,8 @@ public class SessionTrackerTest extends SysuiTestCase {
private KeyguardStateController mKeyguardStateController;
@Mock
private UiEventLogger mUiEventLogger;
+ @Mock
+ private ProcessWrapper mProcessWrapper;
@Captor
ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
@@ -86,13 +89,15 @@ public class SessionTrackerTest extends SysuiTestCase {
@Before
public void setup() throws RemoteException {
MockitoAnnotations.initMocks(this);
+ when(mProcessWrapper.isSystemUser()).thenReturn(true);
mSessionTracker = new SessionTracker(
mStatusBarService,
mAuthController,
mKeyguardUpdateMonitor,
mKeyguardStateController,
- mUiEventLogger
+ mUiEventLogger,
+ mProcessWrapper
);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
index 850e2e014c57..3705909cbc2b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
@@ -31,6 +31,7 @@ import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.media.controls.MediaTestUtils
import com.android.systemui.media.controls.data.repository.MediaFilterRepository
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.shared.mockMediaLogger
import com.android.systemui.media.controls.shared.model.EXTRA_KEY_TRIGGER_RESUME
import com.android.systemui.media.controls.shared.model.MediaCommonModel
import com.android.systemui.media.controls.shared.model.MediaData
@@ -114,7 +115,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
mediaSmartspaceLogger = mockMediaSmartspaceLogger
mediaFilterRepository
}
- private val mediaLoadingLogger = kosmos.mockMediaLoadingLogger
+ private val mediaLogger = kosmos.mockMediaLogger
@Before
fun setup() {
@@ -133,7 +134,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
logger,
mediaFlags,
repository,
- mediaLoadingLogger,
+ mediaLogger,
)
mediaDataFilter.mediaDataProcessor = mediaDataProcessor
mediaDataFilter.addListener(listener)
@@ -194,7 +195,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
verify(listener)
.onMediaDataLoaded(eq(KEY), eq(null), eq(dataMain), eq(true), eq(0), eq(false))
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(eq(dataMain.instanceId), eq(dataMain.active), anyString())
assertThat(currentMedia).containsExactly(mediaCommonModel)
}
@@ -210,7 +211,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
verify(listener, never())
.onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt(), anyBoolean())
- verify(mediaLoadingLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
+ verify(mediaLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
assertThat(currentMedia).doesNotContain(mediaCommonModel)
}
@@ -224,14 +225,14 @@ class MediaDataFilterImplTest : SysuiTestCase() {
// GIVEN a media was removed for main user
mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain)
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(eq(dataMain.instanceId), eq(dataMain.active), anyString())
assertThat(currentMedia).containsExactly(mediaCommonModel)
mediaDataFilter.onMediaDataRemoved(KEY, false)
verify(listener).onMediaDataRemoved(eq(KEY), eq(false))
- verify(mediaLoadingLogger).logMediaRemoved(eq(dataMain.instanceId), anyString())
+ verify(mediaLogger).logMediaRemoved(eq(dataMain.instanceId), anyString())
assertThat(currentMedia).doesNotContain(mediaCommonModel)
}
@@ -245,8 +246,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
mediaDataFilter.onMediaDataRemoved(KEY, false)
verify(listener, never()).onMediaDataRemoved(eq(KEY), eq(false))
- verify(mediaLoadingLogger, never())
- .logMediaRemoved(eq(dataGuest.instanceId), anyString())
+ verify(mediaLogger, never()).logMediaRemoved(eq(dataGuest.instanceId), anyString())
assertThat(currentMedia).isEmpty()
}
@@ -259,7 +259,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
// GIVEN that we have a media loaded for main user
mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain)
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(eq(dataMain.instanceId), eq(dataMain.active), anyString())
assertThat(currentMedia).containsExactly(MediaCommonModel.MediaControl(mediaLoaded))
@@ -268,7 +268,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
// THEN we should remove the main user's media
verify(listener).onMediaDataRemoved(eq(KEY), eq(false))
- verify(mediaLoadingLogger).logMediaRemoved(eq(dataMain.instanceId), anyString())
+ verify(mediaLogger).logMediaRemoved(eq(dataMain.instanceId), anyString())
assertThat(currentMedia).isEmpty()
}
@@ -289,10 +289,10 @@ class MediaDataFilterImplTest : SysuiTestCase() {
// THEN we should add back the guest user media
verify(listener)
.onMediaDataLoaded(eq(KEY_ALT), eq(null), eq(dataGuest), eq(true), eq(0), eq(false))
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(eq(dataGuest.instanceId), eq(dataGuest.active), anyString())
- reset(mediaLoadingLogger)
+ reset(mediaLogger)
// but not the main user's
verify(listener, never())
@@ -304,7 +304,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
anyInt(),
anyBoolean()
)
- verify(mediaLoadingLogger, never())
+ verify(mediaLogger, never())
.logMediaLoaded(eq(dataMain.instanceId), anyBoolean(), anyString())
assertThat(currentMedia)
.containsExactly(MediaCommonModel.MediaControl(guestLoadedStatesModel))
@@ -327,7 +327,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
val mediaLoadedStatesModel = MediaDataLoadingModel.Loaded(dataMain.instanceId)
// THEN we should remove the private profile media
verify(listener).onMediaDataRemoved(eq(KEY_ALT), eq(false))
- verify(mediaLoadingLogger).logMediaRemoved(eq(dataGuest.instanceId), anyString())
+ verify(mediaLogger).logMediaRemoved(eq(dataGuest.instanceId), anyString())
assertThat(currentMedia)
.containsExactly(MediaCommonModel.MediaControl(mediaLoadedStatesModel))
}
@@ -591,8 +591,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
assertThat(hasActiveMedia(selectedUserEntries)).isFalse()
verify(listener)
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true))
- verify(mediaLoadingLogger)
- .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
+ verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
verify(logger).logRecommendationAdded(SMARTSPACE_PACKAGE, SMARTSPACE_INSTANCE_ID)
verify(logger, never()).logRecommendationActivated(any(), any(), any())
}
@@ -622,9 +621,8 @@ class MediaDataFilterImplTest : SysuiTestCase() {
verify(listener, never())
.onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt(), anyBoolean())
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
- verify(mediaLoadingLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
- verify(mediaLoadingLogger, never())
- .logRecommendationLoaded(any(), anyBoolean(), anyString())
+ verify(mediaLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
+ verify(mediaLogger, never()).logRecommendationLoaded(any(), anyBoolean(), anyString())
verify(logger, never()).logRecommendationAdded(any(), any())
verify(logger, never()).logRecommendationActivated(any(), any(), any())
}
@@ -662,8 +660,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
assertThat(hasActiveMedia(selectedUserEntries)).isFalse()
verify(listener)
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true))
- verify(mediaLoadingLogger)
- .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
+ verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
verify(logger).logRecommendationAdded(SMARTSPACE_PACKAGE, SMARTSPACE_INSTANCE_ID)
verify(logger, never()).logRecommendationActivated(any(), any(), any())
}
@@ -698,8 +695,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
.isFalse()
assertThat(hasActiveMedia(selectedUserEntries)).isFalse()
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
- verify(mediaLoadingLogger, never())
- .logRecommendationLoaded(any(), anyBoolean(), anyString())
+ verify(mediaLogger, never()).logRecommendationLoaded(any(), anyBoolean(), anyString())
verify(logger, never()).logRecommendationAdded(any(), any())
verify(logger, never()).logRecommendationActivated(any(), any(), any())
}
@@ -727,10 +723,10 @@ class MediaDataFilterImplTest : SysuiTestCase() {
assertThat(currentMedia).containsExactly(controlCommonModel)
verify(listener)
.onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
- reset(mediaLoadingLogger)
+ reset(mediaLogger)
// AND we get a smartspace signal
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
@@ -749,10 +745,9 @@ class MediaDataFilterImplTest : SysuiTestCase() {
verify(listener, never())
.onMediaDataLoaded(eq(KEY), eq(KEY), any(), anyBoolean(), anyInt(), anyBoolean())
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
- verify(mediaLoadingLogger, never())
+ verify(mediaLogger, never())
.logMediaLoaded(eq(dataCurrent.instanceId), anyBoolean(), anyString())
- verify(mediaLoadingLogger, never())
- .logRecommendationLoaded(any(), anyBoolean(), anyString())
+ verify(mediaLogger, never()).logRecommendationLoaded(any(), anyBoolean(), anyString())
verify(logger, never()).logRecommendationAdded(any(), any())
verify(logger, never()).logRecommendationActivated(any(), any(), any())
}
@@ -775,7 +770,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
assertThat(currentMedia).containsExactly(controlCommonModel)
verify(listener)
.onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
// AND we get a smartspace signal
@@ -810,7 +805,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
eq(100),
eq(true)
)
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(
eq(dataCurrentAndActive.instanceId),
eq(dataCurrentAndActive.active),
@@ -818,8 +813,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
)
// Smartspace update shouldn't be propagated for the empty rec list.
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
- verify(mediaLoadingLogger, never())
- .logRecommendationLoaded(any(), anyBoolean(), anyString())
+ verify(mediaLogger, never()).logRecommendationLoaded(any(), anyBoolean(), anyString())
verify(logger, never()).logRecommendationAdded(any(), any())
verify(logger).logRecommendationActivated(eq(APP_UID), eq(PACKAGE), eq(INSTANCE_ID))
}
@@ -846,7 +840,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
assertThat(currentMedia).containsExactly(controlCommonModel)
verify(listener)
.onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
// AND we get a smartspace signal
@@ -865,7 +859,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
eq(100),
eq(true)
)
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(
eq(dataCurrentAndActive.instanceId),
eq(dataCurrentAndActive.active),
@@ -890,8 +884,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
assertThat(currentMedia).containsExactly(controlCommonModel, recsCommonModel)
verify(listener)
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
- verify(mediaLoadingLogger)
- .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
+ verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
verify(logger).logRecommendationAdded(SMARTSPACE_PACKAGE, SMARTSPACE_INSTANCE_ID)
verify(logger).logRecommendationActivated(eq(APP_UID), eq(PACKAGE), eq(INSTANCE_ID))
}
@@ -908,8 +901,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
- verify(mediaLoadingLogger)
- .logRecommendationRemoved(eq(SMARTSPACE_KEY), eq(true), anyString())
+ verify(mediaLogger).logRecommendationRemoved(eq(SMARTSPACE_KEY), eq(true), anyString())
assertThat(currentMedia).isEmpty()
assertThat(
hasActiveMediaOrRecommendation(
@@ -941,7 +933,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
assertThat(currentMedia).containsExactly(controlCommonModel)
verify(listener)
.onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
runCurrent()
@@ -958,7 +950,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
eq(100),
eq(true)
)
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(
eq(dataCurrentAndActive.instanceId),
eq(dataCurrentAndActive.active),
@@ -968,8 +960,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
- verify(mediaLoadingLogger)
- .logRecommendationRemoved(eq(SMARTSPACE_KEY), eq(true), anyString())
+ verify(mediaLogger).logRecommendationRemoved(eq(SMARTSPACE_KEY), eq(true), anyString())
assertThat(currentMedia).containsExactly(controlCommonModel)
assertThat(
hasActiveMediaOrRecommendation(
@@ -1000,8 +991,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
verify(listener)
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
- verify(mediaLoadingLogger)
- .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(false), anyString())
+ verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(false), anyString())
assertThat(currentMedia).containsExactly(recsCommonModel)
assertThat(
hasActiveMediaOrRecommendation(
@@ -1042,11 +1032,11 @@ class MediaDataFilterImplTest : SysuiTestCase() {
verify(listener)
.onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
assertThat(currentMedia).containsExactly(controlCommonModel)
- reset(mediaLoadingLogger)
+ reset(mediaLogger)
// And an inactive recommendation is loaded
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
@@ -1054,11 +1044,10 @@ class MediaDataFilterImplTest : SysuiTestCase() {
// Smartspace is loaded but the media stays inactive
verify(listener)
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
- verify(mediaLoadingLogger)
- .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(false), anyString())
+ verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(false), anyString())
verify(listener, never())
.onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt(), anyBoolean())
- verify(mediaLoadingLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
+ verify(mediaLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
assertThat(currentMedia).containsExactly(controlCommonModel, recsCommonModel)
assertThat(
hasActiveMediaOrRecommendation(
@@ -1127,7 +1116,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
verify(listener)
.onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
assertThat(currentMedia).containsExactly(controlCommonModel)
@@ -1156,7 +1145,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
eq(100),
eq(true)
)
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(
eq(dataCurrentAndActive.instanceId),
eq(dataCurrentAndActive.active),
@@ -1174,8 +1163,7 @@ class MediaDataFilterImplTest : SysuiTestCase() {
// And update the smartspace data state, but not prioritized
verify(listener)
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
- verify(mediaLoadingLogger)
- .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
+ verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
}
@Test
@@ -1199,11 +1187,11 @@ class MediaDataFilterImplTest : SysuiTestCase() {
verify(listener)
.onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
- verify(mediaLoadingLogger)
+ verify(mediaLogger)
.logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
assertThat(currentMedia).containsExactly(controlCommonModel)
- reset(mediaLoadingLogger)
+ reset(mediaLogger)
// AND we get a smartspace signal with extra to not trigger resume
val extras = Bundle().apply { putBoolean(EXTRA_KEY_TRIGGER_RESUME, false) }
@@ -1213,13 +1201,12 @@ class MediaDataFilterImplTest : SysuiTestCase() {
// THEN listeners are not updated to show media
verify(listener, never())
.onMediaDataLoaded(eq(KEY), eq(KEY), any(), eq(true), eq(100), eq(true))
- verify(mediaLoadingLogger, never())
+ verify(mediaLogger, never())
.logMediaLoaded(eq(dataCurrent.instanceId), anyBoolean(), anyString())
// But the smartspace update is still propagated
verify(listener)
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
- verify(mediaLoadingLogger)
- .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
+ verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
assertThat(currentMedia).containsExactly(controlCommonModel, recsCommonModel)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
index c0d411b12496..785d5a8e6184 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
@@ -16,19 +16,26 @@
package com.android.systemui.mediaprojection.data.repository
+import android.hardware.display.displayManager
import android.media.projection.MediaProjectionInfo
import android.os.Binder
+import android.os.Handler
import android.os.UserHandle
import android.view.ContentRecordingSession
+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.coroutines.collectLastValue
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
+import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createToken
import com.android.systemui.mediaprojection.taskswitcher.FakeMediaProjectionManager.Companion.createDisplaySession
+import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeTasksRepository
import com.android.systemui.mediaprojection.taskswitcher.fakeActivityTaskManager
import com.android.systemui.mediaprojection.taskswitcher.fakeMediaProjectionManager
import com.android.systemui.mediaprojection.taskswitcher.taskSwitcherKosmos
@@ -36,7 +43,9 @@ import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
@SmallTest
@@ -47,6 +56,7 @@ class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
private val fakeMediaProjectionManager = kosmos.fakeMediaProjectionManager
private val fakeActivityTaskManager = kosmos.fakeActivityTaskManager
+ private val displayManager = kosmos.displayManager
private val repo = kosmos.realMediaProjectionRepository
@@ -139,6 +149,37 @@ class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
}
@Test
+ fun mediaProjectionState_entireScreen_validVirtualDisplayId_hasHostDeviceName() =
+ testScope.runTest {
+ val state by collectLastValue(repo.mediaProjectionState)
+
+ val session = ContentRecordingSession.createDisplaySession(/* displayToMirror= */ 123)
+ session.virtualDisplayId = 45
+ val displayInfo = mock<Display>().apply { whenever(this.name).thenReturn("Test Name") }
+ whenever(displayManager.getDisplay(45)).thenReturn(displayInfo)
+
+ fakeMediaProjectionManager.dispatchOnSessionSet(session = session)
+
+ assertThat((state as MediaProjectionState.Projecting.EntireScreen).hostDeviceName)
+ .isEqualTo("Test Name")
+ }
+
+ @Test
+ fun mediaProjectionState_entireScreen_invalidVirtualDisplayId_nullHostDeviceName() =
+ testScope.runTest {
+ val state by collectLastValue(repo.mediaProjectionState)
+
+ val session = ContentRecordingSession.createDisplaySession(/* displayToMirror= */ 123)
+ session.virtualDisplayId = 45
+ whenever(displayManager.getDisplay(45)).thenReturn(null)
+
+ fakeMediaProjectionManager.dispatchOnSessionSet(session = session)
+
+ assertThat((state as MediaProjectionState.Projecting.EntireScreen).hostDeviceName)
+ .isNull()
+ }
+
+ @Test
fun mediaProjectionState_sessionSet_taskWithToken_matchingRunningTask_emitsSingleTask() =
testScope.runTest {
val token = createToken()
@@ -179,6 +220,90 @@ class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
}
@Test
+ fun mediaProjectionState_singleTask_validVirtualDisplayId_hasHostDeviceName() =
+ testScope.runTest {
+ val state by collectLastValue(repo.mediaProjectionState)
+
+ val token = createToken()
+ val task = createTask(taskId = 1, token = token)
+ fakeActivityTaskManager.addRunningTasks(task)
+
+ val session = ContentRecordingSession.createTaskSession(token.asBinder())
+ session.virtualDisplayId = 45
+ val displayInfo = mock<Display>().apply { whenever(this.name).thenReturn("Test Name") }
+ whenever(displayManager.getDisplay(45)).thenReturn(displayInfo)
+
+ fakeMediaProjectionManager.dispatchOnSessionSet(session = session)
+
+ assertThat((state as MediaProjectionState.Projecting.SingleTask).hostDeviceName)
+ .isEqualTo("Test Name")
+ }
+
+ @Test
+ fun mediaProjectionState_singleTask_invalidVirtualDisplayId_nullHostDeviceName() =
+ testScope.runTest {
+ val state by collectLastValue(repo.mediaProjectionState)
+
+ val token = createToken()
+ val task = createTask(taskId = 1, token = token)
+ fakeActivityTaskManager.addRunningTasks(task)
+
+ val session = ContentRecordingSession.createTaskSession(token.asBinder())
+ session.virtualDisplayId = 45
+ whenever(displayManager.getDisplay(45)).thenReturn(null)
+
+ fakeMediaProjectionManager.dispatchOnSessionSet(session = session)
+
+ assertThat((state as MediaProjectionState.Projecting.SingleTask).hostDeviceName)
+ .isNull()
+ }
+
+ /** Regression test for b/352483752. */
+ @Test
+ fun mediaProjectionState_sessionStartedThenImmediatelyStopped_emitsOnlyNotProjecting() =
+ testScope.runTest {
+ val fakeTasksRepo = FakeTasksRepository()
+ val repoWithTimingControl =
+ MediaProjectionManagerRepository(
+ // fakeTasksRepo lets us have control over when the background dispatcher
+ // finishes fetching the tasks info.
+ tasksRepository = fakeTasksRepo,
+ mediaProjectionManager = fakeMediaProjectionManager.mediaProjectionManager,
+ displayManager = displayManager,
+ handler = Handler.getMain(),
+ applicationScope = kosmos.applicationCoroutineScope,
+ backgroundDispatcher = kosmos.testDispatcher,
+ mediaProjectionServiceHelper = fakeMediaProjectionManager.helper,
+ logger = logcatLogBuffer("TestMediaProjection"),
+ )
+
+ val state by collectLastValue(repoWithTimingControl.mediaProjectionState)
+
+ val token = createToken()
+ val task = createTask(taskId = 1, token = token)
+
+ // Dispatch a session using a task session so that MediaProjectionManagerRepository
+ // has to ask TasksRepository for the tasks info.
+ fakeMediaProjectionManager.dispatchOnSessionSet(
+ session = ContentRecordingSession.createTaskSession(token.asBinder())
+ )
+ // FakeTasksRepository is set up to not return the tasks info until the test manually
+ // calls [FakeTasksRepository#setRunningTaskResult]. At this point,
+ // MediaProjectionManagerRepository is waiting for the tasks info and hasn't emitted
+ // anything yet.
+
+ // Before the tasks info comes back, dispatch a stop event.
+ fakeMediaProjectionManager.dispatchOnStop()
+
+ // Then let the tasks info come back.
+ fakeTasksRepo.setRunningTaskResult(task)
+
+ // Verify that MediaProjectionManagerRepository threw away the tasks info because
+ // a newer callback event (#onStop) occurred.
+ assertThat(state).isEqualTo(MediaProjectionState.NotProjecting)
+ }
+
+ @Test
fun stopProjecting_invokesManager() =
testScope.runTest {
repo.stopProjecting()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt
index 548366e3fc38..d183c7370713 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt
@@ -79,7 +79,7 @@ class MediaProjectionPermissionDialogDelegateTest : SysuiTestCase() {
val overrideDisableSingleAppOption = false
setUpAndShowDialog(overrideDisableSingleAppOption)
- val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner)
+ val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
val secondOptionText =
spinner.adapter
.getDropDownView(1, null, spinner)
@@ -100,7 +100,7 @@ class MediaProjectionPermissionDialogDelegateTest : SysuiTestCase() {
val overrideDisableSingleAppOption = true
setUpAndShowDialog(overrideDisableSingleAppOption)
- val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner)
+ val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
val secondOptionText =
spinner.adapter
.getDropDownView(1, null, spinner)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/FakeTasksRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/FakeTasksRepository.kt
new file mode 100644
index 000000000000..ce2b9830951b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/FakeTasksRepository.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.mediaprojection.taskswitcher.data.repository
+
+import android.app.ActivityManager
+import android.os.IBinder
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.emptyFlow
+
+/**
+ * Fake tasks repository that gives us fine-grained control over when the result of
+ * [findRunningTaskFromWindowContainerToken] gets emitted.
+ */
+class FakeTasksRepository : TasksRepository {
+ override suspend fun launchRecentTask(taskInfo: ActivityManager.RunningTaskInfo) {}
+
+ private val findRunningTaskResult: CompletableDeferred<ActivityManager.RunningTaskInfo?> =
+ CompletableDeferred()
+
+ override suspend fun findRunningTaskFromWindowContainerToken(
+ windowContainerToken: IBinder
+ ): ActivityManager.RunningTaskInfo? {
+ return findRunningTaskResult.await()
+ }
+
+ fun setRunningTaskResult(task: ActivityManager.RunningTaskInfo?) {
+ findRunningTaskResult.complete(task)
+ }
+
+ override val foregroundTask: Flow<ActivityManager.RunningTaskInfo> = emptyFlow()
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
new file mode 100644
index 000000000000..84ec1a5677aa
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
@@ -0,0 +1,105 @@
+/*
+ * 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.mediarouter.data.repository
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.policy.CastDevice
+import com.android.systemui.statusbar.policy.fakeCastController
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class MediaRouterRepositoryTest : SysuiTestCase() {
+ val kosmos = Kosmos()
+ val testScope = kosmos.testScope
+ val castController = kosmos.fakeCastController
+
+ val underTest = kosmos.realMediaRouterRepository
+
+ @Test
+ fun castDevices_empty_isEmpty() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.castDevices)
+ // Required to let the listener attach before the devices get set
+ runCurrent()
+
+ castController.castDevices = emptyList()
+
+ assertThat(latest).isEmpty()
+ }
+
+ @Test
+ fun castDevices_onlyIncludesMediaRouterOriginDevices() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.castDevices)
+ // Required to let the listener attach before the devices get set
+ runCurrent()
+
+ val projectionDevice =
+ CastDevice(
+ id = "idProjection",
+ name = "name",
+ description = "desc",
+ state = CastDevice.CastState.Connected,
+ origin = CastDevice.CastOrigin.MediaProjection,
+ )
+ val routerDevice1 =
+ CastDevice(
+ id = "idRouter1",
+ name = "name",
+ description = "desc",
+ state = CastDevice.CastState.Connected,
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+
+ val routerDevice2 =
+ CastDevice(
+ id = "idRouter2",
+ name = "name",
+ description = "desc",
+ state = CastDevice.CastState.Connected,
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ castController.setCastDevices(listOf(projectionDevice, routerDevice1, routerDevice2))
+
+ assertThat(latest).containsExactly(routerDevice1, routerDevice2).inOrder()
+ }
+
+ @Test
+ fun stopCasting_notifiesCastController() {
+ val device =
+ CastDevice(
+ id = "id",
+ name = "name",
+ description = "desc",
+ state = CastDevice.CastState.Connected,
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+
+ underTest.stopCasting(device)
+
+ assertThat(castController.lastStoppedDevice).isEqualTo(device)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
index df8eafe2ea2a..196bbb9f2dee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
@@ -49,6 +49,7 @@ import com.android.dx.mockito.inline.extended.StaticMockitoSession;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.views.NavigationBar;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.shared.recents.utilities.Utilities;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt
index b169cc12f08a..b4db6da2000a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt
@@ -27,6 +27,7 @@ import android.view.ViewConfiguration
import android.view.WindowManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager
import com.android.internal.jank.Cuj
import com.android.internal.util.LatencyTracker
import com.android.systemui.SysuiTestCase
@@ -63,7 +64,7 @@ class BackPanelControllerTest : SysuiTestCase() {
private var triggerThreshold: Float = 0.0f
private val touchSlop = ViewConfiguration.get(context).scaledEdgeSlop
@Mock private lateinit var vibratorHelper: VibratorHelper
- @Mock private lateinit var windowManager: WindowManager
+ @Mock private lateinit var viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager
@Mock private lateinit var configurationController: ConfigurationController
@Mock private lateinit var latencyTracker: LatencyTracker
private val interactionJankMonitor by lazy { kosmos.interactionJankMonitor }
@@ -78,7 +79,7 @@ class BackPanelControllerTest : SysuiTestCase() {
mBackPanelController =
BackPanelController(
context,
- windowManager,
+ viewCaptureAwareWindowManager,
ViewConfiguration.get(context),
Handler.createAsync(testableLooper.looper),
systemClock,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarButtonTest.java
index 85244fd5ce95..00e79f5a3ac2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarButtonTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -38,6 +38,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestableContext;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.settings.FakeDisplayTracker;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarInflaterViewTest.java
index a358c18ec609..e58c8f281fc1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarInflaterViewTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.doNothing;
@@ -32,7 +32,9 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
import com.android.systemui.recents.OverviewProxyService;
import org.junit.After;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
index 982a26904de9..45d77f6d76cd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
@@ -28,7 +28,9 @@ import static android.view.WindowInsets.Type.ime;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
import static com.android.systemui.assist.AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS;
-import static com.android.systemui.navigationbar.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
+import static com.android.systemui.navigationbar.views.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.google.common.truth.Truth.assertThat;
@@ -38,8 +40,9 @@ 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.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -70,6 +73,7 @@ import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowMetrics;
import android.view.accessibility.AccessibilityManager;
+import android.view.inputmethod.Flags;
import android.view.inputmethod.InputMethodManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -86,10 +90,15 @@ import com.android.systemui.assist.AssistManager;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.DeadZone;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.NavBarHelper;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.buttons.NavBarButtonClickLogger;
+import com.android.systemui.navigationbar.views.buttons.NavbarOrientationTrackingLogger;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
@@ -157,6 +166,8 @@ public class NavigationBarTest extends SysuiTestCase {
@Mock
ButtonDispatcher mImeSwitchButton;
@Mock
+ KeyButtonView mImeSwitchButtonView;
+ @Mock
ButtonDispatcher mBackButton;
@Mock
NavigationBarTransitions mNavigationBarTransitions;
@@ -428,6 +439,45 @@ public class NavigationBarTest extends SysuiTestCase {
}
@Test
+ public void testImeSwitcherClick() {
+ mNavigationBar.init();
+ mNavigationBar.onViewAttached();
+ mNavigationBar.onImeSwitcherClick(mImeSwitchButtonView);
+
+ verify(mUiEventLogger).log(NAVBAR_IME_SWITCHER_BUTTON_TAP);
+ verify(mUiEventLogger, never()).log(NAVBAR_IME_SWITCHER_BUTTON_LONGPRESS);
+ if (Flags.imeSwitcherRevamp()) {
+ verify(mInputMethodManager)
+ .onImeSwitchButtonClickFromSystem(mNavigationBar.mDisplayId);
+ verify(mInputMethodManager, never()).showInputMethodPickerFromSystem(
+ anyBoolean() /* showAuxiliarySubtypes */, anyInt() /* displayId */);
+ } else {
+ verify(mInputMethodManager, never())
+ .onImeSwitchButtonClickFromSystem(anyInt() /* displayId */);
+ verify(mInputMethodManager).showInputMethodPickerFromSystem(
+ true /* showAuxiliarySubtypes */, mNavigationBar.mDisplayId);
+ }
+ }
+
+ @Test
+ public void testImeSwitcherLongClick() {
+ mNavigationBar.init();
+ mNavigationBar.onViewAttached();
+ mNavigationBar.onImeSwitcherLongClick(mImeSwitchButtonView);
+
+ verify(mUiEventLogger, never()).log(NAVBAR_IME_SWITCHER_BUTTON_TAP);
+ if (Flags.imeSwitcherRevamp()) {
+ verify(mUiEventLogger).log(NAVBAR_IME_SWITCHER_BUTTON_LONGPRESS);
+ verify(mInputMethodManager).showInputMethodPickerFromSystem(
+ true /* showAuxiliarySubtypes */, mNavigationBar.mDisplayId);
+ } else {
+ verify(mUiEventLogger, never()).log(NAVBAR_IME_SWITCHER_BUTTON_LONGPRESS);
+ verify(mInputMethodManager, never()).showInputMethodPickerFromSystem(
+ anyBoolean() /* showAuxiliarySubtypes */, anyInt() /* displayId */);
+ }
+ }
+
+ @Test
public void testRegisteredWithUserTracker() {
mNavigationBar.init();
mNavigationBar.onViewAttached();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTransitionsTest.java
index c7a92d2a390d..3621ab975daf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTransitionsTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -32,6 +32,8 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/KeyButtonViewTest.java
index 841f620485ae..403a883e1760 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/KeyButtonViewTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import static android.view.KeyEvent.ACTION_DOWN;
import static android.view.KeyEvent.ACTION_UP;
@@ -26,12 +26,12 @@ import static android.view.KeyEvent.KEYCODE_BACK;
import static android.view.KeyEvent.KEYCODE_HOME;
import static android.view.KeyEvent.KEYCODE_UNKNOWN;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_LONGPRESS;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_TAP;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_LONGPRESS;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_TAP;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_TAP;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_TAP;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_TAP;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_TAP;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NavigationBarContextTest.java
index 7eb7c8e9ada8..79c4a96e84bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NavigationBarContextTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrameTest.java
index 6a3c6157a0a0..7941a68fa91e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrameTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
index f624f2029b36..b7fb759eb138 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
@@ -57,7 +57,9 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.anyString
+import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
import org.mockito.MockitoSession
import org.mockito.quality.Strictness
@@ -75,6 +77,9 @@ internal class NoteTaskQuickAffordanceConfigTest : SysuiTestCase() {
private lateinit var mockitoSession: MockitoSession
+ private val spiedContext = spy(context)
+ private val spiedResources = spy(spiedContext.resources)
+
@Before
fun setUp() {
mockitoSession =
@@ -100,6 +105,8 @@ internal class NoteTaskQuickAffordanceConfigTest : SysuiTestCase() {
)
)
.thenReturn(listOf("com.google.test.notes"))
+
+ `when`(spiedContext.resources).thenReturn(spiedResources)
}
@After
@@ -109,7 +116,7 @@ internal class NoteTaskQuickAffordanceConfigTest : SysuiTestCase() {
private fun createUnderTest(isEnabled: Boolean = true): KeyguardQuickAffordanceConfig =
NoteTaskQuickAffordanceConfig(
- context = context,
+ context = spiedContext,
controller = controller,
stylusManager = stylusManager,
userManager = userManager,
@@ -132,126 +139,262 @@ internal class NoteTaskQuickAffordanceConfigTest : SysuiTestCase() {
)
// region lockScreenState
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun lockScreenState_stylusUsed_userUnlocked_isSelected_shouldEmitVisible() = runTest {
- val underTest = createUnderTest()
- TestConfig().setStylusEverUsed(true).setUserUnlocked(true).setConfigSelections(underTest)
+ fun lockScreenState_stylusUnused_userLocked_customizationDisabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(false)
+ .setUserUnlocked(false)
+ .setLockScreenCustomizationEnabled(false)
+ .setConfigSelections()
- val actual by collectLastValue(underTest.lockScreenState)
+ val actual by collectLastValue(underTest.lockScreenState)
- assertThat(actual).isEqualTo(createLockScreenStateVisible())
- }
+ assertThat(actual).isEqualTo(LockScreenState.Hidden)
+ }
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun lockScreenState_stylusUsed_userUnlocked_isSelected_noDefaultNotesAppSet_shouldEmitHidden() =
+ fun lockScreenState_stylusUnused_userLocked_customizationDisabled_notesLockScreenShortcutSelected_shouldEmitHidden() =
runTest {
val underTest = createUnderTest()
TestConfig()
- .setStylusEverUsed(true)
+ .setStylusEverUsed(false)
+ .setUserUnlocked(false)
+ .setLockScreenCustomizationEnabled(false)
+ .setConfigSelections(underTest)
+
+ val actual by collectLastValue(underTest.lockScreenState)
+
+ assertThat(actual).isEqualTo(LockScreenState.Hidden)
+ }
+
+ @Suppress("ktlint:standard:max-line-length")
+ @Test
+ fun lockScreenState_stylusUnused_userLocked_customizationEnabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(false)
+ .setUserUnlocked(false)
+ .setLockScreenCustomizationEnabled(true)
+ .setConfigSelections()
+
+ val actual by collectLastValue(underTest.lockScreenState)
+
+ assertThat(actual).isEqualTo(LockScreenState.Hidden)
+ }
+
+ @Suppress("ktlint:standard:max-line-length")
+ @Test
+ fun lockScreenState_stylusUnused_userLocked_customizationEnabled_notesLockScreenShortcutSelected_shouldEmitHidden() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(false)
+ .setUserUnlocked(false)
+ .setLockScreenCustomizationEnabled(true)
+ .setConfigSelections(underTest)
+
+ val actual by collectLastValue(underTest.lockScreenState)
+
+ assertThat(actual).isEqualTo(LockScreenState.Hidden)
+ }
+
+ @Suppress("ktlint:standard:max-line-length")
+ @Test
+ fun lockScreenState_stylusUnused_userUnlocked_customizationDisabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(false)
.setUserUnlocked(true)
+ .setLockScreenCustomizationEnabled(false)
+ .setConfigSelections()
+
+ val actual by collectLastValue(underTest.lockScreenState)
+
+ assertThat(actual).isEqualTo(LockScreenState.Hidden)
+ }
+
+ @Suppress("ktlint:standard:max-line-length")
+ @Test
+ fun lockScreenState_stylusUnused_userUnlocked_customizationDisabled_notesLockScreenShortcutSelected_shouldEmitHidden() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(false)
+ .setUserUnlocked(true)
+ .setLockScreenCustomizationEnabled(false)
.setConfigSelections(underTest)
- whenever(
- roleManager.getRoleHoldersAsUser(
- eq(RoleManager.ROLE_NOTES),
- any(UserHandle::class.java)
- )
- )
- .thenReturn(emptyList())
val actual by collectLastValue(underTest.lockScreenState)
assertThat(actual).isEqualTo(LockScreenState.Hidden)
}
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun lockScreenState_stylusUnused_userUnlocked_isSelected_shouldEmitHidden() = runTest {
- val underTest = createUnderTest()
- TestConfig().setStylusEverUsed(false).setUserUnlocked(true).setConfigSelections(underTest)
+ fun lockScreenState_stylusUnused_userUnlocked_customizationEnabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(false)
+ .setUserUnlocked(true)
+ .setLockScreenCustomizationEnabled(true)
+ .setConfigSelections()
- val actual by collectLastValue(underTest.lockScreenState)
+ val actual by collectLastValue(underTest.lockScreenState)
- assertThat(actual).isEqualTo(LockScreenState.Hidden)
- }
+ assertThat(actual).isEqualTo(LockScreenState.Hidden)
+ }
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun lockScreenState_stylusUsed_userLocked_isSelected_shouldEmitHidden() = runTest {
- val underTest = createUnderTest()
- TestConfig().setStylusEverUsed(true).setUserUnlocked(false).setConfigSelections(underTest)
+ fun lockScreenState_stylusUnused_userUnlocked_customizationEnabled_notesLockScreenShortcutSelected_shouldEmitVisible() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(false)
+ .setUserUnlocked(true)
+ .setLockScreenCustomizationEnabled(true)
+ .setConfigSelections(underTest)
- val actual by collectLastValue(underTest.lockScreenState)
+ val actual by collectLastValue(underTest.lockScreenState)
- assertThat(actual).isEqualTo(LockScreenState.Hidden)
- }
+ assertThat(actual).isEqualTo(createLockScreenStateVisible())
+ }
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun lockScreenState_stylusUsed_userUnlocked_noSelected_shouldEmitHidden() = runTest {
- TestConfig().setStylusEverUsed(true).setUserUnlocked(true).setConfigSelections()
+ fun lockScreenState_stylusUsed_userLocked_customizationDisabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(true)
+ .setUserUnlocked(false)
+ .setLockScreenCustomizationEnabled(false)
+ .setConfigSelections()
- val underTest = createUnderTest()
- val actual by collectLastValue(underTest.lockScreenState)
+ val actual by collectLastValue(underTest.lockScreenState)
- assertThat(actual).isEqualTo(LockScreenState.Hidden)
- }
+ assertThat(actual).isEqualTo(LockScreenState.Hidden)
+ }
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun lockScreenState_stylusUnused_userUnlocked_noSelected_shouldEmitHidden() = runTest {
- TestConfig().setStylusEverUsed(false).setUserUnlocked(true).setConfigSelections()
+ fun lockScreenState_stylusUsed_userLocked_customizationDisabled_notesLockScreenShortcutSelected_shouldEmitHidden() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(true)
+ .setUserUnlocked(false)
+ .setLockScreenCustomizationEnabled(false)
+ .setConfigSelections(underTest)
- val underTest = createUnderTest()
- val actual by collectLastValue(underTest.lockScreenState)
+ val actual by collectLastValue(underTest.lockScreenState)
- assertThat(actual).isEqualTo(LockScreenState.Hidden)
- }
+ assertThat(actual).isEqualTo(LockScreenState.Hidden)
+ }
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun lockScreenState_stylusUsed_userLocked_noSelected_shouldEmitHidden() = runTest {
- TestConfig().setStylusEverUsed(true).setUserUnlocked(false).setConfigSelections()
+ fun lockScreenState_stylusUsed_userLocked_customizationEnabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(true)
+ .setUserUnlocked(false)
+ .setLockScreenCustomizationEnabled(true)
+ .setConfigSelections()
- val underTest = createUnderTest()
- val actual by collectLastValue(underTest.lockScreenState)
+ val actual by collectLastValue(underTest.lockScreenState)
- assertThat(actual).isEqualTo(LockScreenState.Hidden)
- }
+ assertThat(actual).isEqualTo(LockScreenState.Hidden)
+ }
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun lockScreenState_stylusUsed_userUnlocked_customSelections_shouldEmitHidden() = runTest {
- TestConfig().setStylusEverUsed(true).setUserUnlocked(true).setConfigSelections(mock())
+ fun lockScreenState_stylusUsed_userLocked_customizationEnabled_notesLockScreenShortcutSelected_shouldEmitHidden() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(true)
+ .setUserUnlocked(false)
+ .setLockScreenCustomizationEnabled(true)
+ .setConfigSelections(underTest)
- val underTest = createUnderTest()
- val actual by collectLastValue(underTest.lockScreenState)
+ val actual by collectLastValue(underTest.lockScreenState)
- assertThat(actual).isEqualTo(LockScreenState.Hidden)
- }
+ assertThat(actual).isEqualTo(LockScreenState.Hidden)
+ }
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun lockScreenState_stylusUnused_userUnlocked_customSelections_shouldEmitHidden() = runTest {
- TestConfig().setStylusEverUsed(false).setUserUnlocked(true).setConfigSelections(mock())
+ fun lockScreenState_stylusUsed_userUnlocked_customizationDisabled_notesLockScreenShortcutNotSelected_shouldEmitVisible() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(true)
+ .setUserUnlocked(true)
+ .setLockScreenCustomizationEnabled(false)
+ .setConfigSelections()
- val underTest = createUnderTest()
- val actual by collectLastValue(underTest.lockScreenState)
+ val actual by collectLastValue(underTest.lockScreenState)
- assertThat(actual).isEqualTo(LockScreenState.Hidden)
- }
+ assertThat(actual).isEqualTo(createLockScreenStateVisible())
+ }
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun lockScreenState_stylusUsed_userLocked_customSelections_shouldEmitHidden() = runTest {
- TestConfig().setStylusEverUsed(true).setUserUnlocked(false).setConfigSelections(mock())
+ fun lockScreenState_stylusUsed_userUnlocked_customizationDisabled_notesLockScreenShortcutSelected_shouldEmitVisible() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(true)
+ .setUserUnlocked(true)
+ .setLockScreenCustomizationEnabled(false)
+ .setConfigSelections(underTest)
- val underTest = createUnderTest()
- val actual by collectLastValue(underTest.lockScreenState)
+ val actual by collectLastValue(underTest.lockScreenState)
- assertThat(actual).isEqualTo(LockScreenState.Hidden)
- }
+ assertThat(actual).isEqualTo(createLockScreenStateVisible())
+ }
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun lockScreenState_isNotEnabled_shouldEmitHidden() = runTest {
- TestConfig().setStylusEverUsed(true).setUserUnlocked(true).setConfigSelections()
+ fun lockScreenState_stylusUsed_userUnlocked_customizationEnabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(true)
+ .setUserUnlocked(true)
+ .setLockScreenCustomizationEnabled(true)
+ .setConfigSelections()
- val underTest = createUnderTest(isEnabled = false)
- val actual by collectLastValue(underTest.lockScreenState)
+ val actual by collectLastValue(underTest.lockScreenState)
+
+ assertThat(actual).isEqualTo(LockScreenState.Hidden)
+ }
+
+ @Suppress("ktlint:standard:max-line-length")
+ @Test
+ fun lockScreenState_stylusUsed_userUnlocked_customizationEnabled_notesLockScreenShortcutSelected_shouldEmitVisible() =
+ runTest {
+ val underTest = createUnderTest()
+ TestConfig()
+ .setStylusEverUsed(true)
+ .setUserUnlocked(true)
+ .setLockScreenCustomizationEnabled(true)
+ .setConfigSelections(underTest)
+
+ val actual by collectLastValue(underTest.lockScreenState)
+
+ assertThat(actual).isEqualTo(createLockScreenStateVisible())
+ }
- assertThat(actual).isEqualTo(LockScreenState.Hidden)
- }
// endregion
@Test
@@ -294,18 +437,24 @@ internal class NoteTaskQuickAffordanceConfigTest : SysuiTestCase() {
.isEqualTo(ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE)
assertThat(disabled.actionIntent?.`package`).isEqualTo(context.packageName)
}
+
// endregion
private inner class TestConfig {
fun setStylusEverUsed(value: Boolean) = also {
- whenever(InputSettings.isStylusEverUsed(mContext)).thenReturn(value)
+ whenever(InputSettings.isStylusEverUsed(spiedContext)).thenReturn(value)
}
fun setUserUnlocked(value: Boolean) = also {
whenever(userManager.isUserUnlocked).thenReturn(value)
}
+ fun setLockScreenCustomizationEnabled(value: Boolean) = also {
+ `when`(spiedResources.getBoolean(R.bool.custom_lockscreen_shortcuts_enabled))
+ .thenReturn(value)
+ }
+
fun setConfigSelections(vararg values: KeyguardQuickAffordanceConfig) = also {
val slotKey = "bottom-right"
val configSnapshots = values.toList()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index 16a022f720ae..8681123d0c2b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -276,8 +276,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mLauncherApps = mock(LauncherApps.class);
- mManager = new PeopleSpaceWidgetManager(mContext, mAppWidgetManager, mIPeopleManager,
- mPeopleManager, mLauncherApps, mNotifCollection, mPackageManager,
+ mManager = new PeopleSpaceWidgetManager(mContext, Optional.of(mAppWidgetManager),
+ mIPeopleManager, mPeopleManager, mLauncherApps, mNotifCollection, mPackageManager,
Optional.of(mBubbles), mUserManager, mBackupManager, mINotificationManager,
mNotificationManager, mFakeExecutor, mUserTracker);
mManager.attach(mListenerService);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
index 415cc7c99b2c..988769fe6660 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
@@ -471,7 +471,7 @@ class QSTileViewImplTest : SysuiTestCase() {
}
@Test
- fun onPrepareForLaunch_paddingForLaunchAnimationIsConfigured() {
+ fun getPaddingForLaunchAnimation_onLongClickedState_paddingForLaunchAnimationIsConfigured() {
val startingWidth = 100
val startingHeight = 50
val deltaWidth = (QSTileViewImpl.LONG_PRESS_EFFECT_WIDTH_SCALE - 1f) * startingWidth
@@ -480,8 +480,8 @@ class QSTileViewImplTest : SysuiTestCase() {
// GIVEN that long-press effect properties are initialized
tileView.initializeLongPressProperties(startingHeight, startingWidth)
- // WHEN the tile is preparing for the launch animation
- tileView.prepareForLaunch()
+ // WHEN the long-press effect has ended in the long-click state
+ kosmos.qsLongPressEffect.setState(QSLongPressEffect.State.LONG_CLICKED)
// THE animation padding corresponds to the tile's growth due to the effect
val padding = tileView.getPaddingForLaunchAnimation()
@@ -497,6 +497,22 @@ class QSTileViewImplTest : SysuiTestCase() {
}
@Test
+ fun getPaddingForLaunchAnimation_notInLongClickState_paddingForLaunchAnimationIsEmpty() {
+ val startingWidth = 100
+ val startingHeight = 50
+
+ // GIVEN that long-press effect properties are initialized
+ tileView.initializeLongPressProperties(startingHeight, startingWidth)
+
+ // WHEN the long-press effect has ended in the click state
+ kosmos.qsLongPressEffect.setState(QSLongPressEffect.State.CLICKED)
+
+ // THE animation padding is empty
+ val padding = tileView.getPaddingForLaunchAnimation()
+ assertThat(padding.isEmpty).isTrue()
+ }
+
+ @Test
fun onActivityLaunchAnimationEnd_onFreshTile_longPressPropertiesAreReset() {
// WHEN an activity launch animation ends on a fresh tile
tileView.onActivityLaunchAnimationEnd()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ModesTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ModesTileTest.kt
new file mode 100644
index 000000000000..4c77fb84d8ce
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ModesTileTest.kt
@@ -0,0 +1,167 @@
+/*
+ * 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.qs.tiles
+
+import android.graphics.drawable.TestStubDrawable
+import android.os.Handler
+import android.platform.test.annotations.EnableFlags
+import android.service.quicksettings.Tile
+import android.testing.TestableLooper
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.settingslib.notification.data.repository.FakeZenModeRepository
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileDataInteractor
+import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.modes.ui.ModesTileMapper
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.res.R
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.settings.FakeSettings
+import com.android.systemui.util.settings.SecureSettings
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.whenever
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@EnableFlags(android.app.Flags.FLAG_MODES_UI)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@RunWithLooper(setAsMainLooper = true)
+class ModesTileTest : SysuiTestCase() {
+
+ @Mock private lateinit var qsHost: QSHost
+
+ @Mock private lateinit var metricsLogger: MetricsLogger
+
+ @Mock private lateinit var statusBarStateController: StatusBarStateController
+
+ @Mock private lateinit var activityStarter: ActivityStarter
+
+ @Mock private lateinit var qsLogger: QSLogger
+
+ @Mock private lateinit var uiEventLogger: QsEventLogger
+
+ @Mock private lateinit var qsTileConfigProvider: QSTileConfigProvider
+
+ private val inputHandler = FakeQSTileIntentUserInputHandler()
+ private val zenModeRepository = FakeZenModeRepository()
+ private val tileDataInteractor = ModesTileDataInteractor(zenModeRepository)
+ private val mapper =
+ ModesTileMapper(
+ context.orCreateTestableResources
+ .apply {
+ addOverride(R.drawable.qs_dnd_icon_on, TestStubDrawable())
+ addOverride(R.drawable.qs_dnd_icon_off, TestStubDrawable())
+ }
+ .resources,
+ context.theme,
+ )
+
+ private val testDispatcher = StandardTestDispatcher()
+ private val testScope = TestScope(testDispatcher)
+
+ private lateinit var userActionInteractor: ModesTileUserActionInteractor
+ private lateinit var secureSettings: SecureSettings
+ private lateinit var testableLooper: TestableLooper
+ private lateinit var underTest: ModesTile
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ testableLooper = TestableLooper.get(this)
+ secureSettings = FakeSettings()
+
+ // Allow the tile to load resources
+ whenever(qsHost.context).thenReturn(context)
+ whenever(qsHost.userContext).thenReturn(context)
+
+ whenever(qsTileConfigProvider.getConfig(any()))
+ .thenReturn(
+ QSTileConfigTestBuilder.build {
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = R.drawable.qs_dnd_icon_off,
+ labelRes = R.string.quick_settings_modes_label,
+ )
+ }
+ )
+
+ userActionInteractor = ModesTileUserActionInteractor(inputHandler)
+
+ underTest =
+ ModesTile(
+ qsHost,
+ uiEventLogger,
+ testableLooper.looper,
+ Handler(testableLooper.looper),
+ FalsingManagerFake(),
+ metricsLogger,
+ statusBarStateController,
+ activityStarter,
+ qsLogger,
+ qsTileConfigProvider,
+ tileDataInteractor,
+ mapper,
+ userActionInteractor,
+ )
+
+ underTest.initialize()
+ underTest.setListening(Object(), true)
+
+ testableLooper.processAllMessages()
+ }
+
+ @After
+ fun tearDown() {
+ underTest.destroy()
+ testableLooper.processAllMessages()
+ }
+
+ @Test
+ fun stateUpdatesOnChange() =
+ testScope.runTest {
+ assertThat(underTest.state.state).isEqualTo(Tile.STATE_INACTIVE)
+
+ zenModeRepository.addMode(id = "Test", active = true)
+ runCurrent()
+ testableLooper.processAllMessages()
+
+ assertThat(underTest.state.state).isEqualTo(Tile.STATE_ACTIVE)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
index 798e9fb208b7..d6bde27dfb62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.os.Handler;
+import android.platform.test.annotations.RequiresFlagsDisabled;
import android.service.quicksettings.Tile;
import android.testing.TestableLooper;
@@ -32,6 +33,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.internal.logging.MetricsLogger;
+import com.android.server.display.feature.flags.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.plugins.ActivityStarter;
@@ -131,6 +133,7 @@ public class ReduceBrightColorsTileTest extends SysuiTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_EVEN_DIMMER)
public void testActive_clicked_featureIsActivated() {
when(mReduceBrightColorsController.isReduceBrightColorsActivated()).thenReturn(false);
mTile.refreshState();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java
index 5273495bec2f..eea02eec7099 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java
@@ -61,6 +61,7 @@ import android.view.WindowManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.settingslib.wifi.WifiUtils;
@@ -160,7 +161,7 @@ public class InternetDialogDelegateControllerTest extends SysuiTestCase {
@Mock
InternetDialogController.InternetDialogCallback mInternetDialogCallback;
@Mock
- private WindowManager mWindowManager;
+ private ViewCaptureAwareWindowManager mWindowManager;
@Mock
private ToastFactory mToastFactory;
@Mock
@@ -232,8 +233,9 @@ public class InternetDialogDelegateControllerTest extends SysuiTestCase {
mSubscriptionManager, mTelephonyManager, mWifiManager,
mConnectivityManager, mHandler, mExecutor, mBroadcastDispatcher,
mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController,
- mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker,
- mLocationController, mDialogTransitionAnimator, mWifiStateWorker, mFlags);
+ mWindowManager, mToastFactory, mWorkerHandler,
+ mCarrierConfigTracker, mLocationController, mDialogTransitionAnimator,
+ mWifiStateWorker, mFlags);
mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
mInternetDialogController.mOnSubscriptionsChangedListener);
mInternetDialogController.onStart(mInternetDialogCallback, true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
index 2444af7204e7..477c50b58519 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
@@ -18,6 +18,8 @@ package com.android.systemui.screenrecord;
import static android.os.Process.myUid;
+import static com.android.systemui.log.LogBufferHelperKt.logcatLogBuffer;
+
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertFalse;
@@ -69,10 +71,6 @@ import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
-/**
- * Tests for exception handling and bitmap configuration in adding smart actions to Screenshot
- * Notification.
- */
public class RecordingControllerTest extends SysuiTestCase {
private static final int TEST_USER_ID = 12345;
@@ -146,6 +144,7 @@ public class RecordingControllerTest extends SysuiTestCase {
mFeatureFlags,
() -> mDevicePolicyResolver,
mUserTracker,
+ new RecordingControllerLogger(logcatLogBuffer("RecordingControllerTest")),
mMediaProjectionMetricsLogger,
mScreenCaptureDisabledDialogDelegate,
mScreenRecordDialogFactory,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
index db607fd56643..cc8d7d532bda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
@@ -109,7 +109,7 @@ class ScreenRecordPermissionDialogDelegateTest : SysuiTestCase() {
fun testShowDialog_partialScreenSharingEnabled_optionsSpinnerIsVisible() {
showDialog()
- val visibility = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner).visibility
+ val visibility = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options).visibility
assertThat(visibility).isEqualTo(View.VISIBLE)
}
@@ -155,7 +155,7 @@ class ScreenRecordPermissionDialogDelegateTest : SysuiTestCase() {
fun showDialog_singleAppIsDefault() {
showDialog()
- val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner)
+ val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
val singleApp = context.getString(R.string.screen_share_permission_dialog_option_single_app)
assertEquals(spinner.adapter.getItem(0), singleApp)
}
@@ -217,7 +217,7 @@ class ScreenRecordPermissionDialogDelegateTest : SysuiTestCase() {
}
private fun onSpinnerItemSelected(position: Int) {
- val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner)
+ val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
checkNotNull(spinner.onItemSelectedListener)
.onItemSelected(spinner, mock(), position, /* id= */ 0)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
index 0b81b5e6de35..8d3a29ac7278 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
@@ -69,7 +69,7 @@ class TakeScreenshotExecutorTest : SysuiTestCase() {
@Before
fun setUp() {
- whenever(controllerFactory.create(any(), any())).thenReturn(controller)
+ whenever(controllerFactory.create(any())).thenReturn(controller)
whenever(notificationControllerFactory.create(eq(0))).thenReturn(notificationsController0)
whenever(notificationControllerFactory.create(eq(1))).thenReturn(notificationsController1)
}
@@ -83,8 +83,8 @@ class TakeScreenshotExecutorTest : SysuiTestCase() {
val onSaved = { _: Uri? -> }
screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
- verify(controllerFactory).create(eq(internalDisplay), any())
- verify(controllerFactory, never()).create(eq(externalDisplay), any())
+ verify(controllerFactory).create(eq(internalDisplay))
+ verify(controllerFactory, never()).create(eq(externalDisplay))
val capturer = ArgumentCaptor<ScreenshotData>()
@@ -118,8 +118,8 @@ class TakeScreenshotExecutorTest : SysuiTestCase() {
callback
)
- verify(controllerFactory).create(eq(internalDisplay), any())
- verify(controllerFactory, never()).create(eq(externalDisplay), any())
+ verify(controllerFactory).create(eq(internalDisplay))
+ verify(controllerFactory, never()).create(eq(externalDisplay))
val capturer = ArgumentCaptor<ScreenshotData>()
@@ -151,7 +151,7 @@ class TakeScreenshotExecutorTest : SysuiTestCase() {
@Test
fun executeScreenshots_allowedTypes_allCaptured() =
testScope.runTest {
- whenever(controllerFactory.create(any(), any())).thenReturn(controller)
+ whenever(controllerFactory.create(any())).thenReturn(controller)
setDisplays(
display(TYPE_INTERNAL, id = 0),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
index baf1357a1ae0..193d29c1d550 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
@@ -334,13 +334,17 @@ public final class AppClipsViewModelTest extends SysuiTestCase {
}
private void resetPackageManagerMockingForUsingFallbackBacklinks() {
+ ResolveInfo backlinksTaskResolveInfo = createBacklinksTaskResolveInfo();
reset(mPackageManager);
when(mPackageManager.loadItemIcon(any(), any())).thenReturn(FAKE_DRAWABLE);
when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
- // First the logic queries whether a package has a launcher activity, this should
+ // Firstly, the logic queries whether a package has a launcher activity, this should
// resolve otherwise the logic filters out the task.
- .thenReturn(createBacklinksTaskResolveInfo())
- // Then logic queries with the backlinks intent, this should not resolve for the
+ .thenReturn(backlinksTaskResolveInfo)
+ // Secondly, the logic builds a fallback main launcher intent, this should also
+ // resolve for the fallback intent to build correctly.
+ .thenReturn(backlinksTaskResolveInfo)
+ // Lastly, logic queries with the backlinks intent, this should not resolve for the
// logic to use the fallback intent.
.thenReturn(null);
}
@@ -360,6 +364,8 @@ public final class AppClipsViewModelTest extends SysuiTestCase {
assertThat(actualBacklinksIntent.getPackage()).isEqualTo(BACKLINKS_TASK_PACKAGE_NAME);
assertThat(actualBacklinksIntent.getAction()).isEqualTo(ACTION_MAIN);
assertThat(actualBacklinksIntent.getCategories()).containsExactly(CATEGORY_LAUNCHER);
+ assertThat(actualBacklinksIntent.getComponent()).isEqualTo(
+ new ComponentName(BACKLINKS_TASK_PACKAGE_NAME, BACKLINKS_TASK_APP_NAME));
}
private static ResolveInfo createBacklinksTaskResolveInfo() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index b0213a4b6421..169511f827ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -16,19 +16,24 @@
package com.android.systemui.shade
+import android.graphics.Insets
import android.graphics.Rect
import android.os.PowerManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.ViewUtils
import android.view.MotionEvent
import android.view.View
+import android.view.WindowInsets
import android.widget.FrameLayout
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.Flags
+import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_BACK_GESTURE
import com.android.systemui.SysuiTestCase
import com.android.systemui.ambient.touch.TouchHandler
import com.android.systemui.ambient.touch.TouchMonitor
@@ -66,6 +71,9 @@ import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
@ExperimentalCoroutinesApi
@RunWith(AndroidTestingRunner::class)
@@ -317,6 +325,7 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_GLANCEABLE_HUB_BACK_GESTURE)
fun gestureExclusionZone_setAfterInit() =
with(kosmos) {
testScope.runTest {
@@ -325,10 +334,41 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
assertThat(containerView.systemGestureExclusionRects)
.containsExactly(
Rect(
- /* left */ 0,
- /* top */ TOP_SWIPE_REGION_WIDTH,
- /* right */ CONTAINER_WIDTH,
- /* bottom */ CONTAINER_HEIGHT - BOTTOM_SWIPE_REGION_WIDTH
+ /* left= */ 0,
+ /* top= */ TOP_SWIPE_REGION_WIDTH,
+ /* right= */ CONTAINER_WIDTH,
+ /* bottom= */ CONTAINER_HEIGHT - BOTTOM_SWIPE_REGION_WIDTH
+ ),
+ Rect(
+ /* left= */ 0,
+ /* top= */ 0,
+ /* right= */ 0,
+ /* bottom= */ CONTAINER_HEIGHT
+ )
+ )
+ }
+ }
+
+ @Test
+ @EnableFlags(FLAG_GLANCEABLE_HUB_BACK_GESTURE)
+ fun gestureExclusionZone_setAfterInit_backGestureEnabled() =
+ with(kosmos) {
+ testScope.runTest {
+ goToScene(CommunalScenes.Communal)
+
+ assertThat(containerView.systemGestureExclusionRects)
+ .containsExactly(
+ Rect(
+ /* left= */ FAKE_INSETS.left,
+ /* top= */ TOP_SWIPE_REGION_WIDTH,
+ /* right= */ CONTAINER_WIDTH - FAKE_INSETS.right,
+ /* bottom= */ CONTAINER_HEIGHT - BOTTOM_SWIPE_REGION_WIDTH
+ ),
+ Rect(
+ /* left= */ 0,
+ /* top= */ 0,
+ /* right= */ FAKE_INSETS.right,
+ /* bottom= */ CONTAINER_HEIGHT
)
)
}
@@ -340,6 +380,9 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
testScope.runTest {
goToScene(CommunalScenes.Communal)
+ // Exclusion rect is set.
+ assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
+
// Shade shows up.
shadeTestUtil.setQsExpansion(1.0f)
testableLooper.processAllMessages()
@@ -355,6 +398,9 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
testScope.runTest {
goToScene(CommunalScenes.Communal)
+ // Exclusion rect is set.
+ assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
+
// Bouncer is visible.
fakeKeyguardBouncerRepository.setPrimaryShow(true)
testableLooper.processAllMessages()
@@ -371,7 +417,7 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
goToScene(CommunalScenes.Communal)
// Exclusion rect is set.
- assertThat(containerView.systemGestureExclusionRects).hasSize(1)
+ assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
// Leave the hub.
goToScene(CommunalScenes.Blank)
@@ -399,7 +445,12 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
}
private fun initAndAttachContainerView() {
- containerView = View(context)
+ val mockInsets =
+ mock<WindowInsets> {
+ on { getInsets(WindowInsets.Type.systemGestures()) } doReturn FAKE_INSETS
+ }
+
+ containerView = spy(View(context)) { on { rootWindowInsets } doReturn mockInsets }
parentView = FrameLayout(context)
@@ -422,6 +473,7 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
private const val RIGHT_SWIPE_REGION_WIDTH = 20
private const val TOP_SWIPE_REGION_WIDTH = 12
private const val BOTTOM_SWIPE_REGION_WIDTH = 14
+ private val FAKE_INSETS = Insets.of(10, 20, 30, 50)
/**
* A touch down event right in the middle of the screen, to avoid being in any of the swipe
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index e7ca091aaf4c..b80d1a472a72 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -419,7 +419,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mShadeAnimationInteractor = new ShadeAnimationInteractorLegacyImpl(
new ShadeAnimationRepository(), mShadeRepository);
mPowerInteractor = keyguardInteractorDeps.getPowerInteractor();
- when(mKeyguardTransitionInteractor.isInTransitionToStateWhere(any())).thenReturn(
+ when(mKeyguardTransitionInteractor.isInTransitionWhere(any(), any())).thenReturn(
MutableStateFlow(false));
when(mKeyguardTransitionInteractor.isInTransition(any(), any()))
.thenReturn(emptyFlow());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
index 97acc6e53cdf..7d4918a30d9c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
@@ -19,8 +19,8 @@ package com.android.systemui.shade.data.repository
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.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
@@ -28,7 +28,6 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class ShadeRepositoryImplTest : SysuiTestCase() {
@@ -91,37 +90,37 @@ class ShadeRepositoryImplTest : SysuiTestCase() {
@Test
fun updateLegacyShadeTracking() =
testScope.runTest {
- assertThat(underTest.legacyShadeTracking.value).isEqualTo(false)
+ assertThat(underTest.legacyShadeTracking.value).isFalse()
underTest.setLegacyShadeTracking(true)
- assertThat(underTest.legacyShadeTracking.value).isEqualTo(true)
+ assertThat(underTest.legacyShadeTracking.value).isTrue()
}
@Test
fun updateLegacyLockscreenShadeTracking() =
testScope.runTest {
- assertThat(underTest.legacyLockscreenShadeTracking.value).isEqualTo(false)
+ assertThat(underTest.legacyLockscreenShadeTracking.value).isFalse()
underTest.setLegacyLockscreenShadeTracking(true)
- assertThat(underTest.legacyLockscreenShadeTracking.value).isEqualTo(true)
+ assertThat(underTest.legacyLockscreenShadeTracking.value).isTrue()
}
@Test
fun updateLegacyQsTracking() =
testScope.runTest {
- assertThat(underTest.legacyQsTracking.value).isEqualTo(false)
+ assertThat(underTest.legacyQsTracking.value).isFalse()
underTest.setLegacyQsTracking(true)
- assertThat(underTest.legacyQsTracking.value).isEqualTo(true)
+ assertThat(underTest.legacyQsTracking.value).isTrue()
}
@Test
fun updateLegacyExpandedOrAwaitingInputTransfer() =
testScope.runTest {
- assertThat(underTest.legacyExpandedOrAwaitingInputTransfer.value).isEqualTo(false)
+ assertThat(underTest.legacyExpandedOrAwaitingInputTransfer.value).isFalse()
underTest.setLegacyExpandedOrAwaitingInputTransfer(true)
- assertThat(underTest.legacyExpandedOrAwaitingInputTransfer.value).isEqualTo(true)
+ assertThat(underTest.legacyExpandedOrAwaitingInputTransfer.value).isTrue()
}
@Test
@@ -142,36 +141,46 @@ class ShadeRepositoryImplTest : SysuiTestCase() {
@Test
fun updateLegacyIsQsExpanded() =
testScope.runTest {
- assertThat(underTest.legacyIsQsExpanded.value).isEqualTo(false)
+ assertThat(underTest.legacyIsQsExpanded.value).isFalse()
underTest.setLegacyIsQsExpanded(true)
- assertThat(underTest.legacyIsQsExpanded.value).isEqualTo(true)
+ assertThat(underTest.legacyIsQsExpanded.value).isTrue()
}
@Test
fun updateLegacyExpandImmediate() =
testScope.runTest {
- assertThat(underTest.legacyExpandImmediate.value).isEqualTo(false)
+ assertThat(underTest.legacyExpandImmediate.value).isFalse()
underTest.setLegacyExpandImmediate(true)
- assertThat(underTest.legacyExpandImmediate.value).isEqualTo(true)
+ assertThat(underTest.legacyExpandImmediate.value).isTrue()
}
@Test
fun updateLegacyQsFullscreen() =
testScope.runTest {
- assertThat(underTest.legacyQsFullscreen.value).isEqualTo(false)
+ assertThat(underTest.legacyQsFullscreen.value).isFalse()
underTest.setLegacyQsFullscreen(true)
- assertThat(underTest.legacyQsFullscreen.value).isEqualTo(true)
+ assertThat(underTest.legacyQsFullscreen.value).isTrue()
}
@Test
fun updateLegacyIsClosing() =
testScope.runTest {
- assertThat(underTest.legacyIsClosing.value).isEqualTo(false)
+ assertThat(underTest.legacyIsClosing.value).isFalse()
underTest.setLegacyIsClosing(true)
- assertThat(underTest.legacyIsClosing.value).isEqualTo(true)
+ assertThat(underTest.legacyIsClosing.value).isTrue()
+ }
+
+ @Test
+ fun isShadeLayoutWide() =
+ testScope.runTest {
+ val isShadeLayoutWide by collectLastValue(underTest.isShadeLayoutWide)
+ assertThat(isShadeLayoutWide).isFalse()
+
+ underTest.setShadeLayoutWide(true)
+ assertThat(isShadeLayoutWide).isTrue()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index 2f52248dab6f..150f53d4ad25 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
@@ -28,6 +28,7 @@ import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.plugins.clocks.ClockId
import com.android.systemui.plugins.clocks.ClockMessageBuffers
import com.android.systemui.plugins.clocks.ClockMetadata
+import com.android.systemui.plugins.clocks.ClockPickerConfig
import com.android.systemui.plugins.clocks.ClockProviderPlugin
import com.android.systemui.plugins.clocks.ClockSettings
import com.android.systemui.plugins.PluginLifecycleManager
@@ -74,6 +75,7 @@ class ClockRegistryTest : SysuiTestCase() {
private lateinit var fakeDefaultProvider: FakeClockPlugin
private lateinit var pluginListener: PluginListener<ClockProviderPlugin>
private lateinit var registry: ClockRegistry
+ private lateinit var pickerConfig: ClockPickerConfig
private val featureFlags = FakeFeatureFlags()
companion object {
@@ -82,9 +84,9 @@ class ClockRegistryTest : SysuiTestCase() {
return null!!
}
- private fun failThumbnail(clockId: ClockId): Drawable? {
- fail("Unexpected call to getThumbnail: $clockId")
- return null
+ private fun failPickerConfig(clockId: ClockId): ClockPickerConfig {
+ fail("Unexpected call to getClockPickerConfig: $clockId")
+ return null!!
}
}
@@ -123,22 +125,31 @@ class ClockRegistryTest : SysuiTestCase() {
private class FakeClockPlugin : ClockProviderPlugin {
private val metadata = mutableListOf<ClockMetadata>()
private val createCallbacks = mutableMapOf<ClockId, (ClockId) -> ClockController>()
- private val thumbnailCallbacks = mutableMapOf<ClockId, (ClockId) -> Drawable?>()
+ private val pickerConfigs = mutableMapOf<ClockId, (ClockId) -> ClockPickerConfig>()
override fun getClocks() = metadata
- override fun createClock(settings: ClockSettings): ClockController =
- createCallbacks[settings.clockId!!]!!(settings.clockId!!)
- override fun getClockThumbnail(id: ClockId): Drawable? = thumbnailCallbacks[id]!!(id)
+
+ override fun createClock(settings: ClockSettings): ClockController {
+ val clockId = settings.clockId ?: throw IllegalArgumentException("No clockId specified")
+ return createCallbacks[clockId]?.invoke(clockId)
+ ?: throw NotImplementedError("No callback for '$clockId'")
+ }
+
+ override fun getClockPickerConfig(clockId: ClockId): ClockPickerConfig {
+ return pickerConfigs[clockId]?.invoke(clockId)
+ ?: throw NotImplementedError("No picker config for '$clockId'")
+ }
+
override fun initialize(buffers: ClockMessageBuffers?) { }
fun addClock(
id: ClockId,
create: (ClockId) -> ClockController = ::failFactory,
- getThumbnail: (ClockId) -> Drawable? = ::failThumbnail
+ getPickerConfig: (ClockId) -> ClockPickerConfig = ::failPickerConfig
): FakeClockPlugin {
metadata.add(ClockMetadata(id))
createCallbacks[id] = create
- thumbnailCallbacks[id] = getThumbnail
+ pickerConfigs[id] = getPickerConfig
return this
}
}
@@ -148,9 +159,10 @@ class ClockRegistryTest : SysuiTestCase() {
scheduler = TestCoroutineScheduler()
dispatcher = StandardTestDispatcher(scheduler)
scope = TestScope(dispatcher)
+ pickerConfig = ClockPickerConfig("CLOCK_ID", "NAME", "DESC", mockThumbnail)
fakeDefaultProvider = FakeClockPlugin()
- .addClock(DEFAULT_CLOCK_ID, { mockDefaultClock }, { mockThumbnail })
+ .addClock(DEFAULT_CLOCK_ID, { mockDefaultClock }, { pickerConfig })
whenever(mockContext.contentResolver).thenReturn(mockContentResolver)
val captor = argumentCaptor<PluginListener<ClockProviderPlugin>>()
@@ -215,8 +227,8 @@ class ClockRegistryTest : SysuiTestCase() {
@Test
fun clockIdConflict_ErrorWithoutCrash_unloadDuplicate() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", { mockClock }, { mockThumbnail })
- .addClock("clock_2", { mockClock }, { mockThumbnail })
+ .addClock("clock_1", { mockClock }, { pickerConfig })
+ .addClock("clock_2", { mockClock }, { pickerConfig })
val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
@@ -238,8 +250,8 @@ class ClockRegistryTest : SysuiTestCase() {
assertEquals(registry.createExampleClock("clock_1"), mockClock)
assertEquals(registry.createExampleClock("clock_2"), mockClock)
- assertEquals(registry.getClockThumbnail("clock_1"), mockThumbnail)
- assertEquals(registry.getClockThumbnail("clock_2"), mockThumbnail)
+ assertEquals(registry.getClockPickerConfig("clock_1"), pickerConfig)
+ assertEquals(registry.getClockPickerConfig("clock_2"), pickerConfig)
verify(lifecycle1, never()).unloadPlugin()
verify(lifecycle2, times(2)).unloadPlugin()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
index 2522ed7f9a3c..bbe03f001b03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
@@ -72,6 +72,10 @@ class DefaultClockProviderTest : SysuiTestCase() {
.thenReturn(mockSmallClockView)
whenever(layoutInflater.inflate(eq(R.layout.clock_default_large), any(), anyBoolean()))
.thenReturn(mockLargeClockView)
+ whenever(resources.getString(R.string.clock_default_name))
+ .thenReturn("DEFAULT_CLOCK_NAME")
+ whenever(resources.getString(R.string.clock_default_description))
+ .thenReturn("DEFAULT_CLOCK_DESC")
whenever(resources.getDrawable(R.drawable.clock_default_thumbnail, null))
.thenReturn(mockClockThumbnail)
whenever(mockSmallClockView.getLayoutParams()).thenReturn(FrameLayout.LayoutParams(10, 10))
@@ -85,7 +89,7 @@ class DefaultClockProviderTest : SysuiTestCase() {
// All providers need to provide clocks & thumbnails for exposed clocks
for (metadata in provider.getClocks()) {
assertNotNull(provider.createClock(metadata.clockId))
- assertNotNull(provider.getClockThumbnail(metadata.clockId))
+ assertNotNull(provider.getClockPickerConfig(metadata.clockId))
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java
index 6985a27a59c8..63e56eeb730f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java
@@ -66,7 +66,9 @@ public class KeyboardShortcutListSearchTest extends SysuiTestCase {
@Before
public void setUp() {
- mKeyboardShortcutListSearch = new KeyboardShortcutListSearch(mContext, mWindowManager);
+ when(mWindowManager.getApplicationLaunchKeyboardShortcuts(anyInt())).thenReturn(
+ new KeyboardShortcutGroup("", Collections.emptyList()));
+ mKeyboardShortcutListSearch = new KeyboardShortcutListSearch(mContext, mWindowManager, -1);
mKeyboardShortcutListSearch.sInstance = mKeyboardShortcutListSearch;
mKeyboardShortcutListSearch.mKeyboardShortcutsBottomSheetDialog = mBottomSheetDialog;
mKeyboardShortcutListSearch.mContext = mContext;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java
index 6ad8b8bc3637..105cf168995c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java
@@ -54,6 +54,7 @@ import org.mockito.junit.MockitoRule;
import org.mockito.stubbing.Answer;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
@SmallTest
@@ -71,6 +72,8 @@ public class KeyboardShortcutsTest extends SysuiTestCase {
@Before
public void setUp() {
+ when(mWindowManager.getApplicationLaunchKeyboardShortcuts(anyInt())).thenReturn(
+ new KeyboardShortcutGroup("", Collections.emptyList()));
mKeyboardShortcuts = new KeyboardShortcuts(mContext, mWindowManager);
KeyboardShortcuts.sInstance = mKeyboardShortcuts;
mKeyboardShortcuts.mKeyboardShortcutsDialog = mDialog;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index 69e8f4737a5a..9e6a498b325a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -6,26 +6,23 @@ import android.testing.TestableLooper.RunWithLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.ExpandHelper
-import com.android.systemui.SysUITestModule
import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
-import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
import com.android.systemui.classifier.FalsingCollectorFake
import com.android.systemui.classifier.FalsingManagerFake
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.FakeFeatureFlagsClassicModule
import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.domain.interactor.NaturalScrollingSettingObserver
+import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
import com.android.systemui.plugins.qs.QS
-import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
import com.android.systemui.res.R
+import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.domain.interactor.ShadeLockscreenInteractor
-import com.android.systemui.shade.data.repository.FakeShadeRepository
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel
-import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository
+import com.android.systemui.statusbar.disableflags.data.repository.disableFlagsRepository
+import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.NotificationTestHelper
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
@@ -33,17 +30,16 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.ScrimController
-import com.android.systemui.statusbar.policy.FakeConfigurationController
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
-import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.statusbar.policy.configurationController
+import com.android.systemui.statusbar.policy.fakeConfigurationController
+import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock
-import dagger.BindsInstance
-import dagger.Component
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
@@ -65,8 +61,8 @@ import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
private fun <T> anyObject(): T {
return Mockito.anyObject<T>()
@@ -77,15 +73,14 @@ private fun <T> anyObject(): T {
@RunWith(AndroidJUnit4::class)
@OptIn(ExperimentalCoroutinesApi::class)
class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
-
+ private val kosmos =
+ testKosmos().apply {
+ fakeFeatureFlagsClassic.apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) }
+ }
private lateinit var transitionController: LockscreenShadeTransitionController
- private lateinit var testComponent: TestComponent
- private val configurationController
- get() = testComponent.configurationController
- private val disableFlagsRepository
- get() = testComponent.disableFlagsRepository
- private val testScope
- get() = testComponent.testScope
+ private val configurationController = kosmos.fakeConfigurationController
+ private val disableFlagsRepository = kosmos.fakeDisableFlagsRepository
+ private val testScope = kosmos.testScope
private val qsSceneAdapter = FakeQSSceneAdapter({ mock() })
@@ -134,26 +129,6 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
whenever(keyguardBypassController.bypassEnabled).thenReturn(false)
whenever(naturalScrollingSettingObserver.isNaturalScrollingEnabled).thenReturn(true)
- testComponent =
- DaggerLockscreenShadeTransitionControllerTest_TestComponent.factory()
- .create(
- test = this,
- featureFlags =
- FakeFeatureFlagsClassicModule {
- set(Flags.FULL_SCREEN_USER_SWITCHER, false)
- },
- mocks =
- TestMocksModule(
- notificationShadeDepthController = depthController,
- keyguardBypassController = keyguardBypassController,
- mediaHierarchyManager = mediaHierarchyManager,
- notificationLockscreenUserManager = lockScreenUserManager,
- notificationStackScrollLayoutController = nsslController,
- scrimController = scrimController,
- statusBarStateController = statusbarStateController,
- )
- )
-
transitionController =
LockscreenShadeTransitionController(
statusBarStateController = statusbarStateController,
@@ -191,10 +166,10 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
falsingManager = FalsingManagerFake(),
dumpManager = mock(),
qsTransitionControllerFactory = { qsTransitionController },
- shadeRepository = testComponent.shadeRepository,
- shadeInteractor = testComponent.shadeInteractor,
+ shadeRepository = kosmos.shadeRepository,
+ shadeInteractor = kosmos.shadeInteractor,
splitShadeStateController = ResourcesSplitShadeStateController(),
- shadeLockscreenInteractorLazy = {shadeLockscreenInteractor},
+ shadeLockscreenInteractorLazy = { shadeLockscreenInteractor },
naturalScrollingSettingObserver = naturalScrollingSettingObserver,
lazyQSSceneAdapter = { qsSceneAdapter }
)
@@ -214,387 +189,424 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
}
@Test
- fun testCantDragDownWhenQSExpanded() {
- assertTrue("Can't drag down on keyguard", transitionController.canDragDown())
- whenever(qS.isFullyCollapsed).thenReturn(false)
- assertFalse("Can drag down when QS is expanded", transitionController.canDragDown())
- }
+ fun testCantDragDownWhenQSExpanded() =
+ testScope.runTest {
+ assertTrue("Can't drag down on keyguard", transitionController.canDragDown())
+ whenever(qS.isFullyCollapsed).thenReturn(false)
+ assertFalse("Can drag down when QS is expanded", transitionController.canDragDown())
+ }
@Test
- fun testCanDragDownInLockedDownShade() {
- whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
- assertFalse("Can drag down in shade locked", transitionController.canDragDown())
- whenever(nsslController.isInLockedDownShade).thenReturn(true)
- assertTrue("Can't drag down in locked down shade", transitionController.canDragDown())
- }
+ fun testCanDragDownInLockedDownShade() =
+ testScope.runTest {
+ whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
+ assertFalse("Can drag down in shade locked", transitionController.canDragDown())
+ whenever(nsslController.isInLockedDownShade).thenReturn(true)
+ assertTrue("Can't drag down in locked down shade", transitionController.canDragDown())
+ }
@Test
- fun testGoingToLockedShade() {
- transitionController.goToLockedShade(null)
- verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
- }
+ fun testGoingToLockedShade() =
+ testScope.runTest {
+ transitionController.goToLockedShade(null)
+ verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
+ }
@Test
- fun testWakingToShadeLockedWhenDozing() {
- whenever(statusbarStateController.isDozing).thenReturn(true)
- transitionController.goToLockedShade(null)
- verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
- assertTrue("Not waking to shade locked", transitionController.isWakingToShadeLocked)
- }
+ fun testWakingToShadeLockedWhenDozing() =
+ testScope.runTest {
+ whenever(statusbarStateController.isDozing).thenReturn(true)
+ transitionController.goToLockedShade(null)
+ verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
+ assertTrue("Not waking to shade locked", transitionController.isWakingToShadeLocked)
+ }
@Test
- fun testNotWakingToShadeLockedWhenNotDozing() {
- whenever(statusbarStateController.isDozing).thenReturn(false)
- transitionController.goToLockedShade(null)
- verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
- assertFalse(
- "Waking to shade locked when not dozing",
- transitionController.isWakingToShadeLocked
- )
- }
+ fun testNotWakingToShadeLockedWhenNotDozing() =
+ testScope.runTest {
+ whenever(statusbarStateController.isDozing).thenReturn(false)
+ transitionController.goToLockedShade(null)
+ verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
+ assertFalse(
+ "Waking to shade locked when not dozing",
+ transitionController.isWakingToShadeLocked
+ )
+ }
@Test
- fun testGoToLockedShadeOnlyOnKeyguard() {
- whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
- transitionController.goToLockedShade(null)
- whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE)
- transitionController.goToLockedShade(null)
- verify(statusbarStateController, never()).setState(anyInt())
- }
+ fun testGoToLockedShadeOnlyOnKeyguard() =
+ testScope.runTest {
+ whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
+ transitionController.goToLockedShade(null)
+ whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE)
+ transitionController.goToLockedShade(null)
+ verify(statusbarStateController, never()).setState(anyInt())
+ }
@Test
- fun testDontGoWhenShadeDisabled() {
- disableFlagsRepository.disableFlags.value =
- DisableFlagsModel(
- disable2 = DISABLE2_NOTIFICATION_SHADE,
- )
- testScope.runCurrent()
- transitionController.goToLockedShade(null)
- verify(statusbarStateController, never()).setState(anyInt())
- }
+ fun testDontGoWhenShadeDisabled() =
+ testScope.runTest {
+ disableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 = DISABLE2_NOTIFICATION_SHADE,
+ )
+ testScope.runCurrent()
+ transitionController.goToLockedShade(null)
+ verify(statusbarStateController, never()).setState(anyInt())
+ }
@Test
- fun testUserExpandsViewOnGoingToFullShade() {
- assertFalse("Row shouldn't be user expanded yet", row.isUserExpanded)
- transitionController.goToLockedShade(row)
- assertTrue("Row wasn't user expanded on drag down", row.isUserExpanded)
- }
+ fun testUserExpandsViewOnGoingToFullShade() =
+ testScope.runTest {
+ assertFalse("Row shouldn't be user expanded yet", row.isUserExpanded)
+ transitionController.goToLockedShade(row)
+ assertTrue("Row wasn't user expanded on drag down", row.isUserExpanded)
+ }
@Test
- fun testTriggeringBouncerNoNotificationsOnLockscreen() {
- whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false)
- transitionController.goToLockedShade(null)
- verify(statusbarStateController, never()).setState(anyInt())
- verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true)
- verify(centralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject())
- }
+ fun testTriggeringBouncerNoNotificationsOnLockscreen() =
+ testScope.runTest {
+ whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false)
+ transitionController.goToLockedShade(null)
+ verify(statusbarStateController, never()).setState(anyInt())
+ verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true)
+ verify(centralSurfaces)
+ .showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject())
+ }
@Test
- fun testGoToLockedShadeCreatesQSAnimation() {
- transitionController.goToLockedShade(null)
- verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
- verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
- assertNotNull(transitionController.dragDownAnimator)
- }
+ fun testGoToLockedShadeCreatesQSAnimation() =
+ testScope.runTest {
+ transitionController.goToLockedShade(null)
+ verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
+ verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
+ assertNotNull(transitionController.dragDownAnimator)
+ }
@Test
- fun testGoToLockedShadeDoesntCreateQSAnimation() {
- transitionController.goToLockedShade(null, needsQSAnimation = false)
- verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
- verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
- assertNull(transitionController.dragDownAnimator)
- }
+ fun testGoToLockedShadeDoesntCreateQSAnimation() =
+ testScope.runTest {
+ transitionController.goToLockedShade(null, needsQSAnimation = false)
+ verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
+ verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
+ assertNull(transitionController.dragDownAnimator)
+ }
@Test
- fun testGoToLockedShadeAlwaysCreatesQSAnimationInSplitShade() {
- enableSplitShade()
- transitionController.goToLockedShade(null, needsQSAnimation = true)
- verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
- assertNotNull(transitionController.dragDownAnimator)
- }
+ fun testGoToLockedShadeAlwaysCreatesQSAnimationInSplitShade() =
+ testScope.runTest {
+ enableSplitShade()
+ transitionController.goToLockedShade(null, needsQSAnimation = true)
+ verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
+ assertNotNull(transitionController.dragDownAnimator)
+ }
@Test
- fun testGoToLockedShadeCancelDoesntLeaveShadeOpenOnKeyguardHide() {
- whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false)
- whenever(lockScreenUserManager.isLockscreenPublicMode(any())).thenReturn(true)
- transitionController.goToLockedShade(null)
- val captor = argumentCaptor<Runnable>()
- verify(centralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(isNull(), captor.capture())
- captor.value.run()
- verify(statusbarStateController).setLeaveOpenOnKeyguardHide(false)
- }
+ fun testGoToLockedShadeCancelDoesntLeaveShadeOpenOnKeyguardHide() =
+ testScope.runTest {
+ whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false)
+ whenever(lockScreenUserManager.isLockscreenPublicMode(any())).thenReturn(true)
+ transitionController.goToLockedShade(null)
+ val captor = argumentCaptor<Runnable>()
+ verify(centralSurfaces)
+ .showBouncerWithDimissAndCancelIfKeyguard(isNull(), captor.capture())
+ captor.value.run()
+ verify(statusbarStateController).setLeaveOpenOnKeyguardHide(false)
+ }
@Test
- fun testDragDownAmountDoesntCallOutInLockedDownShade() {
- whenever(nsslController.isInLockedDownShade).thenReturn(true)
- transitionController.dragDownAmount = 10f
- verify(nsslController, never()).setTransitionToFullShadeAmount(anyFloat())
- verify(mediaHierarchyManager, never()).setTransitionToFullShadeAmount(anyFloat())
- verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
- verify(transitionControllerCallback, never())
- .setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong())
- verify(qsTransitionController, never()).dragDownAmount = anyFloat()
- }
+ fun testDragDownAmountDoesntCallOutInLockedDownShade() =
+ testScope.runTest {
+ whenever(nsslController.isInLockedDownShade).thenReturn(true)
+ transitionController.dragDownAmount = 10f
+ verify(nsslController, never()).setTransitionToFullShadeAmount(anyFloat())
+ verify(mediaHierarchyManager, never()).setTransitionToFullShadeAmount(anyFloat())
+ verify(scrimController, never())
+ .setTransitionToFullShadeProgress(anyFloat(), anyFloat())
+ verify(transitionControllerCallback, never())
+ .setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong())
+ verify(qsTransitionController, never()).dragDownAmount = anyFloat()
+ }
@Test
- fun testDragDownAmountCallsOut() {
- transitionController.dragDownAmount = 10f
- verify(nsslController).setTransitionToFullShadeAmount(anyFloat())
- verify(mediaHierarchyManager).setTransitionToFullShadeAmount(anyFloat())
- verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
- verify(transitionControllerCallback)
- .setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong())
- verify(qsTransitionController).dragDownAmount = 10f
- verify(depthController).transitionToFullShadeProgress = anyFloat()
- }
+ fun testDragDownAmountCallsOut() =
+ testScope.runTest {
+ transitionController.dragDownAmount = 10f
+ verify(nsslController).setTransitionToFullShadeAmount(anyFloat())
+ verify(mediaHierarchyManager).setTransitionToFullShadeAmount(anyFloat())
+ verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
+ verify(transitionControllerCallback)
+ .setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong())
+ verify(qsTransitionController).dragDownAmount = 10f
+ verify(depthController).transitionToFullShadeProgress = anyFloat()
+ }
@Test
- fun testDragDownAmount_depthDistanceIsZero_setsProgressToZero() {
- context
- .getOrCreateTestableResources()
- .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 0)
- configurationController.notifyConfigurationChanged()
+ fun testDragDownAmount_depthDistanceIsZero_setsProgressToZero() =
+ testScope.runTest {
+ context
+ .getOrCreateTestableResources()
+ .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 0)
+ configurationController.notifyConfigurationChanged()
- transitionController.dragDownAmount = 10f
+ transitionController.dragDownAmount = 10f
- verify(depthController).transitionToFullShadeProgress = 0f
- }
+ verify(depthController).transitionToFullShadeProgress = 0f
+ }
@Test
- fun testDragDownAmount_depthDistanceNonZero_setsProgressBasedOnDistance() {
- context
- .getOrCreateTestableResources()
- .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
- configurationController.notifyConfigurationChanged()
+ fun testDragDownAmount_depthDistanceNonZero_setsProgressBasedOnDistance() =
+ testScope.runTest {
+ context
+ .getOrCreateTestableResources()
+ .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
+ configurationController.notifyConfigurationChanged()
- transitionController.dragDownAmount = 10f
+ transitionController.dragDownAmount = 10f
- verify(depthController).transitionToFullShadeProgress = 0.1f
- }
+ verify(depthController).transitionToFullShadeProgress = 0.1f
+ }
@Test
- fun setDragAmount_setsKeyguardTransitionProgress() {
- transitionController.dragDownAmount = 10f
+ fun setDragAmount_setsKeyguardTransitionProgress() =
+ testScope.runTest {
+ transitionController.dragDownAmount = 10f
- verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(anyFloat(), anyInt())
- }
+ verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(anyFloat(), anyInt())
+ }
@Test
- fun setDragAmount_setsKeyguardAlphaBasedOnDistance() {
- val alphaDistance =
- context.resources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance
- )
- transitionController.dragDownAmount = 10f
+ fun setDragAmount_setsKeyguardAlphaBasedOnDistance() =
+ testScope.runTest {
+ val alphaDistance =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance
+ )
+ transitionController.dragDownAmount = 10f
- val expectedAlpha = 1 - 10f / alphaDistance
- verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(eq(expectedAlpha), anyInt())
- }
+ val expectedAlpha = 1 - 10f / alphaDistance
+ verify(shadeLockscreenInteractor)
+ .setKeyguardTransitionProgress(eq(expectedAlpha), anyInt())
+ }
@Test
- fun setDragAmount_notInSplitShade_setsKeyguardTranslationToZero() {
- val mediaTranslationY = 123
- disableSplitShade()
- whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
- whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
- .thenReturn(mediaTranslationY)
+ fun setDragAmount_notInSplitShade_setsKeyguardTranslationToZero() =
+ testScope.runTest {
+ val mediaTranslationY = 123
+ disableSplitShade()
+ whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
+ whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
+ .thenReturn(mediaTranslationY)
- transitionController.dragDownAmount = 10f
+ transitionController.dragDownAmount = 10f
- verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(anyFloat(), eq(0))
- }
+ verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(anyFloat(), eq(0))
+ }
@Test
- fun setDragAmount_inSplitShade_setsKeyguardTranslationBasedOnMediaTranslation() {
- val mediaTranslationY = 123
- enableSplitShade()
- whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
- whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
- .thenReturn(mediaTranslationY)
+ fun setDragAmount_inSplitShade_setsKeyguardTranslationBasedOnMediaTranslation() =
+ testScope.runTest {
+ val mediaTranslationY = 123
+ enableSplitShade()
+ whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
+ whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
+ .thenReturn(mediaTranslationY)
- transitionController.dragDownAmount = 10f
+ transitionController.dragDownAmount = 10f
- verify(shadeLockscreenInteractor)
+ verify(shadeLockscreenInteractor)
.setKeyguardTransitionProgress(anyFloat(), eq(mediaTranslationY))
- }
+ }
@Test
- fun setDragAmount_inSplitShade_mediaNotShowing_setsKeyguardTranslationBasedOnDistance() {
- enableSplitShade()
- whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(false)
- whenever(mediaHierarchyManager.getGuidedTransformationTranslationY()).thenReturn(123)
+ fun setDragAmount_inSplitShade_mediaNotShowing_setsKeyguardTranslationBasedOnDistance() =
+ testScope.runTest {
+ enableSplitShade()
+ whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(false)
+ whenever(mediaHierarchyManager.getGuidedTransformationTranslationY()).thenReturn(123)
- transitionController.dragDownAmount = 10f
+ transitionController.dragDownAmount = 10f
- val distance =
- context.resources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_keyguard_transition_distance
- )
- val offset =
- context.resources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_keyguard_transition_vertical_offset
- )
- val expectedTranslation = 10f / distance * offset
- verify(shadeLockscreenInteractor)
- .setKeyguardTransitionProgress(anyFloat(), eq(expectedTranslation.toInt()))
- }
+ val distance =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_keyguard_transition_distance
+ )
+ val offset =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_keyguard_transition_vertical_offset
+ )
+ val expectedTranslation = 10f / distance * offset
+ verify(shadeLockscreenInteractor)
+ .setKeyguardTransitionProgress(anyFloat(), eq(expectedTranslation.toInt()))
+ }
@Test
- fun setDragDownAmount_setsValueOnMediaHierarchyManager() {
- transitionController.dragDownAmount = 10f
+ fun setDragDownAmount_setsValueOnMediaHierarchyManager() =
+ testScope.runTest {
+ transitionController.dragDownAmount = 10f
- verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
- }
+ verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
+ }
@Test
- fun setDragAmount_setsScrimProgressBasedOnScrimDistance() {
- val distance = 10
- context.orCreateTestableResources.addOverride(
- R.dimen.lockscreen_shade_scrim_transition_distance,
- distance
- )
- configurationController.notifyConfigurationChanged()
+ fun setDragAmount_setsScrimProgressBasedOnScrimDistance() =
+ testScope.runTest {
+ val distance = 10
+ context.orCreateTestableResources.addOverride(
+ R.dimen.lockscreen_shade_scrim_transition_distance,
+ distance
+ )
+ configurationController.notifyConfigurationChanged()
- transitionController.dragDownAmount = 5f
+ transitionController.dragDownAmount = 5f
- verify(scrimController)
- .transitionToFullShadeProgress(
- progress = eq(0.5f),
- lockScreenNotificationsProgress = anyFloat()
- )
- }
+ verify(scrimController)
+ .transitionToFullShadeProgress(
+ progress = eq(0.5f),
+ lockScreenNotificationsProgress = anyFloat()
+ )
+ }
@Test
- fun setDragAmount_setsNotificationsScrimProgressBasedOnNotificationsScrimDistanceAndDelay() {
- val distance = 100
- val delay = 10
- context.orCreateTestableResources.addOverride(
- R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
- distance
- )
- context.orCreateTestableResources.addOverride(
- R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
- delay
- )
- configurationController.notifyConfigurationChanged()
+ fun setDragAmount_setsNotificationsScrimProgressBasedOnNotificationsScrimDistanceAndDelay() =
+ testScope.runTest {
+ val distance = 100
+ val delay = 10
+ context.orCreateTestableResources.addOverride(
+ R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
+ distance
+ )
+ context.orCreateTestableResources.addOverride(
+ R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
+ delay
+ )
+ configurationController.notifyConfigurationChanged()
- transitionController.dragDownAmount = 20f
+ transitionController.dragDownAmount = 20f
- verify(scrimController)
- .transitionToFullShadeProgress(
- progress = anyFloat(),
- lockScreenNotificationsProgress = eq(0.1f)
- )
- }
+ verify(scrimController)
+ .transitionToFullShadeProgress(
+ progress = anyFloat(),
+ lockScreenNotificationsProgress = eq(0.1f)
+ )
+ }
@Test
- fun setDragAmount_dragAmountLessThanNotifDelayDistance_setsNotificationsScrimProgressToZero() {
- val distance = 100
- val delay = 50
- context.orCreateTestableResources.addOverride(
- R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
- distance
- )
- context.orCreateTestableResources.addOverride(
- R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
- delay
- )
- configurationController.notifyConfigurationChanged()
+ fun setDragAmount_dragAmountLessThanNotifDelayDistance_setsNotificationsScrimProgressToZero() =
+ testScope.runTest {
+ val distance = 100
+ val delay = 50
+ context.orCreateTestableResources.addOverride(
+ R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
+ distance
+ )
+ context.orCreateTestableResources.addOverride(
+ R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
+ delay
+ )
+ configurationController.notifyConfigurationChanged()
- transitionController.dragDownAmount = 20f
+ transitionController.dragDownAmount = 20f
- verify(scrimController)
- .transitionToFullShadeProgress(
- progress = anyFloat(),
- lockScreenNotificationsProgress = eq(0f)
- )
- }
+ verify(scrimController)
+ .transitionToFullShadeProgress(
+ progress = anyFloat(),
+ lockScreenNotificationsProgress = eq(0f)
+ )
+ }
@Test
- fun setDragAmount_dragAmountMoreThanTotalDistance_setsNotificationsScrimProgressToOne() {
- val distance = 100
- val delay = 50
- context.orCreateTestableResources.addOverride(
- R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
- distance
- )
- context.orCreateTestableResources.addOverride(
- R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
- delay
- )
- configurationController.notifyConfigurationChanged()
+ fun setDragAmount_dragAmountMoreThanTotalDistance_setsNotificationsScrimProgressToOne() =
+ testScope.runTest {
+ val distance = 100
+ val delay = 50
+ context.orCreateTestableResources.addOverride(
+ R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
+ distance
+ )
+ context.orCreateTestableResources.addOverride(
+ R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
+ delay
+ )
+ configurationController.notifyConfigurationChanged()
- transitionController.dragDownAmount = 999999f
+ transitionController.dragDownAmount = 999999f
- verify(scrimController)
- .transitionToFullShadeProgress(
- progress = anyFloat(),
- lockScreenNotificationsProgress = eq(1f)
- )
- }
+ verify(scrimController)
+ .transitionToFullShadeProgress(
+ progress = anyFloat(),
+ lockScreenNotificationsProgress = eq(1f)
+ )
+ }
@Test
- fun setDragDownAmount_inSplitShade_setsValueOnMediaHierarchyManager() {
- enableSplitShade()
+ fun setDragDownAmount_inSplitShade_setsValueOnMediaHierarchyManager() =
+ testScope.runTest {
+ enableSplitShade()
- transitionController.dragDownAmount = 10f
+ transitionController.dragDownAmount = 10f
- verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
- }
+ verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
+ }
@Test
- fun setDragAmount_notInSplitShade_forwardsToSingleShadeOverScroller() {
- disableSplitShade()
+ fun setDragAmount_notInSplitShade_forwardsToSingleShadeOverScroller() =
+ testScope.runTest {
+ disableSplitShade()
- transitionController.dragDownAmount = 10f
+ transitionController.dragDownAmount = 10f
- verify(singleShadeOverScroller).expansionDragDownAmount = 10f
- verifyZeroInteractions(splitShadeOverScroller)
- }
+ verify(singleShadeOverScroller).expansionDragDownAmount = 10f
+ verifyZeroInteractions(splitShadeOverScroller)
+ }
@Test
- fun setDragAmount_inSplitShade_forwardsToSplitShadeOverScroller() {
- enableSplitShade()
+ fun setDragAmount_inSplitShade_forwardsToSplitShadeOverScroller() =
+ testScope.runTest {
+ enableSplitShade()
- transitionController.dragDownAmount = 10f
+ transitionController.dragDownAmount = 10f
- verify(splitShadeOverScroller).expansionDragDownAmount = 10f
- verifyZeroInteractions(singleShadeOverScroller)
- }
+ verify(splitShadeOverScroller).expansionDragDownAmount = 10f
+ verifyZeroInteractions(singleShadeOverScroller)
+ }
@Test
- fun setDragDownAmount_inSplitShade_setsKeyguardStatusBarAlphaBasedOnDistance() {
- val alphaDistance =
- context.resources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance
- )
- val dragDownAmount = 10f
- enableSplitShade()
+ fun setDragDownAmount_inSplitShade_setsKeyguardStatusBarAlphaBasedOnDistance() =
+ testScope.runTest {
+ val alphaDistance =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance
+ )
+ val dragDownAmount = 10f
+ enableSplitShade()
- transitionController.dragDownAmount = dragDownAmount
+ transitionController.dragDownAmount = dragDownAmount
- val expectedAlpha = 1 - dragDownAmount / alphaDistance
- verify(shadeLockscreenInteractor).setKeyguardStatusBarAlpha(expectedAlpha)
- }
+ val expectedAlpha = 1 - dragDownAmount / alphaDistance
+ verify(shadeLockscreenInteractor).setKeyguardStatusBarAlpha(expectedAlpha)
+ }
@Test
- fun setDragDownAmount_notInSplitShade_setsKeyguardStatusBarAlphaToMinusOne() {
- disableSplitShade()
+ fun setDragDownAmount_notInSplitShade_setsKeyguardStatusBarAlphaToMinusOne() =
+ testScope.runTest {
+ disableSplitShade()
- transitionController.dragDownAmount = 10f
+ transitionController.dragDownAmount = 10f
- verify(shadeLockscreenInteractor).setKeyguardStatusBarAlpha(-1f)
- }
+ verify(shadeLockscreenInteractor).setKeyguardStatusBarAlpha(-1f)
+ }
@Test
- fun nullQs_canDragDownFromAdapter() {
- transitionController.qS = null
+ fun nullQs_canDragDownFromAdapter() =
+ testScope.runTest {
+ transitionController.qS = null
- qsSceneAdapter.isQsFullyCollapsed = true
- assertTrue("Can't drag down on keyguard", transitionController.canDragDown())
- qsSceneAdapter.isQsFullyCollapsed = false
- assertFalse("Can drag down when QS is expanded", transitionController.canDragDown())
- }
+ qsSceneAdapter.isQsFullyCollapsed = true
+ assertTrue("Can't drag down on keyguard", transitionController.canDragDown())
+ qsSceneAdapter.isQsFullyCollapsed = false
+ assertFalse("Can drag down when QS is expanded", transitionController.canDragDown())
+ }
private fun enableSplitShade() {
setSplitShadeEnabled(true)
@@ -619,32 +631,4 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
) {
setTransitionToFullShadeProgress(progress, lockScreenNotificationsProgress)
}
-
- @SysUISingleton
- @Component(
- modules =
- [
- SysUITestModule::class,
- UserDomainLayerModule::class,
- BiometricsDomainLayerModule::class,
- ]
- )
- interface TestComponent {
-
- val configurationController: FakeConfigurationController
- val disableFlagsRepository: FakeDisableFlagsRepository
- val powerInteractor: PowerInteractor
- val shadeInteractor: ShadeInteractor
- val shadeRepository: FakeShadeRepository
- val testScope: TestScope
-
- @Component.Factory
- interface Factory {
- fun create(
- @BindsInstance test: SysuiTestCase,
- featureFlags: FakeFeatureFlagsClassicModule,
- mocks: TestMocksModule,
- ): TestComponent
- }
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt
new file mode 100644
index 000000000000..ecb1a6d44b22
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt
@@ -0,0 +1,222 @@
+/*
+ * 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.chips.casttootherdevice.domian.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor.mediaRouterChipInteractor
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.model.MediaRouterCastModel
+import com.android.systemui.statusbar.policy.CastDevice
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class MediaRouterChipInteractorTest : SysuiTestCase() {
+ val kosmos = Kosmos()
+ val testScope = kosmos.testScope
+ val mediaRouterRepository = kosmos.fakeMediaRouterRepository
+
+ val underTest = kosmos.mediaRouterChipInteractor
+
+ @Test
+ fun mediaRouterCastingState_noDevices_doingNothing() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.mediaRouterCastingState)
+
+ mediaRouterRepository.castDevices.value = emptyList()
+
+ assertThat(latest).isEqualTo(MediaRouterCastModel.DoingNothing)
+ }
+
+ @Test
+ fun mediaRouterCastingState_disconnectedDevice_doingNothing() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.mediaRouterCastingState)
+
+ mediaRouterRepository.castDevices.value =
+ listOf(
+ CastDevice(
+ state = CastDevice.CastState.Disconnected,
+ id = "id",
+ name = "name",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ )
+
+ assertThat(latest).isEqualTo(MediaRouterCastModel.DoingNothing)
+ }
+
+ @Test
+ fun mediaRouterCastingState_connectingDevice_casting_withName() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.mediaRouterCastingState)
+
+ mediaRouterRepository.castDevices.value =
+ listOf(
+ CastDevice(
+ state = CastDevice.CastState.Connecting,
+ id = "id",
+ name = "My Favorite Device",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ )
+
+ assertThat(latest)
+ .isEqualTo(MediaRouterCastModel.Casting(deviceName = "My Favorite Device"))
+ }
+
+ @Test
+ fun mediaRouterCastingState_connectedDevice_casting_withName() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.mediaRouterCastingState)
+
+ mediaRouterRepository.castDevices.value =
+ listOf(
+ CastDevice(
+ state = CastDevice.CastState.Connected,
+ id = "id",
+ name = "My Second Favorite Device",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ )
+
+ assertThat(latest)
+ .isEqualTo(MediaRouterCastModel.Casting(deviceName = "My Second Favorite Device"))
+ }
+
+ @Test
+ fun stopCasting_noDevices_doesNothing() =
+ testScope.runTest {
+ collectLastValue(underTest.mediaRouterCastingState)
+
+ mediaRouterRepository.castDevices.value = emptyList()
+ // Let the interactor catch up to the repo value
+ runCurrent()
+
+ underTest.stopCasting()
+
+ assertThat(mediaRouterRepository.lastStoppedDevice).isNull()
+ }
+
+ @Test
+ fun stopCasting_disconnectedDevice_doesNothing() =
+ testScope.runTest {
+ collectLastValue(underTest.mediaRouterCastingState)
+
+ mediaRouterRepository.castDevices.value =
+ listOf(
+ CastDevice(
+ state = CastDevice.CastState.Disconnected,
+ id = "id",
+ name = "name",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ )
+ // Let the interactor catch up to the repo value
+ runCurrent()
+
+ underTest.stopCasting()
+
+ assertThat(mediaRouterRepository.lastStoppedDevice).isNull()
+ }
+
+ @Test
+ fun stopCasting_connectingDevice_notifiesRepo() =
+ testScope.runTest {
+ collectLastValue(underTest.mediaRouterCastingState)
+
+ val device =
+ CastDevice(
+ state = CastDevice.CastState.Connecting,
+ id = "id",
+ name = "name",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ mediaRouterRepository.castDevices.value = listOf(device)
+ // Let the interactor catch up to the repo value
+ runCurrent()
+
+ underTest.stopCasting()
+
+ assertThat(mediaRouterRepository.lastStoppedDevice).isEqualTo(device)
+ }
+
+ @Test
+ fun stopCasting_connectedDevice_notifiesRepo() =
+ testScope.runTest {
+ collectLastValue(underTest.mediaRouterCastingState)
+
+ val device =
+ CastDevice(
+ state = CastDevice.CastState.Connected,
+ id = "id",
+ name = "name",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ mediaRouterRepository.castDevices.value = listOf(device)
+ // Let the interactor catch up to the repo value
+ runCurrent()
+
+ underTest.stopCasting()
+
+ assertThat(mediaRouterRepository.lastStoppedDevice).isEqualTo(device)
+ }
+
+ @Test
+ fun stopCasting_multipleConnectedDevices_notifiesRepoOfFirst() =
+ testScope.runTest {
+ collectLastValue(underTest.mediaRouterCastingState)
+
+ val device1 =
+ CastDevice(
+ state = CastDevice.CastState.Connected,
+ id = "id1",
+ name = "name",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ val device2 =
+ CastDevice(
+ state = CastDevice.CastState.Connected,
+ id = "id2",
+ name = "name",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ mediaRouterRepository.castDevices.value = listOf(device1, device2)
+ // Let the interactor catch up to the repo value
+ runCurrent()
+
+ underTest.stopCasting()
+
+ assertThat(mediaRouterRepository.lastStoppedDevice).isEqualTo(device1)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt
index c6fb481d2d54..5005d1609113 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt
@@ -19,8 +19,10 @@ package com.android.systemui.statusbar.chips.casttootherdevice.ui.view
import android.content.ComponentName
import android.content.DialogInterface
import android.content.Intent
+import android.content.applicationContext
import android.content.packageManager
import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.Kosmos
@@ -48,10 +50,10 @@ import org.mockito.kotlin.whenever
@SmallTest
@OptIn(ExperimentalCoroutinesApi::class)
-class EndCastToOtherDeviceDialogDelegateTest : SysuiTestCase() {
+class EndCastScreenToOtherDeviceDialogDelegateTest : SysuiTestCase() {
private val kosmos = Kosmos().also { it.testCase = this }
private val sysuiDialog = mock<SystemUIDialog>()
- private lateinit var underTest: EndCastToOtherDeviceDialogDelegate
+ private lateinit var underTest: EndCastScreenToOtherDeviceDialogDelegate
@Test
fun icon() {
@@ -72,17 +74,90 @@ class EndCastToOtherDeviceDialogDelegateTest : SysuiTestCase() {
}
@Test
- fun message_entireScreen() {
- createAndSetDelegate(ENTIRE_SCREEN)
+ fun message_entireScreen_unknownDevice() {
+ createAndSetDelegate(
+ MediaProjectionState.Projecting.EntireScreen(HOST_PACKAGE, hostDeviceName = null)
+ )
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ verify(sysuiDialog)
+ .setMessage(
+ context.getString(R.string.cast_to_other_device_stop_dialog_message_entire_screen)
+ )
+ }
+
+ @Test
+ fun message_entireScreen_hasDevice() {
+ createAndSetDelegate(
+ MediaProjectionState.Projecting.EntireScreen(
+ HOST_PACKAGE,
+ hostDeviceName = "My Favorite Device"
+ )
+ )
underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
verify(sysuiDialog)
- .setMessage(context.getString(R.string.cast_to_other_device_stop_dialog_message))
+ .setMessage(
+ context.getString(
+ R.string.cast_to_other_device_stop_dialog_message_entire_screen_with_device,
+ "My Favorite Device",
+ )
+ )
}
@Test
- fun message_singleTask() {
+ fun message_singleTask_unknownAppName_unknownDevice() {
+ val baseIntent =
+ Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
+ whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
+ .thenThrow(PackageManager.NameNotFoundException())
+
+ createAndSetDelegate(
+ MediaProjectionState.Projecting.SingleTask(
+ HOST_PACKAGE,
+ hostDeviceName = null,
+ createTask(taskId = 1, baseIntent = baseIntent)
+ ),
+ )
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ verify(sysuiDialog)
+ .setMessage(
+ context.getString(R.string.cast_to_other_device_stop_dialog_message_generic)
+ )
+ }
+
+ @Test
+ fun message_singleTask_unknownAppName_hasDevice() {
+ val baseIntent =
+ Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
+ whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
+ .thenThrow(PackageManager.NameNotFoundException())
+
+ createAndSetDelegate(
+ MediaProjectionState.Projecting.SingleTask(
+ HOST_PACKAGE,
+ hostDeviceName = "My Favorite Device",
+ createTask(taskId = 1, baseIntent = baseIntent)
+ ),
+ )
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ verify(sysuiDialog)
+ .setMessage(
+ context.getString(
+ R.string.cast_to_other_device_stop_dialog_message_generic_with_device,
+ "My Favorite Device",
+ )
+ )
+ }
+
+ @Test
+ fun message_singleTask_hasAppName_unknownDevice() {
val baseIntent =
Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
val appInfo = mock<ApplicationInfo>()
@@ -93,17 +168,49 @@ class EndCastToOtherDeviceDialogDelegateTest : SysuiTestCase() {
createAndSetDelegate(
MediaProjectionState.Projecting.SingleTask(
HOST_PACKAGE,
+ hostDeviceName = null,
createTask(taskId = 1, baseIntent = baseIntent)
+ ),
+ )
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ verify(sysuiDialog)
+ .setMessage(
+ context.getString(
+ R.string.cast_to_other_device_stop_dialog_message_specific_app,
+ "Fake Package",
+ )
)
+ }
+
+ @Test
+ fun message_singleTask_hasAppName_hasDevice() {
+ val baseIntent =
+ Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
+ val appInfo = mock<ApplicationInfo>()
+ whenever(appInfo.loadLabel(kosmos.packageManager)).thenReturn("Fake Package")
+ whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
+ .thenReturn(appInfo)
+
+ createAndSetDelegate(
+ MediaProjectionState.Projecting.SingleTask(
+ HOST_PACKAGE,
+ hostDeviceName = "My Favorite Device",
+ createTask(taskId = 1, baseIntent = baseIntent),
+ ),
)
underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
- // It'd be nice to use R.string.cast_to_other_device_stop_dialog_message_specific_app
- // directly, but it includes the <b> tags which aren't in the returned string.
- val result = argumentCaptor<CharSequence>()
- verify(sysuiDialog).setMessage(result.capture())
- assertThat(result.firstValue.toString()).isEqualTo("You will stop casting Fake Package")
+ verify(sysuiDialog)
+ .setMessage(
+ context.getString(
+ R.string.cast_to_other_device_stop_dialog_message_specific_app_with_device,
+ "Fake Package",
+ "My Favorite Device",
+ )
+ )
}
@Test
@@ -142,8 +249,9 @@ class EndCastToOtherDeviceDialogDelegateTest : SysuiTestCase() {
private fun createAndSetDelegate(state: MediaProjectionState.Projecting) {
underTest =
- EndCastToOtherDeviceDialogDelegate(
+ EndCastScreenToOtherDeviceDialogDelegate(
kosmos.endMediaProjectionDialogHelper,
+ kosmos.applicationContext,
stopAction = kosmos.mediaProjectionChipInteractor::stopProjecting,
ProjectionChipModel.Projecting(
ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE,
@@ -154,8 +262,13 @@ class EndCastToOtherDeviceDialogDelegateTest : SysuiTestCase() {
companion object {
private const val HOST_PACKAGE = "fake.host.package"
- private val ENTIRE_SCREEN = MediaProjectionState.Projecting.EntireScreen(HOST_PACKAGE)
+ private val ENTIRE_SCREEN =
+ MediaProjectionState.Projecting.EntireScreen(HOST_PACKAGE, hostDeviceName = null)
private val SINGLE_TASK =
- MediaProjectionState.Projecting.SingleTask(HOST_PACKAGE, createTask(taskId = 1))
+ MediaProjectionState.Projecting.SingleTask(
+ HOST_PACKAGE,
+ hostDeviceName = null,
+ createTask(taskId = 1)
+ )
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt
new file mode 100644
index 000000000000..e6101f500ad1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt
@@ -0,0 +1,153 @@
+/*
+ * 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.chips.casttootherdevice.ui.view
+
+import android.content.DialogInterface
+import android.content.applicationContext
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor.mediaRouterChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.statusbar.policy.CastDevice
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class EndGenericCastToOtherDeviceDialogDelegateTest : SysuiTestCase() {
+ private val kosmos = Kosmos().also { it.testCase = this }
+ private val sysuiDialog = mock<SystemUIDialog>()
+ private lateinit var underTest: EndGenericCastToOtherDeviceDialogDelegate
+
+ @Test
+ fun icon() {
+ createAndSetDelegate()
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ verify(sysuiDialog).setIcon(R.drawable.ic_cast_connected)
+ }
+
+ @Test
+ fun title() {
+ createAndSetDelegate()
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ verify(sysuiDialog).setTitle(R.string.cast_to_other_device_stop_dialog_title)
+ }
+
+ @Test
+ fun message_unknownDevice() {
+ createAndSetDelegate(deviceName = null)
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ verify(sysuiDialog)
+ .setMessage(
+ context.getString(R.string.cast_to_other_device_stop_dialog_message_generic)
+ )
+ }
+
+ @Test
+ fun message_hasDevice() {
+ createAndSetDelegate(deviceName = "My Favorite Device")
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ verify(sysuiDialog)
+ .setMessage(
+ context.getString(
+ R.string.cast_to_other_device_stop_dialog_message_generic_with_device,
+ "My Favorite Device",
+ )
+ )
+ }
+
+ @Test
+ fun negativeButton() {
+ createAndSetDelegate()
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ verify(sysuiDialog).setNegativeButton(R.string.close_dialog_button, null)
+ }
+
+ @Test
+ fun positiveButton() =
+ kosmos.testScope.runTest {
+ createAndSetDelegate()
+
+ // Set up a real device so the stop works correctly
+ collectLastValue(kosmos.mediaRouterChipInteractor.mediaRouterCastingState)
+ val device =
+ CastDevice(
+ state = CastDevice.CastState.Connected,
+ id = "id",
+ name = "name",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ kosmos.fakeMediaRouterRepository.castDevices.value = listOf(device)
+ // Let everything catch up to the repo value
+ runCurrent()
+ runCurrent()
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ val clickListener = argumentCaptor<DialogInterface.OnClickListener>()
+
+ // Verify the button has the right text
+ verify(sysuiDialog)
+ .setPositiveButton(
+ eq(R.string.cast_to_other_device_stop_dialog_button),
+ clickListener.capture()
+ )
+
+ // Verify that clicking the button stops the recording
+ assertThat(kosmos.fakeMediaRouterRepository.lastStoppedDevice).isNull()
+
+ clickListener.firstValue.onClick(mock<DialogInterface>(), 0)
+ runCurrent()
+
+ assertThat(kosmos.fakeMediaRouterRepository.lastStoppedDevice).isEqualTo(device)
+ }
+
+ private fun createAndSetDelegate(deviceName: String? = null) {
+ underTest =
+ EndGenericCastToOtherDeviceDialogDelegate(
+ kosmos.endMediaProjectionDialogHelper,
+ kosmos.applicationContext,
+ deviceName,
+ stopAction = kosmos.mediaRouterChipInteractor::stopCasting,
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
index 74b6ae2f9379..c9a7c82d6b3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel
import android.view.View
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.animation.mockDialogTransitionAnimator
+import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
@@ -28,24 +28,24 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
+import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository
import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndCastToOtherDeviceDialogDelegate
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndCastScreenToOtherDeviceDialogDelegate
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndGenericCastToOtherDeviceDialogDelegate
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.CAST_TO_OTHER_DEVICES_PACKAGE
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
import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
-import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
+import com.android.systemui.statusbar.policy.CastDevice
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlinx.coroutines.test.runTest
import org.junit.Before
-import org.mockito.ArgumentMatchers
import org.mockito.kotlin.any
-import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@@ -55,20 +55,11 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
private val kosmos = Kosmos().also { it.testCase = this }
private val testScope = kosmos.testScope
private val mediaProjectionRepo = kosmos.fakeMediaProjectionRepository
+ private val mediaRouterRepo = kosmos.fakeMediaRouterRepository
private val systemClock = kosmos.fakeSystemClock
- private val mockCastDialog = mock<SystemUIDialog>()
-
- private val chipBackgroundView = mock<ChipBackgroundContainer>()
- private val chipView =
- mock<View>().apply {
- whenever(
- this.requireViewById<ChipBackgroundContainer>(
- R.id.ongoing_activity_chip_background
- )
- )
- .thenReturn(chipBackgroundView)
- }
+ private val mockScreenCastDialog = mock<SystemUIDialog>()
+ private val mockGenericCastDialog = mock<SystemUIDialog>()
private val underTest = kosmos.castToOtherDeviceChipViewModel
@@ -76,14 +67,25 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
fun setUp() {
setUpPackageManagerForMediaProjection(kosmos)
- whenever(kosmos.mockSystemUIDialogFactory.create(any<EndCastToOtherDeviceDialogDelegate>()))
- .thenReturn(mockCastDialog)
+ whenever(
+ kosmos.mockSystemUIDialogFactory.create(
+ any<EndCastScreenToOtherDeviceDialogDelegate>()
+ )
+ )
+ .thenReturn(mockScreenCastDialog)
+ whenever(
+ kosmos.mockSystemUIDialogFactory.create(
+ any<EndGenericCastToOtherDeviceDialogDelegate>()
+ )
+ )
+ .thenReturn(mockGenericCastDialog)
}
@Test
fun chip_notProjectingState_isHidden() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
+ mediaRouterRepo.castDevices.value = emptyList()
mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
@@ -91,34 +93,103 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_singleTaskState_otherDevicesPackage_isShownAsTimer() =
+ fun chip_projectionIsSingleTaskState_otherDevicesPackage_isShownAsTimer_forScreen() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
+ mediaRouterRepo.castDevices.value = emptyList()
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.SingleTask(
CAST_TO_OTHER_DEVICES_PACKAGE,
+ hostDeviceName = null,
createTask(taskId = 1),
)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
val icon = (latest as OngoingActivityChipModel.Shown).icon
assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
- assertThat(icon.contentDescription).isNotNull()
+ assertThat((icon.contentDescription as ContentDescription.Resource).res)
+ .isEqualTo(R.string.cast_screen_to_other_device_chip_accessibility_label)
+ }
+
+ @Test
+ fun chip_projectionIsEntireScreenState_otherDevicesPackage_isShownAsTimer_forScreen() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+ mediaRouterRepo.castDevices.value = emptyList()
+
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+ val icon = (latest as OngoingActivityChipModel.Shown).icon
+ assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ assertThat((icon.contentDescription as ContentDescription.Resource).res)
+ .isEqualTo(R.string.cast_screen_to_other_device_chip_accessibility_label)
+ }
+
+ @Test
+ fun chip_routerStateDoingNothing_isHidden() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+ mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+
+ mediaRouterRepo.castDevices.value = emptyList()
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+ }
+
+ @Test
+ fun chip_routerStateCasting_isShownAsGenericIconOnly() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+ mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+
+ mediaRouterRepo.castDevices.value =
+ listOf(
+ CastDevice(
+ state = CastDevice.CastState.Connected,
+ id = "id",
+ name = "name",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ )
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+ val icon = (latest as OngoingActivityChipModel.Shown).icon
+ assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ // This content description is just generic "Casting", not "Casting screen"
+ assertThat((icon.contentDescription as ContentDescription.Resource).res)
+ .isEqualTo(R.string.accessibility_casting)
}
@Test
- fun chip_entireScreenState_otherDevicesPackage_isShownAsTimer() =
+ fun chip_projectingAndRouterCasting_projectionInfoShown() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
+ mediaRouterRepo.castDevices.value =
+ listOf(
+ CastDevice(
+ state = CastDevice.CastState.Connected,
+ id = "id",
+ name = "name",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ )
+ // Only the projection info will show a timer
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
val icon = (latest as OngoingActivityChipModel.Shown).icon
assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
- assertThat(icon.contentDescription).isNotNull()
+ // MediaProjection == screen casting, so this content description reflects that we're
+ // using the MediaProjection information.
+ assertThat((icon.contentDescription as ContentDescription.Resource).res)
+ .isEqualTo(R.string.cast_screen_to_other_device_chip_accessibility_label)
}
@Test
@@ -133,18 +204,22 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_singleTaskState_normalPackage_isHidden() =
+ fun chip_projectionIsSingleTaskState_normalPackage_isHidden() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
mediaProjectionRepo.mediaProjectionState.value =
- MediaProjectionState.Projecting.SingleTask(NORMAL_PACKAGE, createTask(taskId = 1))
+ MediaProjectionState.Projecting.SingleTask(
+ NORMAL_PACKAGE,
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
}
@Test
- fun chip_entireScreenState_normalPackage_isHidden() =
+ fun chip_projectionIsEntireScreenState_normalPackage_isHidden() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -155,7 +230,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_timeResetsOnEachNewShare() =
+ fun chip_projectionOnly_timeResetsOnEachNewShare() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -173,6 +248,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.SingleTask(
CAST_TO_OTHER_DEVICES_PACKAGE,
+ hostDeviceName = null,
createTask(taskId = 1),
)
@@ -181,7 +257,38 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_entireScreen_clickListenerShowsCastDialog() =
+ fun chip_routerInfoThenProjectionInfo_switchesToTimer() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ // First, set only MediaRouter to have information and verify we just show the icon
+ systemClock.setElapsedRealtime(1234)
+ mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+ mediaRouterRepo.castDevices.value =
+ listOf(
+ CastDevice(
+ state = CastDevice.CastState.Connected,
+ id = "id",
+ name = "name",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
+ )
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+
+ // Later, set MediaProjection to also have information
+ systemClock.setElapsedRealtime(5678)
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
+
+ // Verify the new time is used
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+ assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(5678)
+ }
+
+ @Test
+ fun chip_projectionStateEntireScreen_clickListenerShowsScreenCastDialog() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
mediaProjectionRepo.mediaProjectionState.value =
@@ -190,37 +297,49 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
assertThat(clickListener).isNotNull()
- clickListener!!.onClick(chipView)
- verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockCastDialog),
- eq(chipBackgroundView),
- eq(null),
- ArgumentMatchers.anyBoolean(),
- )
+ clickListener!!.onClick(mock<View>())
+ verify(mockScreenCastDialog).show()
}
@Test
- fun chip_singleTask_clickListenerShowsCastDialog() =
+ fun chip_projectionStateSingleTask_clickListenerShowsScreenCastDialog() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.SingleTask(
CAST_TO_OTHER_DEVICES_PACKAGE,
+ hostDeviceName = null,
createTask(taskId = 1),
)
val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
assertThat(clickListener).isNotNull()
- clickListener!!.onClick(chipView)
- verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockCastDialog),
- eq(chipBackgroundView),
- eq(null),
- ArgumentMatchers.anyBoolean(),
+ clickListener!!.onClick(mock<View>())
+ verify(mockScreenCastDialog).show()
+ }
+
+ @Test
+ fun chip_routerStateCasting_clickListenerShowsGenericCastDialog() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaRouterRepo.castDevices.value =
+ listOf(
+ CastDevice(
+ state = CastDevice.CastState.Connected,
+ id = "id",
+ name = "name",
+ description = "desc",
+ origin = CastDevice.CastOrigin.MediaRouter,
+ )
)
+
+ val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+ assertThat(clickListener).isNotNull()
+
+ clickListener!!.onClick(mock<View>())
+ verify(mockGenericCastDialog).show()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
index 7eb4ca06b80d..d0c5e7a102e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
@@ -72,6 +72,7 @@ class MediaProjectionChipInteractorTest : SysuiTestCase() {
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.SingleTask(
CAST_TO_OTHER_DEVICES_PACKAGE,
+ hostDeviceName = null,
createTask(taskId = 1)
)
@@ -101,7 +102,11 @@ class MediaProjectionChipInteractorTest : SysuiTestCase() {
val latest by collectLastValue(underTest.projection)
mediaProjectionRepo.mediaProjectionState.value =
- MediaProjectionState.Projecting.SingleTask(NORMAL_PACKAGE, createTask(taskId = 1))
+ MediaProjectionState.Projecting.SingleTask(
+ NORMAL_PACKAGE,
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
assertThat(latest).isInstanceOf(ProjectionChipModel.Projecting::class.java)
assertThat((latest as ProjectionChipModel.Projecting).type)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt
index ee929ae6235f..c62e40414121 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt
@@ -27,7 +27,6 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testCase
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
-import com.android.systemui.res.R
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
import com.google.common.truth.Truth.assertThat
@@ -56,19 +55,15 @@ class EndMediaProjectionDialogHelperTest : SysuiTestCase() {
}
@Test
- fun getDialogMessage_entireScreen_isGenericMessage() {
+ fun getAppName_stateVersion_entireScreen_returnsNull() {
val result =
- underTest.getDialogMessage(
- MediaProjectionState.Projecting.EntireScreen("host.package"),
- R.string.accessibility_home,
- R.string.cast_to_other_device_stop_dialog_message_specific_app
- )
+ underTest.getAppName(MediaProjectionState.Projecting.EntireScreen("host.package"))
- assertThat(result).isEqualTo(context.getString(R.string.accessibility_home))
+ assertThat(result).isNull()
}
@Test
- fun getDialogMessage_singleTask_cannotFindPackage_isGenericMessage() {
+ fun getAppName_stateVersion_singleTask_cannotFindPackage_returnsNull() {
val baseIntent =
Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
@@ -77,21 +72,17 @@ class EndMediaProjectionDialogHelperTest : SysuiTestCase() {
val projectionState =
MediaProjectionState.Projecting.SingleTask(
"host.package",
- createTask(taskId = 1, baseIntent = baseIntent)
+ hostDeviceName = null,
+ createTask(taskId = 1, baseIntent = baseIntent),
)
- val result =
- underTest.getDialogMessage(
- projectionState,
- R.string.accessibility_home,
- R.string.cast_to_other_device_stop_dialog_message_specific_app
- )
+ val result = underTest.getAppName(projectionState)
- assertThat(result).isEqualTo(context.getString(R.string.accessibility_home))
+ assertThat(result).isNull()
}
@Test
- fun getDialogMessage_singleTask_findsPackage_isSpecificMessageWithAppLabel() {
+ fun getAppName_stateVersion_singleTask_findsPackage_returnsName() {
val baseIntent =
Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
val appInfo = mock<ApplicationInfo>()
@@ -102,93 +93,67 @@ class EndMediaProjectionDialogHelperTest : SysuiTestCase() {
val projectionState =
MediaProjectionState.Projecting.SingleTask(
"host.package",
- createTask(taskId = 1, baseIntent = baseIntent)
+ hostDeviceName = null,
+ createTask(taskId = 1, baseIntent = baseIntent),
)
- val result =
- underTest.getDialogMessage(
- projectionState,
- R.string.accessibility_home,
- R.string.cast_to_other_device_stop_dialog_message_specific_app
- )
+ val result = underTest.getAppName(projectionState)
- // It'd be nice to use the R.string resources directly, but they include the <b> tags which
- // aren't in the returned string.
- assertThat(result.toString()).isEqualTo("You will stop casting Fake Package")
+ assertThat(result).isEqualTo("Fake Package")
}
@Test
- fun getDialogMessage_nullTask_isGenericMessage() {
- val result =
- underTest.getDialogMessage(
- specificTaskInfo = null,
- R.string.accessibility_home,
- R.string.cast_to_other_device_stop_dialog_message_specific_app,
- )
+ fun getAppName_taskInfoVersion_null_returnsNull() {
+ val result = underTest.getAppName(specificTaskInfo = null)
- assertThat(result).isEqualTo(context.getString(R.string.accessibility_home))
+ assertThat(result).isNull()
}
@Test
- fun getDialogMessage_withTask_cannotFindPackage_isGenericMessage() {
+ fun getAppName_taskInfoVersion_cannotFindPackage_returnsNull() {
val baseIntent =
Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
.thenThrow(PackageManager.NameNotFoundException())
- val task = createTask(taskId = 1, baseIntent = baseIntent)
- val result =
- underTest.getDialogMessage(
- task,
- R.string.accessibility_home,
- R.string.cast_to_other_device_stop_dialog_message_specific_app
- )
+ val result = underTest.getAppName(createTask(taskId = 1, baseIntent = baseIntent))
- assertThat(result).isEqualTo(context.getString(R.string.accessibility_home))
+ assertThat(result).isNull()
}
@Test
- fun getDialogMessage_withTask_findsPackage_isSpecificMessageWithAppLabel() {
+ fun getAppName_taskInfoVersion_findsPackage_returnsName() {
val baseIntent =
Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
val appInfo = mock<ApplicationInfo>()
whenever(appInfo.loadLabel(kosmos.packageManager)).thenReturn("Fake Package")
whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
.thenReturn(appInfo)
- val task = createTask(taskId = 1, baseIntent = baseIntent)
- val result =
- underTest.getDialogMessage(
- task,
- R.string.accessibility_home,
- R.string.cast_to_other_device_stop_dialog_message_specific_app
- )
+ val result = underTest.getAppName(createTask(taskId = 1, baseIntent = baseIntent))
- assertThat(result.toString()).isEqualTo("You will stop casting Fake Package")
+ assertThat(result).isEqualTo("Fake Package")
}
@Test
- fun getDialogMessage_appLabelHasSpecialCharacters_isEscaped() {
- val baseIntent =
- Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
+ fun getAppName_packageNameVersion_cannotFindPackage_returnsNull() {
+ whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
+ .thenThrow(PackageManager.NameNotFoundException())
+
+ val result = underTest.getAppName("fake.task.package")
+
+ assertThat(result).isNull()
+ }
+
+ @Test
+ fun getAppName_packageNameVersion_findsPackage_returnsName() {
val appInfo = mock<ApplicationInfo>()
- whenever(appInfo.loadLabel(kosmos.packageManager)).thenReturn("Fake & Package <Here>")
+ whenever(appInfo.loadLabel(kosmos.packageManager)).thenReturn("Fake Package")
whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
.thenReturn(appInfo)
- val projectionState =
- MediaProjectionState.Projecting.SingleTask(
- "host.package",
- createTask(taskId = 1, baseIntent = baseIntent)
- )
-
- val result =
- underTest.getDialogMessage(
- projectionState,
- R.string.accessibility_home,
- R.string.cast_to_other_device_stop_dialog_message_specific_app
- )
+ val result = underTest.getAppName("fake.task.package")
- assertThat(result.toString()).isEqualTo("You will stop casting Fake & Package <Here>")
+ assertThat(result).isEqualTo("Fake Package")
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
index 83b31c2a7b94..6bfb40fa17c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
@@ -103,7 +103,11 @@ class ScreenRecordChipInteractorTest : SysuiTestCase() {
screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
val task = createTask(taskId = 1)
mediaProjectionRepo.mediaProjectionState.value =
- MediaProjectionState.Projecting.SingleTask("host.package", task)
+ MediaProjectionState.Projecting.SingleTask(
+ "host.package",
+ hostDeviceName = null,
+ task,
+ )
assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = task))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
index 7e667de3619c..bfb63ac66d3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
@@ -20,6 +20,7 @@ import android.app.ActivityManager
import android.content.ComponentName
import android.content.DialogInterface
import android.content.Intent
+import android.content.applicationContext
import android.content.packageManager
import android.content.pm.ApplicationInfo
import androidx.test.filters.SmallTest
@@ -95,11 +96,13 @@ class EndScreenRecordingDialogDelegateTest : SysuiTestCase() {
underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
- // It'd be nice to use R.string.screenrecord_stop_dialog_message_specific_app directly, but
- // it includes the <b> tags which aren't in the returned string.
- val result = argumentCaptor<CharSequence>()
- verify(sysuiDialog).setMessage(result.capture())
- assertThat(result.firstValue.toString()).isEqualTo("You will stop recording Fake Package")
+ verify(sysuiDialog)
+ .setMessage(
+ context.getString(
+ R.string.screenrecord_stop_dialog_message_specific_app,
+ "Fake Package",
+ )
+ )
}
@Test
@@ -140,6 +143,7 @@ class EndScreenRecordingDialogDelegateTest : SysuiTestCase() {
underTest =
EndScreenRecordingDialogDelegate(
kosmos.endMediaProjectionDialogHelper,
+ kosmos.applicationContext,
stopAction = kosmos.screenRecordChipInteractor::stopRecording,
recordedTask,
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
index 0a06cc773727..4728c649b9a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
@@ -19,7 +19,6 @@ package com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel
import android.view.View
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.animation.mockDialogTransitionAnimator
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
@@ -34,7 +33,6 @@ import com.android.systemui.screenrecord.data.repository.screenRecordRepository
import com.android.systemui.statusbar.chips.screenrecord.ui.view.EndScreenRecordingDialogDelegate
import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
-import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
import com.android.systemui.util.time.fakeSystemClock
@@ -42,9 +40,7 @@ import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlinx.coroutines.test.runTest
import org.junit.Before
-import org.mockito.ArgumentMatchers
import org.mockito.kotlin.any
-import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@@ -58,17 +54,6 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
private val systemClock = kosmos.fakeSystemClock
private val mockSystemUIDialog = mock<SystemUIDialog>()
- private val chipBackgroundView = mock<ChipBackgroundContainer>()
- private val chipView =
- mock<View>().apply {
- whenever(
- this.requireViewById<ChipBackgroundContainer>(
- R.id.ongoing_activity_chip_background
- )
- )
- .thenReturn(chipBackgroundView)
- }
-
private val underTest = kosmos.screenRecordChipViewModel
@Before
@@ -197,15 +182,9 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
assertThat(clickListener).isNotNull()
- clickListener!!.onClick(chipView)
+ clickListener!!.onClick(mock<View>())
// EndScreenRecordingDialogDelegate will test that the dialog has the right message
- verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockSystemUIDialog),
- eq(chipBackgroundView),
- eq(null),
- ArgumentMatchers.anyBoolean(),
- )
+ verify(mockSystemUIDialog).show()
}
@Test
@@ -219,15 +198,9 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
assertThat(clickListener).isNotNull()
- clickListener!!.onClick(chipView)
+ clickListener!!.onClick(mock<View>())
// EndScreenRecordingDialogDelegate will test that the dialog has the right message
- verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockSystemUIDialog),
- eq(chipBackgroundView),
- eq(null),
- ArgumentMatchers.anyBoolean(),
- )
+ verify(mockSystemUIDialog).show()
}
@Test
@@ -238,20 +211,15 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.SingleTask(
"host.package",
+ hostDeviceName = null,
FakeActivityTaskManager.createTask(taskId = 1)
)
val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
assertThat(clickListener).isNotNull()
- clickListener!!.onClick(chipView)
+ clickListener!!.onClick(mock<View>())
// EndScreenRecordingDialogDelegate will test that the dialog has the right message
- verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockSystemUIDialog),
- eq(chipBackgroundView),
- eq(null),
- ArgumentMatchers.anyBoolean(),
- )
+ verify(mockSystemUIDialog).show()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt
index 63c29ac81b34..325a42bca7d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt
@@ -19,8 +19,10 @@ package com.android.systemui.statusbar.chips.sharetoapp.ui.view
import android.content.ComponentName
import android.content.DialogInterface
import android.content.Intent
+import android.content.applicationContext
import android.content.packageManager
import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.Kosmos
@@ -65,6 +67,8 @@ class EndShareToAppDialogDelegateTest : SysuiTestCase() {
@Test
fun title() {
createAndSetDelegate(ENTIRE_SCREEN)
+ whenever(kosmos.packageManager.getApplicationInfo(eq(HOST_PACKAGE), any<Int>()))
+ .thenThrow(PackageManager.NameNotFoundException())
underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
@@ -72,16 +76,61 @@ class EndShareToAppDialogDelegateTest : SysuiTestCase() {
}
@Test
- fun message_entireScreen() {
+ fun message_entireScreen_unknownHostPackage() {
createAndSetDelegate(ENTIRE_SCREEN)
+ whenever(kosmos.packageManager.getApplicationInfo(eq(HOST_PACKAGE), any<Int>()))
+ .thenThrow(PackageManager.NameNotFoundException())
underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
- verify(sysuiDialog).setMessage(context.getString(R.string.share_to_app_stop_dialog_message))
+ verify(sysuiDialog)
+ .setMessage(context.getString(R.string.share_to_app_stop_dialog_message_entire_screen))
}
@Test
- fun message_singleTask() {
+ fun message_entireScreen_hasHostPackage() {
+ createAndSetDelegate(ENTIRE_SCREEN)
+ val hostAppInfo = mock<ApplicationInfo>()
+ whenever(hostAppInfo.loadLabel(kosmos.packageManager)).thenReturn("Host Package")
+ whenever(kosmos.packageManager.getApplicationInfo(eq(HOST_PACKAGE), any<Int>()))
+ .thenReturn(hostAppInfo)
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ verify(sysuiDialog)
+ .setMessage(
+ context.getString(
+ R.string.share_to_app_stop_dialog_message_entire_screen_with_host_app,
+ "Host Package",
+ )
+ )
+ }
+
+ @Test
+ fun message_singleTask_unknownAppName() {
+ val baseIntent =
+ Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
+ whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
+ .thenThrow(PackageManager.NameNotFoundException())
+
+ createAndSetDelegate(
+ MediaProjectionState.Projecting.SingleTask(
+ HOST_PACKAGE,
+ hostDeviceName = null,
+ createTask(taskId = 1, baseIntent = baseIntent)
+ )
+ )
+
+ underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+ verify(sysuiDialog)
+ .setMessage(
+ context.getString(R.string.share_to_app_stop_dialog_message_single_app_generic)
+ )
+ }
+
+ @Test
+ fun message_singleTask_hasAppName() {
val baseIntent =
Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
val appInfo = mock<ApplicationInfo>()
@@ -92,17 +141,20 @@ class EndShareToAppDialogDelegateTest : SysuiTestCase() {
createAndSetDelegate(
MediaProjectionState.Projecting.SingleTask(
HOST_PACKAGE,
+ hostDeviceName = null,
createTask(taskId = 1, baseIntent = baseIntent)
)
)
underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
- // It'd be nice to use R.string.share_to_app_stop_dialog_message_specific_app directly, but
- // it includes the <b> tags which aren't in the returned string.
- val result = argumentCaptor<CharSequence>()
- verify(sysuiDialog).setMessage(result.capture())
- assertThat(result.firstValue.toString()).isEqualTo("You will stop sharing Fake Package")
+ verify(sysuiDialog)
+ .setMessage(
+ context.getString(
+ R.string.share_to_app_stop_dialog_message_single_app_specific,
+ "Fake Package",
+ )
+ )
}
@Test
@@ -118,6 +170,8 @@ class EndShareToAppDialogDelegateTest : SysuiTestCase() {
fun positiveButton() =
kosmos.testScope.runTest {
createAndSetDelegate(ENTIRE_SCREEN)
+ whenever(kosmos.packageManager.getApplicationInfo(eq(HOST_PACKAGE), any<Int>()))
+ .thenThrow(PackageManager.NameNotFoundException())
underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
@@ -143,8 +197,12 @@ class EndShareToAppDialogDelegateTest : SysuiTestCase() {
underTest =
EndShareToAppDialogDelegate(
kosmos.endMediaProjectionDialogHelper,
+ kosmos.applicationContext,
stopAction = kosmos.mediaProjectionChipInteractor::stopProjecting,
- ProjectionChipModel.Projecting(ProjectionChipModel.Type.SHARE_TO_APP, state),
+ ProjectionChipModel.Projecting(
+ ProjectionChipModel.Type.SHARE_TO_APP,
+ state,
+ ),
)
}
@@ -152,6 +210,10 @@ class EndShareToAppDialogDelegateTest : SysuiTestCase() {
private const val HOST_PACKAGE = "fake.host.package"
private val ENTIRE_SCREEN = MediaProjectionState.Projecting.EntireScreen(HOST_PACKAGE)
private val SINGLE_TASK =
- MediaProjectionState.Projecting.SingleTask(HOST_PACKAGE, createTask(taskId = 1))
+ MediaProjectionState.Projecting.SingleTask(
+ HOST_PACKAGE,
+ hostDeviceName = null,
+ createTask(taskId = 1)
+ )
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
index 3028d008f01d..f87b17dc92d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
@@ -19,7 +19,6 @@ package com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel
import android.view.View
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.animation.mockDialogTransitionAnimator
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
@@ -35,7 +34,6 @@ import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.Me
import com.android.systemui.statusbar.chips.sharetoapp.ui.view.EndShareToAppDialogDelegate
import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
-import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
import com.android.systemui.util.time.fakeSystemClock
@@ -43,9 +41,7 @@ import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlinx.coroutines.test.runTest
import org.junit.Before
-import org.mockito.ArgumentMatchers
import org.mockito.kotlin.any
-import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@@ -59,17 +55,6 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
private val mockShareDialog = mock<SystemUIDialog>()
- private val chipBackgroundView = mock<ChipBackgroundContainer>()
- private val chipView =
- mock<View>().apply {
- whenever(
- this.requireViewById<ChipBackgroundContainer>(
- R.id.ongoing_activity_chip_background
- )
- )
- .thenReturn(chipBackgroundView)
- }
-
private val underTest = kosmos.shareToAppChipViewModel
@Before
@@ -98,6 +83,7 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.SingleTask(
CAST_TO_OTHER_DEVICES_PACKAGE,
+ hostDeviceName = null,
createTask(taskId = 1),
)
@@ -123,6 +109,7 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.SingleTask(
NORMAL_PACKAGE,
+ hostDeviceName = null,
createTask(taskId = 1),
)
@@ -176,6 +163,7 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.SingleTask(
NORMAL_PACKAGE,
+ hostDeviceName = null,
createTask(taskId = 1),
)
@@ -193,14 +181,8 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
assertThat(clickListener).isNotNull()
- clickListener!!.onClick(chipView)
- verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockShareDialog),
- eq(chipBackgroundView),
- eq(null),
- ArgumentMatchers.anyBoolean(),
- )
+ clickListener!!.onClick(mock<View>())
+ verify(mockShareDialog).show()
}
@Test
@@ -210,19 +192,14 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.SingleTask(
NORMAL_PACKAGE,
+ hostDeviceName = null,
createTask(taskId = 1),
)
val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
assertThat(clickListener).isNotNull()
- clickListener!!.onClick(chipView)
- verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockShareDialog),
- eq(chipBackgroundView),
- eq(null),
- ArgumentMatchers.anyBoolean(),
- )
+ clickListener!!.onClick(mock<View>())
+ verify(mockShareDialog).show()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt
index c9c7359a89eb..ca043f163854 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt
@@ -19,50 +19,31 @@ package com.android.systemui.statusbar.chips.ui.viewmodel
import android.view.View
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.animation.DialogTransitionAnimator
-import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
+import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener
import com.android.systemui.statusbar.phone.SystemUIDialog
import kotlin.test.Test
-import org.mockito.ArgumentMatchers.anyBoolean
-import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
-import org.mockito.kotlin.whenever
@SmallTest
class OngoingActivityChipViewModelTest : SysuiTestCase() {
private val mockSystemUIDialog = mock<SystemUIDialog>()
private val dialogDelegate = SystemUIDialog.Delegate { mockSystemUIDialog }
- private val dialogTransitionAnimator = mock<DialogTransitionAnimator>()
-
- private val chipBackgroundView = mock<ChipBackgroundContainer>()
- private val chipView =
- mock<View>().apply {
- whenever(
- this.requireViewById<ChipBackgroundContainer>(
- R.id.ongoing_activity_chip_background
- )
- )
- .thenReturn(chipBackgroundView)
- }
@Test
fun createDialogLaunchOnClickListener_showsDialogOnClick() {
val clickListener =
- createDialogLaunchOnClickListener(dialogDelegate, dialogTransitionAnimator)
+ createDialogLaunchOnClickListener(
+ dialogDelegate,
+ logcatLogBuffer("OngoingActivityChipViewModelTest"),
+ "tag",
+ )
// Dialogs must be created on the main thread
context.mainExecutor.execute {
- clickListener.onClick(chipView)
- verify(dialogTransitionAnimator)
- .showFromView(
- eq(mockSystemUIDialog),
- eq(chipBackgroundView),
- eq(null),
- anyBoolean(),
- )
+ clickListener.onClick(mock<View>())
+ verify(mockSystemUIDialog).show()
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
index 8bc83cf2f3c2..b1a8d0beab34 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
@@ -155,6 +155,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
mediaProjectionState.value =
MediaProjectionState.Projecting.SingleTask(
NORMAL_PACKAGE,
+ hostDeviceName = null,
createTask(taskId = 1),
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
index 25533d82608b..d87b3e23b471 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
@@ -19,16 +19,23 @@ package com.android.systemui.statusbar.notification.collection.coordinator
import android.app.Notification
import android.os.UserHandle
+import android.platform.test.flag.junit.FlagsParameterization
import android.provider.Settings
-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.log.logcatLogBuffer
+import com.android.systemui.flags.andSceneContainer
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.setTransition
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.NotifPipeline
@@ -49,6 +56,8 @@ import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.withArgCaptor
import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
+import java.util.function.Consumer
+import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestCoroutineScheduler
@@ -62,22 +71,28 @@ import org.mockito.Mockito.anyString
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-import java.util.function.Consumer
-import kotlin.time.Duration.Companion.seconds
import org.mockito.Mockito.`when` as whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@SmallTest
-@RunWith(AndroidJUnit4::class)
-class KeyguardCoordinatorTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class KeyguardCoordinatorTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+ private val kosmos = Kosmos()
private val headsUpManager: HeadsUpManager = mock()
private val keyguardNotifVisibilityProvider: KeyguardNotificationVisibilityProvider = mock()
private val keyguardRepository = FakeKeyguardRepository()
- private val keyguardTransitionRepository = FakeKeyguardTransitionRepository()
+ private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
private val notifPipeline: NotifPipeline = mock()
private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider = mock()
private val statusBarStateController: StatusBarStateController = mock()
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
+
@Test
fun testSetSectionHeadersVisibleInShade() = runKeyguardCoordinatorTest {
clearInvocations(sectionHeaderVisibilityProvider)
@@ -147,10 +162,9 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
keyguardRepository.setKeyguardShowing(false)
whenever(statusBarStateController.isExpanded).thenReturn(false)
runKeyguardCoordinatorTest {
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GONE,
- this.testScheduler,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Gone),
+ stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
)
// WHEN: A notification is posted
@@ -163,24 +177,20 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
// WHEN: The keyguard is now showing
keyguardRepository.setKeyguardShowing(true)
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GONE,
- to = KeyguardState.AOD,
- this.testScheduler,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Lockscreen),
+ stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.AOD)
)
- testScheduler.runCurrent()
// THEN: The notification is recognized as "seen" and is filtered out.
assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isTrue()
// WHEN: The keyguard goes away
keyguardRepository.setKeyguardShowing(false)
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.AOD,
- to = KeyguardState.GONE,
- this.testScheduler,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Gone),
+ stateTransition = TransitionStep(KeyguardState.AOD, KeyguardState.GONE)
)
- testScheduler.runCurrent()
// THEN: The notification is shown regardless
assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isFalse()
@@ -344,9 +354,9 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
val fakeEntry = NotificationEntryBuilder().build()
collectionListener.onEntryAdded(fakeEntry)
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.AOD,
- to = KeyguardState.LOCKSCREEN,
- this.testScheduler,
+ from = KeyguardState.AOD,
+ to = KeyguardState.LOCKSCREEN,
+ this.testScheduler,
)
testScheduler.runCurrent()
@@ -356,21 +366,17 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
// WHEN: Keyguard is no longer showing
keyguardRepository.setKeyguardShowing(false)
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GONE,
- this.testScheduler,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Gone),
+ stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
)
- testScheduler.runCurrent()
// WHEN: Keyguard is shown again
keyguardRepository.setKeyguardShowing(true)
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GONE,
- to = KeyguardState.AOD,
- this.testScheduler,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Lockscreen),
+ stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.AOD)
)
- testScheduler.runCurrent()
// THEN: The notification is now recognized as "seen" and is filtered out.
assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isTrue()
@@ -383,9 +389,9 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
keyguardRepository.setKeyguardShowing(true)
runKeyguardCoordinatorTest {
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GONE,
- to = KeyguardState.LOCKSCREEN,
- this.testScheduler,
+ from = KeyguardState.GONE,
+ to = KeyguardState.LOCKSCREEN,
+ this.testScheduler,
)
val fakeEntry = NotificationEntryBuilder().build()
collectionListener.onEntryAdded(fakeEntry)
@@ -393,9 +399,9 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
// WHEN: Keyguard is no longer showing
keyguardRepository.setKeyguardShowing(false)
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GONE,
- this.testScheduler,
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ this.testScheduler,
)
// WHEN: Keyguard is shown again
@@ -413,10 +419,9 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
keyguardRepository.setKeyguardShowing(true)
keyguardRepository.setIsDozing(false)
runKeyguardCoordinatorTest {
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GONE,
- to = KeyguardState.LOCKSCREEN,
- this.testScheduler,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Lockscreen),
+ stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.LOCKSCREEN)
)
val firstEntry = NotificationEntryBuilder().setId(1).build()
collectionListener.onEntryAdded(firstEntry)
@@ -437,21 +442,17 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
// WHEN: the keyguard is no longer showing
keyguardRepository.setKeyguardShowing(false)
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GONE,
- this.testScheduler,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Gone),
+ stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
)
- testScheduler.runCurrent()
// WHEN: Keyguard is shown again
keyguardRepository.setKeyguardShowing(true)
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GONE,
- to = KeyguardState.LOCKSCREEN,
- this.testScheduler,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Lockscreen),
+ stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.LOCKSCREEN)
)
- testScheduler.runCurrent()
// THEN: The first notification is considered seen and is filtered out.
assertThat(unseenFilter.shouldFilterOut(firstEntry, 0L)).isTrue()
@@ -468,9 +469,9 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
keyguardRepository.setIsDozing(false)
runKeyguardCoordinatorTest {
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GONE,
- to = KeyguardState.LOCKSCREEN,
- this.testScheduler,
+ from = KeyguardState.GONE,
+ to = KeyguardState.LOCKSCREEN,
+ this.testScheduler,
)
testScheduler.runCurrent()
@@ -498,18 +499,18 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
// WHEN: the keyguard is no longer showing
keyguardRepository.setKeyguardShowing(false)
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GONE,
- this.testScheduler,
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ this.testScheduler,
)
testScheduler.runCurrent()
// WHEN: Keyguard is shown again
keyguardRepository.setKeyguardShowing(true)
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GONE,
- to = KeyguardState.LOCKSCREEN,
- this.testScheduler,
+ from = KeyguardState.GONE,
+ to = KeyguardState.LOCKSCREEN,
+ this.testScheduler,
)
testScheduler.runCurrent()
@@ -525,9 +526,9 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
keyguardRepository.setIsDozing(false)
runKeyguardCoordinatorTest {
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GONE,
- to = KeyguardState.LOCKSCREEN,
- this.testScheduler,
+ from = KeyguardState.GONE,
+ to = KeyguardState.LOCKSCREEN,
+ this.testScheduler,
)
testScheduler.runCurrent()
@@ -555,18 +556,18 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
// WHEN: the keyguard is no longer showing
keyguardRepository.setKeyguardShowing(false)
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GONE,
- this.testScheduler,
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ this.testScheduler,
)
testScheduler.runCurrent()
// WHEN: Keyguard is shown again
keyguardRepository.setKeyguardShowing(true)
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GONE,
- to = KeyguardState.LOCKSCREEN,
- this.testScheduler,
+ from = KeyguardState.GONE,
+ to = KeyguardState.LOCKSCREEN,
+ this.testScheduler,
)
testScheduler.runCurrent()
@@ -582,9 +583,9 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
keyguardRepository.setIsDozing(false)
runKeyguardCoordinatorTest {
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GONE,
- to = KeyguardState.LOCKSCREEN,
- this.testScheduler,
+ from = KeyguardState.GONE,
+ to = KeyguardState.LOCKSCREEN,
+ this.testScheduler,
)
testScheduler.runCurrent()
@@ -608,18 +609,18 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
// WHEN: the keyguard is no longer showing
keyguardRepository.setKeyguardShowing(false)
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GONE,
- this.testScheduler,
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ this.testScheduler,
)
testScheduler.runCurrent()
// WHEN: Keyguard is shown again
keyguardRepository.setKeyguardShowing(true)
keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GONE,
- to = KeyguardState.LOCKSCREEN,
- this.testScheduler,
+ from = KeyguardState.GONE,
+ to = KeyguardState.LOCKSCREEN,
+ this.testScheduler,
)
testScheduler.runCurrent()
@@ -646,7 +647,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
headsUpManager,
keyguardNotifVisibilityProvider,
keyguardRepository,
- keyguardTransitionRepository,
+ kosmos.keyguardTransitionInteractor,
KeyguardCoordinatorLogger(logcatLogBuffer()),
testScope.backgroundScope,
sectionHeaderVisibilityProvider,
@@ -706,4 +707,12 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
)
}
}
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return FlagsParameterization.allCombinationsOf().andSceneContainer()
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
index 26f53707aba1..f07303ed32e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
@@ -17,21 +17,19 @@ package com.android.systemui.statusbar.notification.icon.domain.interactor
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.SysUITestComponent
-import com.android.systemui.SysUITestModule
import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
-import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
-import com.android.systemui.collectLastValue
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
-import com.android.systemui.runTest
-import com.android.systemui.statusbar.data.repository.NotificationListenerSettingsRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.data.repository.notificationListenerSettingsRepository
import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
-import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
-import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor
-import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
+import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
+import com.android.systemui.statusbar.notification.data.repository.notificationsKeyguardViewStateRepository
+import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
+import com.android.systemui.statusbar.notification.domain.interactor.headsUpNotificationIconInteractor
import com.android.systemui.statusbar.notification.shared.byIsAmbient
import com.android.systemui.statusbar.notification.shared.byIsLastMessageFromReply
import com.android.systemui.statusbar.notification.shared.byIsPulsing
@@ -39,15 +37,15 @@ import com.android.systemui.statusbar.notification.shared.byIsRowDismissed
import com.android.systemui.statusbar.notification.shared.byIsSilent
import com.android.systemui.statusbar.notification.shared.byIsSuppressedFromStatusBar
import com.android.systemui.statusbar.notification.shared.byKey
-import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationsKeyguardInteractor
+import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
-import com.android.wm.shell.bubbles.Bubbles
+import com.android.wm.shell.bubbles.bubbles
+import com.android.wm.shell.bubbles.bubblesOptional
import com.google.common.truth.Truth.assertThat
-import dagger.BindsInstance
-import dagger.Component
-import java.util.Optional
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -55,29 +53,22 @@ import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class NotificationIconsInteractorTest : SysuiTestCase() {
-
- private val bubbles: Bubbles = mock()
-
- @Component(modules = [SysUITestModule::class])
- @SysUISingleton
- interface TestComponent : SysUITestComponent<NotificationIconsInteractor> {
-
- val activeNotificationListRepository: ActiveNotificationListRepository
- val notificationsKeyguardInteractor: NotificationsKeyguardInteractor
-
- @Component.Factory
- interface Factory {
- fun create(@BindsInstance test: SysuiTestCase, mocks: TestMocksModule): TestComponent
- }
- }
-
- val testComponent: TestComponent =
- DaggerNotificationIconsInteractorTest_TestComponent.factory()
- .create(test = this, mocks = TestMocksModule(bubbles = Optional.of(bubbles)))
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val activeNotificationListRepository = kosmos.activeNotificationListRepository
+ private val notificationsKeyguardInteractor = kosmos.notificationsKeyguardInteractor
+
+ private val underTest =
+ NotificationIconsInteractor(
+ kosmos.activeNotificationsInteractor,
+ kosmos.bubblesOptional,
+ kosmos.headsUpNotificationIconInteractor,
+ kosmos.notificationsKeyguardViewStateRepository
+ )
@Before
fun setup() {
- testComponent.apply {
+ testScope.apply {
activeNotificationListRepository.activeNotifications.value =
ActiveNotificationsStore.Builder()
.apply { testIcons.forEach(::addIndividualNotif) }
@@ -87,22 +78,22 @@ class NotificationIconsInteractorTest : SysuiTestCase() {
@Test
fun filteredEntrySet() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.filteredNotifSet())
assertThat(filteredSet).containsExactlyElementsIn(testIcons)
}
@Test
fun filteredEntrySet_noExpandedBubbles() =
- testComponent.runTest {
- whenever(bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
+ testScope.runTest {
+ whenever(kosmos.bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
val filteredSet by collectLastValue(underTest.filteredNotifSet())
assertThat(filteredSet).comparingElementsUsing(byKey).doesNotContain("notif1")
}
@Test
fun filteredEntrySet_noAmbient() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.filteredNotifSet(showAmbient = false))
assertThat(filteredSet).comparingElementsUsing(byIsAmbient).doesNotContain(true)
assertThat(filteredSet)
@@ -112,21 +103,21 @@ class NotificationIconsInteractorTest : SysuiTestCase() {
@Test
fun filteredEntrySet_noLowPriority() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.filteredNotifSet(showLowPriority = false))
assertThat(filteredSet).comparingElementsUsing(byIsSilent).doesNotContain(true)
}
@Test
fun filteredEntrySet_noDismissed() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.filteredNotifSet(showDismissed = false))
assertThat(filteredSet).comparingElementsUsing(byIsRowDismissed).doesNotContain(true)
}
@Test
fun filteredEntrySet_noRepliedMessages() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by
collectLastValue(underTest.filteredNotifSet(showRepliedMessages = false))
assertThat(filteredSet)
@@ -136,7 +127,7 @@ class NotificationIconsInteractorTest : SysuiTestCase() {
@Test
fun filteredEntrySet_noPulsing_notifsNotFullyHidden() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.filteredNotifSet(showPulsing = false))
notificationsKeyguardInteractor.setNotificationsFullyHidden(false)
assertThat(filteredSet).comparingElementsUsing(byIsPulsing).doesNotContain(true)
@@ -144,65 +135,46 @@ class NotificationIconsInteractorTest : SysuiTestCase() {
@Test
fun filteredEntrySet_noPulsing_notifsFullyHidden() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.filteredNotifSet(showPulsing = false))
notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
}
}
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class AlwaysOnDisplayNotificationIconsInteractorTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
- private val bubbles: Bubbles = mock()
-
- @Component(
- modules =
- [
- SysUITestModule::class,
- BiometricsDomainLayerModule::class,
- UserDomainLayerModule::class,
- ]
- )
- @SysUISingleton
- interface TestComponent : SysUITestComponent<AlwaysOnDisplayNotificationIconsInteractor> {
-
- val activeNotificationListRepository: ActiveNotificationListRepository
- val deviceEntryRepository: FakeDeviceEntryRepository
- val notificationsKeyguardInteractor: NotificationsKeyguardInteractor
-
- @Component.Factory
- interface Factory {
- fun create(@BindsInstance test: SysuiTestCase, mocks: TestMocksModule): TestComponent
- }
- }
-
- private val testComponent: TestComponent =
- DaggerAlwaysOnDisplayNotificationIconsInteractorTest_TestComponent.factory()
- .create(test = this, mocks = TestMocksModule(bubbles = Optional.of(bubbles)))
+ private val underTest =
+ AlwaysOnDisplayNotificationIconsInteractor(
+ kosmos.testDispatcher,
+ kosmos.deviceEntryInteractor,
+ kosmos.notificationIconsInteractor,
+ )
@Before
fun setup() {
- testComponent.apply {
- activeNotificationListRepository.activeNotifications.value =
- ActiveNotificationsStore.Builder()
- .apply { testIcons.forEach(::addIndividualNotif) }
- .build()
- }
+ kosmos.activeNotificationListRepository.activeNotifications.value =
+ ActiveNotificationsStore.Builder()
+ .apply { testIcons.forEach(::addIndividualNotif) }
+ .build()
}
@Test
fun filteredEntrySet_noExpandedBubbles() =
- testComponent.runTest {
- whenever(bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
+ testScope.runTest {
+ whenever(kosmos.bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
val filteredSet by collectLastValue(underTest.aodNotifs)
assertThat(filteredSet).comparingElementsUsing(byKey).doesNotContain("notif1")
}
@Test
fun filteredEntrySet_noAmbient() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.aodNotifs)
assertThat(filteredSet).comparingElementsUsing(byIsAmbient).doesNotContain(true)
assertThat(filteredSet)
@@ -212,14 +184,14 @@ class AlwaysOnDisplayNotificationIconsInteractorTest : SysuiTestCase() {
@Test
fun filteredEntrySet_noDismissed() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.aodNotifs)
assertThat(filteredSet).comparingElementsUsing(byIsRowDismissed).doesNotContain(true)
}
@Test
fun filteredEntrySet_noRepliedMessages() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.aodNotifs)
assertThat(filteredSet)
.comparingElementsUsing(byIsLastMessageFromReply)
@@ -228,37 +200,37 @@ class AlwaysOnDisplayNotificationIconsInteractorTest : SysuiTestCase() {
@Test
fun filteredEntrySet_showPulsing_notifsNotFullyHidden_bypassDisabled() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.aodNotifs)
- deviceEntryRepository.setBypassEnabled(false)
- notificationsKeyguardInteractor.setNotificationsFullyHidden(false)
+ kosmos.fakeDeviceEntryRepository.setBypassEnabled(false)
+ kosmos.notificationsKeyguardInteractor.setNotificationsFullyHidden(false)
assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
}
@Test
fun filteredEntrySet_showPulsing_notifsFullyHidden_bypassDisabled() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.aodNotifs)
- deviceEntryRepository.setBypassEnabled(false)
- notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
+ kosmos.fakeDeviceEntryRepository.setBypassEnabled(false)
+ kosmos.notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
}
@Test
fun filteredEntrySet_noPulsing_notifsNotFullyHidden_bypassEnabled() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.aodNotifs)
- deviceEntryRepository.setBypassEnabled(true)
- notificationsKeyguardInteractor.setNotificationsFullyHidden(false)
+ kosmos.fakeDeviceEntryRepository.setBypassEnabled(true)
+ kosmos.notificationsKeyguardInteractor.setNotificationsFullyHidden(false)
assertThat(filteredSet).comparingElementsUsing(byIsPulsing).doesNotContain(true)
}
@Test
fun filteredEntrySet_showPulsing_notifsFullyHidden_bypassEnabled() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.aodNotifs)
- deviceEntryRepository.setBypassEnabled(true)
- notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
+ kosmos.fakeDeviceEntryRepository.setBypassEnabled(true)
+ kosmos.notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
}
}
@@ -266,32 +238,19 @@ class AlwaysOnDisplayNotificationIconsInteractorTest : SysuiTestCase() {
@SmallTest
@RunWith(AndroidJUnit4::class)
class StatusBarNotificationIconsInteractorTest : SysuiTestCase() {
-
- private val bubbles: Bubbles = mock()
-
- @Component(modules = [SysUITestModule::class])
- @SysUISingleton
- interface TestComponent : SysUITestComponent<StatusBarNotificationIconsInteractor> {
-
- val activeNotificationListRepository: ActiveNotificationListRepository
- val headsUpIconsInteractor: HeadsUpNotificationIconInteractor
- val notificationsKeyguardInteractor: NotificationsKeyguardInteractor
- val notificationListenerSettingsRepository: NotificationListenerSettingsRepository
-
- @Component.Factory
- interface Factory {
- fun create(@BindsInstance test: SysuiTestCase, mocks: TestMocksModule): TestComponent
- }
- }
-
- val testComponent: TestComponent =
- DaggerStatusBarNotificationIconsInteractorTest_TestComponent.factory()
- .create(test = this, mocks = TestMocksModule(bubbles = Optional.of(bubbles)))
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val underTest =
+ StatusBarNotificationIconsInteractor(
+ kosmos.testDispatcher,
+ kosmos.notificationIconsInteractor,
+ kosmos.notificationListenerSettingsRepository,
+ )
@Before
fun setup() {
- testComponent.apply {
- activeNotificationListRepository.activeNotifications.value =
+ testScope.apply {
+ kosmos.activeNotificationListRepository.activeNotifications.value =
ActiveNotificationsStore.Builder()
.apply { testIcons.forEach(::addIndividualNotif) }
.build()
@@ -300,15 +259,15 @@ class StatusBarNotificationIconsInteractorTest : SysuiTestCase() {
@Test
fun filteredEntrySet_noExpandedBubbles() =
- testComponent.runTest {
- whenever(bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
+ testScope.runTest {
+ whenever(kosmos.bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
val filteredSet by collectLastValue(underTest.statusBarNotifs)
assertThat(filteredSet).comparingElementsUsing(byKey).doesNotContain("notif1")
}
@Test
fun filteredEntrySet_noAmbient() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.statusBarNotifs)
assertThat(filteredSet).comparingElementsUsing(byIsAmbient).doesNotContain(true)
assertThat(filteredSet)
@@ -318,30 +277,30 @@ class StatusBarNotificationIconsInteractorTest : SysuiTestCase() {
@Test
fun filteredEntrySet_noLowPriority_whenDontShowSilentIcons() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.statusBarNotifs)
- notificationListenerSettingsRepository.showSilentStatusIcons.value = false
+ kosmos.notificationListenerSettingsRepository.showSilentStatusIcons.value = false
assertThat(filteredSet).comparingElementsUsing(byIsSilent).doesNotContain(true)
}
@Test
fun filteredEntrySet_showLowPriority_whenShowSilentIcons() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.statusBarNotifs)
- notificationListenerSettingsRepository.showSilentStatusIcons.value = true
+ kosmos.notificationListenerSettingsRepository.showSilentStatusIcons.value = true
assertThat(filteredSet).comparingElementsUsing(byIsSilent).contains(true)
}
@Test
fun filteredEntrySet_noDismissed() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.statusBarNotifs)
assertThat(filteredSet).comparingElementsUsing(byIsRowDismissed).doesNotContain(true)
}
@Test
fun filteredEntrySet_noRepliedMessages() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.statusBarNotifs)
assertThat(filteredSet)
.comparingElementsUsing(byIsLastMessageFromReply)
@@ -350,9 +309,9 @@ class StatusBarNotificationIconsInteractorTest : SysuiTestCase() {
@Test
fun filteredEntrySet_includesIsolatedIcon() =
- testComponent.runTest {
+ testScope.runTest {
val filteredSet by collectLastValue(underTest.statusBarNotifs)
- headsUpIconsInteractor.setIsolatedIconNotificationKey("notif5")
+ kosmos.headsUpNotificationIconInteractor.setIsolatedIconNotificationKey("notif5")
assertThat(filteredSet).comparingElementsUsing(byKey).contains("notif5")
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
index 894e02e80997..1f4e80e48bb7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
@@ -16,111 +16,81 @@
package com.android.systemui.statusbar.notification.icon.ui.viewmodel
+import android.content.res.mainResources
import android.platform.test.annotations.DisableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR
import com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION
-import com.android.systemui.SysUITestComponent
-import com.android.systemui.SysUITestModule
import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
-import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
-import com.android.systemui.collectLastValue
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.FakeFeatureFlagsClassicModule
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.DozeStateModel
import com.android.systemui.keyguard.shared.model.DozeTransitionModel
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.power.data.repository.FakePowerRepository
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.power.shared.model.WakefulnessState
-import com.android.systemui.runCurrent
-import com.android.systemui.runTest
-import com.android.systemui.statusbar.phone.DozeParameters
-import com.android.systemui.statusbar.phone.ScreenOffAnimationController
-import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository
-import com.android.systemui.user.domain.UserDomainLayerModule
-import com.android.systemui.util.mockito.mock
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.notification.icon.domain.interactor.alwaysOnDisplayNotificationIconsInteractor
+import com.android.systemui.statusbar.phone.dozeParameters
+import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
-import dagger.BindsInstance
-import dagger.Component
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
-
- @SysUISingleton
- @Component(
- modules =
- [
- SysUITestModule::class,
- BiometricsDomainLayerModule::class,
- UserDomainLayerModule::class,
- ]
- )
- interface TestComponent :
- SysUITestComponent<NotificationIconContainerAlwaysOnDisplayViewModel> {
-
- val deviceProvisioningRepository: FakeDeviceProvisioningRepository
- val keyguardRepository: FakeKeyguardRepository
- val keyguardTransitionRepository: FakeKeyguardTransitionRepository
- val powerRepository: FakePowerRepository
-
- @Component.Factory
- interface Factory {
- fun create(
- @BindsInstance test: SysuiTestCase,
- mocks: TestMocksModule,
- featureFlags: FakeFeatureFlagsClassicModule,
- ): TestComponent
+ private val kosmos =
+ testKosmos().apply {
+ fakeFeatureFlagsClassic.apply { set(Flags.FULL_SCREEN_USER_SWITCHER, value = false) }
}
- }
- private val dozeParams: DozeParameters = mock()
- private val screenOffAnimController: ScreenOffAnimationController = mock()
-
- private val testComponent: TestComponent =
- DaggerNotificationIconContainerAlwaysOnDisplayViewModelTest_TestComponent.factory()
- .create(
- test = this,
- featureFlags =
- FakeFeatureFlagsClassicModule {
- set(Flags.FULL_SCREEN_USER_SWITCHER, value = false)
- },
- mocks =
- TestMocksModule(
- dozeParameters = dozeParams,
- screenOffAnimationController = screenOffAnimController,
- ),
- )
+ val underTest =
+ NotificationIconContainerAlwaysOnDisplayViewModel(
+ kosmos.testDispatcher,
+ kosmos.alwaysOnDisplayNotificationIconsInteractor,
+ kosmos.keyguardInteractor,
+ kosmos.keyguardTransitionInteractor,
+ kosmos.mainResources,
+ kosmos.shadeInteractor,
+ )
+ val testScope = kosmos.testScope
+ val keyguardRepository = kosmos.fakeKeyguardRepository
+ val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+ val powerRepository = kosmos.fakePowerRepository
@Before
fun setup() {
- testComponent.apply {
- keyguardRepository.setKeyguardShowing(true)
- keyguardRepository.setKeyguardOccluded(false)
- powerRepository.updateWakefulness(
- rawState = WakefulnessState.AWAKE,
- lastWakeReason = WakeSleepReason.OTHER,
- lastSleepReason = WakeSleepReason.OTHER,
- )
- }
+ keyguardRepository.setKeyguardShowing(true)
+ keyguardRepository.setKeyguardOccluded(false)
+ kosmos.fakePowerRepository.updateWakefulness(
+ rawState = WakefulnessState.AWAKE,
+ lastWakeReason = WakeSleepReason.OTHER,
+ lastSleepReason = WakeSleepReason.OTHER,
+ )
mSetFlagsRule.enableFlags(FLAG_NEW_AOD_TRANSITION)
}
@Test
fun animationsEnabled_isFalse_whenDeviceAsleepAndNotPulsing() =
- testComponent.runTest {
+ testScope.runTest {
powerRepository.updateWakefulness(
rawState = WakefulnessState.ASLEEP,
lastWakeReason = WakeSleepReason.POWER_BUTTON,
@@ -143,7 +113,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
fun animationsEnabled_isTrue_whenDeviceAsleepAndPulsing() =
- testComponent.runTest {
+ testScope.runTest {
powerRepository.updateWakefulness(
rawState = WakefulnessState.ASLEEP,
lastWakeReason = WakeSleepReason.POWER_BUTTON,
@@ -166,7 +136,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
fun animationsEnabled_isFalse_whenStartingToSleepAndNotControlScreenOff() =
- testComponent.runTest {
+ testScope.runTest {
powerRepository.updateWakefulness(
rawState = WakefulnessState.STARTING_TO_SLEEP,
lastWakeReason = WakeSleepReason.POWER_BUTTON,
@@ -179,7 +149,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
transitionState = TransitionState.STARTED,
)
)
- whenever(dozeParams.shouldControlScreenOff()).thenReturn(false)
+ whenever(kosmos.dozeParameters.shouldControlScreenOff()).thenReturn(false)
val animationsEnabled by collectLastValue(underTest.areContainerChangesAnimated)
runCurrent()
assertThat(animationsEnabled).isFalse()
@@ -187,7 +157,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
fun animationsEnabled_isTrue_whenStartingToSleepAndControlScreenOff() =
- testComponent.runTest {
+ testScope.runTest {
val animationsEnabled by collectLastValue(underTest.areContainerChangesAnimated)
assertThat(animationsEnabled).isTrue()
@@ -203,13 +173,13 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
transitionState = TransitionState.STARTED,
)
)
- whenever(dozeParams.shouldControlScreenOff()).thenReturn(true)
+ whenever(kosmos.dozeParameters.shouldControlScreenOff()).thenReturn(true)
assertThat(animationsEnabled).isTrue()
}
@Test
fun animationsEnabled_isTrue_whenNotAsleep() =
- testComponent.runTest {
+ testScope.runTest {
powerRepository.updateWakefulness(
rawState = WakefulnessState.AWAKE,
lastWakeReason = WakeSleepReason.POWER_BUTTON,
@@ -228,7 +198,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
@DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR)
fun animationsEnabled_isTrue_whenKeyguardIsShowing() =
- testComponent.runTest {
+ testScope.runTest {
keyguardTransitionRepository.sendTransitionStep(
TransitionStep(
transitionState = TransitionState.STARTED,
@@ -257,7 +227,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
fun tintAlpha_isZero_whenNotOnAodOrDozing() =
- testComponent.runTest {
+ testScope.runTest {
val tintAlpha by collectLastValue(underTest.tintAlpha)
runCurrent()
keyguardTransitionRepository.sendTransitionSteps(
@@ -271,7 +241,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
fun tintAlpha_isOne_whenOnAod() =
- testComponent.runTest {
+ testScope.runTest {
val tintAlpha by collectLastValue(underTest.tintAlpha)
runCurrent()
keyguardTransitionRepository.sendTransitionSteps(
@@ -285,7 +255,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
fun tintAlpha_isOne_whenDozing() =
- testComponent.runTest {
+ testScope.runTest {
val tintAlpha by collectLastValue(underTest.tintAlpha)
runCurrent()
keyguardTransitionRepository.sendTransitionSteps(
@@ -298,7 +268,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
fun tintAlpha_isOne_whenTransitionFromAodToDoze() =
- testComponent.runTest {
+ testScope.runTest {
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.GONE,
to = KeyguardState.AOD,
@@ -332,7 +302,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
fun tintAlpha_isFraction_midTransitionToAod() =
- testComponent.runTest {
+ testScope.runTest {
val tintAlpha by collectLastValue(underTest.tintAlpha)
runCurrent()
@@ -361,7 +331,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
fun iconAnimationsEnabled_whenOnLockScreen() =
- testComponent.runTest {
+ testScope.runTest {
val iconAnimationsEnabled by collectLastValue(underTest.areIconAnimationsEnabled)
runCurrent()
@@ -376,7 +346,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
fun iconAnimationsDisabled_whenOnAod() =
- testComponent.runTest {
+ testScope.runTest {
val iconAnimationsEnabled by collectLastValue(underTest.areIconAnimationsEnabled)
runCurrent()
@@ -391,7 +361,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Test
fun iconAnimationsDisabled_whenDozing() =
- testComponent.runTest {
+ testScope.runTest {
val iconAnimationsEnabled by collectLastValue(underTest.areIconAnimationsEnabled)
runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index bfe5c6e233d3..61d14b73204a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -60,6 +60,7 @@ import android.os.Handler;
import android.os.PowerManager;
import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -244,6 +245,50 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
}
@Test
+ @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+ public void testShouldNotHeadsUp_silentNotification() {
+ // GIVEN state for "heads up when awake" is true
+ ensureStateForHeadsUpWhenAwake();
+
+ // WHEN the alert for a grouped notification is suppressed
+ // see {@link android.app.Notification#GROUP_ALERT_CHILDREN}
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setPkg("a")
+ .setOpPkg("a")
+ .setTag("a")
+ .setNotification(new Notification.Builder(getContext(), "a")
+ .setSilent(true)
+ .build())
+ .setImportance(IMPORTANCE_DEFAULT)
+ .build();
+
+ // THEN this entry shouldn't HUN
+ assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+ }
+
+ @Test
+ @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+ public void testShouldNotHeadsUp_silentNotificationFalse() {
+ // GIVEN state for "heads up when awake" is true
+ ensureStateForHeadsUpWhenAwake();
+
+ // WHEN the alert for a grouped notification is suppressed
+ // see {@link android.app.Notification#GROUP_ALERT_CHILDREN}
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setPkg("a")
+ .setOpPkg("a")
+ .setTag("a")
+ .setNotification(new Notification.Builder(getContext(), "a")
+ .setSilent(false)
+ .build())
+ .setImportance(IMPORTANCE_HIGH)
+ .build();
+
+ // THEN this entry shouldn't HUN
+ assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isTrue();
+ }
+
+ @Test
public void testShouldHeadsUpWhenDozing() {
ensureStateForHeadsUpWhenDozing();
@@ -685,6 +730,26 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
}
@Test
+ @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+ public void testShouldNotFullScreen_silentNotification() {
+ Notification n = new Notification.Builder(getContext(), "a")
+ .setContentTitle("title")
+ .setContentText("content text")
+ .setFullScreenIntent(mPendingIntent, true)
+ .setSilent(true)
+ .build();
+ NotificationEntry entry = createNotification(IMPORTANCE_HIGH, n);
+
+ assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
+ .isEqualTo(FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION);
+ assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+ .isFalse();
+ verify(mLogger).logNoFullscreen(entry, "NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION");
+ verify(mLogger, never()).logFullscreen(any(), any());
+ verify(mLogger, never()).logNoFullscreenWarning(any(), any());
+ }
+
+ @Test
public void testShouldFullScreen_notInteractive() {
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
Notification.BubbleMetadata bubbleMetadata = new Notification.BubbleMetadata.Builder("foo")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
index 378705a3c1a3..d5ab62b43866 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
@@ -49,6 +49,7 @@ import android.graphics.drawable.Icon
import android.hardware.display.FakeAmbientDisplayConfiguration
import android.os.Looper
import android.os.PowerManager
+import android.platform.test.annotations.EnableFlags
import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED
import android.provider.Settings.Global.HEADS_UP_OFF
import android.provider.Settings.Global.HEADS_UP_ON
@@ -532,6 +533,32 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
}
@Test
+ @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+ fun testShouldNotHeadsUp_silentNotification() {
+ withPeekAndPulseEntry({
+ isGrouped = false
+ isGroupSummary = false
+ isSilent = true
+ }) {
+ assertShouldNotHeadsUp(it)
+ assertNoEventsLogged()
+ }
+ }
+
+ @Test
+ @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+ fun testShouldHeadsUp_silentNotificationFalse() {
+ withPeekAndPulseEntry({
+ isGrouped = false
+ isGroupSummary = false
+ isSilent = false
+ }) {
+ assertShouldHeadsUp(it)
+ assertNoEventsLogged()
+ }
+ }
+
+ @Test
fun testShouldNotHeadsUp_justLaunchedFsi() {
withPeekAndPulseEntry({ hasJustLaunchedFsi = true }) {
assertShouldNotHeadsUp(it)
@@ -1163,6 +1190,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
var groupAlertBehavior: Int? = null
var hasBubbleMetadata = false
var hasFsi = false
+ var isSilent = false
// Set on Notification:
var isForegroundService = false
@@ -1233,6 +1261,8 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
}
groupAlertBehavior?.let { nb.setGroupAlertBehavior(it) }
+ nb.setSilent(isSilent)
+
if (hasBubbleMetadata) {
nb.setBubbleMetadata(buildBubbleMetadata())
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index e8349b0978e0..ed7383cacd29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -1003,21 +1003,6 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
// THEN
assertThat(row.isExpanded()).isFalse();
}
-
- @Test
- @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
- public void hasUserChangedExpansion_expandPinned_returnTrue() throws Exception {
- // GIVEN
- final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
- row.setPinned(true);
-
- // WHEN
- row.expandNotification();
-
- // THEN
- assertThat(row.hasUserChangedExpansion()).isTrue();
- }
-
@Test
public void onDisappearAnimationFinished_shouldSetFalse_headsUpAnimatingAway()
throws Exception {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index 5c45b2e53047..3669e3d8fed1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -64,6 +64,10 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
@Mock private SectionHeaderController mPeopleHeaderController;
@Mock private SectionHeaderController mAlertingHeaderController;
@Mock private SectionHeaderController mSilentHeaderController;
+ @Mock private SectionHeaderController mNewsHeaderController;
+ @Mock private SectionHeaderController mSocialHeaderController;
+ @Mock private SectionHeaderController mRecsHeaderController;
+ @Mock private SectionHeaderController mPromoHeaderController;
private NotificationSectionsManager mSectionsManager;
@@ -94,7 +98,11 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
mIncomingHeaderController,
mPeopleHeaderController,
mAlertingHeaderController,
- mSilentHeaderController
+ mSilentHeaderController,
+ mNewsHeaderController,
+ mSocialHeaderController,
+ mRecsHeaderController,
+ mPromoHeaderController
);
// Required in order for the header inflation to work properly
when(mNssl.generateLayoutParams(any(AttributeSet.class)))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index ce2491bb098e..1060b62f071f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -53,6 +53,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.ExpandHelper;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
@@ -99,6 +100,7 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController.NotificationPanelEvent;
import com.android.systemui.statusbar.notification.stack.NotificationSwipeHelper.NotificationCallback;
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder;
+import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -135,6 +137,8 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
@Mock private NotificationVisibilityProvider mVisibilityProvider;
@Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
@Mock private HeadsUpManager mHeadsUpManager;
+ @Mock private HeadsUpTouchHelper.Callback mHeadsUpCallback;
+ @Mock private Provider<IStatusBarService> mStatusBarService;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
@Mock private TunerService mTunerService;
@Mock private DeviceProvisionedController mDeviceProvisionedController;
@@ -973,6 +977,8 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
when(mNotificationStackScrollLayout.getViewTreeObserver())
.thenReturn(viewTreeObserver);
when(mNotificationStackScrollLayout.getContext()).thenReturn(getContext());
+ when(mNotificationStackScrollLayout.getHeadsUpCallback()).thenReturn(mHeadsUpCallback);
+ when(mHeadsUpCallback.getContext()).thenReturn(getContext());
mController = new NotificationStackScrollLayoutController(
mNotificationStackScrollLayout,
true,
@@ -981,6 +987,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mVisibilityProvider,
mNotificationWakeUpCoordinator,
mHeadsUpManager,
+ mStatusBarService,
mNotificationRoundnessManager,
mTunerService,
mDeviceProvisionedController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 770c4243afc7..a925ccfe174b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -49,6 +49,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.annotation.DimenRes;
import android.graphics.Insets;
import android.graphics.Rect;
import android.os.SystemClock;
@@ -138,7 +139,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Mock private NotificationStackScrollLayoutController mStackScrollLayoutController;
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
@Mock private NotificationShelf mNotificationShelf;
- @Mock private NotificationStackSizeCalculator mNotificationStackSizeCalculator;
+ @Mock private NotificationStackSizeCalculator mStackSizeCalculator;
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock private LargeScreenShadeInterpolator mLargeScreenShadeInterpolator;
@Mock private AvalancheController mAvalancheController;
@@ -197,7 +198,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
// refer to the CUT's member variables, not the spy's member variables.
mStackScrollerInternal = new NotificationStackScrollLayout(getContext(), null);
mStackScrollerInternal.initView(getContext(), mNotificationSwipeHelper,
- mNotificationStackSizeCalculator);
+ mStackSizeCalculator);
mStackScroller = spy(mStackScrollerInternal);
mStackScroller.setResetUserExpandedStatesRunnable(() -> {});
mStackScroller.setEmptyShadeView(mEmptyShadeView);
@@ -233,6 +234,32 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
}
@Test
+ @EnableSceneContainer
+ public void testIntrinsicStackHeight() {
+ int stackHeight = 300;
+ when(mStackSizeCalculator.computeHeight(eq(mStackScroller), anyInt(), anyFloat()))
+ .thenReturn((float) stackHeight);
+
+ mStackScroller.updateContentHeight();
+
+ assertThat(mStackScroller.getIntrinsicStackHeight()).isEqualTo(stackHeight);
+ }
+
+ @Test
+ @DisableSceneContainer
+ public void testIntrinsicStackHeight_includesTopScrimPadding() {
+ int stackHeight = 300;
+ int topScrimPadding = px(R.dimen.notification_side_paddings);
+ when(mStackSizeCalculator.computeHeight(eq(mStackScroller), anyInt(), anyFloat()))
+ .thenReturn((float) stackHeight);
+
+ mStackScroller.updateContentHeight();
+
+ assertThat(mStackScroller.getIntrinsicStackHeight())
+ .isEqualTo(stackHeight + topScrimPadding);
+ }
+
+ @Test
@DisableSceneContainer // TODO(b/312473478): address disabled test
public void testUpdateStackHeight_qsExpansionZero() {
final float expansionFraction = 0.2f;
@@ -819,7 +846,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@DisableSceneContainer // TODO(b/312473478): address disabled test
public void setFractionToShade_recomputesStackHeight() {
mStackScroller.setFractionToShade(1f);
- verify(mNotificationStackSizeCalculator).computeHeight(any(), anyInt(), anyFloat());
+ verify(mStackSizeCalculator).computeHeight(any(), anyInt(), anyFloat());
}
@Test
@@ -1231,6 +1258,10 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
assertEquals(expected, mAmbientState.isClearAllInProgress());
}
+ private int px(@DimenRes int id) {
+ return mTestableResources.getResources().getDimensionPixelSize(id);
+ }
+
private static void mockBoundsOnScreen(View view, Rect bounds) {
doAnswer(invocation -> {
Rect out = invocation.getArgument(0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index b12c0986bdfa..c2a7b52d9f19 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -115,6 +115,17 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
}
@Test
+ @EnableSceneContainer
+ fun resetViewStates_childPositionedAtStackTop() {
+ val stackTop = 100f
+ ambientState.stackTop = stackTop
+
+ stackScrollAlgorithm.resetViewStates(ambientState, 0)
+
+ assertThat(notificationRow.viewState.yTranslation).isEqualTo(stackTop)
+ }
+
+ @Test
fun resetViewStates_defaultHun_yTranslationIsInset() {
whenever(notificationRow.isPinned).thenReturn(true)
whenever(notificationRow.isHeadsUp).thenReturn(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index 285949a41fcd..9eafcdbadfa5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -495,18 +495,18 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
}
@Test
- public void biometricUnlockStateResetOnTransitionFromGone() {
- mBiometricUnlockController.consumeTransitionStepOnStartedKeyguardState(
+ public void biometricUnlockStateResetOnStartedTransition() {
+ mBiometricUnlockController.consumeFromGoneTransitions(
new TransitionStep(
- KeyguardState.AOD,
KeyguardState.GONE,
+ KeyguardState.AOD,
.1f /* value */,
- TransitionState.STARTED
+ TransitionState.RUNNING
)
);
verify(mBiometricUnlockInteractor, never()).setBiometricUnlockState(anyInt(), any());
- mBiometricUnlockController.consumeTransitionStepOnStartedKeyguardState(
+ mBiometricUnlockController.consumeFromGoneTransitions(
new TransitionStep(
KeyguardState.GONE,
KeyguardState.AOD,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
index 7cb41f119c9a..5052a008af68 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
@@ -52,6 +52,8 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.unfold.FoldAodAnimationController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
+import com.android.systemui.util.settings.FakeSettings;
+import com.android.systemui.util.settings.SecureSettings;
import org.junit.Assert;
import org.junit.Before;
@@ -113,6 +115,7 @@ public class DozeParametersTest extends SysuiTestCase {
.thenReturn(mFoldAodAnimationController);
when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
+ SecureSettings secureSettings = new FakeSettings();
mDozeParameters = new DozeParameters(
mContext,
mHandler,
@@ -130,7 +133,8 @@ public class DozeParametersTest extends SysuiTestCase {
mConfigurationController,
mStatusBarStateController,
mUserTracker,
- mDozeInteractor
+ mDozeInteractor,
+ secureSettings
);
verify(mBatteryController).addCallback(mBatteryStateChangeCallback.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index 53e643e00be4..68e17c1b2d73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
@@ -52,28 +52,17 @@ import androidx.test.filters.SmallTest;
import com.android.keyguard.CarrierTextController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.keyguard.TestScopeProvider;
import com.android.keyguard.logging.KeyguardLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.battery.BatteryMeterViewController;
-import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository;
-import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository;
-import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor;
import com.android.systemui.flags.DisableSceneContainer;
import com.android.systemui.flags.EnableSceneContainer;
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.power.domain.interactor.PowerInteractorFactory;
import com.android.systemui.res.R;
import com.android.systemui.shade.ShadeViewStateProvider;
-import com.android.systemui.shade.data.repository.FakeShadeRepository;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.data.repository.FakeKeyguardStatusBarRepository;
-import com.android.systemui.statusbar.domain.interactor.KeyguardStatusBarInteractor;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.ui.StatusBarIconController;
import com.android.systemui.statusbar.phone.ui.TintedIconManager;
@@ -82,14 +71,11 @@ 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.statusbar.policy.UserInfoController;
-import com.android.systemui.statusbar.ui.viewmodel.KeyguardStatusBarViewModel;
import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.FakeSystemClock;
-import kotlinx.coroutines.test.TestScope;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -150,11 +136,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
private KeyguardStatusBarViewController mController;
private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
private final FakeExecutor mBackgroundExecutor = new FakeExecutor(new FakeSystemClock());
- private final TestScope mTestScope = TestScopeProvider.getTestScope();
- private final FakeKeyguardRepository mKeyguardRepository = new FakeKeyguardRepository();
private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
- private KeyguardInteractor mKeyguardInteractor;
- private KeyguardStatusBarViewModel mViewModel;
@Before
public void setup() throws Exception {
@@ -163,28 +145,6 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
when(mIconManagerFactory.create(any(), any())).thenReturn(mIconManager);
- KeyguardTransitionInteractor keyguardTransitionInteractor =
- mKosmos.getKeyguardTransitionInteractor();
- mKeyguardInteractor = new KeyguardInteractor(
- mKeyguardRepository,
- mCommandQueue,
- PowerInteractorFactory.create().getPowerInteractor(),
- new FakeKeyguardBouncerRepository(),
- new ConfigurationInteractor(new FakeConfigurationRepository()),
- new FakeShadeRepository(),
- keyguardTransitionInteractor,
- () -> mKosmos.getSceneInteractor(),
- () -> mKosmos.getFromGoneTransitionInteractor(),
- () -> mKosmos.getFromLockscreenTransitionInteractor(),
- () -> mKosmos.getSharedNotificationContainerInteractor(),
- mTestScope);
- mViewModel =
- new KeyguardStatusBarViewModel(
- mTestScope.getBackgroundScope(),
- mKosmos.getHeadsUpNotificationInteractor(),
- mKeyguardInteractor,
- new KeyguardStatusBarInteractor(new FakeKeyguardStatusBarRepository()),
- mBatteryController);
allowTestableLooperAsMainThread();
TestableLooper.get(this).runWithLooper(() -> {
@@ -212,7 +172,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
mKeyguardStateController,
mKeyguardBypassController,
mKeyguardUpdateMonitor,
- mViewModel,
+ mKosmos.getKeyguardStatusBarViewModel(),
mBiometricUnlockController,
mStatusBarStateController,
mStatusBarContentInsetsProvider,
@@ -356,6 +316,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void setBatteryListening_true_callbackAdded() {
mController.setBatteryListening(true);
@@ -363,6 +324,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void setBatteryListening_false_callbackRemoved() {
// First set to true so that we know setting to false is a change in state.
mController.setBatteryListening(true);
@@ -373,6 +335,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void setBatteryListening_trueThenTrue_callbackAddedOnce() {
mController.setBatteryListening(true);
mController.setBatteryListening(true);
@@ -412,6 +375,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_alphaAndVisibilityGiven_viewUpdated() {
// Verify the initial values so we know the method triggers changes.
assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(1f);
@@ -426,6 +390,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_paramVisibleButIsDisabled_viewIsInvisible() {
mController.onViewAttached();
setDisableSystemIcons(true);
@@ -437,6 +402,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_notKeyguardState_nothingUpdated() {
mController.onViewAttached();
updateStateToNotKeyguard();
@@ -449,6 +415,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_bypassEnabledAndShouldListenForFace_viewHidden() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -464,6 +431,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_bypassNotEnabled_viewShown() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -478,6 +446,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_shouldNotListenForFace_viewShown() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -492,6 +461,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_panelExpandedHeightZero_viewHidden() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -504,6 +474,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_dragProgressOne_viewHidden() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -516,6 +487,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_disableSystemInfoFalse_viewShown() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -527,6 +499,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_disableSystemInfoTrue_viewHidden() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -538,6 +511,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_disableSystemIconsFalse_viewShown() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -549,6 +523,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateViewState_disableSystemIconsTrue_viewHidden() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -648,6 +623,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void setAlpha_explicitAlpha_setsExplicitAlpha() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -658,6 +634,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void setAlpha_explicitAlpha_thenMinusOneAlpha_setsAlphaBasedOnDefaultCriteria() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -672,6 +649,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
// TODO(b/195442899): Add more tests for #updateViewState once CLs are finalized.
@Test
+ @DisableSceneContainer
public void updateForHeadsUp_headsUpShouldBeVisible_viewHidden() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -684,6 +662,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void updateForHeadsUp_headsUpShouldNotBeVisible_viewShown() {
mController.onViewAttached();
updateStateToKeyguard();
@@ -773,6 +752,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void animateKeyguardStatusBarIn_isDisabled_viewStillHidden() {
mController.onViewAttached();
updateStateToKeyguard();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 4590071f0a2d..73e3bf4af31e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -49,6 +49,8 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.testing.TestableLooper;
import android.testing.ViewUtils;
import android.util.MathUtils;
@@ -65,6 +67,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ShadeInterpolation;
import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
import com.android.systemui.dock.DockManager;
+import com.android.systemui.flags.EnableSceneContainer;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
@@ -75,7 +78,9 @@ import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToGoneTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
import com.android.systemui.kosmos.KosmosJavaAdapter;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.scrim.ScrimView;
+import com.android.systemui.shade.shared.flag.DualShade;
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
import com.android.systemui.shade.transition.LinearLargeScreenShadeInterpolator;
import com.android.systemui.statusbar.policy.FakeConfigurationController;
@@ -309,7 +314,11 @@ public class ScrimControllerTest extends SysuiTestCase {
mWallpaperRepository.getWallpaperSupportsAmbientMode().setValue(false);
mTestScope.getTestScheduler().runCurrent();
- mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
+ if (SceneContainerFlag.isEnabled()) {
+ mScrimController.transitionTo(ScrimState.KEYGUARD);
+ } else {
+ mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
+ }
finishAnimationsImmediately();
}
@@ -358,6 +367,47 @@ public class ScrimControllerTest extends SysuiTestCase {
}
@Test
+ @EnableSceneContainer
+ @DisableFlags(DualShade.FLAG_NAME)
+ public void transitionToShadeLocked_sceneContainer_dualShadeOff() {
+ mScrimController.transitionTo(SHADE_LOCKED);
+ mScrimController.setQsPosition(1f, 0);
+ finishAnimationsImmediately();
+
+ assertScrimAlpha(Map.of(
+ mNotificationsScrim, OPAQUE,
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE
+ ));
+
+ assertScrimTinted(Map.of(
+ mScrimInFront, false,
+ mScrimBehind, true
+ ));
+ }
+
+ @Test
+ @EnableSceneContainer
+ @EnableFlags(DualShade.FLAG_NAME)
+ public void transitionToShadeLocked_sceneContainer_dualShadeOn() {
+ mScrimController.transitionTo(SHADE_LOCKED);
+ mScrimController.setQsPosition(1f, 0);
+ finishAnimationsImmediately();
+
+ assertScrimAlpha(Map.of(
+ mNotificationsScrim, TRANSPARENT,
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, TRANSPARENT
+ ));
+
+ assertScrimTinted(Map.of(
+ mScrimInFront, false,
+ mNotificationsScrim, false,
+ mScrimBehind, false
+ ));
+ }
+
+ @Test
public void transitionToShadeLocked_clippingQs() {
mScrimController.setClipsQsScrim(true);
mScrimController.legacyTransitionTo(SHADE_LOCKED);
@@ -997,6 +1047,64 @@ public class ScrimControllerTest extends SysuiTestCase {
}
@Test
+ @EnableSceneContainer
+ @DisableFlags(DualShade.FLAG_NAME)
+ public void transitionToUnlocked_sceneContainer_dualShadeOff() {
+ mScrimController.setRawPanelExpansionFraction(0f);
+ mScrimController.transitionTo(ScrimState.UNLOCKED);
+ finishAnimationsImmediately();
+
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT,
+ mScrimBehind, TRANSPARENT
+ ));
+
+ mScrimController.setRawPanelExpansionFraction(0.5f);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, SEMI_TRANSPARENT,
+ mScrimBehind, SEMI_TRANSPARENT
+ ));
+
+ mScrimController.setRawPanelExpansionFraction(1f);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, OPAQUE,
+ mScrimBehind, OPAQUE
+ ));
+ }
+
+ @Test
+ @EnableSceneContainer
+ @EnableFlags(DualShade.FLAG_NAME)
+ public void transitionToUnlocked_sceneContainer_dualShadeOn() {
+ mScrimController.setRawPanelExpansionFraction(0f);
+ mScrimController.transitionTo(ScrimState.UNLOCKED);
+ finishAnimationsImmediately();
+
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT,
+ mScrimBehind, TRANSPARENT
+ ));
+
+ mScrimController.setRawPanelExpansionFraction(0.5f);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT,
+ mScrimBehind, TRANSPARENT
+ ));
+
+ mScrimController.setRawPanelExpansionFraction(1f);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT,
+ mScrimBehind, TRANSPARENT
+ ));
+ }
+
+ @Test
public void transitionToUnlocked_nonClippedQs_followsLargeScreensInterpolator() {
mScrimController.setClipsQsScrim(false);
mScrimController.setRawPanelExpansionFraction(0f);
@@ -2086,7 +2194,7 @@ public class ScrimControllerTest extends SysuiTestCase {
}
private void assertScrimTinted(Map<ScrimView, Boolean> scrimToTint) {
- scrimToTint.forEach((scrim, hasTint) -> assertScrimTint(scrim, hasTint));
+ scrimToTint.forEach(this::assertScrimTint);
}
private void assertScrimTint(ScrimView scrim, boolean hasTint) {
@@ -2123,7 +2231,7 @@ public class ScrimControllerTest extends SysuiTestCase {
if (!scrimToAlpha.containsKey(mNotificationsScrim)) {
assertScrimAlpha(mNotificationsScrim, TRANSPARENT);
}
- scrimToAlpha.forEach((scrimView, alpha) -> assertScrimAlpha(scrimView, alpha));
+ scrimToAlpha.forEach(this::assertScrimAlpha);
// When clipping, QS scrim should not affect combined visibility.
if (mScrimController.getClipQsScrim() && scrimToAlpha.get(mScrimBehind) == OPAQUE) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 3ca4c594cede..0e4d892438ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -37,6 +37,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
@@ -66,6 +68,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.TrustGrantFlags;
import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
@@ -74,8 +77,11 @@ import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInte
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
import com.android.systemui.bouncer.ui.BouncerView;
import com.android.systemui.bouncer.ui.BouncerViewDelegate;
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.flags.DisableSceneContainer;
+import com.android.systemui.flags.EnableSceneContainer;
import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardSurfaceBehindInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
@@ -158,6 +164,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
@Mock private TaskbarDelegate mTaskbarDelegate;
@Mock private StatusBarKeyguardViewManager.KeyguardViewManagerCallback mCallback;
@Mock private SelectedUserInteractor mSelectedUserInteractor;
+ @Mock private DeviceEntryInteractor mDeviceEntryInteractor;
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback
@@ -178,6 +185,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Before
+ @DisableFlags(com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mContainer.findViewById(anyInt())).thenReturn(mKeyguardMessageArea);
@@ -185,10 +193,6 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
.thenReturn(mKeyguardMessageAreaController);
when(mBouncerView.getDelegate()).thenReturn(mBouncerViewDelegate);
when(mBouncerViewDelegate.getBackCallback()).thenReturn(mBouncerViewDelegateBackCallback);
- mSetFlagsRule.disableFlags(
- com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR,
- com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR
- );
when(mNotificationShadeWindowController.getWindowRootView())
.thenReturn(mNotificationShadeWindowView);
@@ -227,7 +231,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
() -> mock(KeyguardSurfaceBehindInteractor.class),
mock(JavaAdapter.class),
() -> mock(SceneInteractor.class),
- mock(StatusBarKeyguardViewManagerInteractor.class)) {
+ mock(StatusBarKeyguardViewManagerInteractor.class),
+ () -> mDeviceEntryInteractor) {
@Override
public ViewRootImpl getViewRootImpl() {
return mViewRootImpl;
@@ -250,6 +255,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void dismissWithAction_AfterKeyguardGoneSetToFalse() {
OnDismissAction action = () -> false;
Runnable cancelAction = () -> {
@@ -265,6 +271,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
mStatusBarKeyguardViewManager.hide(0 /* startTime */, 0 /* fadeoutDuration */);
mStatusBarKeyguardViewManager.showPrimaryBouncer(true /* scrimmed */);
verify(mPrimaryBouncerInteractor, never()).show(anyBoolean());
+ verify(mDeviceEntryInteractor, never()).attemptDeviceEntry();
}
@Test
@@ -274,9 +281,11 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
KeyguardSecurityModel.SecurityMode.Password);
mStatusBarKeyguardViewManager.showPrimaryBouncer(true /* scrimmed */);
verify(mPrimaryBouncerInteractor, never()).show(anyBoolean());
+ verify(mDeviceEntryInteractor, never()).attemptDeviceEntry();
}
@Test
+ @DisableSceneContainer
public void showBouncer_showsTheBouncer() {
mStatusBarKeyguardViewManager.showPrimaryBouncer(true /* scrimmed */);
verify(mPrimaryBouncerInteractor).show(eq(true));
@@ -320,6 +329,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void onPanelExpansionChanged_showsBouncerWhenSwiping() {
mKeyguardStateController.setCanDismissLockScreen(false);
mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
@@ -456,6 +466,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void testHiding_cancelsGoneRunnable() {
OnDismissAction action = mock(OnDismissAction.class);
Runnable cancelAction = mock(Runnable.class);
@@ -470,6 +481,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void testHidingBouncer_cancelsGoneRunnable() {
OnDismissAction action = mock(OnDismissAction.class);
Runnable cancelAction = mock(Runnable.class);
@@ -484,6 +496,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void testHiding_doesntCancelWhenShowing() {
OnDismissAction action = mock(OnDismissAction.class);
Runnable cancelAction = mock(Runnable.class);
@@ -539,6 +552,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void testShowAltAuth_unlockingWithBiometricNotAllowed() {
// GIVEN cannot use alternate bouncer
when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
@@ -553,6 +567,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
+ @DisableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
public void testShowAlternateBouncer_unlockingWithBiometricAllowed() {
// GIVEN will show alternate bouncer
when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
@@ -735,7 +751,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
() -> mock(KeyguardSurfaceBehindInteractor.class),
mock(JavaAdapter.class),
() -> mock(SceneInteractor.class),
- mock(StatusBarKeyguardViewManagerInteractor.class)) {
+ mock(StatusBarKeyguardViewManagerInteractor.class),
+ () -> mDeviceEntryInteractor) {
@Override
public ViewRootImpl getViewRootImpl() {
return mViewRootImpl;
@@ -783,11 +800,11 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @EnableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
public void handleDispatchTouchEvent_alternateBouncerViewFlagEnabled() {
mStatusBarKeyguardViewManager.addCallback(mCallback);
// GIVEN alternate bouncer view flag enabled & the alternate bouncer is visible
- mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR);
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
// THEN the touch is not acted upon
@@ -795,9 +812,9 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @EnableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
public void onInterceptTouch_alternateBouncerViewFlagEnabled() {
// GIVEN alternate bouncer view flag enabled & the alternate bouncer is visible
- mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR);
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
// THEN the touch is not intercepted
@@ -829,6 +846,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
+ @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
public void handleDispatchTouchEvent_shouldInterceptTouchAndHandleTouch() {
mStatusBarKeyguardViewManager.addCallback(mCallback);
@@ -855,6 +874,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
+ @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
public void handleDispatchTouchEvent_shouldInterceptTouchButNotHandleTouch() {
mStatusBarKeyguardViewManager.addCallback(mCallback);
@@ -881,6 +902,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void shouldInterceptTouch_alternateBouncerNotVisible() {
// GIVEN the alternate bouncer is not visible
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false);
@@ -898,6 +920,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
+ @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
public void shouldInterceptTouch_alternateBouncerVisible() {
// GIVEN the alternate bouncer is visible
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
@@ -931,6 +955,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
+ @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
public void alternateBouncerOnTouch_actionDownThenUp_noMinTimeShown_noHideAltBouncer() {
reset(mAlternateBouncerInteractor);
@@ -955,6 +981,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
+ @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
public void alternateBouncerOnTouch_actionDownThenUp_handlesTouch_hidesAltBouncer() {
reset(mAlternateBouncerInteractor);
@@ -979,6 +1007,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void alternateBouncerOnTouch_actionUp_doesNotHideAlternateBouncer() {
reset(mAlternateBouncerInteractor);
@@ -996,6 +1025,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
+ @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
public void onTrustChanged_hideAlternateBouncerAndClearMessageArea() {
// GIVEN keyguard update monitor callback is registered
verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture());
@@ -1024,6 +1055,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void testShowBouncerOrKeyguard_needsFullScreen() {
when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(
KeyguardSecurityModel.SecurityMode.SimPin);
@@ -1033,6 +1065,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void testShowBouncerOrKeyguard_needsFullScreen_bouncerAlreadyShowing() {
when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(
KeyguardSecurityModel.SecurityMode.SimPin);
@@ -1043,6 +1076,20 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ @EnableSceneContainer
+ public void showBouncer_attemptDeviceEntry() {
+ mStatusBarKeyguardViewManager.showBouncer(false);
+ verify(mDeviceEntryInteractor).attemptDeviceEntry();
+ }
+
+ @Test
+ @EnableSceneContainer
+ public void showPrimaryBouncer_attemptDeviceEntry() {
+ mStatusBarKeyguardViewManager.showPrimaryBouncer(false);
+ verify(mDeviceEntryInteractor).attemptDeviceEntry();
+ }
+
+ @Test
public void altBouncerNotVisible_keyguardAuthenticatedBiometricsHandled() {
clearInvocations(mAlternateBouncerInteractor);
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
index 30e96f10918d..e439aff423b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
@@ -738,6 +738,28 @@ class MobileIconInteractorTest : SysuiTestCase() {
assertThat(latest).isInstanceOf(SignalIconModel.Satellite::class.java)
}
+ @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
+ @Test
+ // See b/346904529 for more context
+ fun satBasedIcon_doesNotInflateSignalStrength() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.signalLevelIcon)
+
+ // GIVEN a satellite connection
+ connectionRepository.isNonTerrestrial.value = true
+ // GIVEN this carrier has set INFLATE_SIGNAL_STRENGTH
+ connectionRepository.inflateSignalStrength.value = true
+
+ connectionRepository.primaryLevel.value = 4
+ assertThat(latest!!.level).isEqualTo(4)
+
+ connectionRepository.inflateSignalStrength.value = true
+ connectionRepository.primaryLevel.value = 4
+
+ // Icon level is unaffected
+ assertThat(latest!!.level).isEqualTo(4)
+ }
+
private fun createInteractor(
overrides: MobileIconCarrierIdOverrides = MobileIconCarrierIdOverridesImpl()
) =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
index cec41557f344..e51092429cd6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
@@ -862,6 +862,38 @@ class MobileIconViewModelTest : SysuiTestCase() {
assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
}
+ @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
+ @Test
+ fun satelliteIcon_ignoresInflateSignalStrength() =
+ testScope.runTest {
+ // Note that this is the exact same test as above, but with inflateSignalStrength set to
+ // true we note that the level is unaffected by inflation
+ repository.inflateSignalStrength.value = true
+ repository.isNonTerrestrial.value = true
+ repository.setAllLevels(0)
+
+ val latest by
+ collectLastValue(underTest.icon.filterIsInstance(SignalIconModel.Satellite::class))
+
+ // Level 0 -> no connection
+ assertThat(latest).isNotNull()
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
+
+ // 1-2 -> 1 bar
+ repository.setAllLevels(1)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+
+ repository.setAllLevels(2)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+
+ // 3-4 -> 2 bars
+ repository.setAllLevels(3)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+
+ repository.setAllLevels(4)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+ }
+
private fun createAndSetViewModel() {
underTest =
MobileIconViewModel(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
index ed8843b1d9f4..db829a2c1f42 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -23,6 +23,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSess
import static com.android.dx.mockito.inline.extended.ExtendedMockito.staticMockMarker;
import static com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_QS;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -308,6 +310,52 @@ public class BatteryControllerTest extends SysuiTestCase {
mBatteryController.fireBatteryLevelChanged();
}
+ @Test
+ public void plugAndUnplugWhenInBatterySaver_stateUpdatedWithoutBatterySaverBroadcast() {
+ PowerSaveState state = new PowerSaveState.Builder()
+ .setBatterySaverEnabled(false)
+ .build();
+ when(mPowerManager.getPowerSaveState(PowerManager.ServiceType.AOD)).thenReturn(state);
+
+ // Set up on power save and not charging
+ when(mPowerManager.isPowerSaveMode()).thenReturn(true);
+ mBatteryController.onReceive(
+ getContext(), new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
+ mBatteryController.onReceive(getContext(), createChargingIntent(false));
+
+ TestCallback callback = new TestCallback();
+ mBatteryController.addCallback(callback);
+
+ assertThat(callback.pluggedIn).isFalse();
+ assertThat(callback.powerSaverOn).isTrue();
+
+ // Plug in (battery saver turns off)
+ when(mPowerManager.isPowerSaveMode()).thenReturn(false);
+ mBatteryController.onReceive(getContext(), createChargingIntent(true));
+
+ assertThat(callback.pluggedIn).isTrue();
+ assertThat(callback.powerSaverOn).isFalse();
+
+ // Unplug (battery saver turns back on)
+ when(mPowerManager.isPowerSaveMode()).thenReturn(true);
+ mBatteryController.onReceive(getContext(), createChargingIntent(false));
+
+ assertThat(callback.pluggedIn).isFalse();
+ assertThat(callback.powerSaverOn).isTrue();
+ }
+
+ private Intent createChargingIntent(boolean charging) {
+ Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
+ if (charging) {
+ return intent
+ .putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_CHARGING)
+ .putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_AC);
+ } else {
+ return intent
+ .putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_DISCHARGING);
+ }
+ }
+
private void setupIncompatibleCharging() {
final List<UsbPort> usbPorts = new ArrayList<>();
usbPorts.add(mUsbPort);
@@ -318,4 +366,19 @@ public class BatteryControllerTest extends SysuiTestCase {
when(mUsbPortStatus.getComplianceWarnings())
.thenReturn(new int[]{UsbPortStatus.COMPLIANCE_WARNING_DEBUG_ACCESSORY});
}
+
+ private static class TestCallback
+ implements BatteryController.BatteryStateChangeCallback {
+ boolean pluggedIn = false;
+ boolean powerSaverOn = false;
+ @Override
+ public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+ this.pluggedIn = pluggedIn;
+ }
+
+ @Override
+ public void onPowerSaveChanged(boolean isPowerSave) {
+ this.powerSaverOn = isPowerSave;
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
index 59b20c824739..627463b45982 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
@@ -1,6 +1,8 @@
package com.android.systemui.statusbar.policy;
+import static com.android.systemui.log.LogBufferHelperKt.logcatLogBuffer;
+
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
@@ -58,7 +60,8 @@ public class CastControllerImplTest extends SysuiTestCase {
mController = new CastControllerImpl(
mContext,
mock(PackageManager.class),
- mock(DumpManager.class));
+ mock(DumpManager.class),
+ new CastControllerLogger(logcatLogBuffer("CastControllerImplTest")));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt
index 03ad66cd4cce..16061df1fa89 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt
@@ -25,6 +25,7 @@ import android.media.MediaRouter
import android.media.projection.MediaProjectionInfo
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.res.R
import com.android.systemui.statusbar.policy.CastDevice.Companion.toCastDevice
import com.google.common.truth.Truth.assertThat
@@ -40,6 +41,7 @@ import org.mockito.kotlin.whenever
class CastDeviceTest : SysuiTestCase() {
private val mockAppInfo =
mock<ApplicationInfo>().apply { whenever(this.loadLabel(any())).thenReturn("") }
+ private val logger = CastControllerLogger(logcatLogBuffer("CastDeviceTest"))
private val packageManager =
mock<PackageManager>().apply {
@@ -322,7 +324,7 @@ class CastDeviceTest : SysuiTestCase() {
whenever(this.packageName).thenReturn("fake.package")
}
- val device = projection.toCastDevice(context, packageManager)
+ val device = projection.toCastDevice(context, packageManager, logger)
assertThat(device.id).isEqualTo("fake.package")
}
@@ -334,7 +336,7 @@ class CastDeviceTest : SysuiTestCase() {
whenever(this.packageName).thenReturn(HEADLESS_REMOTE_PACKAGE)
}
- val device = projection.toCastDevice(context, packageManager)
+ val device = projection.toCastDevice(context, packageManager, logger)
assertThat(device.name).isEmpty()
}
@@ -349,7 +351,7 @@ class CastDeviceTest : SysuiTestCase() {
whenever(packageManager.getApplicationInfo(eq(NORMAL_PACKAGE), any<Int>()))
.thenThrow(PackageManager.NameNotFoundException())
- val device = projection.toCastDevice(context, packageManager)
+ val device = projection.toCastDevice(context, packageManager, logger)
assertThat(device.name).isEqualTo(NORMAL_PACKAGE)
}
@@ -366,7 +368,7 @@ class CastDeviceTest : SysuiTestCase() {
whenever(packageManager.getApplicationInfo(eq(NORMAL_PACKAGE), any<Int>()))
.thenReturn(appInfo)
- val device = projection.toCastDevice(context, packageManager)
+ val device = projection.toCastDevice(context, packageManager, logger)
assertThat(device.name).isEqualTo(NORMAL_PACKAGE)
}
@@ -383,7 +385,7 @@ class CastDeviceTest : SysuiTestCase() {
whenever(packageManager.getApplicationInfo(eq(NORMAL_PACKAGE), any<Int>()))
.thenReturn(appInfo)
- val device = projection.toCastDevice(context, packageManager)
+ val device = projection.toCastDevice(context, packageManager, logger)
assertThat(device.name).isEqualTo("Valid App Name")
}
@@ -392,7 +394,7 @@ class CastDeviceTest : SysuiTestCase() {
fun projectionToCastDevice_descriptionIsCasting() {
val projection = mockProjectionInfo()
- val device = projection.toCastDevice(context, packageManager)
+ val device = projection.toCastDevice(context, packageManager, logger)
assertThat(device.description).isEqualTo(context.getString(R.string.quick_settings_casting))
}
@@ -401,7 +403,7 @@ class CastDeviceTest : SysuiTestCase() {
fun projectionToCastDevice_stateIsConnected() {
val projection = mockProjectionInfo()
- val device = projection.toCastDevice(context, packageManager)
+ val device = projection.toCastDevice(context, packageManager, logger)
assertThat(device.state).isEqualTo(CastDevice.CastState.Connected)
}
@@ -410,7 +412,7 @@ class CastDeviceTest : SysuiTestCase() {
fun projectionToCastDevice_tagIsProjection() {
val projection = mockProjectionInfo()
- val device = projection.toCastDevice(context, packageManager)
+ val device = projection.toCastDevice(context, packageManager, logger)
assertThat(device.tag).isEqualTo(projection)
}
@@ -419,7 +421,7 @@ class CastDeviceTest : SysuiTestCase() {
fun projectionToCastDevice_originIsMediaProjection() {
val projection = mockProjectionInfo()
- val device = projection.toCastDevice(context, packageManager)
+ val device = projection.toCastDevice(context, packageManager, logger)
assertThat(device.origin).isEqualTo(CastDevice.CastOrigin.MediaProjection)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
index d88289d9132c..cc2ef53c6cdb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.ui.viewmodel
+import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -26,10 +27,13 @@ import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.domain.interactor.keyguardStatusBarInteractor
import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
+import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor
import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
import com.android.systemui.statusbar.notification.stack.data.repository.setNotifications
import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
@@ -85,6 +89,7 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa
KeyguardStatusBarViewModel(
testScope.backgroundScope,
headsUpNotificationInteractor,
+ kosmos.sceneInteractor,
keyguardInteractor,
keyguardStatusBarInteractor,
batteryController,
@@ -95,7 +100,7 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa
fun isVisible_dozing_false() =
testScope.runTest {
val latest by collectLastValue(underTest.isVisible)
- keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
keyguardRepository.setIsDozing(true)
@@ -103,26 +108,27 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa
}
@Test
- fun isVisible_statusBarStateShade_false() =
+ fun isVisible_sceneShade_false() =
testScope.runTest {
val latest by collectLastValue(underTest.isVisible)
- keyguardRepository.setStatusBarState(StatusBarState.SHADE)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Shade)
assertThat(latest).isFalse()
}
@Test
- fun isVisible_statusBarStateShadeLocked_false() =
+ fun isVisible_sceneBouncer_false() =
testScope.runTest {
val latest by collectLastValue(underTest.isVisible)
- keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)
assertThat(latest).isFalse()
}
@Test
+ @EnableFlags(NotificationsHeadsUpRefactor.FLAG_NAME)
fun isVisible_headsUpStatusBarShown_false() =
testScope.runTest {
val latest by collectLastValue(underTest.isVisible)
@@ -130,7 +136,7 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa
// WHEN HUN displayed on the bypass lock screen
headsUpRepository.setNotifications(FakeHeadsUpRowRepository("key 0", isPinned = true))
keyguardTransitionRepository.emitInitialStepsFromOff(KeyguardState.LOCKSCREEN)
- keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
faceAuthRepository.isBypassEnabled.value = true
// THEN KeyguardStatusBar is NOT visible to make space for HeadsUpStatusBar
@@ -138,11 +144,11 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa
}
@Test
- fun isVisible_statusBarStateKeyguard_andNotDozing_andNotShowingHeadsUpStatusBar_true() =
+ fun isVisible_sceneLockscreen_andNotDozing_andNotShowingHeadsUpStatusBar_true() =
testScope.runTest {
val latest by collectLastValue(underTest.isVisible)
- keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
keyguardRepository.setIsDozing(false)
assertThat(latest).isTrue()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitorTest.kt
new file mode 100644
index 000000000000..cf0db7b51676
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitorTest.kt
@@ -0,0 +1,160 @@
+/*
+ * 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.touchpad.tutorial.ui.gesture
+
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.ACTION_POINTER_DOWN
+import android.view.MotionEvent.ACTION_POINTER_UP
+import android.view.MotionEvent.ACTION_UP
+import android.view.MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT
+import android.view.MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE
+import android.view.MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE
+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
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BackGestureMonitorTest : SysuiTestCase() {
+
+ private var gestureDoneWasCalled = false
+ private val gestureDoneCallback = { gestureDoneWasCalled = true }
+ private val gestureMonitor = BackGestureMonitor(SWIPE_DISTANCE.toInt(), gestureDoneCallback)
+
+ companion object {
+ const val SWIPE_DISTANCE = 100f
+ }
+
+ @Test
+ fun triggersGestureDoneForThreeFingerGestureRight() {
+ val events =
+ listOf(
+ threeFingerEvent(ACTION_DOWN, x = 0f, y = 0f),
+ threeFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+ threeFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+ threeFingerEvent(ACTION_MOVE, x = SWIPE_DISTANCE / 2, y = 0f),
+ threeFingerEvent(ACTION_POINTER_UP, x = SWIPE_DISTANCE, y = 0f),
+ threeFingerEvent(ACTION_POINTER_UP, x = SWIPE_DISTANCE, y = 0f),
+ threeFingerEvent(ACTION_UP, x = SWIPE_DISTANCE, y = 0f),
+ )
+
+ events.forEach { gestureMonitor.processTouchpadEvent(it) }
+
+ assertThat(gestureDoneWasCalled).isTrue()
+ }
+
+ @Test
+ fun triggersGestureDoneForThreeFingerGestureLeft() {
+ val events =
+ listOf(
+ threeFingerEvent(ACTION_DOWN, x = SWIPE_DISTANCE, y = 0f),
+ threeFingerEvent(ACTION_POINTER_DOWN, x = SWIPE_DISTANCE, y = 0f),
+ threeFingerEvent(ACTION_POINTER_DOWN, x = SWIPE_DISTANCE, y = 0f),
+ threeFingerEvent(ACTION_MOVE, x = SWIPE_DISTANCE / 2, y = 0f),
+ threeFingerEvent(ACTION_POINTER_UP, x = 0f, y = 0f),
+ threeFingerEvent(ACTION_POINTER_UP, x = 0f, y = 0f),
+ threeFingerEvent(ACTION_UP, x = 0f, y = 0f),
+ )
+
+ events.forEach { gestureMonitor.processTouchpadEvent(it) }
+
+ assertThat(gestureDoneWasCalled).isTrue()
+ }
+
+ private fun threeFingerEvent(action: Int, x: Float, y: Float): MotionEvent {
+ return motionEvent(
+ action = action,
+ x = x,
+ y = y,
+ classification = CLASSIFICATION_MULTI_FINGER_SWIPE,
+ axisValues = mapOf(AXIS_GESTURE_SWIPE_FINGER_COUNT to 3f)
+ )
+ }
+
+ @Test
+ fun doesntTriggerGestureDone_onThreeFingersSwipeUp() {
+ val events =
+ listOf(
+ threeFingerEvent(ACTION_DOWN, x = 0f, y = 0f),
+ threeFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+ threeFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+ threeFingerEvent(ACTION_MOVE, x = 0f, y = SWIPE_DISTANCE / 2),
+ threeFingerEvent(ACTION_POINTER_UP, x = 0f, y = SWIPE_DISTANCE),
+ threeFingerEvent(ACTION_POINTER_UP, x = 0f, y = SWIPE_DISTANCE),
+ threeFingerEvent(ACTION_UP, x = 0f, y = SWIPE_DISTANCE),
+ )
+
+ events.forEach { gestureMonitor.processTouchpadEvent(it) }
+
+ assertThat(gestureDoneWasCalled).isFalse()
+ }
+
+ @Test
+ fun doesntTriggerGestureDone_onTwoFingersSwipe() {
+ fun twoFingerEvent(action: Int, x: Float, y: Float) =
+ motionEvent(
+ action = action,
+ x = x,
+ y = y,
+ classification = CLASSIFICATION_TWO_FINGER_SWIPE,
+ axisValues = mapOf(AXIS_GESTURE_SWIPE_FINGER_COUNT to 2f)
+ )
+ val events =
+ listOf(
+ twoFingerEvent(ACTION_DOWN, x = 0f, y = 0f),
+ twoFingerEvent(ACTION_MOVE, x = SWIPE_DISTANCE / 2, y = 0f),
+ twoFingerEvent(ACTION_UP, x = SWIPE_DISTANCE, y = 0f),
+ )
+
+ events.forEach { gestureMonitor.processTouchpadEvent(it) }
+
+ assertThat(gestureDoneWasCalled).isFalse()
+ }
+
+ @Test
+ fun doesntTriggerGestureDone_onFourFingersSwipe() {
+ fun fourFingerEvent(action: Int, x: Float, y: Float) =
+ motionEvent(
+ action = action,
+ x = x,
+ y = y,
+ classification = CLASSIFICATION_MULTI_FINGER_SWIPE,
+ axisValues = mapOf(AXIS_GESTURE_SWIPE_FINGER_COUNT to 4f)
+ )
+ val events =
+ listOf(
+ fourFingerEvent(ACTION_DOWN, x = 0f, y = 0f),
+ fourFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+ fourFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+ fourFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+ fourFingerEvent(ACTION_MOVE, x = SWIPE_DISTANCE / 2, y = 0f),
+ fourFingerEvent(ACTION_POINTER_UP, x = SWIPE_DISTANCE, y = 0f),
+ fourFingerEvent(ACTION_POINTER_UP, x = SWIPE_DISTANCE, y = 0f),
+ fourFingerEvent(ACTION_POINTER_UP, x = SWIPE_DISTANCE, y = 0f),
+ fourFingerEvent(ACTION_UP, x = SWIPE_DISTANCE, y = 0f),
+ )
+
+ events.forEach { gestureMonitor.processTouchpadEvent(it) }
+
+ assertThat(gestureDoneWasCalled).isFalse()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/FakeMotionEvent.kt b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/FakeMotionEvent.kt
new file mode 100644
index 000000000000..f40282f0da69
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/FakeMotionEvent.kt
@@ -0,0 +1,88 @@
+/*
+ * 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.touchpad.tutorial.ui.gesture
+
+import android.view.InputDevice.SOURCE_CLASS_POINTER
+import android.view.InputDevice.SOURCE_MOUSE
+import android.view.MotionEvent
+import android.view.MotionEvent.CLASSIFICATION_NONE
+import android.view.MotionEvent.TOOL_TYPE_FINGER
+import java.lang.reflect.Method
+import org.mockito.kotlin.doNothing
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
+
+fun motionEvent(
+ action: Int,
+ x: Float,
+ y: Float,
+ source: Int = 0,
+ toolType: Int = TOOL_TYPE_FINGER,
+ pointerCount: Int = 1,
+ axisValues: Map<Int, Float> = emptyMap(),
+ classification: Int = CLASSIFICATION_NONE,
+): MotionEvent {
+ val event =
+ MotionEvent.obtain(/* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0)
+ event.source = source
+ val spy =
+ spy<MotionEvent>(event) {
+ on { getToolType(0) } doReturn toolType
+ on { getPointerCount() } doReturn pointerCount
+ axisValues.forEach { (key, value) -> on { getAxisValue(key) } doReturn value }
+ on { getClassification() } doReturn classification
+ }
+ ensureFinalizeIsNotCalledTwice(spy)
+ return spy
+}
+
+private fun ensureFinalizeIsNotCalledTwice(spy: MotionEvent) {
+ // Spy in mockito will create copy of the spied object, copying all its field etc. Here it means
+ // we create copy of MotionEvent and its mNativePtr, so we have two separate objects of type
+ // MotionEvents with the same mNativePtr. That breaks because MotionEvent has custom finalize()
+ // method which goes to native code and tries to delete the reference from mNativePtr. It works
+ // first time but second time reference is already deleted and it breaks. That's why we have to
+ // avoid calling finalize twice
+ doNothing().whenever(spy).finalizeUsingReflection()
+}
+
+private fun MotionEvent.finalizeUsingReflection() {
+ val finalizeMethod: Method = MotionEvent::class.java.getDeclaredMethod("finalize")
+ finalizeMethod.isAccessible = true
+ finalizeMethod.invoke(this)
+}
+
+fun touchpadEvent(
+ action: Int,
+ x: Float,
+ y: Float,
+ pointerCount: Int = 1,
+ classification: Int = CLASSIFICATION_NONE,
+ axisValues: Map<Int, Float> = emptyMap()
+): MotionEvent {
+ return motionEvent(
+ action = action,
+ x = x,
+ y = y,
+ source = SOURCE_MOUSE or SOURCE_CLASS_POINTER,
+ toolType = TOOL_TYPE_FINGER,
+ pointerCount = pointerCount,
+ classification = classification,
+ axisValues = axisValues
+ )
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt
new file mode 100644
index 000000000000..769f264f0870
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt
@@ -0,0 +1,124 @@
+/*
+ * 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.touchpad.tutorial.ui.gesture
+
+import android.view.InputDevice.SOURCE_MOUSE
+import android.view.InputDevice.SOURCE_TOUCHSCREEN
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_HOVER_ENTER
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.ACTION_POINTER_DOWN
+import android.view.MotionEvent.ACTION_POINTER_UP
+import android.view.MotionEvent.ACTION_UP
+import android.view.MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT
+import android.view.MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE
+import android.view.MotionEvent.TOOL_TYPE_FINGER
+import android.view.MotionEvent.TOOL_TYPE_MOUSE
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGesture.BACK
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class TouchpadGestureHandlerTest : SysuiTestCase() {
+
+ private var gestureDone = false
+ private val handler = TouchpadGestureHandler(BACK, SWIPE_DISTANCE) { gestureDone = true }
+
+ companion object {
+ const val SWIPE_DISTANCE = 100
+ }
+
+ @Test
+ fun handlesEventsFromTouchpad() {
+ val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_FINGER)
+ val eventHandled = handler.onMotionEvent(event)
+ assertThat(eventHandled).isTrue()
+ }
+
+ @Test
+ fun ignoresEventsFromMouse() {
+ val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_MOUSE)
+ val eventHandled = handler.onMotionEvent(event)
+ assertThat(eventHandled).isFalse()
+ }
+
+ @Test
+ fun ignoresEventsFromTouch() {
+ val event = downEvent(source = SOURCE_TOUCHSCREEN, toolType = TOOL_TYPE_FINGER)
+ val eventHandled = handler.onMotionEvent(event)
+ assertThat(eventHandled).isFalse()
+ }
+
+ @Test
+ fun ignoresButtonClicksFromTouchpad() {
+ val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_FINGER)
+ event.buttonState = MotionEvent.BUTTON_PRIMARY
+ val eventHandled = handler.onMotionEvent(event)
+ assertThat(eventHandled).isFalse()
+ }
+
+ private fun downEvent(source: Int, toolType: Int) =
+ motionEvent(action = ACTION_DOWN, x = 0f, y = 0f, source = source, toolType = toolType)
+
+ @Test
+ fun triggersGestureDoneForThreeFingerGesture() {
+ backGestureEvents().forEach { handler.onMotionEvent(it) }
+
+ assertThat(gestureDone).isTrue()
+ }
+
+ private fun backGestureEvents(): List<MotionEvent> {
+ // list of motion events read from device while doing back gesture
+ val y = 100f
+ return listOf(
+ touchpadEvent(ACTION_HOVER_ENTER, x = 759f, y = y, pointerCount = 1),
+ threeFingerTouchpadEvent(ACTION_DOWN, x = 759f, y = y, pointerCount = 1),
+ threeFingerTouchpadEvent(ACTION_POINTER_DOWN, x = 759f, y = y, pointerCount = 2),
+ threeFingerTouchpadEvent(ACTION_POINTER_DOWN, x = 759f, y = y, pointerCount = 3),
+ threeFingerTouchpadEvent(ACTION_MOVE, x = 767f, y = y, pointerCount = 3),
+ threeFingerTouchpadEvent(ACTION_MOVE, x = 785f, y = y, pointerCount = 3),
+ threeFingerTouchpadEvent(ACTION_MOVE, x = 814f, y = y, pointerCount = 3),
+ threeFingerTouchpadEvent(ACTION_MOVE, x = 848f, y = y, pointerCount = 3),
+ threeFingerTouchpadEvent(ACTION_MOVE, x = 943f, y = y, pointerCount = 3),
+ threeFingerTouchpadEvent(ACTION_POINTER_UP, x = 943f, y = y, pointerCount = 3),
+ threeFingerTouchpadEvent(ACTION_POINTER_UP, x = 943f, y = y, pointerCount = 2),
+ threeFingerTouchpadEvent(ACTION_UP, x = 943f, y = y, pointerCount = 1)
+ )
+ }
+
+ private fun threeFingerTouchpadEvent(
+ action: Int,
+ x: Float,
+ y: Float,
+ pointerCount: Int
+ ): MotionEvent {
+ return touchpadEvent(
+ action = action,
+ x = x,
+ y = y,
+ pointerCount = pointerCount,
+ classification = CLASSIFICATION_MULTI_FINGER_SWIPE,
+ axisValues = mapOf(AXIS_GESTURE_SWIPE_FINGER_COUNT to 3f)
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialViewModelTest.kt
index 2300a1f6b21e..c705cea2beff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialViewModelTest.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.touchpad.tutorial.ui
+package com.android.systemui.touchpad.tutorial.ui.viewmodel
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java b/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java
deleted file mode 100644
index bb7b31b95f5e..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.tuner;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.testing.LeakCheck.Tracker;
-import android.util.DisplayMetrics;
-import android.view.View;
-import android.view.WindowManager;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.utils.leaks.LeakCheckedTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class TunablePaddingTest extends LeakCheckedTest {
-
- private static final String KEY = "KEY";
- private static final int DEFAULT = 42;
- private View mView;
- private TunablePadding mTunablePadding;
- private TunerService mTunerService;
-
- @Before
- public void setup() {
- injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
- mView = mock(View.class);
- when(mView.getContext()).thenReturn(mContext);
-
- mTunerService = mock(TunerService.class);
- mDependency.injectTestDependency(TunablePadding.TunablePaddingService.class,
- new TunablePadding.TunablePaddingService(mTunerService));
- Tracker tracker = mLeakCheck.getTracker("tuner");
- doAnswer(invocation -> {
- tracker.getLeakInfo(invocation.getArguments()[0]).addAllocation(new Throwable());
- return null;
- }).when(mTunerService).addTunable(any(), any());
- doAnswer(invocation -> {
- tracker.getLeakInfo(invocation.getArguments()[0]).clearAllocations();
- return null;
- }).when(mTunerService).removeTunable(any());
- }
-
- @Test
- public void testFlags() {
- mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
- TunablePadding.FLAG_START);
- mTunablePadding.onTuningChanged(null, null);
- verify(mView).setPadding(eq(DEFAULT), eq(0), eq(0), eq(0));
- mTunablePadding.destroy();
-
- mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
- TunablePadding.FLAG_TOP);
- mTunablePadding.onTuningChanged(null, null);
- verify(mView).setPadding(eq(0), eq(DEFAULT), eq(0), eq(0));
- mTunablePadding.destroy();
-
- mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
- TunablePadding.FLAG_END);
- mTunablePadding.onTuningChanged(null, null);
- verify(mView).setPadding(eq(0), eq(0), eq(DEFAULT), eq(0));
- mTunablePadding.destroy();
-
- mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
- TunablePadding.FLAG_BOTTOM);
- mTunablePadding.onTuningChanged(null, null);
- verify(mView).setPadding(eq(0), eq(0), eq(0), eq(DEFAULT));
- mTunablePadding.destroy();
- }
-
- @Test
- public void testRtl() {
- when(mView.isLayoutRtl()).thenReturn(true);
-
- mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
- TunablePadding.FLAG_END);
- mTunablePadding.onTuningChanged(null, null);
- verify(mView).setPadding(eq(DEFAULT), eq(0), eq(0), eq(0));
- mTunablePadding.destroy();
-
- mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
- TunablePadding.FLAG_START);
- mTunablePadding.onTuningChanged(null, null);
- verify(mView).setPadding(eq(0), eq(0), eq(DEFAULT), eq(0));
- mTunablePadding.destroy();
- }
-
- @Test
- public void testTuning() {
- int value = 3;
- mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
- TunablePadding.FLAG_START);
- mTunablePadding.onTuningChanged(KEY, String.valueOf(value));
-
- DisplayMetrics metrics = new DisplayMetrics();
- mContext.getSystemService(WindowManager.class).getDefaultDisplay().getMetrics(metrics);
- int output = (int) (metrics.density * value);
- verify(mView).setPadding(eq(output), eq(0), eq(0), eq(0));
-
- mTunablePadding.destroy();
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/icons/AppCategoryIconProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/icons/AppCategoryIconProviderTest.kt
new file mode 100644
index 000000000000..ef41b6ee69cc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/icons/AppCategoryIconProviderTest.kt
@@ -0,0 +1,154 @@
+/*
+ * 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.util.icons
+
+import android.app.role.RoleManager.ROLE_ASSISTANT
+import android.content.ComponentName
+import android.content.Intent
+import android.content.Intent.CATEGORY_APP_BROWSER
+import android.content.Intent.CATEGORY_APP_CONTACTS
+import android.content.Intent.CATEGORY_APP_EMAIL
+import android.content.mockPackageManager
+import android.content.mockPackageManagerWrapper
+import android.content.pm.ActivityInfo
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageInfo
+import android.content.pm.ResolveInfo
+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.assist.mockAssistManager
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AppCategoryIconProviderTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val packageManagerWrapper = kosmos.mockPackageManagerWrapper
+ private val packageManager = kosmos.mockPackageManager
+ private val assistManager = kosmos.mockAssistManager
+ private val provider = kosmos.appCategoryIconProvider
+
+ @Before
+ fun setUp() {
+ whenever(packageManagerWrapper.resolveActivity(any<Intent>(), any<Int>())).thenAnswer {
+ invocation ->
+ val category = (invocation.arguments[0] as Intent).categories.first()
+ val categoryAppIcon =
+ categoryAppIcons.firstOrNull { it.category == category } ?: return@thenAnswer null
+ val activityInfo = ActivityInfo().also { it.packageName = categoryAppIcon.packageName }
+ return@thenAnswer ResolveInfo().also { it.activityInfo = activityInfo }
+ }
+ whenever(packageManager.getPackageInfo(any<String>(), any<Int>())).thenAnswer { invocation
+ ->
+ val packageName = invocation.arguments[0] as String
+ val categoryAppIcon =
+ categoryAppIcons.firstOrNull { it.packageName == packageName }
+ ?: return@thenAnswer null
+ val applicationInfo =
+ ApplicationInfo().also {
+ it.packageName = packageName
+ it.icon = categoryAppIcon.iconResId
+ }
+ return@thenAnswer PackageInfo().also {
+ it.packageName = packageName
+ it.applicationInfo = applicationInfo
+ }
+ }
+ }
+
+ @Test
+ fun assistantAppIcon_defaultAssistantSet_returnsIcon() =
+ testScope.runTest {
+ whenever(assistManager.assistInfo)
+ .thenReturn(ComponentName(ASSISTANT_PACKAGE, ASSISTANT_CLASS))
+
+ val icon = provider.assistantAppIcon() as Icon
+
+ assertThat(icon.resPackage).isEqualTo(ASSISTANT_PACKAGE)
+ assertThat(icon.resId).isEqualTo(ASSISTANT_ICON_RES_ID)
+ }
+
+ @Test
+ fun assistantAppIcon_defaultAssistantNotSet_returnsNull() =
+ testScope.runTest {
+ whenever(assistManager.assistInfo).thenReturn(null)
+
+ assertThat(provider.assistantAppIcon()).isNull()
+ }
+
+ @Test
+ fun categoryAppIcon_returnsIconOfKnownBrowserApp() {
+ testScope.runTest {
+ val icon = provider.categoryAppIcon(CATEGORY_APP_BROWSER) as Icon
+
+ assertThat(icon.resPackage).isEqualTo(BROWSER_PACKAGE)
+ assertThat(icon.resId).isEqualTo(BROWSER_ICON_RES_ID)
+ }
+ }
+
+ @Test
+ fun categoryAppIcon_returnsIconOfKnownContactsApp() {
+ testScope.runTest {
+ val icon = provider.categoryAppIcon(CATEGORY_APP_CONTACTS) as Icon
+
+ assertThat(icon.resPackage).isEqualTo(CONTACTS_PACKAGE)
+ assertThat(icon.resId).isEqualTo(CONTACTS_ICON_RES_ID)
+ }
+ }
+
+ @Test
+ fun categoryAppIcon_noDefaultAppForCategoryEmail_returnsNull() {
+ testScope.runTest {
+ val icon = provider.categoryAppIcon(CATEGORY_APP_EMAIL)
+
+ assertThat(icon).isNull()
+ }
+ }
+
+ private companion object {
+ private const val ASSISTANT_PACKAGE = "the.assistant.app"
+ private const val ASSISTANT_CLASS = "the.assistant.app.class"
+ private const val ASSISTANT_ICON_RES_ID = 123
+
+ private const val BROWSER_PACKAGE = "com.test.browser"
+ private const val BROWSER_ICON_RES_ID = 1
+
+ private const val CONTACTS_PACKAGE = "app.test.contacts"
+ private const val CONTACTS_ICON_RES_ID = 234
+
+ private val categoryAppIcons =
+ listOf(
+ App(ROLE_ASSISTANT, ASSISTANT_PACKAGE, ASSISTANT_ICON_RES_ID),
+ App(CATEGORY_APP_BROWSER, BROWSER_PACKAGE, BROWSER_ICON_RES_ID),
+ App(CATEGORY_APP_CONTACTS, CONTACTS_PACKAGE, CONTACTS_ICON_RES_ID),
+ )
+ }
+
+ private class App(val category: String, val packageName: String, val iconResId: Int)
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java
deleted file mode 100644
index ef10fdf63741..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java
+++ /dev/null
@@ -1,178 +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.util.service;
-
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-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.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class PersistentConnectionManagerTest extends SysuiTestCase {
- private static final int MAX_RETRIES = 5;
- private static final int RETRY_DELAY_MS = 1000;
- private static final int CONNECTION_MIN_DURATION_MS = 5000;
- private static final String DUMPSYS_NAME = "dumpsys_name";
-
- private FakeSystemClock mFakeClock = new FakeSystemClock();
- private FakeExecutor mFakeExecutor = new FakeExecutor(mFakeClock);
-
- @Mock
- private ObservableServiceConnection<Proxy> mConnection;
-
- @Mock
- private ObservableServiceConnection.Callback<Proxy> mConnectionCallback;
-
- @Mock
- private Observer mObserver;
-
- @Mock
- private DumpManager mDumpManager;
-
- private static class Proxy {
- }
-
- private PersistentConnectionManager<Proxy> mConnectionManager;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
-
- mConnectionManager = new PersistentConnectionManager<>(
- mFakeClock,
- mFakeExecutor,
- mDumpManager,
- DUMPSYS_NAME,
- mConnection,
- MAX_RETRIES,
- RETRY_DELAY_MS,
- CONNECTION_MIN_DURATION_MS,
- mObserver);
- }
-
- private ObservableServiceConnection.Callback<Proxy> captureCallbackAndSend(
- ObservableServiceConnection<Proxy> mConnection, Proxy proxy) {
- ArgumentCaptor<ObservableServiceConnection.Callback<Proxy>> connectionCallbackCaptor =
- ArgumentCaptor.forClass(ObservableServiceConnection.Callback.class);
-
- verify(mConnection).addCallback(connectionCallbackCaptor.capture());
- verify(mConnection).bind();
- Mockito.clearInvocations(mConnection);
-
- final ObservableServiceConnection.Callback callback = connectionCallbackCaptor.getValue();
- if (proxy != null) {
- callback.onConnected(mConnection, proxy);
- } else {
- callback.onDisconnected(mConnection, 0);
- }
-
- return callback;
- }
-
- /**
- * Validates initial connection.
- */
- @Test
- public void testConnect() {
- mConnectionManager.start();
- captureCallbackAndSend(mConnection, Mockito.mock(Proxy.class));
- }
-
- /**
- * Ensures reconnection on disconnect.
- */
- @Test
- public void testRetryOnBindFailure() {
- mConnectionManager.start();
- ArgumentCaptor<ObservableServiceConnection.Callback<Proxy>> connectionCallbackCaptor =
- ArgumentCaptor.forClass(ObservableServiceConnection.Callback.class);
-
- verify(mConnection).addCallback(connectionCallbackCaptor.capture());
-
- // Verify attempts happen. Note that we account for the retries plus initial attempt, which
- // is not scheduled.
- for (int attemptCount = 0; attemptCount < MAX_RETRIES + 1; attemptCount++) {
- verify(mConnection).bind();
- Mockito.clearInvocations(mConnection);
- connectionCallbackCaptor.getValue().onDisconnected(mConnection, 0);
- mFakeExecutor.advanceClockToNext();
- mFakeExecutor.runAllReady();
- }
- }
-
- /**
- * Ensures manual unbind does not reconnect.
- */
- @Test
- public void testStopDoesNotReconnect() {
- mConnectionManager.start();
- ArgumentCaptor<ObservableServiceConnection.Callback<Proxy>> connectionCallbackCaptor =
- ArgumentCaptor.forClass(ObservableServiceConnection.Callback.class);
-
- verify(mConnection).addCallback(connectionCallbackCaptor.capture());
- verify(mConnection).bind();
- Mockito.clearInvocations(mConnection);
- mConnectionManager.stop();
- mFakeExecutor.advanceClockToNext();
- mFakeExecutor.runAllReady();
- verify(mConnection, never()).bind();
- }
-
- /**
- * Ensures rebind on package change.
- */
- @Test
- public void testAttemptOnPackageChange() {
- mConnectionManager.start();
- verify(mConnection).bind();
- ArgumentCaptor<Observer.Callback> callbackCaptor =
- ArgumentCaptor.forClass(Observer.Callback.class);
- captureCallbackAndSend(mConnection, Mockito.mock(Proxy.class));
-
- verify(mObserver).addCallback(callbackCaptor.capture());
-
- callbackCaptor.getValue().onSourceChanged();
- verify(mConnection).bind();
- }
-
- @Test
- public void testAddConnectionCallback() {
- mConnectionManager.addConnectionCallback(mConnectionCallback);
- verify(mConnection).addCallback(mConnectionCallback);
- }
-
- @Test
- public void testRemoveConnectionCallback() {
- mConnectionManager.removeConnectionCallback(mConnectionCallback);
- verify(mConnection).removeCallback(mConnectionCallback);
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
index ef8d51a23dc2..5ac61102fa99 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
@@ -27,6 +27,12 @@ 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 kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertThrows
import org.junit.Before
import org.junit.Test
@@ -39,60 +45,201 @@ import org.mockito.kotlin.eq
@RunWith(AndroidJUnit4::class)
@SmallTest
@TestableLooper.RunWithLooper
+@OptIn(ExperimentalCoroutinesApi::class)
class SettingsProxyTest : SysuiTestCase() {
+ private val testDispatcher = StandardTestDispatcher()
+
private lateinit var mSettings: SettingsProxy
private lateinit var mContentObserver: ContentObserver
+ private lateinit var testScope: TestScope
@Before
fun setUp() {
- mSettings = FakeSettingsProxy()
+ testScope = TestScope(testDispatcher)
+ mSettings = FakeSettingsProxy(testDispatcher)
mContentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {}
}
@Test
- fun registerContentObserver_inputString_success() {
- mSettings.registerContentObserverSync(TEST_SETTING, mContentObserver)
- verify(mSettings.getContentResolver())
- .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
- }
+ fun registerContentObserver_inputString_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverSync(TEST_SETTING, mContentObserver)
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+ }
@Test
- fun registerContentObserver_inputString_notifyForDescendants_true() {
- mSettings.registerContentObserverSync(
- TEST_SETTING,
- notifyForDescendants = true,
- mContentObserver
- )
- verify(mSettings.getContentResolver())
- .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
- }
+ fun registerContentObserverSuspend_inputString_success() =
+ testScope.runTest {
+ mSettings.registerContentObserver(TEST_SETTING, mContentObserver)
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+ }
@Test
- fun registerContentObserver_inputUri_success() {
- mSettings.registerContentObserverSync(TEST_SETTING_URI, mContentObserver)
- verify(mSettings.getContentResolver())
- .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
- }
+ fun registerContentObserverAsync_inputString_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverAsync(TEST_SETTING, mContentObserver)
+ testScope.advanceUntilIdle()
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+ }
@Test
- fun registerContentObserver_inputUri_notifyForDescendants_true() {
- mSettings.registerContentObserverSync(
- TEST_SETTING_URI,
- notifyForDescendants = true,
- mContentObserver
- )
- verify(mSettings.getContentResolver())
- .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
- }
+ fun registerContentObserver_inputString_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverSync(
+ TEST_SETTING,
+ notifyForDescendants = true,
+ mContentObserver
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserverSuspend_inputString_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserver(
+ TEST_SETTING,
+ notifyForDescendants = true,
+ mContentObserver
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+ }
@Test
- fun unregisterContentObserver() {
- mSettings.unregisterContentObserverSync(mContentObserver)
- verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
+ fun registerContentObserverAsync_inputString_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverAsync(
+ TEST_SETTING,
+ notifyForDescendants = true,
+ mContentObserver
+ )
+ testScope.advanceUntilIdle()
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserver_inputUri_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverSync(TEST_SETTING_URI, mContentObserver)
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserverSuspend_inputUri_success() =
+ testScope.runTest {
+ mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserverAsync_inputUri_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+ testScope.advanceUntilIdle()
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserver_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverSync(
+ TEST_SETTING_URI,
+ notifyForDescendants = true,
+ mContentObserver
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserverSuspend_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserver(
+ TEST_SETTING_URI,
+ notifyForDescendants = true,
+ mContentObserver
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserverAsync_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverAsync(
+ TEST_SETTING_URI,
+ notifyForDescendants = true,
+ mContentObserver
+ )
+ testScope.advanceUntilIdle()
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserverAsync_registeredLambdaPassed_callsCallback() =
+ testScope.runTest {
+ verifyRegisteredCallbackForRegistration {
+ mSettings.registerContentObserverAsync(TEST_SETTING, mContentObserver, it)
+ }
+ verifyRegisteredCallbackForRegistration {
+ mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver, it)
+ }
+ verifyRegisteredCallbackForRegistration {
+ mSettings.registerContentObserverAsync(TEST_SETTING, false, mContentObserver, it)
+ }
+ verifyRegisteredCallbackForRegistration {
+ mSettings.registerContentObserverAsync(
+ TEST_SETTING_URI,
+ false,
+ mContentObserver,
+ it
+ )
+ }
+ }
+
+ private fun verifyRegisteredCallbackForRegistration(
+ call: (registeredRunnable: Runnable) -> Unit
+ ) {
+ var callbackCalled = false
+ val runnable = { callbackCalled = true }
+ call(runnable)
+ testScope.advanceUntilIdle()
+ assertThat(callbackCalled).isTrue()
}
@Test
+ fun unregisterContentObserverSync() =
+ testScope.runTest {
+ mSettings.unregisterContentObserverSync(mContentObserver)
+ verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
+ }
+
+ @Test
+ fun unregisterContentObserverSuspend_inputString_success() =
+ testScope.runTest {
+ mSettings.unregisterContentObserver(mContentObserver)
+ verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
+ }
+
+ @Test
+ fun unregisterContentObserverAsync_inputString_success() =
+ testScope.runTest {
+ mSettings.unregisterContentObserverAsync(mContentObserver)
+ testScope.advanceUntilIdle()
+ verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
+ }
+
+ @Test
fun getString_keyPresent_returnValidValue() {
mSettings.putString(TEST_SETTING, "test")
assertThat(mSettings.getString(TEST_SETTING)).isEqualTo("test")
@@ -199,13 +346,16 @@ class SettingsProxyTest : SysuiTestCase() {
assertThat(mSettings.getFloat(TEST_SETTING, 2.5F)).isEqualTo(2.5F)
}
- private class FakeSettingsProxy : SettingsProxy {
+ private class FakeSettingsProxy(val testDispatcher: CoroutineDispatcher) : SettingsProxy {
private val mContentResolver = mock(ContentResolver::class.java)
private val settingToValueMap: MutableMap<String, String> = mutableMapOf()
override fun getContentResolver() = mContentResolver
+ override val backgroundDispatcher: CoroutineDispatcher
+ get() = testDispatcher
+
override fun getUriFor(name: String) =
Uri.parse(StringBuilder().append("content://settings/").append(name).toString())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
index c08ca7d1bdc1..5f7420d5a16b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
@@ -30,6 +30,13 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.UserTracker
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertThrows
import org.junit.Before
import org.junit.Test
@@ -45,8 +52,10 @@ import org.mockito.kotlin.eq
class UserSettingsProxyTest : SysuiTestCase() {
private var mUserTracker = FakeUserTracker()
- private var mSettings: UserSettingsProxy = FakeUserSettingsProxy(mUserTracker)
+ private val testDispatcher = StandardTestDispatcher()
+ private var mSettings: UserSettingsProxy = FakeUserSettingsProxy(mUserTracker, testDispatcher)
private var mContentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {}
+ private lateinit var testScope: TestScope
@Before
fun setUp() {
@@ -54,93 +63,331 @@ class UserSettingsProxyTest : SysuiTestCase() {
listOf(UserInfo(MAIN_USER_ID, "main", UserInfo.FLAG_MAIN)),
selectedUserIndex = 0
)
+ testScope = TestScope(testDispatcher)
}
@Test
- fun registerContentObserverForUser_inputString_success() {
- mSettings.registerContentObserverForUserSync(
- TEST_SETTING,
- mContentObserver,
- mUserTracker.userId
- )
- verify(mSettings.getContentResolver())
- .registerContentObserver(
- eq(TEST_SETTING_URI),
- eq(false),
- eq(mContentObserver),
- eq(MAIN_USER_ID)
+ fun registerContentObserverForUser_inputString_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUserSync(
+ TEST_SETTING,
+ mContentObserver,
+ mUserTracker.userId
)
- }
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
@Test
- fun registerContentObserverForUser_inputString_notifyForDescendants_true() {
- mSettings.registerContentObserverForUserSync(
- TEST_SETTING,
- notifyForDescendants = true,
- mContentObserver,
- mUserTracker.userId
- )
- verify(mSettings.getContentResolver())
- .registerContentObserver(
- eq(TEST_SETTING_URI),
- eq(true),
- eq(mContentObserver),
- eq(MAIN_USER_ID)
+ fun registerContentObserverForUserSuspend_inputString_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUser(
+ TEST_SETTING,
+ mContentObserver,
+ mUserTracker.userId
)
- }
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
@Test
- fun registerContentObserverForUser_inputUri_success() {
- mSettings.registerContentObserverForUserSync(
- TEST_SETTING_URI,
- mContentObserver,
- mUserTracker.userId
- )
- verify(mSettings.getContentResolver())
- .registerContentObserver(
- eq(TEST_SETTING_URI),
- eq(false),
- eq(mContentObserver),
- eq(MAIN_USER_ID)
+ fun registerContentObserverForUserAsync_inputString_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUserAsync(
+ TEST_SETTING,
+ mContentObserver,
+ mUserTracker.userId
)
- }
+ testScope.advanceUntilIdle()
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
@Test
- fun registerContentObserverForUser_inputUri_notifyForDescendants_true() {
- mSettings.registerContentObserverForUserSync(
- TEST_SETTING_URI,
- notifyForDescendants = true,
- mContentObserver,
- mUserTracker.userId
- )
- verify(mSettings.getContentResolver())
- .registerContentObserver(
- eq(TEST_SETTING_URI),
- eq(true),
- eq(mContentObserver),
- eq(MAIN_USER_ID)
+ fun registerContentObserverForUser_inputString_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUserSync(
+ TEST_SETTING,
+ notifyForDescendants = true,
+ mContentObserver,
+ mUserTracker.userId
)
- }
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(true),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
@Test
- fun registerContentObserver_inputUri_success() {
- mSettings.registerContentObserverSync(TEST_SETTING_URI, mContentObserver)
- verify(mSettings.getContentResolver())
- .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver), eq(0))
- }
+ fun registerContentObserverForUserSuspend_inputString_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUser(
+ TEST_SETTING,
+ notifyForDescendants = true,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(
+ true,
+ ),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
@Test
- fun registerContentObserver_inputUri_notifyForDescendants_true() {
- mSettings.registerContentObserverSync(
- TEST_SETTING_URI,
- notifyForDescendants = true,
- mContentObserver
- )
- verify(mSettings.getContentResolver())
- .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver), eq(0))
+ fun registerContentObserverForUserAsync_inputString_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUserAsync(
+ TEST_SETTING,
+ notifyForDescendants = true,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ testScope.advanceUntilIdle()
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(true),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+
+ @Test
+ fun registerContentObserverForUser_inputUri_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUserSync(
+ TEST_SETTING_URI,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+
+ @Test
+ fun registerContentObserverForUserSuspend_inputUri_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUser(
+ TEST_SETTING_URI,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+
+ @Test
+ fun registerContentObserverForUserAsync_inputUri_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUserAsync(
+ TEST_SETTING_URI,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ testScope.advanceUntilIdle()
+
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun registerContentObserverForUserAsync_callbackAfterRegister() =
+ testScope.runTest {
+ var callbackCalled = false
+ val runnable = { callbackCalled = true }
+
+ mSettings.registerContentObserverForUserAsync(
+ TEST_SETTING_URI,
+ mContentObserver,
+ mUserTracker.userId,
+ runnable
+ )
+ testScope.advanceUntilIdle()
+ assertThat(callbackCalled).isTrue()
+ }
+
+ @Test
+ fun registerContentObserverForUser_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUserSync(
+ TEST_SETTING_URI,
+ notifyForDescendants = true,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(true),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+
+ @Test
+ fun registerContentObserverForUserSuspend_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUser(
+ TEST_SETTING_URI,
+ notifyForDescendants = true,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(
+ true,
+ ),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+
+ @Test
+ fun registerContentObserverForUserAsync_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUserAsync(
+ TEST_SETTING_URI,
+ notifyForDescendants = true,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ testScope.advanceUntilIdle()
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(true),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+
+ @Test
+ fun registerContentObserver_inputUri_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverSync(TEST_SETTING_URI, mContentObserver)
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(0)
+ )
+ }
+
+ @Test
+ fun registerContentObserverSuspend_inputUri_success() =
+ testScope.runTest {
+ mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(0)
+ )
+ }
+
+ @Test
+ fun registerContentObserverAsync_inputUri_success() {
+ mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(0)
+ )
+ }
}
@Test
+ fun registerContentObserver_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverSync(
+ TEST_SETTING_URI,
+ notifyForDescendants = true,
+ mContentObserver
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(true),
+ eq(mContentObserver),
+ eq(0)
+ )
+ }
+
+ @Test
+ fun registerContentObserverSuspend_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(0)
+ )
+ }
+
+ @Test
+ fun registerContentObserverAsync_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(0)
+ )
+ }
+ }
+
+ @Test
fun getString_keyPresent_returnValidValue() {
mSettings.putString(TEST_SETTING, "test")
assertThat(mSettings.getString(TEST_SETTING)).isEqualTo("test")
@@ -300,7 +547,10 @@ class UserSettingsProxyTest : SysuiTestCase() {
*
* This class uses a mock of [ContentResolver] to test the [ContentObserver] registration APIs.
*/
- private class FakeUserSettingsProxy(override val userTracker: UserTracker) : UserSettingsProxy {
+ private class FakeUserSettingsProxy(
+ override val userTracker: UserTracker,
+ val testDispatcher: CoroutineDispatcher
+ ) : UserSettingsProxy {
private val mContentResolver = mock(ContentResolver::class.java)
private val userIdToSettingsValueMap: MutableMap<Int, MutableMap<String, String>> =
@@ -311,6 +561,9 @@ class UserSettingsProxyTest : SysuiTestCase() {
override fun getUriFor(name: String) =
Uri.parse(StringBuilder().append(URI_PREFIX).append(name).toString())
+ override val backgroundDispatcher: CoroutineDispatcher
+ get() = testDispatcher
+
override fun getStringForUser(name: String, userHandle: Int) =
userIdToSettingsValueMap[userHandle]?.get(name) ?: ""
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/CsdWarningDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/CsdWarningDialogTest.java
index c81623e627ae..49aedccde258 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/CsdWarningDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/CsdWarningDialogTest.java
@@ -19,28 +19,46 @@ package com.android.systemui.volume;
import static android.media.AudioManager.CSD_WARNING_DOSE_REACHED_1X;
import static android.media.AudioManager.CSD_WARNING_DOSE_REPEATED_5X;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.app.Notification;
import android.app.NotificationManager;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.media.AudioManager;
+import android.platform.test.annotations.EnableFlags;
import android.testing.TestableLooper;
+import android.util.Pair;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.plugins.VolumeDialog;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
+import com.google.common.collect.ImmutableList;
+
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.List;
+import java.util.Optional;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
@@ -48,41 +66,109 @@ public class CsdWarningDialogTest extends SysuiTestCase {
private NotificationManager mNotificationManager;
private AudioManager mAudioManager;
+ private BroadcastDispatcher mFakeBroadcastDispatcher;
+ private CsdWarningDialog mDialog;
+ private static final String DISMISS_CSD_NOTIFICATION =
+ "com.android.systemui.volume.DISMISS_CSD_NOTIFICATION";
@Before
public void setup() {
mNotificationManager = mock(NotificationManager.class);
- getContext().addMockSystemService(NotificationManager.class, mNotificationManager);
+ mContext.addMockSystemService(NotificationManager.class, mNotificationManager);
mAudioManager = mock(AudioManager.class);
- getContext().addMockSystemService(AudioManager.class, mAudioManager);
+ mContext.addMockSystemService(AudioManager.class, mAudioManager);
+ mFakeBroadcastDispatcher = getFakeBroadcastDispatcher();
}
@Test
public void create1XCsdDialogAndWait_sendsNotification() {
FakeExecutor executor = new FakeExecutor(new FakeSystemClock());
// instantiate directly instead of via factory; we don't want executor to be @Background
- CsdWarningDialog dialog = new CsdWarningDialog(CSD_WARNING_DOSE_REACHED_1X, mContext,
- mAudioManager, mNotificationManager, executor, null);
+ mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REACHED_1X, mContext,
+ mAudioManager, mNotificationManager, executor, null,
+ Optional.of(ImmutableList.of(new Pair("", new Intent()))),
+ mFakeBroadcastDispatcher);
- dialog.show();
+ mDialog.show();
executor.advanceClockToLast();
executor.runAllReady();
- dialog.dismiss();
+ mDialog.dismiss();
verify(mNotificationManager).notify(
eq(SystemMessageProto.SystemMessage.NOTE_CSD_LOWER_AUDIO), any(Notification.class));
}
@Test
- public void create5XCsdDiSalogAndWait_willSendNotification() {
+ public void create5XCsdDialogAndWait_willSendNotification() {
FakeExecutor executor = new FakeExecutor(new FakeSystemClock());
- CsdWarningDialog dialog = new CsdWarningDialog(CSD_WARNING_DOSE_REPEATED_5X, mContext,
- mAudioManager, mNotificationManager, executor, null);
+ mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REPEATED_5X, mContext,
+ mAudioManager, mNotificationManager, executor, null,
+ Optional.of(ImmutableList.of(new Pair("", new Intent()))),
+ mFakeBroadcastDispatcher);
- dialog.show();
+ mDialog.show();
verify(mNotificationManager).notify(
eq(SystemMessageProto.SystemMessage.NOTE_CSD_LOWER_AUDIO), any(Notification.class));
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_SOUNDDOSE_CUSTOMIZATION)
+ public void create1XCsdDialogWithActionsAndUndoIntent_willRegisterReceiverAndUndoVolume() {
+ FakeExecutor executor = new FakeExecutor(new FakeSystemClock());
+ Intent undoIntent = new Intent(VolumeDialog.ACTION_VOLUME_UNDO)
+ .setPackage(mContext.getPackageName());
+ mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REPEATED_5X, mContext,
+ mAudioManager, mNotificationManager, executor, null,
+ Optional.of(ImmutableList.of(new Pair("Undo", undoIntent))),
+ mFakeBroadcastDispatcher);
+
+ when(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)).thenReturn(25);
+ mDialog.show();
+ executor.advanceClockToLast();
+ executor.runAllReady();
+ mDialog.dismiss();
+ mDialog.mReceiverUndo.onReceive(mContext, undoIntent);
+
+ verify(mNotificationManager).notify(
+ eq(SystemMessageProto.SystemMessage.NOTE_CSD_LOWER_AUDIO),
+ any(Notification.class));
+ verify(mAudioManager).setStreamVolume(
+ eq(AudioManager.STREAM_MUSIC),
+ eq(25),
+ eq(AudioManager.FLAG_SHOW_UI));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SOUNDDOSE_CUSTOMIZATION)
+ public void deleteNotificationIntent_willUnregisterAllReceivers() {
+ FakeExecutor executor = new FakeExecutor(new FakeSystemClock());
+ Intent undoIntent = new Intent(VolumeDialog.ACTION_VOLUME_UNDO)
+ .setPackage(mContext.getPackageName());
+ mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REPEATED_5X, mContext,
+ mAudioManager, mNotificationManager, executor, null,
+ Optional.of(ImmutableList.of(new Pair("Undo", undoIntent))),
+ mFakeBroadcastDispatcher);
+ Intent dismissIntent = new Intent(DISMISS_CSD_NOTIFICATION)
+ .setPackage(mContext.getPackageName());
+
+ mDialog.mReceiverDismissNotification.onReceive(mContext, dismissIntent);
+ mDialog.show();
+ executor.advanceClockToLast();
+ executor.runAllReady();
+ mDialog.dismiss();
+
+ List<ResolveInfo> resolveInfoListDismiss = mContext.getPackageManager()
+ .queryBroadcastReceivers(dismissIntent, PackageManager.GET_RESOLVED_FILTER);
+ assertThat(resolveInfoListDismiss).hasSize(0);
+ List<ResolveInfo> resolveInfoListUndo = mContext.getPackageManager()
+ .queryBroadcastReceivers(undoIntent, PackageManager.GET_RESOLVED_FILTER);
+ assertThat(resolveInfoListUndo).hasSize(0);
+ }
+
+ @After
+ public void tearDown() {
+ mDialog.destroy();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeControllerCollectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeControllerCollectorTest.kt
new file mode 100644
index 000000000000..dd78e4a1fdaa
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeControllerCollectorTest.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.volume
+
+import android.media.IVolumeController
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.settingslib.media.data.repository.VolumeControllerEvent
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class VolumeControllerCollectorTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+ private val eventsFlow = MutableStateFlow<VolumeControllerEvent?>(null)
+ private val underTest = VolumeControllerCollector(kosmos.applicationCoroutineScope)
+
+ private val volumeController = mock<IVolumeController> {}
+
+ @Test
+ fun volumeControllerEvent_volumeChanged_callsMethod() =
+ testEvent(VolumeControllerEvent.VolumeChanged(3, 0)) {
+ verify(volumeController) { 1 * { volumeController.volumeChanged(eq(3), eq(0)) } }
+ }
+
+ @Test
+ fun volumeControllerEvent_dismiss_callsMethod() =
+ testEvent(VolumeControllerEvent.Dismiss) {
+ verify(volumeController) { 1 * { volumeController.dismiss() } }
+ }
+
+ @Test
+ fun volumeControllerEvent_displayCsdWarning_callsMethod() =
+ testEvent(VolumeControllerEvent.DisplayCsdWarning(0, 1)) {
+ verify(volumeController) { 1 * { volumeController.displayCsdWarning(eq(0), eq(1)) } }
+ }
+
+ @Test
+ fun volumeControllerEvent_displaySafeVolumeWarning_callsMethod() =
+ testEvent(VolumeControllerEvent.DisplaySafeVolumeWarning(1)) {
+ verify(volumeController) { 1 * { volumeController.displaySafeVolumeWarning(eq(1)) } }
+ }
+
+ @Test
+ fun volumeControllerEvent_masterMuteChanged_callsMethod() =
+ testEvent(VolumeControllerEvent.MasterMuteChanged(1)) {
+ verify(volumeController) { 1 * { volumeController.masterMuteChanged(1) } }
+ }
+
+ @Test
+ fun volumeControllerEvent_setA11yMode_callsMethod() =
+ testEvent(VolumeControllerEvent.SetA11yMode(1)) {
+ verify(volumeController) { 1 * { volumeController.setA11yMode(1) } }
+ }
+
+ @Test
+ fun volumeControllerEvent_SetLayoutDirection_callsMethod() =
+ testEvent(VolumeControllerEvent.SetLayoutDirection(1)) {
+ verify(volumeController) { 1 * { volumeController.setLayoutDirection(eq(1)) } }
+ }
+
+ private fun testEvent(event: VolumeControllerEvent, verify: () -> Unit) =
+ kosmos.testScope.runTest {
+ underTest.collectToController(eventsFlow.filterNotNull(), volumeController)
+
+ eventsFlow.value = event
+ runCurrent()
+
+ verify()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 6efb7d8fc3bb..cdfcca6c7065 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -43,6 +43,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.KeyguardManager;
+import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -55,6 +56,7 @@ import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
import android.testing.TestableLooper;
import android.util.Log;
+import android.util.Pair;
import android.view.Gravity;
import android.view.InputDevice;
import android.view.MotionEvent;
@@ -92,6 +94,8 @@ import com.android.systemui.volume.domain.interactor.VolumePanelNavigationIntera
import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag;
import com.android.systemui.volume.ui.navigation.VolumeNavigator;
+import com.google.common.collect.ImmutableList;
+
import dagger.Lazy;
import junit.framework.Assert;
@@ -107,6 +111,7 @@ import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.Arrays;
+import java.util.Optional;
import java.util.function.Predicate;
@SmallTest
@@ -157,11 +162,12 @@ public class VolumeDialogImplTest extends SysuiTestCase {
private final CsdWarningDialog.Factory mCsdWarningDialogFactory =
new CsdWarningDialog.Factory() {
- @Override
- public CsdWarningDialog create(int warningType, Runnable onCleanup) {
- return mCsdWarningDialog;
- }
- };
+ @Override
+ public CsdWarningDialog create(int warningType, Runnable onCleanup,
+ Optional<ImmutableList<Pair<String, Intent>>> actionIntents) {
+ return mCsdWarningDialog;
+ }
+ };
@Mock
private VibratorHelper mVibratorHelper;
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 dc7a2c320855..6c4608d37c6e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -192,6 +192,7 @@ import com.android.wm.shell.transition.Transitions;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -1852,6 +1853,7 @@ public class BubblesTest extends SysuiTestCase {
any(Bubble.class), anyBoolean(), anyBoolean());
}
+ @Ignore("reason = b/351977103")
@Test
public void testShowStackEdu_isNotConversationBubble() {
// Setup
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/data/repository/SmartspaceRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/android/app/admin/AlarmManagerKosmos.kt
index 0e4c923a3078..a7b5873a4798 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/data/repository/SmartspaceRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/android/app/admin/AlarmManagerKosmos.kt
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-package com.android.systemui.smartspace.data.repository
+package android.app.admin
+import android.app.AlarmManager
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.util.mockito.mock
-val Kosmos.fakeSmartspaceRepository by Fixture { FakeSmartspaceRepository() }
-
-val Kosmos.smartspaceRepository by Fixture<SmartspaceRepository> { fakeSmartspaceRepository }
+var Kosmos.alarmManager by Kosmos.Fixture { mock<AlarmManager>() }
diff --git a/packages/SystemUI/tests/utils/src/android/content/PackageManagerKosmos.kt b/packages/SystemUI/tests/utils/src/android/content/PackageManagerKosmos.kt
index 8901314d8e76..9d7d916a222e 100644
--- a/packages/SystemUI/tests/utils/src/android/content/PackageManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/android/content/PackageManagerKosmos.kt
@@ -17,6 +17,13 @@ package android.content
import android.content.pm.PackageManager
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.shared.system.PackageManagerWrapper
import com.android.systemui.util.mockito.mock
-val Kosmos.packageManager by Kosmos.Fixture { mock<PackageManager>() }
+val Kosmos.mockPackageManager by Kosmos.Fixture { mock<PackageManager>() }
+
+var Kosmos.packageManager by Kosmos.Fixture { mockPackageManager }
+
+val Kosmos.mockPackageManagerWrapper by Kosmos.Fixture { mock<PackageManagerWrapper>() }
+
+var Kosmos.packageManagerWrapper by Kosmos.Fixture { mockPackageManagerWrapper }
diff --git a/packages/SystemUI/tests/utils/src/android/hardware/display/DisplayManagerKosmos.kt b/packages/SystemUI/tests/utils/src/android/hardware/display/DisplayManagerKosmos.kt
new file mode 100644
index 000000000000..796ec9400249
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/android/hardware/display/DisplayManagerKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * 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.hardware.display
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.displayManager by Kosmos.Fixture { mock<DisplayManager>() }
diff --git a/packages/SystemUI/tests/utils/src/android/hardware/input/FakeInputManager.kt b/packages/SystemUI/tests/utils/src/android/hardware/input/FakeInputManager.kt
index 36ac4a469566..c4f93d107dbb 100644
--- a/packages/SystemUI/tests/utils/src/android/hardware/input/FakeInputManager.kt
+++ b/packages/SystemUI/tests/utils/src/android/hardware/input/FakeInputManager.kt
@@ -18,6 +18,7 @@ package android.hardware.input
import android.view.InputDevice
import android.view.KeyCharacterMap
+import android.view.KeyCharacterMap.VIRTUAL_KEYBOARD
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import org.mockito.ArgumentMatchers.anyInt
@@ -25,7 +26,18 @@ import org.mockito.invocation.InvocationOnMock
class FakeInputManager {
- private val devices = mutableMapOf<Int, InputDevice>()
+ private val keyCharacterMap = KeyCharacterMap.load(VIRTUAL_KEYBOARD)
+
+ private val virtualKeyboard =
+ InputDevice.Builder()
+ .setId(VIRTUAL_KEYBOARD)
+ .setKeyboardType(InputDevice.KEYBOARD_TYPE_ALPHABETIC)
+ .setSources(InputDevice.SOURCE_KEYBOARD)
+ .setEnabled(true)
+ .setKeyCharacterMap(keyCharacterMap)
+ .build()
+
+ private val devices = mutableMapOf<Int, InputDevice>(VIRTUAL_KEYBOARD to virtualKeyboard)
val inputManager =
mock<InputManager> {
@@ -56,10 +68,6 @@ class FakeInputManager {
addKeyboard(id, enabled)
}
- fun addVirtualKeyboard(enabled: Boolean = true) {
- addKeyboard(id = KeyCharacterMap.VIRTUAL_KEYBOARD, enabled)
- }
-
private fun addKeyboard(id: Int, enabled: Boolean = true) {
devices[id] =
InputDevice.Builder()
@@ -67,6 +75,7 @@ class FakeInputManager {
.setKeyboardType(InputDevice.KEYBOARD_TYPE_ALPHABETIC)
.setSources(InputDevice.SOURCE_KEYBOARD)
.setEnabled(enabled)
+ .setKeyCharacterMap(keyCharacterMap)
.build()
}
diff --git a/packages/SystemUI/tests/utils/src/android/view/WindowManagerKosmos.kt b/packages/SystemUI/tests/utils/src/android/view/WindowManagerKosmos.kt
index 2a0559869c86..d5451ee8eb10 100644
--- a/packages/SystemUI/tests/utils/src/android/view/WindowManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/android/view/WindowManagerKosmos.kt
@@ -19,4 +19,6 @@ package android.view
import com.android.systemui.kosmos.Kosmos
import org.mockito.Mockito.mock
-val Kosmos.windowManager by Kosmos.Fixture<WindowManager> { mock(WindowManager::class.java) }
+val Kosmos.mockWindowManager: WindowManager by Kosmos.Fixture { mock(WindowManager::class.java) }
+
+var Kosmos.windowManager: WindowManager by Kosmos.Fixture { mockWindowManager }
diff --git a/packages/SystemUI/tests/utils/src/com/android/app/admin/DevicePolicyManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/app/admin/DevicePolicyManagerKosmos.kt
new file mode 100644
index 000000000000..f51e122be214
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/app/admin/DevicePolicyManagerKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * 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.app.admin
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.devicePolicyManager by Kosmos.Fixture { mock<android.app.admin.DevicePolicyManager>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/internal/widget/LockPatternUtilsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/internal/widget/LockPatternUtilsKosmos.kt
index d9ea5e92710c..b511270cdf09 100644
--- a/packages/SystemUI/tests/utils/src/com/android/internal/widget/LockPatternUtilsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/internal/widget/LockPatternUtilsKosmos.kt
@@ -16,7 +16,14 @@
package com.android.internal.widget
+import android.app.admin.devicePolicyManager
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
-var Kosmos.lockPatternUtils by Kosmos.Fixture { mock<LockPatternUtils>() }
+var Kosmos.lockPatternUtils by
+ Kosmos.Fixture {
+ mock<LockPatternUtils>().apply {
+ whenever(this.devicePolicyManager).thenReturn(this@Fixture.devicePolicyManager)
+ }
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
index 9dae44dc8053..0b6b816e589f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
@@ -16,8 +16,10 @@
package com.android.systemui
import android.app.ActivityManager
+import android.app.DreamManager
import android.app.admin.DevicePolicyManager
import android.app.trust.TrustManager
+import android.hardware.fingerprint.FingerprintManager
import android.os.UserManager
import android.service.notification.NotificationListenerService
import android.util.DisplayMetrics
@@ -32,6 +34,8 @@ import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.biometrics.AuthController
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
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.demomode.DemoModeController
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.ScreenLifecycle
@@ -93,7 +97,9 @@ data class TestMocksModule(
@get:Provides val demoModeController: DemoModeController = mock(),
@get:Provides val deviceProvisionedController: DeviceProvisionedController = mock(),
@get:Provides val dozeParameters: DozeParameters = mock(),
+ @get:Provides val dreamManager: DreamManager = mock(),
@get:Provides val dumpManager: DumpManager = mock(),
+ @get:Provides val fingerprintManager: FingerprintManager = mock(),
@get:Provides val headsUpManager: HeadsUpManager = mock(),
@get:Provides val guestResumeSessionReceiver: GuestResumeSessionReceiver = mock(),
@get:Provides val keyguardBypassController: KeyguardBypassController = mock(),
@@ -130,6 +136,8 @@ data class TestMocksModule(
@get:Provides val systemUIDialogManager: SystemUIDialogManager = mock(),
@get:Provides val deviceEntryIconTransitions: Set<DeviceEntryIconTransition> = emptySet(),
@get:Provides val communalInteractor: CommunalInteractor = mock(),
+ @get:Provides val communalSceneInteractor: CommunalSceneInteractor = mock(),
+ @get:Provides val communalSettingsInteractor: CommunalSettingsInteractor = mock(),
@get:Provides val sceneLogger: SceneLogger = mock(),
@get:Provides val trustManager: TrustManager = mock(),
@get:Provides val primaryBouncerInteractor: PrimaryBouncerInteractor = mock(),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/accessibility/FakeReduceBrightColorsController.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/accessibility/FakeReduceBrightColorsController.kt
index 8b0affe2d99d..e02042d26d45 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/accessibility/FakeReduceBrightColorsController.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/accessibility/FakeReduceBrightColorsController.kt
@@ -16,6 +16,8 @@
package com.android.systemui.accessibility
+import android.content.res.Resources
+import com.android.server.display.feature.flags.Flags
import com.android.systemui.qs.ReduceBrightColorsController
class FakeReduceBrightColorsController : ReduceBrightColorsController {
@@ -44,4 +46,20 @@ class FakeReduceBrightColorsController : ReduceBrightColorsController {
}
}
}
+
+ override fun setReduceBrightColorsFeatureAvailable(enabled: Boolean) {
+ // do nothing
+ }
+
+ override fun isReduceBrightColorsFeatureAvailable(): Boolean {
+ return true
+ }
+
+ override fun isInUpgradeMode(resources: Resources?): Boolean {
+ if (resources != null) {
+ return Flags.evenDimmer() &&
+ resources.getBoolean(com.android.internal.R.bool.config_evenDimmerEnabled)
+ }
+ return false
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/assist/AssistManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/assist/AssistManagerKosmos.kt
index b7d6f3a5f91f..22eb646ff48a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/assist/AssistManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/assist/AssistManagerKosmos.kt
@@ -19,4 +19,6 @@ package com.android.systemui.assist
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.util.mockito.mock
-var Kosmos.assistManager by Kosmos.Fixture { mock<AssistManager>() }
+val Kosmos.mockAssistManager by Kosmos.Fixture { mock<AssistManager>() }
+
+var Kosmos.assistManager by Kosmos.Fixture { mockAssistManager }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorKosmos.kt
index cbfc7686a896..ae592b968f8b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorKosmos.kt
@@ -17,17 +17,20 @@
package com.android.systemui.biometrics.domain.interactor
import android.content.applicationContext
+import android.hardware.fingerprint.FingerprintManager
import com.android.systemui.biometrics.authController
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.user.domain.interactor.selectedUserInteractor
+import com.android.systemui.util.mockito.mock
val Kosmos.udfpsOverlayInteractor by Fixture {
UdfpsOverlayInteractor(
context = applicationContext,
authController = authController,
selectedUserInteractor = selectedUserInteractor,
+ fingerprintManager = mock<FingerprintManager>(),
scope = applicationCoroutineScope,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelKosmos.kt
index 4b6441628500..de5f0f3734c6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelKosmos.kt
@@ -24,7 +24,7 @@ import com.android.systemui.bouncer.shared.flag.composeBouncerFlags
import com.android.systemui.deviceentry.domain.interactor.biometricMessageInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryFingerprintAuthInteractor
-import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.user.ui.viewmodel.userSwitcherViewModel
@@ -44,7 +44,7 @@ val Kosmos.bouncerMessageViewModel by
clock = systemClock,
biometricMessageInteractor = biometricMessageInteractor,
faceAuthInteractor = deviceEntryFaceAuthInteractor,
- deviceEntryInteractor = deviceEntryInteractor,
+ deviceUnlockedInteractor = deviceUnlockedInteractor,
fingerprintInteractor = deviceEntryFingerprintAuthInteractor,
flags = composeBouncerFlags,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationKosmos.kt
new file mode 100644
index 000000000000..8d01fcd9fea3
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.communal.data.db
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.Mockito.mock
+
+val Kosmos.defaultWidgetPopulation by
+ Kosmos.Fixture<DefaultWidgetPopulation> { mock(DefaultWidgetPopulation::class.java) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryKosmos.kt
new file mode 100644
index 000000000000..559a6eeb814a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryKosmos.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.communal.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.fakeCommunalSmartspaceRepository by Kosmos.Fixture { FakeCommunalSmartspaceRepository() }
+
+val Kosmos.communalSmartspaceRepository by
+ Kosmos.Fixture<CommunalSmartspaceRepository> { fakeCommunalSmartspaceRepository }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalMediaRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalMediaRepository.kt
index 1884a3264ed6..14b1984f2374 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalMediaRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalMediaRepository.kt
@@ -36,4 +36,18 @@ class FakeCommunalMediaRepository : CommunalMediaRepository {
fun mediaInactive() {
_mediaModel.value = CommunalMediaModel.INACTIVE
}
+
+ private var isListening = false
+
+ override fun startListening() {
+ isListening = true
+ }
+
+ override fun stopListening() {
+ isListening = false
+ }
+
+ fun isListening(): Boolean {
+ return isListening
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSmartspaceRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSmartspaceRepository.kt
new file mode 100644
index 000000000000..904ab4bc3f85
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSmartspaceRepository.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.communal.data.repository
+
+import com.android.systemui.communal.data.model.CommunalSmartspaceTimer
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+
+class FakeCommunalSmartspaceRepository : CommunalSmartspaceRepository {
+
+ private val _timers = MutableStateFlow<List<CommunalSmartspaceTimer>>(emptyList())
+ override val timers: Flow<List<CommunalSmartspaceTimer>> = _timers
+
+ fun setTimers(timers: List<CommunalSmartspaceTimer>) {
+ _timers.value = timers
+ }
+
+ private var isListening = false
+
+ override fun startListening() {
+ isListening = true
+ }
+
+ override fun stopListening() {
+ isListening = false
+ }
+
+ fun isListening(): Boolean {
+ return isListening
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
index b58861b1104e..eb9278537db5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
@@ -19,6 +19,7 @@ package com.android.systemui.communal.domain.interactor
import android.os.userManager
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.communal.data.repository.communalMediaRepository
+import com.android.systemui.communal.data.repository.communalSmartspaceRepository
import com.android.systemui.communal.data.repository.communalWidgetRepository
import com.android.systemui.communal.widgets.EditWidgetsActivityStarter
import com.android.systemui.flags.Flags
@@ -34,7 +35,6 @@ import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.plugins.activityStarter
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.settings.userTracker
-import com.android.systemui.smartspace.data.repository.smartspaceRepository
import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.util.mockito.mock
@@ -47,7 +47,7 @@ val Kosmos.communalInteractor by Fixture {
widgetRepository = communalWidgetRepository,
communalPrefsInteractor = communalPrefsInteractor,
mediaRepository = communalMediaRepository,
- smartspaceRepository = smartspaceRepository,
+ smartspaceRepository = communalSmartspaceRepository,
keyguardInteractor = keyguardInteractor,
keyguardTransitionInteractor = keyguardTransitionInteractor,
communalSettingsInteractor = communalSettingsInteractor,
@@ -64,13 +64,17 @@ val Kosmos.communalInteractor by Fixture {
val Kosmos.editWidgetsActivityStarter by Fixture<EditWidgetsActivityStarter> { mock() }
-suspend fun Kosmos.setCommunalAvailable(available: Boolean) {
- fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, available)
- if (available) {
+suspend fun Kosmos.setCommunalEnabled(enabled: Boolean) {
+ fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, enabled)
+ if (enabled) {
fakeUserRepository.asMainUser()
} else {
fakeUserRepository.asDefaultUser()
}
+}
+
+suspend fun Kosmos.setCommunalAvailable(available: Boolean) {
+ setCommunalEnabled(available)
with(fakeKeyguardRepository) {
setIsEncryptedOrLockdown(!available)
setKeyguardShowing(available)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt
index a8fc27a7da4e..b9be04dc0a32 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt
@@ -57,5 +57,6 @@ val Kosmos.deviceEntryFaceAuthInteractor by
powerInteractor = powerInteractor,
biometricSettingsRepository = biometricSettingsRepository,
trustManager = trustManager,
+ deviceEntryFaceAuthStatusInteractor = deviceEntryFaceAuthStatusInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorKosmos.kt
new file mode 100644
index 000000000000..66d3709d14dc
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorKosmos.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.deviceentry.domain.interactor
+
+import android.content.res.mainResources
+import com.android.systemui.keyguard.data.repository.deviceEntryFaceAuthRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.deviceEntryFaceAuthStatusInteractor by
+ Kosmos.Fixture {
+ DeviceEntryFaceAuthStatusInteractor(
+ repository = deviceEntryFaceAuthRepository,
+ resources = mainResources,
+ applicationScope = applicationCoroutineScope,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt
index 120086686282..caa6e99d58cb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt
@@ -19,8 +19,6 @@ package com.android.systemui.deviceentry.domain.interactor
import com.android.systemui.authentication.domain.interactor.authenticationInteractor
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.deviceentry.data.repository.deviceEntryRepository
-import com.android.systemui.flags.fakeSystemPropertiesHelper
-import com.android.systemui.keyguard.domain.interactor.trustInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -34,12 +32,7 @@ val Kosmos.deviceEntryInteractor by
repository = deviceEntryRepository,
authenticationInteractor = authenticationInteractor,
sceneInteractor = sceneInteractor,
- faceAuthInteractor = deviceEntryFaceAuthInteractor,
- fingerprintAuthInteractor = deviceEntryFingerprintAuthInteractor,
- biometricSettingsInteractor = deviceEntryBiometricSettingsInteractor,
- trustInteractor = trustInteractor,
deviceUnlockedInteractor = deviceUnlockedInteractor,
- systemPropertiesHelper = fakeSystemPropertiesHelper,
alternateBouncerInteractor = alternateBouncerInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt
index 14210bc8d15c..1ed10fbe94c3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt
@@ -18,6 +18,8 @@ package com.android.systemui.deviceentry.domain.interactor
import com.android.systemui.authentication.domain.interactor.authenticationInteractor
import com.android.systemui.deviceentry.data.repository.deviceEntryRepository
+import com.android.systemui.flags.fakeSystemPropertiesHelper
+import com.android.systemui.flags.systemPropertiesHelper
import com.android.systemui.keyguard.domain.interactor.trustInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
@@ -33,5 +35,7 @@ val Kosmos.deviceUnlockedInteractor by Fixture {
faceAuthInteractor = deviceEntryFaceAuthInteractor,
fingerprintAuthInteractor = deviceEntryFingerprintAuthInteractor,
powerInteractor = powerInteractor,
+ biometricSettingsInteractor = deviceEntryBiometricSettingsInteractor,
+ systemPropertiesHelper = fakeSystemPropertiesHelper,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryKosmos.kt
new file mode 100644
index 000000000000..f73f43dc53fe
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright 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.education.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+import java.time.Instant
+
+var Kosmos.contextualEducationRepository: ContextualEducationRepository by
+ Kosmos.Fixture { FakeContextualEducationRepository(FakeEduClock(Instant.MIN)) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt
new file mode 100644
index 000000000000..5410882c9283
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 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.education.data.repository
+
+import com.android.systemui.education.data.model.GestureEduModel
+import com.android.systemui.shared.education.GestureType
+import java.time.Clock
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+class FakeContextualEducationRepository(private val clock: Clock) : ContextualEducationRepository {
+
+ private val userGestureMap = mutableMapOf<Int, GestureEduModel>()
+ private val _gestureEduModels = MutableStateFlow(GestureEduModel())
+ private val gestureEduModelsFlow = _gestureEduModels.asStateFlow()
+
+ override fun setUser(userId: Int) {
+ if (!userGestureMap.contains(userId)) {
+ userGestureMap[userId] = GestureEduModel()
+ }
+ _gestureEduModels.value = userGestureMap[userId]!!
+ }
+
+ override fun readGestureEduModelFlow(gestureType: GestureType): Flow<GestureEduModel> {
+ return gestureEduModelsFlow
+ }
+
+ override suspend fun incrementSignalCount(gestureType: GestureType) {
+ _gestureEduModels.value =
+ GestureEduModel(
+ signalCount = _gestureEduModels.value.signalCount + 1,
+ )
+ }
+
+ override suspend fun updateShortcutTriggerTime(gestureType: GestureType) {
+ _gestureEduModels.value = GestureEduModel(lastShortcutTriggeredTime = clock.instant())
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeEduClock.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeEduClock.kt
new file mode 100644
index 000000000000..513c14381997
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeEduClock.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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.education.data.repository
+
+import java.time.Clock
+import java.time.Instant
+import java.time.ZoneId
+
+class FakeEduClock(private val base: Instant) : Clock() {
+ private val zone: ZoneId = ZoneId.of("UTC")
+
+ override fun instant(): Instant {
+ return base
+ }
+
+ override fun withZone(zoneId: ZoneId?): Clock {
+ return FakeEduClock(base)
+ }
+
+ override fun getZone(): ZoneId {
+ return zone
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsClassicKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsClassicKosmos.kt
index 45ea36464194..d9235cc56c00 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsClassicKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsClassicKosmos.kt
@@ -37,6 +37,7 @@ val Kosmos.fakeFeatureFlagsClassic by
set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, false)
set(Flags.LOCKSCREEN_ENABLE_LANDSCAPE, false)
set(Flags.NSSL_DEBUG_LINES, false)
+ set(Flags.COMMUNAL_SERVICE_ENABLED, false)
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/qs/QSLongPressEffectKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/qs/QSLongPressEffectKosmos.kt
index eff99e047f45..28355e1c3efa 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/qs/QSLongPressEffectKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/qs/QSLongPressEffectKosmos.kt
@@ -16,9 +16,10 @@
package com.android.systemui.haptics.qs
+import com.android.systemui.classifier.falsingManager
import com.android.systemui.haptics.vibratorHelper
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.statusbar.policy.keyguardStateController
val Kosmos.qsLongPressEffect by
- Kosmos.Fixture { QSLongPressEffect(vibratorHelper, keyguardStateController) }
+ Kosmos.Fixture { QSLongPressEffect(vibratorHelper, keyguardStateController, falsingManager) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
index e00f9806f6a2..c423b626b3a7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
@@ -24,6 +24,10 @@ import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperCategoriesRepository
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperTestHelper
+import com.android.systemui.keyboard.shortcut.data.source.AppCategoriesShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.CurrentAppShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.InputShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource
import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperCategoriesInteractor
@@ -38,10 +42,18 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.model.sysUiState
import com.android.systemui.settings.displayTracker
-val Kosmos.shortcutHelperSystemShortcutsSource by
+var Kosmos.shortcutHelperAppCategoriesShortcutsSource: KeyboardShortcutGroupsSource by
+ Kosmos.Fixture {
+ AppCategoriesShortcutsSource(
+ windowManager,
+ testDispatcher,
+ )
+ }
+
+var Kosmos.shortcutHelperSystemShortcutsSource: KeyboardShortcutGroupsSource by
Kosmos.Fixture { SystemShortcutsSource(mainResources) }
-val Kosmos.shortcutHelperMultiTaskingShortcutsSource by
+var Kosmos.shortcutHelperMultiTaskingShortcutsSource: KeyboardShortcutGroupsSource by
Kosmos.Fixture { MultitaskingShortcutsSource(mainResources) }
val Kosmos.shortcutHelperStateRepository by
@@ -55,13 +67,25 @@ val Kosmos.shortcutHelperStateRepository by
)
}
+var Kosmos.shortcutHelperInputShortcutsSource: KeyboardShortcutGroupsSource by
+ Kosmos.Fixture { InputShortcutsSource(mainResources, windowManager) }
+
+var Kosmos.shortcutHelperCurrentAppShortcutsSource: KeyboardShortcutGroupsSource by
+ Kosmos.Fixture { CurrentAppShortcutsSource(windowManager) }
+
val Kosmos.shortcutHelperCategoriesRepository by
Kosmos.Fixture {
ShortcutHelperCategoriesRepository(
+ applicationContext,
+ applicationCoroutineScope,
+ testDispatcher,
shortcutHelperSystemShortcutsSource,
shortcutHelperMultiTaskingShortcutsSource,
- windowManager,
- shortcutHelperStateRepository
+ shortcutHelperAppCategoriesShortcutsSource,
+ shortcutHelperInputShortcutsSource,
+ shortcutHelperCurrentAppShortcutsSource,
+ fakeInputManager.inputManager,
+ shortcutHelperStateRepository,
)
}
@@ -72,7 +96,8 @@ val Kosmos.shortcutHelperTestHelper by
applicationContext,
broadcastDispatcher,
fakeCommandQueue,
- windowManager
+ fakeInputManager,
+ windowManager,
)
}
@@ -90,7 +115,14 @@ val Kosmos.shortcutHelperCategoriesInteractor by
Kosmos.Fixture { ShortcutHelperCategoriesInteractor(shortcutHelperCategoriesRepository) }
val Kosmos.shortcutHelperViewModel by
- Kosmos.Fixture { ShortcutHelperViewModel(testDispatcher, shortcutHelperStateInteractor) }
+ Kosmos.Fixture {
+ ShortcutHelperViewModel(
+ applicationCoroutineScope,
+ testDispatcher,
+ shortcutHelperStateInteractor,
+ shortcutHelperCategoriesInteractor
+ )
+ }
val Kosmos.fakeShortcutHelperStartActivity by Kosmos.Fixture { FakeShortcutHelperStartActivity() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt
index 40510db24f47..6ca5cd81b665 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt
@@ -18,6 +18,7 @@ package com.android.systemui.keyboard.shortcut.data.repository
import android.content.Context
import android.content.Intent
+import android.hardware.input.FakeInputManager
import android.view.KeyboardShortcutGroup
import android.view.WindowManager
import android.view.WindowManager.KeyboardShortcutsReceiver
@@ -31,6 +32,7 @@ class ShortcutHelperTestHelper(
private val context: Context,
private val fakeBroadcastDispatcher: FakeBroadcastDispatcher,
private val fakeCommandQueue: FakeCommandQueue,
+ private val fakeInputManager: FakeInputManager,
windowManager: WindowManager
) {
@@ -39,6 +41,7 @@ class ShortcutHelperTestHelper(
}
private var imeShortcuts: List<KeyboardShortcutGroup> = emptyList()
+ private var currentAppsShortcuts: List<KeyboardShortcutGroup> = emptyList()
init {
whenever(windowManager.requestImeKeyboardShortcuts(any(), any())).thenAnswer {
@@ -46,6 +49,11 @@ class ShortcutHelperTestHelper(
keyboardShortcutReceiver.onKeyboardShortcutsReceived(imeShortcuts)
return@thenAnswer Unit
}
+ whenever(windowManager.requestAppKeyboardShortcuts(any(), any())).thenAnswer {
+ val keyboardShortcutReceiver = it.getArgument<KeyboardShortcutsReceiver>(0)
+ keyboardShortcutReceiver.onKeyboardShortcutsReceived(currentAppsShortcuts)
+ return@thenAnswer Unit
+ }
repo.start()
}
@@ -57,6 +65,14 @@ class ShortcutHelperTestHelper(
this.imeShortcuts = imeShortcuts
}
+ /**
+ * Use this method to set what current app shortcuts should be returned from windowManager in
+ * tests. By default [WindowManager.requestAppKeyboardShortcuts] will return emptyList.
+ */
+ fun setCurrentAppsShortcuts(currentAppShortcuts: List<KeyboardShortcutGroup>) {
+ this.currentAppsShortcuts = currentAppShortcuts
+ }
+
fun hideThroughCloseSystemDialogs() {
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
context,
@@ -79,6 +95,7 @@ class ShortcutHelperTestHelper(
}
fun toggle(deviceId: Int) {
+ fakeInputManager.addPhysicalKeyboard(deviceId)
fakeCommandQueue.doForEachCallback { it.toggleKeyboardShortcutsMenu(deviceId) }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt
new file mode 100644
index 000000000000..2bab1a4b32cf
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.keyboard.shortcut.data.source
+
+import android.view.KeyboardShortcutGroup
+
+class FakeKeyboardShortcutGroupsSource : KeyboardShortcutGroupsSource {
+
+ private var groups = listOf<KeyboardShortcutGroup>()
+
+ override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> = groups
+
+ fun setGroups(groups: List<KeyboardShortcutGroup>) {
+ this.groups = groups
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index 5bae6ec89b65..87143efb7f3c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -135,6 +135,9 @@ class FakeKeyguardRepository @Inject constructor() : KeyguardRepository {
private var isShowKeyguardWhenReenabled: Boolean = false
+ private val _canIgnoreAuthAndReturnToGone = MutableStateFlow(false)
+ override val canIgnoreAuthAndReturnToGone = _canIgnoreAuthAndReturnToGone.asStateFlow()
+
override fun setQuickSettingsVisible(isVisible: Boolean) {
_isQuickSettingsVisible.value = isVisible
}
@@ -278,6 +281,10 @@ class FakeKeyguardRepository @Inject constructor() : KeyguardRepository {
override fun isShowKeyguardWhenReenabled(): Boolean {
return isShowKeyguardWhenReenabled
}
+
+ override fun setCanIgnoreAuthAndReturnToGone(canWake: Boolean) {
+ _canIgnoreAuthAndReturnToGone.value = canWake
+ }
}
@Module
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt
index 78a419f92495..ce317d43e988 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt
@@ -32,6 +32,7 @@ val Kosmos.fromAlternateBouncerTransitionInteractor by
FromAlternateBouncerTransitionInteractor(
transitionRepository = keyguardTransitionRepository,
transitionInteractor = keyguardTransitionInteractor,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
scope = applicationCoroutineScope,
bgDispatcher = testDispatcher,
mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
index 42af25ed51a7..ef789d1b29ff 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
@@ -29,6 +29,7 @@ val Kosmos.fromAodTransitionInteractor by
FromAodTransitionInteractor(
transitionRepository = fakeKeyguardTransitionRepository,
transitionInteractor = keyguardTransitionInteractor,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
scope = applicationCoroutineScope,
bgDispatcher = testDispatcher,
mainDispatcher = testDispatcher,
@@ -36,5 +37,6 @@ val Kosmos.fromAodTransitionInteractor by
powerInteractor = powerInteractor,
keyguardOcclusionInteractor = keyguardOcclusionInteractor,
deviceEntryRepository = deviceEntryRepository,
+ wakeToGoneInteractor = keyguardWakeDirectlyToGoneInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
index edf77a007efd..126d85890531 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
@@ -16,7 +16,9 @@
package com.android.systemui.keyguard.domain.interactor
+import android.service.dream.dreamManager
import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.deviceentry.data.repository.deviceEntryRepository
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
@@ -30,13 +32,17 @@ var Kosmos.fromDozingTransitionInteractor by
FromDozingTransitionInteractor(
transitionRepository = keyguardTransitionRepository,
transitionInteractor = keyguardTransitionInteractor,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
scope = applicationCoroutineScope,
bgDispatcher = testDispatcher,
mainDispatcher = testDispatcher,
keyguardInteractor = keyguardInteractor,
communalInteractor = communalInteractor,
+ communalSceneInteractor = communalSceneInteractor,
powerInteractor = powerInteractor,
keyguardOcclusionInteractor = keyguardOcclusionInteractor,
deviceEntryRepository = deviceEntryRepository,
+ wakeToGoneInteractor = keyguardWakeDirectlyToGoneInteractor,
+ dreamManager = dreamManager
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractorKosmos.kt
index f7a9d59eac26..7ebef10b12c6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractorKosmos.kt
@@ -28,6 +28,7 @@ var Kosmos.fromDreamingLockscreenHostedTransitionInteractor by
FromDreamingLockscreenHostedTransitionInteractor(
transitionRepository = keyguardTransitionRepository,
transitionInteractor = keyguardTransitionInteractor,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
scope = applicationCoroutineScope,
bgDispatcher = testDispatcher,
mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
index 135644cfac3e..f1625948880f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
@@ -16,24 +16,31 @@
package com.android.systemui.keyguard.domain.interactor
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+@OptIn(ExperimentalCoroutinesApi::class)
var Kosmos.fromDreamingTransitionInteractor by
Kosmos.Fixture {
FromDreamingTransitionInteractor(
transitionRepository = keyguardTransitionRepository,
transitionInteractor = keyguardTransitionInteractor,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
scope = applicationCoroutineScope,
bgDispatcher = testDispatcher,
mainDispatcher = testDispatcher,
keyguardInteractor = keyguardInteractor,
glanceableHubTransitions = glanceableHubTransitions,
+ communalSettingsInteractor = communalSettingsInteractor,
powerInteractor = powerInteractor,
keyguardOcclusionInteractor = keyguardOcclusionInteractor,
+ deviceEntryInteractor = deviceEntryInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractorKosmos.kt
index 1695327d75bc..079852a641c2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractorKosmos.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.domain.interactor
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -26,14 +27,16 @@ import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInterac
var Kosmos.fromGlanceableHubTransitionInteractor by
Kosmos.Fixture {
FromGlanceableHubTransitionInteractor(
- transitionRepository = keyguardTransitionRepository,
- transitionInteractor = keyguardTransitionInteractor,
scope = applicationCoroutineScope,
- bgDispatcher = testDispatcher,
mainDispatcher = testDispatcher,
+ bgDispatcher = testDispatcher,
+ glanceableHubTransitions = glanceableHubTransitions,
+ communalSettingsInteractor = communalSettingsInteractor,
keyguardInteractor = keyguardInteractor,
+ transitionRepository = keyguardTransitionRepository,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
+ transitionInteractor = keyguardTransitionInteractor,
powerInteractor = powerInteractor,
keyguardOcclusionInteractor = keyguardOcclusionInteractor,
- glanceableHubTransitions = glanceableHubTransitions,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt
index 4039ee6ea904..317294f3c884 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt
@@ -31,6 +31,7 @@ val Kosmos.fromGoneTransitionInteractor by
FromGoneTransitionInteractor(
transitionRepository = fakeKeyguardTransitionRepository,
transitionInteractor = keyguardTransitionInteractor,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
scope = applicationCoroutineScope,
bgDispatcher = testDispatcher,
mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorKosmos.kt
index 28bd43982eba..b07de16be567 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorKosmos.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.domain.interactor
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -29,6 +30,7 @@ var Kosmos.fromLockscreenTransitionInteractor by
FromLockscreenTransitionInteractor(
transitionRepository = keyguardTransitionRepository,
transitionInteractor = keyguardTransitionInteractor,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
scope = applicationCoroutineScope,
bgDispatcher = testDispatcher,
mainDispatcher = testDispatcher,
@@ -36,6 +38,7 @@ var Kosmos.fromLockscreenTransitionInteractor by
shadeRepository = shadeRepository,
powerInteractor = powerInteractor,
glanceableHubTransitions = glanceableHubTransitions,
+ communalSettingsInteractor = communalSettingsInteractor,
swipeToDismissInteractor = swipeToDismissInteractor,
keyguardOcclusionInteractor = keyguardOcclusionInteractor,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorKosmos.kt
index fc740a180dc4..c2169456eac5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorKosmos.kt
@@ -29,6 +29,7 @@ val Kosmos.fromOccludedTransitionInteractor by
FromOccludedTransitionInteractor(
transitionRepository = keyguardTransitionRepository,
transitionInteractor = keyguardTransitionInteractor,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
scope = applicationCoroutineScope,
bgDispatcher = testDispatcher,
mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt
index d72b9c10d3d8..42ee15216590 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt
@@ -31,6 +31,7 @@ var Kosmos.fromPrimaryBouncerTransitionInteractor by
FromPrimaryBouncerTransitionInteractor(
transitionRepository = keyguardTransitionRepository,
transitionInteractor = keyguardTransitionInteractor,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
scope = applicationCoroutineScope,
bgDispatcher = testDispatcher,
mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractorKosmos.kt
new file mode 100644
index 000000000000..017a9ecd7f9c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractorKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.keyguard.domain.interactor
+
+import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.internalKeyguardTransitionInteractor by
+ Kosmos.Fixture {
+ InternalKeyguardTransitionInteractor(
+ repository = keyguardTransitionRepository,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorKosmos.kt
index 4328ca153374..406b5cb11bb4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorKosmos.kt
@@ -16,11 +16,9 @@
package com.android.systemui.keyguard.domain.interactor
-import android.content.applicationContext
import com.android.systemui.biometrics.domain.interactor.fingerprintPropertyInteractor
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.keyguard.data.repository.keyguardBlueprintRepository
-import com.android.systemui.keyguard.data.repository.keyguardClockSection
import com.android.systemui.keyguard.data.repository.keyguardSmartspaceSection
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -31,12 +29,9 @@ val Kosmos.keyguardBlueprintInteractor by
KeyguardBlueprintInteractor(
keyguardBlueprintRepository = keyguardBlueprintRepository,
applicationScope = applicationCoroutineScope,
- context = applicationContext,
shadeInteractor = shadeInteractor,
- clockInteractor = keyguardClockInteractor,
configurationInteractor = configurationInteractor,
fingerprintPropertyInteractor = fingerprintPropertyInteractor,
- clockSection = keyguardClockSection,
smartspaceSection = keyguardSmartspaceSection,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
index 03e5a90c9f7d..2c6d44f10152 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorKosmos.kt
@@ -19,7 +19,6 @@ package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.domain.interactor.sceneInteractor
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ExperimentalCoroutinesApi
@@ -30,6 +29,5 @@ val Kosmos.keyguardDismissActionInteractor by
transitionInteractor = keyguardTransitionInteractor,
dismissInteractor = keyguardDismissInteractor,
applicationScope = testScope.backgroundScope,
- sceneInteractor = sceneInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
index 0667a6b9536a..c6b5ed0b608f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
@@ -28,5 +28,6 @@ val Kosmos.keyguardEnabledInteractor by
keyguardRepository,
biometricSettingsRepository,
keyguardTransitionInteractor,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractorKosmos.kt
index 7d8d33f7dd11..5836902ad54d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractorKosmos.kt
@@ -30,5 +30,6 @@ val Kosmos.keyguardTransitionBootInteractor: KeyguardTransitionBootInteractor by
deviceProvisioningInteractor = deviceProvisioningInteractor,
keyguardTransitionInteractor = keyguardTransitionInteractor,
repository = keyguardTransitionRepository,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt
index c90642d93939..c5da10e59369 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt
@@ -33,6 +33,6 @@ val Kosmos.keyguardTransitionInteractor: KeyguardTransitionInteractor by
fromAodTransitionInteractor = { fromAodTransitionInteractor },
fromAlternateBouncerTransitionInteractor = { fromAlternateBouncerTransitionInteractor },
fromDozingTransitionInteractor = { fromDozingTransitionInteractor },
- sceneInteractor = { sceneInteractor }
+ sceneInteractor = sceneInteractor
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorKosmos.kt
new file mode 100644
index 000000000000..63e168d018bf
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorKosmos.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.keyguard.domain.interactor
+
+import android.app.admin.alarmManager
+import android.content.mockedContext
+import com.android.internal.widget.lockPatternUtils
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.user.domain.interactor.selectedUserInteractor
+import com.android.systemui.util.settings.fakeSettings
+import com.android.systemui.util.time.systemClock
+
+val Kosmos.keyguardWakeDirectlyToGoneInteractor by
+ Kosmos.Fixture {
+ KeyguardWakeDirectlyToGoneInteractor(
+ applicationCoroutineScope,
+ mockedContext,
+ fakeKeyguardRepository,
+ systemClock,
+ alarmManager,
+ keyguardTransitionInteractor,
+ powerInteractor,
+ fakeSettings,
+ lockPatternUtils,
+ fakeSettings,
+ selectedUserInteractor,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt
index bd9c0be6b0b7..8bb2fcecca58 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.statusbar.notification.domain.interactor.notificationLaunchAnimationInteractor
@@ -25,6 +26,7 @@ val Kosmos.windowManagerLockscreenVisibilityInteractor by
Kosmos.Fixture {
WindowManagerLockscreenVisibilityInteractor(
keyguardInteractor = keyguardInteractor,
+ transitionRepository = keyguardTransitionRepository,
transitionInteractor = keyguardTransitionInteractor,
surfaceBehindInteractor = keyguardSurfaceBehindInteractor,
fromLockscreenInteractor = fromLockscreenTransitionInteractor,
@@ -33,5 +35,6 @@ val Kosmos.windowManagerLockscreenVisibilityInteractor by
notificationLaunchAnimationInteractor = notificationLaunchAnimationInteractor,
sceneInteractor = { sceneInteractor },
deviceEntryInteractor = { deviceEntryInteractor },
+ wakeToGoneInteractor = keyguardWakeDirectlyToGoneInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
index 3c1f7b1b2394..e50e04499168 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.domain.interactor.scenetransition
import com.android.systemui.keyguard.data.repository.lockscreenSceneTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.internalKeyguardTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -29,5 +30,6 @@ var Kosmos.lockscreenSceneTransitionInteractor by
applicationScope = applicationCoroutineScope,
sceneInteractor = sceneInteractor,
repository = lockscreenSceneTransitionRepository,
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModelKosmos.kt
new file mode 100644
index 000000000000..b5f0b897deba
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToAodTransitionViewModelKosmos.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+var Kosmos.dreamingToAodTransitionViewModel by Fixture {
+ DreamingToAodTransitionViewModel(
+ deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+ animationFlow = keyguardTransitionAnimationFlow,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
index 2567ffee9be8..3c5baa557513 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelKosmos.kt
@@ -46,6 +46,7 @@ val Kosmos.keyguardRootViewModel by Fixture {
dozingToGoneTransitionViewModel = dozingToGoneTransitionViewModel,
dozingToLockscreenTransitionViewModel = dozingToLockscreenTransitionViewModel,
dozingToOccludedTransitionViewModel = dozingToOccludedTransitionViewModel,
+ dreamingToAodTransitionViewModel = dreamingToAodTransitionViewModel,
dreamingToGoneTransitionViewModel = dreamingToGoneTransitionViewModel,
dreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel,
glanceableHubToLockscreenTransitionViewModel = glanceableHubToLockscreenTransitionViewModel,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
index 24e47b0af3fa..550ecb3ea7af 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
@@ -21,6 +21,7 @@ import com.android.systemui.keyguard.domain.interactor.keyguardBlueprintInteract
import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
@@ -34,5 +35,6 @@ val Kosmos.lockscreenContentViewModel by
shadeInteractor = shadeInteractor,
applicationScope = applicationCoroutineScope,
unfoldTransitionInteractor = unfoldTransitionInteractor,
+ occlusionInteractor = sceneContainerOcclusionInteractor,
)
}
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 10ff73179f71..06668201a925 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
@@ -68,6 +68,7 @@ import com.android.systemui.statusbar.pipeline.wifi.data.repository.fakeWifiRepo
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.wifiInteractor
import com.android.systemui.statusbar.policy.data.repository.fakeDeviceProvisioningRepository
import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor
+import com.android.systemui.statusbar.ui.viewmodel.keyguardStatusBarViewModel
import com.android.systemui.util.time.systemClock
import com.android.systemui.volume.domain.interactor.volumeDialogInteractor
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -102,6 +103,7 @@ class KosmosJavaAdapter() {
val keyguardInteractor by lazy { kosmos.keyguardInteractor }
val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository }
val keyguardTransitionInteractor by lazy { kosmos.keyguardTransitionInteractor }
+ val keyguardStatusBarViewModel by lazy { kosmos.keyguardStatusBarViewModel }
val powerRepository by lazy { kosmos.fakePowerRepository }
val clock by lazy { kosmos.systemClock }
val mobileConnectionsRepository by lazy { kosmos.fakeMobileConnectionsRepository }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterKosmos.kt
index b8b006098c6f..147318473998 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterKosmos.kt
@@ -21,6 +21,7 @@ import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.shared.mediaLogger
import com.android.systemui.media.controls.util.mediaFlags
import com.android.systemui.media.controls.util.mediaUiEventLogger
import com.android.systemui.settings.userTracker
@@ -45,6 +46,6 @@ val Kosmos.mediaDataFilter by
logger = mediaUiEventLogger,
mediaFlags = mediaFlags,
mediaFilterRepository = mediaFilterRepository,
- mediaLoadingLogger = mediaLoadingLogger,
+ mediaLogger = mediaLogger,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/shared/MediaLoggerKosmos.kt
index 96886f738dbd..55c419e8ade1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLoggerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/shared/MediaLoggerKosmos.kt
@@ -14,12 +14,11 @@
* limitations under the License.
*/
-package com.android.systemui.media.controls.domain.pipeline
+package com.android.systemui.media.controls.shared
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.log.logcatLogBuffer
import org.mockito.Mockito.mock
-val Kosmos.mediaLoadingLogger by
- Kosmos.Fixture { MediaLoadingLogger(logcatLogBuffer("MediaLoadingLogBuffer")) }
-val Kosmos.mockMediaLoadingLogger by Kosmos.Fixture { mock(MediaLoadingLogger::class.java) }
+var Kosmos.mediaLogger by Kosmos.Fixture { MediaLogger(logcatLogBuffer("MediaLogBuffer")) }
+val Kosmos.mockMediaLogger by Kosmos.Fixture { mock(MediaLogger::class.java) }
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 069995aa3fec..054ac2e39993 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
@@ -23,6 +23,7 @@ import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.media.controls.domain.pipeline.interactor.factory.mediaControlInteractorFactory
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
+import com.android.systemui.media.controls.shared.mediaLogger
import com.android.systemui.media.controls.util.mediaFlags
import com.android.systemui.media.controls.util.mediaUiEventLogger
import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
@@ -40,5 +41,6 @@ val Kosmos.mediaCarouselViewModel by
recommendationsViewModel = mediaRecommendationsViewModel,
logger = mediaUiEventLogger,
mediaFlags = mediaFlags,
+ mediaLogger = mediaLogger,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepositoryKosmos.kt
index f253e949375e..04122742bb0d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepositoryKosmos.kt
@@ -16,10 +16,12 @@
package com.android.systemui.mediaprojection.data.repository
+import android.hardware.display.displayManager
import android.os.Handler
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.mediaprojection.taskswitcher.activityTaskManagerTasksRepository
import com.android.systemui.mediaprojection.taskswitcher.fakeMediaProjectionManager
@@ -30,10 +32,12 @@ val Kosmos.realMediaProjectionRepository by
Kosmos.Fixture {
MediaProjectionManagerRepository(
mediaProjectionManager = fakeMediaProjectionManager.mediaProjectionManager,
+ displayManager = displayManager,
handler = Handler.getMain(),
applicationScope = applicationCoroutineScope,
tasksRepository = activityTaskManagerTasksRepository,
backgroundDispatcher = testDispatcher,
mediaProjectionServiceHelper = fakeMediaProjectionManager.helper,
+ logger = logcatLogBuffer("TestMediaProjection"),
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/FakeMediaRouterRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/FakeMediaRouterRepository.kt
new file mode 100644
index 000000000000..8aa7a03710cb
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/FakeMediaRouterRepository.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.mediarouter.data.repository
+
+import com.android.systemui.statusbar.policy.CastDevice
+import kotlinx.coroutines.flow.MutableStateFlow
+
+class FakeMediaRouterRepository : MediaRouterRepository {
+ override val castDevices: MutableStateFlow<List<CastDevice>> = MutableStateFlow(emptyList())
+
+ var lastStoppedDevice: CastDevice? = null
+ private set
+
+ override fun stopCasting(device: CastDevice) {
+ lastStoppedDevice = device
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryKosmos.kt
new file mode 100644
index 000000000000..e1ecc517ec9f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * 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.mediarouter.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.log.logcatLogBuffer
+import com.android.systemui.statusbar.policy.fakeCastController
+
+val Kosmos.realMediaRouterRepository by
+ Kosmos.Fixture {
+ MediaRouterRepositoryImpl(
+ scope = applicationCoroutineScope,
+ castController = fakeCastController,
+ logger = logcatLogBuffer("MediaRouter"),
+ )
+ }
+
+val Kosmos.fakeMediaRouterRepository by Kosmos.Fixture { FakeMediaRouterRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/IconTilesRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/DefaultLargeTilesRepositoryKosmos.kt
index e40152aa588f..92ac08949add 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/IconTilesRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/DefaultLargeTilesRepositoryKosmos.kt
@@ -18,4 +18,5 @@ package com.android.systemui.qs.panels.data.repository
import com.android.systemui.kosmos.Kosmos
-var Kosmos.iconTilesRepository: IconTilesRepository by Kosmos.Fixture { IconTilesRepositoryImpl() }
+var Kosmos.defaultLargeTilesRepository: DefaultLargeTilesRepository by
+ Kosmos.Fixture { DefaultLargeTilesRepositoryImpl() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryKosmos.kt
index 39ae5eb44c65..513d4e418a41 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryKosmos.kt
@@ -22,4 +22,11 @@ import com.android.systemui.settings.userFileManager
import com.android.systemui.user.data.repository.userRepository
val Kosmos.qsPreferencesRepository by
- Kosmos.Fixture { QSPreferencesRepository(userFileManager, userRepository, testDispatcher) }
+ Kosmos.Fixture {
+ QSPreferencesRepository(
+ userFileManager,
+ userRepository,
+ defaultLargeTilesRepository,
+ testDispatcher
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryKosmos.kt
new file mode 100644
index 000000000000..da55e21e6026
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.qs.panels.data.repository
+
+import com.android.systemui.common.ui.data.repository.configurationRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+
+val Kosmos.quickQuickSettingsRowRepository by
+ Kosmos.Fixture {
+ testCase.context.orCreateTestableResources
+ QuickQuickSettingsRowRepository(testCase.context.resources, configurationRepository)
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorKosmos.kt
index eaa702f9f6da..76dccdb95637 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorKosmos.kt
@@ -17,6 +17,16 @@
package com.android.systemui.qs.panels.domain.interactor
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.data.repository.iconTilesRepository
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.log.core.FakeLogBuffer
+import com.android.systemui.qs.panels.data.repository.defaultLargeTilesRepository
-val Kosmos.iconTilesInteractor by Kosmos.Fixture { IconTilesInteractor(iconTilesRepository) }
+val Kosmos.iconTilesInteractor by
+ Kosmos.Fixture {
+ IconTilesInteractor(
+ defaultLargeTilesRepository,
+ qsPreferencesInteractor,
+ FakeLogBuffer.Factory.create(),
+ applicationCoroutineScope
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractorKosmos.kt
new file mode 100644
index 000000000000..3fcbc8dd24d6
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractorKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.qs.panels.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.data.repository.quickQuickSettingsRowRepository
+
+val Kosmos.quickQuickSettingsRowInteractor by
+ Kosmos.Fixture { QuickQuickSettingsRowInteractor(quickQuickSettingsRowRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
new file mode 100644
index 000000000000..40d26242e36c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * 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.qs.panels.ui.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.qs.panels.domain.interactor.quickQuickSettingsRowInteractor
+import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
+
+val Kosmos.quickQuickSettingsViewModel by
+ Kosmos.Fixture {
+ QuickQuickSettingsViewModel(
+ currentTilesInteractor,
+ fixedColumnsSizeViewModel,
+ quickQuickSettingsRowInteractor,
+ iconTilesViewModel,
+ applicationCoroutineScope,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
new file mode 100644
index 000000000000..779634dc5f39
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * 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.qs.ui.viewmodel
+
+import com.android.systemui.brightness.ui.viewmodel.brightnessSliderViewModel
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.quickQuickSettingsViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModel
+
+val Kosmos.quickSettingsContainerViewModel by
+ Kosmos.Fixture {
+ QuickSettingsContainerViewModel(
+ brightnessSliderViewModel,
+ tileGridViewModel,
+ editModeViewModel,
+ quickQuickSettingsViewModel,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
index 8adb26f2d65f..c56c56cddddf 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
@@ -14,24 +14,19 @@
* limitations under the License.
*/
-package com.android.systemui.shade.ui.viewmodel
+package com.android.systemui.qs.ui.viewmodel
-import com.android.systemui.brightness.ui.viewmodel.brightnessSliderViewModel
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModel
-import com.android.systemui.qs.ui.adapter.qsSceneAdapter
-import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneViewModel
+import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.ui.viewmodel.overlayShadeViewModel
val Kosmos.quickSettingsShadeSceneViewModel: QuickSettingsShadeSceneViewModel by
Kosmos.Fixture {
QuickSettingsShadeSceneViewModel(
- overlayShadeViewModel = overlayShadeViewModel,
- brightnessSliderViewModel = brightnessSliderViewModel,
- tileGridViewModel = tileGridViewModel,
- editModeViewModel = editModeViewModel,
- qsSceneAdapter = qsSceneAdapter,
shadeInteractor = shadeInteractor,
+ overlayShadeViewModel = overlayShadeViewModel,
+ quickSettingsContainerViewModel = quickSettingsContainerViewModel,
+ applicationScope = applicationCoroutineScope,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
index 641a75716ea0..2f17ca853d16 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
@@ -18,8 +18,11 @@ package com.android.systemui.scene.data.repository
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -30,6 +33,25 @@ import kotlinx.coroutines.test.runCurrent
private val mutableTransitionState =
MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(Scenes.Lockscreen))
+suspend fun Kosmos.setTransition(
+ sceneTransition: ObservableTransitionState,
+ stateTransition: TransitionStep? = null,
+ scope: TestScope = testScope,
+ repository: SceneContainerRepository = sceneContainerRepository
+) {
+ if (SceneContainerFlag.isEnabled) {
+ setSceneTransition(sceneTransition, scope, repository)
+ } else {
+ if (stateTransition == null) throw IllegalArgumentException("No transitionStep provided")
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = stateTransition.from,
+ to = stateTransition.to,
+ testScope = scope,
+ throughTransitionState = stateTransition.transitionState
+ )
+ }
+}
+
fun Kosmos.setSceneTransition(
transition: ObservableTransitionState,
scope: TestScope = testScope,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
index 0921eb9e83d3..ae8b411a4b95 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
@@ -31,7 +31,7 @@ val Kosmos.sceneInteractor by
repository = sceneContainerRepository,
logger = sceneLogger,
sceneFamilyResolvers = { sceneFamilyResolvers },
- deviceUnlockedInteractor = deviceUnlockedInteractor,
- keyguardEnabledInteractor = keyguardEnabledInteractor,
+ deviceUnlockedInteractor = { deviceUnlockedInteractor },
+ keyguardEnabledInteractor = { keyguardEnabledInteractor },
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
index b9918f1e46d8..4660337c0d4b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
@@ -18,7 +18,6 @@
package com.android.systemui.shade.data.repository
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.shade.shared.model.ShadeMode
import dagger.Binds
import dagger.Module
import javax.inject.Inject
@@ -30,53 +29,65 @@ import kotlinx.coroutines.flow.asStateFlow
@SysUISingleton
class FakeShadeRepository @Inject constructor() : ShadeRepository {
private val _qsExpansion = MutableStateFlow(0f)
- @Deprecated("Use ShadeInteractor.qsExpansion instead") override val qsExpansion = _qsExpansion
+
+ @Deprecated("Use ShadeInteractor.qsExpansion instead")
+ override val qsExpansion = _qsExpansion.asStateFlow()
private val _udfpsTransitionToFullShadeProgress = MutableStateFlow(0f)
- override val udfpsTransitionToFullShadeProgress = _udfpsTransitionToFullShadeProgress
+ override val udfpsTransitionToFullShadeProgress =
+ _udfpsTransitionToFullShadeProgress.asStateFlow()
private val _currentFling: MutableStateFlow<FlingInfo?> = MutableStateFlow(null)
- override val currentFling: StateFlow<FlingInfo?> = _currentFling
+ override val currentFling: StateFlow<FlingInfo?> = _currentFling.asStateFlow()
private val _lockscreenShadeExpansion = MutableStateFlow(0f)
- override val lockscreenShadeExpansion = _lockscreenShadeExpansion
+ override val lockscreenShadeExpansion = _lockscreenShadeExpansion.asStateFlow()
private val _legacyShadeExpansion = MutableStateFlow(0f)
+
@Deprecated("Use ShadeInteractor instead")
- override val legacyShadeExpansion = _legacyShadeExpansion
+ override val legacyShadeExpansion = _legacyShadeExpansion.asStateFlow()
private val _legacyShadeTracking = MutableStateFlow(false)
+
@Deprecated("Use ShadeInteractor instead")
- override val legacyShadeTracking = _legacyShadeTracking
+ override val legacyShadeTracking = _legacyShadeTracking.asStateFlow()
private val _legacyQsTracking = MutableStateFlow(false)
- @Deprecated("Use ShadeInteractor instead") override val legacyQsTracking = _legacyQsTracking
+
+ @Deprecated("Use ShadeInteractor instead")
+ override val legacyQsTracking = _legacyQsTracking.asStateFlow()
private val _legacyExpandedOrAwaitingInputTransfer = MutableStateFlow(false)
+
@Deprecated("Use ShadeInteractor instead")
- override val legacyExpandedOrAwaitingInputTransfer = _legacyExpandedOrAwaitingInputTransfer
+ override val legacyExpandedOrAwaitingInputTransfer =
+ _legacyExpandedOrAwaitingInputTransfer.asStateFlow()
private val _legacyIsQsExpanded = MutableStateFlow(false)
- @Deprecated("Use ShadeInteractor instead") override val legacyIsQsExpanded = _legacyIsQsExpanded
+
+ @Deprecated("Use ShadeInteractor instead")
+ override val legacyIsQsExpanded = _legacyIsQsExpanded.asStateFlow()
@Deprecated("Use ShadeInteractor.isUserInteractingWithShade instead")
override val legacyLockscreenShadeTracking = MutableStateFlow(false)
- private val _shadeMode = MutableStateFlow<ShadeMode>(ShadeMode.Single)
- override val shadeMode: StateFlow<ShadeMode> = _shadeMode.asStateFlow()
-
private var _isDualShadeAlignedToBottom = false
override val isDualShadeAlignedToBottom
get() = _isDualShadeAlignedToBottom
+ private var _isShadeLayoutWide = MutableStateFlow(false)
+ override val isShadeLayoutWide: StateFlow<Boolean> = _isShadeLayoutWide.asStateFlow()
+
@Deprecated("Use ShadeInteractor instead")
override fun setLegacyIsQsExpanded(legacyIsQsExpanded: Boolean) {
_legacyIsQsExpanded.value = legacyIsQsExpanded
}
private val _legacyExpandImmediate = MutableStateFlow(false)
+
@Deprecated("Use ShadeInteractor instead")
- override val legacyExpandImmediate = _legacyExpandImmediate
+ override val legacyExpandImmediate = _legacyExpandImmediate.asStateFlow()
@Deprecated("Use ShadeInteractor instead")
override fun setLegacyExpandImmediate(legacyExpandImmediate: Boolean) {
@@ -106,6 +117,7 @@ class FakeShadeRepository @Inject constructor() : ShadeRepository {
}
private val _legacyQsFullscreen = MutableStateFlow(false)
+
@Deprecated("Use ShadeInteractor instead") override val legacyQsFullscreen = _legacyQsFullscreen
@Deprecated("Use ShadeInteractor instead")
@@ -114,6 +126,7 @@ class FakeShadeRepository @Inject constructor() : ShadeRepository {
}
private val _legacyIsClosing = MutableStateFlow(false)
+
@Deprecated("Use ShadeInteractor instead") override val legacyIsClosing = _legacyIsClosing
@Deprecated("Use ShadeInteractor instead")
@@ -142,13 +155,13 @@ class FakeShadeRepository @Inject constructor() : ShadeRepository {
_legacyShadeExpansion.value = expandedFraction
}
- override fun setShadeMode(mode: ShadeMode) {
- _shadeMode.value = mode
- }
-
fun setDualShadeAlignedToBottom(isAlignedToBottom: Boolean) {
_isDualShadeAlignedToBottom = isAlignedToBottom
}
+
+ override fun setShadeLayoutWide(isShadeLayoutWide: Boolean) {
+ _isShadeLayoutWide.value = isShadeLayoutWide
+ }
}
@Module
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
index a00d2f4fc517..bfd6614a2272 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
@@ -45,7 +45,6 @@ val Kosmos.shadeInteractorSceneContainerImpl by
scope = applicationCoroutineScope,
sceneInteractor = sceneInteractor,
sharedNotificationContainerInteractor = sharedNotificationContainerInteractor,
- shadeRepository = shadeRepository,
)
}
val Kosmos.shadeInteractorLegacyImpl by
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/data/repository/FakeSmartspaceRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/data/repository/FakeSmartspaceRepository.kt
deleted file mode 100644
index 862e52d7703f..000000000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/data/repository/FakeSmartspaceRepository.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.android.systemui.smartspace.data.repository
-
-import android.app.smartspace.SmartspaceTarget
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-
-class FakeSmartspaceRepository(
- smartspaceRemoteViewsEnabled: Boolean = true,
-) : SmartspaceRepository {
-
- override val isSmartspaceRemoteViewsEnabled = smartspaceRemoteViewsEnabled
-
- private val _communalSmartspaceTargets: MutableStateFlow<List<SmartspaceTarget>> =
- MutableStateFlow(emptyList())
- override val communalSmartspaceTargets: Flow<List<SmartspaceTarget>> =
- _communalSmartspaceTargets
-
- fun setCommunalSmartspaceTargets(targets: List<SmartspaceTarget>) {
- _communalSmartspaceTargets.value = targets
- }
-}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/StatusBarChipsLogKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/StatusBarChipsLogKosmos.kt
new file mode 100644
index 000000000000..e904cd27a297
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/StatusBarChipsLogKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * 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.chips
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.logcatLogBuffer
+
+val Kosmos.statusBarChipsLogger by Kosmos.Fixture { logcatLogBuffer("StatusBarChips") }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt
index 064e57bada28..fcd14d8512fb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt
@@ -17,7 +17,15 @@
package com.android.systemui.statusbar.chips.call.domain.interactor
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
val Kosmos.callChipInteractor: CallChipInteractor by
- Kosmos.Fixture { CallChipInteractor(repository = ongoingCallRepository) }
+ Kosmos.Fixture {
+ CallChipInteractor(
+ scope = applicationCoroutineScope,
+ repository = ongoingCallRepository,
+ logger = statusBarChipsLogger,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelKosmos.kt
index ab71b5e2d6b9..1e304d979e03 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelKosmos.kt
@@ -20,6 +20,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.plugins.activityStarter
import com.android.systemui.statusbar.chips.call.domain.interactor.callChipInteractor
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
import com.android.systemui.util.time.fakeSystemClock
val Kosmos.callChipViewModel: CallChipViewModel by
@@ -29,5 +30,6 @@ val Kosmos.callChipViewModel: CallChipViewModel by
interactor = callChipInteractor,
systemClock = fakeSystemClock,
activityStarter = activityStarter,
+ logger = statusBarChipsLogger,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractorKosmos.kt
new file mode 100644
index 000000000000..1737bc4c7dfb
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractorKosmos.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.chips.casttootherdevice.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
+
+val Kosmos.mediaRouterChipInteractor by
+ Kosmos.Fixture {
+ MediaRouterChipInteractor(
+ scope = applicationCoroutineScope,
+ mediaRouterRepository = fakeMediaRouterRepository,
+ logger = statusBarChipsLogger,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt
index 4baa8d0b117e..3d85a4abbd68 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt
@@ -16,20 +16,24 @@
package com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel
-import com.android.systemui.animation.mockDialogTransitionAnimator
+import android.content.applicationContext
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor.mediaRouterChipInteractor
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.mediaProjectionChipInteractor
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
import com.android.systemui.util.time.fakeSystemClock
val Kosmos.castToOtherDeviceChipViewModel: CastToOtherDeviceChipViewModel by
Kosmos.Fixture {
CastToOtherDeviceChipViewModel(
scope = applicationCoroutineScope,
+ context = applicationContext,
mediaProjectionChipInteractor = mediaProjectionChipInteractor,
+ mediaRouterChipInteractor = mediaRouterChipInteractor,
systemClock = fakeSystemClock,
endMediaProjectionDialogHelper = endMediaProjectionDialogHelper,
- dialogTransitionAnimator = mockDialogTransitionAnimator,
+ logger = statusBarChipsLogger,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt
index 6812a9df8973..0bfd88fc2cfc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt
@@ -20,6 +20,7 @@ import android.content.packageManager
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
val Kosmos.mediaProjectionChipInteractor: MediaProjectionChipInteractor by
Kosmos.Fixture {
@@ -27,5 +28,6 @@ val Kosmos.mediaProjectionChipInteractor: MediaProjectionChipInteractor by
scope = applicationCoroutineScope,
mediaProjectionRepository = fakeMediaProjectionRepository,
packageManager = packageManager,
+ logger = statusBarChipsLogger,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperKosmos.kt
index 4f82662fa673..1ed7a4702e2c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperKosmos.kt
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.chips.mediaprojection.ui.view
-import android.content.applicationContext
import android.content.packageManager
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
@@ -26,6 +25,5 @@ val Kosmos.endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper by
EndMediaProjectionDialogHelper(
dialogFactory = mockSystemUIDialogFactory,
packageManager = packageManager,
- context = applicationContext,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorKosmos.kt
index b4e9c146acbe..557d3e22d3b3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorKosmos.kt
@@ -20,6 +20,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
import com.android.systemui.screenrecord.data.repository.screenRecordRepository
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
val Kosmos.screenRecordChipInteractor: ScreenRecordChipInteractor by
Kosmos.Fixture {
@@ -27,5 +28,6 @@ val Kosmos.screenRecordChipInteractor: ScreenRecordChipInteractor by
scope = applicationCoroutineScope,
screenRecordRepository = screenRecordRepository,
mediaProjectionRepository = fakeMediaProjectionRepository,
+ logger = statusBarChipsLogger,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelKosmos.kt
index 99b7ec9c9f1a..e4bb1665a432 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelKosmos.kt
@@ -16,20 +16,22 @@
package com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel
-import com.android.systemui.animation.mockDialogTransitionAnimator
+import android.content.applicationContext
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.screenRecordChipInteractor
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
import com.android.systemui.util.time.fakeSystemClock
val Kosmos.screenRecordChipViewModel: ScreenRecordChipViewModel by
Kosmos.Fixture {
ScreenRecordChipViewModel(
scope = applicationCoroutineScope,
+ context = applicationContext,
interactor = screenRecordChipInteractor,
endMediaProjectionDialogHelper = endMediaProjectionDialogHelper,
- dialogTransitionAnimator = mockDialogTransitionAnimator,
systemClock = fakeSystemClock,
+ logger = statusBarChipsLogger,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt
index 535f81a7d63e..8ed7f9684d86 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt
@@ -16,20 +16,22 @@
package com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel
-import com.android.systemui.animation.mockDialogTransitionAnimator
+import android.content.applicationContext
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.mediaProjectionChipInteractor
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
import com.android.systemui.util.time.fakeSystemClock
val Kosmos.shareToAppChipViewModel: ShareToAppChipViewModel by
Kosmos.Fixture {
ShareToAppChipViewModel(
scope = applicationCoroutineScope,
+ context = applicationContext,
mediaProjectionChipInteractor = mediaProjectionChipInteractor,
systemClock = fakeSystemClock,
endMediaProjectionDialogHelper = endMediaProjectionDialogHelper,
- dialogTransitionAnimator = mockDialogTransitionAnimator,
+ logger = statusBarChipsLogger,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt
index 078e84521d5e..16e288fcf113 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt
@@ -22,6 +22,7 @@ import com.android.systemui.statusbar.chips.call.ui.viewmodel.callChipViewModel
import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.castToOtherDeviceChipViewModel
import com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel.screenRecordChipViewModel
import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.shareToAppChipViewModel
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
val Kosmos.ongoingActivityChipsViewModel: OngoingActivityChipsViewModel by
Kosmos.Fixture {
@@ -31,5 +32,6 @@ val Kosmos.ongoingActivityChipsViewModel: OngoingActivityChipsViewModel by
shareToAppChipViewModel = shareToAppChipViewModel,
castToOtherDeviceChipViewModel = castToOtherDeviceChipViewModel,
callChipViewModel = callChipViewModel,
+ logger = statusBarChipsLogger,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardOcclusionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardOcclusionInteractorKosmos.kt
index a90a9ffc8a33..65016c3eefb8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardOcclusionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardOcclusionInteractorKosmos.kt
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.domain.interactor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardOcclusionInteractor
+import com.android.systemui.keyguard.domain.interactor.internalKeyguardTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
@@ -34,5 +35,6 @@ val Kosmos.keyguardOcclusionInteractor by
transitionInteractor = keyguardTransitionInteractor,
keyguardInteractor = keyguardInteractor,
deviceUnlockedInteractor = { deviceUnlockedInteractor },
+ internalTransitionInteractor = internalKeyguardTransitionInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorKosmos.kt
index e6ca458fabbe..aee90d56faa6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorKosmos.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar.notification.domain.interactor
-import com.android.settingslib.statusbar.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.statusbar.policy.data.repository.zenModeRepository
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt
index 7bf77e5199fe..492e87bbcac4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt
@@ -30,7 +30,12 @@ class FakeHeadsUpNotificationRepository : HeadsUpRepository {
override val topHeadsUpRow: Flow<HeadsUpRowRepository?> = MutableStateFlow(null)
override val activeHeadsUpRows: MutableStateFlow<Set<HeadsUpRowRepository>> =
MutableStateFlow(emptySet())
+
override fun setHeadsUpAnimatingAway(animatingAway: Boolean) {
isHeadsUpAnimatingAway.value = animatingAway
}
+
+ override fun snooze() {
+ // do nothing
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
index a0e9303890ba..afb8acb3d819 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
@@ -22,6 +22,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.ui.viewmodel.shadeSceneViewModel
+import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
val Kosmos.notificationsPlaceholderViewModel by Fixture {
@@ -30,6 +31,7 @@ val Kosmos.notificationsPlaceholderViewModel by Fixture {
interactor = notificationStackAppearanceInteractor,
shadeInteractor = shadeInteractor,
shadeSceneViewModel = shadeSceneViewModel,
+ headsUpNotificationInteractor = headsUpNotificationInteractor,
featureFlags = featureFlagsClassic,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/CastControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/CastControllerKosmos.kt
new file mode 100644
index 000000000000..8e77437efebf
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/CastControllerKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.policy
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.fakeCastController: FakeCastController by Kosmos.Fixture { FakeCastController() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeCastController.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeCastController.kt
new file mode 100644
index 000000000000..2df0c7a5386e
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeCastController.kt
@@ -0,0 +1,61 @@
+/*
+ * 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.policy
+
+import java.io.PrintWriter
+
+class FakeCastController : CastController {
+ private var listeners = mutableListOf<CastController.Callback>()
+
+ private var castDevices = emptyList<CastDevice>()
+
+ var lastStoppedDevice: CastDevice? = null
+ private set
+
+ override fun addCallback(listener: CastController.Callback) {
+ listeners += listener
+ }
+
+ override fun removeCallback(listener: CastController.Callback) {
+ listeners -= listener
+ }
+
+ override fun getCastDevices(): List<CastDevice> {
+ return castDevices
+ }
+
+ fun setCastDevices(devices: List<CastDevice>) {
+ castDevices = devices
+ listeners.forEach { it.onCastDevicesChanged() }
+ }
+
+ override fun startCasting(device: CastDevice?) {}
+
+ override fun stopCasting(device: CastDevice?) {
+ lastStoppedDevice = device
+ }
+
+ override fun hasConnectedCastDevice(): Boolean {
+ return castDevices.any { it.state == CastDevice.CastState.Connected }
+ }
+
+ override fun dump(pw: PrintWriter, args: Array<out String>) {}
+
+ override fun setDiscovering(request: Boolean) {}
+
+ override fun setCurrentUserId(currentUserId: Int) {}
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryKosmos.kt
index c7fda54af39d..1ba5ddbf0337 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryKosmos.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar.policy.data.repository
-import com.android.settingslib.statusbar.notification.data.repository.FakeZenModeRepository
+import com.android.settingslib.notification.data.repository.FakeZenModeRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelKosmos.kt
new file mode 100644
index 000000000000..ea79edcca38c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelKosmos.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.ui.viewmodel
+
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.statusbar.domain.interactor.keyguardStatusBarInteractor
+import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
+import com.android.systemui.statusbar.policy.batteryController
+
+val Kosmos.keyguardStatusBarViewModel: KeyguardStatusBarViewModel by
+ Kosmos.Fixture {
+ KeyguardStatusBarViewModel(
+ applicationCoroutineScope,
+ headsUpNotificationInteractor,
+ sceneInteractor,
+ keyguardInteractor,
+ keyguardStatusBarInteractor,
+ batteryController,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/AppCategoryIconProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/AppCategoryIconProviderKosmos.kt
new file mode 100644
index 000000000000..798718560c08
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/AppCategoryIconProviderKosmos.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.util.icons
+
+import android.content.mockPackageManager
+import android.content.mockPackageManagerWrapper
+import com.android.systemui.assist.mockAssistManager
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+
+var Kosmos.fakeAppCategoryIconProvider by Kosmos.Fixture { FakeAppCategoryIconProvider() }
+
+var Kosmos.appCategoryIconProvider: AppCategoryIconProvider by
+ Kosmos.Fixture {
+ AppCategoryIconProviderImpl(
+ testDispatcher,
+ mockAssistManager,
+ mockPackageManager,
+ mockPackageManagerWrapper
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/FakeAppCategoryIconProvider.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/FakeAppCategoryIconProvider.kt
new file mode 100644
index 000000000000..3e7bf21112ba
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/FakeAppCategoryIconProvider.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.util.icons
+
+import android.app.role.RoleManager.ROLE_ASSISTANT
+import android.graphics.drawable.Icon
+
+class FakeAppCategoryIconProvider : AppCategoryIconProvider {
+
+ private val installedApps = mutableMapOf<String, App>()
+
+ fun installCategoryApp(category: String, packageName: String, iconResId: Int) {
+ installedApps[category] = App(packageName, iconResId)
+ }
+
+ fun installAssistantApp(packageName: String, iconResId: Int) {
+ installedApps[ROLE_ASSISTANT] = App(packageName, iconResId)
+ }
+
+ override suspend fun assistantAppIcon() = categoryAppIcon(ROLE_ASSISTANT)
+
+ override suspend fun categoryAppIcon(category: String): Icon? {
+ val app = installedApps[category] ?: return null
+ return Icon.createWithResource(app.packageName, app.iconResId)
+ }
+
+ private class App(val packageName: String, val iconResId: Int)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
index 3a70cdfc42ed..476b7d8376c8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
@@ -16,12 +16,16 @@
package com.android.systemui.util.settings;
+import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.net.Uri;
+import kotlinx.coroutines.CoroutineDispatcher;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -30,10 +34,16 @@ import java.util.Map;
public class FakeGlobalSettings implements GlobalSettings {
private final Map<String, String> mValues = new HashMap<>();
private final Map<String, List<ContentObserver>> mContentObserversAllUsers = new HashMap<>();
+ private final CoroutineDispatcher mDispatcher;
public static final Uri CONTENT_URI = Uri.parse("content://settings/fake_global");
public FakeGlobalSettings() {
+ mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
+ }
+
+ public FakeGlobalSettings(CoroutineDispatcher dispatcher) {
+ mDispatcher = dispatcher;
}
@Override
@@ -44,6 +54,11 @@ public class FakeGlobalSettings implements GlobalSettings {
}
@Override
+ public CoroutineDispatcher getBackgroundDispatcher() {
+ return mDispatcher;
+ }
+
+ @Override
public void registerContentObserverSync(Uri uri, boolean notifyDescendants,
ContentObserver settingsObserver) {
List<ContentObserver> observers;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
index cd219ec127fc..e35da11ff034 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
@@ -16,6 +16,8 @@
package com.android.systemui.util.settings;
+import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher;
+
import android.annotation.UserIdInt;
import android.content.ContentResolver;
import android.database.ContentObserver;
@@ -27,6 +29,8 @@ import androidx.annotation.NonNull;
import com.android.systemui.settings.UserTracker;
+import kotlinx.coroutines.CoroutineDispatcher;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -37,19 +41,27 @@ public class FakeSettings implements SecureSettings, SystemSettings {
private final Map<SettingsKey, List<ContentObserver>> mContentObservers =
new HashMap<>();
private final Map<String, List<ContentObserver>> mContentObserversAllUsers = new HashMap<>();
+ private final CoroutineDispatcher mDispatcher;
public static final Uri CONTENT_URI = Uri.parse("content://settings/fake");
@UserIdInt
private int mUserId = UserHandle.USER_CURRENT;
public FakeSettings() {
+ mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
+ }
+
+ public FakeSettings(CoroutineDispatcher dispatcher) {
+ mDispatcher = dispatcher;
}
public FakeSettings(String initialKey, String initialValue) {
+ mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
putString(initialKey, initialValue);
}
public FakeSettings(Map<String, String> initialValues) {
+ mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
for (Map.Entry<String, String> kv : initialValues.entrySet()) {
putString(kv.getKey(), kv.getValue());
}
@@ -66,6 +78,11 @@ public class FakeSettings implements SecureSettings, SystemSettings {
}
@Override
+ public CoroutineDispatcher getBackgroundDispatcher() {
+ return mDispatcher;
+ }
+
+ @Override
public void registerContentObserverForUserSync(Uri uri, boolean notifyDescendants,
ContentObserver settingsObserver, int userHandle) {
List<ContentObserver> observers;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
index 5d21ddd9c9bc..372a7c7d218b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
@@ -109,7 +109,7 @@ public abstract class LeakCheckedTest extends SysuiTestCase {
} else if (cls == ZenModeController.class) {
obj = new FakeZenModeController(this);
} else if (cls == CastController.class) {
- obj = new FakeCastController(this);
+ obj = new LeakCheckerCastController(this);
} else if (cls == HotspotController.class) {
obj = new FakeHotspotController(this);
} else if (cls == FlashlightController.class) {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckerCastController.java
index 5fae38f4a82b..2249bc0b667f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckerCastController.java
@@ -1,15 +1,17 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.utils.leaks;
@@ -23,8 +25,8 @@ import com.android.systemui.statusbar.policy.CastDevice;
import java.util.ArrayList;
import java.util.List;
-public class FakeCastController extends BaseLeakChecker<Callback> implements CastController {
- public FakeCastController(LeakCheck test) {
+public class LeakCheckerCastController extends BaseLeakChecker<Callback> implements CastController {
+ public LeakCheckerCastController(LeakCheck test) {
super(test, "cast");
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/VolumeControllerCollectorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/VolumeControllerCollectorKosmos.kt
new file mode 100644
index 000000000000..d60f14cab28f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/VolumeControllerCollectorKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.volume
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+
+val Kosmos.volumeControllerCollector by
+ Kosmos.Fixture { VolumeControllerCollector(applicationCoroutineScope) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
index fcea9e7b2a3f..135cb14a3497 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
@@ -22,7 +22,6 @@ import com.android.settingslib.volume.data.repository.AudioRepository
import com.android.settingslib.volume.shared.model.AudioStream
import com.android.settingslib.volume.shared.model.AudioStreamModel
import com.android.settingslib.volume.shared.model.RingerMode
-import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -61,7 +60,7 @@ class FakeAudioRepository : AudioRepository {
)
}
- override fun getAudioStream(audioStream: AudioStream): Flow<AudioStreamModel> =
+ override fun getAudioStream(audioStream: AudioStream): StateFlow<AudioStreamModel> =
getAudioStreamModelState(audioStream).asStateFlow()
override suspend fun setVolume(audioStream: AudioStream, volume: Int) {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt
index 327e1b5df2ac..d391750a2612 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt
@@ -16,16 +16,40 @@
package com.android.systemui.volume.data.repository
+import androidx.annotation.IntRange
import com.android.settingslib.volume.data.repository.AudioSharingRepository
+import com.android.settingslib.volume.data.repository.AudioSharingRepository.Companion.AUDIO_SHARING_VOLUME_MAX
+import com.android.settingslib.volume.data.repository.AudioSharingRepository.Companion.AUDIO_SHARING_VOLUME_MIN
+import com.android.settingslib.volume.data.repository.GroupIdToVolumes
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
class FakeAudioSharingRepository : AudioSharingRepository {
private val mutableInAudioSharing: MutableStateFlow<Boolean> = MutableStateFlow(false)
+ private val mutableSecondaryGroupId: MutableStateFlow<Int> =
+ MutableStateFlow(TEST_GROUP_ID_INVALID)
+ private val mutableVolumeMap: MutableStateFlow<GroupIdToVolumes> = MutableStateFlow(emptyMap())
override val inAudioSharing: Flow<Boolean> = mutableInAudioSharing
+ override val secondaryGroupId: StateFlow<Int> = mutableSecondaryGroupId
+ override val volumeMap: StateFlow<GroupIdToVolumes> = mutableVolumeMap
+
+ override suspend fun setSecondaryVolume(volume: Int) {}
fun setInAudioSharing(state: Boolean) {
mutableInAudioSharing.value = state
}
+
+ fun setSecondaryGroupId(groupId: Int) {
+ mutableSecondaryGroupId.value = groupId
+ }
+
+ fun setVolumeMap(volumeMap: GroupIdToVolumes) {
+ mutableVolumeMap.value = volumeMap
+ }
+
+ private companion object {
+ const val TEST_GROUP_ID_INVALID = -1
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorKosmos.kt
new file mode 100644
index 000000000000..03981bbef444
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.volume.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.volume.data.repository.audioSharingRepository
+
+val Kosmos.audioSharingInteractor by
+ Kosmos.Fixture {
+ AudioSharingInteractorImpl(
+ applicationCoroutineScope,
+ audioSharingRepository,
+ )
+ }
diff --git a/packages/VpnDialogs/res/values-fr-rCA/strings.xml b/packages/VpnDialogs/res/values-fr-rCA/strings.xml
index ad450b4c5f39..9ae0cb24246e 100644
--- a/packages/VpnDialogs/res/values-fr-rCA/strings.xml
+++ b/packages/VpnDialogs/res/values-fr-rCA/strings.xml
@@ -32,7 +32,7 @@
<string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Modifier les paramètres RPV"</string>
<string name="configure" msgid="4905518375574791375">"Configurer"</string>
<string name="disconnect" msgid="971412338304200056">"Déconnecter"</string>
- <string name="open_app" msgid="3717639178595958667">"Ouvrir l\'application"</string>
+ <string name="open_app" msgid="3717639178595958667">"Ouvrir l\'appli"</string>
<string name="dismiss" msgid="6192859333764711227">"Ignorer"</string>
<string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string>
<string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string>
diff --git a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-fr-rCA/strings.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-fr-rCA/strings.xml
index ea0a27b069da..4f922a57d4ad 100644
--- a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-fr-rCA/strings.xml
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-fr-rCA/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"Rendre les applications sous la zone de découpe"</string>
+ <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"Rendre les applis sous la zone de découpe"</string>
</resources>
diff --git a/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java b/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java
index e031eb27513b..8a1fe62db4e1 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java
@@ -30,7 +30,6 @@ public final class Os {
return RavenwoodRuntimeNative.lseek(fd, offset, whence);
}
-
public static FileDescriptor[] pipe2(int flags) throws ErrnoException {
return RavenwoodRuntimeNative.pipe2(flags);
}
@@ -42,4 +41,16 @@ public final class Os {
public static int fcntlInt(FileDescriptor fd, int cmd, int arg) throws ErrnoException {
return RavenwoodRuntimeNative.fcntlInt(fd, cmd, arg);
}
+
+ public static StructStat fstat(FileDescriptor fd) throws ErrnoException {
+ return RavenwoodRuntimeNative.fstat(fd);
+ }
+
+ public static StructStat lstat(String path) throws ErrnoException {
+ return RavenwoodRuntimeNative.lstat(path);
+ }
+
+ public static StructStat stat(String path) throws ErrnoException {
+ return RavenwoodRuntimeNative.stat(path);
+ }
}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/android/system/StructStat.java b/ravenwood/runtime-helper-src/libcore-fake/android/system/StructStat.java
new file mode 100644
index 000000000000..a8b1fca464dd
--- /dev/null
+++ b/ravenwood/runtime-helper-src/libcore-fake/android/system/StructStat.java
@@ -0,0 +1,121 @@
+/*
+ * 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 android.system;
+
+import libcore.util.Objects;
+
+/**
+ * File information returned by {@link Os#fstat}, {@link Os#lstat}, and {@link Os#stat}.
+ * Corresponds to C's {@code struct stat} from {@code <stat.h>}.
+ */
+public final class StructStat {
+ /** Device ID of device containing file. */
+ public final long st_dev; /*dev_t*/
+
+ /** File serial number (inode). */
+ public final long st_ino; /*ino_t*/
+
+ /** Mode (permissions) of file. */
+ public final int st_mode; /*mode_t*/
+
+ /** Number of hard links to the file. */
+ public final long st_nlink; /*nlink_t*/
+
+ /** User ID of file. */
+ public final int st_uid; /*uid_t*/
+
+ /** Group ID of file. */
+ public final int st_gid; /*gid_t*/
+
+ /** Device ID (if file is character or block special). */
+ public final long st_rdev; /*dev_t*/
+
+ /**
+ * For regular files, the file size in bytes.
+ * For symbolic links, the length in bytes of the pathname contained in the symbolic link.
+ * For a shared memory object, the length in bytes.
+ * For a typed memory object, the length in bytes.
+ * For other file types, the use of this field is unspecified.
+ */
+ public final long st_size; /*off_t*/
+
+ /** Seconds part of time of last access. */
+ public final long st_atime; /*time_t*/
+
+ /** StructTimespec with time of last access. */
+ public final StructTimespec st_atim;
+
+ /** Seconds part of time of last data modification. */
+ public final long st_mtime; /*time_t*/
+
+ /** StructTimespec with time of last modification. */
+ public final StructTimespec st_mtim;
+
+ /** Seconds part of time of last status change */
+ public final long st_ctime; /*time_t*/
+
+ /** StructTimespec with time of last status change. */
+ public final StructTimespec st_ctim;
+
+ /**
+ * A file system-specific preferred I/O block size for this object.
+ * For some file system types, this may vary from file to file.
+ */
+ public final long st_blksize; /*blksize_t*/
+
+ /** Number of blocks allocated for this object. */
+ public final long st_blocks; /*blkcnt_t*/
+
+ /**
+ * Constructs an instance with the given field values.
+ */
+ public StructStat(long st_dev, long st_ino, int st_mode, long st_nlink, int st_uid, int st_gid,
+ long st_rdev, long st_size, long st_atime, long st_mtime, long st_ctime,
+ long st_blksize, long st_blocks) {
+ this(st_dev, st_ino, st_mode, st_nlink, st_uid, st_gid,
+ st_rdev, st_size, new StructTimespec(st_atime, 0L), new StructTimespec(st_mtime, 0L),
+ new StructTimespec(st_ctime, 0L), st_blksize, st_blocks);
+ }
+
+ /**
+ * Constructs an instance with the given field values.
+ */
+ public StructStat(long st_dev, long st_ino, int st_mode, long st_nlink, int st_uid, int st_gid,
+ long st_rdev, long st_size, StructTimespec st_atim, StructTimespec st_mtim,
+ StructTimespec st_ctim, long st_blksize, long st_blocks) {
+ this.st_dev = st_dev;
+ this.st_ino = st_ino;
+ this.st_mode = st_mode;
+ this.st_nlink = st_nlink;
+ this.st_uid = st_uid;
+ this.st_gid = st_gid;
+ this.st_rdev = st_rdev;
+ this.st_size = st_size;
+ this.st_atime = st_atim.tv_sec;
+ this.st_mtime = st_mtim.tv_sec;
+ this.st_ctime = st_ctim.tv_sec;
+ this.st_atim = st_atim;
+ this.st_mtim = st_mtim;
+ this.st_ctim = st_ctim;
+ this.st_blksize = st_blksize;
+ this.st_blocks = st_blocks;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/android/system/StructTimespec.java b/ravenwood/runtime-helper-src/libcore-fake/android/system/StructTimespec.java
new file mode 100644
index 000000000000..c10678057eeb
--- /dev/null
+++ b/ravenwood/runtime-helper-src/libcore-fake/android/system/StructTimespec.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import libcore.util.Objects;;
+
+/**
+ * Corresponds to C's {@code struct timespec} from {@code <time.h>}.
+ */
+public final class StructTimespec implements Comparable<StructTimespec> {
+ /** Seconds part of time of last data modification. */
+ public final long tv_sec; /*time_t*/
+
+ /** Nanoseconds (values are [0, 999999999]). */
+ public final long tv_nsec;
+
+ public StructTimespec(long tv_sec, long tv_nsec) {
+ this.tv_sec = tv_sec;
+ this.tv_nsec = tv_nsec;
+ if (tv_nsec < 0 || tv_nsec > 999_999_999) {
+ throw new IllegalArgumentException(
+ "tv_nsec value " + tv_nsec + " is not in [0, 999999999]");
+ }
+ }
+
+ @Override
+ public int compareTo(StructTimespec other) {
+ if (tv_sec > other.tv_sec) {
+ return 1;
+ }
+ if (tv_sec < other.tv_sec) {
+ return -1;
+ }
+ if (tv_nsec > other.tv_nsec) {
+ return 1;
+ }
+ if (tv_nsec < other.tv_nsec) {
+ return -1;
+ }
+ return 0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ StructTimespec that = (StructTimespec) o;
+
+ if (tv_sec != that.tv_sec) return false;
+ return tv_nsec == that.tv_nsec;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (int) (tv_sec ^ (tv_sec >>> 32));
+ result = 31 * result + (int) (tv_nsec ^ (tv_nsec >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodRuntimeNative.java b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/common/RavenwoodRuntimeNative.java
index 65402219ebee..e9b305e5d789 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodRuntimeNative.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/common/RavenwoodRuntimeNative.java
@@ -15,6 +15,9 @@
*/
package com.android.ravenwood.common;
+import android.system.ErrnoException;
+import android.system.StructStat;
+
import java.io.FileDescriptor;
/**
@@ -31,19 +34,25 @@ public class RavenwoodRuntimeNative {
public static native void applyFreeFunction(long freeFunction, long nativePtr);
- public static native long nLseek(int fd, long offset, int whence);
+ private static native long nLseek(int fd, long offset, int whence) throws ErrnoException;
+
+ private static native int[] nPipe2(int flags) throws ErrnoException;
+
+ private static native int nDup(int oldfd) throws ErrnoException;
+
+ private static native int nFcntlInt(int fd, int cmd, int arg) throws ErrnoException;
- public static native int[] nPipe2(int flags);
+ private static native StructStat nFstat(int fd) throws ErrnoException;
- public static native int nDup(int oldfd);
+ public static native StructStat lstat(String path) throws ErrnoException;
- public static native int nFcntlInt(int fd, int cmd, int arg);
+ public static native StructStat stat(String path) throws ErrnoException;
- public static long lseek(FileDescriptor fd, long offset, int whence) {
+ public static long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException {
return nLseek(JvmWorkaround.getInstance().getFdInt(fd), offset, whence);
}
- public static FileDescriptor[] pipe2(int flags) {
+ public static FileDescriptor[] pipe2(int flags) throws ErrnoException {
var fds = nPipe2(flags);
var ret = new FileDescriptor[] {
new FileDescriptor(),
@@ -55,7 +64,7 @@ public class RavenwoodRuntimeNative {
return ret;
}
- public static FileDescriptor dup(FileDescriptor fd) {
+ public static FileDescriptor dup(FileDescriptor fd) throws ErrnoException {
var fdInt = nDup(JvmWorkaround.getInstance().getFdInt(fd));
var retFd = new java.io.FileDescriptor();
@@ -63,9 +72,15 @@ public class RavenwoodRuntimeNative {
return retFd;
}
- public static int fcntlInt(FileDescriptor fd, int cmd, int arg) {
+ public static int fcntlInt(FileDescriptor fd, int cmd, int arg) throws ErrnoException {
var fdInt = JvmWorkaround.getInstance().getFdInt(fd);
return nFcntlInt(fdInt, cmd, arg);
}
+
+ public static StructStat fstat(FileDescriptor fd) throws ErrnoException {
+ var fdInt = JvmWorkaround.getInstance().getFdInt(fd);
+
+ return nFstat(fdInt);
+ }
}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/libcore/util/Objects.java b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/Objects.java
new file mode 100644
index 000000000000..3781fcf4e891
--- /dev/null
+++ b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/Objects.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 libcore.util;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+
+public final class Objects {
+ private Objects() {}
+
+ /**
+ * Returns a string reporting the value of each declared field, via reflection.
+ * Static and transient fields are automatically skipped. Produces output like
+ * "SimpleClassName[integer=1234,string="hello",character='c',intArray=[1,2,3]]".
+ */
+ public static String toString(Object o) {
+ Class<?> c = o.getClass();
+ StringBuilder sb = new StringBuilder();
+ sb.append(c.getSimpleName()).append('[');
+ int i = 0;
+ for (Field f : c.getDeclaredFields()) {
+ if ((f.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) != 0) {
+ continue;
+ }
+ f.setAccessible(true);
+ try {
+ Object value = f.get(o);
+
+ if (i++ > 0) {
+ sb.append(',');
+ }
+
+ sb.append(f.getName());
+ sb.append('=');
+
+ if (value.getClass().isArray()) {
+ if (value.getClass() == boolean[].class) {
+ sb.append(Arrays.toString((boolean[]) value));
+ } else if (value.getClass() == byte[].class) {
+ sb.append(Arrays.toString((byte[]) value));
+ } else if (value.getClass() == char[].class) {
+ sb.append(Arrays.toString((char[]) value));
+ } else if (value.getClass() == double[].class) {
+ sb.append(Arrays.toString((double[]) value));
+ } else if (value.getClass() == float[].class) {
+ sb.append(Arrays.toString((float[]) value));
+ } else if (value.getClass() == int[].class) {
+ sb.append(Arrays.toString((int[]) value));
+ } else if (value.getClass() == long[].class) {
+ sb.append(Arrays.toString((long[]) value));
+ } else if (value.getClass() == short[].class) {
+ sb.append(Arrays.toString((short[]) value));
+ } else {
+ sb.append(Arrays.toString((Object[]) value));
+ }
+ } else if (value.getClass() == Character.class) {
+ sb.append('\'').append(value).append('\'');
+ } else if (value.getClass() == String.class) {
+ sb.append('"').append(value).append('"');
+ } else {
+ sb.append(value);
+ }
+ } catch (IllegalAccessException unexpected) {
+ throw new AssertionError(unexpected);
+ }
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+}
diff --git a/ravenwood/runtime-jni/ravenwood_runtime.cpp b/ravenwood/runtime-jni/ravenwood_runtime.cpp
index 34cf9f915677..e0a3e1c9edf6 100644
--- a/ravenwood/runtime-jni/ravenwood_runtime.cpp
+++ b/ravenwood/runtime-jni/ravenwood_runtime.cpp
@@ -19,6 +19,9 @@
#include <string.h>
#include <unistd.h>
#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+#include <nativehelper/ScopedUtfChars.h>
+
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"
@@ -41,6 +44,75 @@ static rc_t throwIfMinusOne(JNIEnv* env, const char* name, rc_t rc) {
return rc;
}
+// ---- Helper functions ---
+
+static jclass g_StructStat;
+static jclass g_StructTimespecClass;
+
+static jclass findClass(JNIEnv* env, const char* name) {
+ ScopedLocalRef<jclass> localClass(env, env->FindClass(name));
+ jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
+ if (result == NULL) {
+ ALOGE("failed to find class '%s'", name);
+ abort();
+ }
+ return result;
+}
+
+static jobject makeStructTimespec(JNIEnv* env, const struct timespec& ts) {
+ static jmethodID ctor = env->GetMethodID(g_StructTimespecClass, "<init>",
+ "(JJ)V");
+ if (ctor == NULL) {
+ return NULL;
+ }
+ return env->NewObject(g_StructTimespecClass, ctor,
+ static_cast<jlong>(ts.tv_sec), static_cast<jlong>(ts.tv_nsec));
+}
+
+static jobject makeStructStat(JNIEnv* env, const struct stat64& sb) {
+ static jmethodID ctor = env->GetMethodID(g_StructStat, "<init>",
+ "(JJIJIIJJLandroid/system/StructTimespec;Landroid/system/StructTimespec;Landroid/system/StructTimespec;JJ)V");
+ if (ctor == NULL) {
+ return NULL;
+ }
+
+ jobject atim_timespec = makeStructTimespec(env, sb.st_atim);
+ if (atim_timespec == NULL) {
+ return NULL;
+ }
+ jobject mtim_timespec = makeStructTimespec(env, sb.st_mtim);
+ if (mtim_timespec == NULL) {
+ return NULL;
+ }
+ jobject ctim_timespec = makeStructTimespec(env, sb.st_ctim);
+ if (ctim_timespec == NULL) {
+ return NULL;
+ }
+
+ return env->NewObject(g_StructStat, ctor,
+ static_cast<jlong>(sb.st_dev), static_cast<jlong>(sb.st_ino),
+ static_cast<jint>(sb.st_mode), static_cast<jlong>(sb.st_nlink),
+ static_cast<jint>(sb.st_uid), static_cast<jint>(sb.st_gid),
+ static_cast<jlong>(sb.st_rdev), static_cast<jlong>(sb.st_size),
+ atim_timespec, mtim_timespec, ctim_timespec,
+ static_cast<jlong>(sb.st_blksize), static_cast<jlong>(sb.st_blocks));
+}
+
+static jobject doStat(JNIEnv* env, jstring javaPath, bool isLstat) {
+ ScopedUtfChars path(env, javaPath);
+ if (path.c_str() == NULL) {
+ return NULL;
+ }
+ struct stat64 sb;
+ int rc = isLstat ? TEMP_FAILURE_RETRY(lstat64(path.c_str(), &sb))
+ : TEMP_FAILURE_RETRY(stat64(path.c_str(), &sb));
+ if (rc == -1) {
+ throwErrnoException(env, isLstat ? "lstat" : "stat");
+ return NULL;
+ }
+ return makeStructStat(env, sb);
+}
+
// ---- JNI methods ----
typedef void (*FreeFunction)(void*);
@@ -77,6 +149,24 @@ static jlong nDup(JNIEnv* env, jclass, jint fd) {
return throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, F_DUPFD_CLOEXEC, 0)));
}
+static jobject nFstat(JNIEnv* env, jobject, jint fd) {
+ struct stat64 sb;
+ int rc = TEMP_FAILURE_RETRY(fstat64(fd, &sb));
+ if (rc == -1) {
+ throwErrnoException(env, "fstat");
+ return NULL;
+ }
+ return makeStructStat(env, sb);
+}
+
+static jobject Linux_lstat(JNIEnv* env, jobject, jstring javaPath) {
+ return doStat(env, javaPath, true);
+}
+
+static jobject Linux_stat(JNIEnv* env, jobject, jstring javaPath) {
+ return doStat(env, javaPath, false);
+}
+
// ---- Registration ----
static const JNINativeMethod sMethods[] =
@@ -86,6 +176,9 @@ static const JNINativeMethod sMethods[] =
{ "nLseek", "(IJI)J", (void*)nLseek },
{ "nPipe2", "(I)[I", (void*)nPipe2 },
{ "nDup", "(I)I", (void*)nDup },
+ { "nFstat", "(I)Landroid/system/StructStat;", (void*)nFstat },
+ { "lstat", "(Ljava/lang/String;)Landroid/system/StructStat;", (void*)Linux_lstat },
+ { "stat", "(Ljava/lang/String;)Landroid/system/StructStat;", (void*)Linux_stat },
};
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
@@ -101,6 +194,9 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
ALOGI("%s: JNI_OnLoad", __FILE__);
+ g_StructStat = findClass(env, "android/system/StructStat");
+ g_StructTimespecClass = findClass(env, "android/system/StructTimespec");
+
jint res = jniRegisterNativeMethods(env, "com/android/ravenwood/common/RavenwoodRuntimeNative",
sMethods, NELEM(sMethods));
if (res < 0) {
diff --git a/ravenwood/runtime-test/test/com/android/ravenwood/runtimetest/OsTest.java b/ravenwood/runtime-test/test/com/android/ravenwood/runtimetest/OsTest.java
index b5038e68516d..05275b29e48b 100644
--- a/ravenwood/runtime-test/test/com/android/ravenwood/runtimetest/OsTest.java
+++ b/ravenwood/runtime-test/test/com/android/ravenwood/runtimetest/OsTest.java
@@ -15,15 +15,26 @@
*/
package com.android.ravenwood.runtimetest;
+import static android.system.OsConstants.S_ISBLK;
+import static android.system.OsConstants.S_ISCHR;
+import static android.system.OsConstants.S_ISDIR;
+import static android.system.OsConstants.S_ISFIFO;
+import static android.system.OsConstants.S_ISLNK;
+import static android.system.OsConstants.S_ISREG;
+import static android.system.OsConstants.S_ISSOCK;
+
import static org.junit.Assert.assertEquals;
+import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
+
import android.system.Os;
import android.system.OsConstants;
+import android.system.StructStat;
+import android.system.StructTimespec;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.ravenwood.common.JvmWorkaround;
-import com.android.ravenwood.common.RavenwoodRuntimeNative;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -32,8 +43,15 @@ import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.RandomAccessFile;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.PosixFileAttributes;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
public class OsTest {
@@ -41,7 +59,7 @@ public class OsTest {
void accept(T var1) throws Exception;
}
- private void withTestFile(ConsumerWithThrow<FileDescriptor> consumer) throws Exception {
+ private void withTestFileFD(ConsumerWithThrow<FileDescriptor> consumer) throws Exception {
File file = File.createTempFile("osTest", "bin");
try (var raf = new RandomAccessFile(file, "rw")) {
var fd = raf.getFD();
@@ -57,9 +75,20 @@ public class OsTest {
}
}
+ private void withTestFile(ConsumerWithThrow<Path> consumer) throws Exception {
+ var path = Files.createTempFile("osTest", "bin");
+ try (var os = Files.newOutputStream(path)) {
+ os.write(1);
+ os.write(2);
+ os.write(3);
+ os.write(4);
+ }
+ consumer.accept(path);
+ }
+
@Test
public void testLseek() throws Exception {
- withTestFile((fd) -> {
+ withTestFileFD((fd) -> {
assertEquals(4, Os.lseek(fd, 4, OsConstants.SEEK_SET));
assertEquals(4, Os.lseek(fd, 0, OsConstants.SEEK_CUR));
assertEquals(6, Os.lseek(fd, 2, OsConstants.SEEK_CUR));
@@ -68,7 +97,7 @@ public class OsTest {
@Test
public void testDup() throws Exception {
- withTestFile((fd) -> {
+ withTestFileFD((fd) -> {
var dup = Os.dup(fd);
checkAreDup(fd, dup);
@@ -85,7 +114,7 @@ public class OsTest {
@Test
public void testFcntlInt() throws Exception {
- withTestFile((fd) -> {
+ withTestFileFD((fd) -> {
var dupInt = Os.fcntlInt(fd, 0, 0);
var dup = new FileDescriptor();
@@ -95,16 +124,90 @@ public class OsTest {
});
}
- private static void write(FileDescriptor fd, int oneByte) throws IOException {
+ @Test
+ public void testStat() throws Exception {
+ withTestFile(path -> {
+ var attr = Files.readAttributes(path, PosixFileAttributes.class);
+ var stat = Os.stat(path.toAbsolutePath().toString());
+ assertAttributesEqual(attr, stat);
+ });
+ }
+
+ @Test
+ public void testLstat() throws Exception {
+ withTestFile(path -> {
+ // Create a symbolic link
+ var lnk = Files.createTempFile("osTest", "lnk");
+ Files.delete(lnk);
+ Files.createSymbolicLink(lnk, path);
+
+ // Test lstat
+ var attr = Files.readAttributes(lnk, PosixFileAttributes.class, NOFOLLOW_LINKS);
+ var stat = Os.lstat(lnk.toAbsolutePath().toString());
+ assertAttributesEqual(attr, stat);
+
+ // Test stat
+ var followAttr = Files.readAttributes(lnk, PosixFileAttributes.class);
+ var followStat = Os.stat(lnk.toAbsolutePath().toString());
+ assertAttributesEqual(followAttr, followStat);
+ });
+ }
+
+ @Test
+ public void testFstat() throws Exception {
+ withTestFile(path -> {
+ var attr = Files.readAttributes(path, PosixFileAttributes.class);
+ try (var raf = new RandomAccessFile(path.toFile(), "r")) {
+ var fd = raf.getFD();
+ var stat = Os.fstat(fd);
+ assertAttributesEqual(attr, stat);
+ }
+ });
+ }
+
+ // Verify StructStat values from libcore against native JVM PosixFileAttributes
+ private static void assertAttributesEqual(PosixFileAttributes attr, StructStat stat) {
+ assertEquals(attr.lastModifiedTime(), convertTimespecToFileTime(stat.st_mtim));
+ assertEquals(attr.size(), stat.st_size);
+ assertEquals(attr.isDirectory(), S_ISDIR(stat.st_mode));
+ assertEquals(attr.isRegularFile(), S_ISREG(stat.st_mode));
+ assertEquals(attr.isSymbolicLink(), S_ISLNK(stat.st_mode));
+ assertEquals(attr.isOther(), S_ISCHR(stat.st_mode)
+ || S_ISBLK(stat.st_mode) || S_ISFIFO(stat.st_mode) || S_ISSOCK(stat.st_mode));
+ assertEquals(attr.permissions(), convertModeToPosixPerms(stat.st_mode));
+
+ }
+
+ private static FileTime convertTimespecToFileTime(StructTimespec ts) {
+ var nanos = TimeUnit.SECONDS.toNanos(ts.tv_sec);
+ nanos += ts.tv_nsec;
+ return FileTime.from(nanos, TimeUnit.NANOSECONDS);
+ }
+
+ private static Set<PosixFilePermission> convertModeToPosixPerms(int mode) {
+ var set = new HashSet<PosixFilePermission>();
+ if ((mode & OsConstants.S_IRUSR) != 0) set.add(PosixFilePermission.OWNER_READ);
+ if ((mode & OsConstants.S_IWUSR) != 0) set.add(PosixFilePermission.OWNER_WRITE);
+ if ((mode & OsConstants.S_IXUSR) != 0) set.add(PosixFilePermission.OWNER_EXECUTE);
+ if ((mode & OsConstants.S_IRGRP) != 0) set.add(PosixFilePermission.GROUP_READ);
+ if ((mode & OsConstants.S_IWGRP) != 0) set.add(PosixFilePermission.GROUP_WRITE);
+ if ((mode & OsConstants.S_IXGRP) != 0) set.add(PosixFilePermission.GROUP_EXECUTE);
+ if ((mode & OsConstants.S_IROTH) != 0) set.add(PosixFilePermission.OTHERS_READ);
+ if ((mode & OsConstants.S_IWOTH) != 0) set.add(PosixFilePermission.OTHERS_WRITE);
+ if ((mode & OsConstants.S_IXOTH) != 0) set.add(PosixFilePermission.OTHERS_EXECUTE);
+ return set;
+ }
+
+ private static void write(FileDescriptor fd, int oneByte) throws Exception {
// Create a dup to avoid closing the FD.
- try (var dup = new FileOutputStream(RavenwoodRuntimeNative.dup(fd))) {
+ try (var dup = new FileOutputStream(Os.dup(fd))) {
dup.write(oneByte);
}
}
- private static int read(FileDescriptor fd) throws IOException {
+ private static int read(FileDescriptor fd) throws Exception {
// Create a dup to avoid closing the FD.
- try (var dup = new FileInputStream(RavenwoodRuntimeNative.dup(fd))) {
+ try (var dup = new FileInputStream(Os.dup(fd))) {
return dup.read();
}
}
diff --git a/services/Android.bp b/services/Android.bp
index cd974c5f562d..dce6aa71daea 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -186,7 +186,15 @@ art_profile_java_defaults {
// merge all required services into one jar
// ============================================================
-java_library {
+soong_config_module_type {
+ name: "system_java_library",
+ module_type: "java_library",
+ config_namespace: "system_services",
+ bool_variables: ["without_vibrator"],
+ properties: ["vintf_fragments"],
+}
+
+system_java_library {
name: "services",
defaults: [
"services_java_defaults",
@@ -248,9 +256,19 @@ java_library {
"service-sdksandbox.stubs.system_server",
],
- vintf_fragments: [
- "manifest_services.xml",
- ],
+ soong_config_variables: {
+ without_vibrator: {
+ vintf_fragments: [
+ "manifest_services.xml",
+ ],
+ conditions_default: {
+ vintf_fragments: [
+ "manifest_services.xml",
+ "manifest_services_android.frameworks.vibrator.xml",
+ ],
+ },
+ },
+ },
required: [
"libukey2_jni_shared",
diff --git a/services/accessibility/Android.bp b/services/accessibility/Android.bp
index 7a99b605c4fb..311addb90298 100644
--- a/services/accessibility/Android.bp
+++ b/services/accessibility/Android.bp
@@ -29,10 +29,12 @@ java_library_static {
"//frameworks/base/packages/SettingsLib/RestrictedLockUtils:SettingsLibRestrictedLockUtilsSrc",
],
libs: [
+ "aatf",
"services.core",
"androidx.annotation_annotation",
],
static_libs: [
+ "a11ychecker-protos-java-proto-lite",
"com_android_server_accessibility_flags_lib",
"//frameworks/base/packages/SystemUI/aconfig:com_android_systemui_flags_lib",
@@ -68,3 +70,14 @@ java_aconfig_library {
name: "com_android_server_accessibility_flags_lib",
aconfig_declarations: "com_android_server_accessibility_flags",
}
+
+java_library_static {
+ name: "a11ychecker-protos-java-proto-lite",
+ proto: {
+ type: "lite",
+ canonical_path_from_root: false,
+ },
+ srcs: [
+ "java/**/a11ychecker/proto/*.proto",
+ ],
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index d3efa21a2311..099cb2894515 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -26,6 +26,7 @@ import android.annotation.MainThread;
import android.annotation.NonNull;
import android.content.Context;
import android.graphics.Region;
+import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemClock;
import android.provider.Settings;
@@ -158,6 +159,13 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
*/
static final int FLAG_FEATURE_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP = 0x00001000;
+ /**
+ * Flag for enabling the Accessibility mouse key events feature.
+ *
+ * @see #setUserAndEnabledFeatures(int, int)
+ */
+ static final int FLAG_FEATURE_MOUSE_KEYS = 0x00002000;
+
static final int FEATURES_AFFECTING_MOTION_EVENTS =
FLAG_FEATURE_INJECT_MOTION_EVENTS
| FLAG_FEATURE_AUTOCLICK
@@ -189,6 +197,8 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
private KeyboardInterceptor mKeyboardInterceptor;
+ private MouseKeysInterceptor mMouseKeysInterceptor;
+
private boolean mInstalled;
private int mUserId;
@@ -733,6 +743,13 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
// default display.
addFirstEventHandler(Display.DEFAULT_DISPLAY, mKeyboardInterceptor);
}
+
+ if ((mEnabledFeatures & FLAG_FEATURE_MOUSE_KEYS) != 0) {
+ mMouseKeysInterceptor = new MouseKeysInterceptor(mAms,
+ Looper.myLooper(),
+ Display.DEFAULT_DISPLAY);
+ addFirstEventHandler(Display.DEFAULT_DISPLAY, mMouseKeysInterceptor);
+ }
}
/**
@@ -816,6 +833,11 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
mKeyboardInterceptor.onDestroy();
mKeyboardInterceptor = null;
}
+
+ if (mMouseKeysInterceptor != null) {
+ mMouseKeysInterceptor.onDestroy();
+ mMouseKeysInterceptor = null;
+ }
}
private MagnificationGestureHandler createMagnificationGestureHandler(
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 32491b7eb0e0..b918d80fc63d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -57,6 +57,7 @@ import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils
import static com.android.internal.util.FunctionalUtils.ignoreRemoteException;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.server.accessibility.AccessibilityUserState.doesShortcutTargetsStringContain;
+import static com.android.hardware.input.Flags.keyboardA11yMouseKeys;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import android.accessibilityservice.AccessibilityGestureEvent;
@@ -2936,6 +2937,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
if (combinedGenericMotionEventSources != 0) {
flags |= AccessibilityInputFilter.FLAG_FEATURE_INTERCEPT_GENERIC_MOTION_EVENTS;
}
+ if (userState.isMouseKeysEnabled()) {
+ flags |= AccessibilityInputFilter.FLAG_FEATURE_MOUSE_KEYS;
+ }
if (flags != 0) {
if (!mHasInputFilter) {
mHasInputFilter = true;
@@ -3216,6 +3220,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
somethingChanged |= readMagnificationCapabilitiesLocked(userState);
somethingChanged |= readMagnificationFollowTypingLocked(userState);
somethingChanged |= readAlwaysOnMagnificationLocked(userState);
+ somethingChanged |= readMouseKeysEnabledLocked(userState);
return somethingChanged;
}
@@ -5476,6 +5481,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
private final Uri mAlwaysOnMagnificationUri = Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED);
+ private final Uri mMouseKeysUri = Settings.Secure.getUriFor(
+ Settings.Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED);
+
public AccessibilityContentObserver(Handler handler) {
super(handler);
}
@@ -5524,6 +5532,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
mMagnificationFollowTypingUri, false, this, UserHandle.USER_ALL);
contentResolver.registerContentObserver(
mAlwaysOnMagnificationUri, false, this, UserHandle.USER_ALL);
+ contentResolver.registerContentObserver(
+ mMouseKeysUri, false, this, UserHandle.USER_ALL);
}
@Override
@@ -5604,6 +5614,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
readMagnificationFollowTypingLocked(userState);
} else if (mAlwaysOnMagnificationUri.equals(uri)) {
readAlwaysOnMagnificationLocked(userState);
+ } else if (mMouseKeysUri.equals(uri)) {
+ if (readMouseKeysEnabledLocked(userState)) {
+ onUserStateChangedLocked(userState);
+ }
}
}
}
@@ -5742,6 +5756,20 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
return false;
}
+ boolean readMouseKeysEnabledLocked(AccessibilityUserState userState) {
+ if (!keyboardA11yMouseKeys()) {
+ return false;
+ }
+ final boolean isMouseKeysEnabled =
+ Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED, 0, userState.mUserId) == 1;
+ if (isMouseKeysEnabled != userState.isMouseKeysEnabled()) {
+ userState.setMouseKeysEnabled(isMouseKeysEnabled);
+ return true;
+ }
+ return false;
+ }
+
@Override
public void setGestureDetectionPassthroughRegion(int displayId, Region region) {
mMainHandler.sendMessage(
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
index 7bcbc2768a16..3706dccbb717 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
@@ -169,6 +169,8 @@ class AccessibilityUserState {
private final int mFocusStrokeWidthDefaultValue;
// The default value of the focus color.
private final int mFocusColorDefaultValue;
+ /** Whether mouse keys feature is enabled. */
+ private boolean mMouseKeysEnabled = false;
private final Map<ComponentName, ComponentName> mA11yServiceToTileService = new ArrayMap<>();
private final Map<ComponentName, ComponentName> mA11yActivityToTileService = new ArrayMap<>();
@@ -232,6 +234,8 @@ class AccessibilityUserState {
mAccessibilityShortcutKeyTargets.clear();
mAccessibilityButtonTargets.clear();
mAccessibilityGestureTargets.clear();
+ mAccessibilityQsTargets.clear();
+ mA11yTilesInQsPanel.clear();
mTargetAssignedToAccessibilityButton = null;
mIsTouchExplorationEnabled = false;
mServiceHandlesDoubleTap = false;
@@ -674,6 +678,14 @@ class AccessibilityUserState {
mIsFilterKeyEventsEnabled = enabled;
}
+ public void setMouseKeysEnabled(boolean enabled) {
+ mMouseKeysEnabled = enabled;
+ }
+
+ public boolean isMouseKeysEnabled() {
+ return mMouseKeysEnabled;
+ }
+
public int getInteractiveUiTimeoutLocked() {
return mInteractiveUiTimeout;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/MouseKeysInterceptor.java b/services/accessibility/java/com/android/server/accessibility/MouseKeysInterceptor.java
new file mode 100644
index 000000000000..56da231ad31a
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/MouseKeysInterceptor.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright 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.accessibility;
+
+import static android.accessibilityservice.AccessibilityTrace.FLAGS_INPUT_FILTER;
+import static android.util.MathUtils.sqrt;
+
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.companion.virtual.VirtualDeviceManager;
+import android.companion.virtual.VirtualDeviceParams;
+import android.hardware.input.VirtualMouse;
+import android.hardware.input.VirtualMouseButtonEvent;
+import android.hardware.input.VirtualMouseConfig;
+import android.hardware.input.VirtualMouseRelativeEvent;
+import android.hardware.input.VirtualMouseScrollEvent;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.view.KeyEvent;
+
+import com.android.server.LocalServices;
+import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
+
+/**
+ * Implements the "mouse keys" accessibility feature for physical keyboards.
+ *
+ * If enabled, mouse keys will allow users to use a physical keyboard to
+ * control the mouse on the display.
+ * The following mouse functionality is supported by the mouse keys:
+ * <ul>
+ * <li> Move the mouse pointer in different directions (up, down, left, right and diagonally).
+ * <li> Click the mouse button (left, right and middle click).
+ * <li> Press and hold the mouse button.
+ * <li> Release the mouse button.
+ * <li> Scroll (up and down).
+ * </ul>
+ *
+ * The keys that are mapped to mouse keys are consumed by {@link AccessibilityInputFilter}.
+ * Non-mouse key {@link KeyEvent} will be passed to the parent handler to be handled as usual.
+ * A new {@link VirtualMouse} is created whenever the mouse keys feature is turned on in Settings.
+ * In case multiple physical keyboard are connected to a device,
+ * mouse keys of each physical keyboard will control a single (global) mouse pointer.
+ */
+public class MouseKeysInterceptor extends BaseEventStreamTransformation
+ implements Handler.Callback {
+ private static final String LOG_TAG = "MouseKeysInterceptor";
+
+ // To enable these logs, run: 'adb shell setprop log.tag.MouseKeysInterceptor DEBUG'
+ // (requires restart)
+ private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
+
+ private static final int MESSAGE_MOVE_MOUSE_POINTER = 1;
+ private static final int MESSAGE_SCROLL_MOUSE_POINTER = 2;
+ private static final float MOUSE_POINTER_MOVEMENT_STEP = 1.8f;
+ private static final int KEY_NOT_SET = -1;
+
+ /** Time interval after which mouse action will be repeated */
+ private static final int INTERVAL_MILLIS = 10;
+
+ private final AccessibilityManagerService mAms;
+ private final Handler mHandler;
+
+ VirtualDeviceManager.VirtualDevice mVirtualDevice = null;
+
+ private VirtualMouse mVirtualMouse = null;
+
+ /**
+ * State of the active directional mouse key.
+ * Multiple mouse keys will not be allowed to be used simultaneously i.e.,
+ * once a mouse key is pressed, other mouse key presses will be disregarded
+ * (except for when the "HOLD" key is pressed).
+ */
+ private int mActiveMoveKey = KEY_NOT_SET;
+
+ /** State of the active scroll mouse key. */
+ private int mActiveScrollKey = KEY_NOT_SET;
+
+ /** Last time the key action was performed */
+ private long mLastTimeKeyActionPerformed = 0;
+
+ /** Whether scroll toggle is on */
+ private boolean mScrollToggleOn = false;
+
+ public enum MouseKeyEvent {
+ DIAGONAL_UP_LEFT_MOVE(KeyEvent.KEYCODE_7),
+ UP_MOVE_OR_SCROLL(KeyEvent.KEYCODE_8),
+ DIAGONAL_UP_RIGHT_MOVE(KeyEvent.KEYCODE_9),
+ LEFT_MOVE(KeyEvent.KEYCODE_U),
+ RIGHT_MOVE(KeyEvent.KEYCODE_O),
+ DIAGONAL_DOWN_LEFT_MOVE(KeyEvent.KEYCODE_J),
+ DOWN_MOVE_OR_SCROLL(KeyEvent.KEYCODE_K),
+ DIAGONAL_DOWN_RIGHT_MOVE(KeyEvent.KEYCODE_L),
+ LEFT_CLICK(KeyEvent.KEYCODE_I),
+ RIGHT_CLICK(KeyEvent.KEYCODE_SLASH),
+ HOLD(KeyEvent.KEYCODE_M),
+ RELEASE(KeyEvent.KEYCODE_COMMA),
+ SCROLL_TOGGLE(KeyEvent.KEYCODE_PERIOD);
+
+ private final int mKeyCode;
+ MouseKeyEvent(int enumValue) {
+ mKeyCode = enumValue;
+ }
+
+ private static final SparseArray<MouseKeyEvent> VALUE_TO_ENUM_MAP = new SparseArray<>();
+
+ static {
+ for (MouseKeyEvent type : MouseKeyEvent.values()) {
+ VALUE_TO_ENUM_MAP.put(type.mKeyCode, type);
+ }
+ }
+
+ public final int getKeyCodeValue() {
+ return mKeyCode;
+ }
+
+ /**
+ * Convert int value of the key code to corresponding MouseEvent enum. If no matching
+ * value is found, this will return {@code null}.
+ */
+ @Nullable
+ public static MouseKeyEvent from(int value) {
+ return VALUE_TO_ENUM_MAP.get(value);
+ }
+ }
+
+ /**
+ * Construct a new MouseKeysInterceptor.
+ *
+ * @param service The service to notify of key events
+ * @param looper Looper to use for callbacks and messages
+ * @param displayId Display ID to send mouse events to
+ */
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ public MouseKeysInterceptor(AccessibilityManagerService service, Looper looper, int displayId) {
+ mAms = service;
+ mHandler = new Handler(looper, this);
+ // Create the virtual mouse on a separate thread since virtual device creation
+ // should happen on an auxiliary thread, and not from the handler's thread.
+ // This is because virtual device creation is a blocking operation and can cause a
+ // deadlock if it is called from the handler's thread.
+ new Thread(() -> {
+ mVirtualMouse = createVirtualMouse(displayId);
+ }).start();
+
+ }
+
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ private void sendVirtualMouseRelativeEvent(float x, float y) {
+ if (mVirtualMouse != null) {
+ mVirtualMouse.sendRelativeEvent(new VirtualMouseRelativeEvent.Builder()
+ .setRelativeX(x)
+ .setRelativeY(y)
+ .build()
+ );
+ }
+ }
+
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ private void sendVirtualMouseButtonEvent(int buttonCode, int actionCode) {
+ if (mVirtualMouse != null) {
+ mVirtualMouse.sendButtonEvent(new VirtualMouseButtonEvent.Builder()
+ .setAction(actionCode)
+ .setButtonCode(buttonCode)
+ .build()
+ );
+ }
+ }
+
+ /**
+ * Performs a mouse scroll action based on the provided key code.
+ * The scroll action will only be performed if the scroll toggle is on.
+ * This method interprets the key code as a mouse scroll and sends
+ * the corresponding {@code VirtualMouseScrollEvent#mYAxisMovement}.
+
+ * @param keyCode The key code representing the mouse scroll action.
+ * Supported keys are:
+ * <ul>
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#UP_MOVE_OR_SCROLL}
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#DOWN_MOVE_OR_SCROLL}
+ * </ul>
+ */
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ private void performMouseScrollAction(int keyCode) {
+ MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(keyCode);
+ float y = switch (mouseKeyEvent) {
+ case UP_MOVE_OR_SCROLL -> 1.0f;
+ case DOWN_MOVE_OR_SCROLL -> -1.0f;
+ default -> 0.0f;
+ };
+ if (mVirtualMouse != null) {
+ mVirtualMouse.sendScrollEvent(new VirtualMouseScrollEvent.Builder()
+ .setYAxisMovement(y)
+ .build()
+ );
+ }
+ if (DEBUG) {
+ Slog.d(LOG_TAG, "Performed mouse key event: " + mouseKeyEvent.name()
+ + " for scroll action with axis movement (y=" + y + ")");
+ }
+ }
+
+ /**
+ * Performs a mouse button action based on the provided key code.
+ * This method interprets the key code as a mouse button press and sends
+ * the corresponding press and release events to the virtual mouse.
+
+ * @param keyCode The key code representing the mouse button action.
+ * Supported keys are:
+ * <ul>
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#LEFT_CLICK} (Primary Button)
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#RIGHT_CLICK} (Secondary
+ * Button)
+ * </ul>
+ */
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ private void performMouseButtonAction(int keyCode) {
+ MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(keyCode);
+ int buttonCode = switch (mouseKeyEvent) {
+ case LEFT_CLICK -> VirtualMouseButtonEvent.BUTTON_PRIMARY;
+ case RIGHT_CLICK -> VirtualMouseButtonEvent.BUTTON_SECONDARY;
+ default -> VirtualMouseButtonEvent.BUTTON_UNKNOWN;
+ };
+ if (buttonCode != VirtualMouseButtonEvent.BUTTON_UNKNOWN) {
+ sendVirtualMouseButtonEvent(buttonCode, VirtualMouseButtonEvent.ACTION_BUTTON_PRESS);
+ sendVirtualMouseButtonEvent(buttonCode, VirtualMouseButtonEvent.ACTION_BUTTON_RELEASE);
+ }
+ if (DEBUG) {
+ if (buttonCode == VirtualMouseButtonEvent.BUTTON_UNKNOWN) {
+ Slog.d(LOG_TAG, "Button code is unknown for mouse key event: "
+ + mouseKeyEvent.name());
+ } else {
+ Slog.d(LOG_TAG, "Performed mouse key event: " + mouseKeyEvent.name()
+ + " for button action");
+ }
+ }
+ }
+
+ /**
+ * Performs a mouse pointer action based on the provided key code.
+ * The method calculates the relative movement of the mouse pointer
+ * and sends the corresponding event to the virtual mouse.
+ *
+ * The UP and DOWN pointer actions will only take place for their respective keys
+ * if the scroll toggle is off.
+ *
+ * @param keyCode The key code representing the direction or button press.
+ * Supported keys are:
+ * <ul>
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#DIAGONAL_DOWN_LEFT_MOVE}
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#DOWN_MOVE_OR_SCROLL}
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#DIAGONAL_DOWN_RIGHT_MOVE}
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#LEFT_MOVE}
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#RIGHT_MOVE}
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#DIAGONAL_UP_LEFT_MOVE}
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#UP_MOVE_OR_SCROLL}
+ * <li>{@link MouseKeysInterceptor.MouseKeyEvent#DIAGONAL_UP_RIGHT_MOVE}
+ * </ul>
+ */
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ private void performMousePointerAction(int keyCode) {
+ float x = 0f;
+ float y = 0f;
+ MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(keyCode);
+ switch (mouseKeyEvent) {
+ case DIAGONAL_DOWN_LEFT_MOVE -> {
+ x = -MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+ y = MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+ }
+ case DOWN_MOVE_OR_SCROLL -> {
+ if (!mScrollToggleOn) {
+ y = MOUSE_POINTER_MOVEMENT_STEP;
+ }
+ }
+ case DIAGONAL_DOWN_RIGHT_MOVE -> {
+ x = MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+ y = MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+ }
+ case LEFT_MOVE -> {
+ x = -MOUSE_POINTER_MOVEMENT_STEP;
+ }
+ case RIGHT_MOVE -> {
+ x = MOUSE_POINTER_MOVEMENT_STEP;
+ }
+ case DIAGONAL_UP_LEFT_MOVE -> {
+ x = -MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+ y = -MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+ }
+ case UP_MOVE_OR_SCROLL -> {
+ if (!mScrollToggleOn) {
+ y = -MOUSE_POINTER_MOVEMENT_STEP;
+ }
+ }
+ case DIAGONAL_UP_RIGHT_MOVE -> {
+ x = MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+ y = -MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+ }
+ default -> {
+ x = 0.0f;
+ y = 0.0f;
+ }
+ }
+ sendVirtualMouseRelativeEvent(x, y);
+ if (DEBUG) {
+ Slog.d(LOG_TAG, "Performed mouse key event: " + mouseKeyEvent.name()
+ + " for relative pointer movement (x=" + x + ", y=" + y + ")");
+ }
+ }
+
+ private boolean isMouseKey(int keyCode) {
+ return MouseKeyEvent.VALUE_TO_ENUM_MAP.contains(keyCode);
+ }
+
+ private boolean isMouseButtonKey(int keyCode) {
+ return keyCode == MouseKeyEvent.LEFT_CLICK.getKeyCodeValue()
+ || keyCode == MouseKeyEvent.RIGHT_CLICK.getKeyCodeValue();
+ }
+
+ private boolean isMouseScrollKey(int keyCode) {
+ return keyCode == MouseKeyEvent.UP_MOVE_OR_SCROLL.getKeyCodeValue()
+ || keyCode == MouseKeyEvent.DOWN_MOVE_OR_SCROLL.getKeyCodeValue();
+ }
+
+ /**
+ * Create a virtual mouse using the VirtualDeviceManagerInternal.
+ *
+ * @return The created VirtualMouse.
+ */
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ private VirtualMouse createVirtualMouse(int displayId) {
+ final VirtualDeviceManagerInternal localVdm =
+ LocalServices.getService(VirtualDeviceManagerInternal.class);
+ mVirtualDevice = localVdm.createVirtualDevice(
+ new VirtualDeviceParams.Builder().setName("Mouse Keys Virtual Device").build());
+ VirtualMouse virtualMouse = mVirtualDevice.createVirtualMouse(
+ new VirtualMouseConfig.Builder()
+ .setInputDeviceName("Mouse Keys Virtual Mouse")
+ .setAssociatedDisplayId(displayId)
+ .build());
+ return virtualMouse;
+ }
+
+ /**
+ * Handles key events and forwards mouse key events to the virtual mouse.
+ *
+ * @param event The key event to handle.
+ * @param policyFlags The policy flags associated with the key event.
+ */
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ @Override
+ public void onKeyEvent(KeyEvent event, int policyFlags) {
+ if (mAms.getTraceManager().isA11yTracingEnabledForTypes(FLAGS_INPUT_FILTER)) {
+ mAms.getTraceManager().logTrace(LOG_TAG + ".onKeyEvent",
+ FLAGS_INPUT_FILTER, "event=" + event + ";policyFlags=" + policyFlags);
+ }
+ boolean isDown = event.getAction() == KeyEvent.ACTION_DOWN;
+ int keyCode = event.getKeyCode();
+
+ if (!isMouseKey(keyCode)) {
+ // Pass non-mouse key events to the next handler
+ super.onKeyEvent(event, policyFlags);
+ } else if (isDown) {
+ if (keyCode == MouseKeyEvent.SCROLL_TOGGLE.getKeyCodeValue()) {
+ mScrollToggleOn = !mScrollToggleOn;
+ if (DEBUG) {
+ Slog.d(LOG_TAG, "Scroll toggle " + (mScrollToggleOn ? "ON" : "OFF"));
+ }
+ } else if (keyCode == MouseKeyEvent.HOLD.getKeyCodeValue()) {
+ sendVirtualMouseButtonEvent(
+ VirtualMouseButtonEvent.BUTTON_PRIMARY,
+ VirtualMouseButtonEvent.ACTION_BUTTON_PRESS
+ );
+ } else if (keyCode == MouseKeyEvent.RELEASE.getKeyCodeValue()) {
+ sendVirtualMouseButtonEvent(
+ VirtualMouseButtonEvent.BUTTON_PRIMARY,
+ VirtualMouseButtonEvent.ACTION_BUTTON_RELEASE
+ );
+ } else if (isMouseButtonKey(keyCode)) {
+ performMouseButtonAction(keyCode);
+ } else if (mScrollToggleOn && isMouseScrollKey(keyCode)) {
+ // If the scroll key is pressed down and no other key is active,
+ // set it as the active key and send a message to scroll the pointer
+ if (mActiveScrollKey == KEY_NOT_SET) {
+ mActiveScrollKey = keyCode;
+ mLastTimeKeyActionPerformed = event.getDownTime();
+ mHandler.sendEmptyMessage(MESSAGE_SCROLL_MOUSE_POINTER);
+ }
+ } else {
+ // This is a directional key.
+ // If the key is pressed down and no other key is active,
+ // set it as the active key and send a message to move the pointer
+ if (mActiveMoveKey == KEY_NOT_SET) {
+ mActiveMoveKey = keyCode;
+ mLastTimeKeyActionPerformed = event.getDownTime();
+ mHandler.sendEmptyMessage(MESSAGE_MOVE_MOUSE_POINTER);
+ }
+ }
+ } else {
+ // Up event received
+ if (mActiveMoveKey == keyCode) {
+ // If the key is released, and it is the active key, stop moving the pointer
+ mActiveMoveKey = KEY_NOT_SET;
+ mHandler.removeMessages(MESSAGE_MOVE_MOUSE_POINTER);
+ } else if (mActiveScrollKey == keyCode) {
+ // If the key is released, and it is the active key, stop scrolling the pointer
+ mActiveScrollKey = KEY_NOT_SET;
+ mHandler.removeMessages(MESSAGE_SCROLL_MOUSE_POINTER);
+ } else {
+ Slog.i(LOG_TAG, "Dropping event with key code: '" + keyCode
+ + "', with no matching down event from deviceId = " + event.getDeviceId());
+ }
+ }
+ }
+
+ /**
+ * Handle messages for moving or scrolling the mouse pointer.
+ *
+ * @param msg The message to handle.
+ * @return True if the message was handled, false otherwise.
+ */
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ @Override
+ public boolean handleMessage(Message msg) {
+ switch (msg.what) {
+ case MESSAGE_MOVE_MOUSE_POINTER ->
+ handleMouseMessage(msg.getWhen(), mActiveMoveKey, MESSAGE_MOVE_MOUSE_POINTER);
+ case MESSAGE_SCROLL_MOUSE_POINTER ->
+ handleMouseMessage(msg.getWhen(), mActiveScrollKey,
+ MESSAGE_SCROLL_MOUSE_POINTER);
+ default -> {
+ Slog.e(LOG_TAG, "Unexpected message type");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Handles mouse-related messages for moving or scrolling the mouse pointer.
+ * This method checks if the specified time interval {@code INTERVAL_MILLIS} has passed since
+ * the last movement or scroll action and performs the corresponding action if necessary.
+ * If there is an active key, the message is rescheduled to be handled again
+ * after the specified {@code INTERVAL_MILLIS}.
+ *
+ * @param currentTime The current time when the message is being handled.
+ * @param activeKey The key code representing the active key. This determines
+ * the direction or type of action to be performed.
+ * @param messageType The type of message to be handled. It can be one of the
+ * following:
+ * <ul>
+ * <li>{@link #MESSAGE_MOVE_MOUSE_POINTER} - for moving the mouse pointer.
+ * <li>{@link #MESSAGE_SCROLL_MOUSE_POINTER} - for scrolling mouse pointer.
+ * </ul>
+ */
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ public void handleMouseMessage(long currentTime, int activeKey, int messageType) {
+ if (currentTime - mLastTimeKeyActionPerformed >= INTERVAL_MILLIS) {
+ if (messageType == MESSAGE_MOVE_MOUSE_POINTER) {
+ performMousePointerAction(activeKey);
+ } else if (messageType == MESSAGE_SCROLL_MOUSE_POINTER) {
+ performMouseScrollAction(activeKey);
+ }
+ mLastTimeKeyActionPerformed = currentTime;
+ }
+ if (activeKey != KEY_NOT_SET) {
+ // Reschedule the message if the key is still active
+ mHandler.sendEmptyMessageDelayed(messageType, INTERVAL_MILLIS);
+ }
+ }
+
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ @Override
+ public void onDestroy() {
+ // Clear mouse state
+ mActiveMoveKey = KEY_NOT_SET;
+ mActiveScrollKey = KEY_NOT_SET;
+ mLastTimeKeyActionPerformed = 0;
+
+ mHandler.removeCallbacksAndMessages(null);
+ mVirtualDevice.close();
+ }
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerUtils.java b/services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerUtils.java
new file mode 100644
index 000000000000..55af9a0cfd24
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerUtils.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 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.accessibility.a11ychecker;
+
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.util.Slog;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckClass;
+import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckResultReported;
+import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckResultType;
+
+import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult;
+import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheck;
+import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheckResult;
+import com.google.android.apps.common.testing.accessibility.framework.checks.ClassNameCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.ClickableSpanCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.DuplicateClickableBoundsCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.DuplicateSpeakableTextCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.EditableContentDescCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.ImageContrastCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.LinkPurposeUnclearCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.RedundantDescriptionCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.SpeakableTextPresentCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.TextContrastCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.TextSizeCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.TouchTargetSizeCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.TraversalOrderCheck;
+
+import java.util.AbstractMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Util class to process a11y checker results for logging.
+ *
+ * @hide
+ */
+public class AccessibilityCheckerUtils {
+
+ private static final String LOG_TAG = "AccessibilityCheckerUtils";
+ @VisibleForTesting
+ // LINT.IfChange
+ static final Map<Class<? extends AccessibilityHierarchyCheck>, AccessibilityCheckClass>
+ CHECK_CLASS_TO_ENUM_MAP =
+ Map.ofEntries(
+ classMapEntry(ClassNameCheck.class, AccessibilityCheckClass.CLASS_NAME_CHECK),
+ classMapEntry(ClickableSpanCheck.class,
+ AccessibilityCheckClass.CLICKABLE_SPAN_CHECK),
+ classMapEntry(DuplicateClickableBoundsCheck.class,
+ AccessibilityCheckClass.DUPLICATE_CLICKABLE_BOUNDS_CHECK),
+ classMapEntry(DuplicateSpeakableTextCheck.class,
+ AccessibilityCheckClass.DUPLICATE_SPEAKABLE_TEXT_CHECK),
+ classMapEntry(EditableContentDescCheck.class,
+ AccessibilityCheckClass.EDITABLE_CONTENT_DESC_CHECK),
+ classMapEntry(ImageContrastCheck.class,
+ AccessibilityCheckClass.IMAGE_CONTRAST_CHECK),
+ classMapEntry(LinkPurposeUnclearCheck.class,
+ AccessibilityCheckClass.LINK_PURPOSE_UNCLEAR_CHECK),
+ classMapEntry(RedundantDescriptionCheck.class,
+ AccessibilityCheckClass.REDUNDANT_DESCRIPTION_CHECK),
+ classMapEntry(SpeakableTextPresentCheck.class,
+ AccessibilityCheckClass.SPEAKABLE_TEXT_PRESENT_CHECK),
+ classMapEntry(TextContrastCheck.class,
+ AccessibilityCheckClass.TEXT_CONTRAST_CHECK),
+ classMapEntry(TextSizeCheck.class, AccessibilityCheckClass.TEXT_SIZE_CHECK),
+ classMapEntry(TouchTargetSizeCheck.class,
+ AccessibilityCheckClass.TOUCH_TARGET_SIZE_CHECK),
+ classMapEntry(TraversalOrderCheck.class,
+ AccessibilityCheckClass.TRAVERSAL_ORDER_CHECK));
+ // LINT.ThenChange(/services/accessibility/java/com/android/server/accessibility/a11ychecker/proto/a11ychecker.proto)
+
+ static Set<AccessibilityCheckResultReported> processResults(
+ Context context,
+ AccessibilityNodeInfo nodeInfo,
+ List<AccessibilityHierarchyCheckResult> checkResults,
+ @Nullable AccessibilityEvent accessibilityEvent,
+ ComponentName a11yServiceComponentName) {
+ return processResults(nodeInfo, checkResults, accessibilityEvent,
+ context.getPackageManager(), a11yServiceComponentName);
+ }
+
+ @VisibleForTesting
+ static Set<AccessibilityCheckResultReported> processResults(
+ AccessibilityNodeInfo nodeInfo,
+ List<AccessibilityHierarchyCheckResult> checkResults,
+ @Nullable AccessibilityEvent accessibilityEvent,
+ PackageManager packageManager,
+ ComponentName a11yServiceComponentName) {
+ String appPackageName = nodeInfo.getPackageName().toString();
+ AccessibilityCheckResultReported.Builder builder;
+ try {
+ builder = AccessibilityCheckResultReported.newBuilder()
+ .setPackageName(appPackageName)
+ .setAppVersionCode(getAppVersionCode(packageManager, appPackageName))
+ .setUiElementPath(AccessibilityNodePathBuilder.createNodePath(nodeInfo))
+ .setActivityName(getActivityName(packageManager, accessibilityEvent))
+ .setWindowTitle(getWindowTitle(nodeInfo))
+ .setSourceComponentName(a11yServiceComponentName.flattenToString())
+ .setSourceVersionCode(
+ getAppVersionCode(packageManager,
+ a11yServiceComponentName.getPackageName()));
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(LOG_TAG, "Unknown package name", e);
+ return Set.of();
+ }
+
+ return checkResults.stream()
+ .filter(checkResult -> checkResult.getType()
+ == AccessibilityCheckResult.AccessibilityCheckResultType.ERROR
+ || checkResult.getType()
+ == AccessibilityCheckResult.AccessibilityCheckResultType.WARNING)
+ .map(checkResult -> builder.setResultCheckClass(
+ getCheckClass(checkResult)).setResultType(
+ getCheckResultType(checkResult)).setResultId(
+ checkResult.getResultId()).build())
+ .collect(Collectors.toUnmodifiableSet());
+ }
+
+ private static long getAppVersionCode(PackageManager packageManager, String packageName) throws
+ PackageManager.NameNotFoundException {
+ PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0);
+ return packageInfo.getLongVersionCode();
+ }
+
+ /**
+ * Returns the simple class name of the Activity providing the cache update, if available,
+ * or an empty String if not.
+ */
+ @VisibleForTesting
+ static String getActivityName(
+ PackageManager packageManager, @Nullable AccessibilityEvent accessibilityEvent) {
+ if (accessibilityEvent == null) {
+ return "";
+ }
+ CharSequence activityName = accessibilityEvent.getClassName();
+ if (accessibilityEvent.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
+ && accessibilityEvent.getPackageName() != null
+ && activityName != null) {
+ try {
+ // Check class is for a valid Activity.
+ packageManager
+ .getActivityInfo(
+ new ComponentName(accessibilityEvent.getPackageName().toString(),
+ activityName.toString()), 0);
+ int qualifierEnd = activityName.toString().lastIndexOf('.');
+ return activityName.toString().substring(qualifierEnd + 1);
+ } catch (PackageManager.NameNotFoundException e) {
+ // No need to spam the logs. This is very frequent when the class doesn't match
+ // an activity.
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Returns the title of the window containing the a11y node.
+ */
+ private static String getWindowTitle(AccessibilityNodeInfo nodeInfo) {
+ if (nodeInfo.getWindow() == null) {
+ return "";
+ }
+ CharSequence windowTitle = nodeInfo.getWindow().getTitle();
+ return windowTitle == null ? "" : windowTitle.toString();
+ }
+
+ /**
+ * Maps the {@link AccessibilityHierarchyCheck} class that produced the given result, with the
+ * corresponding {@link AccessibilityCheckClass} enum. This enumeration is to avoid relying on
+ * String class names in the logging, which can be proguarded. It also reduces the logging size.
+ */
+ private static AccessibilityCheckClass getCheckClass(
+ AccessibilityHierarchyCheckResult checkResult) {
+ if (CHECK_CLASS_TO_ENUM_MAP.containsKey(checkResult.getSourceCheckClass())) {
+ return CHECK_CLASS_TO_ENUM_MAP.get(checkResult.getSourceCheckClass());
+ }
+ return AccessibilityCheckClass.UNKNOWN_CHECK;
+ }
+
+ private static AccessibilityCheckResultType getCheckResultType(
+ AccessibilityHierarchyCheckResult checkResult) {
+ return switch (checkResult.getType()) {
+ case ERROR -> AccessibilityCheckResultType.ERROR;
+ case WARNING -> AccessibilityCheckResultType.WARNING;
+ default -> AccessibilityCheckResultType.UNKNOWN_RESULT_TYPE;
+ };
+ }
+
+ private static Map.Entry<Class<? extends AccessibilityHierarchyCheck>,
+ AccessibilityCheckClass> classMapEntry(
+ Class<? extends AccessibilityHierarchyCheck> checkClass,
+ AccessibilityCheckClass checkClassEnum) {
+ return new AbstractMap.SimpleImmutableEntry<>(checkClass, checkClassEnum);
+ }
+}
diff --git a/core/java/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilder.java b/services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityNodePathBuilder.java
index 2996ddef6f64..bbfb217d925e 100644
--- a/core/java/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilder.java
+++ b/services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityNodePathBuilder.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view.accessibility.a11ychecker;
+package com.android.server.accessibility.a11ychecker;
import android.annotation.NonNull;
import android.annotation.Nullable;
diff --git a/core/java/android/view/accessibility/a11ychecker/OWNERS b/services/accessibility/java/com/android/server/accessibility/a11ychecker/OWNERS
index d1e7986cc209..d1e7986cc209 100644
--- a/core/java/android/view/accessibility/a11ychecker/OWNERS
+++ b/services/accessibility/java/com/android/server/accessibility/a11ychecker/OWNERS
diff --git a/services/accessibility/java/com/android/server/accessibility/a11ychecker/proto/a11ychecker.proto b/services/accessibility/java/com/android/server/accessibility/a11ychecker/proto/a11ychecker.proto
new file mode 100644
index 000000000000..8beed4afa9cb
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/a11ychecker/proto/a11ychecker.proto
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+syntax = "proto2";
+package android.accessibility;
+
+option java_package = "com.android.server.accessibility.a11ychecker";
+option java_outer_classname = "A11yCheckerProto";
+
+// TODO(b/326385939): remove and replace usage with the atom extension proto, when submitted.
+/** Logs the result of an AccessibilityCheck. */
+message AccessibilityCheckResultReported {
+ // Package name of the app containing the checked View.
+ optional string package_name = 1;
+ // Version code of the app containing the checked View.
+ optional int64 app_version_code = 2;
+ // The path of the View starting from the root element in the window. Each element is
+ // represented by the View's resource id, when available, or the View's class name.
+ optional string ui_element_path = 3;
+ // Class name of the activity containing the checked View.
+ optional string activity_name = 4;
+ // Title of the window containing the checked View.
+ optional string window_title = 5;
+ // The flattened component name of the app running the AccessibilityService which provided the a11y node.
+ optional string source_component_name = 6;
+ // Version code of the app running the AccessibilityService that provided the a11y node.
+ optional int64 source_version_code = 7;
+ // Class Name of the AccessibilityCheck that produced the result.
+ optional AccessibilityCheckClass result_check_class = 8;
+ // Result type of the AccessibilityCheckResult.
+ optional AccessibilityCheckResultType result_type = 9;
+ // Result ID of the AccessibilityCheckResult.
+ optional int32 result_id = 10;
+}
+
+/** The AccessibilityCheck class. */
+// LINT.IfChange
+enum AccessibilityCheckClass {
+ UNKNOWN_CHECK = 0;
+ CLASS_NAME_CHECK = 1;
+ CLICKABLE_SPAN_CHECK = 2;
+ DUPLICATE_CLICKABLE_BOUNDS_CHECK = 3;
+ DUPLICATE_SPEAKABLE_TEXT_CHECK = 4;
+ EDITABLE_CONTENT_DESC_CHECK = 5;
+ IMAGE_CONTRAST_CHECK = 6;
+ LINK_PURPOSE_UNCLEAR_CHECK = 7;
+ REDUNDANT_DESCRIPTION_CHECK = 8;
+ SPEAKABLE_TEXT_PRESENT_CHECK = 9;
+ TEXT_CONTRAST_CHECK = 10;
+ TEXT_SIZE_CHECK = 11;
+ TOUCH_TARGET_SIZE_CHECK = 12;
+ TRAVERSAL_ORDER_CHECK = 13;
+}
+// LINT.ThenChange(/services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerUtils.java)
+
+/** The type of AccessibilityCheckResult */
+enum AccessibilityCheckResultType {
+ UNKNOWN_RESULT_TYPE = 0;
+ ERROR = 1;
+ WARNING = 2;
+}
diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
index d7da2f0052d3..026c69c2378c 100644
--- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
@@ -846,7 +846,6 @@ public final class PresentationStatsEventLogger {
mCallingAppUid,
event.mIsCredentialRequest,
event.mWebviewRequestedCredential,
- event.mFilteredFillabaleViewCount,
event.mViewFillableTotalCount,
event.mViewFillFailureCount,
event.mFocusedId,
@@ -859,7 +858,8 @@ public final class PresentationStatsEventLogger {
event.mSuggestionPresentedLastTimestampMs,
event.mFocusedVirtualAutofillId,
event.mFieldFirstLength,
- event.mFieldLastLength);
+ event.mFieldLastLength,
+ event.mFilteredFillabaleViewCount);
mEventInternal = Optional.empty();
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 2e9a4dcb45aa..a10039f9bf6c 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -462,7 +462,9 @@ public final class AutoFillUI {
@Override
public void onShown() {
- mCallback.onShown(UI_TYPE_DIALOG, response.getDatasets().size());
+ if (mCallback != null) {
+ mCallback.onShown(UI_TYPE_DIALOG, response.getDatasets().size());
+ }
}
@Override
@@ -511,7 +513,9 @@ public final class AutoFillUI {
@Override
public void startIntentSender(IntentSender intentSender) {
- mCallback.startIntentSenderAndFinishSession(intentSender);
+ if (mCallback != null) {
+ mCallback.startIntentSenderAndFinishSession(intentSender);
+ }
}
private void log(int type) {
diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
index 4860a274cfa8..8abbe5666d58 100644
--- a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
+++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
@@ -792,10 +792,11 @@ public class TarBackupReader {
}
private String getVToUAllowlist(Context context, int userId) {
- return Settings.Secure.getStringForUser(
+ String allowlist = Settings.Secure.getStringForUser(
context.getContentResolver(),
Settings.Secure.V_TO_U_RESTORE_ALLOWLIST,
userId);
+ return (allowlist == null) ? "" : allowlist;
}
private static long extractRadix(byte[] data, int offset, int maxChars, int radix)
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index 657e261a345f..7d9d660af536 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -1349,14 +1349,14 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
private boolean shouldShowBlockedActivityDialog(ComponentName blockedComponent,
ComponentName blockedAppStreamingActivityComponent) {
- if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
- return true;
- }
if (Objects.equals(blockedComponent, blockedAppStreamingActivityComponent)) {
// Do not show the dialog if it was blocked for some reason already to avoid
// infinite blocking loop.
return false;
}
+ if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+ return true;
+ }
// Do not show the dialog if disabled by policy.
return getDevicePolicy(POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR) == DEVICE_POLICY_DEFAULT;
}
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 1cd20ed0f7cd..9d4310c21cf9 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -215,6 +215,7 @@ java_library_static {
"power_hint_flags_lib",
"biometrics_flags_lib",
"am_flags_lib",
+ "updates_flags_lib",
"com_android_server_accessibility_flags_lib",
"//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
"com_android_wm_shell_flags_lib",
diff --git a/services/core/java/com/android/server/CertBlacklister.java b/services/core/java/com/android/server/CertBlocklister.java
index e726c6abfac3..9e23f884f4ba 100644
--- a/services/core/java/com/android/server/CertBlacklister.java
+++ b/services/core/java/com/android/server/CertBlocklister.java
@@ -16,37 +16,39 @@
package com.android.server;
-import android.content.Context;
import android.content.ContentResolver;
+import android.content.Context;
import android.database.ContentObserver;
import android.os.Binder;
import android.os.FileUtils;
import android.provider.Settings;
import android.util.Slog;
+import libcore.io.IoUtils;
+
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import libcore.io.IoUtils;
-
/**
- * <p>CertBlacklister provides a simple mechanism for updating the platform denylists for SSL
+ * <p>CertBlocklister provides a simple mechanism for updating the platform denylists for SSL
* certificate public keys and serial numbers.
*/
-public class CertBlacklister extends Binder {
+public class CertBlocklister extends Binder {
- private static final String TAG = "CertBlacklister";
+ private static final String TAG = "CertBlocklister";
private static final String DENYLIST_ROOT = System.getenv("ANDROID_DATA") + "/misc/keychain/";
+ /* For compatibility reasons, the name of these paths cannot be changed */
public static final String PUBKEY_PATH = DENYLIST_ROOT + "pubkey_blacklist.txt";
public static final String SERIAL_PATH = DENYLIST_ROOT + "serial_blacklist.txt";
- public static final String PUBKEY_BLACKLIST_KEY = "pubkey_blacklist";
- public static final String SERIAL_BLACKLIST_KEY = "serial_blacklist";
+ /* For compatibility reasons, the name of these keys cannot be changed */
+ public static final String PUBKEY_BLOCKLIST_KEY = "pubkey_blacklist";
+ public static final String SERIAL_BLOCKLIST_KEY = "serial_blacklist";
- private static class BlacklistObserver extends ContentObserver {
+ private static class BlocklistObserver extends ContentObserver {
private final String mKey;
private final String mName;
@@ -54,7 +56,7 @@ public class CertBlacklister extends Binder {
private final File mTmpDir;
private final ContentResolver mContentResolver;
- public BlacklistObserver(String key, String name, String path, ContentResolver cr) {
+ BlocklistObserver(String key, String name, String path, ContentResolver cr) {
super(null);
mKey = key;
mName = name;
@@ -66,59 +68,61 @@ public class CertBlacklister extends Binder {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
- writeDenylist();
+ new Thread("BlocklistUpdater") {
+ public void run() {
+ writeDenylist();
+ }
+ }.start();
}
public String getValue() {
- return Settings.Secure.getString(mContentResolver, mKey);
+ return Settings.Secure.getStringForUser(
+ mContentResolver, mKey, mContentResolver.getUserId());
}
private void writeDenylist() {
- new Thread("BlacklistUpdater") {
- public void run() {
- synchronized(mTmpDir) {
- String blacklist = getValue();
- if (blacklist != null) {
- Slog.i(TAG, "Certificate blacklist changed, updating...");
- FileOutputStream out = null;
- try {
- // create a temporary file
- File tmp = File.createTempFile("journal", "", mTmpDir);
- // mark it -rw-r--r--
- tmp.setReadable(true, false);
- // write to it
- out = new FileOutputStream(tmp);
- out.write(blacklist.getBytes());
- // sync to disk
- FileUtils.sync(out);
- // atomic rename
- tmp.renameTo(new File(mPath));
- Slog.i(TAG, "Certificate blacklist updated");
- } catch (IOException e) {
- Slog.e(TAG, "Failed to write blacklist", e);
- } finally {
- IoUtils.closeQuietly(out);
- }
- }
- }
+ synchronized (mTmpDir) {
+ String blocklist = getValue();
+ if (blocklist == null) {
+ return;
}
- }.start();
+ if (mPath.equals(SERIAL_PATH)) {
+ Slog.w(TAG, "The certificate blocklist based on serials is deprecated. "
+ + "Please use the pubkey blocklist instead.");
+ }
+ Slog.i(TAG, "Certificate blocklist changed, updating...");
+ FileOutputStream out = null;
+ try {
+ // Create a temporary file and rename it atomically.
+ File tmp = File.createTempFile("journal", "", mTmpDir);
+ tmp.setReadable(true /* readable */, false /* ownerOnly */);
+ out = new FileOutputStream(tmp);
+ out.write(blocklist.getBytes());
+ FileUtils.sync(out);
+ tmp.renameTo(new File(mPath));
+ Slog.i(TAG, "Certificate blocklist updated");
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to write blocklist", e);
+ } finally {
+ IoUtils.closeQuietly(out);
+ }
+ }
}
}
- public CertBlacklister(Context context) {
+ public CertBlocklister(Context context) {
registerObservers(context.getContentResolver());
}
- private BlacklistObserver buildPubkeyObserver(ContentResolver cr) {
- return new BlacklistObserver(PUBKEY_BLACKLIST_KEY,
+ private BlocklistObserver buildPubkeyObserver(ContentResolver cr) {
+ return new BlocklistObserver(PUBKEY_BLOCKLIST_KEY,
"pubkey",
PUBKEY_PATH,
cr);
}
- private BlacklistObserver buildSerialObserver(ContentResolver cr) {
- return new BlacklistObserver(SERIAL_BLACKLIST_KEY,
+ private BlocklistObserver buildSerialObserver(ContentResolver cr) {
+ return new BlocklistObserver(SERIAL_BLOCKLIST_KEY,
"serial",
SERIAL_PATH,
cr);
@@ -127,16 +131,16 @@ public class CertBlacklister extends Binder {
private void registerObservers(ContentResolver cr) {
// set up the public key denylist observer
cr.registerContentObserver(
- Settings.Secure.getUriFor(PUBKEY_BLACKLIST_KEY),
- true,
- buildPubkeyObserver(cr)
+ Settings.Secure.getUriFor(PUBKEY_BLOCKLIST_KEY),
+ true,
+ buildPubkeyObserver(cr)
);
// set up the serial number denylist observer
cr.registerContentObserver(
- Settings.Secure.getUriFor(SERIAL_BLACKLIST_KEY),
- true,
- buildSerialObserver(cr)
+ Settings.Secure.getUriFor(SERIAL_BLOCKLIST_KEY),
+ true,
+ buildSerialObserver(cr)
);
}
}
diff --git a/services/core/java/com/android/server/ExplicitHealthCheckController.java b/services/core/java/com/android/server/ExplicitHealthCheckController.java
index 3d610d3747c9..6a6aea49f6f2 100644
--- a/services/core/java/com/android/server/ExplicitHealthCheckController.java
+++ b/services/core/java/com/android/server/ExplicitHealthCheckController.java
@@ -15,6 +15,7 @@
*/
package com.android.server;
+import static android.crashrecovery.flags.Flags.refactorCrashrecovery;
import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_HEALTH_CHECK_PASSED_PACKAGE;
import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_REQUESTED_PACKAGES;
import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_SUPPORTED_PACKAGES;
@@ -41,7 +42,6 @@ import android.util.ArraySet;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
import java.util.Collection;
import java.util.Collections;
@@ -363,22 +363,34 @@ class ExplicitHealthCheckController {
@GuardedBy("mLock")
@Nullable
private ServiceInfo getServiceInfoLocked() {
- final String packageName =
- mContext.getPackageManager().getServicesSystemSharedLibraryPackageName();
- if (packageName == null) {
- Slog.w(TAG, "no external services package!");
- return null;
- }
+ if (refactorCrashrecovery()) {
+ final Intent intent = new Intent(ExplicitHealthCheckService.SERVICE_INTERFACE);
+ final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
+ PackageManager.GET_SERVICES | PackageManager.GET_META_DATA
+ | PackageManager.MATCH_SYSTEM_ONLY);
+ if (resolveInfo == null || resolveInfo.serviceInfo == null) {
+ Slog.w(TAG, "No valid components found.");
+ return null;
+ }
+ return resolveInfo.serviceInfo;
+ } else {
+ final String packageName =
+ mContext.getPackageManager().getServicesSystemSharedLibraryPackageName();
+ if (packageName == null) {
+ Slog.w(TAG, "no external services package!");
+ return null;
+ }
- final Intent intent = new Intent(ExplicitHealthCheckService.SERVICE_INTERFACE);
- intent.setPackage(packageName);
- final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
- PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
- if (resolveInfo == null || resolveInfo.serviceInfo == null) {
- Slog.w(TAG, "No valid components found.");
- return null;
+ final Intent intent = new Intent(ExplicitHealthCheckService.SERVICE_INTERFACE);
+ intent.setPackage(packageName);
+ final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
+ PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+ if (resolveInfo == null || resolveInfo.serviceInfo == null) {
+ Slog.w(TAG, "No valid components found.");
+ return null;
+ }
+ return resolveInfo.serviceInfo;
}
- return resolveInfo.serviceInfo;
}
@GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index c4d38e46da3c..a2bbff026b95 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -48,3 +48,6 @@ per-file VcnManagementService.java = file:/services/core/java/com/android/server
# SystemConfig
per-file SystemConfig.java = file:/PACKAGE_MANAGER_OWNERS
+
+# CertBlocklister
+per-file Cert*.java = tweek@google.com, brambonne@google.com, prb@google.com, miguelaranda@google.com
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index eb037095c6c9..d42a3dc9b6b3 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -16,13 +16,18 @@
package com.android.server;
+import static android.content.Intent.ACTION_REBOOT;
+import static android.content.Intent.ACTION_SHUTDOWN;
import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
@@ -2001,6 +2006,31 @@ public class PackageWatchdog {
}
}
}
+ }
+
+ /**
+ * Register broadcast receiver for shutdown.
+ * We would save the observer state to persist across boots.
+ *
+ * @hide
+ */
+ public void registerShutdownBroadcastReceiver() {
+ BroadcastReceiver shutdownEventReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Only write if intent is relevant to device reboot or shutdown.
+ String intentAction = intent.getAction();
+ if (ACTION_REBOOT.equals(intentAction)
+ || ACTION_SHUTDOWN.equals(intentAction)) {
+ writeNow();
+ }
+ }
+ };
+ // Setup receiver for device reboots or shutdowns.
+ IntentFilter filter = new IntentFilter(ACTION_REBOOT);
+ filter.addAction(ACTION_SHUTDOWN);
+ mContext.registerReceiverForAllUsers(shutdownEventReceiver, filter, null,
+ /* run on main thread */ null);
}
}
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index dfd148dfc0ec..c2cb5e90ca58 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -241,12 +241,14 @@ public class RescueParty {
* opportunity to reset any settings depending on our rescue level.
*/
public static void onSettingsProviderPublished(Context context) {
- handleNativeRescuePartyResets();
- ContentResolver contentResolver = context.getContentResolver();
- DeviceConfig.setMonitorCallback(
- contentResolver,
- Executors.newSingleThreadExecutor(),
- new RescuePartyMonitorCallback(context));
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ handleNativeRescuePartyResets();
+ ContentResolver contentResolver = context.getContentResolver();
+ DeviceConfig.setMonitorCallback(
+ contentResolver,
+ Executors.newSingleThreadExecutor(),
+ new RescuePartyMonitorCallback(context));
+ }
}
@@ -256,75 +258,81 @@ public class RescueParty {
* on modules of newer versions.
*/
public static void resetDeviceConfigForPackages(List<String> packageNames) {
- if (packageNames == null) {
- return;
- }
- Set<String> namespacesToReset = new ArraySet<String>();
- Iterator<String> it = packageNames.iterator();
- RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstanceIfCreated();
- // Get runtime package to namespace mapping if created.
- if (rescuePartyObserver != null) {
- while (it.hasNext()) {
- String packageName = it.next();
- Set<String> runtimeAffectedNamespaces =
- rescuePartyObserver.getAffectedNamespaceSet(packageName);
- if (runtimeAffectedNamespaces != null) {
- namespacesToReset.addAll(runtimeAffectedNamespaces);
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ if (packageNames == null) {
+ return;
+ }
+ Set<String> namespacesToReset = new ArraySet<String>();
+ Iterator<String> it = packageNames.iterator();
+ RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstanceIfCreated();
+ // Get runtime package to namespace mapping if created.
+ if (rescuePartyObserver != null) {
+ while (it.hasNext()) {
+ String packageName = it.next();
+ Set<String> runtimeAffectedNamespaces =
+ rescuePartyObserver.getAffectedNamespaceSet(packageName);
+ if (runtimeAffectedNamespaces != null) {
+ namespacesToReset.addAll(runtimeAffectedNamespaces);
+ }
}
}
- }
- // Get preset package to namespace mapping if created.
- Set<String> presetAffectedNamespaces = getPresetNamespacesForPackages(
- packageNames);
- if (presetAffectedNamespaces != null) {
- namespacesToReset.addAll(presetAffectedNamespaces);
- }
+ // Get preset package to namespace mapping if created.
+ Set<String> presetAffectedNamespaces = getPresetNamespacesForPackages(
+ packageNames);
+ if (presetAffectedNamespaces != null) {
+ namespacesToReset.addAll(presetAffectedNamespaces);
+ }
- // Clear flags under the namespaces mapped to these packages.
- // Using setProperties since DeviceConfig.resetToDefaults bans the current flag set.
- Iterator<String> namespaceIt = namespacesToReset.iterator();
- while (namespaceIt.hasNext()) {
- String namespaceToReset = namespaceIt.next();
- Properties properties = new Properties.Builder(namespaceToReset).build();
- try {
- if (!DeviceConfig.setProperties(properties)) {
- logCriticalInfo(Log.ERROR, "Failed to clear properties under "
+ // Clear flags under the namespaces mapped to these packages.
+ // Using setProperties since DeviceConfig.resetToDefaults bans the current flag set.
+ Iterator<String> namespaceIt = namespacesToReset.iterator();
+ while (namespaceIt.hasNext()) {
+ String namespaceToReset = namespaceIt.next();
+ Properties properties = new Properties.Builder(namespaceToReset).build();
+ try {
+ if (!DeviceConfig.setProperties(properties)) {
+ logCriticalInfo(Log.ERROR, "Failed to clear properties under "
+ namespaceToReset
+ ". Running `device_config get_sync_disabled_for_tests` will confirm"
+ " if config-bulk-update is enabled.");
+ }
+ } catch (DeviceConfig.BadConfigException exception) {
+ logCriticalInfo(Log.WARN, "namespace " + namespaceToReset
+ + " is already banned, skip reset.");
}
- } catch (DeviceConfig.BadConfigException exception) {
- logCriticalInfo(Log.WARN, "namespace " + namespaceToReset
- + " is already banned, skip reset.");
}
}
}
private static Set<String> getPresetNamespacesForPackages(List<String> packageNames) {
Set<String> resultSet = new ArraySet<String>();
- try {
- String flagVal = DeviceConfig.getString(NAMESPACE_CONFIGURATION,
- NAMESPACE_TO_PACKAGE_MAPPING_FLAG, "");
- String[] mappingEntries = flagVal.split(",");
- for (int i = 0; i < mappingEntries.length; i++) {
- if (TextUtils.isEmpty(mappingEntries[i])) {
- continue;
- }
- String[] splittedEntry = mappingEntries[i].split(":");
- if (splittedEntry.length != 2) {
- throw new RuntimeException("Invalid mapping entry: " + mappingEntries[i]);
- }
- String namespace = splittedEntry[0];
- String packageName = splittedEntry[1];
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ try {
+ String flagVal = DeviceConfig.getString(NAMESPACE_CONFIGURATION,
+ NAMESPACE_TO_PACKAGE_MAPPING_FLAG, "");
+ String[] mappingEntries = flagVal.split(",");
+ for (int i = 0; i < mappingEntries.length; i++) {
+ if (TextUtils.isEmpty(mappingEntries[i])) {
+ continue;
+ }
+ String[] splitEntry = mappingEntries[i].split(":");
+ if (splitEntry.length != 2) {
+ throw new RuntimeException("Invalid mapping entry: " + mappingEntries[i]);
+ }
+ String namespace = splitEntry[0];
+ String packageName = splitEntry[1];
- if (packageNames.contains(packageName)) {
- resultSet.add(namespace);
+ if (packageNames.contains(packageName)) {
+ resultSet.add(namespace);
+ }
}
+ } catch (Exception e) {
+ resultSet.clear();
+ Slog.e(TAG, "Failed to read preset package to namespaces mapping.", e);
+ } finally {
+ return resultSet;
}
- } catch (Exception e) {
- resultSet.clear();
- Slog.e(TAG, "Failed to read preset package to namespaces mapping.", e);
- } finally {
+ } else {
return resultSet;
}
}
@@ -342,43 +350,54 @@ public class RescueParty {
}
public void onNamespaceUpdate(@NonNull String updatedNamespace) {
- startObservingPackages(mContext, updatedNamespace);
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ startObservingPackages(mContext, updatedNamespace);
+ }
}
public void onDeviceConfigAccess(@NonNull String callingPackage,
@NonNull String namespace) {
- RescuePartyObserver.getInstance(mContext).recordDeviceConfigAccess(
- callingPackage,
- namespace);
+
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ RescuePartyObserver.getInstance(mContext).recordDeviceConfigAccess(
+ callingPackage,
+ namespace);
+ }
}
}
private static void startObservingPackages(Context context, @NonNull String updatedNamespace) {
- RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstance(context);
- Set<String> callingPackages = rescuePartyObserver.getCallingPackagesSet(updatedNamespace);
- if (callingPackages == null) {
- return;
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstance(context);
+ Set<String> callingPackages = rescuePartyObserver.getCallingPackagesSet(
+ updatedNamespace);
+ if (callingPackages == null) {
+ return;
+ }
+ List<String> callingPackageList = new ArrayList<>();
+ callingPackageList.addAll(callingPackages);
+ Slog.i(TAG, "Starting to observe: " + callingPackageList + ", updated namespace: "
+ + updatedNamespace);
+ PackageWatchdog.getInstance(context).startObservingHealth(
+ rescuePartyObserver,
+ callingPackageList,
+ DEFAULT_OBSERVING_DURATION_MS);
}
- List<String> callingPackageList = new ArrayList<>();
- callingPackageList.addAll(callingPackages);
- Slog.i(TAG, "Starting to observe: " + callingPackageList + ", updated namespace: "
- + updatedNamespace);
- PackageWatchdog.getInstance(context).startObservingHealth(
- rescuePartyObserver,
- callingPackageList,
- DEFAULT_OBSERVING_DURATION_MS);
}
private static void handleNativeRescuePartyResets() {
- if (SettingsToPropertiesMapper.isNativeFlagsResetPerformed()) {
- String[] resetNativeCategories = SettingsToPropertiesMapper.getResetNativeCategories();
- for (int i = 0; i < resetNativeCategories.length; i++) {
- // Don't let RescueParty reset the namespace for RescueParty switches.
- if (NAMESPACE_CONFIGURATION.equals(resetNativeCategories[i])) {
- continue;
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ if (SettingsToPropertiesMapper.isNativeFlagsResetPerformed()) {
+ String[] resetNativeCategories =
+ SettingsToPropertiesMapper.getResetNativeCategories();
+ for (int i = 0; i < resetNativeCategories.length; i++) {
+ // Don't let RescueParty reset the namespace for RescueParty switches.
+ if (NAMESPACE_CONFIGURATION.equals(resetNativeCategories[i])) {
+ continue;
+ }
+ DeviceConfig.resetToDefaults(DEVICE_CONFIG_RESET_MODE,
+ resetNativeCategories[i]);
}
- DeviceConfig.resetToDefaults(DEVICE_CONFIG_RESET_MODE,
- resetNativeCategories[i]);
}
}
}
@@ -400,6 +419,13 @@ public class RescueParty {
}
}
+ private static int getMaxRescueLevel() {
+ if (!SystemProperties.getBoolean(PROP_DISABLE_FACTORY_RESET_FLAG, false)) {
+ return Level.factoryReset();
+ }
+ return Level.reboot();
+ }
+
/**
* Get the rescue level to perform if this is the n-th attempt at mitigating failure.
*
@@ -409,19 +435,30 @@ public class RescueParty {
* @return the rescue level for the n-th mitigation attempt.
*/
private static int getRescueLevel(int mitigationCount, boolean mayPerformReboot) {
- if (mitigationCount == 1) {
- return LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS;
- } else if (mitigationCount == 2) {
- return LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES;
- } else if (mitigationCount == 3) {
- return LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS;
- } else if (mitigationCount == 4) {
- return Math.min(getMaxRescueLevel(mayPerformReboot), LEVEL_WARM_REBOOT);
- } else if (mitigationCount >= 5) {
- return Math.min(getMaxRescueLevel(mayPerformReboot), LEVEL_FACTORY_RESET);
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ if (mitigationCount == 1) {
+ return LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS;
+ } else if (mitigationCount == 2) {
+ return LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES;
+ } else if (mitigationCount == 3) {
+ return LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS;
+ } else if (mitigationCount == 4) {
+ return Math.min(getMaxRescueLevel(mayPerformReboot), LEVEL_WARM_REBOOT);
+ } else if (mitigationCount >= 5) {
+ return Math.min(getMaxRescueLevel(mayPerformReboot), LEVEL_FACTORY_RESET);
+ } else {
+ Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount);
+ return LEVEL_NONE;
+ }
} else {
- Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount);
- return LEVEL_NONE;
+ if (mitigationCount == 1) {
+ return Level.reboot();
+ } else if (mitigationCount >= 2) {
+ return Math.min(getMaxRescueLevel(), Level.factoryReset());
+ } else {
+ Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount);
+ return LEVEL_NONE;
+ }
}
}
@@ -451,13 +488,13 @@ public class RescueParty {
return Math.min(getMaxRescueLevel(mayPerformReboot), RESCUE_LEVEL_WARM_REBOOT);
} else if (mitigationCount == 4) {
return Math.min(getMaxRescueLevel(mayPerformReboot),
- RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS);
+ RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS);
} else if (mitigationCount == 5) {
return Math.min(getMaxRescueLevel(mayPerformReboot),
- RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES);
+ RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES);
} else if (mitigationCount == 6) {
return Math.min(getMaxRescueLevel(mayPerformReboot),
- RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS);
+ RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS);
} else if (mitigationCount >= 7) {
return Math.min(getMaxRescueLevel(mayPerformReboot), RESCUE_LEVEL_FACTORY_RESET);
} else {
@@ -465,6 +502,22 @@ public class RescueParty {
}
}
+ /**
+ * Get the rescue level to perform if this is the n-th attempt at mitigating failure.
+ *
+ * @param mitigationCount the mitigation attempt number (1 = first attempt etc.).
+ * @return the rescue level for the n-th mitigation attempt.
+ */
+ private static @RescueLevels int getRescueLevel(int mitigationCount) {
+ if (mitigationCount == 1) {
+ return Level.reboot();
+ } else if (mitigationCount >= 2) {
+ return Math.min(getMaxRescueLevel(), Level.factoryReset());
+ } else {
+ return Level.none();
+ }
+ }
+
private static void executeRescueLevel(Context context, @Nullable String failedPackage,
int level) {
Slog.w(TAG, "Attempting rescue level " + levelToString(level));
@@ -537,13 +590,22 @@ public class RescueParty {
executeWarmReboot(context, level, failedPackage);
break;
case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS:
- resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS, level);
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS,
+ level);
+ }
break;
case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES:
- resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_CHANGES, level);
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_CHANGES,
+ level);
+ }
break;
case RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS:
- resetAllSettingsIfNecessary(context, Settings.RESET_MODE_TRUSTED_DEFAULTS, level);
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ resetAllSettingsIfNecessary(context, Settings.RESET_MODE_TRUSTED_DEFAULTS,
+ level);
+ }
break;
case RESCUE_LEVEL_FACTORY_RESET:
// Before the completion of Reboot, if any crash happens then PackageWatchdog
@@ -560,6 +622,12 @@ public class RescueParty {
private static void executeWarmReboot(Context context, int level,
@Nullable String failedPackage) {
+ if (Flags.deprecateFlagsAndSettingsResets()) {
+ if (shouldThrottleReboot()) {
+ return;
+ }
+ }
+
// Request the reboot from a separate thread to avoid deadlock on PackageWatchdog
// when device shutting down.
setRebootProperty(true);
@@ -579,6 +647,11 @@ public class RescueParty {
private static void executeFactoryReset(Context context, int level,
@Nullable String failedPackage) {
+ if (Flags.deprecateFlagsAndSettingsResets()) {
+ if (shouldThrottleReboot()) {
+ return;
+ }
+ }
setFactoryResetProperty(true);
long now = System.currentTimeMillis();
setLastFactoryResetTimeMs(now);
@@ -655,30 +728,32 @@ public class RescueParty {
private static void resetAllSettingsIfNecessary(Context context, int mode,
int level) throws Exception {
- // No need to reset Settings again if they are already reset in the current level once.
- if (getMaxRescueLevelAttempted() >= level) {
- return;
- }
- setMaxRescueLevelAttempted(level);
- // Try our best to reset all settings possible, and once finished
- // rethrow any exception that we encountered
- Exception res = null;
- final ContentResolver resolver = context.getContentResolver();
- try {
- Settings.Global.resetToDefaultsAsUser(resolver, null, mode,
- UserHandle.SYSTEM.getIdentifier());
- } catch (Exception e) {
- res = new RuntimeException("Failed to reset global settings", e);
- }
- for (int userId : getAllUserIds()) {
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ // No need to reset Settings again if they are already reset in the current level once.
+ if (getMaxRescueLevelAttempted() >= level) {
+ return;
+ }
+ setMaxRescueLevelAttempted(level);
+ // Try our best to reset all settings possible, and once finished
+ // rethrow any exception that we encountered
+ Exception res = null;
+ final ContentResolver resolver = context.getContentResolver();
try {
- Settings.Secure.resetToDefaultsAsUser(resolver, null, mode, userId);
+ Settings.Global.resetToDefaultsAsUser(resolver, null, mode,
+ UserHandle.SYSTEM.getIdentifier());
} catch (Exception e) {
- res = new RuntimeException("Failed to reset secure settings for " + userId, e);
+ res = new RuntimeException("Failed to reset global settings", e);
+ }
+ for (int userId : getAllUserIds()) {
+ try {
+ Settings.Secure.resetToDefaultsAsUser(resolver, null, mode, userId);
+ } catch (Exception e) {
+ res = new RuntimeException("Failed to reset secure settings for " + userId, e);
+ }
+ }
+ if (res != null) {
+ throw res;
}
- }
- if (res != null) {
- throw res;
}
}
@@ -728,18 +803,28 @@ public class RescueParty {
@Override
public int onHealthCheckFailed(@Nullable VersionedPackage failedPackage,
@FailureReasons int failureReason, int mitigationCount) {
+ int impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
if (!isDisabled() && (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH
|| failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING)) {
if (Flags.recoverabilityDetection()) {
- return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
- mayPerformReboot(failedPackage), failedPackage));
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ impact = mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
+ mayPerformReboot(failedPackage), failedPackage));
+ } else {
+ impact = mapRescueLevelToUserImpact(getRescueLevel(mitigationCount));
+ }
} else {
- return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
- mayPerformReboot(failedPackage)));
+ impact = mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
+ mayPerformReboot(failedPackage)));
}
- } else {
- return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
}
+
+ Slog.i(TAG, "Checking available remediations for health check failure."
+ + " failedPackage: "
+ + (failedPackage == null ? null : failedPackage.getPackageName())
+ + " failureReason: " + failureReason
+ + " available impact: " + impact);
+ return impact;
}
@Override
@@ -748,12 +833,24 @@ public class RescueParty {
if (isDisabled()) {
return false;
}
+ Slog.i(TAG, "Executing remediation."
+ + " failedPackage: "
+ + (failedPackage == null ? null : failedPackage.getPackageName())
+ + " failureReason: " + failureReason
+ + " mitigationCount: " + mitigationCount);
if (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH
|| failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING) {
- final int level = Flags.recoverabilityDetection() ? getRescueLevel(mitigationCount,
- mayPerformReboot(failedPackage), failedPackage)
- : getRescueLevel(mitigationCount,
- mayPerformReboot(failedPackage));
+ final int level;
+ if (Flags.recoverabilityDetection()) {
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ level = getRescueLevel(mitigationCount, mayPerformReboot(failedPackage),
+ failedPackage);
+ } else {
+ level = getRescueLevel(mitigationCount);
+ }
+ } else {
+ level = getRescueLevel(mitigationCount, mayPerformReboot(failedPackage));
+ }
executeRescueLevel(mContext,
failedPackage == null ? null : failedPackage.getPackageName(), level);
return true;
@@ -787,8 +884,12 @@ public class RescueParty {
return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
}
if (Flags.recoverabilityDetection()) {
- return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
- true, /*failedPackage=*/ null));
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
+ true, /*failedPackage=*/ null));
+ } else {
+ return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount));
+ }
} else {
return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount, true));
}
@@ -800,9 +901,17 @@ public class RescueParty {
return false;
}
boolean mayPerformReboot = !shouldThrottleReboot();
- final int level = Flags.recoverabilityDetection() ? getRescueLevel(mitigationCount,
- mayPerformReboot, /*failedPackage=*/ null)
- : getRescueLevel(mitigationCount, mayPerformReboot);
+ final int level;
+ if (Flags.recoverabilityDetection()) {
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ level = getRescueLevel(mitigationCount, mayPerformReboot,
+ /*failedPackage=*/ null);
+ } else {
+ level = getRescueLevel(mitigationCount);
+ }
+ } else {
+ level = getRescueLevel(mitigationCount, mayPerformReboot);
+ }
executeRescueLevel(mContext, /*failedPackage=*/ null, level);
return true;
}
@@ -828,18 +937,6 @@ public class RescueParty {
return isPersistentSystemApp(failingPackage.getPackageName());
}
- /**
- * Returns {@code true} if Rescue Party is allowed to attempt a reboot or factory reset.
- * Will return {@code false} if a factory reset was already offered recently.
- */
- private boolean shouldThrottleReboot() {
- Long lastResetTime = getLastFactoryResetTimeMs();
- long now = System.currentTimeMillis();
- long throttleDurationMin = SystemProperties.getLong(PROP_THROTTLE_DURATION_MIN_FLAG,
- DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN);
- return now < lastResetTime + TimeUnit.MINUTES.toMillis(throttleDurationMin);
- }
-
private boolean isPersistentSystemApp(@NonNull String packageName) {
PackageManager pm = mContext.getPackageManager();
try {
@@ -852,20 +949,22 @@ public class RescueParty {
private synchronized void recordDeviceConfigAccess(@NonNull String callingPackage,
@NonNull String namespace) {
- // Record it in calling packages to namespace map
- Set<String> namespaceSet = mCallingPackageNamespaceSetMap.get(callingPackage);
- if (namespaceSet == null) {
- namespaceSet = new ArraySet<>();
- mCallingPackageNamespaceSetMap.put(callingPackage, namespaceSet);
- }
- namespaceSet.add(namespace);
- // Record it in namespace to calling packages map
- Set<String> callingPackageSet = mNamespaceCallingPackageSetMap.get(namespace);
- if (callingPackageSet == null) {
- callingPackageSet = new ArraySet<>();
+ if (!Flags.deprecateFlagsAndSettingsResets()) {
+ // Record it in calling packages to namespace map
+ Set<String> namespaceSet = mCallingPackageNamespaceSetMap.get(callingPackage);
+ if (namespaceSet == null) {
+ namespaceSet = new ArraySet<>();
+ mCallingPackageNamespaceSetMap.put(callingPackage, namespaceSet);
+ }
+ namespaceSet.add(namespace);
+ // Record it in namespace to calling packages map
+ Set<String> callingPackageSet = mNamespaceCallingPackageSetMap.get(namespace);
+ if (callingPackageSet == null) {
+ callingPackageSet = new ArraySet<>();
+ }
+ callingPackageSet.add(callingPackage);
+ mNamespaceCallingPackageSetMap.put(namespace, callingPackageSet);
}
- callingPackageSet.add(callingPackage);
- mNamespaceCallingPackageSetMap.put(namespace, callingPackageSet);
}
private synchronized Set<String> getAffectedNamespaceSet(String failedPackage) {
@@ -881,6 +980,18 @@ public class RescueParty {
}
}
+ /**
+ * Returns {@code true} if Rescue Party is allowed to attempt a reboot or factory reset.
+ * Will return {@code false} if a factory reset was already offered recently.
+ */
+ private static boolean shouldThrottleReboot() {
+ Long lastResetTime = getLastFactoryResetTimeMs();
+ long now = System.currentTimeMillis();
+ long throttleDurationMin = SystemProperties.getLong(PROP_THROTTLE_DURATION_MIN_FLAG,
+ DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN);
+ return now < lastResetTime + TimeUnit.MINUTES.toMillis(throttleDurationMin);
+ }
+
private static int[] getAllUserIds() {
int systemUserId = UserHandle.SYSTEM.getIdentifier();
int[] userIds = { systemUserId };
@@ -919,6 +1030,22 @@ public class RescueParty {
}
}
+ private static class Level {
+ static int none() {
+ return Flags.recoverabilityDetection() ? RESCUE_LEVEL_NONE : LEVEL_NONE;
+ }
+
+ static int reboot() {
+ return Flags.recoverabilityDetection() ? RESCUE_LEVEL_WARM_REBOOT : LEVEL_WARM_REBOOT;
+ }
+
+ static int factoryReset() {
+ return Flags.recoverabilityDetection()
+ ? RESCUE_LEVEL_FACTORY_RESET
+ : LEVEL_FACTORY_RESET;
+ }
+ }
+
private static String levelToString(int level) {
if (Flags.recoverabilityDetection()) {
switch (level) {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index bc83a0edd918..3633d0f9dd6f 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -921,8 +921,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
//helper function to determine if limit on num listeners applies to callingUid
private boolean doesLimitApplyForListeners(int callingUid, int exemptUid) {
- return (callingUid != Process.SYSTEM_UID
- && callingUid != Process.PHONE_UID
+ return (!TelephonyPermissions.isSystemOrPhone(callingUid)
&& callingUid != exemptUid);
}
@@ -2990,7 +2989,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
// Always redact location info from PhysicalChannelConfig if the registrant is from neither
// PHONE nor SYSTEM process. There is no user case that the registrant needs the location
// info (e.g. physicalCellId). This also remove the need for the location permissions check.
- return record.callerUid != Process.PHONE_UID && record.callerUid != Process.SYSTEM_UID;
+ return !TelephonyPermissions.isSystemOrPhone(record.callerUid);
}
/**
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 21947bac137b..95dbaae2c43b 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -1016,6 +1016,7 @@ public class Watchdog implements Dumpable {
// Trigger the kernel to dump all blocked threads, and backtraces on all CPUs to the
// kernel log
doSysRq('w');
+ doSysRq('m');
doSysRq('l');
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index ac9ed0da95a5..2d913311dae9 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -185,6 +185,12 @@ public class AccountManagerService
final Context mContext;
+ private static final int[] INTERESTING_APP_OPS = new int[] {
+ AppOpsManager.OP_GET_ACCOUNTS,
+ AppOpsManager.OP_READ_CONTACTS,
+ AppOpsManager.OP_WRITE_CONTACTS,
+ };
+
private final PackageManager mPackageManager;
private final AppOpsManager mAppOpsManager;
private UserManager mUserManager;
@@ -388,74 +394,47 @@ public class AccountManagerService
}.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
// Cancel account request notification if an app op was preventing the account access
- mAppOpsManager.startWatchingMode(AppOpsManager.OP_GET_ACCOUNTS, null,
- new AppOpsManager.OnOpChangedInternalListener() {
- @Override
- public void onOpChanged(int op, String packageName) {
- try {
- final int userId = ActivityManager.getCurrentUser();
- final int uid = mPackageManager.getPackageUidAsUser(packageName, userId);
- final int mode = mAppOpsManager.checkOpNoThrow(
- AppOpsManager.OP_GET_ACCOUNTS, uid, packageName);
- if (mode == AppOpsManager.MODE_ALLOWED) {
- final long identity = Binder.clearCallingIdentity();
- try {
- UserAccounts accounts = getUserAccounts(userId);
- cancelAccountAccessRequestNotificationIfNeeded(
- packageName, uid, true, accounts);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- } catch (NameNotFoundException e) {
- /* ignore */
- } catch (SQLiteCantOpenDatabaseException e) {
- Log.w(TAG, "Can't read accounts database", e);
- return;
- }
- }
- });
+ for (int i = 0; i < INTERESTING_APP_OPS.length; ++i) {
+ mAppOpsManager.startWatchingMode(INTERESTING_APP_OPS[i], null,
+ new OnInterestingAppOpChangedListener());
+ }
- // Cancel account request notification if a permission was preventing the account access
- mPackageManager.addOnPermissionsChangeListener(
- (int uid) -> {
- // Permission changes cause requires updating accounts cache.
+ // Clear the accounts cache on permission changes.
+ // The specific permissions we care about are backed by AppOps, so just
+ // let the change events on those handle clearing any notifications.
+ mPackageManager.addOnPermissionsChangeListener((int uid) -> {
AccountManager.invalidateLocalAccountsDataCaches();
+ });
+ }
- Account[] accounts = null;
- String[] packageNames = mPackageManager.getPackagesForUid(uid);
- if (packageNames != null) {
- final int userId = UserHandle.getUserId(uid);
- final long identity = Binder.clearCallingIdentity();
- try {
- for (String packageName : packageNames) {
- // if app asked for permission we need to cancel notification even
- // for O+ applications.
- if (mPackageManager.checkPermission(
- Manifest.permission.GET_ACCOUNTS,
- packageName) != PackageManager.PERMISSION_GRANTED) {
- continue;
- }
+ private class OnInterestingAppOpChangedListener implements AppOpsManager.OnOpChangedListener {
+ @Override
+ public void onOpChanged(String op, String packageName) {
+ final int userId = ActivityManager.getCurrentUser();
+ final int packageUid;
+ try {
+ packageUid = mPackageManager.getPackageUidAsUser(packageName, userId);
+ } catch (NameNotFoundException e) {
+ /* ignore */
+ return;
+ }
- if (accounts == null) {
- accounts = getAccountsOrEmptyArray(null, userId, "android");
- if (ArrayUtils.isEmpty(accounts)) {
- return;
- }
- }
- UserAccounts userAccounts = getUserAccounts(UserHandle.getUserId(uid));
- for (Account account : accounts) {
- cancelAccountAccessRequestNotificationIfNeeded(
- account, uid, packageName, true, userAccounts);
- }
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ final int mode = mAppOpsManager.checkOpNoThrow(op, packageUid, packageName);
+ if (mode != AppOpsManager.MODE_ALLOWED) {
+ return;
}
- });
- }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ cancelAccountAccessRequestNotificationIfNeeded(
+ packageName, packageUid, true, getUserAccounts(userId));
+ } catch (SQLiteCantOpenDatabaseException e) {
+ Log.w(TAG, "Can't read accounts database", e);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
boolean getBindInstantServiceAllowed(int userId) {
return mAuthenticatorCache.getBindInstantServiceAllowed(userId);
@@ -1233,6 +1212,10 @@ public class AccountManagerService
obsoleteAuthType.add(type);
// And delete it from the TABLE_META
accountsDb.deleteMetaByAuthTypeAndUid(type, uid);
+ } else if (knownUid != null && knownUid != uid) {
+ Slog.w(TAG, "authenticator no longer exist for type " + type);
+ obsoleteAuthType.add(type);
+ accountsDb.deleteMetaByAuthTypeAndUid(type, uid);
}
}
}
@@ -5048,6 +5031,9 @@ public class AccountManagerService
if (resolveInfo == null) {
return false;
}
+ if ("content".equals(intent.getScheme())) {
+ return false;
+ }
ActivityInfo targetActivityInfo = resolveInfo.activityInfo;
int targetUid = targetActivityInfo.applicationInfo.uid;
PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 25fb729e7e7c..69ee8fc831f4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -72,6 +72,7 @@ import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageManager.SIGNATURE_NO_MATCH;
+import static android.crashrecovery.flags.Flags.refactorCrashrecovery;
import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
import static android.os.FactoryTest.FACTORY_TEST_OFF;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
@@ -2075,7 +2076,8 @@ public class ActivityManagerService extends IActivityManager.Stub
app.setPersistent(true);
app.setPid(MY_PID);
app.mState.setMaxAdj(ProcessList.SYSTEM_ADJ);
- app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
+ app.makeActive(new ApplicationThreadDeferred(mSystemThread.getApplicationThread()),
+ mProcessStats);
app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_SYSTEM);
addPidLocked(app);
updateLruProcessLocked(app, false, null);
@@ -2322,7 +2324,9 @@ public class ActivityManagerService extends IActivityManager.Stub
} else if (phase == PHASE_ACTIVITY_MANAGER_READY) {
mService.startBroadcastObservers();
} else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
- mService.mPackageWatchdog.onPackagesReady();
+ if (!refactorCrashrecovery()) {
+ mService.mPackageWatchdog.onPackagesReady();
+ }
mService.scheduleHomeTimeout();
}
}
@@ -4871,7 +4875,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// Make app active after binding application or client may be running requests (e.g
// starting activities) before it is ready.
synchronized (mProcLock) {
- app.makeActive(thread, mProcessStats);
+ app.makeActive(new ApplicationThreadDeferred(thread), mProcessStats);
checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
}
app.setPendingFinishAttach(true);
diff --git a/services/core/java/com/android/server/am/ApplicationThreadDeferred.java b/services/core/java/com/android/server/am/ApplicationThreadDeferred.java
new file mode 100644
index 000000000000..b0f9b53ff525
--- /dev/null
+++ b/services/core/java/com/android/server/am/ApplicationThreadDeferred.java
@@ -0,0 +1,173 @@
+/*
+ * 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.am;
+
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.annotation.IntDef;
+import android.app.IApplicationThread;
+import android.os.RemoteException;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+
+/**
+ * A subclass of {@link IApplicationThread} that defers certain binder calls while the process is
+ * paused (frozen). Any deferred calls are executed when the process is unpaused. In some cases,
+ * multiple instances of deferred calls are collapsed into a single call when the process is
+ * unpaused.
+ *
+ * {@hide}
+ */
+class ApplicationThreadDeferred extends ApplicationThreadFilter {
+
+ static final String TAG = TAG_WITH_CLASS_NAME ? "ApplicationThreadDeferred" : TAG_AM;
+
+ // The flag that enables the deferral behavior of this class. If the flag is disabled then
+ // the class behaves exactly like an ApplicationThreadFilter.
+ private static boolean deferBindersWhenPaused() {
+ return Flags.deferBindersWhenPaused();
+ }
+
+ // The list of notifications that may be deferred.
+ private static final int CLEAR_DNS_CACHE = 0;
+ private static final int UPDATE_TIME_ZONE = 1;
+ private static final int SCHEDULE_LOW_MEMORY = 2;
+ private static final int UPDATE_HTTP_PROXY = 3;
+ private static final int NOTIFICATION_COUNT = 4;
+
+ @IntDef(value = {
+ CLEAR_DNS_CACHE,
+ UPDATE_TIME_ZONE,
+ SCHEDULE_LOW_MEMORY,
+ UPDATE_HTTP_PROXY
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface NotificationType {};
+
+ private final Object mLock = new Object();
+
+ // If this is true, notifications should be queued for later delivery. If this is false,
+ // notifications should be delivered immediately.
+ @GuardedBy("mLock")
+ private boolean mPaused = false;
+
+ // An operation is a lambda that throws an exception.
+ private interface Operation {
+ void run() throws RemoteException;
+ }
+
+ // The array of operations.
+ @GuardedBy("mLock")
+ private final Operation[] mOperations = new Operation[NOTIFICATION_COUNT];
+
+ // The array of operations that actually pending right now.
+ @GuardedBy("mLock")
+ private final boolean[] mPending = new boolean[NOTIFICATION_COUNT];
+
+ // When true, binder calls to paused processes will be deferred until the process is unpaused.
+ private final boolean mDefer;
+
+ /** Create an instance with a base thread and a deferral enable flag. */
+ @VisibleForTesting
+ public ApplicationThreadDeferred(IApplicationThread thread, boolean defer) {
+ super(thread);
+
+ mDefer = defer;
+
+ mOperations[CLEAR_DNS_CACHE] = () -> { super.clearDnsCache(); };
+ mOperations[UPDATE_TIME_ZONE] = () -> { super.updateTimeZone(); };
+ mOperations[SCHEDULE_LOW_MEMORY] = () -> { super.scheduleLowMemory(); };
+ mOperations[UPDATE_HTTP_PROXY] = () -> { super.updateHttpProxy(); };
+ }
+
+ /** Create an instance with a base flag, using the system deferral enable flag. */
+ public ApplicationThreadDeferred(IApplicationThread thread) {
+ this(thread, deferBindersWhenPaused());
+ }
+
+ /** The process is being paused. Start deferring calls. */
+ void onProcessPaused() {
+ synchronized (mLock) {
+ mPaused = true;
+ }
+ }
+
+ /** The process is no longer paused. Drain any deferred calls. */
+ void onProcessUnpaused() {
+ synchronized (mLock) {
+ mPaused = false;
+ try {
+ for (int i = 0; i < mOperations.length; i++) {
+ if (mPending[i]) {
+ mOperations[i].run();
+ }
+ }
+ } catch (RemoteException e) {
+ // Swallow the exception. The caller is not expecting it. Remote exceptions
+ // happen if a has process died; there is no need to report it here.
+ } finally {
+ Arrays.fill(mPending, false);
+ }
+ }
+ }
+
+ /** The pause operation has been canceled. Drain any deferred calls. */
+ void onProcessPausedCancelled() {
+ onProcessUnpaused();
+ }
+
+ /**
+ * If the thread is not paused, execute the operation. Otherwise, save it to the pending
+ * list.
+ */
+ private void execute(@NotificationType int tag) throws RemoteException {
+ synchronized (mLock) {
+ if (mPaused && mDefer) {
+ mPending[tag] = true;
+ return;
+ }
+ }
+ // Outside the synchronization block to avoid contention.
+ mOperations[tag].run();
+ }
+
+ @Override
+ public void clearDnsCache() throws RemoteException {
+ execute(CLEAR_DNS_CACHE);
+ }
+
+ @Override
+ public void updateTimeZone() throws RemoteException {
+ execute(UPDATE_TIME_ZONE);
+ }
+
+ @Override
+ public void scheduleLowMemory() throws RemoteException {
+ execute(SCHEDULE_LOW_MEMORY);
+ }
+
+ @Override
+ public void updateHttpProxy() throws RemoteException {
+ execute(UPDATE_HTTP_PROXY);
+ }
+}
diff --git a/services/core/java/com/android/server/am/ApplicationThreadFilter.java b/services/core/java/com/android/server/am/ApplicationThreadFilter.java
new file mode 100644
index 000000000000..d049305025c2
--- /dev/null
+++ b/services/core/java/com/android/server/am/ApplicationThreadFilter.java
@@ -0,0 +1,603 @@
+/*
+ * 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.am;
+
+
+class ApplicationThreadFilter implements android.app.IApplicationThread {
+ private final android.app.IApplicationThread mBase;
+ public ApplicationThreadFilter(android.app.IApplicationThread base) { mBase = base; }
+ android.app.IApplicationThread getBase() { return mBase; }
+ public android.os.IBinder asBinder() {
+ return mBase.asBinder();
+ }
+
+ @Override
+ public void scheduleReceiver(android.content.Intent intent,
+ android.content.pm.ActivityInfo info,
+ android.content.res.CompatibilityInfo compatInfo,
+ int resultCode,
+ String data,
+ android.os.Bundle extras,
+ boolean ordered,
+ boolean assumeDelivered,
+ int sendingUser,
+ int processState,
+ int sentFromUid,
+ String sentFromPackage)
+ throws android.os.RemoteException {
+ mBase.scheduleReceiver(intent,
+ info,
+ compatInfo,
+ resultCode,
+ data,
+ extras,
+ ordered,
+ assumeDelivered,
+ sendingUser,
+ processState,
+ sentFromUid,
+ sentFromPackage);
+ }
+ @Override
+ public void scheduleReceiverList(java.util.List<android.app.ReceiverInfo> info)
+ throws android.os.RemoteException {
+ mBase.scheduleReceiverList(info);
+ }
+ @Override
+ public void scheduleCreateService(android.os.IBinder token,
+ android.content.pm.ServiceInfo info,
+ android.content.res.CompatibilityInfo compatInfo,
+ int processState)
+ throws android.os.RemoteException {
+ mBase.scheduleCreateService(token,
+ info,
+ compatInfo,
+ processState);
+ }
+ @Override
+ public void scheduleStopService(android.os.IBinder token)
+ throws android.os.RemoteException {
+ mBase.scheduleStopService(token);
+ }
+ @Override
+ public void bindApplication(String packageName,
+ android.content.pm.ApplicationInfo info,
+ String sdkSandboxClientAppVolumeUuid,
+ String sdkSandboxClientAppPackage,
+ boolean isSdkInSandbox,
+ android.content.pm.ProviderInfoList providerList,
+ android.content.ComponentName testName,
+ android.app.ProfilerInfo profilerInfo,
+ android.os.Bundle testArguments,
+ android.app.IInstrumentationWatcher testWatcher,
+ android.app.IUiAutomationConnection uiAutomationConnection,
+ int debugMode,
+ boolean enableBinderTracking,
+ boolean trackAllocation,
+ boolean restrictedBackupMode,
+ boolean persistent,
+ android.content.res.Configuration config,
+ android.content.res.CompatibilityInfo compatInfo,
+ java.util.Map services,
+ android.os.Bundle coreSettings,
+ String buildSerial,
+ android.content.AutofillOptions autofillOptions,
+ android.content.ContentCaptureOptions contentCaptureOptions,
+ long[] disabledCompatChanges,
+ long[] loggableCompatChanges,
+ android.os.SharedMemory serializedSystemFontMap,
+ long startRequestedElapsedTime,
+ long startRequestedUptime)
+ throws android.os.RemoteException {
+ mBase.bindApplication(packageName,
+ info,
+ sdkSandboxClientAppVolumeUuid,
+ sdkSandboxClientAppPackage,
+ isSdkInSandbox,
+ providerList,
+ testName,
+ profilerInfo,
+ testArguments,
+ testWatcher,
+ uiAutomationConnection,
+ debugMode,
+ enableBinderTracking,
+ trackAllocation,
+ restrictedBackupMode,
+ persistent,
+ config,
+ compatInfo,
+ services,
+ coreSettings,
+ buildSerial,
+ autofillOptions,
+ contentCaptureOptions,
+ disabledCompatChanges,
+ loggableCompatChanges,
+ serializedSystemFontMap,
+ startRequestedElapsedTime,
+ startRequestedUptime);
+ }
+ @Override
+ public void runIsolatedEntryPoint(String entryPoint,
+ String[] entryPointArgs)
+ throws android.os.RemoteException {
+ mBase.runIsolatedEntryPoint(entryPoint,
+ entryPointArgs);
+ }
+ @Override
+ public void scheduleExit()
+ throws android.os.RemoteException {
+ mBase.scheduleExit();
+ }
+ @Override
+ public void scheduleServiceArgs(android.os.IBinder token,
+ android.content.pm.ParceledListSlice args)
+ throws android.os.RemoteException {
+ mBase.scheduleServiceArgs(token,
+ args);
+ }
+ @Override
+ public void updateTimeZone()
+ throws android.os.RemoteException {
+ mBase.updateTimeZone();
+ }
+ @Override
+ public void processInBackground()
+ throws android.os.RemoteException {
+ mBase.processInBackground();
+ }
+ @Override
+ public void scheduleBindService(android.os.IBinder token,
+ android.content.Intent intent,
+ boolean rebind,
+ int processState,
+ long bindSeq)
+ throws android.os.RemoteException {
+ mBase.scheduleBindService(token,
+ intent,
+ rebind,
+ processState,
+ bindSeq);
+ }
+ @Override
+ public void scheduleUnbindService(android.os.IBinder token,
+ android.content.Intent intent)
+ throws android.os.RemoteException {
+ mBase.scheduleUnbindService(token,
+ intent);
+ }
+ @Override
+ public void dumpService(android.os.ParcelFileDescriptor fd,
+ android.os.IBinder servicetoken,
+ String[] args)
+ throws android.os.RemoteException {
+ mBase.dumpService(fd,
+ servicetoken,
+ args);
+ }
+ @Override
+ public void scheduleRegisteredReceiver(android.content.IIntentReceiver receiver,
+ android.content.Intent intent,
+ int resultCode,
+ String data,
+ android.os.Bundle extras,
+ boolean ordered,
+ boolean sticky,
+ boolean assumeDelivered,
+ int sendingUser,
+ int processState,
+ int sentFromUid,
+ String sentFromPackage)
+ throws android.os.RemoteException {
+ mBase.scheduleRegisteredReceiver(receiver,
+ intent,
+ resultCode,
+ data,
+ extras,
+ ordered,
+ sticky,
+ assumeDelivered,
+ sendingUser,
+ processState,
+ sentFromUid,
+ sentFromPackage);
+ }
+ @Override
+ public void scheduleLowMemory()
+ throws android.os.RemoteException {
+ mBase.scheduleLowMemory();
+ }
+ @Override
+ public void profilerControl(boolean start,
+ android.app.ProfilerInfo profilerInfo,
+ int profileType)
+ throws android.os.RemoteException {
+ mBase.profilerControl(start,
+ profilerInfo,
+ profileType);
+ }
+ @Override
+ public void setSchedulingGroup(int group)
+ throws android.os.RemoteException {
+ mBase.setSchedulingGroup(group);
+ }
+ @Override
+ public void scheduleCreateBackupAgent(android.content.pm.ApplicationInfo app,
+ int backupMode,
+ int userId,
+ int operationType)
+ throws android.os.RemoteException {
+ mBase.scheduleCreateBackupAgent(app,
+ backupMode,
+ userId,
+ operationType);
+ }
+ @Override
+ public void scheduleDestroyBackupAgent(android.content.pm.ApplicationInfo app,
+ int userId)
+ throws android.os.RemoteException {
+ mBase.scheduleDestroyBackupAgent(app,
+ userId);
+ }
+ @Override
+ public void scheduleOnNewSceneTransitionInfo(android.os.IBinder token,
+ android.app.ActivityOptions.SceneTransitionInfo info)
+ throws android.os.RemoteException {
+ mBase.scheduleOnNewSceneTransitionInfo(token,
+ info);
+ }
+ @Override
+ public void scheduleSuicide()
+ throws android.os.RemoteException {
+ mBase.scheduleSuicide();
+ }
+ @Override
+ public void dispatchPackageBroadcast(int cmd,
+ String[] packages)
+ throws android.os.RemoteException {
+ mBase.dispatchPackageBroadcast(cmd,
+ packages);
+ }
+ @Override
+ public void scheduleCrash(String msg,
+ int typeId,
+ android.os.Bundle extras)
+ throws android.os.RemoteException {
+ mBase.scheduleCrash(msg,
+ typeId,
+ extras);
+ }
+ @Override
+ public void dumpHeap(boolean managed,
+ boolean mallocInfo,
+ boolean runGc,
+ String dumpBitmaps,
+ String path,
+ android.os.ParcelFileDescriptor fd,
+ android.os.RemoteCallback finishCallback)
+ throws android.os.RemoteException {
+ mBase.dumpHeap(managed,
+ mallocInfo,
+ runGc,
+ dumpBitmaps,
+ path,
+ fd,
+ finishCallback);
+ }
+ @Override
+ public void dumpActivity(android.os.ParcelFileDescriptor fd,
+ android.os.IBinder servicetoken,
+ String prefix,
+ String[] args)
+ throws android.os.RemoteException {
+ mBase.dumpActivity(fd,
+ servicetoken,
+ prefix,
+ args);
+ }
+ @Override
+ public void dumpResources(android.os.ParcelFileDescriptor fd,
+ android.os.RemoteCallback finishCallback)
+ throws android.os.RemoteException {
+ mBase.dumpResources(fd,
+ finishCallback);
+ }
+ @Override
+ public void clearDnsCache()
+ throws android.os.RemoteException {
+ mBase.clearDnsCache();
+ }
+ @Override
+ public void updateHttpProxy()
+ throws android.os.RemoteException {
+ mBase.updateHttpProxy();
+ }
+ @Override
+ public void setCoreSettings(android.os.Bundle coreSettings)
+ throws android.os.RemoteException {
+ mBase.setCoreSettings(coreSettings);
+ }
+ @Override
+ public void updatePackageCompatibilityInfo(String pkg,
+ android.content.res.CompatibilityInfo info)
+ throws android.os.RemoteException {
+ mBase.updatePackageCompatibilityInfo(pkg,
+ info);
+ }
+ @Override
+ public void scheduleTrimMemory(int level)
+ throws android.os.RemoteException {
+ mBase.scheduleTrimMemory(level);
+ }
+ @Override
+ public void dumpMemInfo(android.os.ParcelFileDescriptor fd,
+ android.os.Debug.MemoryInfo mem,
+ boolean checkin,
+ boolean dumpInfo,
+ boolean dumpDalvik,
+ boolean dumpSummaryOnly,
+ boolean dumpUnreachable,
+ boolean dumpAllocatorLogs,
+ String[] args)
+ throws android.os.RemoteException {
+ mBase.dumpMemInfo(fd,
+ mem,
+ checkin,
+ dumpInfo,
+ dumpDalvik,
+ dumpSummaryOnly,
+ dumpUnreachable,
+ dumpAllocatorLogs,
+ args);
+ }
+ @Override
+ public void dumpMemInfoProto(android.os.ParcelFileDescriptor fd,
+ android.os.Debug.MemoryInfo mem,
+ boolean dumpInfo,
+ boolean dumpDalvik,
+ boolean dumpSummaryOnly,
+ boolean dumpUnreachable,
+ String[] args)
+ throws android.os.RemoteException {
+ mBase.dumpMemInfoProto(fd,
+ mem,
+ dumpInfo,
+ dumpDalvik,
+ dumpSummaryOnly,
+ dumpUnreachable,
+ args);
+ }
+ @Override
+ public void dumpGfxInfo(android.os.ParcelFileDescriptor fd,
+ String[] args)
+ throws android.os.RemoteException {
+ mBase.dumpGfxInfo(fd,
+ args);
+ }
+ @Override
+ public void dumpCacheInfo(android.os.ParcelFileDescriptor fd,
+ String[] args)
+ throws android.os.RemoteException {
+ mBase.dumpCacheInfo(fd,
+ args);
+ }
+ @Override
+ public void dumpProvider(android.os.ParcelFileDescriptor fd,
+ android.os.IBinder servicetoken,
+ String[] args)
+ throws android.os.RemoteException {
+ mBase.dumpProvider(fd,
+ servicetoken,
+ args);
+ }
+ @Override
+ public void dumpDbInfo(android.os.ParcelFileDescriptor fd,
+ String[] args)
+ throws android.os.RemoteException {
+ mBase.dumpDbInfo(fd,
+ args);
+ }
+ @Override
+ public void unstableProviderDied(android.os.IBinder provider)
+ throws android.os.RemoteException {
+ mBase.unstableProviderDied(provider);
+ }
+ @Override
+ public void requestAssistContextExtras(android.os.IBinder activityToken,
+ android.os.IBinder requestToken,
+ int requestType,
+ int sessionId,
+ int flags)
+ throws android.os.RemoteException {
+ mBase.requestAssistContextExtras(activityToken,
+ requestToken,
+ requestType,
+ sessionId,
+ flags);
+ }
+ @Override
+ public void scheduleTranslucentConversionComplete(android.os.IBinder token,
+ boolean timeout)
+ throws android.os.RemoteException {
+ mBase.scheduleTranslucentConversionComplete(token,
+ timeout);
+ }
+ @Override
+ public void setProcessState(int state)
+ throws android.os.RemoteException {
+ mBase.setProcessState(state);
+ }
+ @Override
+ public void scheduleInstallProvider(android.content.pm.ProviderInfo provider)
+ throws android.os.RemoteException {
+ mBase.scheduleInstallProvider(provider);
+ }
+ @Override
+ public void updateTimePrefs(int timeFormatPreference)
+ throws android.os.RemoteException {
+ mBase.updateTimePrefs(timeFormatPreference);
+ }
+ @Override
+ public void scheduleEnterAnimationComplete(android.os.IBinder token)
+ throws android.os.RemoteException {
+ mBase.scheduleEnterAnimationComplete(token);
+ }
+ @Override
+ public void notifyCleartextNetwork(byte[] firstPacket)
+ throws android.os.RemoteException {
+ mBase.notifyCleartextNetwork(firstPacket);
+ }
+ @Override
+ public void startBinderTracking()
+ throws android.os.RemoteException {
+ mBase.startBinderTracking();
+ }
+ @Override
+ public void stopBinderTrackingAndDump(android.os.ParcelFileDescriptor fd)
+ throws android.os.RemoteException {
+ mBase.stopBinderTrackingAndDump(fd);
+ }
+ @Override
+ public void scheduleLocalVoiceInteractionStarted(android.os.IBinder token,
+ com.android.internal.app.IVoiceInteractor voiceInteractor)
+ throws android.os.RemoteException {
+ mBase.scheduleLocalVoiceInteractionStarted(token,
+ voiceInteractor);
+ }
+ @Override
+ public void handleTrustStorageUpdate()
+ throws android.os.RemoteException {
+ mBase.handleTrustStorageUpdate();
+ }
+ @Override
+ public void attachAgent(String path)
+ throws android.os.RemoteException {
+ mBase.attachAgent(path);
+ }
+ @Override
+ public void attachStartupAgents(String dataDir)
+ throws android.os.RemoteException {
+ mBase.attachStartupAgents(dataDir);
+ }
+ @Override
+ public void scheduleApplicationInfoChanged(android.content.pm.ApplicationInfo ai)
+ throws android.os.RemoteException {
+ mBase.scheduleApplicationInfoChanged(ai);
+ }
+ @Override
+ public void setNetworkBlockSeq(long procStateSeq)
+ throws android.os.RemoteException {
+ mBase.setNetworkBlockSeq(procStateSeq);
+ }
+ @Override
+ public void scheduleTransaction(android.app.servertransaction.ClientTransaction transaction)
+ throws android.os.RemoteException {
+ mBase.scheduleTransaction(transaction);
+ }
+ @Override
+ public void scheduleTaskFragmentTransaction(android.window.ITaskFragmentOrganizer organizer,
+ android.window.TaskFragmentTransaction transaction)
+ throws android.os.RemoteException {
+ mBase.scheduleTaskFragmentTransaction(organizer,
+ transaction);
+ }
+ @Override
+ public void requestDirectActions(android.os.IBinder activityToken,
+ com.android.internal.app.IVoiceInteractor intractor,
+ android.os.RemoteCallback cancellationCallback,
+ android.os.RemoteCallback callback)
+ throws android.os.RemoteException {
+ mBase.requestDirectActions(activityToken,
+ intractor,
+ cancellationCallback,
+ callback);
+ }
+ @Override
+ public void performDirectAction(android.os.IBinder activityToken,
+ String actionId,
+ android.os.Bundle arguments,
+ android.os.RemoteCallback cancellationCallback,
+ android.os.RemoteCallback resultCallback)
+ throws android.os.RemoteException {
+ mBase.performDirectAction(activityToken,
+ actionId,
+ arguments,
+ cancellationCallback,
+ resultCallback);
+ }
+ @Override
+ public void notifyContentProviderPublishStatus(android.app.ContentProviderHolder holder,
+ String authorities,
+ int userId,
+ boolean published)
+ throws android.os.RemoteException {
+ mBase.notifyContentProviderPublishStatus(holder,
+ authorities,
+ userId,
+ published);
+ }
+ @Override
+ public void instrumentWithoutRestart(android.content.ComponentName instrumentationName,
+ android.os.Bundle instrumentationArgs,
+ android.app.IInstrumentationWatcher instrumentationWatcher,
+ android.app.IUiAutomationConnection instrumentationUiConnection,
+ android.content.pm.ApplicationInfo targetInfo)
+ throws android.os.RemoteException {
+ mBase.instrumentWithoutRestart(instrumentationName,
+ instrumentationArgs,
+ instrumentationWatcher,
+ instrumentationUiConnection,
+ targetInfo);
+ }
+ @Override
+ public void updateUiTranslationState(android.os.IBinder activityToken,
+ int state,
+ android.view.translation.TranslationSpec sourceSpec,
+ android.view.translation.TranslationSpec targetSpec,
+ java.util.List<android.view.autofill.AutofillId> viewIds,
+ android.view.translation.UiTranslationSpec uiTranslationSpec)
+ throws android.os.RemoteException {
+ mBase.updateUiTranslationState(activityToken,
+ state,
+ sourceSpec,
+ targetSpec,
+ viewIds,
+ uiTranslationSpec);
+ }
+ @Override
+ public void scheduleTimeoutService(android.os.IBinder token,
+ int startId)
+ throws android.os.RemoteException {
+ mBase.scheduleTimeoutService(token,
+ startId);
+ }
+ @Override
+ public void scheduleTimeoutServiceForType(android.os.IBinder token,
+ int startId,
+ int fgsType)
+ throws android.os.RemoteException {
+ mBase.scheduleTimeoutServiceForType(token,
+ startId,
+ fgsType);
+ }
+ @Override
+ public void schedulePing(android.os.RemoteCallback pong)
+ throws android.os.RemoteException {
+ mBase.schedulePing(pong);
+ }
+}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 00183ac0350b..67985efcd7bc 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -76,6 +76,7 @@ import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.Trace;
+import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.os.WakeLockStats;
import android.os.WorkSource;
@@ -158,6 +159,7 @@ import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -1107,6 +1109,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub
FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET,
null, // use default PullAtomMetadata values
DIRECT_EXECUTOR, pullAtomCallback);
+ if (Flags.addBatteryUsageStatsSliceAtom()) {
+ statsManager.setPullAtomCallback(
+ FrameworkStatsLog.BATTERY_USAGE_STATS_PER_UID,
+ null, // use default PullAtomMetadata values
+ DIRECT_EXECUTOR,
+ pullAtomCallback);
+ }
}
/** StatsPullAtomCallback for pulling BatteryUsageStats data. */
@@ -1115,7 +1124,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
public int onPullAtom(int atomTag, List<StatsEvent> data) {
final BatteryUsageStats bus;
switch (atomTag) {
- case FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET:
+ case FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET: {
@SuppressLint("MissingPermission")
final double minConsumedPowerThreshold =
DeviceConfig.getFloat(DEVICE_CONFIG_NAMESPACE,
@@ -1130,6 +1139,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
.build();
bus = getBatteryUsageStats(List.of(querySinceReset)).get(0);
break;
+ }
case FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL:
final BatteryUsageStatsQuery queryPowerProfile =
new BatteryUsageStatsQuery.Builder()
@@ -1141,7 +1151,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
.build();
bus = getBatteryUsageStats(List.of(queryPowerProfile)).get(0);
break;
- case FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET:
+ case FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET: {
final long sessionStart =
getLastBatteryUsageStatsBeforeResetAtomPullTimestamp();
final long sessionEnd;
@@ -1158,6 +1168,31 @@ public final class BatteryStatsService extends IBatteryStats.Stub
bus = getBatteryUsageStats(List.of(queryBeforeReset)).get(0);
setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(sessionEnd);
break;
+ }
+ case FrameworkStatsLog.BATTERY_USAGE_STATS_PER_UID: {
+ if (!Flags.addBatteryUsageStatsSliceAtom()) {
+ return StatsManager.PULL_SKIP;
+ }
+
+ @SuppressLint("MissingPermission")
+ final double minConsumedPowerThreshold =
+ DeviceConfig.getFloat(
+ DEVICE_CONFIG_NAMESPACE,
+ MIN_CONSUMED_POWER_THRESHOLD_KEY,
+ 0);
+ final long sessionStart = 0;
+ final long sessionEnd = System.currentTimeMillis();
+ final BatteryUsageStatsQuery query =
+ new BatteryUsageStatsQuery.Builder()
+ .setMaxStatsAgeMs(0)
+ .includeProcessStateData()
+ .includeVirtualUids()
+ .aggregateSnapshots(sessionStart, sessionEnd)
+ .setMinConsumedPowerThreshold(minConsumedPowerThreshold)
+ .build();
+ bus = getBatteryUsageStats(List.of(query)).get(0);
+ return StatsPerUidLogger.logStats(bus, data);
+ }
default:
throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
}
@@ -1169,6 +1204,262 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
}
+ private static class StatsPerUidLogger {
+
+ private static final int STATSD_METRIC_MAX_DIMENSIONS_COUNT = 3000;
+
+ private static final int[] UID_PROCESS_STATES = {
+ BatteryConsumer.PROCESS_STATE_UNSPECIFIED,
+ BatteryConsumer.PROCESS_STATE_FOREGROUND,
+ BatteryConsumer.PROCESS_STATE_BACKGROUND,
+ BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE,
+ BatteryConsumer.PROCESS_STATE_CACHED
+ };
+
+ public record SessionInfo(
+ long startTs,
+ long endTs,
+ long duration,
+ int dischargePercentage,
+ long dischargeDuration) {}
+ ;
+
+ static int logStats(BatteryUsageStats bus, List<StatsEvent> data) {
+ final SessionInfo sessionInfo =
+ new SessionInfo(
+ bus.getStatsStartTimestamp(),
+ bus.getStatsEndTimestamp(),
+ bus.getStatsDuration(),
+ bus.getDischargePercentage(),
+ bus.getDischargeDurationMs());
+
+ if (DBG) {
+ Slog.d(TAG, "BatteryUsageStats dump = " + bus);
+ }
+ final BatteryConsumer deviceConsumer =
+ bus.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
+
+ final float totalDeviceConsumedPowerMah = (float) deviceConsumer.getConsumedPower();
+
+ for (@BatteryConsumer.PowerComponent int componentId = 0;
+ componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
+ componentId++) {
+
+ for (@BatteryConsumer.ProcessState int processState : UID_PROCESS_STATES) {
+
+ if (!addStatsForPredefinedComponent(
+ data,
+ sessionInfo,
+ Process.INVALID_UID,
+ processState,
+ totalDeviceConsumedPowerMah,
+ deviceConsumer,
+ componentId)) {
+ return StatsManager.PULL_SUCCESS;
+ }
+ }
+ }
+
+ final int customPowerComponentCount = deviceConsumer.getCustomPowerComponentCount();
+ for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
+ componentId
+ < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+ + customPowerComponentCount;
+ componentId++) {
+
+ if (!addStatsForCustomComponent(
+ data,
+ sessionInfo,
+ Process.INVALID_UID,
+ BatteryConsumer.PROCESS_STATE_UNSPECIFIED,
+ 0,
+ totalDeviceConsumedPowerMah,
+ deviceConsumer,
+ componentId)) {
+ return StatsManager.PULL_SUCCESS;
+ }
+ }
+
+ final List<UidBatteryConsumer> uidConsumers = bus.getUidBatteryConsumers();
+ uidConsumers.sort(
+ Comparator.<BatteryConsumer>comparingDouble(BatteryConsumer::getConsumedPower)
+ .reversed());
+
+ // Log single atom for BatteryUsageStats per uid/process_state/component/etc.
+ for (UidBatteryConsumer uidConsumer : uidConsumers) {
+ final int uid = uidConsumer.getUid();
+ final float totalConsumedPowerMah = (float) uidConsumer.getConsumedPower();
+
+ for (@BatteryConsumer.PowerComponent int componentId = 0;
+ componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
+ componentId++) {
+
+ for (@BatteryConsumer.ProcessState int processState : UID_PROCESS_STATES) {
+
+ if (!addStatsForPredefinedComponent(
+ data,
+ sessionInfo,
+ uid,
+ processState,
+ totalConsumedPowerMah,
+ uidConsumer,
+ componentId)) {
+ return StatsManager.PULL_SUCCESS;
+ }
+ }
+ }
+
+ // looping over custom components
+ for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
+ componentId
+ < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+ + customPowerComponentCount;
+ componentId++) {
+ for (@BatteryConsumer.ProcessState int processState : UID_PROCESS_STATES) {
+ final long timeInStateMillis =
+ uidConsumer.getTimeInProcessStateMs(processState);
+ if (timeInStateMillis <= 0) {
+ continue;
+ }
+
+ if (!addStatsForCustomComponent(
+ data,
+ sessionInfo,
+ uid,
+ processState,
+ timeInStateMillis,
+ totalConsumedPowerMah,
+ uidConsumer,
+ componentId)) {
+ return StatsManager.PULL_SUCCESS;
+ }
+ }
+ }
+ }
+ return StatsManager.PULL_SUCCESS;
+ }
+
+ private static boolean addStatsForPredefinedComponent(
+ List<StatsEvent> data,
+ SessionInfo sessionInfo,
+ int uid,
+ @BatteryConsumer.ProcessState int processState,
+ float totalConsumedPowerMah,
+ BatteryConsumer batteryConsumer,
+ @BatteryConsumer.PowerComponent int componentId) {
+ final BatteryConsumer.Key key = batteryConsumer.getKey(componentId, processState);
+ if (key == null) {
+ return true;
+ }
+
+ final String powerComponentName = BatteryConsumer.powerComponentIdToString(componentId);
+ final float powerMah = (float) batteryConsumer.getConsumedPower(key);
+ final long powerComponentDurationMillis = batteryConsumer.getUsageDurationMillis(key);
+
+ if (powerMah == 0 && powerComponentDurationMillis == 0) {
+ return true;
+ }
+
+ long timeInState = 0;
+ if (batteryConsumer instanceof UidBatteryConsumer) {
+ timeInState =
+ ((UidBatteryConsumer) batteryConsumer)
+ .getTimeInProcessStateMs(processState);
+ }
+
+ return addStatsAtom(
+ data,
+ sessionInfo,
+ uid,
+ processState,
+ timeInState,
+ powerComponentName,
+ totalConsumedPowerMah,
+ powerMah,
+ powerComponentDurationMillis);
+ }
+
+ private static boolean addStatsForCustomComponent(
+ List<StatsEvent> data,
+ SessionInfo sessionInfo,
+ int uid,
+ @BatteryConsumer.ProcessState int processState,
+ long timeInStateMillis,
+ float totalConsumedPowerMah,
+ BatteryConsumer batteryConsumer,
+ int componentId) {
+
+ if (componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) {
+ throw new IllegalArgumentException("Invalid custom component id: " + componentId);
+ }
+
+ final float powerMah =
+ (float) batteryConsumer.getConsumedPowerForCustomComponent(componentId);
+ if (powerMah == 0) {
+ return true;
+ }
+
+ final String powerComponentName =
+ batteryConsumer.getCustomPowerComponentName(componentId);
+
+ final long powerComponentDurationMillis =
+ batteryConsumer.getUsageDurationForCustomComponentMillis(componentId);
+
+ return addStatsAtom(
+ data,
+ sessionInfo,
+ uid,
+ processState,
+ timeInStateMillis,
+ powerComponentName,
+ totalConsumedPowerMah,
+ powerMah,
+ powerComponentDurationMillis);
+ }
+
+ /**
+ * Returns true on success and false if reached max atoms capacity and no more atoms should
+ * be added
+ */
+ private static boolean addStatsAtom(
+ List<StatsEvent> data,
+ SessionInfo sessionInfo,
+ int uid,
+ int processState,
+ long timeInStateMillis,
+ String powerComponentName,
+ float totalConsumedPowerMah,
+ float powerComponentMah,
+ long powerComponentDurationMillis) {
+ data.add(
+ FrameworkStatsLog.buildStatsEvent(
+ FrameworkStatsLog.BATTERY_USAGE_STATS_PER_UID,
+ sessionInfo.startTs(),
+ sessionInfo.endTs(),
+ sessionInfo.duration(),
+ sessionInfo.dischargePercentage(),
+ sessionInfo.dischargeDuration(),
+ uid,
+ processState,
+ timeInStateMillis,
+ powerComponentName,
+ totalConsumedPowerMah,
+ powerComponentMah,
+ powerComponentDurationMillis));
+
+ // Early termination due to statsd dimensions guardrail
+ if (data.size() == STATSD_METRIC_MAX_DIMENSIONS_COUNT) {
+ Slog.w(
+ TAG,
+ "BATTERY_USAGE_STATS_PER_UID is complete reaching"
+ + " dimension guardrail");
+ return false;
+ }
+ return true;
+ }
+ }
+
@Override
@RequiresNoPermission
public boolean isCharging() {
@@ -2824,9 +3115,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub
pw.println(" --checkin: generate output for a checkin report; will write (and clear) the");
pw.println(" last old completed stats when they had been reset.");
pw.println(" -c: write the current stats in checkin format.");
- pw.println(" --proto: write the current aggregate stats (without history) in proto format.");
+ pw.println(
+ " --proto: write the current aggregate stats (without history) in proto format.");
pw.println(" --history: show only history data.");
- pw.println(" --history-start <num>: show only history data starting at given time offset.");
+ pw.println(
+ " --history-start <num>: show only history data starting at given time offset.");
pw.println(" --history-create-events <num>: create <num> of battery history events.");
pw.println(" --charged: only output data since last charged.");
pw.println(" --daily: only output full daily data.");
@@ -2850,12 +3143,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub
pw.println(" -h: print this help text.");
pw.println("Battery stats (batterystats) commands:");
pw.println(" enable|disable <option>");
- pw.println(" Enable or disable a running option. Option state is not saved across boots.");
+ pw.println(
+ " Enable or disable a running option. Option state is not saved across boots.");
pw.println(" Options are:");
pw.println(" full-history: include additional detailed events in battery history:");
pw.println(" wake_lock_in, alarms and proc events");
pw.println(" no-auto-reset: don't automatically reset stats when unplugged");
- pw.println(" pretend-screen-off: pretend the screen is off, even if screen state changes");
+ pw.println(
+ " pretend-screen-off: pretend the screen is off, even if screen state"
+ + " changes");
}
private void dumpSettings(PrintWriter pw) {
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 6433f2c1c25d..1c4ffbb812a4 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -2656,6 +2656,7 @@ public final class CachedAppOptimizer {
// PIDs that run out of async binder buffer when being frozen
ArraySet<Integer> pidsAsync = (mFreezerBinderAsyncThreshold < 0) ? null : new ArraySet<>();
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "binderErrorSync");
for (int i = 0; i < pids.size(); i++) {
int current = pids.get(i);
try {
@@ -2684,6 +2685,7 @@ public final class CachedAppOptimizer {
Slog.w(TAG_AM, "Unable to query binder frozen stats for pid " + current);
}
}
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// TODO: when kernel binder driver supports, poll the binder status directly.
// Binderfs stats, like other debugfs files, is not a reliable interface. But it's the
@@ -2693,6 +2695,8 @@ public final class CachedAppOptimizer {
if (pidsAsync == null || pidsAsync.size() == 0) {
return;
}
+
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "binderErrorAsync");
new BinderfsStatsReader().handleFreeAsyncSpace(
// Check if the frozen process has pending async calls
pidsAsync::contains,
@@ -2710,5 +2714,6 @@ public final class CachedAppOptimizer {
// Log the error if binderfs stats can't be accesses or correctly parsed
exception -> Slog.e(TAG_AM, "Unable to parse binderfs stats"));
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
diff --git a/services/core/java/com/android/server/am/LmkdConnection.java b/services/core/java/com/android/server/am/LmkdConnection.java
index 598f086db94d..4faadcbe0cca 100644
--- a/services/core/java/com/android/server/am/LmkdConnection.java
+++ b/services/core/java/com/android/server/am/LmkdConnection.java
@@ -91,10 +91,18 @@ public class LmkdConnection {
@GuardedBy("mLmkdSocketLock")
private LocalSocket mLmkdSocket = null;
- // socket I/O streams
- @GuardedBy("mLmkdSocketLock")
+ // mutex to synchronize socket output stream with socket creation/destruction
+ private final Object mLmkdOutputStreamLock = new Object();
+
+ // socket output stream
+ @GuardedBy("mLmkdOutputStreamLock")
private OutputStream mLmkdOutputStream = null;
- @GuardedBy("mLmkdSocketLock")
+
+ // mutex to synchronize socket input stream with socket creation/destruction
+ private final Object mLmkdInputStreamLock = new Object();
+
+ // socket input stream
+ @GuardedBy("mLmkdInputStreamLock")
private InputStream mLmkdInputStream = null;
// buffer to store incoming data
@@ -148,9 +156,13 @@ public class LmkdConnection {
return false;
}
// connection established
- mLmkdSocket = socket;
- mLmkdOutputStream = ostream;
- mLmkdInputStream = istream;
+ synchronized(mLmkdOutputStreamLock) {
+ synchronized(mLmkdInputStreamLock) {
+ mLmkdSocket = socket;
+ mLmkdOutputStream = ostream;
+ mLmkdInputStream = istream;
+ }
+ }
mMsgQueue.addOnFileDescriptorEventListener(mLmkdSocket.getFileDescriptor(),
EVENT_INPUT | EVENT_ERROR,
new MessageQueue.OnFileDescriptorEventListener() {
@@ -177,7 +189,13 @@ public class LmkdConnection {
mMsgQueue.removeOnFileDescriptorEventListener(
mLmkdSocket.getFileDescriptor());
IoUtils.closeQuietly(mLmkdSocket);
- mLmkdSocket = null;
+ synchronized(mLmkdOutputStreamLock) {
+ synchronized(mLmkdInputStreamLock) {
+ mLmkdOutputStream = null;
+ mLmkdInputStream = null;
+ mLmkdSocket = null;
+ }
+ }
}
// wake up reply waiters if any
synchronized (mReplyBufLock) {
@@ -262,24 +280,33 @@ public class LmkdConnection {
}
private boolean write(ByteBuffer buf) {
- synchronized (mLmkdSocketLock) {
- try {
- mLmkdOutputStream.write(buf.array(), 0, buf.position());
- } catch (IOException ex) {
- return false;
+ boolean result = false;
+
+ synchronized(mLmkdOutputStreamLock) {
+ if (mLmkdOutputStream != null) {
+ try {
+ mLmkdOutputStream.write(buf.array(), 0, buf.position());
+ result = true;
+ } catch (IOException ex) {
+ }
}
- return true;
}
+
+ return result;
}
private int read(ByteBuffer buf) {
- synchronized (mLmkdSocketLock) {
- try {
- return mLmkdInputStream.read(buf.array(), 0, buf.array().length);
- } catch (IOException ex) {
+ int result = -1;
+
+ synchronized(mLmkdInputStreamLock) {
+ if (mLmkdInputStream != null) {
+ try {
+ result = mLmkdInputStream.read(buf.array(), 0, buf.array().length);
+ } catch (IOException ex) {
+ }
}
- return -1;
}
+ return result;
}
/**
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index f4b1229696f5..779aabecbb99 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -5559,8 +5559,9 @@ public final class ProcessList {
void noteAppKill(final ProcessRecord app, final @Reason int reason,
final @SubReason int subReason, final String msg) {
if (DEBUG_PROCESSES) {
- Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason
- + ", sub-reason: " + subReason + ", message: " + msg);
+ Slog.i(TAG, "note: " + app + " is being killed, reason: "
+ + ApplicationExitInfo.reasonCodeToString(reason) + ", sub-reason: "
+ + ApplicationExitInfo.subreasonToString(subReason) + ", message: " + msg);
}
if (app.getPid() > 0 && !app.isolated && app.getDeathRecipient() != null) {
// We are killing it, put it into the dying process list.
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index a74c4896dd8c..3e71d003f455 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -151,7 +151,7 @@ class ProcessRecord implements WindowProcessListener {
* (in which case we are in the process of launching the app).
*/
@CompositeRWLock({"mService", "mProcLock"})
- private IApplicationThread mThread;
+ private ApplicationThreadDeferred mThread;
/**
* Instance of {@link #mThread} that will always meet the {@code oneway}
@@ -737,15 +737,15 @@ class ProcessRecord implements WindowProcessListener {
}
@GuardedBy({"mService", "mProcLock"})
- public void makeActive(IApplicationThread thread, ProcessStatsService tracker) {
+ public void makeActive(ApplicationThreadDeferred thread, ProcessStatsService tracker) {
mProfile.onProcessActive(thread, tracker);
mThread = thread;
if (mPid == Process.myPid()) {
- mOnewayThread = new SameProcessApplicationThread(thread, FgThread.getHandler());
+ mOnewayThread = new SameProcessApplicationThread(mThread, FgThread.getHandler());
} else {
- mOnewayThread = thread;
+ mOnewayThread = mThread;
}
- mWindowProcessController.setThread(thread);
+ mWindowProcessController.setThread(mThread);
if (mWindowProcessController.useFifoUiScheduling()) {
mService.mSpecifiedFifoProcesses.add(this);
}
@@ -1436,14 +1436,17 @@ class ProcessRecord implements WindowProcessListener {
void onProcessFrozen() {
mProfile.onProcessFrozen();
+ if (mThread != null) mThread.onProcessPaused();
}
void onProcessUnfrozen() {
+ if (mThread != null) mThread.onProcessUnpaused();
mProfile.onProcessUnfrozen();
mServices.onProcessUnfrozen();
}
void onProcessFrozenCancelled() {
+ if (mThread != null) mThread.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 cbea7aa9a92c..7f43fae72d60 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -136,6 +136,7 @@ public class SettingsToPropertiesMapper {
static final String[] sDeviceConfigAconfigScopes = new String[] {
"accessibility",
"android_core_networking",
+ "android_sdk",
"android_stylus",
"aoc",
"app_widgets",
@@ -209,6 +210,7 @@ public class SettingsToPropertiesMapper {
"safety_center",
"sensors",
"spoon",
+ "stability",
"statsd",
"system_performance",
"system_sw_touch",
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index 9b380ff12e2d..5315167b46eb 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -163,7 +163,7 @@ flag {
flag {
name: "collect_logcat_on_run_synchronously"
- namespace: "dropbox"
+ namespace: "stability"
description: "Allow logcat collection on synchronous dropbox collection"
bug: "324222683"
is_fixed_read_only: true
@@ -171,8 +171,16 @@ flag {
flag {
name: "enable_dropbox_watchdog_headers"
- namespace: "dropbox"
+ namespace: "stability"
description: "Add watchdog-specific dropbox headers"
bug: "330682397"
is_fixed_read_only: true
}
+
+flag {
+ name: "defer_binders_when_paused"
+ namespace: "system_performance"
+ is_fixed_read_only: true
+ description: "Defer submitting binder calls to paused processes."
+ bug: "327038797"
+}
diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java
index b1a12f7338da..5d83ad67d535 100644
--- a/services/core/java/com/android/server/appop/DiscreteRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java
@@ -26,6 +26,7 @@ import static android.app.AppOpsManager.FILTER_BY_PACKAGE_NAME;
import static android.app.AppOpsManager.FILTER_BY_UID;
import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.AppOpsManager.OP_COARSE_LOCATION;
+import static android.app.AppOpsManager.OP_EMERGENCY_LOCATION;
import static android.app.AppOpsManager.OP_FINE_LOCATION;
import static android.app.AppOpsManager.OP_FLAGS_ALL;
import static android.app.AppOpsManager.OP_FLAG_SELF;
@@ -135,9 +136,10 @@ final class DiscreteRegistry {
private static final String PROPERTY_DISCRETE_FLAGS = "discrete_history_op_flags";
private static final String PROPERTY_DISCRETE_OPS_LIST = "discrete_history_ops_cslist";
private static final String DEFAULT_DISCRETE_OPS = OP_FINE_LOCATION + "," + OP_COARSE_LOCATION
- + "," + OP_CAMERA + "," + OP_RECORD_AUDIO + "," + OP_PHONE_CALL_MICROPHONE + ","
- + OP_PHONE_CALL_CAMERA + "," + OP_RECEIVE_AMBIENT_TRIGGER_AUDIO + ","
- + OP_RECEIVE_SANDBOX_TRIGGER_AUDIO + "," + OP_RESERVED_FOR_TESTING;
+ + "," + OP_EMERGENCY_LOCATION + "," + OP_CAMERA + "," + OP_RECORD_AUDIO + ","
+ + OP_PHONE_CALL_MICROPHONE + "," + OP_PHONE_CALL_CAMERA + ","
+ + OP_RECEIVE_AMBIENT_TRIGGER_AUDIO + "," + OP_RECEIVE_SANDBOX_TRIGGER_AUDIO
+ + "," + OP_RESERVED_FOR_TESTING;
private static final long DEFAULT_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(7).toMillis();
private static final long MAXIMUM_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(30).toMillis();
private static final long DEFAULT_DISCRETE_HISTORY_QUANTIZATION =
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index cc4f7d9b2ddb..8de1552a7f60 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -474,19 +474,10 @@ public class AudioDeviceBroker {
mBtHelper.stopBluetoothSco(eventSource);
}
}
- // In BT classic for communication, the device changes from a2dp to sco device, but for
- // LE Audio it stays the same and we must trigger the proper stream volume alignment, if
- // LE Audio communication device is activated after the audio system has already switched to
- // MODE_IN_CALL mode.
- if (isBluetoothLeAudioRequested() && device != null) {
- final int streamType = mAudioService.getBluetoothContextualVolumeStream();
- final int leAudioVolIndex = getVssVolumeForDevice(streamType, device.getInternalType());
- final int leAudioMaxVolIndex = getMaxVssVolumeForStream(streamType);
- if (AudioService.DEBUG_COMM_RTE) {
- Log.v(TAG, "setCommunicationRouteForClient restoring LE Audio device volume lvl.");
- }
- postSetLeAudioVolumeIndex(leAudioVolIndex, leAudioMaxVolIndex, streamType);
- }
+ // In BT classic for communication, the device changes from a2dp to sco device,
+ // but for LE Audio or Hearing Aid it stays the same and we must trigger the proper
+ // stream volume alignment.
+ mAudioService.postUpdateContextualVolumes();
updateCommunicationRoute(eventSource);
}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 2986340c684d..02aa6f52ba8a 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -2548,23 +2548,27 @@ public class AudioDeviceInventory {
new DeviceInfo(device, name, address,
btInfo.mDevice.getIdentityAddress(), codec,
groupId, peerAddress, peerIdentityAddress));
- mDeviceBroker.postAccessoryPlugMediaUnmute(device);
- setCurrentAudioRouteNameIfPossible(name, /*fromA2dp=*/false);
+ if (btInfo.mIsLeOutput) {
+ mDeviceBroker.postAccessoryPlugMediaUnmute(device);
+ setCurrentAudioRouteNameIfPossible(name, /*fromA2dp=*/false);
+ }
addAudioDeviceInInventoryIfNeeded(device, address, peerAddress,
BtHelper.getBtDeviceCategory(address), /*userDefined=*/false);
}
- if (streamType == AudioSystem.STREAM_DEFAULT) {
- // No need to update volume for input devices
- return;
- }
+ if (btInfo.mIsLeOutput) {
+ if (streamType == AudioSystem.STREAM_DEFAULT) {
+ // No need to update volume for input devices
+ return;
+ }
- final int leAudioVolIndex = (volumeIndex == -1)
- ? mDeviceBroker.getVssVolumeForDevice(streamType, device)
- : volumeIndex;
- final int maxIndex = mDeviceBroker.getMaxVssVolumeForStream(streamType);
- mDeviceBroker.postSetLeAudioVolumeIndex(leAudioVolIndex, maxIndex, streamType);
- mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "makeLeAudioDeviceAvailable");
+ final int leAudioVolIndex = (volumeIndex == -1)
+ ? mDeviceBroker.getVssVolumeForDevice(streamType, device)
+ : volumeIndex;
+ final int maxIndex = mDeviceBroker.getMaxVssVolumeForStream(streamType);
+ mDeviceBroker.postSetLeAudioVolumeIndex(leAudioVolIndex, maxIndex, streamType);
+ mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "makeLeAudioDeviceAvailable");
+ }
updateBluetoothPreferredModes_l(btInfo.mDevice /*connectedDevice*/);
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 989a4d14b1b5..0d309eb6786d 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -841,7 +841,9 @@ public class AudioService extends IAudioService.Stub
// full scale, and volume control separately) and can be used for multiple use cases reflected
// by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>(
- Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID));
+ Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID,
+ AudioSystem.DEVICE_OUT_BLE_HEADSET,
+ AudioSystem.DEVICE_OUT_BLE_SPEAKER));
private final boolean mMonitorRotation;
@@ -975,7 +977,7 @@ public class AudioService extends IAudioService.Stub
private NotificationManager mNm;
private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
- private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
+ private volatile VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
private long mLoweredFromNormalToVibrateTime;
// Array of Uids of valid assistant services to check if caller is one of them
@@ -3815,17 +3817,16 @@ public class AudioService extends IAudioService.Stub
mStreamStates[streamType].getMaxIndex(), streamType);
}
- // Check if volume update should be send to Hearing Aid
- if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
- // only modify the hearing aid attenuation when the stream to modify matches
- // the one expected by the hearing aid
- if (streamType == getBluetoothContextualVolumeStream()) {
- if (DEBUG_VOL) {
- Log.d(TAG, "adjustStreamVolume postSetHearingAidVolumeIndex index="
- + newIndex + " stream=" + streamType);
- }
- mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
+ // Check if volume update should be send to Hearing Aid.
+ // Only modify the hearing aid attenuation when the stream to modify matches
+ // the one expected by the hearing aid.
+ if (device == AudioSystem.DEVICE_OUT_HEARING_AID
+ && streamType == getBluetoothContextualVolumeStream()) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "adjustStreamVolume postSetHearingAidVolumeIndex index="
+ + newIndex + " stream=" + streamType);
}
+ mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
}
}
@@ -4631,93 +4632,43 @@ public class AudioService extends IAudioService.Stub
private void onUpdateContextualVolumes() {
final int streamType = getBluetoothContextualVolumeStream();
- final int device = getDeviceForStream(streamType);
- final int index = getStreamVolume(streamType, device);
-
- if (AudioSystem.isLeAudioDeviceType(device)) {
- mDeviceBroker.postSetLeAudioVolumeIndex(index * 10,
- mStreamStates[streamType].getMaxIndex(), streamType);
- } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
- mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
- }
- sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME,
- mVoicePlaybackActive.get(), streamType, index, device));
- }
-
- /**
- * Manage an audio mode change for audio devices that use an "absolute volume" model,
- * i.e. the framework sends the full scale signal, and the actual volume for the use case
- * is communicated separately.
- */
- void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) {
- if (oldMode == newMode) {
- return;
- }
- switch (newMode) {
- case AudioSystem.MODE_IN_COMMUNICATION:
- case AudioSystem.MODE_IN_CALL:
- case AudioSystem.MODE_NORMAL:
- case AudioSystem.MODE_CALL_SCREENING:
- case AudioSystem.MODE_CALL_REDIRECT:
- case AudioSystem.MODE_COMMUNICATION_REDIRECT:
- break;
- default:
- // no-op is enough for all other values
- return;
- }
-
- int streamType = getBluetoothContextualVolumeStream(newMode);
final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
- final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes(
- mAbsVolumeMultiModeCaseDevices, deviceTypes);
+ final Set<Integer> absVolumeMultiModeCaseDevices =
+ AudioSystem.intersectionAudioDeviceTypes(
+ mAbsVolumeMultiModeCaseDevices, deviceTypes);
if (absVolumeMultiModeCaseDevices.isEmpty()) {
return;
}
-
- // handling of specific interfaces goes here:
- if (AudioSystem.isSingleAudioDeviceType(
- absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) {
- final int index = getStreamVolume(streamType);
- sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
- newMode, streamType, index));
- mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
+ if (absVolumeMultiModeCaseDevices.size() > 1) {
+ Log.w(TAG, "onUpdateContextualVolumes too many active devices: "
+ + absVolumeMultiModeCaseDevices.stream().map(AudioSystem::getOutputDeviceName)
+ .collect(Collectors.joining(","))
+ + ", for stream: " + streamType);
+ return;
}
- }
- private void setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index,
- int maxIndex) {
- switch (mode) {
- case AudioSystem.MODE_IN_COMMUNICATION:
- case AudioSystem.MODE_IN_CALL:
- case AudioSystem.MODE_NORMAL:
- case AudioSystem.MODE_CALL_SCREENING:
- case AudioSystem.MODE_CALL_REDIRECT:
- case AudioSystem.MODE_COMMUNICATION_REDIRECT:
- case AudioSystem.MODE_RINGTONE:
- break;
- default:
- // no-op is enough for all other values
- return;
+ final int device = absVolumeMultiModeCaseDevices.toArray(new Integer[0])[0].intValue();
+
+ final int index = getStreamVolume(streamType, device);
+
+ if (DEBUG_VOL) {
+ Log.i(TAG, "onUpdateContextualVolumes streamType: " + streamType
+ + ", device: " + AudioSystem.getOutputDeviceName(device)
+ + ", index: " + index);
}
- // In some cases (like the outgoing or rejected call) the value of 'device' is not
- // DEVICE_OUT_BLE_* even when BLE is connected. Changing the volume level in such case
- // may cuase the other devices volume level leaking into the LeAudio device settings.
- if (!AudioSystem.isLeAudioDeviceType(device)) {
- Log.w(TAG, "setLeAudioVolumeOnModeUpdate ignoring invalid device="
- + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
- + " streamType=" + streamType);
+ if (AudioSystem.isLeAudioDeviceType(device)) {
+ mDeviceBroker.postSetLeAudioVolumeIndex(index * 10,
+ mStreamStates[streamType].getMaxIndex(), streamType);
+ } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
+ mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
+ } else {
return;
}
- if (DEBUG_VOL) {
- Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex device="
- + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
- + " streamType=" + streamType);
- }
- mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType);
- mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate");
+ sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME,
+ mVoicePlaybackActive.get(), streamType, index, device));
}
private void setStreamVolume(int streamType, int index, int flags,
@@ -6254,9 +6205,7 @@ public class AudioService extends IAudioService.Stub
updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage);
// change of mode may require volume to be re-applied on some devices
- updateAbsVolumeMultiModeDevices(previousMode, mode);
-
- setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex);
+ onUpdateContextualVolumes();
synchronized (mCachedAbsVolDrivingStreamsLock) {
mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> {
@@ -12152,6 +12101,11 @@ public class AudioService extends IAudioService.Stub
}
}
+ @Override
+ public VolumePolicy getVolumePolicy() {
+ return mVolumePolicy;
+ }
+
/** Interface used for enforcing the safe hearing standard. */
public interface ISafeHearingVolumeController {
/** Displays an instructional safeguard as required by the safe hearing standard. */
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 0de342807df3..57bffa7e5b40 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -470,8 +470,13 @@ public class BtHelper {
if (mBluetoothHeadset == null || mBluetoothHeadsetDevice == null) {
return false;
}
- return mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
- == BluetoothHeadset.STATE_AUDIO_CONNECTED;
+ try {
+ return mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
+ == BluetoothHeadset.STATE_AUDIO_CONNECTED;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception while getting audio state of " + mBluetoothHeadsetDevice, e);
+ }
+ return false;
}
/*package*/ synchronized boolean isBluetoothScoRequestedInternally() {
@@ -1150,12 +1155,16 @@ public class BtHelper {
}
private void checkScoAudioState() {
- if (mBluetoothHeadset != null
- && mBluetoothHeadsetDevice != null
- && mScoAudioState == SCO_STATE_INACTIVE
- && mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
- != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
- mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+ try {
+ if (mBluetoothHeadset != null
+ && mBluetoothHeadsetDevice != null
+ && mScoAudioState == SCO_STATE_INACTIVE
+ && mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
+ != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
+ mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Exception while getting audio state of " + mBluetoothHeadsetDevice, e);
}
}
diff --git a/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java b/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java
index 1726da2ff05d..a83813f32e3e 100644
--- a/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java
+++ b/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java
@@ -18,6 +18,8 @@ package com.android.server.backup;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
+import android.app.backup.BackupRestoreEventLogger.BackupRestoreError;
+import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType;
import android.app.backup.BlobBackupHelper;
import android.util.Slog;
@@ -33,6 +35,16 @@ public class AppSpecificLocalesBackupHelper extends BlobBackupHelper {
private static final String TAG = "AppLocalesBackupHelper"; // must be < 23 chars
private static final boolean DEBUG = false;
+ @BackupRestoreDataType
+ private static final String DATA_TYPE_APP_LOCALES = "app_locales:locales";
+
+ @BackupRestoreError
+ private static final String ERROR_UNEXPECTED_KEY = "unexpected_key";
+ @BackupRestoreError
+ private static final String ERROR_BACKUP_FAILED = "backup_failed";
+ @BackupRestoreError
+ private static final String ERROR_RESTORE_FAILED = "restore_failed";
+
// Current version of the blob schema
private static final int BLOB_VERSION = 1;
@@ -59,13 +71,24 @@ public class AppSpecificLocalesBackupHelper extends BlobBackupHelper {
if (KEY_APP_LOCALES.equals(key)) {
try {
newPayload = mLocaleManagerInternal.getBackupPayload(mUserId);
+ getLogger().logItemsBackedUp(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1);
} catch (Exception e) {
// Treat as no data
Slog.e(TAG, "Couldn't communicate with locale manager", e);
+ getLogger().logItemsBackupFailed(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1,
+ ERROR_BACKUP_FAILED);
newPayload = null;
}
} else {
Slog.w(TAG, "Unexpected backup key " + key);
+ getLogger().logItemsBackupFailed(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1,
+ ERROR_UNEXPECTED_KEY);
}
return newPayload;
}
@@ -79,11 +102,22 @@ public class AppSpecificLocalesBackupHelper extends BlobBackupHelper {
if (KEY_APP_LOCALES.equals(key)) {
try {
mLocaleManagerInternal.stageAndApplyRestoredPayload(payload, mUserId);
+ getLogger().logItemsRestored(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1);
} catch (Exception e) {
Slog.e(TAG, "Couldn't communicate with locale manager", e);
+ getLogger().logItemsRestoreFailed(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1,
+ ERROR_RESTORE_FAILED);
}
} else {
Slog.w(TAG, "Unexpected restore key " + key);
+ getLogger().logItemsBackupFailed(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1,
+ ERROR_UNEXPECTED_KEY);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
index d061e2d21811..fbd32a67fe6c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
@@ -31,7 +31,6 @@ import android.util.Slog;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.fingerprint.aidl.AidlSession;
import java.util.function.Supplier;
@@ -203,16 +202,6 @@ public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implement
}
}
- // TODO(b/317414324): Deprecate setIgnoreDisplayTouches
- protected final void resetIgnoreDisplayTouches() {
- final AidlSession session = (AidlSession) getFreshDaemon();
- try {
- session.getSession().setIgnoreDisplayTouches(false);
- } catch (RemoteException e) {
- Slog.e(TAG, "Remote exception when resetting setIgnoreDisplayTouches");
- }
- }
-
@Override
public boolean isInterruptable() {
return true;
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java b/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java
index eb78fe620c0b..a1184156f86e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java
@@ -20,7 +20,6 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.biometrics.BiometricConstants;
-import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
@@ -28,11 +27,12 @@ import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
+import com.android.modules.expresslog.Counter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
-import java.util.function.BooleanSupplier;
+
/**
* Contains all the necessary information for a HAL operation.
@@ -89,8 +89,6 @@ public class BiometricSchedulerOperation {
private final BaseClientMonitor mClientMonitor;
@Nullable
private final ClientMonitorCallback mClientCallback;
- @NonNull
- private final BooleanSupplier mIsDebuggable;
@Nullable
private ClientMonitorCallback mOnStartCallback;
@OperationState
@@ -99,6 +97,7 @@ public class BiometricSchedulerOperation {
@NonNull
final Runnable mCancelWatchdog;
+ @VisibleForTesting
BiometricSchedulerOperation(
@NonNull BaseClientMonitor clientMonitor,
@Nullable ClientMonitorCallback callback
@@ -106,33 +105,14 @@ public class BiometricSchedulerOperation {
this(clientMonitor, callback, STATE_WAITING_IN_QUEUE);
}
- @VisibleForTesting
- BiometricSchedulerOperation(
- @NonNull BaseClientMonitor clientMonitor,
- @Nullable ClientMonitorCallback callback,
- @NonNull BooleanSupplier isDebuggable
- ) {
- this(clientMonitor, callback, STATE_WAITING_IN_QUEUE, isDebuggable);
- }
-
protected BiometricSchedulerOperation(
@NonNull BaseClientMonitor clientMonitor,
@Nullable ClientMonitorCallback callback,
@OperationState int state
) {
- this(clientMonitor, callback, state, Build::isDebuggable);
- }
-
- private BiometricSchedulerOperation(
- @NonNull BaseClientMonitor clientMonitor,
- @Nullable ClientMonitorCallback callback,
- @OperationState int state,
- @NonNull BooleanSupplier isDebuggable
- ) {
mClientMonitor = clientMonitor;
mClientCallback = callback;
mState = state;
- mIsDebuggable = isDebuggable;
mCancelWatchdog = () -> {
if (!isFinished()) {
Slog.e(TAG, "[Watchdog Triggered]: " + this);
@@ -187,9 +167,7 @@ public class BiometricSchedulerOperation {
if (mClientMonitor.getCookie() != 0) {
String err = "operation requires cookie";
- if (mIsDebuggable.getAsBoolean()) {
- throw new IllegalStateException(err);
- }
+ Counter.logIncrement("biometric.value_biometric_scheduler_operation_state_error_count");
Slog.e(TAG, err);
}
@@ -456,10 +434,9 @@ public class BiometricSchedulerOperation {
private boolean errorWhenOneOf(String op, @OperationState int... states) {
final boolean isError = ArrayUtils.contains(states, mState);
if (isError) {
- String err = op + ": mState must not be " + mState;
- if (mIsDebuggable.getAsBoolean()) {
- throw new IllegalStateException(err);
- }
+ Counter.logIncrement(
+ "biometric.value_biometric_scheduler_operation_state_error_count");
+ final String err = op + ": mState must not be " + mState;
Slog.e(TAG, err);
}
return isError;
@@ -468,10 +445,10 @@ public class BiometricSchedulerOperation {
private boolean errorWhenNoneOf(String op, @OperationState int... states) {
final boolean isError = !ArrayUtils.contains(states, mState);
if (isError) {
- String err = op + ": mState=" + mState + " must be one of " + Arrays.toString(states);
- if (mIsDebuggable.getAsBoolean()) {
- throw new IllegalStateException(err);
- }
+ Counter.logIncrement(
+ "biometric.value_biometric_scheduler_operation_state_error_count");
+ final String err = op + ": mState=" + mState + " must be one of "
+ + Arrays.toString(states);
Slog.e(TAG, err);
}
return isError;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 4c86f57a190b..60cfd5a5a6ae 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -962,6 +962,19 @@ public class FingerprintService extends SystemService {
provider.onUdfpsUiEvent(event, requestId, sensorId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
+ @Override
+ public void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouches) {
+ super.setIgnoreDisplayTouches_enforcePermission();
+
+ final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+ if (provider == null) {
+ Slog.w(TAG,
+ "No matching provider for setIgnoreDisplayTouches, sensorId: " + sensorId);
+ return;
+ }
+ provider.setIgnoreDisplayTouches(requestId, sensorId, ignoreTouches);
+ }
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
index a6cf2f4b31ae..e4a99e6be72c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
@@ -134,6 +134,8 @@ public interface ServiceProvider extends
void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller);
+ void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouches);
+
void onPowerPressed();
@NonNull
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
index dce0175ca593..15d7a476b345 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
@@ -31,4 +31,5 @@ public interface Udfps {
void onPointerUp(PointerContext pc);
void onUdfpsUiEvent(@FingerprintManager.UdfpsUiEvent int event);
boolean isPointerDown();
+ void setIgnoreDisplayTouches(boolean ignoreTouches);
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 72d92b974c1a..d04afdb72913 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -33,7 +33,6 @@ import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcqu
import android.hardware.biometrics.BiometricManager.Authenticators;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.biometrics.common.ICancellationSignal;
-import android.hardware.biometrics.common.OperationState;
import android.hardware.biometrics.events.AuthenticationAcquiredInfo;
import android.hardware.biometrics.events.AuthenticationErrorInfo;
import android.hardware.biometrics.events.AuthenticationFailedInfo;
@@ -182,7 +181,6 @@ public class FingerprintAuthenticationClient
handleLockout(authenticated);
if (authenticated) {
mState = STATE_STOPPED;
- resetIgnoreDisplayTouches();
mSensorOverlays.hide(getSensorId());
if (reportBiometricAuthAttempts()) {
mAuthenticationStateListeners.onAuthenticationSucceeded(
@@ -223,7 +221,6 @@ public class FingerprintAuthenticationClient
// Send the error, but do not invoke the FinishCallback yet. Since lockout is not
// controlled by the HAL, the framework must stop the sensor before finishing the
// client.
- resetIgnoreDisplayTouches();
mSensorOverlays.hide(getSensorId());
mAuthenticationStateListeners.onAuthenticationError(
new AuthenticationErrorInfo.Builder(BiometricSourceType.FINGERPRINT,
@@ -275,7 +272,6 @@ public class FingerprintAuthenticationClient
BiometricNotificationUtils.showBadCalibrationNotification(getContext());
}
- resetIgnoreDisplayTouches();
mSensorOverlays.hide(getSensorId());
mAuthenticationStateListeners.onAuthenticationStopped(new AuthenticationStoppedInfo
.Builder(BiometricSourceType.FINGERPRINT, getRequestReason()).build()
@@ -284,7 +280,6 @@ public class FingerprintAuthenticationClient
@Override
protected void startHalOperation() {
- resetIgnoreDisplayTouches();
mSensorOverlays.show(getSensorId(), getRequestReason(), this);
mAuthenticationStateListeners.onAuthenticationStarted(new AuthenticationStartedInfo
.Builder(BiometricSourceType.FINGERPRINT, getRequestReason()).build()
@@ -331,12 +326,6 @@ public class FingerprintAuthenticationClient
if (session.hasContextMethods()) {
try {
session.getSession().onContextChanged(ctx);
- // TODO(b/317414324): Deprecate setIgnoreDisplayTouches
- if (ctx.operationState != null && ctx.operationState.getTag()
- == OperationState.fingerprintOperationState) {
- session.getSession().setIgnoreDisplayTouches(ctx.operationState
- .getFingerprintOperationState().isHardwareIgnoringTouches);
- }
} catch (RemoteException e) {
Slog.e(TAG, "Unable to notify context changed", e);
}
@@ -353,7 +342,6 @@ public class FingerprintAuthenticationClient
@Override
protected void stopHalOperation() {
- resetIgnoreDisplayTouches();
mSensorOverlays.hide(getSensorId());
mAuthenticationStateListeners.onAuthenticationStopped(new AuthenticationStoppedInfo
.Builder(BiometricSourceType.FINGERPRINT, getRequestReason()).build()
@@ -415,6 +403,15 @@ public class FingerprintAuthenticationClient
}
@Override
+ public void setIgnoreDisplayTouches(boolean ignoreTouches) {
+ try {
+ getFreshDaemon().getSession().setIgnoreDisplayTouches(ignoreTouches);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ }
+ }
+
+ @Override
public boolean isPointerDown() {
return mIsPointerDown;
}
@@ -457,7 +454,6 @@ public class FingerprintAuthenticationClient
Slog.e(TAG, "Remote exception", e);
}
- resetIgnoreDisplayTouches();
mSensorOverlays.hide(getSensorId());
mAuthenticationStateListeners.onAuthenticationStopped(new AuthenticationStoppedInfo
.Builder(BiometricSourceType.FINGERPRINT, getRequestReason()).build()
@@ -492,7 +488,6 @@ public class FingerprintAuthenticationClient
Slog.e(TAG, "Remote exception", e);
}
- resetIgnoreDisplayTouches();
mSensorOverlays.hide(getSensorId());
mAuthenticationStateListeners.onAuthenticationStopped(new AuthenticationStoppedInfo
.Builder(BiometricSourceType.FINGERPRINT, getRequestReason()).build()
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
index 36af5dba909f..fb48053913cf 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
@@ -87,7 +87,6 @@ public class FingerprintDetectClient extends AcquisitionClient<AidlSession>
@Override
protected void stopHalOperation() {
- resetIgnoreDisplayTouches();
mSensorOverlays.hide(getSensorId());
mAuthenticationStateListeners.onAuthenticationStopped(
new AuthenticationStoppedInfo.Builder(BiometricSourceType.FINGERPRINT,
@@ -107,7 +106,6 @@ public class FingerprintDetectClient extends AcquisitionClient<AidlSession>
@Override
protected void startHalOperation() {
- resetIgnoreDisplayTouches();
mSensorOverlays.show(getSensorId(), BiometricRequestConstants.REASON_AUTH_KEYGUARD,
this);
mAuthenticationStateListeners.onAuthenticationStarted(
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index 3a72d7e9a91a..993a68fd6ff8 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -150,7 +150,6 @@ public class FingerprintEnrollClient extends EnrollClient<AidlSession> implement
controller -> controller.onEnrollmentProgress(getSensorId(), remaining));
if (remaining == 0) {
- resetIgnoreDisplayTouches();
mSensorOverlays.hide(getSensorId());
mAuthenticationStateListeners.onAuthenticationStopped(
new AuthenticationStoppedInfo.Builder(
@@ -211,7 +210,6 @@ public class FingerprintEnrollClient extends EnrollClient<AidlSession> implement
);
super.onError(errorCode, vendorCode);
- resetIgnoreDisplayTouches();
mSensorOverlays.hide(getSensorId());
mAuthenticationStateListeners.onAuthenticationStopped(
new AuthenticationStoppedInfo.Builder(BiometricSourceType.FINGERPRINT,
@@ -227,7 +225,6 @@ public class FingerprintEnrollClient extends EnrollClient<AidlSession> implement
@Override
protected void startHalOperation() {
- resetIgnoreDisplayTouches();
mSensorOverlays.show(getSensorId(),
getRequestReasonFromFingerprintEnrollReason(mEnrollReason), this);
mAuthenticationStateListeners.onAuthenticationStarted(new AuthenticationStartedInfo
@@ -277,7 +274,6 @@ public class FingerprintEnrollClient extends EnrollClient<AidlSession> implement
@Override
protected void stopHalOperation() {
- resetIgnoreDisplayTouches();
mSensorOverlays.hide(getSensorId());
mAuthenticationStateListeners.onAuthenticationStopped(new AuthenticationStoppedInfo
.Builder(BiometricSourceType.FINGERPRINT,
@@ -359,5 +355,14 @@ public class FingerprintEnrollClient extends EnrollClient<AidlSession> implement
}
@Override
+ public void setIgnoreDisplayTouches(boolean ignoreTouches) {
+ try {
+ getFreshDaemon().getSession().setIgnoreDisplayTouches(ignoreTouches);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to send setIgnoreDisplayTouches", e);
+ }
+ }
+
+ @Override
public void onPowerPressed() {}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 1bddb83b1441..12baf00c1c4a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -790,6 +790,19 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
}
@Override
+ public void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouches) {
+ mFingerprintSensors.get(sensorId).getScheduler().getCurrentClientIfMatches(
+ requestId, (client) -> {
+ if (!(client instanceof Udfps)) {
+ Slog.e(getTag(),
+ "setIgnoreDisplayTouches received during client: " + client);
+ return;
+ }
+ ((Udfps) client).setIgnoreDisplayTouches(ignoreTouches);
+ });
+ }
+
+ @Override
public void onPowerPressed() {
for (int i = 0; i < mFingerprintSensors.size(); i++) {
final Sensor sensor = mFingerprintSensors.valueAt(i);
diff --git a/services/core/java/com/android/server/crashrecovery/CrashRecoveryModule.java b/services/core/java/com/android/server/crashrecovery/CrashRecoveryModule.java
new file mode 100644
index 000000000000..5f2fbcedce88
--- /dev/null
+++ b/services/core/java/com/android/server/crashrecovery/CrashRecoveryModule.java
@@ -0,0 +1,55 @@
+/*
+ * 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.crashrecovery;
+
+import android.content.Context;
+
+import com.android.server.PackageWatchdog;
+import com.android.server.RescueParty;
+import com.android.server.SystemService;
+
+
+/** This class encapsulate the lifecycle methods of CrashRecovery module. */
+public class CrashRecoveryModule {
+ private static final String TAG = "CrashRecoveryModule";
+
+ /** Lifecycle definition for CrashRecovery module. */
+ public static class Lifecycle extends SystemService {
+ private Context mSystemContext;
+ private PackageWatchdog mPackageWatchdog;
+
+ public Lifecycle(Context context) {
+ super(context);
+ mSystemContext = context;
+ mPackageWatchdog = PackageWatchdog.getInstance(context);
+ }
+
+ @Override
+ public void onStart() {
+ RescueParty.registerHealthObserver(mSystemContext);
+ mPackageWatchdog.registerShutdownBroadcastReceiver();
+ mPackageWatchdog.noteBoot();
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
+ mPackageWatchdog.onPackagesReady();
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/crashrecovery/TEST_MAPPING b/services/core/java/com/android/server/crashrecovery/TEST_MAPPING
index 4a66bac2e4ec..615db345635c 100644
--- a/services/core/java/com/android/server/crashrecovery/TEST_MAPPING
+++ b/services/core/java/com/android/server/crashrecovery/TEST_MAPPING
@@ -7,6 +7,9 @@
"include-filter": "com.android.server.RescuePartyTest"
}
]
+ },
+ {
+ "name": "CrashRecoveryModuleTests"
}
]
} \ No newline at end of file
diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java
index 9b37418bb6fe..515e70495f9e 100644
--- a/services/core/java/com/android/server/display/BrightnessRangeController.java
+++ b/services/core/java/com/android/server/display/BrightnessRangeController.java
@@ -22,6 +22,7 @@ import android.os.IBinder;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.brightness.clamper.HdrClamper;
+import com.android.server.display.config.HighBrightnessModeData;
import com.android.server.display.feature.DisplayManagerFlags;
import java.io.PrintWriter;
@@ -157,7 +158,7 @@ class BrightnessRangeController {
private void updateHdrClamper(DisplayDeviceInfo info, IBinder token,
DisplayDeviceConfig displayDeviceConfig) {
if (mUseHdrClamper) {
- DisplayDeviceConfig.HighBrightnessModeData hbmData =
+ HighBrightnessModeData hbmData =
displayDeviceConfig.getHighBrightnessModeData();
float minimumHdrPercentOfScreen =
hbmData == null ? -1f : hbmData.minimumHdrPercentOfScreen;
diff --git a/services/core/java/com/android/server/display/DisplayBrightnessState.java b/services/core/java/com/android/server/display/DisplayBrightnessState.java
index 184ae41fe045..222c5a83a551 100644
--- a/services/core/java/com/android/server/display/DisplayBrightnessState.java
+++ b/services/core/java/com/android/server/display/DisplayBrightnessState.java
@@ -29,9 +29,10 @@ import java.util.Objects;
*/
public final class DisplayBrightnessState {
public static final float CUSTOM_ANIMATION_RATE_NOT_SET = -1f;
+ public static final float BRIGHTNESS_NOT_SET = -1f;
private final float mBrightness;
- private final float mSdrBrightness;
+ private final float mHdrBrightness;
private final float mMaxBrightness;
private final float mMinBrightness;
@@ -51,7 +52,7 @@ public final class DisplayBrightnessState {
private DisplayBrightnessState(Builder builder) {
mBrightness = builder.getBrightness();
- mSdrBrightness = builder.getSdrBrightness();
+ mHdrBrightness = builder.getHdrBrightness();
mBrightnessReason = builder.getBrightnessReason();
mDisplayBrightnessStrategyName = builder.getDisplayBrightnessStrategyName();
mShouldUseAutoBrightness = builder.getShouldUseAutoBrightness();
@@ -73,10 +74,10 @@ public final class DisplayBrightnessState {
}
/**
- * Gets the sdr brightness
+ * Gets the hdr brightness
*/
- public float getSdrBrightness() {
- return mSdrBrightness;
+ public float getHdrBrightness() {
+ return mHdrBrightness;
}
/**
@@ -163,8 +164,8 @@ public final class DisplayBrightnessState {
StringBuilder stringBuilder = new StringBuilder("DisplayBrightnessState:");
stringBuilder.append("\n brightness:");
stringBuilder.append(getBrightness());
- stringBuilder.append("\n sdrBrightness:");
- stringBuilder.append(getSdrBrightness());
+ stringBuilder.append("\n hdrBrightness:");
+ stringBuilder.append(getHdrBrightness());
stringBuilder.append("\n brightnessReason:");
stringBuilder.append(getBrightnessReason());
stringBuilder.append("\n shouldUseAutoBrightness:");
@@ -198,7 +199,7 @@ public final class DisplayBrightnessState {
DisplayBrightnessState otherState = (DisplayBrightnessState) other;
return mBrightness == otherState.getBrightness()
- && mSdrBrightness == otherState.getSdrBrightness()
+ && mHdrBrightness == otherState.getHdrBrightness()
&& mBrightnessReason.equals(otherState.getBrightnessReason())
&& TextUtils.equals(mDisplayBrightnessStrategyName,
otherState.getDisplayBrightnessStrategyName())
@@ -216,7 +217,7 @@ public final class DisplayBrightnessState {
@Override
public int hashCode() {
- return Objects.hash(mBrightness, mSdrBrightness, mBrightnessReason,
+ return Objects.hash(mBrightness, mHdrBrightness, mBrightnessReason,
mShouldUseAutoBrightness, mIsSlowChange, mMaxBrightness, mMinBrightness,
mCustomAnimationRate,
mShouldUpdateScreenBrightnessSetting, mBrightnessEvent, mBrightnessAdjustmentFlag,
@@ -235,7 +236,7 @@ public final class DisplayBrightnessState {
*/
public static class Builder {
private float mBrightness;
- private float mSdrBrightness;
+ private float mHdrBrightness = BRIGHTNESS_NOT_SET;
private BrightnessReason mBrightnessReason = new BrightnessReason();
private String mDisplayBrightnessStrategyName;
private boolean mShouldUseAutoBrightness;
@@ -260,7 +261,7 @@ public final class DisplayBrightnessState {
public static Builder from(DisplayBrightnessState state) {
Builder builder = new Builder();
builder.setBrightness(state.getBrightness());
- builder.setSdrBrightness(state.getSdrBrightness());
+ builder.setHdrBrightness(state.getHdrBrightness());
builder.setBrightnessReason(state.getBrightnessReason());
builder.setDisplayBrightnessStrategyName(state.getDisplayBrightnessStrategyName());
builder.setShouldUseAutoBrightness(state.getShouldUseAutoBrightness());
@@ -295,20 +296,20 @@ public final class DisplayBrightnessState {
}
/**
- * Gets the sdr brightness
+ * Gets the hdr brightness
*/
- public float getSdrBrightness() {
- return mSdrBrightness;
+ public float getHdrBrightness() {
+ return mHdrBrightness;
}
/**
- * Sets the sdr brightness
+ * Sets the hdr brightness
*
- * @param sdrBrightness The sdr brightness to be associated with DisplayBrightnessState's
+ * @param hdrBrightness The hdr brightness to be associated with DisplayBrightnessState's
* builder
*/
- public Builder setSdrBrightness(float sdrBrightness) {
- this.mSdrBrightness = sdrBrightness;
+ public Builder setHdrBrightness(float hdrBrightness) {
+ this.mHdrBrightness = hdrBrightness;
return this;
}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index e4db634c0e26..7a055d1d7e5c 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -53,9 +53,9 @@ import com.android.server.display.config.DisplayBrightnessPoint;
import com.android.server.display.config.DisplayConfiguration;
import com.android.server.display.config.DisplayQuirks;
import com.android.server.display.config.EvenDimmerBrightnessData;
-import com.android.server.display.config.HbmTiming;
import com.android.server.display.config.HdrBrightnessData;
import com.android.server.display.config.HighBrightnessMode;
+import com.android.server.display.config.HighBrightnessModeData;
import com.android.server.display.config.HysteresisLevels;
import com.android.server.display.config.IdleScreenRefreshRateTimeout;
import com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholdPoint;
@@ -75,8 +75,6 @@ import com.android.server.display.config.RefreshRateRange;
import com.android.server.display.config.RefreshRateThrottlingMap;
import com.android.server.display.config.RefreshRateThrottlingPoint;
import com.android.server.display.config.RefreshRateZone;
-import com.android.server.display.config.SdrHdrRatioMap;
-import com.android.server.display.config.SdrHdrRatioPoint;
import com.android.server.display.config.SensorData;
import com.android.server.display.config.ThermalStatus;
import com.android.server.display.config.ThermalThrottling;
@@ -302,6 +300,19 @@ import javax.xml.datatype.DatatypeConfigurationException;
* <brightnessIncreaseDurationMillis>10000</brightnessIncreaseDurationMillis>
* <brightnessDecreaseDebounceMillis>13000</brightnessDecreaseDebounceMillis>
* <brightnessDecreaseDurationMillis>10000</brightnessDecreaseDurationMillis>
+ * <minimumHdrPercentOfScreenForNbm>0.2</minimumHdrPercentOfScreenForNbm>
+ * <minimumHdrPercentOfScreenForHbm>0.5</minimumHdrPercentOfScreenForHbm>
+ * <allowInLowPowerMode>true</allowInLowPowerMode>
+ * <sdrHdrRatioMap>
+ * <point>
+ * <first>2.0</first>
+ * <second>4.0</second>
+ * </point>
+ * <point>
+ * <first>100</first>
+ * <second>8.0</second>
+ * </point>
+ * </sdrHdrRatioMap>
* </hdrBrightnessConfig>
* <luxThrottling>
* <brightnessLimitMap>
@@ -608,6 +619,15 @@ import javax.xml.datatype.DatatypeConfigurationException;
* </idleScreenRefreshRateTimeout>
* <supportsVrr>true</supportsVrr>
*
+ * <dozeBrightnessSensorValueToBrightness>
+ * <item>-1</item> <!-- 0: OFF -->
+ * <item>0.003937008</item> <!-- 1: NIGHT -->
+ * <item>0.015748031</item> <!-- 2: LOW -->
+ * <item>0.102362205</item> <!-- 3: HIGH -->
+ * <item>0.106299213</item> <!-- 4: SUN -->
+ * </dozeBrightnessSensorValueToBrightness>
+ * <defaultDozeBrightness>0.235</defaultDozeBrightness>
+ *
* </displayConfiguration>
* }
* </pre>
@@ -627,6 +647,10 @@ public class DisplayDeviceConfig {
public static final int DEFAULT_LOW_REFRESH_RATE = 60;
+ // Float.NaN (used as invalid for brightness) cannot be stored in config.xml
+ // so -2 is used instead
+ public static final float INVALID_BRIGHTNESS_IN_CONFIG = -2f;
+
@VisibleForTesting
static final float BRIGHTNESS_DEFAULT = 0.5f;
private static final String ETC_DIR = "etc";
@@ -645,10 +669,6 @@ public class DisplayDeviceConfig {
private static final int INTERPOLATION_DEFAULT = 0;
private static final int INTERPOLATION_LINEAR = 1;
- // Float.NaN (used as invalid for brightness) cannot be stored in config.xml
- // so -2 is used instead
- private static final float INVALID_BRIGHTNESS_IN_CONFIG = -2f;
-
// Length of the ambient light horizon used to calculate the long term estimate of ambient
// light.
private static final int AMBIENT_LIGHT_LONG_HORIZON_MILLIS = 10000;
@@ -662,6 +682,8 @@ public class DisplayDeviceConfig {
@VisibleForTesting
static final float HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT = 0.5f;
+ private static final int KEEP_CURRENT_BRIGHTNESS = -1;
+
private final Context mContext;
// The details of the ambient light sensor associated with this display.
@@ -743,13 +765,13 @@ public class DisplayDeviceConfig {
private Spline mNitsToBacklightSpline;
private List<String> mQuirks;
- private boolean mIsHighBrightnessModeEnabled = false;
+ @Nullable
private HighBrightnessModeData mHbmData;
@Nullable
private PowerThrottlingConfigData mPowerThrottlingConfigData;
private DensityMapping mDensityMapping;
private String mLoadedFrom = null;
- private Spline mSdrToHdrRatioSpline;
+
// Represents the auto-brightness brightening light debounce.
private long mAutoBrightnessBrighteningLightDebounce =
@@ -869,10 +891,14 @@ public class DisplayDeviceConfig {
private boolean mVrrSupportEnabled;
+ @Nullable
+ private float[] mDozeBrightnessSensorValueToBrightness;
+ private float mDefaultDozeBrightness;
+
private final DisplayManagerFlags mFlags;
@VisibleForTesting
- DisplayDeviceConfig(Context context, DisplayManagerFlags flags) {
+ public DisplayDeviceConfig(Context context, DisplayManagerFlags flags) {
mContext = context;
mFlags = flags;
}
@@ -1155,7 +1181,7 @@ public class DisplayDeviceConfig {
* @return true if there is sdrHdrRatioMap, false otherwise.
*/
public boolean hasSdrToHdrRatioSpline() {
- return mSdrToHdrRatioSpline != null;
+ return mHbmData != null && mHbmData.sdrToHdrRatioSpline != null;
}
/**
@@ -1165,7 +1191,8 @@ public class DisplayDeviceConfig {
* @return the HDR brightness or BRIGHTNESS_INVALID when no mapping exists.
*/
public float getHdrBrightnessFromSdr(float brightness, float maxDesiredHdrSdrRatio) {
- if (mSdrToHdrRatioSpline == null) {
+ Spline sdrToHdrSpline = mHbmData != null ? mHbmData.sdrToHdrRatioSpline : null;
+ if (sdrToHdrSpline == null) {
return PowerManager.BRIGHTNESS_INVALID;
}
@@ -1175,7 +1202,7 @@ public class DisplayDeviceConfig {
return PowerManager.BRIGHTNESS_INVALID;
}
- float ratio = Math.min(mSdrToHdrRatioSpline.interpolate(nits), maxDesiredHdrSdrRatio);
+ float ratio = Math.min(sdrToHdrSpline.interpolate(nits), maxDesiredHdrSdrRatio);
float hdrNits = nits * ratio;
if (getNitsToBacklightSpline() == null) {
return PowerManager.BRIGHTNESS_INVALID;
@@ -1321,13 +1348,11 @@ public class DisplayDeviceConfig {
* @return high brightness mode configuration data for the display.
*/
public HighBrightnessModeData getHighBrightnessModeData() {
- if (!mIsHighBrightnessModeEnabled || mHbmData == null) {
+ if (mHbmData == null || !mHbmData.isHighBrightnessModeEnabled) {
return null;
}
- HighBrightnessModeData hbmData = new HighBrightnessModeData();
- mHbmData.copyTo(hbmData);
- return hbmData;
+ return mHbmData;
}
/**
@@ -1585,6 +1610,24 @@ public class DisplayDeviceConfig {
return mVrrSupportEnabled;
}
+ /**
+ * While the device is dozing, a designated light sensor is used to determine the brightness.
+ * @return The mapping between doze brightness sensor values and brightness values. The value
+ * -1 means that the current brightness should be kept.
+ */
+ @Nullable
+ public float[] getDozeBrightnessSensorValueToBrightness() {
+ return mDozeBrightnessSensorValueToBrightness;
+ }
+
+ /**
+ * @return The default doze brightness to use while no other doze brightness is available. Can
+ * be {@link PowerManager#BRIGHTNESS_INVALID_FLOAT} if undefined.
+ */
+ public float getDefaultDozeBrightness() {
+ return mDefaultDozeBrightness;
+ }
+
@Override
public String toString() {
return "DisplayDeviceConfig{"
@@ -1604,11 +1647,10 @@ public class DisplayDeviceConfig {
+ ", mBacklightMaximum=" + mBacklightMaximum
+ ", mBrightnessDefault=" + mBrightnessDefault
+ ", mQuirks=" + mQuirks
- + ", mIsHighBrightnessModeEnabled=" + mIsHighBrightnessModeEnabled
+ "\n"
+ "mLuxThrottlingData=" + mLuxThrottlingData
+ ", mHbmData=" + mHbmData
- + ", mSdrToHdrRatioSpline=" + mSdrToHdrRatioSpline
+
+ ", mThermalBrightnessThrottlingDataMapByThrottlingId="
+ mThermalBrightnessThrottlingDataMapByThrottlingId
+ "\n"
@@ -1683,6 +1725,9 @@ public class DisplayDeviceConfig {
? mEvenDimmerBrightnessData.toString() : "null")
+ "\n"
+ "mVrrSupported= " + mVrrSupportEnabled + "\n"
+ + "mDozeBrightnessSensorValueToBrightness= "
+ + Arrays.toString(mDozeBrightnessSensorValueToBrightness) + "\n"
+ + "mDefaultDozeBrightness= " + mDefaultDozeBrightness + "\n"
+ "}";
}
@@ -1715,7 +1760,7 @@ public class DisplayDeviceConfig {
}
@VisibleForTesting
- boolean initFromFile(File configFile) {
+ public boolean initFromFile(File configFile) {
if (!configFile.exists()) {
// Display configuration files aren't required to exist.
return false;
@@ -1740,7 +1785,23 @@ public class DisplayDeviceConfig {
loadBrightnessMap(config);
loadThermalThrottlingConfig(config);
loadPowerThrottlingConfigData(config);
- loadHighBrightnessModeData(config);
+ // Backlight and evenDimmer data should be loaded for HbmData
+ mHbmData = HighBrightnessModeData.loadHighBrightnessModeData(config, (hbm) -> {
+ float transitionPointBacklightScale = hbm.getTransitionPoint_all().floatValue();
+ if (transitionPointBacklightScale >= mBacklightMaximum) {
+ throw new IllegalArgumentException("HBM transition point invalid. "
+ + mHbmData.transitionPoint + " is not less than "
+ + mBacklightMaximum);
+ }
+ return getBrightnessFromBacklight(transitionPointBacklightScale);
+ });
+ if (mHbmData.isHighBrightnessModeEnabled && mHbmData.refreshRateLimit != null) {
+ // TODO(b/331650248): cleanup, DMD can use mHbmData.refreshRateLimit
+ mRefreshRateLimitations.add(new RefreshRateLimitation(
+ DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE,
+ mHbmData.refreshRateLimit));
+ }
+
loadLuxThrottling(config);
loadQuirks(config);
loadBrightnessRamps(config);
@@ -1761,6 +1822,7 @@ public class DisplayDeviceConfig {
loadBrightnessCapForWearBedtimeMode(config);
loadIdleScreenRefreshRateTimeoutConfigs(config);
mVrrSupportEnabled = config.getSupportsVrr();
+ loadDozeBrightness(config);
} else {
Slog.w(TAG, "DisplayDeviceConfig file is null");
}
@@ -1789,6 +1851,7 @@ public class DisplayDeviceConfig {
loadRefreshRateSetting(null);
loadBrightnessCapForWearBedtimeModeFromConfigXml();
loadIdleScreenRefreshRateTimeoutConfigs(null);
+ loadDozeBrightness(null);
mLoadedFrom = "<config.xml>";
}
@@ -1938,40 +2001,6 @@ public class DisplayDeviceConfig {
constrainNitsAndBacklightArrays();
}
- private Spline loadSdrHdrRatioMap(HighBrightnessMode hbmConfig) {
- final SdrHdrRatioMap sdrHdrRatioMap = hbmConfig.getSdrHdrRatioMap_all();
-
- if (sdrHdrRatioMap == null) {
- return null;
- }
-
- final List<SdrHdrRatioPoint> points = sdrHdrRatioMap.getPoint();
- final int size = points.size();
- if (size == 0) {
- return null;
- }
-
- float[] nits = new float[size];
- float[] ratios = new float[size];
-
- int i = 0;
- for (SdrHdrRatioPoint point : points) {
- nits[i] = point.getSdrNits().floatValue();
- if (i > 0) {
- if (nits[i] < nits[i - 1]) {
- Slog.e(TAG, "sdrHdrRatioMap must be non-decreasing, ignoring rest "
- + " of configuration. nits: " + nits[i] + " < "
- + nits[i - 1]);
- return null;
- }
- }
- ratios[i] = point.getHdrRatio().floatValue();
- ++i;
- }
-
- return Spline.createSpline(nits, ratios);
- }
-
private void loadThermalThrottlingConfig(DisplayConfiguration config) {
final ThermalThrottling throttlingConfig = config.getThermalThrottling();
if (throttlingConfig == null) {
@@ -2525,49 +2554,6 @@ public class DisplayDeviceConfig {
}
}
- private void loadHighBrightnessModeData(DisplayConfiguration config) {
- final HighBrightnessMode hbm = config.getHighBrightnessMode();
- if (hbm != null) {
- mIsHighBrightnessModeEnabled = hbm.getEnabled();
- mHbmData = new HighBrightnessModeData();
- mHbmData.minimumLux = hbm.getMinimumLux_all().floatValue();
- float transitionPointBacklightScale = hbm.getTransitionPoint_all().floatValue();
- if (transitionPointBacklightScale >= mBacklightMaximum) {
- throw new IllegalArgumentException("HBM transition point invalid. "
- + mHbmData.transitionPoint + " is not less than "
- + mBacklightMaximum);
- }
- mHbmData.transitionPoint =
- getBrightnessFromBacklight(transitionPointBacklightScale);
- final HbmTiming hbmTiming = hbm.getTiming_all();
- mHbmData.timeWindowMillis = hbmTiming.getTimeWindowSecs_all().longValue() * 1000;
- mHbmData.timeMaxMillis = hbmTiming.getTimeMaxSecs_all().longValue() * 1000;
- mHbmData.timeMinMillis = hbmTiming.getTimeMinSecs_all().longValue() * 1000;
- mHbmData.allowInLowPowerMode = hbm.getAllowInLowPowerMode_all();
- final RefreshRateRange rr = hbm.getRefreshRate_all();
- if (rr != null) {
- final float min = rr.getMinimum().floatValue();
- final float max = rr.getMaximum().floatValue();
- mRefreshRateLimitations.add(new RefreshRateLimitation(
- DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE, min, max));
- }
- BigDecimal minHdrPctOfScreen = hbm.getMinimumHdrPercentOfScreen_all();
- if (minHdrPctOfScreen != null) {
- mHbmData.minimumHdrPercentOfScreen = minHdrPctOfScreen.floatValue();
- if (mHbmData.minimumHdrPercentOfScreen > 1
- || mHbmData.minimumHdrPercentOfScreen < 0) {
- Slog.w(TAG, "Invalid minimum HDR percent of screen: "
- + String.valueOf(mHbmData.minimumHdrPercentOfScreen));
- mHbmData.minimumHdrPercentOfScreen = HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT;
- }
- } else {
- mHbmData.minimumHdrPercentOfScreen = HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT;
- }
-
- mSdrToHdrRatioSpline = loadSdrHdrRatioMap(hbm);
- }
- }
-
private void loadLuxThrottling(DisplayConfiguration config) {
LuxThrottling cfg = config.getLuxThrottling();
if (cfg != null) {
@@ -2800,6 +2786,37 @@ public class DisplayDeviceConfig {
}
}
+ private void loadDozeBrightness(DisplayConfiguration config) {
+ if (mFlags.isDozeBrightnessFloatEnabled() && config != null
+ && config.getDozeBrightnessSensorValueToBrightness() != null) {
+ List<BigDecimal> values = config.getDozeBrightnessSensorValueToBrightness().getItem();
+ mDozeBrightnessSensorValueToBrightness = new float[values.size()];
+ for (int i = 0; i < values.size(); i++) {
+ float backlight = values.get(i).floatValue();
+ if (backlight != KEEP_CURRENT_BRIGHTNESS) {
+ mDozeBrightnessSensorValueToBrightness[i] =
+ getBrightnessFromBacklight(backlight);
+ } else {
+ mDozeBrightnessSensorValueToBrightness[i] = KEEP_CURRENT_BRIGHTNESS;
+ }
+ }
+ }
+
+ if (mFlags.isDozeBrightnessFloatEnabled() && config != null
+ && config.getDefaultDozeBrightness() != null) {
+ float backlight = config.getDefaultDozeBrightness().floatValue();
+ mDefaultDozeBrightness = getBrightnessFromBacklight(backlight);
+ } else {
+ mDefaultDozeBrightness = mContext.getResources().getFloat(
+ com.android.internal.R.dimen.config_screenBrightnessDozeFloat);
+ if (mDefaultDozeBrightness == INVALID_BRIGHTNESS_IN_CONFIG) {
+ mDefaultDozeBrightness = BrightnessSynchronizer.brightnessIntToFloat(
+ mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_screenBrightnessDoze));
+ }
+ }
+ }
+
private void validateIdleScreenRefreshRateTimeoutConfig(
IdleScreenRefreshRateTimeout idleScreenRefreshRateTimeoutConfig) {
IdleScreenRefreshRateTimeoutLuxThresholds idleScreenRefreshRateTimeoutLuxThresholds =
@@ -2921,73 +2938,6 @@ public class DisplayDeviceConfig {
}
/**
- * Container for high brightness mode configuration data.
- */
- static class HighBrightnessModeData {
- /** Minimum lux needed to enter high brightness mode */
- public float minimumLux;
-
- /** Brightness level at which we transition from normal to high-brightness. */
- public float transitionPoint;
-
- /** Whether HBM is allowed when {@code Settings.Global.LOW_POWER_MODE} is active. */
- public boolean allowInLowPowerMode;
-
- /** Time window for HBM. */
- public long timeWindowMillis;
-
- /** Maximum time HBM is allowed to be during in a {@code timeWindowMillis}. */
- public long timeMaxMillis;
-
- /** Minimum time that HBM can be on before being enabled. */
- public long timeMinMillis;
-
- /** Minimum HDR video size to enter high brightness mode */
- public float minimumHdrPercentOfScreen;
-
- HighBrightnessModeData() {}
-
- HighBrightnessModeData(float minimumLux, float transitionPoint, long timeWindowMillis,
- long timeMaxMillis, long timeMinMillis, boolean allowInLowPowerMode,
- float minimumHdrPercentOfScreen) {
- this.minimumLux = minimumLux;
- this.transitionPoint = transitionPoint;
- this.timeWindowMillis = timeWindowMillis;
- this.timeMaxMillis = timeMaxMillis;
- this.timeMinMillis = timeMinMillis;
- this.allowInLowPowerMode = allowInLowPowerMode;
- this.minimumHdrPercentOfScreen = minimumHdrPercentOfScreen;
- }
-
- /**
- * Copies the HBM data to the specified parameter instance.
- * @param other the instance to copy data to.
- */
- public void copyTo(@NonNull HighBrightnessModeData other) {
- other.minimumLux = minimumLux;
- other.timeWindowMillis = timeWindowMillis;
- other.timeMaxMillis = timeMaxMillis;
- other.timeMinMillis = timeMinMillis;
- other.transitionPoint = transitionPoint;
- other.allowInLowPowerMode = allowInLowPowerMode;
- other.minimumHdrPercentOfScreen = minimumHdrPercentOfScreen;
- }
-
- @Override
- public String toString() {
- return "HBM{"
- + "minLux: " + minimumLux
- + ", transition: " + transitionPoint
- + ", timeWindow: " + timeWindowMillis + "ms"
- + ", timeMax: " + timeMaxMillis + "ms"
- + ", timeMin: " + timeMinMillis + "ms"
- + ", allowInLowPowerMode: " + allowInLowPowerMode
- + ", minimumHdrPercentOfScreen: " + minimumHdrPercentOfScreen
- + "} ";
- }
- }
-
- /**
* Container for Power throttling configuration data.
* TODO(b/302814899): extract to separate class.
*/
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 43c1f24f2b73..b3a6c1c1e20a 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -823,6 +823,13 @@ public final class DisplayManagerService extends SystemService {
}
@VisibleForTesting
+ void setDisplayState(int displayId, int state) {
+ synchronized (mSyncRoot) {
+ mDisplayStates.setValueAt(displayId, state);
+ }
+ }
+
+ @VisibleForTesting
Handler getDisplayHandler() {
return mHandler;
}
@@ -1940,6 +1947,27 @@ public final class DisplayManagerService extends SystemService {
}
}
+ private void setVirtualDisplayRotationInternal(IBinder appToken,
+ @Surface.Rotation int rotation) {
+ int displayId;
+ synchronized (mSyncRoot) {
+ if (mVirtualDisplayAdapter == null) {
+ return;
+ }
+ DisplayDevice device = mVirtualDisplayAdapter.getDisplayDevice(appToken);
+ if (device == null) {
+ return;
+ }
+ LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
+ if (display == null) {
+ return;
+ }
+ displayId = display.getDisplayIdLocked();
+ }
+ mWindowManagerInternal.setNonDefaultDisplayRotation(
+ displayId, rotation, /* caller= */ "Virtual Display");
+ }
+
private void registerDefaultDisplayAdapters() {
// Register default display adapters.
synchronized (mSyncRoot) {
@@ -3411,27 +3439,39 @@ public final class DisplayManagerService extends SystemService {
}
}
- boolean requestDisplayPower(int displayId, boolean on) {
+ boolean requestDisplayPower(int displayId, int requestedState) {
synchronized (mSyncRoot) {
final var display = mLogicalDisplayMapper.getDisplayLocked(displayId);
if (display == null) {
- Slog.w(TAG, "requestDisplayPower: Cannot find a display with displayId="
+ Slog.w(TAG, "requestDisplayPower: Cannot find the display with displayId="
+ displayId);
return false;
}
+ var state = requestedState;
+ if (state == Display.STATE_UNKNOWN) {
+ state = mDisplayStates.get(displayId);
+ }
+
final BrightnessPair brightnessPair = mDisplayBrightnesses.get(displayId);
+ var brightnessState = brightnessPair.brightness;
+ if (state == Display.STATE_OFF) {
+ brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
+ }
+
var runnable = display.getPrimaryDisplayDeviceLocked().requestDisplayStateLocked(
- on ? Display.STATE_ON : Display.STATE_OFF,
- on ? brightnessPair.brightness : PowerManager.BRIGHTNESS_OFF_FLOAT,
+ state,
+ brightnessState,
brightnessPair.sdrBrightness,
display.getDisplayOffloadSessionLocked());
if (runnable == null) {
- Slog.w(TAG, "requestDisplayPower: Cannot update the power state to ON=" + on
- + " for a display with displayId=" + displayId + ", runnable is null");
+ Slog.w(TAG, "requestDisplayPower: Cannot set power state = " + state
+ + " for the display with displayId=" + displayId + ","
+ + " requestedState=" + requestedState + ": runnable is null");
return false;
}
runnable.run();
- Slog.i(TAG, "requestDisplayPower(displayId=" + displayId + ", on=" + on + ")");
+ Slog.i(TAG, "requestDisplayPower(displayId=" + displayId
+ + ", requestedState=" + requestedState + "): state set to " + state);
}
return true;
}
@@ -4180,6 +4220,20 @@ public final class DisplayManagerService extends SystemService {
}
@Override // Binder call
+ public void setVirtualDisplayRotation(IVirtualDisplayCallback callback,
+ @Surface.Rotation int rotation) {
+ if (!android.companion.virtualdevice.flags.Flags.virtualDisplayRotationApi()) {
+ return;
+ }
+ final long token = Binder.clearCallingIdentity();
+ try {
+ setVirtualDisplayRotationInternal(callback.asBinder(), rotation);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
public void dump(@NonNull FileDescriptor fd, @NonNull final PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
@@ -4660,9 +4714,9 @@ public final class DisplayManagerService extends SystemService {
}
@EnforcePermission(MANAGE_DISPLAYS)
- public boolean requestDisplayPower(int displayId, boolean on) {
+ public boolean requestDisplayPower(int displayId, int state) {
requestDisplayPower_enforcePermission();
- return DisplayManagerService.this.requestDisplayPower(displayId, on);
+ return DisplayManagerService.this.requestDisplayPower(displayId, state);
}
@EnforcePermission(RESTRICT_DISPLAY_MODES)
@@ -4672,6 +4726,32 @@ public final class DisplayManagerService extends SystemService {
DisplayManagerService.this.mDisplayModeDirector.requestDisplayModes(
token, displayId, modeIds);
}
+
+ @EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
+ @Override // Binder call
+ public float[] getDozeBrightnessSensorValueToBrightness(int displayId) {
+ getDozeBrightnessSensorValueToBrightness_enforcePermission();
+ DisplayDeviceConfig ddc =
+ mDisplayDeviceConfigProvider.getDisplayDeviceConfig(displayId);
+ if (ddc == null) {
+ throw new IllegalArgumentException(
+ "Display ID does not have a config: " + displayId);
+ }
+ return ddc.getDozeBrightnessSensorValueToBrightness();
+ }
+
+ @EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
+ @Override // Binder call
+ public float getDefaultDozeBrightness(int displayId) {
+ getDefaultDozeBrightness_enforcePermission();
+ DisplayDeviceConfig ddc =
+ mDisplayDeviceConfigProvider.getDisplayDeviceConfig(displayId);
+ if (ddc == null) {
+ throw new IllegalArgumentException(
+ "Display ID does not have a config for doze-default: " + displayId);
+ }
+ return ddc.getDefaultDozeBrightness();
+ }
}
private static boolean isValidBrightness(float brightness) {
@@ -4787,6 +4867,8 @@ public final class DisplayManagerService extends SystemService {
}
final int[] supportedStates =
mDeviceStateManager.getSupportedStateIdentifiers();
+ // TODO(b/352019542): remove the log once b/345960547 is fixed.
+ Slog.d(TAG, "supportedStates=" + Arrays.toString(supportedStates));
DisplayInfo displayInfo;
for (int state : supportedStates) {
displayInfo = mLogicalDisplayMapper.getDisplayInfoForStateLocked(state,
@@ -4795,6 +4877,8 @@ public final class DisplayManagerService extends SystemService {
possibleInfo.add(displayInfo);
}
}
+ // TODO(b/352019542): remove the log once b/345960547 is fixed.
+ Slog.d(TAG, "possibleInfos=" + possibleInfo);
return possibleInfo;
}
}
@@ -5182,7 +5266,7 @@ public final class DisplayManagerService extends SystemService {
mHandler.sendMessage(msg);
mLogicalDisplayMapper
- .setDeviceStateLocked(deviceState.getIdentifier());
+ .setDeviceStateLocked(deviceState);
}
}
};
diff --git a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
index d973b71366b1..e46397bc8ab7 100644
--- a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
+++ b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
@@ -62,6 +62,8 @@ class DisplayManagerShellCommand extends ShellCommand {
return showNotification();
case "cancel-notifications":
return cancelNotifications();
+ case "get-brightness":
+ return getBrightness();
case "set-brightness":
return setBrightness();
case "reset-brightness-configuration":
@@ -106,10 +108,10 @@ class DisplayManagerShellCommand extends ShellCommand {
return setDisplayEnabled(true);
case "disable-display":
return setDisplayEnabled(false);
- case "power-on":
- return requestDisplayPower(true);
+ case "power-reset":
+ return requestDisplayPower(Display.STATE_UNKNOWN);
case "power-off":
- return requestDisplayPower(false);
+ return requestDisplayPower(Display.STATE_OFF);
default:
return handleDefaultCommands(cmd);
}
@@ -183,6 +185,10 @@ class DisplayManagerShellCommand extends ShellCommand {
pw.println(" disable-display DISPLAY_ID");
pw.println(" Disable the DISPLAY_ID. Only possible if this is a connected display.");
}
+ pw.println(" power-reset DISPLAY_ID");
+ pw.println(" Turn the DISPLAY_ID power to a state the display supposed to have.");
+ pw.println(" power-off DISPLAY_ID");
+ pw.println(" Turn the display DISPLAY_ID power off.");
pw.println();
Intent.printIntentArgsHelp(pw , "");
}
@@ -309,6 +315,25 @@ class DisplayManagerShellCommand extends ShellCommand {
return 0;
}
+ private int getBrightness() {
+ String displayIdString = getNextArg();
+ if (displayIdString == null) {
+ getErrPrintWriter().println("Error: no display id specified");
+ return 1;
+ }
+ int displayId;
+ try {
+ displayId = Integer.parseInt(displayIdString);
+ } catch (NumberFormatException e) {
+ getErrPrintWriter().println("Error: invalid displayId=" + displayIdString + " not int");
+ return 1;
+ }
+ final Context context = mService.getContext();
+ final DisplayManager dm = context.getSystemService(DisplayManager.class);
+ getOutPrintWriter().println(dm.getBrightness(displayId));
+ return 0;
+ }
+
private int setBrightness() {
String brightnessText = getNextArg();
if (brightnessText == null) {
@@ -597,7 +622,7 @@ class DisplayManagerShellCommand extends ShellCommand {
return 0;
}
- private int requestDisplayPower(boolean enable) {
+ private int requestDisplayPower(int state) {
final String displayIdText = getNextArg();
if (displayIdText == null) {
getErrPrintWriter().println("Error: no displayId specified");
@@ -610,7 +635,7 @@ class DisplayManagerShellCommand extends ShellCommand {
getErrPrintWriter().println("Error: invalid displayId: '" + displayIdText + "'");
return 1;
}
- mService.requestDisplayPower(displayId, enable);
+ mService.requestDisplayPower(displayId, state);
return 0;
}
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 7cd9144be77b..5c1e783c0f52 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -87,6 +87,7 @@ import com.android.server.display.brightness.strategy.AutomaticBrightnessStrateg
import com.android.server.display.brightness.strategy.DisplayBrightnessStrategyConstants;
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
+import com.android.server.display.config.HighBrightnessModeData;
import com.android.server.display.config.HysteresisLevels;
import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.layout.Layout;
@@ -271,7 +272,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private final SettingsObserver mSettingsObserver;
// The doze screen brightness.
- private final float mScreenBrightnessDozeConfig;
+ private float mScreenBrightnessDozeConfig;
// True if auto-brightness should be used.
private boolean mUseSoftwareAutoBrightnessConfig;
@@ -549,7 +550,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// DOZE AND DIM SETTINGS
mScreenBrightnessDozeConfig = BrightnessUtils.clampAbsoluteBrightness(
- pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE));
+ mDisplayDeviceConfig.getDefaultDozeBrightness());
loadBrightnessRampRates();
mSkipScreenOnBrightnessRamp = resources.getBoolean(
R.bool.config_skipScreenOnBrightnessRamp);
@@ -931,6 +932,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
HighBrightnessModeMetadata hbmMetadata) {
// All properties that depend on the associated DisplayDevice and the DDC must be
// updated here.
+ mScreenBrightnessDozeConfig = BrightnessUtils.clampAbsoluteBrightness(
+ mDisplayDeviceConfig.getDefaultDozeBrightness());
loadBrightnessRampRates();
loadNitsRange(mContext.getResources());
setUpAutoBrightness(mContext, mHandler);
@@ -1485,6 +1488,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|| !mAutomaticBrightnessStrategy.shouldUseAutoBrightness())) {
rawBrightnessState = getDozeBrightnessForOffload();
brightnessState = clampScreenBrightness(rawBrightnessState);
+ updateScreenBrightnessSetting = false;
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_MANUAL);
mTempBrightnessEvent.setFlags(
mTempBrightnessEvent.getFlags() | BrightnessEvent.FLAG_DOZE_SCALE);
@@ -1632,9 +1636,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// use instead. We still preserve the calculated brightness for Standard Dynamic Range
// (SDR) layers, but the main brightness value will be the one for HDR.
float sdrAnimateValue = animateValue;
- // TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
- // done in HighBrightnessModeController.
- if (mBrightnessRangeController.getHighBrightnessMode()
+
+ if (clampedState.getHdrBrightness() != DisplayBrightnessState.BRIGHTNESS_NOT_SET) {
+ // TODO(b/343792639): The decision to prevent HBM for HDR in low power mode will be
+ // done in HdrBrightnessModifier.
+ // customAnimationRate and reason also handled by HdrBrightnessModifier
+ animateValue = clampedState.getHdrBrightness();
+ } else if (mBrightnessRangeController.getHighBrightnessMode()
== BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
&& (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0
&& (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_LOW_POWER)
@@ -2012,7 +2020,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
final DisplayDeviceConfig ddConfig = mDisplayDevice.getDisplayDeviceConfig();
final IBinder displayToken = mDisplayDevice.getDisplayTokenLocked();
final String displayUniqueId = mDisplayDevice.getUniqueId();
- final DisplayDeviceConfig.HighBrightnessModeData hbmData =
+ final HighBrightnessModeData hbmData =
ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
final DisplayDeviceInfo info = mDisplayDevice.getDisplayDeviceInfoLocked();
return mInjector.getHighBrightnessModeController(mHandler, info.width, info.height,
@@ -3246,7 +3254,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
HighBrightnessModeController getHighBrightnessModeController(Handler handler, int width,
int height, IBinder displayToken, String displayUniqueId, float brightnessMin,
- float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData,
+ float brightnessMax, HighBrightnessModeData hbmData,
HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg,
Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata,
Context context) {
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeController.java b/services/core/java/com/android/server/display/HighBrightnessModeController.java
index 47176fe331bf..da9eef2d7459 100644
--- a/services/core/java/com/android/server/display/HighBrightnessModeController.java
+++ b/services/core/java/com/android/server/display/HighBrightnessModeController.java
@@ -36,8 +36,8 @@ import android.view.SurfaceControlHdrLayerInfoListener;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.util.FrameworkStatsLog;
-import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData;
import com.android.server.display.DisplayManagerService.Clock;
+import com.android.server.display.config.HighBrightnessModeData;
import com.android.server.display.utils.DebugUtils;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index e645e98c215c..e9ecfc67b7db 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -16,12 +16,18 @@
package com.android.server.display;
+import static android.hardware.devicestate.DeviceState.PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP;
+import static android.hardware.devicestate.DeviceState.PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE;
+import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
import static android.view.Display.DEFAULT_DISPLAY;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.hardware.devicestate.DeviceState;
import android.hardware.devicestate.DeviceStateManager;
+import android.hardware.devicestate.feature.flags.FeatureFlags;
+import android.hardware.devicestate.feature.flags.FeatureFlagsImpl;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -198,14 +204,14 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
private final DisplayIdProducer mIdProducer = (isDefault) ->
isDefault ? DEFAULT_DISPLAY : sNextNonDefaultDisplayId++;
private Layout mCurrentLayout = null;
- private int mDeviceState = DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
- private int mPendingDeviceState = DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
- private int mDeviceStateToBeAppliedAfterBoot =
- DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
+ private DeviceState mDeviceState = INVALID_DEVICE_STATE;
+ private DeviceState mPendingDeviceState = INVALID_DEVICE_STATE;
+ private DeviceState mDeviceStateToBeAppliedAfterBoot = INVALID_DEVICE_STATE;
private boolean mBootCompleted = false;
private boolean mInteractive;
private final DisplayManagerFlags mFlags;
private final SyntheticModeManager mSyntheticModeManager;
+ private final FeatureFlags mDeviceStateManagerFlags;
LogicalDisplayMapper(@NonNull Context context, FoldSettingProvider foldSettingProvider,
FoldGracePeriodProvider foldGracePeriodProvider,
@@ -245,6 +251,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
mDeviceStateToLayoutMap = deviceStateToLayoutMap;
mFlags = flags;
mSyntheticModeManager = syntheticModeManager;
+ mDeviceStateManagerFlags = new FeatureFlagsImpl();
}
@Override
@@ -389,18 +396,22 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
// Retrieve the layout for this particular state.
final Layout layout = mDeviceStateToLayoutMap.get(deviceState);
if (layout == null) {
+ // TODO(b/352019542): remove the log once b/345960547 is fixed.
+ Slog.d(TAG, "Cannot get layout for given state:" + deviceState);
return null;
}
// Retrieve the details of the given display within this layout.
Layout.Display display = layout.getById(displayId);
if (display == null) {
+ // TODO(b/352019542): remove the log once b/345960547 is fixed.
+ Slog.d(TAG, "Cannot get display for given layout:" + layout);
return null;
}
// Retrieve the display info for the display that matches the display id.
final DisplayDevice device = mDisplayDeviceRepo.getByAddressLocked(display.getAddress());
if (device == null) {
- Slog.w(TAG, "The display device (" + display.getAddress() + "), is not available"
- + " for the display state " + mDeviceState);
+ Slog.w(TAG, "The display device (" + display.getAddress()
+ + "), is not available for the display state " + mDeviceState.getIdentifier());
return null;
}
LogicalDisplay logicalDisplay = getDisplayLocked(device, /* includeDisabled= */ true);
@@ -427,9 +438,11 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
ipw.println("mBootCompleted=" + mBootCompleted);
ipw.println();
- ipw.println("mDeviceState=" + mDeviceState);
- ipw.println("mPendingDeviceState=" + mPendingDeviceState);
- ipw.println("mDeviceStateToBeAppliedAfterBoot=" + mDeviceStateToBeAppliedAfterBoot);
+
+ ipw.println("mDeviceState=" + mDeviceState.getIdentifier());
+ ipw.println("mPendingDeviceState=" + mPendingDeviceState.getIdentifier());
+ ipw.println("mDeviceStateToBeAppliedAfterBoot="
+ + mDeviceStateToBeAppliedAfterBoot.getIdentifier());
final int logicalDisplayCount = mLogicalDisplays.size();
ipw.println();
@@ -459,7 +472,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
mVirtualDeviceDisplayMapping.put(displayDevice.getUniqueId(), virtualDeviceUniqueId);
}
- void setDeviceStateLocked(int state) {
+ void setDeviceStateLocked(DeviceState state) {
if (!mBootCompleted) {
// The boot animation might still be in progress, we do not want to switch states now
// as the boot animation would end up with an incorrect size.
@@ -471,15 +484,17 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
return;
}
- Slog.i(TAG, "Requesting Transition to state: " + state + ", from state=" + mDeviceState
- + ", interactive=" + mInteractive + ", mBootCompleted=" + mBootCompleted);
+ Slog.i(TAG, "Requesting Transition to state: " + state + ", from state="
+ + mDeviceState.getIdentifier() + ", interactive=" + mInteractive
+ + ", mBootCompleted=" + mBootCompleted);
// As part of a state transition, we may need to turn off some displays temporarily so that
// the transition is smooth. Plus, on some devices, only one internal displays can be
// on at a time. We use LogicalDisplay.setIsInTransition to mark a display that needs to be
// temporarily turned off.
- resetLayoutLocked(mDeviceState, state, /* transitionValue= */ true);
+ resetLayoutLocked(mDeviceState.getIdentifier(),
+ state.getIdentifier(), /* transitionValue= */ true);
mPendingDeviceState = state;
- mDeviceStateToBeAppliedAfterBoot = DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
+ mDeviceStateToBeAppliedAfterBoot = INVALID_DEVICE_STATE;
final boolean wakeDevice = shouldDeviceBeWoken(mPendingDeviceState, mDeviceState,
mInteractive, mBootCompleted);
final boolean sleepDevice = shouldDeviceBePutToSleep(mPendingDeviceState, mDeviceState,
@@ -494,7 +509,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
}
if (DEBUG) {
- Slog.d(TAG, "Postponing transition to state: " + mPendingDeviceState);
+ Slog.d(TAG, "Postponing transition to state: " + mPendingDeviceState.getIdentifier());
}
// Send the transitioning phase updates to DisplayManager so that the displays can
// start turning OFF in preparation for the new layout.
@@ -529,8 +544,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
void onBootCompleted() {
synchronized (mSyncRoot) {
mBootCompleted = true;
- if (mDeviceStateToBeAppliedAfterBoot
- != DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER) {
+ if (!mDeviceStateToBeAppliedAfterBoot.equals(INVALID_DEVICE_STATE)) {
setDeviceStateLocked(mDeviceStateToBeAppliedAfterBoot);
}
}
@@ -559,11 +573,18 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
* @see #setDeviceStateLocked
*/
@VisibleForTesting
- boolean shouldDeviceBeWoken(int pendingState, int currentState, boolean isInteractive,
- boolean isBootCompleted) {
- return mDeviceStatesOnWhichToWakeUp.get(pendingState)
- && !mDeviceStatesOnWhichToWakeUp.get(currentState)
- && !isInteractive && isBootCompleted;
+ boolean shouldDeviceBeWoken(DeviceState pendingState, DeviceState currentState,
+ boolean isInteractive, boolean isBootCompleted) {
+ if (mDeviceStateManagerFlags.deviceStatePropertyMigration()) {
+ return pendingState.hasProperty(PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE)
+ && !currentState.equals(INVALID_DEVICE_STATE)
+ && !currentState.hasProperty(PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE)
+ && !isInteractive && isBootCompleted;
+ } else {
+ return mDeviceStatesOnWhichToWakeUp.get(pendingState.getIdentifier())
+ && !mDeviceStatesOnWhichToWakeUp.get(currentState.getIdentifier())
+ && !isInteractive && isBootCompleted;
+ }
}
/**
@@ -584,14 +605,26 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
* @see #setDeviceStateLocked
*/
@VisibleForTesting
- boolean shouldDeviceBePutToSleep(int pendingState, int currentState, boolean isInteractive,
- boolean isBootCompleted) {
- return currentState != DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER
- && mDeviceStatesOnWhichToSelectiveSleep.get(pendingState)
- && !mDeviceStatesOnWhichToSelectiveSleep.get(currentState)
- && isInteractive
- && isBootCompleted
- && !mFoldSettingProvider.shouldStayAwakeOnFold();
+ boolean shouldDeviceBePutToSleep(DeviceState pendingState, DeviceState currentState,
+ boolean isInteractive, boolean isBootCompleted) {
+ if (mDeviceStateManagerFlags.deviceStatePropertyMigration()) {
+ return pendingState.hasProperty(PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP)
+ && !currentState.equals(INVALID_DEVICE_STATE)
+ && !currentState.hasProperty(PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP)
+ && isInteractive
+ && isBootCompleted
+ && !mFoldSettingProvider.shouldStayAwakeOnFold();
+ } else {
+ return currentState.getIdentifier()
+ != DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER
+ && pendingState.getIdentifier()
+ != DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER
+ && mDeviceStatesOnWhichToSelectiveSleep.get(pendingState.getIdentifier())
+ && !mDeviceStatesOnWhichToSelectiveSleep.get(currentState.getIdentifier())
+ && isInteractive
+ && isBootCompleted
+ && !mFoldSettingProvider.shouldStayAwakeOnFold();
+ }
}
private boolean areAllTransitioningDisplaysOffLocked() {
@@ -614,27 +647,25 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
}
private void transitionToPendingStateLocked() {
- resetLayoutLocked(mDeviceState, mPendingDeviceState, /* transitionValue= */ false);
+ resetLayoutLocked(mDeviceState.getIdentifier(),
+ mPendingDeviceState.getIdentifier(), /* transitionValue= */ false);
mDeviceState = mPendingDeviceState;
- mPendingDeviceState = DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
+ mPendingDeviceState = INVALID_DEVICE_STATE;
applyLayoutLocked();
updateLogicalDisplaysLocked();
}
private void finishStateTransitionLocked(boolean force) {
- if (mPendingDeviceState == DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER) {
+ if (mPendingDeviceState.equals(INVALID_DEVICE_STATE)) {
return;
}
- final boolean waitingToWakeDevice = mDeviceStatesOnWhichToWakeUp.get(mPendingDeviceState)
- && !mDeviceStatesOnWhichToWakeUp.get(mDeviceState)
- && !mInteractive && mBootCompleted;
+ final boolean waitingToWakeDevice = shouldDeviceBeWoken(mPendingDeviceState, mDeviceState,
+ mInteractive, mBootCompleted);
// The device should only wait for sleep if #shouldStayAwakeOnFold method returns false.
// If not, device should be marked ready for transition immediately.
- final boolean waitingToSleepDevice = mDeviceStatesOnWhichToSelectiveSleep.get(
- mPendingDeviceState)
- && !mDeviceStatesOnWhichToSelectiveSleep.get(mDeviceState)
- && mInteractive && mBootCompleted && !shouldStayAwakeOnFold();
+ final boolean waitingToSleepDevice = shouldDeviceBePutToSleep(mPendingDeviceState,
+ mDeviceState, mInteractive, mBootCompleted) && !shouldStayAwakeOnFold();
final boolean displaysOff = areAllTransitioningDisplaysOffLocked();
final boolean isReadyToTransition = displaysOff && !waitingToWakeDevice
@@ -1100,7 +1131,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
*/
private void applyLayoutLocked() {
final Layout oldLayout = mCurrentLayout;
- mCurrentLayout = mDeviceStateToLayoutMap.get(mDeviceState);
+ mCurrentLayout = mDeviceStateToLayoutMap.get(mDeviceState.getIdentifier());
Slog.i(TAG, "Applying layout: " + mCurrentLayout + ", Previous layout: " + oldLayout);
// Go through each of the displays in the current layout set.
@@ -1116,7 +1147,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
final DisplayDevice device = mDisplayDeviceRepo.getByAddressLocked(address);
if (device == null) {
Slog.w(TAG, "applyLayoutLocked: The display device (" + address + "), is not "
- + "available for the display state " + mDeviceState);
+ + "available for the display state " + mDeviceState.getIdentifier());
continue;
}
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 1a5c79fada55..9b02f4b71ebe 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -56,6 +56,7 @@ import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.Slog;
import android.view.Display;
+import android.view.DisplayCutout;
import android.view.DisplayShape;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -213,6 +214,10 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
}
}
+ DisplayDevice getDisplayDevice(IBinder appToken) {
+ return mVirtualDisplayDevices.get(appToken);
+ }
+
/**
* Generates a virtual display's unique identifier.
*
@@ -271,6 +276,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
private boolean mIsDisplayOn;
private int mDisplayIdToMirror;
private boolean mIsWindowManagerMirroring;
+ private DisplayCutout mDisplayCutout;
public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
int ownerUid, String ownerPackageName, Surface surface, int flags,
@@ -286,6 +292,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
mHeight = virtualDisplayConfig.getHeight();
mDensityDpi = virtualDisplayConfig.getDensityDpi();
mRequestedRefreshRate = virtualDisplayConfig.getRequestedRefreshRate();
+ mDisplayCutout = virtualDisplayConfig.getDisplayCutout();
mMode = createMode(mWidth, mHeight, getRefreshRate());
mSurface = surface;
mFlags = flags;
@@ -567,6 +574,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
mInfo.displayShape =
DisplayShape.createDefaultDisplayShape(mInfo.width, mInfo.height, false);
+ mInfo.displayCutout = mDisplayCutout;
}
return mInfo;
}
diff --git a/services/core/java/com/android/server/display/brightness/BrightnessUtils.java b/services/core/java/com/android/server/display/brightness/BrightnessUtils.java
index 8bf675cb33b1..d009e614d5b5 100644
--- a/services/core/java/com/android/server/display/brightness/BrightnessUtils.java
+++ b/services/core/java/com/android/server/display/brightness/BrightnessUtils.java
@@ -52,9 +52,8 @@ public final class BrightnessUtils {
* A utility to construct the DisplayBrightnessState
*/
public static DisplayBrightnessState constructDisplayBrightnessState(
- int brightnessChangeReason, float brightness, float sdrBrightness,
- String displayBrightnessStrategyName) {
- return constructDisplayBrightnessState(brightnessChangeReason, brightness, sdrBrightness,
+ int brightnessChangeReason, float brightness, String displayBrightnessStrategyName) {
+ return constructDisplayBrightnessState(brightnessChangeReason, brightness,
displayBrightnessStrategyName, /* slowChange= */ false);
}
@@ -62,13 +61,12 @@ public final class BrightnessUtils {
* A utility to construct the DisplayBrightnessState
*/
public static DisplayBrightnessState constructDisplayBrightnessState(
- int brightnessChangeReason, float brightness, float sdrBrightness,
+ int brightnessChangeReason, float brightness,
String displayBrightnessStrategyName, boolean slowChange) {
BrightnessReason brightnessReason = new BrightnessReason();
brightnessReason.setReason(brightnessChangeReason);
return new DisplayBrightnessState.Builder()
.setBrightness(brightness)
- .setSdrBrightness(sdrBrightness)
.setBrightnessReason(brightnessReason)
.setDisplayBrightnessStrategyName(displayBrightnessStrategyName)
.setIsSlowChange(slowChange)
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
index 220640270e02..88d2c007cf37 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
@@ -304,6 +304,9 @@ public class BrightnessClamperController {
modifiers.add(new BrightnessLowLuxModifier(handler, listener, context,
displayDeviceConfig));
}
+ if (flags.useNewHdrBrightnessModifier()) {
+ modifiers.add(new HdrBrightnessModifier());
+ }
return modifiers;
}
diff --git a/services/core/java/com/android/server/display/brightness/clamper/HdrBrightnessModifier.java b/services/core/java/com/android/server/display/brightness/clamper/HdrBrightnessModifier.java
new file mode 100644
index 000000000000..a829866ae6fc
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/clamper/HdrBrightnessModifier.java
@@ -0,0 +1,51 @@
+/*
+ * 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.display.brightness.clamper;
+
+import android.hardware.display.DisplayManagerInternal;
+
+import com.android.server.display.DisplayBrightnessState;
+
+import java.io.PrintWriter;
+
+public class HdrBrightnessModifier implements BrightnessStateModifier {
+ @Override
+ public void apply(DisplayManagerInternal.DisplayPowerRequest request,
+ DisplayBrightnessState.Builder stateBuilder) {
+ // noop
+ }
+
+ @Override
+ public void dump(PrintWriter printWriter) {
+ // noop
+ }
+
+ @Override
+ public void stop() {
+ // noop
+ }
+
+ @Override
+ public boolean shouldListenToLightSensor() {
+ return false;
+ }
+
+ @Override
+ public void setAmbientLux(float lux) {
+ // noop
+ }
+}
diff --git a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
index 902daa4b7ce2..5c2db35717c5 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
@@ -133,7 +133,7 @@ public class HdrClamper {
// new token not null and hdr min % of the screen is set, subscribe.
// e.g. for virtual display, HBM data will be missing and HdrListener
// should not be registered
- if (displayToken != null && mHdrListener.mHdrMinPixels >= 0) {
+ if (displayToken != null && mHdrListener.mHdrMinPixels >= 0 && hasBrightnessLimits()) {
mHdrListener.register(displayToken);
mRegisteredDisplayToken = displayToken;
}
@@ -179,6 +179,10 @@ public class HdrClamper {
pw.println(" mAutoBrightnessEnabled=" + mAutoBrightnessEnabled);
}
+ private boolean hasBrightnessLimits() {
+ return mHdrBrightnessData != null && !mHdrBrightnessData.maxBrightnessLimits.isEmpty();
+ }
+
private void reset() {
if (mMaxBrightness == PowerManager.BRIGHTNESS_MAX
&& mDesiredMaxBrightness == PowerManager.BRIGHTNESS_MAX && mTransitionRate == -1f
@@ -214,11 +218,11 @@ public class HdrClamper {
mDesiredMaxBrightness = expectedMaxBrightness;
long debounceTime;
if (mDesiredMaxBrightness > mMaxBrightness) {
- debounceTime = mHdrBrightnessData.mBrightnessIncreaseDebounceMillis;
- mDesiredTransitionRate = mHdrBrightnessData.mScreenBrightnessRampIncrease;
+ debounceTime = mHdrBrightnessData.brightnessIncreaseDebounceMillis;
+ mDesiredTransitionRate = mHdrBrightnessData.screenBrightnessRampIncrease;
} else {
- debounceTime = mHdrBrightnessData.mBrightnessDecreaseDebounceMillis;
- mDesiredTransitionRate = mHdrBrightnessData.mScreenBrightnessRampDecrease;
+ debounceTime = mHdrBrightnessData.brightnessDecreaseDebounceMillis;
+ mDesiredTransitionRate = mHdrBrightnessData.screenBrightnessRampDecrease;
}
mHandler.removeCallbacks(mDebouncer);
@@ -232,7 +236,7 @@ public class HdrClamper {
float foundAmbientBoundary = Float.MAX_VALUE;
float foundMaxBrightness = PowerManager.BRIGHTNESS_MAX;
for (Map.Entry<Float, Float> brightnessPoint :
- data.mMaxBrightnessLimits.entrySet()) {
+ data.maxBrightnessLimits.entrySet()) {
float ambientBoundary = brightnessPoint.getKey();
// find ambient lux upper boundary closest to current ambient lux
if (ambientBoundary > ambientLux && ambientBoundary < foundAmbientBoundary) {
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategy.java
index 16bf177f191b..d8b95ec3b5c9 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategy.java
@@ -75,7 +75,6 @@ public final class AutoBrightnessFallbackStrategy implements DisplayBrightnessSt
brightnessReason.setReason(BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR);
return new DisplayBrightnessState.Builder()
.setBrightness(brightness)
- .setSdrBrightness(brightness)
.setBrightnessReason(brightnessReason)
.setDisplayBrightnessStrategyName(getName())
.setShouldUpdateScreenBrightnessSetting(brightness
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
index ddb091dd170d..706b4a63f31b 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
@@ -297,7 +297,6 @@ public class AutomaticBrightnessStrategy extends AutomaticBrightnessStrategy2
/* isAutomaticBrightnessAdjusted = */ true);
return new DisplayBrightnessState.Builder()
.setBrightness(brightness)
- .setSdrBrightness(brightness)
.setBrightnessReason(brightnessReason)
.setDisplayBrightnessStrategyName(getName())
.setIsSlowChange(mIsSlowChange)
diff --git a/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java
index 009a47ad8ade..2ef7ea925fdf 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java
@@ -42,7 +42,6 @@ public class BoostBrightnessStrategy implements DisplayBrightnessStrategy {
// the brightness
DisplayBrightnessState displayBrightnessState =
BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_BOOST,
- PowerManager.BRIGHTNESS_MAX,
PowerManager.BRIGHTNESS_MAX, getName());
return displayBrightnessState;
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java
index 2b493f3a181f..0855c9e098c4 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java
@@ -36,7 +36,6 @@ public class DozeBrightnessStrategy implements DisplayBrightnessStrategy {
// the brightness
return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_DOZE,
strategyExecutionRequest.getDisplayPowerRequest().dozeScreenBrightness,
- strategyExecutionRequest.getDisplayPowerRequest().dozeScreenBrightness,
getName());
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/FallbackBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/FallbackBrightnessStrategy.java
index 0b92317a61cb..7c0c9312888e 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/FallbackBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/FallbackBrightnessStrategy.java
@@ -39,7 +39,6 @@ public class FallbackBrightnessStrategy implements DisplayBrightnessStrategy{
brightnessReason.setReason(BrightnessReason.REASON_MANUAL);
return new DisplayBrightnessState.Builder()
.setBrightness(strategyExecutionRequest.getCurrentScreenBrightness())
- .setSdrBrightness(strategyExecutionRequest.getCurrentScreenBrightness())
.setBrightnessReason(brightnessReason)
.setDisplayBrightnessStrategyName(getName())
// The fallback brightness might change due to clamping. Make sure we tell the rest
diff --git a/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java
index 5a07ce2a719d..7ab92d101fc6 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java
@@ -53,7 +53,7 @@ public class FollowerBrightnessStrategy implements DisplayBrightnessStrategy {
// Todo(b/241308599): Introduce a validator class and add validations before setting
// the brightness
return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_FOLLOWER,
- mBrightnessToFollow, mBrightnessToFollow, getName(), mBrightnessToFollowSlowChange);
+ mBrightnessToFollow, getName(), mBrightnessToFollowSlowChange);
}
@Override
diff --git a/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java
index 9dc6cffe5c1e..f9e56bbe47d1 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java
@@ -34,8 +34,7 @@ public class InvalidBrightnessStrategy implements DisplayBrightnessStrategy {
public DisplayBrightnessState updateBrightness(
StrategyExecutionRequest strategyExecutionRequest) {
return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_UNKNOWN,
- PowerManager.BRIGHTNESS_INVALID_FLOAT, PowerManager.BRIGHTNESS_INVALID_FLOAT,
- getName());
+ PowerManager.BRIGHTNESS_INVALID_FLOAT, getName());
}
@Override
diff --git a/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java
index b46873aec814..1d7d3a6fa3ef 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java
@@ -55,7 +55,6 @@ public class OffloadBrightnessStrategy implements DisplayBrightnessStrategy {
brightnessReason.setReason(BrightnessReason.REASON_OFFLOAD);
return new DisplayBrightnessState.Builder()
.setBrightness(offloadBrightness)
- .setSdrBrightness(offloadBrightness)
.setBrightnessReason(brightnessReason)
.setDisplayBrightnessStrategyName(getName())
.setIsSlowChange(false)
diff --git a/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java
index a2982b16454f..40a495c85467 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java
@@ -35,8 +35,7 @@ public class OverrideBrightnessStrategy implements DisplayBrightnessStrategy {
// the brightness
return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_OVERRIDE,
strategyExecutionRequest.getDisplayPowerRequest().screenBrightnessOverride,
- strategyExecutionRequest.getDisplayPowerRequest()
- .screenBrightnessOverride, getName());
+ getName());
}
@Override
diff --git a/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java
index 6a3162c75dc5..fe7a6b754cbc 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java
@@ -36,7 +36,6 @@ public class ScreenOffBrightnessStrategy implements DisplayBrightnessStrategy {
// Todo(b/241308599): Introduce a validator class and add validations before setting
// the brightness
return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_SCREEN_OFF,
- PowerManager.BRIGHTNESS_OFF_FLOAT,
PowerManager.BRIGHTNESS_OFF_FLOAT, getName());
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
index 6b8817a3b62a..ca0beefd86fd 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
@@ -48,7 +48,6 @@ public class TemporaryBrightnessStrategy implements DisplayBrightnessStrategy {
// the brightness
DisplayBrightnessState displayBrightnessState =
BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_TEMPORARY,
- mTemporaryScreenBrightness,
mTemporaryScreenBrightness, getName());
return displayBrightnessState;
}
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 3883604b7134..bd759f378d5b 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -25,6 +25,9 @@ import static android.hardware.display.ColorDisplayManager.COLOR_MODE_NATURAL;
import static android.hardware.display.ColorDisplayManager.COLOR_MODE_SATURATED;
import static android.hardware.display.ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MAX;
import static android.hardware.display.ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MIN;
+import static android.os.UserHandle.USER_SYSTEM;
+import static android.os.UserHandle.getCallingUserId;
+import static android.os.UserManager.isVisibleBackgroundUsersEnabled;
import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
@@ -80,6 +83,7 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.accessibility.Flags;
import com.android.server.display.feature.DisplayManagerFlags;
+import com.android.server.pm.UserManagerService;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
@@ -186,9 +190,14 @@ public final class ColorDisplayService extends SystemService {
private final Object mCctTintApplierLock = new Object();
+ private final boolean mVisibleBackgroundUsersEnabled;
+ private final UserManagerService mUserManager;
+
public ColorDisplayService(Context context) {
super(context);
mHandler = new TintHandler(DisplayThread.get().getLooper());
+ mVisibleBackgroundUsersEnabled = isVisibleBackgroundUsersEnabled();
+ mUserManager = UserManagerService.getInstance();
}
@Override
@@ -1745,6 +1754,9 @@ public final class ColorDisplayService extends SystemService {
@Override
public void setColorMode(int colorMode) {
setColorMode_enforcePermission();
+
+ enforceValidCallingUser("setColorMode");
+
final long token = Binder.clearCallingIdentity();
try {
setColorModeInternal(colorMode);
@@ -1784,6 +1796,9 @@ public final class ColorDisplayService extends SystemService {
if (!hasTransformsPermission && !hasLegacyPermission) {
throw new SecurityException("Permission required to set display saturation level");
}
+
+ enforceValidCallingUser("setSaturationLevel");
+
final long token = Binder.clearCallingIdentity();
try {
setSaturationLevelInternal(level);
@@ -1812,6 +1827,8 @@ public final class ColorDisplayService extends SystemService {
public boolean setAppSaturationLevel(String packageName, int level) {
super.setAppSaturationLevel_enforcePermission();
+ enforceValidCallingUser("setAppSaturationLevel");
+
final String callingPackageName = LocalServices.getService(PackageManagerInternal.class)
.getNameForUid(Binder.getCallingUid());
final long token = Binder.clearCallingIdentity();
@@ -1838,6 +1855,9 @@ public final class ColorDisplayService extends SystemService {
@Override
public boolean setNightDisplayActivated(boolean activated) {
setNightDisplayActivated_enforcePermission();
+
+ enforceValidCallingUser("setNightDisplayActivated");
+
final long token = Binder.clearCallingIdentity();
try {
mNightDisplayTintController.setActivated(activated);
@@ -1861,6 +1881,9 @@ public final class ColorDisplayService extends SystemService {
@Override
public boolean setNightDisplayColorTemperature(int temperature) {
setNightDisplayColorTemperature_enforcePermission();
+
+ enforceValidCallingUser("setNightDisplayColorTemperature");
+
final long token = Binder.clearCallingIdentity();
try {
return mNightDisplayTintController.setColorTemperature(temperature);
@@ -1883,6 +1906,9 @@ public final class ColorDisplayService extends SystemService {
@Override
public boolean setNightDisplayAutoMode(int autoMode) {
setNightDisplayAutoMode_enforcePermission();
+
+ enforceValidCallingUser("setNightDisplayAutoMode");
+
final long token = Binder.clearCallingIdentity();
try {
return setNightDisplayAutoModeInternal(autoMode);
@@ -1917,6 +1943,9 @@ public final class ColorDisplayService extends SystemService {
@Override
public boolean setNightDisplayCustomStartTime(Time startTime) {
setNightDisplayCustomStartTime_enforcePermission();
+
+ enforceValidCallingUser("setNightDisplayCustomStartTime");
+
final long token = Binder.clearCallingIdentity();
try {
return setNightDisplayCustomStartTimeInternal(startTime);
@@ -1939,6 +1968,9 @@ public final class ColorDisplayService extends SystemService {
@Override
public boolean setNightDisplayCustomEndTime(Time endTime) {
setNightDisplayCustomEndTime_enforcePermission();
+
+ enforceValidCallingUser("setNightDisplayCustomEndTime");
+
final long token = Binder.clearCallingIdentity();
try {
return setNightDisplayCustomEndTimeInternal(endTime);
@@ -1961,6 +1993,9 @@ public final class ColorDisplayService extends SystemService {
@Override
public boolean setDisplayWhiteBalanceEnabled(boolean enabled) {
setDisplayWhiteBalanceEnabled_enforcePermission();
+
+ enforceValidCallingUser("setDisplayWhiteBalanceEnabled");
+
final long token = Binder.clearCallingIdentity();
try {
return setDisplayWhiteBalanceSettingEnabled(enabled);
@@ -1993,6 +2028,9 @@ public final class ColorDisplayService extends SystemService {
@Override
public boolean setReduceBrightColorsActivated(boolean activated) {
setReduceBrightColorsActivated_enforcePermission();
+
+ enforceValidCallingUser("setReduceBrightColorsActivated");
+
final long token = Binder.clearCallingIdentity();
try {
return setReduceBrightColorsActivatedInternal(activated);
@@ -2025,6 +2063,9 @@ public final class ColorDisplayService extends SystemService {
@Override
public boolean setReduceBrightColorsStrength(int strength) {
setReduceBrightColorsStrength_enforcePermission();
+
+ enforceValidCallingUser("setReduceBrightColorsStrength");
+
final long token = Binder.clearCallingIdentity();
try {
return setReduceBrightColorsStrengthInternal(strength);
@@ -2064,4 +2105,32 @@ public final class ColorDisplayService extends SystemService {
}
}
}
+
+ /**
+ * This method validates whether the calling user is allowed to set display's color transform
+ * on a device that enables visible background users.
+ * Only system or current user or the user that belongs to the same profile group as the current
+ * user is permitted to set the color transform.
+ */
+ private void enforceValidCallingUser(String method) {
+ if (!mVisibleBackgroundUsersEnabled) {
+ return;
+ }
+
+ int callingUserId = getCallingUserId();
+ if (callingUserId == USER_SYSTEM || callingUserId == mCurrentUser) {
+ return;
+ }
+ long ident = Binder.clearCallingIdentity();
+ try {
+ if (mUserManager.isSameProfileGroup(callingUserId, mCurrentUser)) {
+ return;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+
+ throw new SecurityException("Calling user id: " + callingUserId
+ + ", is not permitted to use Method " + method + "().");
+ }
}
diff --git a/services/core/java/com/android/server/display/config/DisplayDeviceConfigUtils.java b/services/core/java/com/android/server/display/config/DisplayDeviceConfigUtils.java
new file mode 100644
index 000000000000..5b4e8d51a168
--- /dev/null
+++ b/services/core/java/com/android/server/display/config/DisplayDeviceConfigUtils.java
@@ -0,0 +1,63 @@
+/*
+ * 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.display.config;
+
+import android.annotation.Nullable;
+import android.util.Slog;
+import android.util.Spline;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.function.Function;
+
+public class DisplayDeviceConfigUtils {
+ private static final String TAG = "DisplayDeviceConfigUtils";
+
+ /**
+ * Create Spline from generic data
+ * @param points - points for Spline in format (x0, y0), (x1, y1) etc
+ * @param xExtractor - extract X component from generic data
+ * @param yExtractor - extract Y component from generic data
+ */
+ @Nullable
+ public static <T> Spline createSpline(List<T> points, Function<T, BigDecimal> xExtractor,
+ Function<T, BigDecimal> yExtractor) {
+ int size = points.size();
+ if (size == 0) {
+ return null;
+ }
+
+ float[] x = new float[size];
+ float[] y = new float[size];
+
+ int i = 0;
+ for (T point : points) {
+ x[i] = xExtractor.apply(point).floatValue();
+ if (i > 0) {
+ if (x[i] <= x[i - 1]) {
+ Slog.e(TAG, "spline control points must be strictly increasing, ignoring "
+ + "configuration. x: " + x[i] + " <= " + x[i - 1]);
+ return null;
+ }
+ }
+ y[i] = yExtractor.apply(point).floatValue();
+ ++i;
+ }
+
+ return Spline.createSpline(x, y);
+ }
+}
diff --git a/services/core/java/com/android/server/display/config/HdrBrightnessData.java b/services/core/java/com/android/server/display/config/HdrBrightnessData.java
index 837fbf7ca17c..c9408077e5af 100644
--- a/services/core/java/com/android/server/display/config/HdrBrightnessData.java
+++ b/services/core/java/com/android/server/display/config/HdrBrightnessData.java
@@ -16,63 +16,138 @@
package com.android.server.display.config;
+import static com.android.server.display.config.HighBrightnessModeData.HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT;
+
import android.annotation.Nullable;
+import android.util.Spline;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.DisplayBrightnessState;
+import java.math.BigDecimal;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Brightness config for HDR content
+ * <pre>
+ * {@code
+ * <displayConfiguration>
+ * ...
+ * <hdrBrightnessConfig>
+ * <brightnessMap>
+ * <point>
+ * <first>500</first>
+ * <second>0.3</second>
+ * </point>
+ * <point>
+ * <first>1200</first>
+ * <second>0.6</second>
+ * </point>
+ * </brightnessMap>
+ * <brightnessIncreaseDebounceMillis>1000</brightnessIncreaseDebounceMillis>
+ * <brightnessIncreaseDurationMillis>10000</brightnessIncreaseDurationMillis>
+ * <brightnessDecreaseDebounceMillis>13000</brightnessDecreaseDebounceMillis>
+ * <brightnessDecreaseDurationMillis>10000</brightnessDecreaseDurationMillis>
+ * <minimumHdrPercentOfScreenForNbm>0.2</minimumHdrPercentOfScreenForNbm>
+ * <minimumHdrPercentOfScreenForHbm>0.5</minimumHdrPercentOfScreenForHbm>
+ * <allowInLowPowerMode>true</allowInLowPowerMode>
+ * <sdrHdrRatioMap>
+ * <point>
+ * <first>2.0</first>
+ * <second>4.0</second>
+ * </point>
+ * <point>
+ * <first>100</first>
+ * <second>8.0</second>
+ * </point>
+ * </sdrHdrRatioMap>
+ * </hdrBrightnessConfig>
+ * ...
+ * </displayConfiguration>
+ * }
+ * </pre>
*/
public class HdrBrightnessData {
+ private static final String TAG = "HdrBrightnessData";
/**
* Lux to brightness map
*/
- public final Map<Float, Float> mMaxBrightnessLimits;
+ public final Map<Float, Float> maxBrightnessLimits;
/**
* Debounce time for brightness increase
*/
- public final long mBrightnessIncreaseDebounceMillis;
+ public final long brightnessIncreaseDebounceMillis;
/**
* Brightness increase animation speed
*/
- public final float mScreenBrightnessRampIncrease;
+ public final float screenBrightnessRampIncrease;
/**
* Debounce time for brightness decrease
*/
- public final long mBrightnessDecreaseDebounceMillis;
+ public final long brightnessDecreaseDebounceMillis;
/**
* Brightness decrease animation speed
*/
- public final float mScreenBrightnessRampDecrease;
+ public final float screenBrightnessRampDecrease;
+
+ /**
+ * Min Hdr layer size to start hdr brightness boost up to high brightness mode transition point
+ */
+ public final float minimumHdrPercentOfScreenForNbm;
+
+ /**
+ * Min Hdr layer size to start hdr brightness boost above high brightness mode transition point
+ */
+ public final float minimumHdrPercentOfScreenForHbm;
+
+ /**
+ * If Hdr brightness boost allowed in low power mode
+ */
+ public final boolean allowInLowPowerMode;
+
+ /**
+ * brightness to boost ratio spline
+ */
+ @Nullable
+ public final Spline sdrToHdrRatioSpline;
@VisibleForTesting
public HdrBrightnessData(Map<Float, Float> maxBrightnessLimits,
long brightnessIncreaseDebounceMillis, float screenBrightnessRampIncrease,
- long brightnessDecreaseDebounceMillis, float screenBrightnessRampDecrease) {
- mMaxBrightnessLimits = maxBrightnessLimits;
- mBrightnessIncreaseDebounceMillis = brightnessIncreaseDebounceMillis;
- mScreenBrightnessRampIncrease = screenBrightnessRampIncrease;
- mBrightnessDecreaseDebounceMillis = brightnessDecreaseDebounceMillis;
- mScreenBrightnessRampDecrease = screenBrightnessRampDecrease;
+ long brightnessDecreaseDebounceMillis, float screenBrightnessRampDecrease,
+ float minimumHdrPercentOfScreenForNbm, float minimumHdrPercentOfScreenForHbm,
+ boolean allowInLowPowerMode, @Nullable Spline sdrToHdrRatioSpline) {
+ this.maxBrightnessLimits = maxBrightnessLimits;
+ this.brightnessIncreaseDebounceMillis = brightnessIncreaseDebounceMillis;
+ this.screenBrightnessRampIncrease = screenBrightnessRampIncrease;
+ this.brightnessDecreaseDebounceMillis = brightnessDecreaseDebounceMillis;
+ this.screenBrightnessRampDecrease = screenBrightnessRampDecrease;
+ this.minimumHdrPercentOfScreenForNbm = minimumHdrPercentOfScreenForNbm;
+ this.minimumHdrPercentOfScreenForHbm = minimumHdrPercentOfScreenForHbm;
+ this.allowInLowPowerMode = allowInLowPowerMode;
+ this.sdrToHdrRatioSpline = sdrToHdrRatioSpline;
}
@Override
public String toString() {
return "HdrBrightnessData {"
- + "mMaxBrightnessLimits: " + mMaxBrightnessLimits
- + ", mBrightnessIncreaseDebounceMillis: " + mBrightnessIncreaseDebounceMillis
- + ", mScreenBrightnessRampIncrease: " + mScreenBrightnessRampIncrease
- + ", mBrightnessDecreaseDebounceMillis: " + mBrightnessDecreaseDebounceMillis
- + ", mScreenBrightnessRampDecrease: " + mScreenBrightnessRampDecrease
+ + "mMaxBrightnessLimits: " + maxBrightnessLimits
+ + ", mBrightnessIncreaseDebounceMillis: " + brightnessIncreaseDebounceMillis
+ + ", mScreenBrightnessRampIncrease: " + screenBrightnessRampIncrease
+ + ", mBrightnessDecreaseDebounceMillis: " + brightnessDecreaseDebounceMillis
+ + ", mScreenBrightnessRampDecrease: " + screenBrightnessRampDecrease
+ + ", minimumHdrPercentOfScreenForNbm: " + minimumHdrPercentOfScreenForNbm
+ + ", minimumHdrPercentOfScreenForHbm: " + minimumHdrPercentOfScreenForHbm
+ + ", allowInLowPowerMode: " + allowInLowPowerMode
+ + ", sdrToHdrRatioSpline: " + sdrToHdrRatioSpline
+ "} ";
}
@@ -83,7 +158,7 @@ public class HdrBrightnessData {
public static HdrBrightnessData loadConfig(DisplayConfiguration config) {
HdrBrightnessConfig hdrConfig = config.getHdrBrightnessConfig();
if (hdrConfig == null) {
- return null;
+ return getFallbackData(config.getHighBrightnessMode());
}
List<NonNegativeFloatToFloatPoint> points = hdrConfig.getBrightnessMap().getPoint();
@@ -92,10 +167,59 @@ public class HdrBrightnessData {
brightnessLimits.put(point.getFirst().floatValue(), point.getSecond().floatValue());
}
+ float minHdrPercentForHbm = hdrConfig.getMinimumHdrPercentOfScreenForHbm() != null
+ ? hdrConfig.getMinimumHdrPercentOfScreenForHbm().floatValue()
+ : getFallbackHdrPercent(config.getHighBrightnessMode());
+
+ float minHdrPercentForNbm = hdrConfig.getMinimumHdrPercentOfScreenForNbm() != null
+ ? hdrConfig.getMinimumHdrPercentOfScreenForNbm().floatValue() : minHdrPercentForHbm;
+
return new HdrBrightnessData(brightnessLimits,
hdrConfig.getBrightnessIncreaseDebounceMillis().longValue(),
hdrConfig.getScreenBrightnessRampIncrease().floatValue(),
hdrConfig.getBrightnessDecreaseDebounceMillis().longValue(),
- hdrConfig.getScreenBrightnessRampDecrease().floatValue());
+ hdrConfig.getScreenBrightnessRampDecrease().floatValue(),
+ minHdrPercentForNbm, minHdrPercentForHbm, hdrConfig.getAllowInLowPowerMode(),
+ getSdrHdrRatioSpline(hdrConfig, config.getHighBrightnessMode()));
+ }
+
+ @Nullable
+ private static HdrBrightnessData getFallbackData(HighBrightnessMode hbm) {
+ if (hbm == null) {
+ return null;
+ }
+ float fallbackPercent = getFallbackHdrPercent(hbm);
+ Spline fallbackSpline = getFallbackSdrHdrRatioSpline(hbm);
+ return new HdrBrightnessData(Collections.emptyMap(),
+ 0, DisplayBrightnessState.CUSTOM_ANIMATION_RATE_NOT_SET,
+ 0, DisplayBrightnessState.CUSTOM_ANIMATION_RATE_NOT_SET,
+ fallbackPercent, fallbackPercent, false, fallbackSpline);
+ }
+
+ private static float getFallbackHdrPercent(HighBrightnessMode hbm) {
+ BigDecimal minHdrPctOfScreen = hbm != null ? hbm.getMinimumHdrPercentOfScreen_all() : null;
+ return minHdrPctOfScreen != null ? minHdrPctOfScreen.floatValue()
+ : HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT;
+ }
+
+ @Nullable
+ private static Spline getSdrHdrRatioSpline(HdrBrightnessConfig hdrConfig,
+ HighBrightnessMode hbm) {
+ NonNegativeFloatToFloatMap sdrHdrRatioMap = hdrConfig.getSdrHdrRatioMap();
+ if (sdrHdrRatioMap == null) {
+ return getFallbackSdrHdrRatioSpline(hbm);
+ }
+ return DisplayDeviceConfigUtils.createSpline(sdrHdrRatioMap.getPoint(),
+ NonNegativeFloatToFloatPoint::getFirst, NonNegativeFloatToFloatPoint::getSecond);
+ }
+
+ @Nullable
+ private static Spline getFallbackSdrHdrRatioSpline(HighBrightnessMode hbm) {
+ SdrHdrRatioMap fallbackMap = hbm != null ? hbm.getSdrHdrRatioMap_all() : null;
+ if (fallbackMap == null) {
+ return null;
+ }
+ return DisplayDeviceConfigUtils.createSpline(fallbackMap.getPoint(),
+ SdrHdrRatioPoint::getSdrNits, SdrHdrRatioPoint::getHdrRatio);
}
}
diff --git a/services/core/java/com/android/server/display/config/HighBrightnessModeData.java b/services/core/java/com/android/server/display/config/HighBrightnessModeData.java
new file mode 100644
index 000000000000..dc2f976748e6
--- /dev/null
+++ b/services/core/java/com/android/server/display/config/HighBrightnessModeData.java
@@ -0,0 +1,157 @@
+/*
+ * 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.display.config;
+
+import android.annotation.Nullable;
+import android.util.Slog;
+import android.util.Spline;
+import android.view.SurfaceControl;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.math.BigDecimal;
+import java.util.function.Function;
+
+/**
+ * Container for high brightness mode configuration data.
+ */
+public class HighBrightnessModeData {
+ private static final String TAG = "HighBrightnessModeData";
+
+ static final float HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT = 0.5f;
+
+ /** Minimum lux needed to enter high brightness mode */
+ public final float minimumLux;
+
+ /** Brightness level at which we transition from normal to high-brightness. */
+ public final float transitionPoint;
+
+ /** Whether HBM is allowed when {@code Settings.Global.LOW_POWER_MODE} is active. */
+ public final boolean allowInLowPowerMode;
+
+ /** Time window for HBM. */
+ public final long timeWindowMillis;
+
+ /** Maximum time HBM is allowed to be during in a {@code timeWindowMillis}. */
+ public final long timeMaxMillis;
+
+ /** Minimum time that HBM can be on before being enabled. */
+ public final long timeMinMillis;
+
+ /** Minimum HDR video size to enter high brightness mode */
+ public final float minimumHdrPercentOfScreen;
+
+ @Nullable
+ public final Spline sdrToHdrRatioSpline;
+
+ @Nullable
+ public final SurfaceControl.RefreshRateRange refreshRateLimit;
+
+ public final boolean isHighBrightnessModeEnabled;
+
+ @VisibleForTesting
+ public HighBrightnessModeData(float minimumLux, float transitionPoint, long timeWindowMillis,
+ long timeMaxMillis, long timeMinMillis, boolean allowInLowPowerMode,
+ float minimumHdrPercentOfScreen, @Nullable Spline sdrToHdrRatioSpline,
+ @Nullable SurfaceControl.RefreshRateRange refreshRateLimit,
+ boolean isHighBrightnessModeEnabled) {
+ this.minimumLux = minimumLux;
+ this.transitionPoint = transitionPoint;
+ this.timeWindowMillis = timeWindowMillis;
+ this.timeMaxMillis = timeMaxMillis;
+ this.timeMinMillis = timeMinMillis;
+ this.allowInLowPowerMode = allowInLowPowerMode;
+ this.minimumHdrPercentOfScreen = minimumHdrPercentOfScreen;
+ this.sdrToHdrRatioSpline = sdrToHdrRatioSpline;
+ this.refreshRateLimit = refreshRateLimit;
+ this.isHighBrightnessModeEnabled = isHighBrightnessModeEnabled;
+ }
+
+ @Override
+ public String toString() {
+ return "HBM{"
+ + "minLux: " + minimumLux
+ + ", transition: " + transitionPoint
+ + ", timeWindow: " + timeWindowMillis + "ms"
+ + ", timeMax: " + timeMaxMillis + "ms"
+ + ", timeMin: " + timeMinMillis + "ms"
+ + ", allowInLowPowerMode: " + allowInLowPowerMode
+ + ", minimumHdrPercentOfScreen: " + minimumHdrPercentOfScreen
+ + ", mSdrToHdrRatioSpline=" + sdrToHdrRatioSpline
+ + ", refreshRateLimit=" + refreshRateLimit
+ + ", isHighBrightnessModeEnabled=" + isHighBrightnessModeEnabled
+ + "} ";
+ }
+
+ /**
+ * Loads HighBrightnessModeData from DisplayConfiguration
+ */
+ public static HighBrightnessModeData loadHighBrightnessModeData(DisplayConfiguration config,
+ Function<HighBrightnessMode, Float> transitionPointProvider) {
+ final HighBrightnessMode hbm = config.getHighBrightnessMode();
+ float minimumLux = 0f;
+ float transitionPoint = 0f;
+ long timeWindowMillis = 0L;
+ long timeMaxMillis = 0L;
+ long timeMinMillis = 0L;
+ boolean allowInLowPowerMode = false;
+ float minimumHdrPercentOfScreen = HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT;
+ Spline sdrToHdrRatioSpline = null;
+ SurfaceControl.RefreshRateRange refreshRateLimit = null;
+ boolean isEnabled = false;
+
+ if (hbm != null) {
+ minimumLux = hbm.getMinimumLux_all().floatValue();
+ transitionPoint = transitionPointProvider.apply(hbm);
+ HbmTiming hbmTiming = hbm.getTiming_all();
+ timeWindowMillis = hbmTiming.getTimeWindowSecs_all().longValue() * 1000;
+ timeMaxMillis = hbmTiming.getTimeMaxSecs_all().longValue() * 1000;
+ timeMinMillis = hbmTiming.getTimeMinSecs_all().longValue() * 1000;
+ allowInLowPowerMode = hbm.getAllowInLowPowerMode_all();
+ BigDecimal minHdrPctOfScreen = hbm.getMinimumHdrPercentOfScreen_all();
+ if (minHdrPctOfScreen != null) {
+ minimumHdrPercentOfScreen = minHdrPctOfScreen.floatValue();
+ if (minimumHdrPercentOfScreen > 1 || minimumHdrPercentOfScreen < 0) {
+ Slog.w(TAG, "Invalid minimum HDR percent of screen: "
+ + minimumHdrPercentOfScreen);
+ minimumHdrPercentOfScreen = HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT;
+ }
+ }
+
+ sdrToHdrRatioSpline = loadSdrHdrRatioMap(hbm);
+ RefreshRateRange rr = hbm.getRefreshRate_all();
+ if (rr != null) {
+ refreshRateLimit = new SurfaceControl.RefreshRateRange(
+ rr.getMinimum().floatValue(), rr.getMaximum().floatValue());
+ }
+ isEnabled = hbm.getEnabled();
+ }
+ return new HighBrightnessModeData(minimumLux, transitionPoint,
+ timeWindowMillis, timeMaxMillis, timeMinMillis, allowInLowPowerMode,
+ minimumHdrPercentOfScreen, sdrToHdrRatioSpline, refreshRateLimit, isEnabled);
+
+ }
+
+ private static Spline loadSdrHdrRatioMap(HighBrightnessMode hbmConfig) {
+ final SdrHdrRatioMap sdrHdrRatioMap = hbmConfig.getSdrHdrRatioMap_all();
+ if (sdrHdrRatioMap == null) {
+ return null;
+ }
+ return DisplayDeviceConfigUtils.createSpline(sdrHdrRatioMap.getPoint(),
+ SdrHdrRatioPoint::getSdrNits, SdrHdrRatioPoint::getHdrRatio);
+ }
+}
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index 41d18cd6bf12..e1934b0df3f1 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -154,6 +154,10 @@ public class DisplayManagerFlags {
Flags::useFusionProxSensor
);
+ private final FlagState mDozeBrightnessFloat = new FlagState(
+ Flags.FLAG_DOZE_BRIGHTNESS_FLOAT,
+ Flags::dozeBrightnessFloat);
+
private final FlagState mOffloadControlsDozeAutoBrightness = new FlagState(
Flags.FLAG_OFFLOAD_CONTROLS_DOZE_AUTO_BRIGHTNESS,
Flags::offloadControlsDozeAutoBrightness
@@ -184,6 +188,11 @@ public class DisplayManagerFlags {
Flags.FLAG_OFFLOAD_SESSION_CANCEL_BLOCK_SCREEN_ON,
Flags::offloadSessionCancelBlockScreenOn);
+ private final FlagState mNewHdrBrightnessModifier =
+ new FlagState(
+ Flags.FLAG_NEW_HDR_BRIGHTNESS_MODIFIER,
+ Flags::newHdrBrightnessModifier);
+
/**
* @return {@code true} if 'port' is allowed in display layout configuration file.
*/
@@ -342,6 +351,10 @@ public class DisplayManagerFlags {
return mUseFusionProxSensor.getName();
}
+ public boolean isDozeBrightnessFloatEnabled() {
+ return mDozeBrightnessFloat.isEnabled();
+ }
+
/**
* @return Whether DisplayOffload should control auto-brightness in doze
*/
@@ -373,6 +386,13 @@ public class DisplayManagerFlags {
}
/**
+ * @return Whether to use new HDR brightness modifier or not
+ */
+ public boolean useNewHdrBrightnessModifier() {
+ return mNewHdrBrightnessModifier.isEnabled();
+ }
+
+ /**
* dumps all flagstates
* @param pw printWriter
*/
@@ -403,12 +423,14 @@ public class DisplayManagerFlags {
pw.println(" " + mRefactorDisplayPowerController);
pw.println(" " + mResolutionBackupRestore);
pw.println(" " + mUseFusionProxSensor);
+ pw.println(" " + mDozeBrightnessFloat);
pw.println(" " + mOffloadControlsDozeAutoBrightness);
pw.println(" " + mPeakRefreshRatePhysicalLimit);
pw.println(" " + mIgnoreAppPreferredRefreshRate);
pw.println(" " + mSynthetic60hzModes);
pw.println(" " + mOffloadDozeOverrideHoldsWakelock);
pw.println(" " + mOffloadSessionCancelBlockScreenOn);
+ pw.println(" " + mNewHdrBrightnessModifier);
}
private static class FlagState {
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 1ea5c0b23be1..ac5f97fc3661 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -246,6 +246,14 @@ flag {
}
flag {
+ name: "doze_brightness_float"
+ namespace: "display_manager"
+ description: "Define doze brightness in the float scale [0, 1]."
+ bug: "343796384"
+ is_fixed_read_only: true
+}
+
+flag {
name: "offload_controls_doze_auto_brightness"
namespace: "display_manager"
description: "Allows the registered DisplayOffloader to control if auto-brightness is used in doze"
@@ -307,3 +315,11 @@ flag {
bug: "331725519"
is_fixed_read_only: true
}
+
+flag {
+ name: "new_hdr_brightness_modifier"
+ namespace: "display_manager"
+ description: "Flag for new HDR brightness clamper."
+ bug: "331275392"
+ is_fixed_read_only: true
+}
diff --git a/services/core/java/com/android/server/flags/services.aconfig b/services/core/java/com/android/server/flags/services.aconfig
index d387828872e9..c361aee24916 100644
--- a/services/core/java/com/android/server/flags/services.aconfig
+++ b/services/core/java/com/android/server/flags/services.aconfig
@@ -35,3 +35,13 @@ flag {
description: "Enable BackgroundInstallControl based on system feature to prevent it from starting on form factors."
bug: "340928990"
}
+
+flag {
+ namespace: "input"
+ name: "modifier_shortcut_manager_multiuser"
+ description: "Update Modifier Shortcut Manager to work correctly with multiple users, including HSUM"
+ bug: "351963350"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 0f9c3440923b..49888db98755 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -597,6 +597,12 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
@Constants.HandleMessageResult
protected int handleReportPhysicalAddress(HdmiCecMessage message) {
super.handleReportPhysicalAddress(message);
+ // Ignore <Report Physical Address> while DeviceDiscoveryAction is in progress to avoid
+ // starting a NewDeviceAction which might interfere in creating the list of known devices.
+ if (hasAction(DeviceDiscoveryAction.class)) {
+ return Constants.HANDLED;
+ }
+
int path = HdmiUtils.twoBytesToInt(message.getParams());
int address = message.getSource();
int type = message.getParams()[2];
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
index 88da6fb94754..550f68fbc94c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
@@ -660,7 +660,11 @@ public class HdmiCecNetwork {
.setPortId(physicalAddressToPortId(physicalAddress))
.setDeviceType(type)
.build();
- updateCecDevice(updatedDeviceInfo);
+ if (deviceInfo.getPhysicalAddress() != physicalAddress) {
+ addCecDevice(updatedDeviceInfo);
+ } else {
+ updateCecDevice(updatedDeviceInfo);
+ }
}
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index e5dbce9931a1..1f46af8b741d 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -53,6 +53,7 @@ import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
import android.hardware.input.InputSensorInfo;
import android.hardware.input.InputSettings;
+import android.hardware.input.KeyGlyphMap;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.KeyboardLayoutSelectionResult;
import android.hardware.input.TouchCalibration;
@@ -311,6 +312,9 @@ public class InputManagerService extends IInputManager.Stub
// Manages Keyboard modifier keys remapping
private final KeyRemapper mKeyRemapper;
+ // Manages Keyboard glyphs for specific keyboards
+ private final KeyboardGlyphManager mKeyboardGlyphManager;
+
// Manages loading PointerIcons
private final PointerIconCache mPointerIconCache;
@@ -460,6 +464,7 @@ public class InputManagerService extends IInputManager.Stub
mKeyboardLedController = new KeyboardLedController(mContext, injector.getLooper(),
mNative);
mKeyRemapper = new KeyRemapper(mContext, mNative, mDataStore, injector.getLooper());
+ mKeyboardGlyphManager = new KeyboardGlyphManager(mContext, injector.getLooper());
mPointerIconCache = new PointerIconCache(mContext, mNative);
mUseDevInputEventForAudioJack =
@@ -576,6 +581,7 @@ public class InputManagerService extends IInputManager.Stub
mKeyboardLedController.systemRunning();
mKeyRemapper.systemRunning();
mPointerIconCache.systemRunning();
+ mKeyboardGlyphManager.systemRunning();
}
private void reloadDeviceAliases() {
@@ -1208,6 +1214,11 @@ public class InputManagerService extends IInputManager.Stub
imeInfo, imeSubtype);
}
+ @Override // Binder call
+ public KeyGlyphMap getKeyGlyphMap(int deviceId) {
+ return mKeyboardGlyphManager.getKeyGlyphMap(deviceId);
+ }
+
public void setFocusedApplication(int displayId, InputApplicationHandle application) {
mNative.setFocusedApplication(displayId, application);
}
@@ -2077,6 +2088,7 @@ public class InputManagerService extends IInputManager.Stub
mBatteryController.dump(ipw);
mKeyboardBacklightController.dump(ipw);
mKeyboardLedController.dump(ipw);
+ mKeyboardGlyphManager.dump(ipw);
}
private void dumpAssociations(IndentingPrintWriter pw) {
@@ -3352,6 +3364,10 @@ public class InputManagerService extends IInputManager.Stub
mPointerIconCache.setPointerFillStyle(fillStyle);
}
+ void setPointerStrokeStyle(@PointerIcon.PointerIconVectorStyleStroke int strokeStyle) {
+ mPointerIconCache.setPointerStrokeStyle(strokeStyle);
+ }
+
void setPointerScale(float scale) {
mPointerIconCache.setPointerScale(scale);
}
diff --git a/services/core/java/com/android/server/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java
index 593b0917efc7..000f3122f05a 100644
--- a/services/core/java/com/android/server/input/InputSettingsObserver.java
+++ b/services/core/java/com/android/server/input/InputSettingsObserver.java
@@ -18,6 +18,7 @@ package com.android.server.input;
import static android.view.PointerIcon.DEFAULT_POINTER_SCALE;
import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_BLACK;
+import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_WHITE;
import static android.view.flags.Flags.enableVectorCursorA11ySettings;
import static com.android.input.flags.Flags.rateLimitUserActivityPokeInDispatcher;
@@ -103,6 +104,8 @@ class InputSettingsObserver extends ContentObserver {
(reason) -> updateStylusPointerIconEnabled()),
Map.entry(Settings.System.getUriFor(Settings.System.POINTER_FILL_STYLE),
(reason) -> updatePointerFillStyleFromSettings()),
+ Map.entry(Settings.System.getUriFor(Settings.System.POINTER_STROKE_STYLE),
+ (reason) -> updatePointerStrokeStyleFromSettings()),
Map.entry(Settings.System.getUriFor(Settings.System.POINTER_SCALE),
(reason) -> updatePointerScaleFromSettings()));
}
@@ -281,6 +284,17 @@ class InputSettingsObserver extends ContentObserver {
mService.setPointerFillStyle(pointerFillStyle);
}
+ private void updatePointerStrokeStyleFromSettings() {
+ if (!enableVectorCursorA11ySettings()) {
+ return;
+ }
+ final int pointerStrokeStyle = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.POINTER_STROKE_STYLE,
+ POINTER_ICON_VECTOR_STYLE_STROKE_WHITE,
+ UserHandle.USER_CURRENT);
+ mService.setPointerStrokeStyle(pointerStrokeStyle);
+ }
+
private void updatePointerScaleFromSettings() {
if (!enableVectorCursorA11ySettings()) {
return;
diff --git a/services/core/java/com/android/server/input/KeyboardGlyphManager.java b/services/core/java/com/android/server/input/KeyboardGlyphManager.java
new file mode 100644
index 000000000000..f59d72b0c0b6
--- /dev/null
+++ b/services/core/java/com/android/server/input/KeyboardGlyphManager.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright 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.input;
+
+import static com.android.hardware.input.Flags.keyboardGlyphMap;
+
+import android.annotation.AnyRes;
+import android.annotation.MainThread;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.hardware.input.InputManager;
+import android.hardware.input.KeyGlyphMap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+import android.view.InputDevice;
+
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Provides information on custom glyphs configured for specific keyboard devices.
+ *
+ * @hide
+ */
+public final class KeyboardGlyphManager implements InputManager.InputDeviceListener {
+
+ private static final String TAG = "KeyboardGlyphManager";
+ // To enable these logs, run: 'adb shell setprop log.tag.KeyboardGlyphManager DEBUG'
+ // (requires restart)
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private static final String TAG_KEYBOARD_GLYPH_MAPS = "keyboard-glyph-maps";
+ private static final String TAG_KEYBOARD_GLYPH_MAP = "keyboard-glyph-map";
+ private static final String TAG_KEY_GLYPH = "key-glyph";
+ private static final String TAG_MODIFIER_GLYPH = "modifier-glyph";
+ private static final String TAG_FUNCTION_ROW_KEY = "function-row-key";
+ private static final String TAG_HARDWARE_DEFINED_SHORTCUT = "hardware-defined-shortcut";
+
+ private final Context mContext;
+ private final Handler mHandler;
+ private final Object mGlyphMapLock = new Object();
+ @GuardedBy("mGlyphMapLock")
+ private boolean mGlyphMapDataLoaded = false;
+ @GuardedBy("mGlyphMapLock")
+ private List<KeyGlyphMapData> mGlyphMapDataList = new ArrayList<>();
+ // Cache for already loaded glyph maps
+ @GuardedBy("mGlyphMapLock")
+ private final SparseArray<KeyGlyphMap> mGlyphMapCache = new SparseArray<>();
+
+ KeyboardGlyphManager(Context context, Looper looper) {
+ mContext = context;
+ mHandler = new Handler(looper);
+ }
+
+ void systemRunning() {
+ if (!keyboardGlyphMap()) {
+ return;
+ }
+ // Listen to new Package installations to fetch new Keyboard glyph maps
+ IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+ filter.addDataScheme("package");
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ resetMaps();
+ }
+ }, filter, null, mHandler);
+ }
+
+ @Override
+ @MainThread
+ public void onInputDeviceAdded(int deviceId) {
+ }
+
+ @Override
+ @MainThread
+ public void onInputDeviceRemoved(int deviceId) {
+ synchronized (mGlyphMapLock) {
+ mGlyphMapCache.remove(deviceId);
+ }
+ }
+
+ @Override
+ @MainThread
+ public void onInputDeviceChanged(int deviceId) {
+ }
+
+ @MainThread
+ private void resetMaps() {
+ synchronized (mGlyphMapLock) {
+ mGlyphMapDataLoaded = false;
+ mGlyphMapDataList.clear();
+ mGlyphMapCache.clear();
+ }
+ }
+
+ @NonNull
+ private List<KeyGlyphMapData> loadGlyphMapDataList() {
+ final PackageManager pm = mContext.getPackageManager();
+ List<KeyGlyphMapData> glyphMaps = new ArrayList<>();
+ Intent intent = new Intent(InputManager.ACTION_QUERY_KEYBOARD_GLYPH_MAPS);
+ for (ResolveInfo resolveInfo : pm.queryBroadcastReceiversAsUser(intent,
+ PackageManager.GET_META_DATA | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, UserHandle.USER_SYSTEM)) {
+ if (resolveInfo == null || resolveInfo.activityInfo == null) {
+ continue;
+ }
+ final ActivityInfo activityInfo = resolveInfo.activityInfo;
+ KeyGlyphMapData data = getKeyboardGlyphMapsInPackage(pm, activityInfo);
+ if (data == null) {
+ continue;
+ }
+ glyphMaps.add(data);
+ }
+ return glyphMaps;
+ }
+
+ @Nullable
+ private KeyGlyphMapData getKeyboardGlyphMapsInPackage(PackageManager pm,
+ @NonNull ActivityInfo receiver) {
+ Bundle metaData = receiver.metaData;
+ if (metaData == null) {
+ return null;
+ }
+
+ int configResId = metaData.getInt(InputManager.META_DATA_KEYBOARD_GLYPH_MAPS);
+ if (configResId == 0) {
+ Slog.w(TAG, "Missing meta-data '" + InputManager.META_DATA_KEYBOARD_GLYPH_MAPS
+ + "' on receiver " + receiver.packageName + "/" + receiver.name);
+ return null;
+ }
+
+ try {
+ Resources resources = pm.getResourcesForApplication(receiver.applicationInfo);
+ try (XmlResourceParser parser = resources.getXml(configResId)) {
+ XmlUtils.beginDocument(parser, TAG_KEYBOARD_GLYPH_MAPS);
+
+ while (true) {
+ XmlUtils.nextElement(parser);
+ String element = parser.getName();
+ if (element == null) {
+ break;
+ }
+ if (!TAG_KEYBOARD_GLYPH_MAP.equals(element)) {
+ continue;
+ }
+ TypedArray a = resources.obtainAttributes(parser, R.styleable.KeyboardGlyphMap);
+ try {
+ int glyphMapRes = a.getResourceId(R.styleable.KeyboardGlyphMap_glyphMap, 0);
+ int vendor = a.getInt(R.styleable.KeyboardGlyphMap_vendorId, -1);
+ int product = a.getInt(R.styleable.KeyboardGlyphMap_productId, -1);
+ if (glyphMapRes != 0 && vendor != -1 && product != -1) {
+ return new KeyGlyphMapData(receiver.packageName, receiver.name,
+ glyphMapRes, vendor, product);
+ }
+ } finally {
+ a.recycle();
+ }
+ }
+ }
+ } catch (Exception ex) {
+ Slog.w(TAG, "Could not parse keyboard glyph map resource from receiver "
+ + receiver.packageName + "/" + receiver.name, ex);
+ }
+ return null;
+ }
+
+ @Nullable
+ private KeyGlyphMap loadGlyphMap(KeyGlyphMapData data) {
+ final PackageManager pm = mContext.getPackageManager();
+ try {
+ ComponentName componentName = new ComponentName(data.packageName, data.receiverName);
+ ActivityInfo receiver = pm.getReceiverInfo(componentName,
+ PackageManager.GET_META_DATA
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
+ Resources resources = pm.getResourcesForApplication(receiver.applicationInfo);
+ return loadGlyphMapFromResource(resources, componentName, data.resourceId);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Package not found: " + e);
+ }
+ return null;
+ }
+
+ @NonNull
+ private KeyGlyphMap loadGlyphMapFromResource(Resources resources,
+ @NonNull ComponentName componentName, @AnyRes int glyphMapId) {
+ SparseIntArray keyGlyphs = new SparseIntArray();
+ SparseIntArray modifierGlyphs = new SparseIntArray();
+ List<Integer> functionRowKeys = new ArrayList<>();
+ HashMap<KeyGlyphMap.KeyCombination, Integer> hardwareShortcuts = new HashMap<>();
+ try {
+ XmlResourceParser parser = resources.getXml(glyphMapId);
+ XmlUtils.beginDocument(parser, TAG_KEYBOARD_GLYPH_MAP);
+
+ while (true) {
+ XmlUtils.nextElement(parser);
+ String element = parser.getName();
+ if (element == null) {
+ break;
+ }
+ switch (element) {
+ case TAG_KEY_GLYPH -> {
+ final TypedArray a = resources.obtainAttributes(parser,
+ R.styleable.KeyGlyph);
+ try {
+ int keycode = a.getInt(R.styleable.KeyGlyph_keycode, 0);
+ int keyGlyph = a.getResourceId(R.styleable.KeyGlyph_glyphDrawable, 0);
+ if (keycode != 0 && keyGlyph != 0) {
+ keyGlyphs.put(keycode, keyGlyph);
+ }
+ } finally {
+ a.recycle();
+ }
+ }
+ case TAG_MODIFIER_GLYPH -> {
+ final TypedArray a = resources.obtainAttributes(parser,
+ R.styleable.ModifierGlyph);
+ try {
+ int modifier = a.getInt(R.styleable.ModifierGlyph_modifier, 0);
+ int modifierGlyph = a.getResourceId(
+ R.styleable.ModifierGlyph_glyphDrawable,
+ 0);
+ if (modifier != 0 && modifierGlyph != 0) {
+ modifierGlyphs.put(modifier, modifierGlyph);
+ }
+ } finally {
+ a.recycle();
+ }
+ }
+ case TAG_FUNCTION_ROW_KEY -> {
+ final TypedArray a = resources.obtainAttributes(parser,
+ R.styleable.FunctionRowKey);
+ try {
+ int keycode = a.getInt(R.styleable.FunctionRowKey_keycode, 0);
+ if (keycode != 0) {
+ functionRowKeys.add(keycode);
+ }
+ } finally {
+ a.recycle();
+ }
+ }
+ case TAG_HARDWARE_DEFINED_SHORTCUT -> {
+ final TypedArray a = resources.obtainAttributes(parser,
+ R.styleable.HardwareDefinedShortcut);
+ try {
+ int keycode = a.getInt(R.styleable.HardwareDefinedShortcut_keycode,
+ 0);
+ int modifierState = a.getInt(
+ R.styleable.HardwareDefinedShortcut_modifierState, 0);
+ int outKeycode = a.getInt(
+ R.styleable.HardwareDefinedShortcut_outKeycode,
+ 0);
+ if (keycode != 0 && modifierState != 0 && outKeycode != 0) {
+ hardwareShortcuts.put(
+ new KeyGlyphMap.KeyCombination(modifierState, keycode),
+ outKeycode);
+ }
+ } finally {
+ a.recycle();
+ }
+ }
+ }
+ }
+ } catch (XmlPullParserException | IOException e) {
+ Log.e(TAG, "Unable to parse key glyph map : " + e);
+ }
+ return new KeyGlyphMap(componentName, keyGlyphs, modifierGlyphs,
+ functionRowKeys.stream().mapToInt(Integer::intValue).toArray(), hardwareShortcuts);
+ }
+
+ /**
+ * Returns keyboard glyph map corresponding to device ID
+ */
+ @Nullable
+ public KeyGlyphMap getKeyGlyphMap(int deviceId) {
+ if (!keyboardGlyphMap()) {
+ return null;
+ }
+ synchronized (mGlyphMapLock) {
+ if (mGlyphMapCache.indexOfKey(deviceId) >= 0) {
+ return mGlyphMapCache.get(deviceId);
+ }
+ KeyGlyphMap keyGlyphMap = getKeyGlyphMapInternal(deviceId);
+ mGlyphMapCache.put(deviceId, keyGlyphMap);
+ return keyGlyphMap;
+ }
+ }
+
+ @GuardedBy("mGlyphMapLock")
+ private KeyGlyphMap getKeyGlyphMapInternal(int deviceId) {
+ final InputDevice inputDevice = getInputDevice(deviceId);
+ if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
+ return null;
+ }
+ if (!mGlyphMapDataLoaded) {
+ mGlyphMapDataList = loadGlyphMapDataList();
+ mGlyphMapDataLoaded = true;
+ }
+ for (KeyGlyphMapData data : mGlyphMapDataList) {
+ if (data.vendorId == inputDevice.getVendorId()
+ && data.productId == inputDevice.getProductId()) {
+ return loadGlyphMap(data);
+ }
+ }
+ return null;
+ }
+
+ void dump(IndentingPrintWriter ipw) {
+ if (!keyboardGlyphMap()) {
+ return;
+ }
+ List<KeyGlyphMapData> glyphMapDataList = loadGlyphMapDataList();
+ ipw.println(TAG + ": " + glyphMapDataList.size() + " glyph maps");
+ ipw.increaseIndent();
+ for (KeyGlyphMapData data : glyphMapDataList) {
+ ipw.println(data);
+ if (DEBUG) {
+ KeyGlyphMap map = loadGlyphMap(data);
+ if (map != null) {
+ ipw.increaseIndent();
+ ipw.println(map);
+ ipw.decreaseIndent();
+ }
+ }
+ }
+ ipw.decreaseIndent();
+ }
+
+ @Nullable
+ private InputDevice getInputDevice(int deviceId) {
+ InputManager inputManager = mContext.getSystemService(InputManager.class);
+ return inputManager != null ? inputManager.getInputDevice(deviceId) : null;
+ }
+
+ private record KeyGlyphMapData(@NonNull String packageName, @NonNull String receiverName,
+ @AnyRes int resourceId, int vendorId, int productId) {
+ }
+}
diff --git a/services/core/java/com/android/server/input/PointerIconCache.java b/services/core/java/com/android/server/input/PointerIconCache.java
index 44622d80da0e..297cd68d5d3d 100644
--- a/services/core/java/com/android/server/input/PointerIconCache.java
+++ b/services/core/java/com/android/server/input/PointerIconCache.java
@@ -18,6 +18,7 @@ package com.android.server.input;
import static android.view.PointerIcon.DEFAULT_POINTER_SCALE;
import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_BLACK;
+import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_WHITE;
import android.annotation.NonNull;
import android.content.Context;
@@ -65,6 +66,9 @@ final class PointerIconCache {
private @PointerIcon.PointerIconVectorStyleFill int mPointerIconFillStyle =
POINTER_ICON_VECTOR_STYLE_FILL_BLACK;
@GuardedBy("mLoadedPointerIconsByDisplayAndType")
+ private @PointerIcon.PointerIconVectorStyleStroke int mPointerIconStrokeStyle =
+ POINTER_ICON_VECTOR_STYLE_STROKE_WHITE;
+ @GuardedBy("mLoadedPointerIconsByDisplayAndType")
private float mPointerIconScale = DEFAULT_POINTER_SCALE;
private final DisplayManager.DisplayListener mDisplayListener =
@@ -120,6 +124,11 @@ final class PointerIconCache {
mUiThreadHandler.post(() -> handleSetPointerFillStyle(fillStyle));
}
+ /** Set the stroke style for vector pointer icons. */
+ public void setPointerStrokeStyle(@PointerIcon.PointerIconVectorStyleStroke int strokeStyle) {
+ mUiThreadHandler.post(() -> handleSetPointerStrokeStyle(strokeStyle));
+ }
+
/** Set the scale for vector pointer icons. */
public void setPointerScale(float scale) {
mUiThreadHandler.post(() -> handleSetPointerScale(scale));
@@ -144,6 +153,8 @@ final class PointerIconCache {
theme.setTo(context.getTheme());
theme.applyStyle(PointerIcon.vectorFillStyleToResource(mPointerIconFillStyle),
/* force= */ true);
+ theme.applyStyle(PointerIcon.vectorStrokeStyleToResource(mPointerIconStrokeStyle),
+ /* force= */ true);
icon = PointerIcon.getLoadedSystemIcon(new ContextThemeWrapper(context, theme),
type, mUseLargePointerIcons, mPointerIconScale);
iconsByType.put(type, icon);
@@ -224,6 +235,20 @@ final class PointerIconCache {
}
@android.annotation.UiThread
+ private void handleSetPointerStrokeStyle(
+ @PointerIcon.PointerIconVectorStyleStroke int strokeStyle) {
+ synchronized (mLoadedPointerIconsByDisplayAndType) {
+ if (mPointerIconStrokeStyle == strokeStyle) {
+ return;
+ }
+ mPointerIconStrokeStyle = strokeStyle;
+ // Clear all cached icons on all displays.
+ mLoadedPointerIconsByDisplayAndType.clear();
+ }
+ mNative.reloadPointerIcons();
+ }
+
+ @android.annotation.UiThread
private void handleSetPointerScale(float scale) {
synchronized (mLoadedPointerIconsByDisplayAndType) {
if (mPointerIconScale == scale) {
diff --git a/services/core/java/com/android/server/inputmethod/AdditionalSubtypeMapRepository.java b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeMapRepository.java
index 82ecb4acb197..8ca045834981 100644
--- a/services/core/java/com/android/server/inputmethod/AdditionalSubtypeMapRepository.java
+++ b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeMapRepository.java
@@ -18,20 +18,14 @@ package com.android.server.inputmethod;
import android.annotation.AnyThread;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
-import android.content.Context;
-import android.content.pm.UserInfo;
import android.os.Handler;
import android.os.Process;
import android.util.IntArray;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.inputmethod.DirectBootAwareness;
-import com.android.server.LocalServices;
-import com.android.server.pm.UserManagerInternal;
import java.util.ArrayList;
import java.util.concurrent.locks.Condition;
@@ -225,49 +219,17 @@ final class AdditionalSubtypeMapRepository {
sWriter.startThread();
}
- static void initialize(@NonNull Handler handler, @NonNull Context context) {
- final UserManagerInternal userManagerInternal =
- LocalServices.getService(UserManagerInternal.class);
- handler.post(() -> {
- userManagerInternal.addUserLifecycleListener(
- new UserManagerInternal.UserLifecycleListener() {
- @Override
- public void onUserCreated(UserInfo user, @Nullable Object token) {
- final int userId = user.id;
- sWriter.onUserCreated(userId);
- handler.post(() -> {
- synchronized (ImfLock.class) {
- if (!sPerUserMap.contains(userId)) {
- final AdditionalSubtypeMap additionalSubtypeMap =
- AdditionalSubtypeUtils.load(userId);
- sPerUserMap.put(userId, additionalSubtypeMap);
- final InputMethodSettings settings =
- InputMethodManagerService
- .queryInputMethodServicesInternal(context,
- userId,
- additionalSubtypeMap,
- DirectBootAwareness.AUTO);
- InputMethodSettingsRepository.put(userId, settings);
- }
- }
- });
- }
+ @AnyThread
+ static void onUserCreated(@UserIdInt int userId) {
+ sWriter.onUserCreated(userId);
+ }
- @Override
- public void onUserRemoved(UserInfo user) {
- final int userId = user.id;
- sWriter.onUserRemoved(userId);
- handler.post(() -> {
- synchronized (ImfLock.class) {
- sPerUserMap.remove(userId);
- }
- });
- }
- });
+ @AnyThread
+ static void remove(@UserIdInt int userId, @NonNull Handler ioHandler) {
+ sWriter.onUserRemoved(userId);
+ ioHandler.post(() -> {
synchronized (ImfLock.class) {
- for (int userId : userManagerInternal.getUserIds()) {
- sPerUserMap.put(userId, AdditionalSubtypeUtils.load(userId));
- }
+ sPerUserMap.remove(userId);
}
});
}
diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
index 356bc40cb985..7c93c8b80897 100644
--- a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
+++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
@@ -89,8 +89,8 @@ final class DefaultImeVisibilityApplier {
void performShowIme(IBinder showInputToken, @NonNull ImeTracker.Token statsToken,
@InputMethod.ShowFlags int showFlags, ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason, @UserIdInt int userId) {
- final var bindingController = mService.getInputMethodBindingController(userId);
final var userData = mService.getUserData(userId);
+ final var bindingController = userData.mBindingController;
final IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod != null) {
if (DEBUG) {
@@ -128,9 +128,9 @@ final class DefaultImeVisibilityApplier {
void performHideIme(IBinder hideInputToken, @NonNull ImeTracker.Token statsToken,
ResultReceiver resultReceiver, @SoftInputShowHideReason int reason,
@UserIdInt int userId) {
- final var bindingController = mService.getInputMethodBindingController(userId);
- final IInputMethodInvoker curMethod = bindingController.getCurMethod();
final var userData = mService.getUserData(userId);
+ final var bindingController = userData.mBindingController;
+ final IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod != null) {
// The IME will report its visible state again after the following message finally
// delivered to the IME process as an IPC. Hence the inconsistency between
@@ -171,7 +171,8 @@ final class DefaultImeVisibilityApplier {
void applyImeVisibility(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
@ImeVisibilityStateComputer.VisibilityState int state,
@SoftInputShowHideReason int reason, @UserIdInt int userId) {
- final var bindingController = mService.getInputMethodBindingController(userId);
+ final var userData = mService.getUserData(userId);
+ final var bindingController = userData.mBindingController;
final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
switch (state) {
case STATE_SHOW_IME:
@@ -184,7 +185,7 @@ final class DefaultImeVisibilityApplier {
break;
case STATE_HIDE_IME:
if (!Flags.refactorInsetsController()) {
- if (mService.hasAttachedClient()) {
+ if (userData.mCurClient != null) {
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
// IMMS only knows of focused window, not the actual IME target.
diff --git a/services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java b/services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java
index 3f28c47a430b..a7280e6e99b4 100644
--- a/services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java
+++ b/services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java
@@ -138,6 +138,9 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
@PermissionVerified(Manifest.permission.TEST_INPUT_METHOD)
boolean isInputMethodPickerShownForTest();
+ @PermissionVerified(Manifest.permission.WRITE_SECURE_SETTINGS)
+ void onImeSwitchButtonClickFromSystem(int displayId);
+
InputMethodSubtype getCurrentInputMethodSubtype(@UserIdInt int userId);
void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes,
@@ -344,6 +347,14 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
return mCallback.isInputMethodPickerShownForTest();
}
+ @EnforcePermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+ @Override
+ public void onImeSwitchButtonClickFromSystem(int displayId) {
+ super.onImeSwitchButtonClickFromSystem_enforcePermission();
+
+ mCallback.onImeSwitchButtonClickFromSystem(displayId);
+ }
+
@Override
public InputMethodSubtype getCurrentInputMethodSubtype(@UserIdInt int userId) {
return mCallback.getCurrentInputMethodSubtype(userId);
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
index b2298197f407..9837ab16a310 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
@@ -408,7 +408,8 @@ final class InputMethodBindingController {
InputMethodManager
.invalidateLocalConnectionlessStylusHandwritingAvailabilityCaches();
}
- mService.initializeImeLocked(mCurMethod, mCurToken, mUserId);
+ mService.initializeImeLocked(mCurMethod, mCurToken,
+ InputMethodBindingController.this);
mService.scheduleNotifyImeUidToAudioService(mCurMethodUid);
mService.reRequestCurrentClientSessionLocked(mUserId);
mAutofillController.performOnCreateInlineSuggestionsRequest();
@@ -664,6 +665,36 @@ final class InputMethodBindingController {
}
}
+ /**
+ * Returns the current {@link InputMethodSubtype}.
+ *
+ * <p>Also this method has had questionable behaviors:</p>
+ * <ul>
+ * <li>Calling this method can update {@link #mCurrentSubtype}.</li>
+ * <li>This method may return {@link #mCurrentSubtype} as-is, even if it does not belong to
+ * the current IME.</li>
+ * </ul>
+ * <p>TODO(b/347083680): Address above issues.</p>
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ InputMethodSubtype getCurrentInputMethodSubtype() {
+ final var selectedMethodId = getSelectedMethodId();
+ if (selectedMethodId == null) {
+ return null;
+ }
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(mUserId);
+ final InputMethodInfo imi = settings.getMethodMap().get(selectedMethodId);
+ if (imi == null || imi.getSubtypeCount() == 0) {
+ return null;
+ }
+ final var subtype = SubtypeUtils.getCurrentInputMethodSubtype(imi, settings,
+ mCurrentSubtype);
+ mCurrentSubtype = subtype;
+ return subtype;
+ }
+
+
@GuardedBy("ImfLock.class")
void setDisplayIdToShowIme(int displayId) {
mDisplayIdToShowIme = displayId;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodDrawsNavBarResourceMonitor.java b/services/core/java/com/android/server/inputmethod/InputMethodDrawsNavBarResourceMonitor.java
new file mode 100644
index 000000000000..b835d058f00f
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/InputMethodDrawsNavBarResourceMonitor.java
@@ -0,0 +1,89 @@
+/*
+ * 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.inputmethod;
+
+import static android.content.Intent.ACTION_OVERLAY_CHANGED;
+
+import android.annotation.AnyThread;
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.annotation.UserIdInt;
+import android.annotation.WorkerThread;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.PatternMatcher;
+import android.os.UserHandle;
+import android.util.Slog;
+
+final class InputMethodDrawsNavBarResourceMonitor {
+ private static final String TAG = "InputMethodDrawsNavBarResourceMonitor";
+
+ private static final String SYSTEM_PACKAGE_NAME = "android";
+
+ /**
+ * Not intended to be instantiated.
+ */
+ private InputMethodDrawsNavBarResourceMonitor() {
+ }
+
+ @WorkerThread
+ static boolean evaluate(@NonNull Context context, @UserIdInt int userId) {
+ final Context userAwareContext;
+ if (context.getUserId() == userId) {
+ userAwareContext = context;
+ } else {
+ userAwareContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
+ }
+ try {
+ return userAwareContext.getPackageManager()
+ .getResourcesForApplication(SYSTEM_PACKAGE_NAME)
+ .getBoolean(com.android.internal.R.bool.config_imeDrawsImeNavBar);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(TAG, "getResourcesForApplication(\"" + SYSTEM_PACKAGE_NAME + "\") failed",
+ e);
+ return false;
+ }
+ }
+
+ @FunctionalInterface
+ interface OnUpdateCallback {
+ void onUpdate(@UserIdInt int userId);
+ }
+
+ @SuppressLint("MissingPermission")
+ @AnyThread
+ static void registerCallback(@NonNull Context context, @NonNull Handler ioHandler,
+ @NonNull OnUpdateCallback callback) {
+ final IntentFilter intentFilter = new IntentFilter(ACTION_OVERLAY_CHANGED);
+ intentFilter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
+ intentFilter.addDataSchemeSpecificPart(SYSTEM_PACKAGE_NAME, PatternMatcher.PATTERN_LITERAL);
+
+ final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final int userId = getSendingUserId();
+ callback.onUpdate(userId);
+ }
+ };
+ context.registerReceiverAsUser(broadcastReceiver, UserHandle.ALL, intentFilter,
+ null /* broadcastPermission */, ioHandler, Context.RECEIVER_NOT_EXPORTED);
+ }
+}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 5228be48371c..8fd203324d97 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -26,6 +26,7 @@ import static android.provider.Settings.Secure.STYLUS_HANDWRITING_DEFAULT_VALUE;
import static android.provider.Settings.Secure.STYLUS_HANDWRITING_ENABLED;
import static android.server.inputmethod.InputMethodManagerServiceProto.BACK_DISPOSITION;
import static android.server.inputmethod.InputMethodManagerServiceProto.BOUND_TO_METHOD;
+import static android.server.inputmethod.InputMethodManagerServiceProto.CONCURRENT_MULTI_USER_MODE_ENABLED;
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_ATTRIBUTE;
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_CLIENT;
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_FOCUSED_WINDOW_SOFT_INPUT_MODE;
@@ -52,6 +53,7 @@ import static com.android.server.inputmethod.ImeVisibilityStateComputer.ImeTarge
import static com.android.server.inputmethod.ImeVisibilityStateComputer.ImeVisibilityResult;
import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME;
import static com.android.server.inputmethod.InputMethodBindingController.TIME_TO_RECONNECT;
+import static com.android.server.inputmethod.InputMethodSubtypeSwitchingController.MODE_AUTO;
import static com.android.server.inputmethod.InputMethodUtils.isSoftInputModeStateVisibleAllowed;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -66,11 +68,11 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiThread;
import android.annotation.UserIdInt;
+import android.annotation.WorkerThread;
import android.app.ActivityManagerInternal;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentProvider;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -79,8 +81,8 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.content.pm.UserInfo;
import android.content.res.Resources;
-import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManagerInternal;
@@ -90,6 +92,7 @@ import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.LocaleList;
+import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
@@ -168,14 +171,12 @@ import com.android.internal.inputmethod.StartInputReason;
import com.android.internal.inputmethod.UnbindReason;
import com.android.internal.os.TransferPipe;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.AccessibilityManagerInternal;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
-import com.android.server.SystemServerInitThreadPool;
import com.android.server.SystemService;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.input.InputManagerInternal;
@@ -201,7 +202,6 @@ import java.util.Objects;
import java.util.OptionalInt;
import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.IntFunction;
@@ -298,22 +298,21 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
private final String[] mNonPreemptibleInputMethods;
/**
- * See {@link #shouldEnableExperimentalConcurrentMultiUserMode(Context)} about when set to be
- * {@code true}.
+ * See {@link #shouldEnableConcurrentMultiUserMode(Context)} about when set to be {@code true}.
*/
@SharedByAllUsersField
- private final boolean mExperimentalConcurrentMultiUserModeEnabled;
+ private final boolean mConcurrentMultiUserModeEnabled;
/**
- * Returns {@code true} if experimental concurrent multi-user mode is enabled.
+ * Returns {@code true} if the concurrent multi-user mode is enabled.
*
* <p>Currently not compatible with profiles (e.g. work profile).</p>
*
* @param context {@link Context} to be used to query
* {@link PackageManager#FEATURE_AUTOMOTIVE}
- * @return {@code true} if experimental concurrent multi-user mode is enabled.
+ * @return {@code true} if the concurrent multi-user mode is enabled.
*/
- static boolean shouldEnableExperimentalConcurrentMultiUserMode(@NonNull Context context) {
+ static boolean shouldEnableConcurrentMultiUserMode(@NonNull Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
&& UserManager.isVisibleBackgroundUsersEnabled()
&& context.getResources().getBoolean(android.R.bool.config_perDisplayFocusEnabled)
@@ -330,13 +329,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@UserIdInt
@BinderThread
private int resolveImeUserIdLocked(@UserIdInt int callingProcessUserId) {
- return mExperimentalConcurrentMultiUserModeEnabled ? callingProcessUserId : mCurrentUserId;
+ return mConcurrentMultiUserModeEnabled ? callingProcessUserId : mCurrentUserId;
}
final Context mContext;
final Resources mRes;
private final Handler mHandler;
+ private final InputMethodManagerInternal mInputMethodManagerInternal;
@NonNull
private final Handler mIoHandler;
@@ -346,11 +346,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
private int mCurrentUserId;
/** Holds all user related data */
- @GuardedBy("ImfLock.class")
- private UserDataRepository mUserDataRepository;
+ @SharedByAllUsersField
+ private final UserDataRepository mUserDataRepository;
- @MultiUserUnawareField
- final SettingsObserver mSettingsObserver;
final WindowManagerInternal mWindowManagerInternal;
private final ActivityManagerInternal mActivityManagerInternal;
final PackageManagerInternal mPackageManagerInternal;
@@ -400,15 +398,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@SharedByAllUsersField
private IntArray mStylusIds;
- @GuardedBy("ImfLock.class")
- @Nullable
- @MultiUserUnawareField
- private OverlayableSystemBooleanResourceWrapper mImeDrawsImeNavBarRes;
- @GuardedBy("ImfLock.class")
- @Nullable
- @MultiUserUnawareField
- Future<?> mImeDrawsImeNavBarResLazyInitFuture;
-
private final ImeTracing.ServiceDumper mDumper = new ImeTracing.ServiceDumper() {
/**
* {@inheritDoc}
@@ -485,25 +474,18 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@SharedByAllUsersField
boolean mSystemReady;
- @GuardedBy("ImfLock.class")
+ @AnyThread
@NonNull
- UserDataRepository.UserData getUserData(@UserIdInt int userId) {
+ UserData getUserData(@UserIdInt int userId) {
return mUserDataRepository.getOrCreate(userId);
}
- @GuardedBy("ImfLock.class")
+ @AnyThread
@NonNull
InputMethodBindingController getInputMethodBindingController(@UserIdInt int userId) {
return getUserData(userId).mBindingController;
}
-
- @GuardedBy("ImfLock.class")
- @Nullable
- InputMethodInfo queryInputMethodForCurrentUserLocked(@NonNull String imeId) {
- return InputMethodSettingsRepository.get(mCurrentUserId).getMethodMap().get(imeId);
- }
-
/**
* The last window token that we confirmed that IME started talking to. This is always updated
* upon reports from the input method. If the window state is already changed before the report
@@ -523,14 +505,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
private final WeakHashMap<IBinder, Boolean> mFocusedWindowPerceptible = new WeakHashMap<>();
/**
- * The displayId of current active input method.
- */
- @GuardedBy("ImfLock.class")
- int getCurTokenDisplayIdLocked() {
- return getInputMethodBindingController(mCurrentUserId).getCurTokenDisplayId();
- }
-
- /**
* The display ID of the input method indicates the fallback display which returned by
* {@link #computeImeDisplayIdForTarget}.
*/
@@ -585,96 +559,53 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@NonNull
private final ImeTrackerService mImeTrackerService;
- class SettingsObserver extends ContentObserver {
- int mUserId;
- boolean mRegistered = false;
- @NonNull
- String mLastEnabled = "";
-
- /**
- * <em>This constructor must be called within the lock.</em>
- */
- SettingsObserver(Handler handler) {
- super(handler);
+ @GuardedBy("ImfLock.class")
+ private void onSecureSettingsChangedLocked(@NonNull String key, @UserIdInt int userId) {
+ if (!mConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
+ return;
}
-
- @GuardedBy("ImfLock.class")
- public void registerContentObserverLocked(@UserIdInt int userId) {
- if (mRegistered && mUserId == userId) {
- return;
+ switch (key) {
+ case Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD: {
+ mMenuController.updateKeyboardFromSettingsLocked();
+ break;
}
- ContentResolver resolver = mContext.getContentResolver();
- if (mRegistered) {
- mContext.getContentResolver().unregisterContentObserver(this);
- mRegistered = false;
- }
- if (mUserId != userId) {
- mLastEnabled = "";
- mUserId = userId;
- }
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.DEFAULT_INPUT_METHOD), false, this, userId);
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.ENABLED_INPUT_METHODS), false, this, userId);
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, this, userId);
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD), false, this, userId);
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE), false, this, userId);
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- STYLUS_HANDWRITING_ENABLED), false, this);
- mRegistered = true;
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- final Uri showImeUri = Settings.Secure.getUriFor(
- Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
- final Uri accessibilityRequestingNoImeUri = Settings.Secure.getUriFor(
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE);
- final Uri stylusHandwritingEnabledUri = Settings.Secure.getUriFor(
- STYLUS_HANDWRITING_ENABLED);
- synchronized (ImfLock.class) {
- if (showImeUri.equals(uri)) {
- mMenuController.updateKeyboardFromSettingsLocked();
- } else if (accessibilityRequestingNoImeUri.equals(uri)) {
- final int accessibilitySoftKeyboardSetting = Settings.Secure.getIntForUser(
- mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0, mUserId);
- mVisibilityStateComputer.getImePolicy().setA11yRequestNoSoftKeyboard(
- accessibilitySoftKeyboardSetting);
- final var userData = getUserData(mUserId);
- if (mVisibilityStateComputer.getImePolicy().isA11yRequestNoSoftKeyboard()) {
- hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
- 0 /* flags */, SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE,
- mUserId);
- } else if (isShowRequestedForCurrentWindow(mUserId)) {
- showCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
- InputMethodManager.SHOW_IMPLICIT,
- SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE, mUserId);
- }
- } else if (stylusHandwritingEnabledUri.equals(uri)) {
- InputMethodManager.invalidateLocalStylusHandwritingAvailabilityCaches();
- InputMethodManager
- .invalidateLocalConnectionlessStylusHandwritingAvailabilityCaches();
- } else {
- boolean enabledChanged = false;
- String newEnabled = InputMethodSettingsRepository.get(mUserId)
- .getEnabledInputMethodsStr();
- if (!mLastEnabled.equals(newEnabled)) {
- mLastEnabled = newEnabled;
- enabledChanged = true;
- }
- updateInputMethodsFromSettingsLocked(enabledChanged, mUserId);
+ case Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE: {
+ final int accessibilitySoftKeyboardSetting = Settings.Secure.getIntForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0, userId);
+ mVisibilityStateComputer.getImePolicy().setA11yRequestNoSoftKeyboard(
+ accessibilitySoftKeyboardSetting);
+ final var userData = getUserData(userId);
+ if (mVisibilityStateComputer.getImePolicy().isA11yRequestNoSoftKeyboard()) {
+ hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+ 0 /* flags */, SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE, userId);
+ } else if (isShowRequestedForCurrentWindow(userId)) {
+ showCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+ InputMethodManager.SHOW_IMPLICIT,
+ SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE, userId);
}
+ break;
+ }
+ case STYLUS_HANDWRITING_ENABLED: {
+ InputMethodManager.invalidateLocalStylusHandwritingAvailabilityCaches();
+ InputMethodManager
+ .invalidateLocalConnectionlessStylusHandwritingAvailabilityCaches();
+ break;
+ }
+ case Settings.Secure.DEFAULT_INPUT_METHOD:
+ case Settings.Secure.ENABLED_INPUT_METHODS:
+ case Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE: {
+ boolean enabledChanged = false;
+ String newEnabled = InputMethodSettingsRepository.get(userId)
+ .getEnabledInputMethodsStr();
+ final var userData = getUserData(userId);
+ if (!userData.mLastEnabledInputMethodsStr.equals(newEnabled)) {
+ userData.mLastEnabledInputMethodsStr = newEnabled;
+ enabledChanged = true;
+ }
+ updateInputMethodsFromSettingsLocked(enabledChanged, userId);
+ break;
}
- }
-
- @Override
- public String toString() {
- return "SettingsObserver{mUserId=" + mUserId + " mRegistered=" + mRegistered
- + " mLastEnabled=" + mLastEnabled + "}";
}
}
@@ -711,7 +642,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
* Handles {@link Intent#ACTION_LOCALE_CHANGED}.
*
* <p>Note: For historical reasons, {@link Intent#ACTION_LOCALE_CHANGED} has been sent to all
- * the users. We should ignore this event if this is about any background user's locale.</p>
+ * the users.</p>
*/
void onActionLocaleChanged(@NonNull LocaleList prevLocales, @NonNull LocaleList newLocales) {
if (DEBUG) {
@@ -728,13 +659,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
AdditionalSubtypeMapRepository.get(userId),
DirectBootAwareness.AUTO);
InputMethodSettingsRepository.put(userId, settings);
+
+ if (mConcurrentMultiUserModeEnabled || userId == mCurrentUserId) {
+ postInputMethodSettingUpdatedLocked(true /* resetDefaultEnabledIme */, userId);
+ // If the locale is changed, needs to reset the default ime
+ resetDefaultImeLocked(mContext, userId);
+ updateFromSettingsLocked(true, userId);
+ }
}
- // TODO(b/305849394): Dispatch this to non-current users.
- final int userId = mCurrentUserId;
- postInputMethodSettingUpdatedLocked(true /* resetDefaultEnabledIme */, userId);
- // If the locale is changed, needs to reset the default ime
- resetDefaultImeLocked(mContext, userId);
- updateFromSettingsLocked(true, userId);
}
}
@@ -769,8 +701,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (!isChangingPackagesOfCurrentUserLocked()) {
return false;
}
- final InputMethodSettings settings =
- InputMethodSettingsRepository.get(mCurrentUserId);
+ final int userId = getChangingUserId();
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
String curInputMethodId = settings.getSelectedInputMethod();
final List<InputMethodInfo> methodList = settings.getMethodList();
final int numImes = methodList.size();
@@ -783,8 +715,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (!doit) {
return true;
}
- resetSelectedInputMethodAndSubtypeLocked("");
- chooseNewDefaultIMELocked();
+ resetSelectedInputMethodAndSubtypeLocked("", userId);
+ chooseNewDefaultIMELocked(userId);
return true;
}
}
@@ -851,7 +783,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (change == PACKAGE_PERMANENT_CHANGE) {
Slog.i(TAG, "Input method uninstalled, disabling: " + imi.getComponent());
if (isCurrentUser) {
- setInputMethodEnabledLocked(imi.getId(), false);
+ setInputMethodEnabledLocked(imi.getId(), false, userId);
} else {
settings.buildAndPutEnabledInputMethodsStrRemovingId(
new StringBuilder(),
@@ -912,11 +844,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final var bindingController = getInputMethodBindingController(userId);
updateSystemUiLocked(0 /* vis */,
bindingController.getBackDisposition(), userId);
- if (!chooseNewDefaultIMELocked()) {
+ if (!chooseNewDefaultIMELocked(userId)) {
changed = true;
curIm = null;
Slog.i(TAG, "Unsetting current input method");
- resetSelectedInputMethodAndSubtypeLocked("");
+ resetSelectedInputMethodAndSubtypeLocked("", userId);
}
}
}
@@ -925,7 +857,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (curIm == null) {
// We currently don't have a default input method... is
// one now available?
- changed = chooseNewDefaultIMELocked();
+ changed = chooseNewDefaultIMELocked(userId);
} else if (!changed && isPackageModified(curIm.getPackageName())) {
// Even if the current input method is still available, current subtype could
// be obsolete when the package is modified in practice.
@@ -982,21 +914,62 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
* {@link SystemService} used to publish and manage the lifecycle of
* {@link InputMethodManagerService}.
*/
- public static final class Lifecycle extends SystemService {
+ public static final class Lifecycle extends SystemService
+ implements UserManagerInternal.UserLifecycleListener {
private final InputMethodManagerService mService;
-
public Lifecycle(Context context) {
- this(context, new InputMethodManagerService(context,
- shouldEnableExperimentalConcurrentMultiUserMode(context)));
+ this(context, createServiceForProduction(context));
+
+ // For production code, hook up user lifecycle
+ mService.mUserManagerInternal.addUserLifecycleListener(this);
+
+ // Hook up resource change first before initializeUsersAsync() starts reading the
+ // seemingly initial data so that we can eliminate the race condition.
+ InputMethodDrawsNavBarResourceMonitor.registerCallback(context, mService.mIoHandler,
+ mService::onUpdateResourceOverlay);
+
+ // Also schedule user init tasks onto an I/O thread.
+ initializeUsersAsync(mService.mUserManagerInternal.getUserIds());
}
- public Lifecycle(
- Context context, @NonNull InputMethodManagerService inputMethodManagerService) {
+ @VisibleForTesting
+ Lifecycle(Context context, @NonNull InputMethodManagerService inputMethodManagerService) {
super(context);
mService = inputMethodManagerService;
}
+ /**
+ * Does initialization then instantiate {@link InputMethodManagerService} for production
+ * configurations.
+ *
+ * <p>We have this abstraction just because several unit tests directly initialize
+ * {@link InputMethodManagerService} with some mocked/emulated dependencies.</p>
+ *
+ * @param context {@link Context} to be used to set up
+ * @return {@link InputMethodManagerService} object to be used
+ */
+ @NonNull
+ private static InputMethodManagerService createServiceForProduction(
+ @NonNull Context context) {
+ // TODO(b/196206770): Disallow I/O on this thread. Currently it's needed for loading
+ // additional subtypes in switchUserOnHandlerLocked().
+ final ServiceThread thread = new ServiceThread(HANDLER_THREAD_NAME,
+ Process.THREAD_PRIORITY_FOREGROUND, true /* allowIo */);
+ thread.start();
+
+ final ServiceThread ioThread = new ServiceThread(PACKAGE_MONITOR_THREAD_NAME,
+ Process.THREAD_PRIORITY_FOREGROUND, true /* allowIo */);
+ ioThread.start();
+
+ SecureSettingsWrapper.setContentResolver(context.getContentResolver());
+
+ return new InputMethodManagerService(context,
+ shouldEnableConcurrentMultiUserMode(context), thread.getLooper(),
+ Handler.createAsync(ioThread.getLooper()),
+ null /* bindingControllerForTesting */);
+ }
+
@Override
public void onStart() {
mService.publishLocalService();
@@ -1018,7 +991,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
// Called on ActivityManager thread.
synchronized (ImfLock.class) {
- if (mService.mExperimentalConcurrentMultiUserModeEnabled) {
+ if (mService.mConcurrentMultiUserModeEnabled) {
// In concurrent multi-user mode, we in general do not rely on the concept of
// current user.
return;
@@ -1038,6 +1011,24 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
@Override
+ public void onUserCreated(UserInfo user, @Nullable Object token) {
+ // Called directly from UserManagerService. Do not block the calling thread.
+ final int userId = user.id;
+ AdditionalSubtypeMapRepository.onUserCreated(userId);
+ initializeUsersAsync(new int[userId]);
+ }
+
+ @Override
+ public void onUserRemoved(UserInfo user) {
+ // Called directly from UserManagerService. Do not block the calling thread.
+ final int userId = user.id;
+ SecureSettingsWrapper.onUserRemoved(userId);
+ AdditionalSubtypeMapRepository.remove(userId, mService.mIoHandler);
+ InputMethodSettingsRepository.remove(userId);
+ mService.mUserDataRepository.remove(userId);
+ }
+
+ @Override
public void onUserUnlocking(@NonNull TargetUser user) {
// Called on ActivityManager thread.
SecureSettingsWrapper.onUserUnlocking(user.getUserIdentifier());
@@ -1050,16 +1041,55 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// Called on ActivityManager thread.
final int userId = user.getUserIdentifier();
SecureSettingsWrapper.onUserStarting(userId);
- synchronized (ImfLock.class) {
- mService.getUserData(userId);
- if (mService.mExperimentalConcurrentMultiUserModeEnabled) {
- if (mService.mCurrentUserId != userId && mService.mSystemReady) {
- mService.experimentalInitializeVisibleBackgroundUserLocked(userId);
+ mService.mIoHandler.post(() -> {
+ synchronized (ImfLock.class) {
+ if (mService.mConcurrentMultiUserModeEnabled) {
+ if (mService.mCurrentUserId != userId && mService.mSystemReady) {
+ mService.initializeVisibleBackgroundUserLocked(userId);
+ }
}
}
- }
+ });
}
+ @AnyThread
+ private void initializeUsersAsync(@UserIdInt int[] userIds) {
+ mService.mIoHandler.post(() -> {
+ final var service = mService;
+ final var context = service.mContext;
+ final var userManagerInternal = service.mUserManagerInternal;
+
+ // We first create InputMethodMap for each user without loading AdditionalSubtypes.
+ final int numUsers = userIds.length;
+ final InputMethodMap[] rawMethodMaps = new InputMethodMap[numUsers];
+ for (int i = 0; i < numUsers; ++i) {
+ final int userId = userIds[i];
+ rawMethodMaps[i] = InputMethodManagerService.queryInputMethodServicesInternal(
+ context, userId, AdditionalSubtypeMap.EMPTY_MAP,
+ DirectBootAwareness.AUTO).getMethodMap();
+ final int profileParentId = userManagerInternal.getProfileParentId(userId);
+ final boolean value =
+ InputMethodDrawsNavBarResourceMonitor.evaluate(context,
+ profileParentId);
+ final var userData = mService.getUserData(userId);
+ userData.mImeDrawsNavBar.set(value);
+ }
+
+ // Then create full InputMethodMap for each user. Note that
+ // AdditionalSubtypeMapRepository#get() and InputMethodSettingsRepository#put()
+ // need to be called with ImfLock held (b/352387655).
+ // TODO(b/343601565): Avoid ImfLock after fixing b/352387655.
+ synchronized (ImfLock.class) {
+ for (int i = 0; i < numUsers; ++i) {
+ final int userId = userIds[i];
+ final var map = AdditionalSubtypeMapRepository.get(userId);
+ final var methodMap = rawMethodMaps[i].applyAdditionalSubtypes(map);
+ final var settings = InputMethodSettings.create(methodMap, userId);
+ InputMethodSettingsRepository.put(userId, settings);
+ }
+ }
+ });
+ }
}
void onUnlockUser(@UserIdInt int userId) {
@@ -1077,8 +1107,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// We need to rebuild IMEs.
postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */, userId);
updateInputMethodsFromSettingsLocked(true /* enabledChanged */, userId);
- } else if (mExperimentalConcurrentMultiUserModeEnabled) {
- experimentalInitializeVisibleBackgroundUserLocked(userId);
+ } else if (mConcurrentMultiUserModeEnabled) {
+ initializeVisibleBackgroundUserLocked(userId);
}
}
}
@@ -1104,51 +1134,22 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mHandler.post(task);
}
- public InputMethodManagerService(Context context,
- boolean experimentalConcurrentMultiUserModeEnabled) {
- this(context, experimentalConcurrentMultiUserModeEnabled, null, null, null);
- }
-
@VisibleForTesting
InputMethodManagerService(
Context context,
- boolean experimentalConcurrentMultiUserModeEnabled,
- @Nullable ServiceThread serviceThreadForTesting,
- @Nullable ServiceThread ioThreadForTesting,
+ boolean concurrentMultiUserModeEnabled,
+ @NonNull Looper uiLooper,
+ @NonNull Handler ioHandler,
@Nullable IntFunction<InputMethodBindingController> bindingControllerForTesting) {
synchronized (ImfLock.class) {
- mExperimentalConcurrentMultiUserModeEnabled =
- experimentalConcurrentMultiUserModeEnabled;
+ mConcurrentMultiUserModeEnabled = concurrentMultiUserModeEnabled;
mContext = context;
mRes = context.getResources();
- SecureSettingsWrapper.onStart(mContext);
- // TODO(b/196206770): Disallow I/O on this thread. Currently it's needed for loading
- // additional subtypes in switchUserOnHandlerLocked().
- final ServiceThread thread =
- serviceThreadForTesting != null
- ? serviceThreadForTesting
- : new ServiceThread(
- HANDLER_THREAD_NAME,
- Process.THREAD_PRIORITY_FOREGROUND,
- true /* allowIo */);
- thread.start();
- mHandler = Handler.createAsync(thread.getLooper(), this);
- {
- final ServiceThread ioThread =
- ioThreadForTesting != null
- ? ioThreadForTesting
- : new ServiceThread(
- PACKAGE_MONITOR_THREAD_NAME,
- Process.THREAD_PRIORITY_FOREGROUND,
- true /* allowIo */);
- ioThread.start();
- mIoHandler = Handler.createAsync(ioThread.getLooper());
- }
+ mHandler = Handler.createAsync(uiLooper, this);
+ mIoHandler = ioHandler;
SystemLocaleWrapper.onStart(context, this::onActionLocaleChanged, mHandler);
mImeTrackerService = new ImeTrackerService(mHandler);
- // Note: SettingsObserver doesn't register observers in its constructor.
- mSettingsObserver = new SettingsObserver(mHandler);
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
@@ -1161,26 +1162,13 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mShowOngoingImeSwitcherForPhones = false;
- // Executing InputMethodSettingsRepository.initialize() does not mean that it
- // immediately becomes ready to return the up-to-date InputMethodSettings for each
- // running user, because we want to return from the constructor as early as possible so
- // as not to delay the system boot process.
- // Search for InputMethodSettingsRepository.put() to find where and when it's actually
- // being updated. In general IMMS should refrain from exposing the existence of IMEs
- // until systemReady().
- InputMethodSettingsRepository.initialize(mHandler, mContext);
- AdditionalSubtypeMapRepository.initialize(mHandler, mContext);
-
mCurrentUserId = mActivityManagerInternal.getCurrentUserId();
@SuppressWarnings("GuardedBy") final IntFunction<InputMethodBindingController>
bindingControllerFactory = userId -> new InputMethodBindingController(userId,
InputMethodManagerService.this);
- mUserDataRepository = new UserDataRepository(mHandler, mUserManagerInternal,
+ mUserDataRepository = new UserDataRepository(
bindingControllerForTesting != null ? bindingControllerForTesting
: bindingControllerFactory);
- for (int id : mUserManagerInternal.getUserIds()) {
- getUserData(id);
- }
mMenuController = new InputMethodMenuController(this);
mVisibilityStateComputer = new ImeVisibilityStateComputer(this);
@@ -1194,9 +1182,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mNonPreemptibleInputMethods = mRes.getStringArray(
com.android.internal.R.array.config_nonPreemptibleInputMethods);
Runnable discardDelegationTextRunnable = () -> discardHandwritingDelegationText();
- mHwController = new HandwritingModeController(mContext, thread.getLooper(),
+ mHwController = new HandwritingModeController(mContext, uiLooper,
new InkWindowInitializer(), discardDelegationTextRunnable);
registerDeviceListenerAndCheckStylusSupport();
+ mInputMethodManagerInternal = new LocalServiceImpl();
}
}
@@ -1258,36 +1247,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false, userId);
}
- @GuardedBy("ImfLock.class")
- private void maybeInitImeNavbarConfigLocked(@UserIdInt int targetUserId) {
- // Currently, com.android.internal.R.bool.config_imeDrawsImeNavBar is overlaid only for the
- // profile parent user.
- // TODO(b/221443458): See if we can make OverlayManager be aware of profile groups.
- final int profileParentUserId = mUserManagerInternal.getProfileParentId(targetUserId);
- if (mImeDrawsImeNavBarRes != null
- && mImeDrawsImeNavBarRes.getUserId() != profileParentUserId) {
- mImeDrawsImeNavBarRes.close();
- mImeDrawsImeNavBarRes = null;
- }
- if (mImeDrawsImeNavBarRes == null) {
- final Context userContext;
- if (mContext.getUserId() == profileParentUserId) {
- userContext = mContext;
- } else {
- userContext = mContext.createContextAsUser(UserHandle.of(profileParentUserId),
- 0 /* flags */);
- }
- mImeDrawsImeNavBarRes = OverlayableSystemBooleanResourceWrapper.create(userContext,
- com.android.internal.R.bool.config_imeDrawsImeNavBar, mHandler, resource -> {
- synchronized (ImfLock.class) {
- if (resource == mImeDrawsImeNavBarRes) {
- sendOnNavButtonFlagsChangedLocked();
- }
- }
- });
- }
- }
-
@NonNull
private static PackageManager getPackageManagerForUser(@NonNull Context context,
@UserIdInt int userId) {
@@ -1320,13 +1279,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// Hereafter we start initializing things for "newUserId".
- maybeInitImeNavbarConfigLocked(newUserId);
+ final var newUserData = getUserData(newUserId);
- // ContentObserver should be registered again when the user is changed
- mSettingsObserver.registerContentObserverLocked(newUserId);
+ // TODO(b/342027196): Double check if we need to always reset upon user switching.
+ newUserData.mLastEnabledInputMethodsStr = "";
mCurrentUserId = newUserId;
- final var newUserData = getUserData(newUserId);
final String defaultImiId = SecureSettingsWrapper.getString(
Settings.Secure.DEFAULT_INPUT_METHOD, null, newUserId);
@@ -1399,25 +1357,20 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
});
}
- // TODO(b/32343335): The entire systemRunning() method needs to be revisited.
- mImeDrawsImeNavBarResLazyInitFuture = SystemServerInitThreadPool.submit(() -> {
- // Note that the synchronization block below guarantees that the task
- // can never be completed before the returned Future<?> object is assigned to
- // the "mImeDrawsImeNavBarResLazyInitFuture" field.
- synchronized (ImfLock.class) {
- mImeDrawsImeNavBarResLazyInitFuture = null;
- if (currentUserId != mCurrentUserId) {
- // This means that the current user is already switched to other user
- // before the background task is executed. In this scenario the relevant
- // field should already be initialized.
- return;
- }
- maybeInitImeNavbarConfigLocked(currentUserId);
- }
- }, "Lazily initialize IMMS#mImeDrawsImeNavBarRes");
-
mMyPackageMonitor.register(mContext, UserHandle.ALL, mIoHandler);
- mSettingsObserver.registerContentObserverLocked(currentUserId);
+ SecureSettingsChangeCallback.register(mHandler, mContext.getContentResolver(),
+ new String[] {
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ Settings.Secure.DEFAULT_INPUT_METHOD,
+ Settings.Secure.ENABLED_INPUT_METHODS,
+ Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE,
+ Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED,
+ }, (key, flags, userId) -> {
+ synchronized (ImfLock.class) {
+ onSecureSettingsChangedLocked(key, userId);
+ }
+ });
final IntentFilter broadcastFilterForAllUsers = new IntentFilter();
broadcastFilterForAllUsers.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
@@ -1439,14 +1392,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
getPackageManagerForUser(mContext, currentUserId),
newSettings.getEnabledInputMethodList());
- final var unused = SystemServerInitThreadPool.submit(
- AdditionalSubtypeMapRepository::startWriterThread,
- "Start AdditionalSubtypeMapRepository's writer thread");
+ AdditionalSubtypeMapRepository.startWriterThread();
- if (mExperimentalConcurrentMultiUserModeEnabled) {
+ if (mConcurrentMultiUserModeEnabled) {
for (int userId : mUserManagerInternal.getUserIds()) {
if (userId != mCurrentUserId) {
- experimentalInitializeVisibleBackgroundUserLocked(userId);
+ initializeVisibleBackgroundUserLocked(userId);
}
}
}
@@ -1471,15 +1422,15 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
* Returns true iff the caller is identified to be the current input method with the token.
*
* @param token the window token given to the input method when it was started
- * @param userId userId of the calling IME process
+ * @param userData {@link UserData} of the calling IME process
* @return true if and only if non-null valid token is specified
*/
@GuardedBy("ImfLock.class")
- private boolean calledWithValidTokenLocked(@NonNull IBinder token, @UserIdInt int userId) {
+ private boolean calledWithValidTokenLocked(@NonNull IBinder token, @NonNull UserData userData) {
if (token == null) {
throw new InvalidParameterException("token must not be null.");
}
- final var bindingController = getInputMethodBindingController(userId);
+ final var bindingController = userData.mBindingController;
if (token != bindingController.getCurToken()) {
Slog.e(TAG, "Ignoring " + Debug.getCaller() + " due to an invalid token."
+ " uid:" + Binder.getCallingUid() + " token:" + token);
@@ -1758,7 +1709,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
clearClientSessionLocked(client);
clearClientSessionForAccessibilityLocked(client);
// TODO(b/324907325): Remove the suppress warnings once b/324907325 is fixed.
- @SuppressWarnings("GuardedBy") Consumer<UserDataRepository.UserData> clientRemovedForUser =
+ @SuppressWarnings("GuardedBy") Consumer<UserData> clientRemovedForUser =
userData -> onClientRemovedInternalLocked(client, userData);
mUserDataRepository.forAllUserData(clientRemovedForUser);
}
@@ -1768,15 +1719,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
*/
// TODO(b/325515685): Move this method to InputMethodBindingController
@GuardedBy("ImfLock.class")
- private void onClientRemovedInternalLocked(ClientState client,
- @NonNull UserDataRepository.UserData userData) {
+ private void onClientRemovedInternalLocked(ClientState client, @NonNull UserData userData) {
final int userId = userData.mUserId;
if (userData.mCurClient == client) {
hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
SoftInputShowHideReason.HIDE_REMOVE_CLIENT, userId);
if (userData.mBoundToMethod) {
userData.mBoundToMethod = false;
- final var userBindingController = getInputMethodBindingController(userId);
+ final var userBindingController = userData.mBindingController;
IInputMethodInvoker curMethod = userBindingController.getCurMethod();
if (curMethod != null) {
// When we unbind input, we are unbinding the client, so we always
@@ -1808,7 +1758,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
Slog.v(TAG, "unbindCurrentInputLocked: client="
+ userData.mCurClient.mClient.asBinder());
}
- final var bindingController = getInputMethodBindingController(userId);
+ final var bindingController = userData.mBindingController;
if (userData.mBoundToMethod) {
userData.mBoundToMethod = false;
IInputMethodInvoker curMethod = bindingController.getCurMethod();
@@ -1863,15 +1813,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
}
- /**
- * {@code true} when a {@link ClientState} has attached from starting the
- * input connection.
- */
- @GuardedBy("ImfLock.class")
- boolean hasAttachedClient() {
- return getUserData(mCurrentUserId).mCurClient != null;
- }
-
@VisibleForTesting
void setAttachedClientForTesting(@NonNull ClientState cs) {
synchronized (ImfLock.class) {
@@ -1903,8 +1844,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@NonNull
InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial,
@UserIdInt int userId) {
- final var bindingController = getInputMethodBindingController(userId);
final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
if (!userData.mBoundToMethod) {
bindingController.getCurMethod().bindInput(userData.mCurClient.mBinding);
userData.mBoundToMethod = true;
@@ -1912,7 +1853,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final boolean restarting = !initial;
final Binder startInputToken = new Binder();
- final StartInputInfo info = new StartInputInfo(mCurrentUserId,
+ final StartInputInfo info = new StartInputInfo(userId,
bindingController.getCurToken(), bindingController.getCurTokenDisplayId(),
bindingController.getCurId(), startInputReason,
restarting, UserHandle.getUserId(userData.mCurClient.mUid),
@@ -1934,7 +1875,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
userData.mCurClient.mUid, true /* direct */);
}
- @InputMethodNavButtonFlags final int navButtonFlags = getInputMethodNavButtonFlagsLocked();
+ @InputMethodNavButtonFlags final int navButtonFlags =
+ getInputMethodNavButtonFlagsLocked(userData);
final SessionState session = userData.mCurClient.mCurSession;
setEnabledSessionLocked(session, userData);
session.mMethod.startInput(startInputToken, userData.mCurInputConnection,
@@ -2326,15 +2268,16 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
void initializeImeLocked(@NonNull IInputMethodInvoker inputMethod, @NonNull IBinder token,
- @UserIdInt int userId) {
+ @NonNull InputMethodBindingController bindingController) {
if (DEBUG) {
Slog.v(TAG, "Sending attach of token: " + token + " for display: "
- + getInputMethodBindingController(userId).getCurTokenDisplayId());
+ + bindingController.getCurTokenDisplayId());
}
+ final int userId = bindingController.getUserId();
+ final var userData = getUserData(userId);
inputMethod.initializeInternal(token,
- new InputMethodPrivilegedOperationsImpl(this, token, userId),
- // TODO(b/345519864): Make getInputMethodNavButtonFlagsLocked() multi-user aware
- getInputMethodNavButtonFlagsLocked());
+ new InputMethodPrivilegedOperationsImpl(this, token, userData),
+ getInputMethodNavButtonFlagsLocked(userData));
}
@AnyThread
@@ -2374,8 +2317,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
channel.dispose();
return;
}
- final var bindingController = getInputMethodBindingController(userId);
final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod != null && method != null
&& curMethod.asBinder() == method.asBinder()) {
@@ -2562,7 +2505,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@SuppressWarnings("GuardedBy") Consumer<ClientState> clearClientSession = c -> {
// TODO(b/305849394): Figure out what we should do for single user IME mode.
final boolean shouldClearClientSession =
- !mExperimentalConcurrentMultiUserModeEnabled
+ !mConcurrentMultiUserModeEnabled
|| UserHandle.getUserId(c.mUid) == userId;
if (shouldClearClientSession) {
clearClientSessionLocked(c);
@@ -2583,13 +2526,15 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
hideStatusBarIconLocked();
getUserData(userId).mInFullscreenMode = false;
mWindowManagerInternal.setDismissImeOnBackKeyPressed(false);
+ scheduleResetStylusHandwriting();
}
@BinderThread
private void updateStatusIcon(@NonNull IBinder token, String packageName,
- @DrawableRes int iconId, @UserIdInt int userId) {
+ @DrawableRes int iconId, @NonNull UserData userData) {
+ final int userId = userData.mUserId;
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
return;
}
final long ident = Binder.clearCallingIdentity();
@@ -2600,7 +2545,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
} else if (packageName != null) {
if (DEBUG) Slog.d(TAG, "show a small icon for the input method");
final PackageManager userAwarePackageManager =
- getPackageManagerForUser(mContext, mCurrentUserId);
+ getPackageManagerForUser(mContext, userId);
ApplicationInfo applicationInfo = null;
try {
applicationInfo = userAwarePackageManager.getApplicationInfo(packageName,
@@ -2632,23 +2577,18 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
@InputMethodNavButtonFlags
- private int getInputMethodNavButtonFlagsLocked() {
- if (mImeDrawsImeNavBarResLazyInitFuture != null) {
- // TODO(b/225366708): Avoid Future.get(), which is internally used here.
- ConcurrentUtils.waitForFutureNoInterrupt(mImeDrawsImeNavBarResLazyInitFuture,
- "Waiting for the lazy init of mImeDrawsImeNavBarRes");
- }
+ private int getInputMethodNavButtonFlagsLocked(@NonNull UserData userData) {
+ final int userId = userData.mUserId;
+ final var bindingController = userData.mBindingController;
// Whether the current display has a navigation bar. When this is false (e.g. emulator),
// the IME should not draw the IME navigation bar.
- final int tokenDisplayId = getCurTokenDisplayIdLocked();
+ final int tokenDisplayId = bindingController.getCurTokenDisplayId();
final boolean hasNavigationBar = mWindowManagerInternal
.hasNavigationBar(tokenDisplayId != INVALID_DISPLAY
? tokenDisplayId : DEFAULT_DISPLAY);
- final boolean canImeDrawsImeNavBar =
- mImeDrawsImeNavBarRes != null && mImeDrawsImeNavBarRes.get() && hasNavigationBar;
+ final boolean canImeDrawsImeNavBar = userData.mImeDrawsNavBar.get() && hasNavigationBar;
final boolean shouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherLocked(
- InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE,
- mCurrentUserId);
+ InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE, userId);
return (canImeDrawsImeNavBar ? InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR : 0)
| (shouldShowImeSwitcherWhenImeIsShown
? InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN : 0);
@@ -2732,14 +2672,15 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@BinderThread
@SuppressWarnings("deprecation")
private void setImeWindowStatus(@NonNull IBinder token, int vis, int backDisposition,
- @UserIdInt int userId) {
+ @NonNull UserData userData) {
final int topFocusedDisplayId = mWindowManagerInternal.getTopFocusedDisplayId();
+ final int userId = userData.mUserId;
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
return;
}
- final var bindingController = getInputMethodBindingController(userId);
+ final var bindingController = userData.mBindingController;
// Skip update IME status when current token display is not same as focused display.
// Note that we still need to update IME status when focusing external display
// that does not support system decoration and fallback to show IME on default
@@ -2771,9 +2712,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@BinderThread
private void reportStartInput(@NonNull IBinder token, IBinder startInputToken,
- @UserIdInt int userId) {
+ @NonNull UserData userData) {
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
return;
}
final IBinder targetWindow = mImeTargetWindowMap.get(startInputToken);
@@ -2807,8 +2748,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
private void updateSystemUiLocked(int vis, int backDisposition, @UserIdInt int userId) {
- final var bindingController = getInputMethodBindingController(userId);
final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
final var curToken = bindingController.getCurToken();
if (curToken == null) {
return;
@@ -2862,27 +2803,25 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
/**
- * This is an experimental implementation used when and only when
- * {@link #mExperimentalConcurrentMultiUserModeEnabled}.
+ * This initialization logic is used when and only when {@link #mConcurrentMultiUserModeEnabled}
+ * is set to {@code true}.
*
- * <p>Never assume what this method is doing is officially supported. For the canonical and
- * desired behaviors always refer to single-user code paths such as
+ * <p>There remain several yet-to-be-implemented features. For the canonical and desired
+ * behaviors always refer to single-user code paths such as
* {@link #updateInputMethodsFromSettingsLocked(boolean, int)}.</p>
*
* <p>Here are examples of missing features.</p>
* <ul>
- * <li>Subtypes are not supported at all!</li>
* <li>Profiles are not supported.</li>
* <li>
* {@link PackageManager#COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED} is not updated.
* </li>
* <li>{@link InputMethodBindingController#getDeviceIdToShowIme()} is ignored.</li>
- * <li>{@link #mPreventImeStartupUnlessTextEditor} is ignored.</li>
* <li>and so on.</li>
* </ul>
*/
@GuardedBy("ImfLock.class")
- void experimentalInitializeVisibleBackgroundUserLocked(@UserIdInt int userId) {
+ void initializeVisibleBackgroundUserLocked(@UserIdInt int userId) {
final var settings = InputMethodSettingsRepository.get(userId);
// Until we figure out what makes most sense, we enable all the pre-installed IMEs in
@@ -2890,7 +2829,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
String enabledImeIdsStr = settings.getEnabledInputMethodsStr();
for (var imi : settings.getMethodList()) {
if (!imi.isSystem()) {
- return;
+ continue;
}
enabledImeIdsStr = InputMethodUtils.concatEnabledImeIds(enabledImeIdsStr, imi.getId());
}
@@ -2903,19 +2842,18 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (TextUtils.isEmpty(id)) {
final InputMethodInfo imi = InputMethodInfoUtils.getMostApplicableDefaultIME(
settings.getEnabledInputMethodList());
- if (imi == null) {
- return;
+ if (imi != null) {
+ id = imi.getId();
+ settings.putSelectedInputMethod(id);
}
- id = imi.getId();
- settings.putSelectedInputMethod(id);
}
-
final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
+ bindingController.setSelectedMethodId(id);
+
+ // Also re-initialize controllers.
userData.mSwitchingController.resetCircularListLocked(mContext, settings);
userData.mHardwareKeyboardShortcutController.update(settings);
-
- final var bindingController = getInputMethodBindingController(userId);
- bindingController.setSelectedMethodId(id);
}
@GuardedBy("ImfLock.class")
@@ -2950,7 +2888,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
}
- final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
if (bindingController.getDeviceIdToShowIme() == DEVICE_ID_DEFAULT) {
String ime = SecureSettingsWrapper.getString(
Settings.Secure.DEFAULT_INPUT_METHOD, null, userId);
@@ -2975,7 +2914,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// enabled.
String id = settings.getSelectedInputMethod();
// There is no input method selected, try to choose new applicable input method.
- if (TextUtils.isEmpty(id) && chooseNewDefaultIMELocked()) {
+ if (TextUtils.isEmpty(id) && chooseNewDefaultIMELocked(userId)) {
id = settings.getSelectedInputMethod();
}
if (!TextUtils.isEmpty(id)) {
@@ -2990,10 +2929,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
resetCurrentMethodAndClientLocked(UnbindReason.NO_IME, userId);
}
- final var userData = getUserData(userId);
userData.mSwitchingController.resetCircularListLocked(mContext, settings);
userData.mHardwareKeyboardShortcutController.update(settings);
- sendOnNavButtonFlagsChangedLocked();
+ sendOnNavButtonFlagsChangedLocked(userData);
}
@GuardedBy("ImfLock.class")
@@ -3038,7 +2976,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// getCurrentInputMethodSubtype.
subtypeId = NOT_A_SUBTYPE_ID;
// TODO(b/347083680): The method below has questionable behaviors.
- newSubtype = getCurrentInputMethodSubtypeLocked();
+ newSubtype = bindingController.getCurrentInputMethodSubtype();
if (newSubtype != null) {
for (int i = 0; i < subtypeCount; ++i) {
if (Objects.equals(newSubtype, info.getSubtypeAt(i))) {
@@ -3472,8 +3410,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mVisibilityStateComputer.requestImeVisibility(windowToken, true);
// Ensure binding the connection when IME is going to show.
- final var bindingController = getInputMethodBindingController(userId);
final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
bindingController.setCurrentMethodVisible();
final IInputMethodInvoker curMethod = bindingController.getCurMethod();
ImeTracker.forLogging().onCancelled(userData.mCurStatsToken,
@@ -3606,7 +3544,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
boolean hideCurrentInputLocked(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
@InputMethodManager.HideFlags int flags, @Nullable ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason, @UserIdInt int userId) {
- final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
if (!mVisibilityStateComputer.canHideIme(statsToken, flags)) {
return false;
}
@@ -3619,7 +3558,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// since Android Eclair. That's why we need to accept IMM#hideSoftInput() even when only
// IMMS#InputShown indicates that the software keyboard is shown.
// TODO(b/246309664): Clean up IMMS#mImeWindowVis
- final var userData = getUserData(userId);
IInputMethodInvoker curMethod = bindingController.getCurMethod();
final boolean shouldHideSoftInput = curMethod != null
&& (isInputShownLocked()
@@ -3699,6 +3637,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
Slog.w(TAG, "User #" + userId + " is not running.");
return InputBindResult.INVALID_USER;
}
+ final var userData = getUserData(userId);
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
"IMMS.startInputOrWindowGainedFocus");
@@ -3706,7 +3645,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
"InputMethodManagerService#startInputOrWindowGainedFocus", mDumper);
final InputBindResult result;
synchronized (ImfLock.class) {
- final var bindingController = getInputMethodBindingController(userId);
+ final var bindingController = userData.mBindingController;
// If the system is not yet ready, we shouldn't be running third party code.
if (!mSystemReady) {
return new InputBindResult(
@@ -3723,8 +3662,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final long ident = Binder.clearCallingIdentity();
try {
// Verify if IMMS is in the process of switching user.
- if (!mExperimentalConcurrentMultiUserModeEnabled
- && mUserSwitchHandlerTask != null) {
+ if (!mConcurrentMultiUserModeEnabled && mUserSwitchHandlerTask != null) {
// There is already an on-going pending user switch task.
final int nextUserId = mUserSwitchHandlerTask.mToUserId;
if (userId == nextUserId) {
@@ -3772,14 +3710,13 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final boolean shouldClearFlag =
mImePlatformCompatUtils.shouldClearShowForcedFlag(cs.mUid);
final boolean showForced = mVisibilityStateComputer.mShowForced;
- final var userData = getUserData(userId);
if (userData.mImeBindingState.mFocusedWindow != windowToken
&& showForced && shouldClearFlag) {
mVisibilityStateComputer.mShowForced = false;
}
// Verify if caller is a background user.
- if (!mExperimentalConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
+ if (!mConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
if (ArrayUtils.contains(
mUserManagerInternal.getProfileIds(mCurrentUserId, false),
userId)) {
@@ -4032,6 +3969,25 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
}
+ @BinderThread
+ private void onImeSwitchButtonClickFromClient(@NonNull IBinder token, int displayId,
+ @NonNull UserData userData) {
+ synchronized (ImfLock.class) {
+ if (!calledWithValidTokenLocked(token, userData)) {
+ return;
+ }
+ showInputMethodPickerFromSystem(
+ InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES, displayId);
+ }
+ }
+
+ @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.WRITE_SECURE_SETTINGS)
+ @Override
+ public void onImeSwitchButtonClickFromSystem(int displayId) {
+ showInputMethodPickerFromSystem(
+ InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES, displayId);
+ }
+
@NonNull
private static IllegalArgumentException getExceptionForUnknownImeId(
@Nullable String imeId) {
@@ -4039,10 +3995,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
@BinderThread
- private void setInputMethod(@NonNull IBinder token, String id, @UserIdInt int userId) {
+ private void setInputMethod(@NonNull IBinder token, String id, @NonNull UserData userData) {
final int callingUid = Binder.getCallingUid();
+ final int userId = userData.mUserId;
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
return;
}
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
@@ -4057,10 +4014,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@BinderThread
private void setInputMethodAndSubtype(@NonNull IBinder token, String id,
- InputMethodSubtype subtype, @UserIdInt int userId) {
+ InputMethodSubtype subtype, @NonNull UserData userData) {
final int callingUid = Binder.getCallingUid();
+ final int userId = userData.mUserId;
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
return;
}
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
@@ -4073,18 +4031,20 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
setInputMethodWithSubtypeIdLocked(token, id,
SubtypeUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode()), userId);
} else {
- setInputMethod(token, id, userId);
+ setInputMethod(token, id, userData);
}
}
}
@BinderThread
- private boolean switchToPreviousInputMethod(@NonNull IBinder token, @UserIdInt int userId) {
+ private boolean switchToPreviousInputMethod(@NonNull IBinder token,
+ @NonNull UserData userData) {
+ final int userId = userData.mUserId;
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
return false;
}
- final var bindingController = getInputMethodBindingController(userId);
+ final var bindingController = userData.mBindingController;
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
final Pair<String, String> lastIme = settings.getLastInputMethodAndSubtype();
final InputMethodInfo lastImi;
@@ -4161,43 +4121,45 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@BinderThread
private boolean switchToNextInputMethod(@NonNull IBinder token, boolean onlyCurrentIme,
- @UserIdInt int userId) {
+ @NonNull UserData userData) {
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
return false;
}
- return switchToNextInputMethodLocked(token, onlyCurrentIme, userId);
+ return switchToNextInputMethodLocked(token, onlyCurrentIme, userData);
}
}
@GuardedBy("ImfLock.class")
private boolean switchToNextInputMethodLocked(@Nullable IBinder token, boolean onlyCurrentIme,
- @UserIdInt int userId) {
- final var bindingController = getInputMethodBindingController(userId);
+ @NonNull UserData userData) {
+ final var bindingController = userData.mBindingController;
final var currentImi = bindingController.getSelectedMethod();
- final ImeSubtypeListItem nextSubtype = getUserData(userId).mSwitchingController
+ final ImeSubtypeListItem nextSubtype = userData.mSwitchingController
.getNextInputMethodLocked(onlyCurrentIme, currentImi,
- bindingController.getCurrentSubtype());
+ bindingController.getCurrentSubtype(),
+ MODE_AUTO, true /* forward */);
if (nextSubtype == null) {
return false;
}
setInputMethodWithSubtypeIdLocked(token, nextSubtype.mImi.getId(),
- nextSubtype.mSubtypeId, userId);
+ nextSubtype.mSubtypeId, userData.mUserId);
return true;
}
@BinderThread
private boolean shouldOfferSwitchingToNextInputMethod(@NonNull IBinder token,
- @UserIdInt int userId) {
+ @NonNull UserData userData) {
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
return false;
}
- final var bindingController = getInputMethodBindingController(userId);
+ final var bindingController = userData.mBindingController;
final var currentImi = bindingController.getSelectedMethod();
- final ImeSubtypeListItem nextSubtype = getUserData(userId).mSwitchingController
+ final ImeSubtypeListItem nextSubtype = userData.mSwitchingController
.getNextInputMethodLocked(false /* onlyCurrentIme */, currentImi,
- bindingController.getCurrentSubtype());
+ bindingController.getCurrentSubtype(),
+ MODE_AUTO, true /* forward */);
return nextSubtype != null;
}
}
@@ -4291,9 +4253,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
if (currentUser) {
// To avoid unnecessary "updateInputMethodsFromSettingsLocked" from happening.
- if (mSettingsObserver != null) {
- mSettingsObserver.mLastEnabled = settings.getEnabledInputMethodsStr();
- }
+ final var userData = getUserData(userId);
+ userData.mLastEnabledInputMethodsStr = settings.getEnabledInputMethodsStr();
updateInputMethodsFromSettingsLocked(false /* enabledChanged */, userId);
}
}
@@ -4596,8 +4557,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
private void dumpDebug(ProtoOutputStream proto, long fieldId) {
synchronized (ImfLock.class) {
final int userId = mCurrentUserId;
- final var bindingController = getInputMethodBindingController(userId);
final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
final long token = proto.start(fieldId);
proto.write(CUR_METHOD_ID, bindingController.getSelectedMethodId());
proto.write(CUR_SEQ, bindingController.getSequenceNumber());
@@ -4622,17 +4583,18 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
proto.write(BACK_DISPOSITION, bindingController.getBackDisposition());
proto.write(IME_WINDOW_VISIBILITY, bindingController.getImeWindowVis());
proto.write(SHOW_IME_WITH_HARD_KEYBOARD, mMenuController.getShowImeWithHardKeyboard());
+ proto.write(CONCURRENT_MULTI_USER_MODE_ENABLED, mConcurrentMultiUserModeEnabled);
proto.end(token);
}
}
@BinderThread
- private void notifyUserAction(@NonNull IBinder token, @UserIdInt int userId) {
+ private void notifyUserAction(@NonNull IBinder token, @NonNull UserData userData) {
if (DEBUG) {
Slog.d(TAG, "Got the notification of a user action.");
}
synchronized (ImfLock.class) {
- final var bindingController = getInputMethodBindingController(userId);
+ final var bindingController = userData.mBindingController;
if (bindingController.getCurToken() != token) {
if (DEBUG) {
Slog.d(TAG, "Ignoring the user action notification from IMEs that are no longer"
@@ -4642,7 +4604,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
final InputMethodInfo imi = bindingController.getSelectedMethod();
if (imi != null) {
- getUserData(userId).mSwitchingController.onUserActionLocked(imi,
+ userData.mSwitchingController.onUserActionLocked(imi,
bindingController.getCurrentSubtype());
}
}
@@ -4650,11 +4612,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@BinderThread
private void applyImeVisibility(IBinder token, IBinder windowToken, boolean setVisible,
- @NonNull ImeTracker.Token statsToken, @UserIdInt int userId) {
+ @NonNull ImeTracker.Token statsToken, @NonNull UserData userData) {
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.applyImeVisibility");
+ final int userId = userData.mUserId;
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
return;
@@ -4704,7 +4667,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
return;
} else {
// Called with current IME's token.
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
if (settings.getMethodMap().get(id) != null
&& settings.getEnabledInputMethodListWithFilter(
(info) -> info.getId().equals(id)).isEmpty()) {
@@ -4729,8 +4692,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@UserIdInt int userId) {
final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(requestImeToken,
userId);
- final var bindingController = getInputMethodBindingController(userId);
final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
final WindowManagerInternal.ImeTargetInfo info =
mWindowManagerInternal.onToggleImeRequested(
show, userData.mImeBindingState.mFocusedWindow, requestToken,
@@ -4750,16 +4713,16 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@BinderThread
private void hideMySoftInput(@NonNull IBinder token, @NonNull ImeTracker.Token statsToken,
@InputMethodManager.HideFlags int flags, @SoftInputShowHideReason int reason,
- @UserIdInt int userId) {
+ @NonNull UserData userData) {
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideMySoftInput");
+ final int userId = userData.mUserId;
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
return;
}
- final var userData = getUserData(userId);
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
final long ident = Binder.clearCallingIdentity();
@@ -4789,16 +4752,16 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@BinderThread
private void showMySoftInput(@NonNull IBinder token, @NonNull ImeTracker.Token statsToken,
@InputMethodManager.ShowFlags int flags, @SoftInputShowHideReason int reason,
- @UserIdInt int userId) {
+ @NonNull UserData userData) {
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showMySoftInput");
+ final int userId = userData.mUserId;
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
return;
}
- final var userData = getUserData(userId);
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
final long ident = Binder.clearCallingIdentity();
@@ -4843,8 +4806,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
@GuardedBy("ImfLock.class")
- void setEnabledSessionLocked(SessionState session,
- @NonNull UserDataRepository.UserData userData) {
+ void setEnabledSessionLocked(SessionState session, @NonNull UserData userData) {
if (userData.mEnabledSession != session) {
if (userData.mEnabledSession != null && userData.mEnabledSession.mSession != null) {
if (DEBUG) Slog.v(TAG, "Disabling: " + userData.mEnabledSession);
@@ -4863,7 +4825,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
void setEnabledSessionForAccessibilityLocked(
SparseArray<AccessibilitySessionState> accessibilitySessions,
- @NonNull UserDataRepository.UserData userData) {
+ @NonNull UserData userData) {
// mEnabledAccessibilitySessions could the same object as accessibilitySessions.
SparseArray<IAccessibilityInputMethodSession> disabledSessions = new SparseArray<>();
for (int i = 0; i < userData.mEnabledAccessibilitySessions.size(); i++) {
@@ -5018,7 +4980,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
mMenuController.handleHardKeyboardStatusChange(msg.arg1 == 1);
synchronized (ImfLock.class) {
- sendOnNavButtonFlagsChangedLocked();
+ sendOnNavButtonFlagsChangedToAllImesLocked();
}
return true;
case MSG_SYSTEM_UNLOCK_USER: {
@@ -5072,9 +5034,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
case MSG_START_HANDWRITING:
final var handwritingRequest = (HandwritingRequest) msg.obj;
synchronized (ImfLock.class) {
- final int userId = handwritingRequest.userId;
- final var bindingController = getInputMethodBindingController(userId);
- final var userData = getUserData(userId);
+ final var userData = handwritingRequest.userData;
+ final var bindingController = userData.mBindingController;
IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod == null || userData.mImeBindingState.mFocusedWindow == null) {
return true;
@@ -5119,24 +5080,24 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
return false;
}
- private record HandwritingRequest(int requestId, int pid, @UserIdInt int userId) { }
+ private record HandwritingRequest(int requestId, int pid, @NonNull UserData userData) { }
@BinderThread
- private void onStylusHandwritingReady(int requestId, int pid, @UserIdInt int userId) {
+ private void onStylusHandwritingReady(int requestId, int pid, @NonNull UserData userData) {
mHandler.obtainMessage(MSG_START_HANDWRITING,
- new HandwritingRequest(requestId, pid, userId)).sendToTarget();
+ new HandwritingRequest(requestId, pid, userData)).sendToTarget();
}
private void handleSetInteractive(final boolean interactive) {
synchronized (ImfLock.class) {
// TODO(b/305849394): Support multiple IMEs.
final int userId = mCurrentUserId;
- final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
mIsInteractive = interactive;
updateSystemUiLocked(
interactive ? bindingController.getImeWindowVis() : 0,
bindingController.getBackDisposition(), userId);
- final var userData = getUserData(userId);
// Inform the current client of the change in active status
if (userData.mCurClient == null || userData.mCurClient.mClient == null) {
return;
@@ -5164,15 +5125,15 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
@GuardedBy("ImfLock.class")
- private boolean chooseNewDefaultIMELocked() {
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+ private boolean chooseNewDefaultIMELocked(@UserIdInt int userId) {
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
final InputMethodInfo imi = InputMethodInfoUtils.getMostApplicableDefaultIME(
settings.getEnabledInputMethodList());
if (imi != null) {
if (DEBUG) {
Slog.d(TAG, "New default IME was selected: " + imi.getId());
}
- resetSelectedInputMethodAndSubtypeLocked(imi.getId());
+ resetSelectedInputMethodAndSubtypeLocked(imi.getId(), userId);
return true;
}
@@ -5310,7 +5271,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
Slog.i(TAG, "All the enabled IMEs are gone. Reset default enabled IMEs.");
}
resetDefaultEnabledIme = true;
- resetSelectedInputMethodAndSubtypeLocked("");
+ resetSelectedInputMethodAndSubtypeLocked("", userId);
} else if (!enabledNonAuxImeFound) {
if (DEBUG) {
Slog.i(TAG, "All the enabled non-Aux IMEs are gone. Do partial reset.");
@@ -5329,7 +5290,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (DEBUG) {
Slog.d(TAG, "--- enable ime = " + imi);
}
- setInputMethodEnabledLocked(imi.getId(), true);
+ setInputMethodEnabledLocked(imi.getId(), true, userId);
}
}
@@ -5337,22 +5298,22 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (!TextUtils.isEmpty(defaultImiId)) {
if (!settings.getMethodMap().containsKey(defaultImiId)) {
Slog.w(TAG, "Default IME is uninstalled. Choose new default IME.");
- if (chooseNewDefaultIMELocked()) {
+ if (chooseNewDefaultIMELocked(userId)) {
updateInputMethodsFromSettingsLocked(true, userId);
}
} else {
// Double check that the default IME is certainly enabled.
- setInputMethodEnabledLocked(defaultImiId, true);
+ setInputMethodEnabledLocked(defaultImiId, true, userId);
}
}
- updateDefaultVoiceImeIfNeededLocked();
+ updateDefaultVoiceImeIfNeededLocked(userId);
final var userData = getUserData(userId);
userData.mSwitchingController.resetCircularListLocked(mContext, settings);
userData.mHardwareKeyboardShortcutController.update(settings);
- sendOnNavButtonFlagsChangedLocked();
+ sendOnNavButtonFlagsChangedLocked(userData);
// Notify InputMethodListListeners of the new installed InputMethods.
final List<InputMethodInfo> inputMethodList = settings.getMethodList();
@@ -5361,19 +5322,43 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
@GuardedBy("ImfLock.class")
- void sendOnNavButtonFlagsChangedLocked() {
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
+ void sendOnNavButtonFlagsChangedToAllImesLocked() {
+ for (int userId : mUserManagerInternal.getUserIds()) {
+ sendOnNavButtonFlagsChangedLocked(getUserData(userId));
+ }
+ }
+
+ @GuardedBy("ImfLock.class")
+ void sendOnNavButtonFlagsChangedLocked(@NonNull UserData userData) {
+ final var bindingController = userData.mBindingController;
final IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod == null) {
// No need to send the data if the IME is not yet bound.
return;
}
- curMethod.onNavButtonFlagsChanged(getInputMethodNavButtonFlagsLocked());
+ curMethod.onNavButtonFlagsChanged(getInputMethodNavButtonFlagsLocked(userData));
+ }
+
+ @WorkerThread
+ private void onUpdateResourceOverlay(@UserIdInt int userId) {
+ final int profileParentId = mUserManagerInternal.getProfileParentId(userId);
+ final boolean value =
+ InputMethodDrawsNavBarResourceMonitor.evaluate(mContext, profileParentId);
+ final var profileUserIds = mUserManagerInternal.getProfileIds(profileParentId, false);
+ final ArrayList<UserData> updatedUsers = new ArrayList<>();
+ for (int profileUserId : profileUserIds) {
+ final var userData = getUserData(profileUserId);
+ userData.mImeDrawsNavBar.set(value);
+ updatedUsers.add(userData);
+ }
+ synchronized (ImfLock.class) {
+ updatedUsers.forEach(this::sendOnNavButtonFlagsChangedLocked);
+ }
}
@GuardedBy("ImfLock.class")
- private void updateDefaultVoiceImeIfNeededLocked() {
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+ private void updateDefaultVoiceImeIfNeededLocked(@UserIdInt int userId) {
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
final String systemSpeechRecognizer =
mContext.getString(com.android.internal.R.string.config_systemSpeechRecognizer);
final String currentDefaultVoiceImeId = settings.getDefaultVoiceInputMethod();
@@ -5397,9 +5382,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
return;
}
if (DEBUG) {
- Slog.i(TAG, "Enabling the default Voice IME:" + newSystemVoiceIme);
+ Slog.i(TAG, "Enabling the default Voice IME:" + newSystemVoiceIme
+ + " userId:" + userId);
}
- setInputMethodEnabledLocked(newSystemVoiceIme.getId(), true);
+ setInputMethodEnabledLocked(newSystemVoiceIme.getId(), true, userId);
settings.putDefaultVoiceInputMethod(newSystemVoiceIme.getId());
}
@@ -5411,11 +5397,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
* @param id ID of the IME is to be manipulated. It is OK to pass IME ID that is currently
* not recognized by the system
* @param enabled {@code true} if {@code id} needs to be enabled
+ * @param userId the user ID to be updated
* @return {@code true} if the IME was previously enabled
*/
@GuardedBy("ImfLock.class")
- private boolean setInputMethodEnabledLocked(String id, boolean enabled) {
- final int userId = mCurrentUserId;
+ private boolean setInputMethodEnabledLocked(String id, boolean enabled, @UserIdInt int userId) {
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
if (enabled) {
final String enabledImeIdsStr = settings.getEnabledInputMethodsStr();
@@ -5439,9 +5425,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (bindingController.getDeviceIdToShowIme() == DEVICE_ID_DEFAULT) {
// Disabled input method is currently selected, switch to another one.
final String selId = settings.getSelectedInputMethod();
- if (id.equals(selId) && !chooseNewDefaultIMELocked()) {
+ if (id.equals(selId) && !chooseNewDefaultIMELocked(userId)) {
Slog.i(TAG, "Can't find new IME, unsetting the current input method.");
- resetSelectedInputMethodAndSubtypeLocked("");
+ resetSelectedInputMethodAndSubtypeLocked("", userId);
}
} else if (id.equals(settings.getSelectedDefaultDeviceInputMethod())) {
// Disabled default device IME while using a virtual device one, choose a
@@ -5486,7 +5472,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
newSubtypeHashcode = INVALID_SUBTYPE_HASHCODE;
// If the subtype is not specified, choose the most applicable one
// TODO(b/347083680): The method below has questionable behaviors.
- newSubtype = getCurrentInputMethodSubtypeLocked();
+ newSubtype = bindingController.getCurrentInputMethodSubtype();
}
}
settings.putSelectedSubtype(newSubtypeHashcode);
@@ -5497,12 +5483,15 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// Set InputMethod here
settings.putSelectedInputMethod(imi != null ? imi.getId() : "");
}
+
+ if (Flags.imeSwitcherRevamp()) {
+ getUserData(userId).mSwitchingController.onInputMethodSubtypeChanged();
+ }
}
@GuardedBy("ImfLock.class")
- private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme) {
- // TODO(b/305849394): get userId from callers
- final int userId = mCurrentUserId;
+ private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme,
+ @UserIdInt int userId) {
final var bindingController = getInputMethodBindingController(userId);
bindingController.setDisplayIdToShowIme(INVALID_DISPLAY);
bindingController.setDeviceIdToShowIme(DEVICE_ID_DEFAULT);
@@ -5541,51 +5530,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
synchronized (ImfLock.class) {
- if (mCurrentUserId == userId) {
- // TODO(b/347083680): The method below has questionable behaviors.
- return getCurrentInputMethodSubtypeLocked();
- }
-
- return InputMethodSettingsRepository.get(userId)
- .getCurrentInputMethodSubtypeForNonCurrentUsers();
- }
- }
-
- /**
- * Returns the current {@link InputMethodSubtype} for the current user.
- *
- * <p>CAVEATS: You must also update
- * {@link InputMethodSettings#getCurrentInputMethodSubtypeForNonCurrentUsers()}
- * when you update the algorithm of this method.</p>
- *
- * <p>TODO: Address code duplication between this and
- * {@link InputMethodSettings#getCurrentInputMethodSubtypeForNonCurrentUsers()}.</p>
- *
- * <p>Also this method has had questionable behaviors:</p>
- * <ul>
- * <li>Calling this method can update {@link #mCurrentSubtype}.</li>
- * <li>This method may return {@link #mCurrentSubtype} as-is, even if it does not belong
- * to the current IME.</li>
- * </ul>
- * <p>TODO(b/347083680): Address above issues.</p>
- */
- @GuardedBy("ImfLock.class")
- InputMethodSubtype getCurrentInputMethodSubtypeLocked() {
- final int userId = mCurrentUserId;
- final var selectedMethodId = getInputMethodBindingController(userId).getSelectedMethodId();
- if (selectedMethodId == null) {
- return null;
- }
- final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
- final InputMethodInfo imi = settings.getMethodMap().get(selectedMethodId);
- if (imi == null || imi.getSubtypeCount() == 0) {
- return null;
+ final var bindingController = getInputMethodBindingController(userId);
+ // TODO(b/347083680): The method below has questionable behaviors.
+ return bindingController.getCurrentInputMethodSubtype();
}
- final var bindingController = getInputMethodBindingController(userId);
- final var subtype = SubtypeUtils.getCurrentInputMethodSubtype(imi, settings,
- bindingController.getCurrentSubtype());
- bindingController.setCurrentSubtype(subtype);
- return subtype;
}
/**
@@ -5602,7 +5550,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
private boolean switchToInputMethodLocked(String imeId, @UserIdInt int userId) {
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
- if (userId == mCurrentUserId) {
+ if (mConcurrentMultiUserModeEnabled || userId == mCurrentUserId) {
if (!settings.getMethodMap().containsKey(imeId)
|| !settings.getEnabledInputMethodList()
.contains(settings.getMethodMap().get(imeId))) {
@@ -5650,20 +5598,38 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
@GuardedBy("ImfLock.class")
- private void switchKeyboardLayoutLocked(int direction, @UserIdInt int userId) {
+ private void switchKeyboardLayoutLocked(int direction, @NonNull UserData userData) {
+ final int userId = userData.mUserId;
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
- final var bindingController = getInputMethodBindingController(userId);
+ final var bindingController = userData.mBindingController;
final InputMethodInfo currentImi = settings.getMethodMap().get(
bindingController.getSelectedMethodId());
if (currentImi == null) {
return;
}
- final InputMethodSubtypeHandle currentSubtypeHandle =
- InputMethodSubtypeHandle.of(currentImi, bindingController.getCurrentSubtype());
- final InputMethodSubtypeHandle nextSubtypeHandle =
- getUserData(userId).mHardwareKeyboardShortcutController.onSubtypeSwitch(
+ final var currentSubtype = bindingController.getCurrentSubtype();
+ final InputMethodSubtypeHandle nextSubtypeHandle;
+ if (Flags.imeSwitcherRevamp()) {
+ final var nextItem = userData.mSwitchingController
+ .getNextInputMethodForHardware(
+ false /* onlyCurrentIme */, currentImi, currentSubtype, MODE_AUTO,
+ direction > 0 /* forward */);
+ if (nextItem == null) {
+ Slog.i(TAG, "Hardware keyboard switching shortcut,"
+ + " next input method and subtype not found");
+ return;
+ }
+
+ final var nextSubtype = nextItem.mSubtypeId > NOT_A_SUBTYPE_ID
+ ? nextItem.mImi.getSubtypeAt(nextItem.mSubtypeId) : null;
+ nextSubtypeHandle = InputMethodSubtypeHandle.of(nextItem.mImi, nextSubtype);
+ } else {
+ final InputMethodSubtypeHandle currentSubtypeHandle =
+ InputMethodSubtypeHandle.of(currentImi, currentSubtype);
+ nextSubtypeHandle = userData.mHardwareKeyboardShortcutController.onSubtypeSwitch(
currentSubtypeHandle, direction > 0);
+ }
if (nextSubtypeHandle == null) {
return;
}
@@ -5690,7 +5656,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
private void publishLocalService() {
- LocalServices.addService(InputMethodManagerInternal.class, new LocalServiceImpl());
+ LocalServices.addService(InputMethodManagerInternal.class, mInputMethodManagerInternal);
+ }
+
+ // TODO(b/352228316): Remove it once IMMIProxy is removed.
+ InputMethodManagerInternal getLocalService(){
+ return mInputMethodManagerInternal;
}
private final class LocalServiceImpl extends InputMethodManagerInternal {
@@ -5753,7 +5724,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
return false; // IME is not found.
}
if (userId == mCurrentUserId) {
- setInputMethodEnabledLocked(imeId, enabled);
+ setInputMethodEnabledLocked(imeId, enabled, userId);
return true;
}
if (enabled) {
@@ -5804,7 +5775,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (displayId != bindingController.getCurTokenDisplayId()) {
return false;
}
- curHostInputToken = getInputMethodBindingController(userId).getCurHostInputToken();
+ curHostInputToken = bindingController.getCurHostInputToken();
if (curHostInputToken == null) {
return false;
}
@@ -5860,8 +5831,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
public void onSessionForAccessibilityCreated(int accessibilityConnectionId,
IAccessibilityInputMethodSession session, @UserIdInt int userId) {
synchronized (ImfLock.class) {
- final var bindingController = getInputMethodBindingController(userId);
final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
// TODO(b/305829876): Implement user ID verification
if (userData.mCurClient != null) {
clearClientSessionForAccessibilityLocked(userData.mCurClient,
@@ -5898,8 +5869,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
public void unbindAccessibilityFromCurrentClient(int accessibilityConnectionId,
@UserIdInt int userId) {
synchronized (ImfLock.class) {
- final var bindingController = getInputMethodBindingController(userId);
final var userData = getUserData(userId);
+ final var bindingController = userData.mBindingController;
// TODO(b/305829876): Implement user ID verification
if (userData.mCurClient != null) {
if (DEBUG) {
@@ -5943,14 +5914,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
IBinder targetWindowToken) {
synchronized (ImfLock.class) {
// TODO(b/305849394): Infer userId from displayId
- switchKeyboardLayoutLocked(direction, mCurrentUserId);
+ switchKeyboardLayoutLocked(direction, getUserData(mCurrentUserId));
}
}
}
@BinderThread
private IInputContentUriToken createInputContentUriToken(@Nullable IBinder token,
- @Nullable Uri contentUri, @Nullable String packageName, @UserIdInt int imeUserId) {
+ @Nullable Uri contentUri, @Nullable String packageName, @NonNull UserData userData) {
if (token == null) {
throw new NullPointerException("token");
}
@@ -5967,7 +5938,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
synchronized (ImfLock.class) {
final int uid = Binder.getCallingUid();
- final var bindingController = getInputMethodBindingController(imeUserId);
+ final var bindingController = userData.mBindingController;
if (bindingController.getSelectedMethodId() == null) {
return null;
}
@@ -5979,7 +5950,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// We cannot simply distinguish a bad IME that reports an arbitrary package name from
// an unfortunate IME whose internal state is already obsolete due to the asynchronous
// nature of our system. Let's compare it with our internal record.
- final var userData = getUserData(imeUserId);
final var curPackageName = userData.mCurEditorInfo != null
? userData.mCurEditorInfo.packageName : null;
if (!TextUtils.equals(curPackageName, packageName)) {
@@ -5991,7 +5961,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final int appUserId = UserHandle.getUserId(userData.mCurClient.mUid);
// This user ID may be invalid if "contentUri" embedded an invalid user ID.
final int contentUriOwnerUserId = ContentProvider.getUserIdFromUri(contentUri,
- imeUserId);
+ userData.mUserId);
final Uri contentUriWithoutUserId = ContentProvider.getUriWithoutUserId(contentUri);
// Note: InputContentUriTokenHandler.take() checks whether the IME (specified by "uid")
// actually has the right to grant a read permission for "contentUriWithoutUserId" that
@@ -6006,12 +5976,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@BinderThread
private void reportFullscreenMode(@NonNull IBinder token, boolean fullscreen,
- @UserIdInt int userId) {
+ @NonNull UserData userData) {
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token, userId)) {
+ if (!calledWithValidTokenLocked(token, userData)) {
return;
}
- final var userData = getUserData(userId);
if (userData.mCurClient != null && userData.mCurClient.mClient != null) {
userData.mInFullscreenMode = fullscreen;
userData.mCurClient.mClient.reportFullscreenMode(fullscreen);
@@ -6111,6 +6080,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
final var userData = getUserData(userId);
p.println("Current Input Method Manager state:");
+ p.println(" concurrentMultiUserModeEnabled" + mConcurrentMultiUserModeEnabled);
final List<InputMethodInfo> methodList = settings.getMethodList();
int numImes = methodList.size();
p.println(" Input Methods:");
@@ -6137,8 +6107,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
p.println(" pid=" + c.mPid);
};
mClientController.forAllClients(clientControllerDump);
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
- p.println(" mCurrentUserId=" + mCurrentUserId);
+ final var bindingController = userData.mBindingController;
+ p.println(" mCurrentUserId=" + userData.mUserId);
p.println(" mCurMethodId=" + bindingController.getSelectedMethodId());
client = userData.mCurClient;
p.println(" mCurClient=" + client + " mCurSeq="
@@ -6153,7 +6123,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
p.println(" mUserDataRepository=");
// TODO(b/324907325): Remove the suppress warnings once b/324907325 is fixed.
- @SuppressWarnings("GuardedBy") Consumer<UserDataRepository.UserData> userDataDump =
+ @SuppressWarnings("GuardedBy") Consumer<UserData> userDataDump =
u -> {
p.println(" mUserId=" + u.mUserId);
p.println(" hasMainConnection="
@@ -6171,8 +6141,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
u.mImeBindingState.dump(" ", p);
p.println(" enabledSession=" + u.mEnabledSession);
p.println(" inFullscreenMode=" + u.mInFullscreenMode);
+ p.println(" imeDrawsNavBar=" + u.mImeDrawsNavBar.get());
p.println(" switchingController:");
u.mSwitchingController.dump(p, " ");
+ p.println(" mLastEnabledInputMethodsStr="
+ + u.mLastEnabledInputMethodsStr);
};
mUserDataRepository.forAllUserData(userDataDump);
@@ -6186,11 +6159,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mVisibilityStateComputer.dump(pw, " ");
p.println(" mInFullscreenMode=" + userData.mInFullscreenMode);
p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mIsInteractive);
- p.println(" mExperimentalConcurrentMultiUserModeEnabled="
- + mExperimentalConcurrentMultiUserModeEnabled);
+ p.println(" mConcurrentMultiUserModeEnabled=" + mConcurrentMultiUserModeEnabled);
p.println(" ENABLE_HIDE_IME_CAPTION_BAR="
+ InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR);
- p.println(" mSettingsObserver=" + mSettingsObserver);
p.println(" mStylusIds=" + (mStylusIds != null
? Arrays.toString(mStylusIds.toArray()) : ""));
@@ -6561,7 +6532,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (enabled && !settings.getMethodMap().containsKey(imeId)) {
failedToEnableUnknownIme = true;
} else {
- previouslyEnabled = setInputMethodEnabledLocked(imeId, enabled);
+ previouslyEnabled = setInputMethodEnabledLocked(imeId, enabled, userId);
}
} else {
if (enabled) {
@@ -6689,7 +6660,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
0 /* flags */,
SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND, userId);
}
- final var bindingController = getInputMethodBindingController(userId);
+ final var bindingController = userData.mBindingController;
bindingController.unbindCurrentMethod();
// Enable default IMEs, disable others
@@ -6698,14 +6669,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mContext, settings.getMethodList());
toDisable.removeAll(defaultEnabled);
for (InputMethodInfo info : toDisable) {
- setInputMethodEnabledLocked(info.getId(), false);
+ setInputMethodEnabledLocked(info.getId(), false, userId);
}
for (InputMethodInfo info : defaultEnabled) {
- setInputMethodEnabledLocked(info.getId(), true);
+ setInputMethodEnabledLocked(info.getId(), true, userId);
}
// Choose new default IME, reset to none if no IME available.
- if (!chooseNewDefaultIMELocked()) {
- resetSelectedInputMethodAndSubtypeLocked(null);
+ if (!chooseNewDefaultIMELocked(userId)) {
+ resetSelectedInputMethodAndSubtypeLocked(null, userId);
}
updateInputMethodsFromSettingsLocked(true /* enabledMayChange */, userId);
InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
@@ -6837,26 +6808,26 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
private final InputMethodManagerService mImms;
@NonNull
private final IBinder mToken;
- @UserIdInt
- private final int mUserId;
+ @NonNull
+ private final UserData mUserData;
InputMethodPrivilegedOperationsImpl(InputMethodManagerService imms,
- @NonNull IBinder token, @UserIdInt int userId) {
+ @NonNull IBinder token, @NonNull UserData userData) {
mImms = imms;
mToken = token;
- mUserId = userId;
+ mUserData = userData;
}
@BinderThread
@Override
public void setImeWindowStatusAsync(int vis, int backDisposition) {
- mImms.setImeWindowStatus(mToken, vis, backDisposition, mUserId);
+ mImms.setImeWindowStatus(mToken, vis, backDisposition, mUserData);
}
@BinderThread
@Override
public void reportStartInputAsync(IBinder startInputToken) {
- mImms.reportStartInput(mToken, startInputToken, mUserId);
+ mImms.reportStartInput(mToken, startInputToken, mUserData);
}
@BinderThread
@@ -6872,7 +6843,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@SuppressWarnings("unchecked") final AndroidFuture<IBinder> typedFuture = future;
try {
typedFuture.complete(mImms.createInputContentUriToken(
- mToken, contentUri, packageName, mUserId).asBinder());
+ mToken, contentUri, packageName, mUserData).asBinder());
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
}
@@ -6881,7 +6852,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@BinderThread
@Override
public void reportFullscreenModeAsync(boolean fullscreen) {
- mImms.reportFullscreenMode(mToken, fullscreen, mUserId);
+ mImms.reportFullscreenMode(mToken, fullscreen, mUserData);
}
@BinderThread
@@ -6889,7 +6860,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
public void setInputMethod(String id, AndroidFuture future /* T=Void */) {
@SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
try {
- mImms.setInputMethod(mToken, id, mUserId);
+ mImms.setInputMethod(mToken, id, mUserData);
typedFuture.complete(null);
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
@@ -6902,7 +6873,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
AndroidFuture future /* T=Void */) {
@SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
try {
- mImms.setInputMethodAndSubtype(mToken, id, subtype, mUserId);
+ mImms.setInputMethodAndSubtype(mToken, id, subtype, mUserData);
typedFuture.complete(null);
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
@@ -6916,7 +6887,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
AndroidFuture future /* T=Void */) {
@SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
try {
- mImms.hideMySoftInput(mToken, statsToken, flags, reason, mUserId);
+ mImms.hideMySoftInput(mToken, statsToken, flags, reason, mUserData);
typedFuture.complete(null);
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
@@ -6930,7 +6901,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
AndroidFuture future /* T=Void */) {
@SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
try {
- mImms.showMySoftInput(mToken, statsToken, flags, reason, mUserId);
+ mImms.showMySoftInput(mToken, statsToken, flags, reason, mUserData);
typedFuture.complete(null);
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
@@ -6940,7 +6911,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@BinderThread
@Override
public void updateStatusIconAsync(String packageName, @DrawableRes int iconId) {
- mImms.updateStatusIcon(mToken, packageName, iconId, mUserId);
+ mImms.updateStatusIcon(mToken, packageName, iconId, mUserData);
}
@BinderThread
@@ -6948,7 +6919,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
public void switchToPreviousInputMethod(AndroidFuture future /* T=Boolean */) {
@SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future;
try {
- typedFuture.complete(mImms.switchToPreviousInputMethod(mToken, mUserId));
+ typedFuture.complete(mImms.switchToPreviousInputMethod(mToken, mUserData));
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
}
@@ -6961,7 +6932,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future;
try {
typedFuture.complete(mImms.switchToNextInputMethod(mToken, onlyCurrentIme,
- mUserId));
+ mUserData));
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
}
@@ -6972,7 +6943,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
public void shouldOfferSwitchingToNextInputMethod(AndroidFuture future /* T=Boolean */) {
@SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future;
try {
- typedFuture.complete(mImms.shouldOfferSwitchingToNextInputMethod(mToken, mUserId));
+ typedFuture.complete(mImms.shouldOfferSwitchingToNextInputMethod(mToken,
+ mUserData));
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
}
@@ -6980,21 +6952,27 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@BinderThread
@Override
+ public void onImeSwitchButtonClickFromClient(int displayId) {
+ mImms.onImeSwitchButtonClickFromClient(mToken, displayId, mUserData);
+ }
+
+ @BinderThread
+ @Override
public void notifyUserActionAsync() {
- mImms.notifyUserAction(mToken, mUserId);
+ mImms.notifyUserAction(mToken, mUserData);
}
@BinderThread
@Override
public void applyImeVisibilityAsync(IBinder windowToken, boolean setVisible,
@NonNull ImeTracker.Token statsToken) {
- mImms.applyImeVisibility(mToken, windowToken, setVisible, statsToken, mUserId);
+ mImms.applyImeVisibility(mToken, windowToken, setVisible, statsToken, mUserData);
}
@BinderThread
@Override
public void onStylusHandwritingReady(int requestId, int pid) {
- mImms.onStylusHandwritingReady(requestId, pid, mUserId);
+ mImms.onStylusHandwritingReady(requestId, pid, mUserData);
}
@BinderThread
@@ -7007,12 +6985,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@Override
public void switchKeyboardLayoutAsync(int direction) {
synchronized (ImfLock.class) {
- if (!mImms.calledWithValidTokenLocked(mToken, mUserId)) {
+ if (!mImms.calledWithValidTokenLocked(mToken, mUserData)) {
return;
}
final long ident = Binder.clearCallingIdentity();
try {
- mImms.switchKeyboardLayoutLocked(direction, mUserId);
+ mImms.switchKeyboardLayoutLocked(direction, mUserData);
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
index 154ee1d9fde8..06f73f34e427 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
@@ -85,7 +85,7 @@ final class InputMethodMenuController {
if (preferredInputMethodSubtypeId == NOT_A_SUBTYPE_ID) {
final InputMethodSubtype currentSubtype =
- mService.getCurrentInputMethodSubtypeLocked();
+ bindingController.getCurrentInputMethodSubtype();
if (currentSubtype != null) {
final String curMethodId = bindingController.getSelectedMethodId();
final InputMethodInfo currentImi =
@@ -202,7 +202,7 @@ final class InputMethodMenuController {
attrs.setTitle("Select input method");
w.setAttributes(attrs);
mService.updateSystemUiLocked(userId);
- mService.sendOnNavButtonFlagsChangedLocked();
+ mService.sendOnNavButtonFlagsChangedLocked(mService.getUserData(userId));
mSwitchingDialog.show();
}
@@ -242,7 +242,7 @@ final class InputMethodMenuController {
// TODO(b/305849394): Make InputMethodMenuController multi-user aware
final int userId = mService.getCurrentImeUserIdLocked();
mService.updateSystemUiLocked(userId);
- mService.sendOnNavButtonFlagsChangedLocked();
+ mService.sendOnNavButtonFlagsChangedToAllImesLocked();
mDialogBuilder = null;
mIms = null;
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
index 5569e1e5211e..0152158cbb7a 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
@@ -571,57 +571,6 @@ final class InputMethodSettings {
}
}
- /**
- * A variant of {@link InputMethodManagerService#getCurrentInputMethodSubtypeLocked()} for
- * non-current users.
- *
- * <p>TODO: Address code duplication between this and
- * {@link InputMethodManagerService#getCurrentInputMethodSubtypeLocked()}.</p>
- *
- * @return {@link InputMethodSubtype} if exists. {@code null} otherwise.
- */
- @Nullable
- InputMethodSubtype getCurrentInputMethodSubtypeForNonCurrentUsers() {
- final String selectedMethodId = getSelectedInputMethod();
- if (selectedMethodId == null) {
- return null;
- }
- final InputMethodInfo imi = mMethodMap.get(selectedMethodId);
- if (imi == null || imi.getSubtypeCount() == 0) {
- return null;
- }
-
- final int subtypeHashCode = getSelectedInputMethodSubtypeHashCode();
- if (subtypeHashCode != INVALID_SUBTYPE_HASHCODE) {
- final int subtypeIndex = SubtypeUtils.getSubtypeIdFromHashCode(imi,
- subtypeHashCode);
- if (subtypeIndex >= 0) {
- return imi.getSubtypeAt(subtypeIndex);
- }
- }
-
- // If there are no selected subtypes, the framework will try to find the most applicable
- // subtype from explicitly or implicitly enabled subtypes.
- final List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
- getEnabledInputMethodSubtypeList(imi, true);
- // If there is only one explicitly or implicitly enabled subtype, just returns it.
- if (explicitlyOrImplicitlyEnabledSubtypes.isEmpty()) {
- return null;
- }
- if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
- return explicitlyOrImplicitlyEnabledSubtypes.get(0);
- }
- final String locale = SystemLocaleWrapper.get(mUserId).get(0).toString();
- final InputMethodSubtype subtype = SubtypeUtils.findLastResortApplicableSubtype(
- explicitlyOrImplicitlyEnabledSubtypes, SubtypeUtils.SUBTYPE_MODE_KEYBOARD,
- locale, true);
- if (subtype != null) {
- return subtype;
- }
- return SubtypeUtils.findLastResortApplicableSubtype(
- explicitlyOrImplicitlyEnabledSubtypes, null, locale, true);
- }
-
@NonNull
AdditionalSubtypeMap getNewAdditionalSubtypeMap(@NonNull String imeId,
@NonNull ArrayList<InputMethodSubtype> subtypes,
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSettingsRepository.java b/services/core/java/com/android/server/inputmethod/InputMethodSettingsRepository.java
index 68924b5f370f..50ba36450bda 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSettingsRepository.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSettingsRepository.java
@@ -16,17 +16,12 @@
package com.android.server.inputmethod;
+import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.os.Handler;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.inputmethod.DirectBootAwareness;
-import com.android.server.LocalServices;
-import com.android.server.pm.UserManagerInternal;
final class InputMethodSettingsRepository {
@GuardedBy("ImfLock.class")
@@ -54,33 +49,10 @@ final class InputMethodSettingsRepository {
sPerUserMap.put(userId, obj);
}
- static void initialize(@NonNull Handler handler, @NonNull Context context) {
- final UserManagerInternal userManagerInternal =
- LocalServices.getService(UserManagerInternal.class);
- handler.post(() -> {
- userManagerInternal.addUserLifecycleListener(
- new UserManagerInternal.UserLifecycleListener() {
- @Override
- public void onUserRemoved(UserInfo user) {
- final int userId = user.id;
- handler.post(() -> {
- synchronized (ImfLock.class) {
- sPerUserMap.remove(userId);
- }
- });
- }
- });
- synchronized (ImfLock.class) {
- for (int userId : userManagerInternal.getUserIds()) {
- final InputMethodSettings settings =
- InputMethodManagerService.queryInputMethodServicesInternal(
- context,
- userId,
- AdditionalSubtypeMapRepository.get(userId),
- DirectBootAwareness.AUTO);
- put(userId, settings);
- }
- }
- });
+ @AnyThread
+ static void remove(@UserIdInt int userId) {
+ synchronized (ImfLock.class) {
+ sPerUserMap.remove(userId);
+ }
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
index bb1b9df6cf4c..05cc5985a8cc 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -16,6 +16,8 @@
package com.android.server.inputmethod;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -24,11 +26,14 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Printer;
import android.util.Slog;
+import android.view.inputmethod.Flags;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
import com.android.internal.annotations.VisibleForTesting;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -45,6 +50,34 @@ final class InputMethodSubtypeSwitchingController {
private static final boolean DEBUG = false;
private static final int NOT_A_SUBTYPE_ID = InputMethodUtils.NOT_A_SUBTYPE_ID;
+ @IntDef(prefix = {"MODE_"}, value = {
+ MODE_STATIC,
+ MODE_RECENT,
+ MODE_AUTO
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SwitchMode {
+ }
+
+ /**
+ * Switch using the static order (the order of the given list of input methods and subtypes).
+ * This order is only set when given a new list, and never updated.
+ */
+ public static final int MODE_STATIC = 0;
+
+ /**
+ * Switch using the recency based order, going from most recent to least recent,
+ * updated on {@link #onUserActionLocked user action}.
+ */
+ public static final int MODE_RECENT = 1;
+
+ /**
+ * If there was a {@link #onUserActionLocked user action} since the last
+ * {@link #onInputMethodSubtypeChanged() switch}, and direction is forward,
+ * use {@link #MODE_RECENT}, otherwise use {@link #MODE_STATIC}.
+ */
+ public static final int MODE_AUTO = 2;
+
public static class ImeSubtypeListItem implements Comparable<ImeSubtypeListItem> {
@NonNull
@@ -117,20 +150,25 @@ final class InputMethodSubtypeSwitchingController {
if (result != 0) {
return result;
}
- // Subtype that has the same locale of the system's has higher priority.
- result = (mIsSystemLocale ? -1 : 0) - (other.mIsSystemLocale ? -1 : 0);
- if (result != 0) {
- return result;
- }
- // Subtype that has the same language of the system's has higher priority.
- result = (mIsSystemLanguage ? -1 : 0) - (other.mIsSystemLanguage ? -1 : 0);
- if (result != 0) {
- return result;
- }
- result = compareNullableCharSequences(mSubtypeName, other.mSubtypeName);
- if (result != 0) {
- return result;
+ if (!Flags.imeSwitcherRevamp()) {
+ // Subtype that has the same locale of the system's has higher priority.
+ result = (mIsSystemLocale ? -1 : 0) - (other.mIsSystemLocale ? -1 : 0);
+ if (result != 0) {
+ return result;
+ }
+ // Subtype that has the same language of the system's has higher priority.
+ result = (mIsSystemLanguage ? -1 : 0) - (other.mIsSystemLanguage ? -1 : 0);
+ if (result != 0) {
+ return result;
+ }
+ result = compareNullableCharSequences(mSubtypeName, other.mSubtypeName);
+ if (result != 0) {
+ return result;
+ }
}
+ // This will no longer compare by subtype name, however as {@link Collections.sort} is
+ // guaranteed to be a stable sorting, this allows sorting by the IME name (and ID),
+ // while maintaining the order of subtypes (given by each IME) at the IME level.
return mImi.getId().compareTo(other.mImi.getId());
}
@@ -226,6 +264,59 @@ final class InputMethodSubtypeSwitchingController {
return imList;
}
+ @NonNull
+ private static List<ImeSubtypeListItem> getInputMethodAndSubtypeListForHardwareKeyboard(
+ @NonNull Context context, @NonNull InputMethodSettings settings) {
+ if (!Flags.imeSwitcherRevamp()) {
+ return new ArrayList<>();
+ }
+ final int userId = settings.getUserId();
+ final Context userAwareContext = context.getUserId() == userId
+ ? context
+ : context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
+ final String mSystemLocaleStr = SystemLocaleWrapper.get(userId).get(0).toLanguageTag();
+
+ final ArrayList<InputMethodInfo> imis = settings.getEnabledInputMethodList();
+ if (imis.isEmpty()) {
+ Slog.w(TAG, "Enabled input method list is empty.");
+ return new ArrayList<>();
+ }
+
+ final ArrayList<ImeSubtypeListItem> imList = new ArrayList<>();
+ final int numImes = imis.size();
+ for (int i = 0; i < numImes; ++i) {
+ final InputMethodInfo imi = imis.get(i);
+ if (!imi.shouldShowInInputMethodPicker()) {
+ continue;
+ }
+ final var subtypes = settings.getEnabledInputMethodSubtypeList(imi, true);
+ final ArraySet<InputMethodSubtype> enabledSubtypeSet = new ArraySet<>(subtypes);
+ final CharSequence imeLabel = imi.loadLabel(userAwareContext.getPackageManager());
+ if (!subtypes.isEmpty()) {
+ final int subtypeCount = imi.getSubtypeCount();
+ if (DEBUG) {
+ Slog.v(TAG, "Add subtypes: " + subtypeCount + ", " + imi.getId());
+ }
+ for (int j = 0; j < subtypeCount; j++) {
+ final InputMethodSubtype subtype = imi.getSubtypeAt(j);
+ if (enabledSubtypeSet.contains(subtype)
+ && subtype.isSuitableForPhysicalKeyboardLayoutMapping()) {
+ final CharSequence subtypeLabel =
+ subtype.overridesImplicitlyEnabledSubtype() ? null : subtype
+ .getDisplayName(userAwareContext, imi.getPackageName(),
+ imi.getServiceInfo().applicationInfo);
+ imList.add(new ImeSubtypeListItem(imeLabel,
+ subtypeLabel, imi, j, subtype.getLocale(), mSystemLocaleStr));
+ }
+ }
+ } else {
+ imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID, null,
+ mSystemLocaleStr));
+ }
+ }
+ return imList;
+ }
+
private static int calculateSubtypeId(@NonNull InputMethodInfo imi,
@Nullable InputMethodSubtype subtype) {
return subtype != null ? SubtypeUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode())
@@ -385,6 +476,132 @@ final class InputMethodSubtypeSwitchingController {
}
}
+ /**
+ * List container that allows getting the next item in either forwards or backwards direction,
+ * in either static or recency order, and either in the same IME or not.
+ */
+ private static class RotationList {
+
+ /**
+ * List of items in a static order.
+ */
+ @NonNull
+ private final List<ImeSubtypeListItem> mItems;
+
+ /**
+ * Mapping of recency index to static index (in {@link #mItems}), with lower indices being
+ * more recent.
+ */
+ @NonNull
+ private final int[] mRecencyMap;
+
+ RotationList(@NonNull List<ImeSubtypeListItem> items) {
+ mItems = items;
+ mRecencyMap = new int[items.size()];
+ for (int i = 0; i < mItems.size(); i++) {
+ mRecencyMap[i] = i;
+ }
+ }
+
+ /**
+ * Gets the next input method and subtype from the given ones.
+ *
+ * @param imi the input method to find the next value from.
+ * @param subtype the input method subtype to find the next value from, if any.
+ * @param onlyCurrentIme whether to consider only subtypes of the current input method.
+ * @param useRecency whether to use the recency order, or the static order.
+ * @param forward whether to search forwards to backwards in the list.
+ * @return the next input method and subtype if found, otherwise {@code null}.
+ */
+ @Nullable
+ public ImeSubtypeListItem next(@NonNull InputMethodInfo imi,
+ @Nullable InputMethodSubtype subtype, boolean onlyCurrentIme,
+ boolean useRecency, boolean forward) {
+ final int size = mItems.size();
+ if (size <= 1) {
+ return null;
+ }
+ final int index = getIndex(imi, subtype, useRecency);
+ if (index < 0) {
+ return null;
+ }
+
+ final int incrementSign = (forward ? 1 : -1);
+
+ for (int i = 1; i < size; i++) {
+ final int nextIndex = (index + i * incrementSign + size) % size;
+ final int mappedIndex = useRecency ? mRecencyMap[nextIndex] : nextIndex;
+ final var nextItem = mItems.get(mappedIndex);
+ if (!onlyCurrentIme || nextItem.mImi.equals(imi)) {
+ return nextItem;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Sets the given input method and subtype as the most recent one.
+ *
+ * @param imi the input method to set as the most recent.
+ * @param subtype the input method subtype to set as the most recent, if any.
+ * @return {@code true} if the recency was updated, otherwise {@code false}.
+ */
+ public boolean setMostRecent(@NonNull InputMethodInfo imi,
+ @Nullable InputMethodSubtype subtype) {
+ if (mItems.size() <= 1) {
+ return false;
+ }
+
+ final int recencyIndex = getIndex(imi, subtype, true /* useRecency */);
+ if (recencyIndex <= 0) {
+ // Already most recent or not found.
+ return false;
+ }
+ final int staticIndex = mRecencyMap[recencyIndex];
+ System.arraycopy(mRecencyMap, 0, mRecencyMap, 1, recencyIndex);
+ mRecencyMap[0] = staticIndex;
+ return true;
+ }
+
+ /**
+ * Gets the index of the given input method and subtype, in either recency or static order.
+ *
+ * @param imi the input method to get the index of.
+ * @param subtype the input method subtype to get the index of, if any.
+ * @param useRecency whether to get the index in the recency or static order.
+ * @return an index in either {@link #mItems} or {@link #mRecencyMap}, or {@code -1}
+ * if not found.
+ */
+ @IntRange(from = -1)
+ private int getIndex(@NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
+ boolean useRecency) {
+ final int subtypeIndex = calculateSubtypeId(imi, subtype);
+ for (int i = 0; i < mItems.size(); i++) {
+ final int mappedIndex = useRecency ? mRecencyMap[i] : i;
+ final var item = mItems.get(mappedIndex);
+ if (item.mImi.equals(imi) && item.mSubtypeId == subtypeIndex) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /** Dumps the state of the list into the given printer. */
+ private void dump(@NonNull Printer pw, @NonNull String prefix) {
+ pw.println(prefix + "Static order:");
+ for (int i = 0; i < mItems.size(); ++i) {
+ final var item = mItems.get(i);
+ pw.println(prefix + "i=" + i + " item=" + item);
+ }
+ pw.println(prefix + "Recency order:");
+ for (int i = 0; i < mRecencyMap.length; ++i) {
+ final int index = mRecencyMap[i];
+ final var item = mItems.get(index);
+ pw.println(prefix + "i=" + i + " item=" + item);
+ }
+ }
+ }
+
@VisibleForTesting
public static class ControllerImpl {
@@ -392,10 +609,23 @@ final class InputMethodSubtypeSwitchingController {
private final DynamicRotationList mSwitchingAwareRotationList;
@NonNull
private final StaticRotationList mSwitchingUnawareRotationList;
+ /** List of input methods and subtypes. */
+ @Nullable
+ private final RotationList mRotationList;
+ /** List of input methods and subtypes suitable for hardware keyboards. */
+ @Nullable
+ private final RotationList mHardwareRotationList;
+
+ /**
+ * Whether there was a user action since the last input method and subtype switch.
+ * Used to determine the switching behaviour for {@link #MODE_AUTO}.
+ */
+ private boolean mUserActionSinceSwitch;
@NonNull
public static ControllerImpl createFrom(@Nullable ControllerImpl currentInstance,
- @NonNull List<ImeSubtypeListItem> sortedEnabledItems) {
+ @NonNull List<ImeSubtypeListItem> sortedEnabledItems,
+ @NonNull List<ImeSubtypeListItem> hardwareKeyboardItems) {
final var switchingAwareImeSubtypes = filterImeSubtypeList(sortedEnabledItems,
true /* supportsSwitchingToNextInputMethod */);
final var switchingUnawareImeSubtypes = filterImeSubtypeList(sortedEnabledItems,
@@ -421,22 +651,55 @@ final class InputMethodSubtypeSwitchingController {
switchingUnawareRotationList = new StaticRotationList(switchingUnawareImeSubtypes);
}
- return new ControllerImpl(switchingAwareRotationList, switchingUnawareRotationList);
+ final RotationList rotationList;
+ if (!Flags.imeSwitcherRevamp()) {
+ rotationList = null;
+ } else if (currentInstance != null && currentInstance.mRotationList != null
+ && Objects.equals(
+ currentInstance.mRotationList.mItems, sortedEnabledItems)) {
+ // Can reuse the current instance.
+ rotationList = currentInstance.mRotationList;
+ } else {
+ rotationList = new RotationList(sortedEnabledItems);
+ }
+
+ final RotationList hardwareRotationList;
+ if (!Flags.imeSwitcherRevamp()) {
+ hardwareRotationList = null;
+ } else if (currentInstance != null && currentInstance.mHardwareRotationList != null
+ && Objects.equals(
+ currentInstance.mHardwareRotationList.mItems, hardwareKeyboardItems)) {
+ // Can reuse the current instance.
+ hardwareRotationList = currentInstance.mHardwareRotationList;
+ } else {
+ hardwareRotationList = new RotationList(hardwareKeyboardItems);
+ }
+
+ return new ControllerImpl(switchingAwareRotationList, switchingUnawareRotationList,
+ rotationList, hardwareRotationList);
}
private ControllerImpl(@NonNull DynamicRotationList switchingAwareRotationList,
- @NonNull StaticRotationList switchingUnawareRotationList) {
+ @NonNull StaticRotationList switchingUnawareRotationList,
+ @Nullable RotationList rotationList,
+ @Nullable RotationList hardwareRotationList) {
mSwitchingAwareRotationList = switchingAwareRotationList;
mSwitchingUnawareRotationList = switchingUnawareRotationList;
+ mRotationList = rotationList;
+ mHardwareRotationList = hardwareRotationList;
}
@Nullable
public ImeSubtypeListItem getNextInputMethod(boolean onlyCurrentIme,
- @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype) {
+ @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
+ @SwitchMode int mode, boolean forward) {
if (imi == null) {
return null;
}
- if (imi.supportsSwitchingToNextInputMethod()) {
+ if (Flags.imeSwitcherRevamp() && mRotationList != null) {
+ return mRotationList.next(imi, subtype, onlyCurrentIme,
+ isRecency(mode, forward), forward);
+ } else if (imi.supportsSwitchingToNextInputMethod()) {
return mSwitchingAwareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi,
subtype);
} else {
@@ -445,11 +708,66 @@ final class InputMethodSubtypeSwitchingController {
}
}
- public void onUserActionLocked(@NonNull InputMethodInfo imi,
+ @Nullable
+ public ImeSubtypeListItem getNextInputMethodForHardware(boolean onlyCurrentIme,
+ @NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
+ @SwitchMode int mode, boolean forward) {
+ if (Flags.imeSwitcherRevamp() && mHardwareRotationList != null) {
+ return mHardwareRotationList.next(imi, subtype, onlyCurrentIme,
+ isRecency(mode, forward), forward);
+ }
+ return null;
+ }
+
+ /**
+ * Called when the user took an action that should update the recency of the current
+ * input method and subtype in the switching list.
+ *
+ * @param imi the currently selected input method.
+ * @param subtype the currently selected input method subtype, if any.
+ * @return {@code true} if the recency was updated, otherwise {@code false}.
+ * @see android.inputmethodservice.InputMethodServiceInternal#notifyUserActionIfNecessary()
+ */
+ public boolean onUserActionLocked(@NonNull InputMethodInfo imi,
@Nullable InputMethodSubtype subtype) {
- if (imi.supportsSwitchingToNextInputMethod()) {
+ boolean recencyUpdated = false;
+ if (Flags.imeSwitcherRevamp()) {
+ if (mRotationList != null) {
+ recencyUpdated |= mRotationList.setMostRecent(imi, subtype);
+ }
+ if (mHardwareRotationList != null) {
+ recencyUpdated |= mHardwareRotationList.setMostRecent(imi, subtype);
+ }
+ if (recencyUpdated) {
+ mUserActionSinceSwitch = true;
+ }
+ } else if (imi.supportsSwitchingToNextInputMethod()) {
mSwitchingAwareRotationList.onUserAction(imi, subtype);
}
+ return recencyUpdated;
+ }
+
+ /** Called when the input method and subtype was changed. */
+ public void onInputMethodSubtypeChanged() {
+ mUserActionSinceSwitch = false;
+ }
+
+ /**
+ * Whether the given mode and direction result in recency or static order.
+ *
+ * <p>{@link #MODE_AUTO} resolves to the recency order for the first forwards switch
+ * after an {@link #onUserActionLocked user action}, and otherwise to the static order.</p>
+ *
+ * @param mode the switching mode.
+ * @param forward the switching direction.
+ * @return {@code true} for the recency order, otherwise {@code false}.
+ */
+ private boolean isRecency(@SwitchMode int mode, boolean forward) {
+ if (mode == MODE_AUTO && mUserActionSinceSwitch && forward) {
+ return true;
+ } else {
+ return mode == MODE_RECENT;
+ }
}
@NonNull
@@ -473,6 +791,17 @@ final class InputMethodSubtypeSwitchingController {
mSwitchingAwareRotationList.dump(pw, prefix + " ");
pw.println(prefix + "mSwitchingUnawareRotationList:");
mSwitchingUnawareRotationList.dump(pw, prefix + " ");
+ if (Flags.imeSwitcherRevamp()) {
+ if (mRotationList != null) {
+ pw.println(prefix + "mRotationList:");
+ mRotationList.dump(pw, prefix + " ");
+ }
+ if (mHardwareRotationList != null) {
+ pw.println(prefix + "mHardwareRotationList:");
+ mHardwareRotationList.dump(pw, prefix + " ");
+ }
+ pw.println("User action since last switch: " + mUserActionSinceSwitch);
+ }
}
}
@@ -480,26 +809,71 @@ final class InputMethodSubtypeSwitchingController {
private ControllerImpl mController;
InputMethodSubtypeSwitchingController() {
- mController = ControllerImpl.createFrom(null, Collections.emptyList());
+ mController = ControllerImpl.createFrom(null, Collections.emptyList(),
+ Collections.emptyList());
}
+ /**
+ * Called when the user took an action that should update the recency of the current
+ * input method and subtype in the switching list.
+ *
+ * @param imi the currently selected input method.
+ * @param subtype the currently selected input method subtype, if any.
+ * @see android.inputmethodservice.InputMethodServiceInternal#notifyUserActionIfNecessary()
+ */
public void onUserActionLocked(@NonNull InputMethodInfo imi,
@Nullable InputMethodSubtype subtype) {
mController.onUserActionLocked(imi, subtype);
}
+ /** Called when the input method and subtype was changed. */
+ public void onInputMethodSubtypeChanged() {
+ mController.onInputMethodSubtypeChanged();
+ }
+
public void resetCircularListLocked(@NonNull Context context,
@NonNull InputMethodSettings settings) {
mController = ControllerImpl.createFrom(mController,
getSortedInputMethodAndSubtypeList(
false /* includeAuxiliarySubtypes */, false /* isScreenLocked */,
- false /* forImeMenu */, context, settings));
+ false /* forImeMenu */, context, settings),
+ getInputMethodAndSubtypeListForHardwareKeyboard(context, settings));
}
+ /**
+ * Gets the next input method and subtype, starting from the given ones, in the given direction.
+ *
+ * @param onlyCurrentIme whether to consider only subtypes of the current input method.
+ * @param imi the input method to find the next value from.
+ * @param subtype the input method subtype to find the next value from, if any.
+ * @param mode the switching mode.
+ * @param forward whether to search search forwards or backwards in the list.
+ * @return the next input method and subtype if found, otherwise {@code null}.
+ */
@Nullable
public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme,
- @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype) {
- return mController.getNextInputMethod(onlyCurrentIme, imi, subtype);
+ @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
+ @SwitchMode int mode, boolean forward) {
+ return mController.getNextInputMethod(onlyCurrentIme, imi, subtype, mode, forward);
+ }
+
+ /**
+ * Gets the next input method and subtype suitable for hardware keyboards, starting from the
+ * given ones, in the given direction.
+ *
+ * @param onlyCurrentIme whether to consider only subtypes of the current input method.
+ * @param imi the input method to find the next value from.
+ * @param subtype the input method subtype to find the next value from, if any.
+ * @param mode the switching mode
+ * @param forward whether to search search forwards or backwards in the list.
+ * @return the next input method and subtype if found, otherwise {@code null}.
+ */
+ @Nullable
+ public ImeSubtypeListItem getNextInputMethodForHardware(boolean onlyCurrentIme,
+ @NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
+ @SwitchMode int mode, boolean forward) {
+ return mController.getNextInputMethodForHardware(onlyCurrentIme, imi, subtype, mode,
+ forward);
}
public void dump(@NonNull Printer pw, @NonNull String prefix) {
diff --git a/services/core/java/com/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper.java b/services/core/java/com/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper.java
deleted file mode 100644
index 33e7a7621340..000000000000
--- a/services/core/java/com/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.inputmethod;
-
-import static android.content.Intent.ACTION_OVERLAY_CHANGED;
-
-import android.annotation.AnyThread;
-import android.annotation.BoolRes;
-import android.annotation.NonNull;
-import android.annotation.UserHandleAware;
-import android.annotation.UserIdInt;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.os.Handler;
-import android.os.PatternMatcher;
-import android.util.Slog;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Consumer;
-
-/**
- * A wrapper object for any boolean resource defined in {@code "android"} package, in a way that is
- * aware of per-user Runtime Resource Overlay (RRO).
- */
-final class OverlayableSystemBooleanResourceWrapper implements AutoCloseable {
- private static final String TAG = "OverlayableSystemBooleanResourceWrapper";
-
- private static final String SYSTEM_PACKAGE_NAME = "android";
-
- @UserIdInt
- private final int mUserId;
- @NonNull
- private final AtomicBoolean mValueRef;
- @NonNull
- private final AtomicReference<Runnable> mCleanerRef;
-
- /**
- * Creates {@link OverlayableSystemBooleanResourceWrapper} for the given boolean resource ID
- * with a value change callback for the user associated with the {@link Context}.
- *
- * @param userContext The {@link Context} to be used to access the resource. This needs to be
- * associated with the right user because the Runtime Resource Overlay (RRO)
- * is per-user configuration.
- * @param boolResId The resource ID to be queried.
- * @param handler {@link Handler} to be used to dispatch {@code callback}.
- * @param callback The callback to be notified when the specified value might be updated.
- * The callback needs to take care of spurious wakeup. The value returned from
- * {@link #get()} may look to be exactly the same as the previously read value
- * e.g. when the value is changed from {@code false} to {@code true} to
- * {@code false} in a very short period of time, because {@link #get()} always
- * does volatile-read.
- * @return New {@link OverlayableSystemBooleanResourceWrapper}.
- */
- @NonNull
- @UserHandleAware
- static OverlayableSystemBooleanResourceWrapper create(@NonNull Context userContext,
- @BoolRes int boolResId, @NonNull Handler handler,
- @NonNull Consumer<OverlayableSystemBooleanResourceWrapper> callback) {
-
- // Note that we cannot fully trust this initial value due to the dead time between obtaining
- // the value here and setting up a broadcast receiver for change callback below.
- // We will refresh the value again later after setting up the change callback anyway.
- final AtomicBoolean valueRef = new AtomicBoolean(evaluate(userContext, boolResId));
-
- final AtomicReference<Runnable> cleanerRef = new AtomicReference<>();
-
- final OverlayableSystemBooleanResourceWrapper object =
- new OverlayableSystemBooleanResourceWrapper(userContext.getUserId(), valueRef,
- cleanerRef);
-
- final IntentFilter intentFilter = new IntentFilter(ACTION_OVERLAY_CHANGED);
- intentFilter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
- intentFilter.addDataSchemeSpecificPart(SYSTEM_PACKAGE_NAME, PatternMatcher.PATTERN_LITERAL);
-
- final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final boolean newValue = evaluate(userContext, boolResId);
- if (newValue != valueRef.getAndSet(newValue)) {
- callback.accept(object);
- }
- }
- };
- userContext.registerReceiver(broadcastReceiver, intentFilter,
- null /* broadcastPermission */, handler,
- Context.RECEIVER_NOT_EXPORTED);
- cleanerRef.set(() -> userContext.unregisterReceiver(broadcastReceiver));
-
- // Make sure that the initial observable value is obtained after the change callback is set.
- valueRef.set(evaluate(userContext, boolResId));
- return object;
- }
-
- private OverlayableSystemBooleanResourceWrapper(@UserIdInt int userId,
- @NonNull AtomicBoolean valueRef, @NonNull AtomicReference<Runnable> cleanerRef) {
- mUserId = userId;
- mValueRef = valueRef;
- mCleanerRef = cleanerRef;
- }
-
- /**
- * @return The boolean resource value.
- */
- @AnyThread
- boolean get() {
- return mValueRef.get();
- }
-
- /**
- * @return The user ID associated with this resource reader.
- */
- @AnyThread
- @UserIdInt
- int getUserId() {
- return mUserId;
- }
-
- @AnyThread
- private static boolean evaluate(@NonNull Context context, @BoolRes int boolResId) {
- try {
- return context.getPackageManager()
- .getResourcesForApplication(SYSTEM_PACKAGE_NAME)
- .getBoolean(boolResId);
- } catch (PackageManager.NameNotFoundException e) {
- Slog.e(TAG, "getResourcesForApplication(\"" + SYSTEM_PACKAGE_NAME + "\") failed", e);
- return false;
- }
- }
-
- /**
- * Cleans up the callback.
- */
- @AnyThread
- @Override
- public void close() {
- final Runnable cleaner = mCleanerRef.getAndSet(null);
- if (cleaner != null) {
- cleaner.run();
- }
- }
-}
diff --git a/services/core/java/com/android/server/inputmethod/SecureSettingsChangeCallback.java b/services/core/java/com/android/server/inputmethod/SecureSettingsChangeCallback.java
new file mode 100644
index 000000000000..328d7c698cb1
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/SecureSettingsChangeCallback.java
@@ -0,0 +1,78 @@
+/*
+ * 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.inputmethod;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.ArrayMap;
+
+import java.util.Collection;
+
+/**
+ * A wrapper interface to monitor the given set of {@link Settings.Secure}.
+ */
+@FunctionalInterface
+interface SecureSettingsChangeCallback {
+ /**
+ * Called back when the value associated with {@code key} is updated.
+ *
+ * @param key a key defined in {@link Settings.Secure}
+ * @param flags flags defined in {@link ContentResolver.NotifyFlags}
+ * @param userId the user ID with which the value is associated
+ */
+ void onChange(@NonNull String key, @ContentResolver.NotifyFlags int flags,
+ @UserIdInt int userId);
+
+ /**
+ * Registers {@link SecureSettingsChangeCallback} to the given set of {@link Settings.Secure}.
+ *
+ * @param handler {@link Handler} to be used to call back {@link #onChange(String, int, int)}
+ * @param resolver {@link ContentResolver} with which {@link Settings.Secure} will be retrieved
+ * @param keys A set of {@link Settings.Secure} to be monitored
+ * @param callback {@link SecureSettingsChangeCallback} to be called back
+ */
+ @NonNull
+ static void register(@NonNull Handler handler, @NonNull ContentResolver resolver,
+ @NonNull String[] keys, @NonNull SecureSettingsChangeCallback callback) {
+ final ArrayMap<Uri, String> uriMapper = new ArrayMap<>();
+ for (String key : keys) {
+ uriMapper.put(Settings.Secure.getUriFor(key), key);
+ }
+ final ContentObserver observer = new ContentObserver(handler) {
+ @Override
+ public void onChange(boolean selfChange, @NonNull Collection<Uri> uris, int flags,
+ @UserIdInt int userId) {
+ uris.forEach(uri -> {
+ final String key = uriMapper.get(uri);
+ if (key != null) {
+ callback.onChange(key, flags, userId);
+ }
+ });
+ }
+ };
+ for (Uri uri : uriMapper.keySet()) {
+ resolver.registerContentObserverAsUser(uri, false /* notifyForDescendants */, observer,
+ UserHandle.ALL);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java b/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
index 4764e4fadd6e..e7cff20ea2cb 100644
--- a/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
+++ b/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
@@ -20,10 +20,7 @@ import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
-import android.app.ActivityManagerInternal;
import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.UserInfo;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -321,30 +318,13 @@ final class SecureSettingsWrapper {
}
/**
- * Called when {@link InputMethodManagerService} is starting.
+ * Called when the system is starting.
*
- * @param context the {@link Context} to be used.
+ * @param contentResolver the {@link ContentResolver} to be used
*/
@AnyThread
- static void onStart(@NonNull Context context) {
- sContentResolver = context.getContentResolver();
-
- final int userId = LocalServices.getService(ActivityManagerInternal.class)
- .getCurrentUserId();
- final UserManagerInternal userManagerInternal =
- LocalServices.getService(UserManagerInternal.class);
- putOrGet(userId, createImpl(userManagerInternal, userId));
-
- userManagerInternal.addUserLifecycleListener(
- new UserManagerInternal.UserLifecycleListener() {
- @Override
- public void onUserRemoved(UserInfo user) {
- synchronized (sUserMap) {
- sUserMap.remove(userId);
- }
- }
- }
- );
+ static void setContentResolver(@NonNull ContentResolver contentResolver) {
+ sContentResolver = contentResolver;
}
/**
@@ -377,6 +357,18 @@ final class SecureSettingsWrapper {
}
/**
+ * Called when a user is being removed.
+ *
+ * @param userId the ID of the user whose storage is being removed.
+ */
+ @AnyThread
+ static void onUserRemoved(@UserIdInt int userId) {
+ synchronized (sUserMap) {
+ sUserMap.remove(userId);
+ }
+ }
+
+ /**
* Put the given string {@code value} to {@code key}.
*
* @param key a secure settings key.
diff --git a/services/core/java/com/android/server/inputmethod/UserData.java b/services/core/java/com/android/server/inputmethod/UserData.java
new file mode 100644
index 000000000000..ec5c9e6a3550
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/UserData.java
@@ -0,0 +1,147 @@
+/*
+ * 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.inputmethod;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.util.SparseArray;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.ImeTracker;
+import android.window.ImeOnBackInvokedDispatcher;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
+import com.android.internal.inputmethod.IRemoteInputConnection;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/** Placeholder for all IMMS user specific fields */
+final class UserData {
+ @UserIdInt
+ final int mUserId;
+
+ @NonNull
+ final InputMethodBindingController mBindingController;
+
+ @NonNull
+ final InputMethodSubtypeSwitchingController mSwitchingController =
+ new InputMethodSubtypeSwitchingController();
+
+ @NonNull
+ final HardwareKeyboardShortcutController mHardwareKeyboardShortcutController =
+ new HardwareKeyboardShortcutController();
+
+ /**
+ * Have we called mCurMethod.bindInput()?
+ */
+ @GuardedBy("ImfLock.class")
+ boolean mBoundToMethod = false;
+
+ /**
+ * Have we called bindInput() for accessibility services?
+ */
+ @GuardedBy("ImfLock.class")
+ boolean mBoundToAccessibility;
+
+ @GuardedBy("ImfLock.class")
+ @NonNull
+ ImeBindingState mImeBindingState = ImeBindingState.newEmptyState();
+
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ ClientState mCurClient = null;
+
+ @GuardedBy("ImfLock.class")
+ boolean mInFullscreenMode;
+
+ /**
+ * The {@link IRemoteInputConnection} last provided by the current client.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ IRemoteInputConnection mCurInputConnection;
+
+ /**
+ * The {@link ImeOnBackInvokedDispatcher} last provided by the current client to
+ * receive {@link android.window.OnBackInvokedCallback}s forwarded from IME.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ ImeOnBackInvokedDispatcher mCurImeDispatcher;
+
+ /**
+ * The {@link IRemoteAccessibilityInputConnection} last provided by the current client.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ IRemoteAccessibilityInputConnection mCurRemoteAccessibilityInputConnection;
+
+ /**
+ * The {@link EditorInfo} last provided by the current client.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ EditorInfo mCurEditorInfo;
+
+ /**
+ * The token tracking the current IME show request that is waiting for a connection to an
+ * IME, otherwise {@code null}.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ ImeTracker.Token mCurStatsToken;
+
+ /**
+ * Currently enabled session.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ InputMethodManagerService.SessionState mEnabledSession;
+
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ SparseArray<InputMethodManagerService.AccessibilitySessionState>
+ mEnabledAccessibilitySessions = new SparseArray<>();
+
+ /**
+ * A per-user cache of {@link InputMethodSettings#getEnabledInputMethodsStr()}.
+ */
+ @GuardedBy("ImfLock.class")
+ @NonNull
+ String mLastEnabledInputMethodsStr = "";
+
+ /**
+ * {@code true} when the IME is responsible for drawing the navigation bar and its buttons.
+ */
+ @NonNull
+ final AtomicBoolean mImeDrawsNavBar = new AtomicBoolean();
+
+ /**
+ * Intended to be instantiated only from this file.
+ */
+ UserData(@UserIdInt int userId,
+ @NonNull InputMethodBindingController bindingController) {
+ mUserId = userId;
+ mBindingController = bindingController;
+ }
+
+ @Override
+ public String toString() {
+ return "UserData{" + "mUserId=" + mUserId + '}';
+ }
+}
diff --git a/services/core/java/com/android/server/inputmethod/UserDataRepository.java b/services/core/java/com/android/server/inputmethod/UserDataRepository.java
index 48284fb3163c..6f831cc29026 100644
--- a/services/core/java/com/android/server/inputmethod/UserDataRepository.java
+++ b/services/core/java/com/android/server/inputmethod/UserDataRepository.java
@@ -16,177 +16,68 @@
package com.android.server.inputmethod;
+import android.annotation.AnyThread;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.UserIdInt;
-import android.content.pm.UserInfo;
-import android.os.Handler;
import android.util.SparseArray;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.ImeTracker;
-import android.window.ImeOnBackInvokedDispatcher;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
-import com.android.internal.inputmethod.IRemoteInputConnection;
-import com.android.server.pm.UserManagerInternal;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
import java.util.function.IntFunction;
final class UserDataRepository {
- @GuardedBy("ImfLock.class")
+ private final ReentrantReadWriteLock mUserDataLock = new ReentrantReadWriteLock();
+
+ @GuardedBy("mUserDataLock")
private final SparseArray<UserData> mUserData = new SparseArray<>();
private final IntFunction<InputMethodBindingController> mBindingControllerFactory;
- @GuardedBy("ImfLock.class")
+ @AnyThread
@NonNull
UserData getOrCreate(@UserIdInt int userId) {
- UserData userData = mUserData.get(userId);
- if (userData == null) {
- userData = new UserData(userId, mBindingControllerFactory.apply(userId));
- mUserData.put(userId, userData);
+ mUserDataLock.writeLock().lock();
+ try {
+ UserData userData = mUserData.get(userId);
+ if (userData == null) {
+ userData = new UserData(userId, mBindingControllerFactory.apply(userId));
+ mUserData.put(userId, userData);
+ }
+ return userData;
+ } finally {
+ mUserDataLock.writeLock().unlock();
}
- return userData;
}
- @GuardedBy("ImfLock.class")
+ @AnyThread
void forAllUserData(Consumer<UserData> consumer) {
- for (int i = 0; i < mUserData.size(); i++) {
- consumer.accept(mUserData.valueAt(i));
+ final SparseArray<UserData> copiedArray;
+ mUserDataLock.readLock().lock();
+ try {
+ copiedArray = mUserData.clone();
+ } finally {
+ mUserDataLock.readLock().unlock();
+ }
+ for (int i = 0; i < copiedArray.size(); i++) {
+ consumer.accept(copiedArray.valueAt(i));
}
}
UserDataRepository(
- @NonNull Handler handler, @NonNull UserManagerInternal userManagerInternal,
@NonNull IntFunction<InputMethodBindingController> bindingControllerFactory) {
mBindingControllerFactory = bindingControllerFactory;
- userManagerInternal.addUserLifecycleListener(
- new UserManagerInternal.UserLifecycleListener() {
- @Override
- public void onUserRemoved(UserInfo user) {
- final int userId = user.id;
- handler.post(() -> {
- synchronized (ImfLock.class) {
- mUserData.remove(userId);
- }
- });
- }
-
- @Override
- public void onUserCreated(UserInfo user, Object unusedToken) {
- final int userId = user.id;
- handler.post(() -> {
- synchronized (ImfLock.class) {
- getOrCreate(userId);
- }
- });
- }
- });
}
- /** Placeholder for all IMMS user specific fields */
- static final class UserData {
- @UserIdInt
- final int mUserId;
-
- @NonNull
- final InputMethodBindingController mBindingController;
-
- @NonNull
- final InputMethodSubtypeSwitchingController mSwitchingController;
-
- @NonNull
- final HardwareKeyboardShortcutController mHardwareKeyboardShortcutController;
-
- /**
- * Have we called mCurMethod.bindInput()?
- */
- @GuardedBy("ImfLock.class")
- boolean mBoundToMethod = false;
-
- /**
- * Have we called bindInput() for accessibility services?
- */
- @GuardedBy("ImfLock.class")
- boolean mBoundToAccessibility;
-
- @GuardedBy("ImfLock.class")
- @NonNull
- ImeBindingState mImeBindingState = ImeBindingState.newEmptyState();
-
- @GuardedBy("ImfLock.class")
- @Nullable
- ClientState mCurClient = null;
-
- @GuardedBy("ImfLock.class")
- boolean mInFullscreenMode;
-
- /**
- * The {@link IRemoteInputConnection} last provided by the current client.
- */
- @GuardedBy("ImfLock.class")
- @Nullable
- IRemoteInputConnection mCurInputConnection;
-
- /**
- * The {@link ImeOnBackInvokedDispatcher} last provided by the current client to
- * receive {@link android.window.OnBackInvokedCallback}s forwarded from IME.
- */
- @GuardedBy("ImfLock.class")
- @Nullable
- ImeOnBackInvokedDispatcher mCurImeDispatcher;
-
- /**
- * The {@link IRemoteAccessibilityInputConnection} last provided by the current client.
- */
- @GuardedBy("ImfLock.class")
- @Nullable
- IRemoteAccessibilityInputConnection mCurRemoteAccessibilityInputConnection;
-
- /**
- * The {@link EditorInfo} last provided by the current client.
- */
- @GuardedBy("ImfLock.class")
- @Nullable
- EditorInfo mCurEditorInfo;
-
- /**
- * The token tracking the current IME show request that is waiting for a connection to an
- * IME, otherwise {@code null}.
- */
- @GuardedBy("ImfLock.class")
- @Nullable
- ImeTracker.Token mCurStatsToken;
-
- /**
- * Currently enabled session.
- */
- @GuardedBy("ImfLock.class")
- @Nullable
- InputMethodManagerService.SessionState mEnabledSession;
-
- @GuardedBy("ImfLock.class")
- @Nullable
- SparseArray<InputMethodManagerService.AccessibilitySessionState>
- mEnabledAccessibilitySessions = new SparseArray<>();
-
- /**
- * Intended to be instantiated only from this file.
- */
- private UserData(@UserIdInt int userId,
- @NonNull InputMethodBindingController bindingController) {
- mUserId = userId;
- mBindingController = bindingController;
- mSwitchingController = new InputMethodSubtypeSwitchingController();
- mHardwareKeyboardShortcutController = new HardwareKeyboardShortcutController();
- }
-
- @Override
- public String toString() {
- return "UserData{" + "mUserId=" + mUserId + '}';
+ @AnyThread
+ void remove(@UserIdInt int userId) {
+ mUserDataLock.writeLock().lock();
+ try {
+ mUserData.remove(userId);
+ } finally {
+ mUserDataLock.writeLock().unlock();
}
}
}
diff --git a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
index 41aac32ad08f..770e12d8e49a 100644
--- a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
+++ b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
@@ -296,6 +296,12 @@ final class ZeroJankProxy implements IInputMethodManagerImpl.Callback {
return mInner.isInputMethodPickerShownForTest();
}
+ @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.WRITE_SECURE_SETTINGS)
+ @Override
+ public void onImeSwitchButtonClickFromSystem(int displayId) {
+ mInner.onImeSwitchButtonClickFromSystem(displayId);
+ }
+
@Override
public InputMethodSubtype getCurrentInputMethodSubtype(int userId) {
return mInner.getCurrentInputMethodSubtype(userId);
diff --git a/services/core/java/com/android/server/locales/LocaleManagerService.java b/services/core/java/com/android/server/locales/LocaleManagerService.java
index 4851a81d3b69..3d0b079c69c8 100644
--- a/services/core/java/com/android/server/locales/LocaleManagerService.java
+++ b/services/core/java/com/android/server/locales/LocaleManagerService.java
@@ -48,6 +48,7 @@ import android.util.AtomicFile;
import android.util.Slog;
import android.util.Xml;
+import com.android.internal.annotations.KeepForWeakReference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.util.FrameworkStatsLog;
@@ -100,6 +101,7 @@ public class LocaleManagerService extends SystemService {
private LocaleManagerBackupHelper mBackupHelper;
+ @KeepForWeakReference
private final PackageMonitor mPackageMonitor;
private final Object mWriteLock = new Object();
diff --git a/services/core/java/com/android/server/location/altitude/AltitudeService.java b/services/core/java/com/android/server/location/altitude/AltitudeService.java
index 289d4a25f208..96540c225e23 100644
--- a/services/core/java/com/android/server/location/altitude/AltitudeService.java
+++ b/services/core/java/com/android/server/location/altitude/AltitudeService.java
@@ -25,6 +25,7 @@ import android.frameworks.location.altitude.IAltitudeService;
import android.location.Location;
import android.location.altitude.AltitudeConverter;
import android.os.RemoteException;
+import android.util.Log;
import com.android.server.SystemService;
@@ -38,6 +39,8 @@ import java.io.IOException;
*/
public class AltitudeService extends IAltitudeService.Stub {
+ private static final String TAG = "AltitudeService";
+
private final AltitudeConverter mAltitudeConverter = new AltitudeConverter();
private final Context mContext;
@@ -59,6 +62,7 @@ public class AltitudeService extends IAltitudeService.Stub {
try {
mAltitudeConverter.addMslAltitudeToLocation(mContext, location);
} catch (IOException e) {
+ Log.e(TAG, "", e);
response.success = false;
return response;
}
@@ -74,6 +78,7 @@ public class AltitudeService extends IAltitudeService.Stub {
try {
return mAltitudeConverter.getGeoidHeight(mContext, request);
} catch (IOException e) {
+ Log.e(TAG, "", e);
GetGeoidHeightResponse response = new GetGeoidHeightResponse();
response.success = false;
return response;
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEventLogger.java b/services/core/java/com/android/server/location/contexthub/ContextHubEventLogger.java
index 058c1c8efda5..e1b1416169cd 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEventLogger.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEventLogger.java
@@ -16,10 +16,12 @@
package com.android.server.location.contexthub;
+import android.chre.flags.Flags;
import android.hardware.location.NanoAppMessage;
import android.util.Log;
import java.util.Collection;
+import java.util.Optional;
/**
* A class to log events and useful metrics within the Context Hub service.
@@ -149,10 +151,20 @@ public class ContextHubEventLogger {
*/
public final NanoAppMessage message;
+ /**
+ * the error code for the message
+ */
+ public Optional<Byte> errorCode;
+
public NanoappMessageEvent(long mTimeStampInMs, int mContextHubId,
NanoAppMessage mMessage, boolean mSuccess) {
super(mTimeStampInMs, mContextHubId, 0, mSuccess);
message = mMessage;
+ errorCode = Optional.empty();
+ }
+
+ public void setErrorCode(byte errorCode) {
+ this.errorCode = Optional.of(errorCode);
}
@Override
@@ -165,6 +177,8 @@ public class ContextHubEventLogger {
sb.append(message.toString());
sb.append(", success = ");
sb.append(success ? "true" : "false");
+ sb.append(", errorCode = ");
+ sb.append(errorCode.isPresent() ? errorCode.get() : "null");
sb.append(']');
return sb.toString();
}
@@ -312,6 +326,28 @@ public class ContextHubEventLogger {
}
/**
+ * Logs the status of a reliable message
+ *
+ * @param messageSequenceNumber the message sequence number
+ * @param errorCode the error code
+ */
+ public synchronized void logReliableMessageToNanoappStatus(
+ int messageSequenceNumber, byte errorCode) {
+ if (!Flags.reliableMessage()) {
+ return;
+ }
+
+ for (NanoappMessageEvent event : mMessageToNanoappQueue) {
+ if (event.message.isReliable()
+ && event.message.getMessageSequenceNumber()
+ == messageSequenceNumber) {
+ event.setErrorCode(errorCode);
+ break;
+ }
+ }
+ }
+
+ /**
* Logs a context hub restart event
*
* @param contextHubId the ID of the context hub
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index a0aad5215f00..ed451ff0c194 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -1087,6 +1087,8 @@ public class ContextHubService extends IContextHubService.Stub {
* @param messageDeliveryStatus The message delivery status to deliver.
*/
private void handleMessageDeliveryStatusCallback(MessageDeliveryStatus messageDeliveryStatus) {
+ ContextHubEventLogger.getInstance().logReliableMessageToNanoappStatus(
+ messageDeliveryStatus.messageSequenceNumber, messageDeliveryStatus.errorCode);
mTransactionManager.onMessageDeliveryResponse(messageDeliveryStatus.messageSequenceNumber,
messageDeliveryStatus.errorCode == ErrorCode.OK);
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java b/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
index 2ec9bdb75349..3aea6d533295 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
@@ -33,11 +33,11 @@ abstract class ContextHubServiceTransaction {
@ContextHubTransaction.Type
private final int mTransactionType;
- private final Long mNanoAppId;
+ private final long mNanoAppId;
private final String mPackage;
- private final Integer mMessageSequenceNumber;
+ private final int mMessageSequenceNumber;
private long mNextRetryTime;
@@ -53,9 +53,9 @@ abstract class ContextHubServiceTransaction {
ContextHubServiceTransaction(int id, int type, String packageName) {
mTransactionId = id;
mTransactionType = type;
- mNanoAppId = null;
+ mNanoAppId = Long.MAX_VALUE;
mPackage = packageName;
- mMessageSequenceNumber = null;
+ mMessageSequenceNumber = Integer.MAX_VALUE;
mNextRetryTime = Long.MAX_VALUE;
mTimeoutTime = Long.MAX_VALUE;
mNumCompletedStartCalls = 0;
@@ -68,7 +68,7 @@ abstract class ContextHubServiceTransaction {
mTransactionType = type;
mNanoAppId = nanoAppId;
mPackage = packageName;
- mMessageSequenceNumber = null;
+ mMessageSequenceNumber = Integer.MAX_VALUE;
mNextRetryTime = Long.MAX_VALUE;
mTimeoutTime = Long.MAX_VALUE;
mNumCompletedStartCalls = 0;
@@ -79,7 +79,7 @@ abstract class ContextHubServiceTransaction {
int messageSequenceNumber, short hostEndpointId) {
mTransactionId = id;
mTransactionType = type;
- mNanoAppId = null;
+ mNanoAppId = Long.MAX_VALUE;
mPackage = packageName;
mMessageSequenceNumber = messageSequenceNumber;
mNextRetryTime = Long.MAX_VALUE;
@@ -131,7 +131,7 @@ abstract class ContextHubServiceTransaction {
return mTransactionType;
}
- Integer getMessageSequenceNumber() {
+ int getMessageSequenceNumber() {
return mMessageSequenceNumber;
}
@@ -204,14 +204,14 @@ abstract class ContextHubServiceTransaction {
out.append(ContextHubTransaction.typeToString(mTransactionType,
/* upperCase= */ true));
out.append(" (");
- if (mNanoAppId != null) {
+ if (mNanoAppId != Long.MAX_VALUE) {
out.append("appId = 0x");
out.append(Long.toHexString(mNanoAppId));
out.append(", ");
}
out.append("package = ");
out.append(mPackage);
- if (mMessageSequenceNumber != null) {
+ if (mMessageSequenceNumber != Integer.MAX_VALUE) {
out.append(", messageSequenceNumber = ");
out.append(mMessageSequenceNumber);
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java
index e50324eb7c83..f2714dbd7e5f 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java
@@ -29,19 +29,22 @@ import java.util.Random;
public class ContextHubTestModeManager {
private static final String TAG = "ContextHubTestModeManager";
- /** Probability (in percent) of duplicating a message. */
- private static final int MESSAGE_DROP_PROBABILITY_PERCENT = 20;
+ /** Probability of duplicating a message. */
+ private static final double MESSAGE_DROP_PROBABILITY = 0.05;
- /** Probability (in percent) of duplicating a message. */
- private static final int MESSAGE_DUPLICATION_PROBABILITY_PERCENT = 20;
+ /** Probability of duplicating a message. */
+ private static final double MESSAGE_DUPLICATION_PROBABILITY = 0.05;
- /** The number of total messages to send when the duplicate event happens. */
+ /** The number of total messages to send when the duplication event happens. */
private static final int NUM_MESSAGES_TO_DUPLICATE = 3;
- /** A probability percent for a certain event. */
- private static final int MAX_PROBABILITY_PERCENT = 100;
+ /**
+ * The seed for the random number generator. This is used to make the
+ * test more deterministic.
+ */
+ private static final long SEED = 0xDEADBEEF;
- private final Random mRandom = new Random();
+ private final Random mRandom = new Random(SEED);
/**
* @return whether the message was handled
@@ -50,8 +53,7 @@ public class ContextHubTestModeManager {
public boolean handleNanoappMessage(Runnable handleMessage, NanoAppMessage message) {
if (Flags.reliableMessageDuplicateDetectionService()
&& message.isReliable()
- && mRandom.nextInt(MAX_PROBABILITY_PERCENT)
- < MESSAGE_DUPLICATION_PROBABILITY_PERCENT) {
+ && mRandom.nextDouble() < MESSAGE_DUPLICATION_PROBABILITY) {
Log.i(TAG, "[TEST MODE] Duplicating message ("
+ NUM_MESSAGES_TO_DUPLICATE
+ " sends) with message sequence number: "
@@ -71,8 +73,7 @@ public class ContextHubTestModeManager {
public boolean sendMessageToContextHub(NanoAppMessage message) {
if (Flags.reliableMessageRetrySupportService()
&& message.isReliable()
- && mRandom.nextInt(MAX_PROBABILITY_PERCENT)
- < MESSAGE_DROP_PROBABILITY_PERCENT) {
+ && mRandom.nextDouble() < MESSAGE_DROP_PROBABILITY) {
Log.i(TAG, "[TEST MODE] Dropping message with message sequence number: "
+ message.getMessageSequenceNumber());
return true;
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
index 1a449e024ee1..e6d330f85dfc 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
@@ -474,9 +474,8 @@ import java.util.concurrent.atomic.AtomicInteger;
return;
}
- Integer transactionMessageSequenceNumber = transaction.getMessageSequenceNumber();
+ int transactionMessageSequenceNumber = transaction.getMessageSequenceNumber();
if (transaction.getTransactionType() != ContextHubTransaction.TYPE_RELIABLE_MESSAGE
- || transactionMessageSequenceNumber == null
|| transactionMessageSequenceNumber != messageSequenceNumber) {
Log.w(TAG, "Received unexpected message transaction response (expected message "
+ "sequence number = "
@@ -494,7 +493,8 @@ import java.util.concurrent.atomic.AtomicInteger;
ContextHubServiceTransaction transaction =
mReliableMessageTransactionMap.get(messageSequenceNumber);
if (transaction == null) {
- Log.w(TAG, "Could not find reliable message transaction with message sequence number"
+ Log.w(TAG, "Could not find reliable message transaction with "
+ + "message sequence number = "
+ messageSequenceNumber);
return;
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ae3a2afb79ef..db4d68b52a95 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1815,6 +1815,20 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
+ @Override
+ public boolean writeRepairModeCredential(int userId) {
+ checkWritePermission();
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mSpManager) {
+ long protectorId = getCurrentLskfBasedProtectorId(userId);
+ return mSpManager.writeRepairModeCredentialLocked(protectorId, userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
/**
* @param savedCredential if the user is a profile with
* {@link UserManager#isCredentialSharableWithParent()} with unified challenge and
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
index 7c1a5e113a5e..93ef6f044e1b 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
@@ -56,6 +56,7 @@ final class MediaRoute2ProviderWatcher {
private final PackageManager mPackageManager;
private final ArrayList<MediaRoute2ProviderServiceProxy> mProxies = new ArrayList<>();
+ private final Runnable mScanPackagesRunnable = this::scanPackages;
private boolean mRunning;
MediaRoute2ProviderWatcher(Context context,
@@ -106,7 +107,7 @@ final class MediaRoute2ProviderWatcher {
mRunning = false;
mContext.unregisterReceiver(mScanPackagesReceiver);
- mHandler.removeCallbacks(this::scanPackages);
+ mHandler.removeCallbacks(mScanPackagesRunnable);
// Stop all providers.
for (int i = mProxies.size() - 1; i >= 0; i--) {
@@ -189,8 +190,8 @@ final class MediaRoute2ProviderWatcher {
}
private void postScanPackagesIfNeeded() {
- if (!mHandler.hasCallbacks(this::scanPackages)) {
- mHandler.post(this::scanPackages);
+ if (!mHandler.hasCallbacks(mScanPackagesRunnable)) {
+ mHandler.post(mScanPackagesRunnable);
}
}
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index e3d5c54f1d5e..803b125cbabc 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.media.projection;
import static android.Manifest.permission.MANAGE_MEDIA_PROJECTION;
+import static android.Manifest.permission.RECORD_SENSITIVE_CONTENT;
import static android.app.ActivityManagerInternal.MEDIA_PROJECTION_TOKEN_EVENT_CREATED;
import static android.app.ActivityManagerInternal.MEDIA_PROJECTION_TOKEN_EVENT_DESTROYED;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
@@ -34,10 +35,12 @@ import android.Manifest;
import android.annotation.EnforcePermission;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions.LaunchCookie;
import android.app.AppOpsManager;
import android.app.IProcessObserver;
+import android.app.KeyguardManager;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
@@ -78,6 +81,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
+import com.android.server.SystemConfig;
import com.android.server.SystemService;
import com.android.server.Watchdog;
import com.android.server.wm.WindowManagerInternal;
@@ -132,6 +136,7 @@ public final class MediaProjectionManagerService extends SystemService
private final ActivityManagerInternal mActivityManagerInternal;
private final PackageManager mPackageManager;
private final WindowManagerInternal mWmInternal;
+ private final KeyguardManager mKeyguardManager;
private final MediaRouter mMediaRouter;
private final MediaRouterCallback mMediaRouterCallback;
@@ -147,7 +152,9 @@ public final class MediaProjectionManagerService extends SystemService
this(context, new Injector());
}
- @VisibleForTesting MediaProjectionManagerService(Context context, Injector injector) {
+ @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
+ @VisibleForTesting
+ MediaProjectionManagerService(Context context, Injector injector) {
super(context);
mContext = context;
mInjector = injector;
@@ -163,9 +170,47 @@ public final class MediaProjectionManagerService extends SystemService
mMediaRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
mMediaRouterCallback = new MediaRouterCallback();
mMediaProjectionMetricsLogger = injector.mediaProjectionMetricsLogger(context);
+ mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+ mKeyguardManager.addKeyguardLockedStateListener(
+ mContext.getMainExecutor(), this::onKeyguardLockedStateChanged);
Watchdog.getInstance().addMonitor(this);
}
+ /**
+ * In order to record the keyguard, the MediaProjection package must be either:
+ * - a holder of RECORD_SENSITIVE_CONTENT permission, or
+ * - be one of the bugreport whitelisted packages
+ */
+ private boolean canCaptureKeyguard() {
+ if (!android.companion.virtualdevice.flags.Flags.mediaProjectionKeyguardRestrictions()) {
+ return true;
+ }
+ synchronized (mLock) {
+ if (mProjectionGrant == null || mProjectionGrant.packageName == null) {
+ return false;
+ }
+ if (mPackageManager.checkPermission(RECORD_SENSITIVE_CONTENT,
+ mProjectionGrant.packageName)
+ == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ return SystemConfig.getInstance().getBugreportWhitelistedPackages()
+ .contains(mProjectionGrant.packageName);
+ }
+ }
+
+ @VisibleForTesting
+ void onKeyguardLockedStateChanged(boolean isKeyguardLocked) {
+ if (!isKeyguardLocked) return;
+ synchronized (mLock) {
+ if (mProjectionGrant != null && !canCaptureKeyguard()) {
+ Slog.d(TAG, "Content Recording: Stopped MediaProjection"
+ + " due to keyguard lock");
+ mProjectionGrant.stop();
+ }
+ }
+ }
+
/** Functional interface for providing time. */
@VisibleForTesting
interface Clock {
@@ -1252,6 +1297,11 @@ public final class MediaProjectionManagerService extends SystemService
@Override
public void notifyVirtualDisplayCreated(int displayId) {
notifyVirtualDisplayCreated_enforcePermission();
+ if (mKeyguardManager.isKeyguardLocked() && !canCaptureKeyguard()) {
+ Slog.w(TAG, "Content Recording: Keyguard locked, aborting MediaProjection");
+ stop();
+ return;
+ }
synchronized (mLock) {
mVirtualDisplayId = displayId;
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 13cc99c804f6..1cdab44a5b1b 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -24,9 +24,14 @@ import static android.app.Notification.FLAG_NO_CLEAR;
import static android.app.Notification.FLAG_ONGOING_EVENT;
import static android.app.Notification.VISIBILITY_PRIVATE;
import static android.app.Notification.VISIBILITY_PUBLIC;
+import static android.service.notification.Flags.notificationForceGrouping;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -34,7 +39,9 @@ import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
import android.util.ArrayMap;
+import android.util.Log;
import android.util.Slog;
import com.android.internal.R;
@@ -42,14 +49,20 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
+import java.util.Set;
+import java.util.function.Predicate;
/**
* NotificationManagerService helper for auto-grouping notifications.
*/
public class GroupHelper {
private static final String TAG = "GroupHelper";
+ static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
protected static final String AUTOGROUP_KEY = "ranker_group";
@@ -63,8 +76,16 @@ public class GroupHelper {
// Flags that autogroup summaries inherits if any child has them
private static final int ANY_CHILDREN_FLAGS = FLAG_ONGOING_EVENT | FLAG_NO_CLEAR;
+ protected static final String AGGREGATE_GROUP_KEY = "Aggregate_";
+
+ // If an app posts more than NotificationManagerService.AUTOGROUP_SPARSE_GROUPS_AT_COUNT groups
+ // with less than this value, they will be forced grouped
+ private static final int MIN_CHILD_COUNT_TO_AVOID_FORCE_GROUPING = 3;
+
+
private final Callback mCallback;
private final int mAutoGroupAtCount;
+ private final int mAutogroupSparseGroupsAtCount;
private final Context mContext;
private final PackageManager mPackageManager;
@@ -75,12 +96,41 @@ public class GroupHelper {
private final ArrayMap<String, ArrayMap<String, NotificationAttributes>> mUngroupedNotifications
= new ArrayMap<>();
+ // Contains the list of notifications that should be aggregated (forced grouping)
+ // but there are less than mAutoGroupAtCount per section for a package.
+ // The primary map's key is the full aggregated group key: userId|pkgName|g:groupName
+ // The internal map's key is the notification record key
+ @GuardedBy("mAggregatedNotifications")
+ private final ArrayMap<FullyQualifiedGroupKey, ArrayMap<String, NotificationAttributes>>
+ mUngroupedAbuseNotifications = new ArrayMap<>();
+
+ // Contains the list of group summaries that were canceled when "singleton groups" were
+ // force grouped. Used to remove the original group's children when an app cancels the
+ // already removed summary. Key is userId|packageName|g:OriginalGroupName
+ @GuardedBy("mAggregatedNotifications")
+ private final ArrayMap<FullyQualifiedGroupKey, CachedSummary>
+ mCanceledSummaries = new ArrayMap<>();
+
+ // Represents the current state of the aggregated (forced grouped) notifications
+ // Key is the full aggregated group key: userId|pkgName|g:groupName
+ // And groupName is "Aggregate_"+sectionName
+ @GuardedBy("mAggregatedNotifications")
+ private final ArrayMap<FullyQualifiedGroupKey, ArrayMap<String, NotificationAttributes>>
+ mAggregatedNotifications = new ArrayMap<>();
+
+ private static final List<NotificationSectioner> NOTIFICATION_SHADE_SECTIONS = List.of(
+ new NotificationSectioner("AlertingSection", 0, (record) ->
+ record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT),
+ new NotificationSectioner("SilentSection", 1, (record) ->
+ record.getImportance() < NotificationManager.IMPORTANCE_DEFAULT));
+
public GroupHelper(Context context, PackageManager packageManager, int autoGroupAtCount,
- Callback callback) {
+ int autoGroupSparseGroupsAtCount, Callback callback) {
mAutoGroupAtCount = autoGroupAtCount;
mCallback = callback;
mContext = context;
mPackageManager = packageManager;
+ mAutogroupSparseGroupsAtCount = autoGroupSparseGroupsAtCount;
}
private String generatePackageKey(int userId, String pkg) {
@@ -88,40 +138,50 @@ public class GroupHelper {
}
@VisibleForTesting
- @GuardedBy("mUngroupedNotifications")
- protected int getAutogroupSummaryFlags(
- @NonNull final ArrayMap<String, NotificationAttributes> children) {
+ protected static int getAutogroupSummaryFlags(
+ @NonNull final ArrayMap<String, NotificationAttributes> childrenMap) {
+ final Collection<NotificationAttributes> children = childrenMap.values();
boolean allChildrenHasFlag = children.size() > 0;
int anyChildFlagSet = 0;
- for (int i = 0; i < children.size(); i++) {
- if (!hasAnyFlag(children.valueAt(i).flags, ALL_CHILDREN_FLAG)) {
+ for (NotificationAttributes childAttr: children) {
+ if (!hasAnyFlag(childAttr.flags, ALL_CHILDREN_FLAG)) {
allChildrenHasFlag = false;
}
- if (hasAnyFlag(children.valueAt(i).flags, ANY_CHILDREN_FLAGS)) {
- anyChildFlagSet |= (children.valueAt(i).flags & ANY_CHILDREN_FLAGS);
+ if (hasAnyFlag(childAttr.flags, ANY_CHILDREN_FLAGS)) {
+ anyChildFlagSet |= (childAttr.flags & ANY_CHILDREN_FLAGS);
}
}
return BASE_FLAGS | (allChildrenHasFlag ? ALL_CHILDREN_FLAG : 0) | anyChildFlagSet;
}
- private boolean hasAnyFlag(int flags, int mask) {
+ private static boolean hasAnyFlag(int flags, int mask) {
return (flags & mask) != 0;
}
/**
* Called when a notification is newly posted. Checks whether that notification, and all other
* active notifications should be grouped or ungrouped atuomatically, and returns whether.
- * @param sbn The posted notification.
+ * @param record The posted notification.
* @param autogroupSummaryExists Whether a summary for this notification already exists.
* @return Whether the provided notification should be autogrouped synchronously.
*/
- public boolean onNotificationPosted(StatusBarNotification sbn, boolean autogroupSummaryExists) {
+ public boolean onNotificationPosted(NotificationRecord record, boolean autogroupSummaryExists) {
boolean sbnToBeAutogrouped = false;
try {
- if (!sbn.isAppGroup()) {
- sbnToBeAutogrouped = maybeGroup(sbn, autogroupSummaryExists);
+ if (notificationForceGrouping()) {
+ final StatusBarNotification sbn = record.getSbn();
+ if (!sbn.isAppGroup()) {
+ sbnToBeAutogrouped = maybeGroupWithSections(record, autogroupSummaryExists);
+ } else {
+ maybeUngroupWithSections(record);
+ }
} else {
- maybeUngroup(sbn, false, sbn.getUserId());
+ final StatusBarNotification sbn = record.getSbn();
+ if (!sbn.isAppGroup()) {
+ sbnToBeAutogrouped = maybeGroup(sbn, autogroupSummaryExists);
+ } else {
+ maybeUngroup(sbn, false, sbn.getUserId());
+ }
}
} catch (Exception e) {
Slog.e(TAG, "Failure processing new notification", e);
@@ -129,9 +189,20 @@ public class GroupHelper {
return sbnToBeAutogrouped;
}
- public void onNotificationRemoved(StatusBarNotification sbn) {
+ /**
+ * Called when a notification was removed. Checks if that notification was part of an autogroup
+ * and triggers any necessary cleanups: summary removal, clearing caches etc.
+ *
+ * @param record The removed notification.
+ */
+ public void onNotificationRemoved(NotificationRecord record) {
try {
- maybeUngroup(sbn, true, sbn.getUserId());
+ if (notificationForceGrouping()) {
+ onNotificationRemoved(record, new ArrayList<>());
+ } else {
+ final StatusBarNotification sbn = record.getSbn();
+ maybeUngroup(sbn, true, sbn.getUserId());
+ }
} catch (Exception e) {
Slog.e(TAG, "Error processing canceled notification", e);
}
@@ -156,10 +227,10 @@ public class GroupHelper {
String packageKey = generatePackageKey(sbn.getUserId(), sbn.getPackageName());
final ArrayMap<String, NotificationAttributes> children =
mUngroupedNotifications.getOrDefault(packageKey, new ArrayMap<>());
-
NotificationAttributes attr = new NotificationAttributes(sbn.getNotification().flags,
sbn.getNotification().getSmallIcon(), sbn.getNotification().color,
- sbn.getNotification().visibility);
+ sbn.getNotification().visibility, Notification.GROUP_ALERT_CHILDREN,
+ sbn.getNotification().getChannelId());
children.put(sbn.getKey(), attr);
mUngroupedNotifications.put(packageKey, children);
@@ -173,17 +244,20 @@ public class GroupHelper {
if (autogroupSummaryExists) {
NotificationAttributes attr = new NotificationAttributes(flags,
sbn.getNotification().getSmallIcon(), sbn.getNotification().color,
- VISIBILITY_PRIVATE);
+ VISIBILITY_PRIVATE, Notification.GROUP_ALERT_CHILDREN,
+ sbn.getNotification().getChannelId());
if (Flags.autogroupSummaryIconUpdate()) {
attr = updateAutobundledSummaryAttributes(sbn.getPackageName(), childrenAttr,
attr);
}
- mCallback.updateAutogroupSummary(sbn.getUserId(), sbn.getPackageName(), attr);
+ mCallback.updateAutogroupSummary(sbn.getUserId(), sbn.getPackageName(),
+ AUTOGROUP_KEY, attr);
} else {
Icon summaryIcon = sbn.getNotification().getSmallIcon();
int summaryIconColor = sbn.getNotification().color;
int summaryVisibility = VISIBILITY_PRIVATE;
+ String summaryChannelId = sbn.getNotification().getChannelId();
if (Flags.autogroupSummaryIconUpdate()) {
// Calculate the initial summary icon, icon color and visibility
NotificationAttributes iconAttr = getAutobundledSummaryAttributes(
@@ -191,12 +265,14 @@ public class GroupHelper {
summaryIcon = iconAttr.icon;
summaryIconColor = iconAttr.iconColor;
summaryVisibility = iconAttr.visibility;
+ summaryChannelId = iconAttr.channelId;
}
NotificationAttributes attr = new NotificationAttributes(flags, summaryIcon,
- summaryIconColor, summaryVisibility);
+ summaryIconColor, summaryVisibility, Notification.GROUP_ALERT_CHILDREN,
+ summaryChannelId);
mCallback.addAutoGroupSummary(sbn.getUserId(), sbn.getPackageName(), sbn.getKey(),
- attr);
+ AUTOGROUP_KEY, Integer.MAX_VALUE, attr);
}
for (String keyToGroup : notificationsToGroup) {
if (android.app.Flags.checkAutogroupBeforePost()) {
@@ -204,10 +280,10 @@ public class GroupHelper {
// Autogrouping for the provided notification is to be done synchronously.
sbnToBeAutogrouped = true;
} else {
- mCallback.addAutoGroup(keyToGroup, /*requestSort=*/true);
+ mCallback.addAutoGroup(keyToGroup, AUTOGROUP_KEY, /*requestSort=*/true);
}
} else {
- mCallback.addAutoGroup(keyToGroup, /*requestSort=*/true);
+ mCallback.addAutoGroup(keyToGroup, AUTOGROUP_KEY, /*requestSort=*/true);
}
}
}
@@ -263,11 +339,12 @@ public class GroupHelper {
}
if (removeSummary) {
- mCallback.removeAutoGroupSummary(userId, sbn.getPackageName());
+ mCallback.removeAutoGroupSummary(userId, sbn.getPackageName(), AUTOGROUP_KEY);
} else {
NotificationAttributes attr = new NotificationAttributes(summaryFlags,
sbn.getNotification().getSmallIcon(), sbn.getNotification().color,
- VISIBILITY_PRIVATE);
+ VISIBILITY_PRIVATE, Notification.GROUP_ALERT_CHILDREN,
+ sbn.getNotification().getChannelId());
boolean attributesUpdated = false;
if (Flags.autogroupSummaryIconUpdate()) {
NotificationAttributes newAttr = updateAutobundledSummaryAttributes(
@@ -279,7 +356,7 @@ public class GroupHelper {
}
if (updateSummaryFlags || attributesUpdated) {
- mCallback.updateAutogroupSummary(userId, sbn.getPackageName(), attr);
+ mCallback.updateAutogroupSummary(userId, sbn.getPackageName(), AUTOGROUP_KEY, attr);
}
}
if (removeAutogroupOverlay) {
@@ -287,16 +364,6 @@ public class GroupHelper {
}
}
- @VisibleForTesting
- int getNotGroupedByAppCount(int userId, String pkg) {
- synchronized (mUngroupedNotifications) {
- String key = generatePackageKey(userId, pkg);
- final ArrayMap<String, NotificationAttributes> children =
- mUngroupedNotifications.getOrDefault(key, new ArrayMap<>());
- return children.size();
- }
- }
-
NotificationAttributes getAutobundledSummaryAttributes(@NonNull String packageName,
@NonNull List<NotificationAttributes> childrenAttr) {
Icon newIcon = null;
@@ -338,7 +405,20 @@ public class GroupHelper {
newColor = COLOR_DEFAULT;
}
- return new NotificationAttributes(0, newIcon, newColor, newVisibility);
+ // Use GROUP_ALERT_CHILDREN
+ // Unless all children have GROUP_ALERT_SUMMARY => avoid muting all notifications in group
+ int newGroupAlertBehavior = Notification.GROUP_ALERT_SUMMARY;
+ for (NotificationAttributes attr: childrenAttr) {
+ if (attr.groupAlertBehavior != Notification.GROUP_ALERT_SUMMARY) {
+ newGroupAlertBehavior = Notification.GROUP_ALERT_CHILDREN;
+ break;
+ }
+ }
+
+ String channelId = !childrenAttr.isEmpty() ? childrenAttr.get(0).channelId : null;
+
+ return new NotificationAttributes(0, newIcon, newColor, newVisibility,
+ newGroupAlertBehavior, channelId);
}
NotificationAttributes updateAutobundledSummaryAttributes(@NonNull String packageName,
@@ -348,14 +428,28 @@ public class GroupHelper {
childrenAttr);
Icon newIcon = newAttr.icon;
int newColor = newAttr.iconColor;
+ String newChannelId = newAttr.channelId;
if (newAttr.icon == null) {
newIcon = oldAttr.icon;
}
if (newAttr.iconColor == Notification.COLOR_INVALID) {
newColor = oldAttr.iconColor;
}
+ if (newAttr.channelId == null) {
+ newChannelId = oldAttr.channelId;
+ }
- return new NotificationAttributes(oldAttr.flags, newIcon, newColor, newAttr.visibility);
+ return new NotificationAttributes(oldAttr.flags, newIcon, newColor, newAttr.visibility,
+ oldAttr.groupAlertBehavior, newChannelId);
+ }
+
+ private NotificationAttributes getSummaryAttributes(String pkgName,
+ ArrayMap<String, NotificationAttributes> childrenMap) {
+ int flags = getAutogroupSummaryFlags(childrenMap);
+ NotificationAttributes attr = getAutobundledSummaryAttributes(pkgName,
+ childrenMap.values().stream().toList());
+ return new NotificationAttributes(flags, attr.icon, attr.iconColor, attr.visibility,
+ attr.groupAlertBehavior, attr.channelId);
}
/**
@@ -388,17 +482,865 @@ public class GroupHelper {
}
}
+ /**
+ * A non-app grouped notification has been added or updated
+ * Evaluate if:
+ * (a) an existing autogroup summary needs updated attributes
+ * (b) a new autogroup summary needs to be added with correct attributes
+ * (c) other non-app grouped children need to be moved to the autogroup
+ *
+ * This method implements autogrouping with sections support.
+ *
+ * And stores the list of upgrouped notifications & their flags
+ */
+ private boolean maybeGroupWithSections(NotificationRecord record,
+ boolean autogroupSummaryExists) {
+ final StatusBarNotification sbn = record.getSbn();
+ boolean sbnToBeAutogrouped = false;
+
+ final NotificationSectioner sectioner = getSection(record);
+ if (sectioner == null) {
+ if (DEBUG) {
+ Log.i(TAG, "Skipping autogrouping for " + record + " no valid section found.");
+ }
+ return false;
+ }
+
+ final String pkgName = sbn.getPackageName();
+ final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(
+ record.getUserId(), pkgName, sectioner);
+
+ // This notification is already aggregated
+ if (record.getGroupKey().equals(fullAggregateGroupKey.toString())) {
+ return false;
+ }
+
+ synchronized (mAggregatedNotifications) {
+ ArrayMap<String, NotificationAttributes> ungrouped =
+ mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+ ungrouped.put(record.getKey(), new NotificationAttributes(
+ record.getFlags(),
+ record.getNotification().getSmallIcon(),
+ record.getNotification().color,
+ record.getNotification().visibility,
+ record.getNotification().getGroupAlertBehavior(),
+ record.getChannel().getId()));
+ mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+
+ // scenario 0: ungrouped notifications
+ if (ungrouped.size() >= mAutoGroupAtCount || autogroupSummaryExists) {
+ if (DEBUG) {
+ if (ungrouped.size() >= mAutoGroupAtCount) {
+ Log.i(TAG,
+ "Found >=" + mAutoGroupAtCount
+ + " ungrouped notifications => force grouping");
+ } else {
+ Log.i(TAG, "Found aggregate summary => force grouping");
+ }
+ }
+
+ final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+ mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+ aggregatedNotificationsAttrs.putAll(ungrouped);
+ mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+ // add/update aggregate summary
+ updateAggregateAppGroup(fullAggregateGroupKey, record.getKey(),
+ autogroupSummaryExists, sectioner.mSummaryId);
+
+ // add notification to aggregate group
+ for (String keyToGroup : ungrouped.keySet()) {
+ if (android.app.Flags.checkAutogroupBeforePost()) {
+ if (keyToGroup.equals(record.getKey())) {
+ // Autogrouping for the posted notification is to be done synchronously.
+ sbnToBeAutogrouped = true;
+ } else {
+ mCallback.addAutoGroup(keyToGroup, fullAggregateGroupKey.toString(),
+ true);
+ }
+ } else {
+ mCallback.addAutoGroup(keyToGroup, fullAggregateGroupKey.toString(), true);
+ }
+ }
+
+ //cleanup mUngroupedAbuseNotifications
+ mUngroupedAbuseNotifications.remove(fullAggregateGroupKey);
+ }
+ }
+
+ return sbnToBeAutogrouped;
+ }
+
+ /**
+ * A notification was added that's app grouped.
+ * Evaluate whether:
+ * (a) an existing autogroup summary needs updated attributes
+ * (b) if we need to remove our autogroup overlay for this notification
+ * (c) we need to remove the autogroup summary
+ *
+ * This method implements autogrouping with sections support.
+ *
+ * And updates the internal state of un-app-grouped notifications and their flags.
+ */
+ private void maybeUngroupWithSections(NotificationRecord record) {
+ final StatusBarNotification sbn = record.getSbn();
+ final String pkgName = sbn.getPackageName();
+ final int userId = record.getUserId();
+ final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(userId,
+ pkgName, getSection(record));
+
+ synchronized (mAggregatedNotifications) {
+ // if this notification still exists and has an autogroup overlay, but is now
+ // grouped by the app, clear the overlay
+ ArrayMap<String, NotificationAttributes> ungrouped =
+ mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+ ungrouped.remove(sbn.getKey());
+ mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+
+ final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+ mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+ // check if the removed notification was part of the aggregate group
+ if (aggregatedNotificationsAttrs.containsKey(record.getKey())) {
+ aggregatedNotificationsAttrs.remove(sbn.getKey());
+ mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+ if (DEBUG) {
+ Log.i(TAG, "maybeUngroup removeAutoGroup: " + record);
+ }
+
+ mCallback.removeAutoGroup(sbn.getKey());
+
+ if (aggregatedNotificationsAttrs.isEmpty()) {
+ if (DEBUG) {
+ Log.i(TAG, "Aggregate group is empty: " + fullAggregateGroupKey);
+ }
+ mCallback.removeAutoGroupSummary(userId, pkgName,
+ fullAggregateGroupKey.toString());
+ mAggregatedNotifications.remove(fullAggregateGroupKey);
+ } else {
+ if (DEBUG) {
+ Log.i(TAG, "Aggregate group not empty, updating: " + fullAggregateGroupKey);
+ }
+ updateAggregateAppGroup(fullAggregateGroupKey, sbn.getKey(), true, 0);
+ }
+ }
+ }
+ }
+
+ /**
+ * Called when a notification is newly posted, after some delay, so that the app
+ * has a chance to post a group summary or children (complete a group).
+ * Checks whether that notification and other active notifications should be forced grouped
+ * because their grouping is incorrect:
+ * - missing summary
+ * - only summaries
+ * - sparse groups == multiple groups with very few notifications
+ *
+ * @param record the notification that was posted
+ * @param notificationList the full notification list from NotificationManagerService
+ * @param summaryByGroupKey the map of group summaries from NotificationManagerService
+ */
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+ protected void onNotificationPostedWithDelay(final NotificationRecord record,
+ final List<NotificationRecord> notificationList,
+ final Map<String, NotificationRecord> summaryByGroupKey) {
+ // Ungrouped notifications are handled separately in
+ // {@link #onNotificationPosted(StatusBarNotification, boolean)}
+ final StatusBarNotification sbn = record.getSbn();
+ if (!sbn.isAppGroup()) {
+ return;
+ }
+
+ if (record.isCanceled) {
+ return;
+ }
+
+ final NotificationSectioner sectioner = getSection(record);
+ if (sectioner == null) {
+ if (DEBUG) {
+ Log.i(TAG, "Skipping autogrouping for " + record + " no valid section found.");
+ }
+ return;
+ }
+
+ final String pkgName = sbn.getPackageName();
+ final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(
+ record.getUserId(), pkgName, sectioner);
+
+ // This notification is already aggregated
+ if (record.getGroupKey().equals(fullAggregateGroupKey.toString())) {
+ return;
+ }
+
+ synchronized (mAggregatedNotifications) {
+ // scenario 1: group w/o summary
+ // scenario 2: summary w/o children
+ if (isGroupChildWithoutSummary(record, summaryByGroupKey) ||
+ isGroupSummaryWithoutChildren(record, notificationList)) {
+ if (DEBUG) {
+ Log.i(TAG, "isGroupChildWithoutSummary OR isGroupSummaryWithoutChild"
+ + record);
+ }
+
+ ArrayMap<String, NotificationAttributes> ungrouped =
+ mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey,
+ new ArrayMap<>());
+ ungrouped.put(record.getKey(), new NotificationAttributes(
+ record.getFlags(),
+ record.getNotification().getSmallIcon(),
+ record.getNotification().color,
+ record.getNotification().visibility,
+ record.getNotification().getGroupAlertBehavior(),
+ record.getChannel().getId()));
+ mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+ // Create/update summary and group if >= mAutoGroupAtCount notifications
+ // or if aggregate group exists
+ boolean hasSummary = !mAggregatedNotifications.getOrDefault(fullAggregateGroupKey,
+ new ArrayMap<>()).isEmpty();
+ if (ungrouped.size() >= mAutoGroupAtCount || hasSummary) {
+ if (DEBUG) {
+ if (ungrouped.size() >= mAutoGroupAtCount) {
+ Log.i(TAG,
+ "Found >=" + mAutoGroupAtCount
+ + " ungrouped notifications => force grouping");
+ } else {
+ Log.i(TAG, "Found aggregate summary => force grouping");
+ }
+ }
+ aggregateUngroupedNotifications(fullAggregateGroupKey, sbn.getKey(),
+ ungrouped, hasSummary, sectioner.mSummaryId);
+ }
+
+ return;
+ }
+
+ // scenario 3: sparse/singleton groups
+ if (Flags.notificationForceGroupSingletons()) {
+ groupSparseGroups(record, notificationList, summaryByGroupKey, sectioner,
+ fullAggregateGroupKey);
+ }
+ }
+ }
+
+ /**
+ * Called when a notification is removed, so that this helper can adjust the aggregate groups:
+ * - Removes the autogroup summary of the notification's section
+ * if the record was the last child.
+ * - Recalculates the autogroup summary "attributes":
+ * icon, icon color, visibility, groupAlertBehavior, flags - if the removed record was
+ * part of an autogroup.
+ * - Removes the saved summary of the original group, if the record was the last remaining
+ * child of a sparse group that was forced auto-grouped.
+ *
+ * see also {@link #onNotificationPostedWithDelay(NotificationRecord, List, Map)}
+ *
+ * @param record the removed notification
+ * @param notificationList the full notification list from NotificationManagerService
+ */
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+ protected void onNotificationRemoved(final NotificationRecord record,
+ final List<NotificationRecord> notificationList) {
+ final StatusBarNotification sbn = record.getSbn();
+ final String pkgName = sbn.getPackageName();
+ final int userId = record.getUserId();
+ final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(userId,
+ pkgName, getSection(record));
+
+ synchronized (mAggregatedNotifications) {
+ ArrayMap<String, NotificationAttributes> ungrouped =
+ mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+ ungrouped.remove(record.getKey());
+ mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+
+ final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+ mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+ // check if the removed notification was part of the aggregate group
+ if (record.getGroupKey().equals(fullAggregateGroupKey.toString())
+ || aggregatedNotificationsAttrs.containsKey(record.getKey())) {
+ aggregatedNotificationsAttrs.remove(record.getKey());
+ mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+ if (aggregatedNotificationsAttrs.isEmpty()) {
+ if (DEBUG) {
+ Log.i(TAG, "Aggregate group is empty: " + fullAggregateGroupKey);
+ }
+ mCallback.removeAutoGroupSummary(userId, pkgName,
+ fullAggregateGroupKey.toString());
+ mAggregatedNotifications.remove(fullAggregateGroupKey);
+ } else {
+ if (DEBUG) {
+ Log.i(TAG, "Aggregate group not empty, updating: " + fullAggregateGroupKey);
+ }
+ updateAggregateAppGroup(fullAggregateGroupKey, sbn.getKey(), true, 0);
+ }
+
+ // Try to cleanup cached summaries if notification was canceled (not snoozed)
+ if (record.isCanceled) {
+ maybeClearCanceledSummariesCache(pkgName, userId,
+ record.getNotification().getGroup(), notificationList);
+ }
+ }
+ }
+ }
+
+ private record NotificationMoveOp(NotificationRecord record, FullyQualifiedGroupKey oldGroup,
+ FullyQualifiedGroupKey newGroup) { }
+
+ /**
+ * Called when a notification channel is updated, so that this helper can adjust
+ * the aggregate groups by moving children if their section has changed.
+ * see {@link #onNotificationPostedWithDelay(NotificationRecord, List, Map)}
+ * @param userId the userId of the channel
+ * @param pkgName the channel's package
+ * @param channel the channel that was updated
+ * @param notificationList the full notification list from NotificationManagerService
+ */
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void onChannelUpdated(final int userId, final String pkgName,
+ final NotificationChannel channel, final List<NotificationRecord> notificationList) {
+ synchronized (mAggregatedNotifications) {
+ ArrayMap<String, NotificationRecord> notificationsToCheck = new ArrayMap<>();
+ for (NotificationRecord r : notificationList) {
+ if (r.getChannel().getId().equals(channel.getId())
+ && r.getSbn().getPackageName().equals(pkgName)
+ && r.getUserId() == userId) {
+ notificationsToCheck.put(r.getKey(), r);
+ }
+ }
+
+ final ArrayList<NotificationMoveOp> notificationsToMove = new ArrayList<>();
+
+ final Set<FullyQualifiedGroupKey> oldGroups =
+ new HashSet<>(mAggregatedNotifications.keySet());
+ for (FullyQualifiedGroupKey oldFullAggKey : oldGroups) {
+ // Only check aggregate groups that match the same userId & packageName
+ if (pkgName.equals(oldFullAggKey.pkg) && userId == oldFullAggKey.userId) {
+ final ArrayMap<String, NotificationAttributes> notificationsInAggGroup =
+ mAggregatedNotifications.get(oldFullAggKey);
+ if (notificationsInAggGroup == null) {
+ continue;
+ }
+
+ FullyQualifiedGroupKey newFullAggregateGroupKey = null;
+ for (String key : notificationsInAggGroup.keySet()) {
+ if (notificationsToCheck.get(key) != null) {
+ // check if section changes
+ NotificationSectioner sectioner = getSection(
+ notificationsToCheck.get(key));
+ if (sectioner == null) {
+ continue;
+ }
+ newFullAggregateGroupKey = new FullyQualifiedGroupKey(userId, pkgName,
+ sectioner);
+ if (!oldFullAggKey.equals(newFullAggregateGroupKey)) {
+ if (DEBUG) {
+ Log.i(TAG, "Change section on channel update: " + key);
+ }
+ notificationsToMove.add(
+ new NotificationMoveOp(notificationsToCheck.get(key),
+ oldFullAggKey, newFullAggregateGroupKey));
+ }
+ }
+ }
+
+ if (newFullAggregateGroupKey != null) {
+ // Add any notifications left ungrouped to the new section
+ ArrayMap<String, NotificationAttributes> ungrouped =
+ mUngroupedAbuseNotifications.get(newFullAggregateGroupKey);
+ if (ungrouped != null) {
+ for (NotificationRecord r : notificationList) {
+ if (ungrouped.containsKey(r.getKey())) {
+ if (DEBUG) {
+ Log.i(TAG, "Add previously ungrouped: " + r);
+ }
+ notificationsToMove.add(
+ new NotificationMoveOp(r, null, newFullAggregateGroupKey));
+ }
+ }
+ //Cleanup mUngroupedAbuseNotifications
+ mUngroupedAbuseNotifications.remove(newFullAggregateGroupKey);
+ }
+ }
+ }
+ }
+
+ // Batch move to new section
+ if (!notificationsToMove.isEmpty()) {
+ moveNotificationsToNewSection(userId, pkgName, notificationsToMove);
+ }
+ }
+ }
+
+ @GuardedBy("mAggregatedNotifications")
+ private void moveNotificationsToNewSection(final int userId, final String pkgName,
+ final List<NotificationMoveOp> notificationsToMove) {
+ record GroupUpdateOp(FullyQualifiedGroupKey groupKey, NotificationRecord record,
+ boolean hasSummary) { }
+ ArrayMap<FullyQualifiedGroupKey, GroupUpdateOp> groupsToUpdate = new ArrayMap<>();
+
+ for (NotificationMoveOp moveOp: notificationsToMove) {
+ final NotificationRecord record = moveOp.record;
+ final FullyQualifiedGroupKey oldFullAggregateGroupKey = moveOp.oldGroup;
+ final FullyQualifiedGroupKey newFullAggregateGroupKey = moveOp.newGroup;
+
+ if (DEBUG) {
+ Log.i(TAG,
+ "moveNotificationToNewSection: " + record + " " + newFullAggregateGroupKey
+ + " from: " + oldFullAggregateGroupKey);
+ }
+
+ // Update/remove aggregate summary for old group
+ if (oldFullAggregateGroupKey != null) {
+ final ArrayMap<String, NotificationAttributes> oldAggregatedNotificationsAttrs =
+ mAggregatedNotifications.getOrDefault(oldFullAggregateGroupKey,
+ new ArrayMap<>());
+ oldAggregatedNotificationsAttrs.remove(record.getKey());
+ mAggregatedNotifications.put(oldFullAggregateGroupKey,
+ oldAggregatedNotificationsAttrs);
+
+ // Only add once, for triggering notification
+ if (!groupsToUpdate.containsKey(oldFullAggregateGroupKey)) {
+ groupsToUpdate.put(oldFullAggregateGroupKey,
+ new GroupUpdateOp(oldFullAggregateGroupKey, record, true));
+ }
+ }
+
+ // Add/update aggregate summary for new group
+ if (newFullAggregateGroupKey != null) {
+ final ArrayMap<String, NotificationAttributes> newAggregatedNotificationsAttrs =
+ mAggregatedNotifications.getOrDefault(newFullAggregateGroupKey,
+ new ArrayMap<>());
+ boolean newGroupExists = !newAggregatedNotificationsAttrs.isEmpty();
+ newAggregatedNotificationsAttrs.put(record.getKey(),
+ new NotificationAttributes(record.getFlags(),
+ record.getNotification().getSmallIcon(),
+ record.getNotification().color,
+ record.getNotification().visibility,
+ record.getNotification().getGroupAlertBehavior(),
+ record.getChannel().getId()));
+ mAggregatedNotifications.put(newFullAggregateGroupKey,
+ newAggregatedNotificationsAttrs);
+
+ // Only add once, for triggering notification
+ if (!groupsToUpdate.containsKey(newFullAggregateGroupKey)) {
+ groupsToUpdate.put(newFullAggregateGroupKey,
+ new GroupUpdateOp(newFullAggregateGroupKey, record, newGroupExists));
+ }
+
+ // Add notification to new group. do not request resort
+ record.setOverrideGroupKey(null);
+ mCallback.addAutoGroup(record.getKey(), newFullAggregateGroupKey.toString(), false);
+ }
+ }
+
+ // Update groups (sections)
+ for (FullyQualifiedGroupKey groupKey : groupsToUpdate.keySet()) {
+ final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+ mAggregatedNotifications.getOrDefault(groupKey, new ArrayMap<>());
+ if (aggregatedNotificationsAttrs.isEmpty()) {
+ mCallback.removeAutoGroupSummary(userId, pkgName, groupKey.toString());
+ mAggregatedNotifications.remove(groupKey);
+ } else {
+ NotificationRecord triggeringNotification = groupsToUpdate.get(groupKey).record;
+ boolean hasSummary = groupsToUpdate.get(groupKey).hasSummary;
+ NotificationSectioner sectioner = getSection(triggeringNotification);
+ if (sectioner == null) {
+ continue;
+ }
+ updateAggregateAppGroup(groupKey, triggeringNotification.getKey(), hasSummary,
+ sectioner.mSummaryId);
+ }
+ }
+ }
+
+ static String getFullAggregateGroupKey(String pkgName,
+ String groupName, int userId) {
+ return new FullyQualifiedGroupKey(userId, pkgName, groupName).toString();
+ }
+
+ /**
+ * Returns the full aggregate group key, which contains the userId and package name
+ * in addition to the aggregate group key (name).
+ * Equivalent to {@link StatusBarNotification#groupKey()}
+ */
+ static String getFullAggregateGroupKey(NotificationRecord record) {
+ return new FullyQualifiedGroupKey(record.getUserId(), record.getSbn().getPackageName(),
+ getSection(record)).toString();
+ }
+
+ protected static boolean isAggregatedGroup(NotificationRecord record) {
+ return (record.mOriginalFlags & Notification.FLAG_AUTOGROUP_SUMMARY) != 0;
+ }
+
+ private static int getNumChildrenForGroup(@NonNull final String groupKey,
+ final List<NotificationRecord> notificationList) {
+ //TODO (b/349072751): track grouping state in GroupHelper -> do not use notificationList
+ int numChildren = 0;
+ // find children for this summary
+ for (NotificationRecord r : notificationList) {
+ if (!r.getNotification().isGroupSummary()
+ && groupKey.equals(r.getSbn().getGroup())) {
+ numChildren++;
+ }
+ }
+
+ if (DEBUG) {
+ Log.i(TAG, "getNumChildrenForGroup " + groupKey + " numChild: " + numChildren);
+ }
+ return numChildren;
+ }
+
+ private static boolean isGroupSummaryWithoutChildren(final NotificationRecord record,
+ final List<NotificationRecord> notificationList) {
+ final StatusBarNotification sbn = record.getSbn();
+ final String groupKey = record.getSbn().getGroup();
+
+ // ignore non app groups and non summaries
+ if (!sbn.isAppGroup() || !record.getNotification().isGroupSummary()) {
+ return false;
+ }
+
+ return getNumChildrenForGroup(groupKey, notificationList) == 0;
+ }
+
+ private static boolean isGroupChildWithoutSummary(final NotificationRecord record,
+ final Map<String, NotificationRecord> summaryByGroupKey) {
+ final StatusBarNotification sbn = record.getSbn();
+ final String groupKey = record.getSbn().getGroupKey();
+
+ if (!sbn.isAppGroup()) {
+ return false;
+ }
+
+ if (record.getNotification().isGroupSummary()) {
+ return false;
+ }
+
+ if (summaryByGroupKey.containsKey(groupKey)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @GuardedBy("mAggregatedNotifications")
+ private void aggregateUngroupedNotifications(FullyQualifiedGroupKey fullAggregateGroupKey,
+ String triggeringNotifKey, Map<String, NotificationAttributes> ungrouped,
+ final boolean hasSummary, int summaryId) {
+ final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+ mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+ aggregatedNotificationsAttrs.putAll(ungrouped);
+ mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+ // add/update aggregate summary
+ updateAggregateAppGroup(fullAggregateGroupKey, triggeringNotifKey, hasSummary, summaryId);
+
+ // add notification to aggregate group
+ for (String key: ungrouped.keySet()) {
+ mCallback.addAutoGroup(key, fullAggregateGroupKey.toString(), true);
+ }
+
+ //cleanup mUngroupedAbuseNotifications
+ mUngroupedAbuseNotifications.remove(fullAggregateGroupKey);
+ }
+
+ @GuardedBy("mAggregatedNotifications")
+ private void updateAggregateAppGroup(FullyQualifiedGroupKey fullAggregateGroupKey,
+ String triggeringNotifKey, boolean hasSummary, int summaryId) {
+ final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+ mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+ NotificationAttributes attr = getSummaryAttributes(fullAggregateGroupKey.pkg,
+ aggregatedNotificationsAttrs);
+ String channelId = hasSummary ? attr.channelId
+ : aggregatedNotificationsAttrs.get(triggeringNotifKey).channelId;
+ NotificationAttributes summaryAttr = new NotificationAttributes(attr.flags, attr.icon,
+ attr.iconColor, attr.visibility, attr.groupAlertBehavior, channelId);
+
+ if (!hasSummary) {
+ if (DEBUG) {
+ Log.i(TAG, "Create aggregate summary: " + fullAggregateGroupKey);
+ }
+ mCallback.addAutoGroupSummary(fullAggregateGroupKey.userId, fullAggregateGroupKey.pkg,
+ triggeringNotifKey, fullAggregateGroupKey.toString(), summaryId, summaryAttr);
+ } else {
+ if (DEBUG) {
+ Log.i(TAG, "Update aggregate summary: " + fullAggregateGroupKey);
+ }
+ mCallback.updateAutogroupSummary(fullAggregateGroupKey.userId,
+ fullAggregateGroupKey.pkg, fullAggregateGroupKey.toString(), summaryAttr);
+ }
+ }
+
+ @GuardedBy("mAggregatedNotifications")
+ private void groupSparseGroups(final NotificationRecord record,
+ final List<NotificationRecord> notificationList,
+ final Map<String, NotificationRecord> summaryByGroupKey,
+ final NotificationSectioner sectioner,
+ final FullyQualifiedGroupKey fullAggregateGroupKey) {
+ final ArrayMap<String, NotificationRecord> sparseGroupSummaries = getSparseGroups(
+ fullAggregateGroupKey, notificationList, summaryByGroupKey, sectioner);
+ if (sparseGroupSummaries.size() >= mAutogroupSparseGroupsAtCount) {
+ if (DEBUG) {
+ Log.i(TAG,
+ "Aggregate sparse groups for: " + record.getSbn().getPackageName()
+ + " Section: " + sectioner.mName);
+ }
+
+ ArrayMap<String, NotificationAttributes> ungrouped =
+ mUngroupedAbuseNotifications.getOrDefault(
+ fullAggregateGroupKey, new ArrayMap<>());
+ final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+ mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+ final boolean hasSummary = !aggregatedNotificationsAttrs.isEmpty();
+ for (NotificationRecord r : notificationList) {
+ // Add notifications for detected sparse groups
+ if (sparseGroupSummaries.containsKey(r.getGroupKey())) {
+ // Move child notifications to aggregate group
+ if (!r.getNotification().isGroupSummary()) {
+ if (DEBUG) {
+ Log.i(TAG, "Aggregate notification (sparse group): " + r);
+ }
+ mCallback.addAutoGroup(r.getKey(), fullAggregateGroupKey.toString(), true);
+ aggregatedNotificationsAttrs.put(r.getKey(),
+ new NotificationAttributes(r.getFlags(),
+ r.getNotification().getSmallIcon(), r.getNotification().color,
+ r.getNotification().visibility,
+ r.getNotification().getGroupAlertBehavior(),
+ r.getChannel().getId()));
+
+ } else if (r.getNotification().isGroupSummary()) {
+ // Remove summary notifications
+ if (DEBUG) {
+ Log.i(TAG, "Remove app summary (sparse group): " + r);
+ }
+ mCallback.removeAppProvidedSummary(r.getKey());
+ cacheCanceledSummary(r);
+ }
+ } else {
+ // Add any notifications left ungrouped
+ if (ungrouped.containsKey(r.getKey())) {
+ if (DEBUG) {
+ Log.i(TAG, "Aggregate ungrouped (sparse group): " + r);
+ }
+ mCallback.addAutoGroup(r.getKey(), fullAggregateGroupKey.toString(), true);
+ aggregatedNotificationsAttrs.put(r.getKey(),ungrouped.get(r.getKey()));
+ }
+ }
+ }
+
+ mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+ // add/update aggregate summary
+ updateAggregateAppGroup(fullAggregateGroupKey, record.getKey(), hasSummary,
+ sectioner.mSummaryId);
+
+ //cleanup mUngroupedAbuseNotifications
+ mUngroupedAbuseNotifications.remove(fullAggregateGroupKey);
+ }
+ }
+
+ private ArrayMap<String, NotificationRecord> getSparseGroups(
+ final FullyQualifiedGroupKey fullAggregateGroupKey,
+ final List<NotificationRecord> notificationList,
+ final Map<String, NotificationRecord> summaryByGroupKey,
+ final NotificationSectioner sectioner) {
+ ArrayMap<String, NotificationRecord> sparseGroups = new ArrayMap<>();
+ for (NotificationRecord summary : summaryByGroupKey.values()) {
+ if (summary != null && sectioner.isInSection(summary)) {
+ if (summary.getSbn().getPackageName().equalsIgnoreCase(fullAggregateGroupKey.pkg)
+ && summary.getUserId() == fullAggregateGroupKey.userId
+ && summary.getSbn().isAppGroup()
+ && !summary.getGroupKey().equals(fullAggregateGroupKey.toString())) {
+ int numChildren = getNumChildrenForGroup(summary.getSbn().getGroup(),
+ notificationList);
+ if (numChildren > 0 && numChildren < MIN_CHILD_COUNT_TO_AVOID_FORCE_GROUPING) {
+ sparseGroups.put(summary.getGroupKey(), summary);
+ }
+ }
+ }
+ }
+ return sparseGroups;
+ }
+
+ @GuardedBy("mAggregatedNotifications")
+ private void cacheCanceledSummary(NotificationRecord record) {
+ final FullyQualifiedGroupKey groupKey = new FullyQualifiedGroupKey(record.getUserId(),
+ record.getSbn().getPackageName(), record.getNotification().getGroup());
+ mCanceledSummaries.put(groupKey, new CachedSummary(record.getSbn().getId(),
+ record.getSbn().getTag(), record.getNotification().getGroup(), record.getKey()));
+ }
+
+ @GuardedBy("mAggregatedNotifications")
+ private void maybeClearCanceledSummariesCache(String pkgName, int userId,
+ String groupName, List<NotificationRecord> notificationList) {
+ final FullyQualifiedGroupKey findKey = new FullyQualifiedGroupKey(userId, pkgName,
+ groupName);
+ CachedSummary summary = mCanceledSummaries.get(findKey);
+ // Check if any notifications from original group remain
+ if (summary != null) {
+ if (DEBUG) {
+ Log.i(TAG, "Try removing cached summary: " + summary);
+ }
+ boolean stillHasChildren = false;
+ //TODO (b/349072751): track grouping state in GroupHelper -> do not use notificationList
+ for (NotificationRecord r : notificationList) {
+ if (summary.originalGroupKey.equals(r.getNotification().getGroup())
+ && r.getUser().getIdentifier() == userId
+ && r.getSbn().getPackageName().equals(pkgName)) {
+ stillHasChildren = true;
+ break;
+ }
+ }
+ if (!stillHasChildren) {
+ removeCachedSummary(pkgName, userId, summary);
+ }
+ }
+ }
+
+ @VisibleForTesting
+ @GuardedBy("mAggregatedNotifications")
+ protected CachedSummary findCanceledSummary(String pkgName, String tag, int id, int userId) {
+ for (FullyQualifiedGroupKey key: mCanceledSummaries.keySet()) {
+ if (pkgName.equals(key.pkg) && userId == key.userId) {
+ CachedSummary summary = mCanceledSummaries.get(key);
+ if (summary != null && summary.id == id && TextUtils.equals(tag, summary.tag)) {
+ return summary;
+ }
+ }
+ }
+ return null;
+ }
+
+ @VisibleForTesting
+ @GuardedBy("mAggregatedNotifications")
+ protected CachedSummary findCanceledSummary(String pkgName, String tag, int id, int userId,
+ String groupName) {
+ final FullyQualifiedGroupKey findKey = new FullyQualifiedGroupKey(userId, pkgName,
+ groupName);
+ CachedSummary summary = mCanceledSummaries.get(findKey);
+ if (summary != null && summary.id == id && TextUtils.equals(tag, summary.tag)) {
+ return summary;
+ } else {
+ return null;
+ }
+ }
+
+ @GuardedBy("mAggregatedNotifications")
+ private void removeCachedSummary(String pkgName, int userId, CachedSummary summary) {
+ final FullyQualifiedGroupKey key = new FullyQualifiedGroupKey(userId, pkgName,
+ summary.originalGroupKey);
+ mCanceledSummaries.remove(key);
+ }
+
+ protected boolean isUpdateForCanceledSummary(final NotificationRecord record) {
+ synchronized (mAggregatedNotifications) {
+ if (record.getSbn().isAppGroup() && record.getNotification().isGroupSummary()) {
+ CachedSummary cachedSummary = findCanceledSummary(record.getSbn().getPackageName(),
+ record.getSbn().getTag(), record.getSbn().getId(), record.getUserId(),
+ record.getNotification().getGroup());
+ return cachedSummary != null;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Cancels the original group's children when an app cancels a summary that was 'maybe'
+ * previously removed due to forced grouping of a "sparse group".
+ *
+ * @param pkgName packageName
+ * @param tag original summary notification tag
+ * @param id original summary notification id
+ * @param userId original summary userId
+ */
+ @FlaggedApi(Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS)
+ public void maybeCancelGroupChildrenForCanceledSummary(String pkgName, String tag, int id,
+ int userId, int cancelReason) {
+ synchronized (mAggregatedNotifications) {
+ final CachedSummary summary = findCanceledSummary(pkgName, tag, id, userId);
+ if (summary != null) {
+ if (DEBUG) {
+ Log.i(TAG, "Found cached summary: " + summary.key);
+ }
+ mCallback.removeNotificationFromCanceledGroup(userId, pkgName,
+ summary.originalGroupKey, cancelReason);
+ removeCachedSummary(pkgName, userId, summary);
+ }
+ }
+ }
+
+ static NotificationSectioner getSection(final NotificationRecord record) {
+ for (NotificationSectioner sectioner: NOTIFICATION_SHADE_SECTIONS) {
+ if (sectioner.isInSection(record)) {
+ return sectioner;
+ }
+ }
+ return null;
+ }
+
+ record FullyQualifiedGroupKey(int userId, String pkg, String groupName) {
+ FullyQualifiedGroupKey(int userId, String pkg, @Nullable NotificationSectioner sectioner) {
+ this(userId, pkg, AGGREGATE_GROUP_KEY + (sectioner != null ? sectioner.mName : ""));
+ }
+
+ @Override
+ public String toString() {
+ return userId + "|" + pkg + "|" + "g:" + groupName;
+ }
+ }
+
+ protected static class NotificationSectioner {
+ final String mName;
+ final int mSummaryId;
+ private final Predicate<NotificationRecord> mSectionChecker;
+
+ public NotificationSectioner(String name, int summaryId,
+ Predicate<NotificationRecord> sectionChecker) {
+ mName = name;
+ mSummaryId = summaryId;
+ mSectionChecker = sectionChecker;
+ }
+
+ boolean isInSection(final NotificationRecord record) {
+ return isNotificationGroupable(record) && mSectionChecker.test(record);
+ }
+
+ private boolean isNotificationGroupable(final NotificationRecord record) {
+ if (record.isConversation()) {
+ return false;
+ }
+
+ Notification notification = record.getSbn().getNotification();
+ boolean isColorizedFGS = notification.isForegroundService()
+ && notification.isColorized()
+ && record.getImportance() > NotificationManager.IMPORTANCE_MIN;
+ boolean isCall = record.getImportance() > NotificationManager.IMPORTANCE_MIN
+ && notification.isStyle(Notification.CallStyle.class);
+ if (isColorizedFGS || isCall) {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ record CachedSummary(int id, String tag, String originalGroupKey, String key) {}
+
protected static class NotificationAttributes {
public final int flags;
public final int iconColor;
public final Icon icon;
public final int visibility;
+ public final int groupAlertBehavior;
+ public final String channelId;
- public NotificationAttributes(int flags, Icon icon, int iconColor, int visibility) {
+ public NotificationAttributes(int flags, Icon icon, int iconColor, int visibility,
+ int groupAlertBehavior, String channelId) {
this.flags = flags;
this.icon = icon;
this.iconColor = iconColor;
this.visibility = visibility;
+ this.groupAlertBehavior = groupAlertBehavior;
+ this.channelId = channelId;
}
public NotificationAttributes(@NonNull NotificationAttributes attr) {
@@ -406,6 +1348,8 @@ public class GroupHelper {
this.icon = attr.icon;
this.iconColor = attr.iconColor;
this.visibility = attr.visibility;
+ this.groupAlertBehavior = attr.groupAlertBehavior;
+ this.channelId = attr.channelId;
}
@Override
@@ -417,22 +1361,39 @@ public class GroupHelper {
return false;
}
return flags == that.flags && iconColor == that.iconColor && icon.sameAs(that.icon)
- && visibility == that.visibility;
+ && visibility == that.visibility
+ && groupAlertBehavior == that.groupAlertBehavior
+ && channelId.equals(that.channelId);
}
@Override
public int hashCode() {
- return Objects.hash(flags, iconColor, icon, visibility);
+ return Objects.hash(flags, iconColor, icon, visibility, groupAlertBehavior, channelId);
+ }
+
+ @Override
+ public String toString() {
+ return "NotificationAttributes: flags: " + flags + " icon: " + icon + " color: "
+ + iconColor + " vis: " + visibility + " groupAlertBehavior: "
+ + groupAlertBehavior + " channelId: " + channelId;
}
}
protected interface Callback {
- void addAutoGroup(String key, boolean requestSort);
+ void addAutoGroup(String key, String groupName, boolean requestSort);
void removeAutoGroup(String key);
- void addAutoGroupSummary(int userId, String pkg, String triggeringKey,
+ void addAutoGroupSummary(int userId, String pkg, String triggeringKey, String groupName,
+ int summaryId, NotificationAttributes summaryAttr);
+ void removeAutoGroupSummary(int user, String pkg, String groupKey);
+
+ void updateAutogroupSummary(int userId, String pkg, String groupKey,
NotificationAttributes summaryAttr);
- void removeAutoGroupSummary(int user, String pkg);
- void updateAutogroupSummary(int userId, String pkg, NotificationAttributes summaryAttr);
+
+ // New callbacks for API abuse grouping
+ void removeAppProvidedSummary(String key);
+
+ void removeNotificationFromCanceledGroup(int userId, String pkg, String groupKey,
+ int cancelReason);
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java
index a7e14d9baea2..5a9cf0326244 100644
--- a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java
+++ b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java
@@ -138,6 +138,7 @@ public final class NotificationAttentionHelper {
private final boolean mUseAttentionLight;
boolean mHasLight;
+ private final boolean mEnableNotificationAccessibilityEvents;
private final SettingsObserver mSettingsObserver;
@@ -190,6 +191,9 @@ public final class NotificationAttentionHelper {
mUseAttentionLight = resources.getBoolean(R.bool.config_useAttentionLight);
mHasLight =
resources.getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed);
+ mEnableNotificationAccessibilityEvents =
+ resources.getBoolean(
+ com.android.internal.R.bool.config_enableNotificationAccessibilityEvents);
// Don't start allowing notifications until the setup wizard has run once.
// After that, including subsequent boots, init with notifications turned on.
@@ -604,6 +608,13 @@ public final class NotificationAttentionHelper {
}
}
+ // Suppressed because notification was explicitly flagged as silent
+ if (android.service.notification.Flags.notificationSilentFlag()) {
+ if (notification.isSilent()) {
+ return true;
+ }
+ }
+
// Suppressed for being too recently noisy
final String pkg = record.getSbn().getPackageName();
if (mUsageStats.isAlertRateLimited(pkg)) {
@@ -1023,7 +1034,7 @@ public final class NotificationAttentionHelper {
}
void sendAccessibilityEvent(NotificationRecord record) {
- if (!mAccessibilityManager.isEnabled()) {
+ if (!mAccessibilityManager.isEnabled() || !mEnableNotificationAccessibilityEvents) {
return;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a4f534eeba67..016abff88299 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -39,6 +39,7 @@ import static android.app.Notification.FLAG_AUTO_CANCEL;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
import static android.app.Notification.FLAG_FSI_REQUESTED_BUT_DENIED;
+import static android.app.Notification.FLAG_GROUP_SUMMARY;
import static android.app.Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
import static android.app.Notification.FLAG_NO_CLEAR;
import static android.app.Notification.FLAG_NO_DISMISS;
@@ -108,8 +109,9 @@ import static android.service.notification.Adjustment.TYPE_NEWS;
import static android.service.notification.Adjustment.TYPE_PROMOTION;
import static android.service.notification.Adjustment.TYPE_SOCIAL_MEDIA;
import static android.service.notification.Flags.callstyleCallbackApi;
-import static android.service.notification.Flags.redactSensitiveNotificationsFromUntrustedListeners;
+import static android.service.notification.Flags.notificationForceGrouping;
import static android.service.notification.Flags.redactSensitiveNotificationsBigTextStyle;
+import static android.service.notification.Flags.redactSensitiveNotificationsFromUntrustedListeners;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
@@ -246,7 +248,6 @@ import android.content.pm.UserInfo;
import android.content.pm.VersionedPackage;
import android.content.res.Resources;
import android.database.ContentObserver;
-import android.graphics.drawable.Icon;
import android.metrics.LogMaker;
import android.net.Uri;
import android.os.Binder;
@@ -512,6 +513,8 @@ public class NotificationManagerService extends SystemService {
private static final long DELAY_FOR_ASSISTANT_TIME = 200;
+ private static final long DELAY_FORCE_REGROUP_TIME = 3000;
+
private static final String ACTION_NOTIFICATION_TIMEOUT =
NotificationManagerService.class.getSimpleName() + ".TIMEOUT";
private static final int REQUEST_CODE_TIMEOUT = 1;
@@ -608,6 +611,9 @@ public class NotificationManagerService extends SystemService {
static final long NOTIFICATION_MAX_AGE_AT_POST = Duration.ofDays(14).toMillis();
+ // Minium number of sparse groups for a package before autogrouping them
+ private static final int AUTOGROUP_SPARSE_GROUPS_AT_COUNT = 3;
+
private IActivityManager mAm;
private ActivityTaskManagerInternal mAtm;
private ActivityManager mActivityManager;
@@ -1001,17 +1007,25 @@ public class NotificationManagerService extends SystemService {
* icons are different.
* @param userId user id of the autogroup summary
* @param pkg package of the autogroup summary
+ * @param groupKey group key of the autogroup summary
* @param summaryAttr the new flags and/or icon & color for this summary
* @param isAppForeground true if the app is currently in the foreground.
*/
@GuardedBy("mNotificationLock")
- protected void updateAutobundledSummaryLocked(int userId, String pkg,
- NotificationAttributes summaryAttr, boolean isAppForeground) {
+ protected void updateAutobundledSummaryLocked(int userId, String pkg, String groupKey,
+ NotificationAttributes summaryAttr, boolean isAppForeground) {
ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId);
if (summaries == null) {
return;
}
- String summaryKey = summaries.get(pkg);
+ final String autbundledGroupKey;
+ if (notificationForceGrouping()) {
+ autbundledGroupKey = groupKey;
+ } else {
+ autbundledGroupKey = pkg;
+ }
+
+ String summaryKey = summaries.get(autbundledGroupKey);
if (summaryKey == null) {
return;
}
@@ -1019,12 +1033,26 @@ public class NotificationManagerService extends SystemService {
if (summary == null) {
return;
}
+
int oldFlags = summary.getSbn().getNotification().flags;
boolean attributesUpdated =
!summaryAttr.icon.sameAs(summary.getSbn().getNotification().getSmallIcon())
|| summaryAttr.iconColor != summary.getSbn().getNotification().color
- || summaryAttr.visibility != summary.getSbn().getNotification().visibility;
+ || summaryAttr.visibility != summary.getSbn().getNotification().visibility
+ || summaryAttr.groupAlertBehavior !=
+ summary.getSbn().getNotification().getGroupAlertBehavior();
+
+ if (notificationForceGrouping()) {
+ if (!summary.getChannel().getId().equals(summaryAttr.channelId)) {
+ NotificationChannel newChannel = mPreferencesHelper.getNotificationChannel(pkg,
+ summary.getUid(), summaryAttr.channelId, false);
+ if (newChannel != null) {
+ summary.updateNotificationChannel(newChannel);
+ attributesUpdated = true;
+ }
+ }
+ }
if (oldFlags != summaryAttr.flags || attributesUpdated) {
summary.getSbn().getNotification().flags =
@@ -1032,6 +1060,8 @@ public class NotificationManagerService extends SystemService {
summary.getSbn().getNotification().setSmallIcon(summaryAttr.icon);
summary.getSbn().getNotification().color = summaryAttr.iconColor;
summary.getSbn().getNotification().visibility = summaryAttr.visibility;
+ summary.getSbn().getNotification()
+ .setGroupAlertBehavior(summaryAttr.groupAlertBehavior);
mHandler.post(new EnqueueNotificationRunnable(userId, summary, isAppForeground,
/* isAppProvided= */ false, mPostNotificationTrackerFactory.newTracker(null)));
}
@@ -2836,12 +2866,17 @@ public class NotificationManagerService extends SystemService {
mAutoGroupAtCount =
getContext().getResources().getInteger(R.integer.config_autoGroupAtCount);
return new GroupHelper(getContext(), getContext().getPackageManager(),
- mAutoGroupAtCount, new GroupHelper.Callback() {
+ mAutoGroupAtCount, AUTOGROUP_SPARSE_GROUPS_AT_COUNT, new GroupHelper.Callback() {
@Override
- public void addAutoGroup(String key, boolean requestSort) {
- synchronized (mNotificationLock) {
- addAutogroupKeyLocked(key, requestSort);
- }
+ public void addAutoGroup(String key, String groupName, boolean requestSort) {
+ synchronized (mNotificationLock) {
+ if (notificationForceGrouping()) {
+ convertSummaryToNotificationLocked(key);
+ addAutogroupKeyLocked(key, groupName, requestSort);
+ } else {
+ addAutogroupKeyLocked(key, groupName, requestSort);
+ }
+ }
}
@Override
@@ -2853,10 +2888,9 @@ public class NotificationManagerService extends SystemService {
@Override
public void addAutoGroupSummary(int userId, String pkg, String triggeringKey,
- NotificationAttributes summaryAttr) {
+ String groupName, int summaryId, NotificationAttributes summaryAttr) {
NotificationRecord r = createAutoGroupSummary(userId, pkg, triggeringKey,
- summaryAttr.flags, summaryAttr.icon, summaryAttr.iconColor,
- summaryAttr.visibility);
+ groupName, summaryId, summaryAttr);
if (r != null) {
final boolean isAppForeground =
mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
@@ -2867,19 +2901,56 @@ public class NotificationManagerService extends SystemService {
}
@Override
- public void removeAutoGroupSummary(int userId, String pkg) {
+ public void removeAutoGroupSummary(int userId, String pkg, String groupKey) {
synchronized (mNotificationLock) {
- clearAutogroupSummaryLocked(userId, pkg);
+ clearAutogroupSummaryLocked(userId, pkg, groupKey);
}
}
@Override
- public void updateAutogroupSummary(int userId, String pkg,
+ public void updateAutogroupSummary(int userId, String pkg, String groupKey,
NotificationAttributes summaryAttr) {
boolean isAppForeground = pkg != null
&& mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
synchronized (mNotificationLock) {
- updateAutobundledSummaryLocked(userId, pkg, summaryAttr, isAppForeground);
+ updateAutobundledSummaryLocked(userId, pkg, groupKey, summaryAttr,
+ isAppForeground);
+ }
+ }
+
+ @Override
+ public void removeAppProvidedSummary(String key) {
+ synchronized (mNotificationLock) {
+ removeAppSummaryLocked(key);
+ }
+ }
+
+ @Override
+ public void removeNotificationFromCanceledGroup(int userId, String pkg,
+ String groupKey, int cancelReason) {
+ synchronized (mNotificationLock) {
+ final int mustNotHaveFlags;
+ if (lifetimeExtensionRefactor()) {
+ // Also don't allow client apps to cancel lifetime extended notifs.
+ mustNotHaveFlags = (FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB
+ | FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY);
+ } else {
+ mustNotHaveFlags = (FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB);
+ }
+ FlagChecker childrenFlagChecker = (flags) -> {
+ if (cancelReason == REASON_CANCEL
+ || cancelReason == REASON_CLICK
+ || cancelReason == REASON_CANCEL_ALL) {
+ if ((flags & FLAG_BUBBLE) != 0) {
+ return false;
+ }
+ }
+ return (flags & mustNotHaveFlags) == 0;
+ };
+ cancelGroupChildrenLocked(userId, pkg, Binder.getCallingUid(),
+ Binder.getCallingPid(), null,
+ false, childrenFlagChecker, groupKey,
+ REASON_APP_CANCEL, SystemClock.elapsedRealtime());
}
}
});
@@ -3107,6 +3178,18 @@ public class NotificationManagerService extends SystemService {
modifiedChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
}
+ if (notificationForceGrouping()) {
+ final NotificationChannel updatedChannel = mPreferencesHelper.getNotificationChannel(
+ pkg, uid, channel.getId(), false);
+ mHandler.postDelayed(() -> {
+ synchronized (mNotificationLock) {
+ mGroupHelper.onChannelUpdated(
+ UserHandle.getUserHandleForUid(uid).getIdentifier(), pkg,
+ updatedChannel, mNotificationList);
+ }
+ }, DELAY_FORCE_REGROUP_TIME);
+ }
+
handleSavePolicyFile();
}
@@ -4549,29 +4632,28 @@ public class NotificationManagerService extends SystemService {
@Override
public List<String> getPackagesBypassingDnd(int userId,
- boolean includeConversationChannels) {
+ boolean includeConversationChannels) {
checkCallerIsSystem();
final ArraySet<String> packageNames = new ArraySet<>();
- for (int user : mUm.getProfileIds(userId, false)) {
- List<PackageInfo> pkgs = mPackageManagerClient.getInstalledPackagesAsUser(0, user);
- for (PackageInfo pi : pkgs) {
- String pkg = pi.packageName;
- // If any NotificationChannel for this package is bypassing, the
- // package is considered bypassing.
- for (NotificationChannel channel : getNotificationChannelsBypassingDnd(pkg,
- pi.applicationInfo.uid).getList()) {
- // Skips non-demoted conversation channels.
- if (!includeConversationChannels
- && !TextUtils.isEmpty(channel.getConversationId())
- && !channel.isDemoted()) {
- continue;
- }
- packageNames.add(pkg);
+ List<PackageInfo> pkgs = mPackageManagerClient.getInstalledPackagesAsUser(0, userId);
+ for (PackageInfo pi : pkgs) {
+ String pkg = pi.packageName;
+ // If any NotificationChannel for this package is bypassing, the
+ // package is considered bypassing.
+ for (NotificationChannel channel : getNotificationChannelsBypassingDnd(pkg,
+ pi.applicationInfo.uid).getList()) {
+ // Skips non-demoted conversation channels.
+ if (!includeConversationChannels
+ && !TextUtils.isEmpty(channel.getConversationId())
+ && !channel.isDemoted()) {
+ continue;
}
+ packageNames.add(pkg);
}
}
+
return new ArrayList<String>(packageNames);
}
@@ -6652,18 +6734,33 @@ public class NotificationManagerService extends SystemService {
}
}
+ @SuppressWarnings("GuardedBy")
@GuardedBy("mNotificationLock")
- void addAutogroupKeyLocked(String key, boolean requestSort) {
+ void addAutogroupKeyLocked(String key, String groupName, boolean requestSort) {
NotificationRecord r = mNotificationsByKey.get(key);
if (r == null) {
return;
}
if (r.getSbn().getOverrideGroupKey() == null) {
- addAutoGroupAdjustment(r, GroupHelper.AUTOGROUP_KEY);
+ if (notificationForceGrouping()) {
+ if (r.getSbn().isAppGroup()) {
+ // Override group key early for forced grouped notifications
+ r.setOverrideGroupKey(groupName);
+ }
+ }
+
+ addAutoGroupAdjustment(r, groupName);
EventLogTags.writeNotificationAutogrouped(key);
+
if (!android.app.Flags.checkAutogroupBeforePost() || requestSort) {
mRankingHandler.requestSort();
}
+
+ if (notificationForceGrouping()) {
+ if (r.getSbn().isAppGroup()) {
+ mListeners.notifyPostedLocked(r, r);
+ }
+ }
}
}
@@ -6692,27 +6789,57 @@ public class NotificationManagerService extends SystemService {
// Clears the 'fake' auto-group summary.
@VisibleForTesting
@GuardedBy("mNotificationLock")
- void clearAutogroupSummaryLocked(int userId, String pkg) {
+ void clearAutogroupSummaryLocked(int userId, String pkg, String groupKey) {
+ final String autbundledGroupKey;
+ if (notificationForceGrouping()) {
+ autbundledGroupKey = groupKey;
+ } else {
+ autbundledGroupKey = pkg;
+ }
ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId);
- if (summaries != null && summaries.containsKey(pkg)) {
- final NotificationRecord removed = findNotificationByKeyLocked(summaries.remove(pkg));
+ if (summaries != null && summaries.containsKey(autbundledGroupKey)) {
+ final NotificationRecord removed = findNotificationByKeyLocked(
+ summaries.remove(autbundledGroupKey));
if (removed != null) {
final StatusBarNotification sbn = removed.getSbn();
cancelNotification(MY_UID, MY_PID, pkg, sbn.getTag(), sbn.getId(), 0, 0, false,
- userId, REASON_UNAUTOBUNDLED, null);
+ userId, REASON_UNAUTOBUNDLED, null);
}
}
}
@GuardedBy("mNotificationLock")
- private boolean hasAutoGroupSummaryLocked(StatusBarNotification sbn) {
- ArrayMap<String, String> summaries = mAutobundledSummaries.get(sbn.getUserId());
- return summaries != null && summaries.containsKey(sbn.getPackageName());
+ void removeAppSummaryLocked(String key) {
+ NotificationRecord r = mNotificationsByKey.get(key);
+ if (r == null) {
+ return;
+ }
+ if (convertSummaryToNotificationLocked(key)) {
+ r.isCanceled = true;
+ cancelNotification(Binder.getCallingUid(),
+ Binder.getCallingPid(), r.getSbn().getPackageName(),
+ r.getSbn().getTag(), r.getSbn().getId(), 0, 0,
+ false, r.getUserId(),
+ NotificationListenerService.REASON_GROUP_OPTIMIZATION, null);
+ }
+ }
+
+ @GuardedBy("mNotificationLock")
+ private boolean hasAutoGroupSummaryLocked(NotificationRecord record) {
+ final String autbundledGroupKey;
+ if (notificationForceGrouping()) {
+ autbundledGroupKey = GroupHelper.getFullAggregateGroupKey(record);
+ } else {
+ autbundledGroupKey = record.getSbn().getPackageName();
+ }
+
+ ArrayMap<String, String> summaries = mAutobundledSummaries.get(record.getUserId());
+ return summaries != null && summaries.containsKey(autbundledGroupKey);
}
// Creates a 'fake' summary for a package that has exceeded the solo-notification limit.
NotificationRecord createAutoGroupSummary(int userId, String pkg, String triggeringKey,
- int flagsToSet, Icon summaryIcon, int summaryIconColor, int summaryVisibilty) {
+ String groupKey, int summaryId, NotificationAttributes summaryAttr) {
NotificationRecord summaryRecord = null;
boolean isPermissionFixed = mPermissionHelper.isPermissionFixed(pkg, userId);
synchronized (mNotificationLock) {
@@ -6730,24 +6857,35 @@ public class NotificationManagerService extends SystemService {
summaries = new ArrayMap<>();
}
mAutobundledSummaries.put(userId, summaries);
- if (!summaries.containsKey(pkg)) {
+
+ boolean hasSummary;
+ String channelId;
+ if (notificationForceGrouping()) {
+ hasSummary = summaries.containsKey(groupKey);
+ channelId = summaryAttr.channelId;
+ } else {
+ hasSummary = summaries.containsKey(pkg);
+ channelId = notificationRecord.getChannel().getId();
+ }
+
+ if (!hasSummary) {
// Add summary
final ApplicationInfo appInfo =
adjustedSbn.getNotification().extras.getParcelable(
EXTRA_BUILDER_APPLICATION_INFO, ApplicationInfo.class);
final Bundle extras = new Bundle();
extras.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, appInfo);
- final String channelId = notificationRecord.getChannel().getId();
+
final Notification summaryNotification =
new Notification.Builder(getContext(), channelId)
- .setSmallIcon(summaryIcon)
+ .setSmallIcon(summaryAttr.icon)
.setGroupSummary(true)
- .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN)
- .setGroup(GroupHelper.AUTOGROUP_KEY)
- .setFlag(flagsToSet, true)
- .setColor(summaryIconColor)
- .setVisibility(summaryVisibilty)
+ .setGroupAlertBehavior(summaryAttr.groupAlertBehavior)
+ .setGroup(groupKey)
+ .setFlag(summaryAttr.flags, true)
+ .setColor(summaryAttr.iconColor)
+ .setVisibility(summaryAttr.visibility)
.build();
summaryNotification.extras.putAll(extras);
Intent appIntent = getContext().getPackageManager().getLaunchIntentForPackage(pkg);
@@ -6759,17 +6897,22 @@ public class NotificationManagerService extends SystemService {
final StatusBarNotification summarySbn =
new StatusBarNotification(adjustedSbn.getPackageName(),
adjustedSbn.getOpPkg(),
- Integer.MAX_VALUE,
- GroupHelper.AUTOGROUP_KEY, adjustedSbn.getUid(),
+ summaryId,
+ groupKey, adjustedSbn.getUid(),
adjustedSbn.getInitialPid(), summaryNotification,
- adjustedSbn.getUser(), GroupHelper.AUTOGROUP_KEY,
+ adjustedSbn.getUser(), groupKey,
System.currentTimeMillis());
summaryRecord = new NotificationRecord(getContext(), summarySbn,
notificationRecord.getChannel());
summaryRecord.setImportanceFixed(isPermissionFixed);
summaryRecord.setIsAppImportanceLocked(
notificationRecord.getIsAppImportanceLocked());
- summaries.put(pkg, summarySbn.getKey());
+
+ if (notificationForceGrouping()) {
+ summaries.put(summarySbn.getGroupKey(), summarySbn.getKey());
+ } else {
+ summaries.put(pkg, summarySbn.getKey());
+ }
}
if (summaryRecord != null && checkDisqualifyingFeatures(userId, uid,
summaryRecord.getSbn().getId(), summaryRecord.getSbn().getTag(), summaryRecord,
@@ -6780,6 +6923,27 @@ public class NotificationManagerService extends SystemService {
return null;
}
+ @GuardedBy("mNotificationLock")
+ boolean convertSummaryToNotificationLocked(final String key) {
+ NotificationRecord r = mNotificationsByKey.get(key);
+ if (r == null) {
+ return false;
+ }
+ // Convert summary to regular notification
+ if (r.getSbn().isAppGroup() && r.getNotification().isGroupSummary()) {
+ String oldGroupKey = r.getGroupKey();
+ NotificationRecord groupSummary = mSummaryByGroupKey.get(oldGroupKey);
+ if (groupSummary != null && groupSummary.getKey().equals(r.getKey())) {
+ mSummaryByGroupKey.remove(oldGroupKey);
+ }
+ // Clear summary flag
+ StatusBarNotification sbn = r.getSbn();
+ sbn.getNotification().flags = (r.mOriginalFlags & ~FLAG_GROUP_SUMMARY);
+ return true;
+ }
+ return false;
+ }
+
// Gets packages that have requested notification permission, and whether that has been
// allowed/denied, for all users on the device.
// Returns a single map containing that info keyed by (uid, package name) for all users.
@@ -7794,6 +7958,10 @@ public class NotificationManagerService extends SystemService {
notification.setTimeoutAfter(NOTIFICATION_TTL);
}
}
+
+ if (notificationForceGrouping()) {
+ notification.fixSilentGroup();
+ }
}
/**
@@ -8347,8 +8515,15 @@ public class NotificationManagerService extends SystemService {
* They will be recreated as needed when the group children are unsnoozed
*/
private boolean isSnoozable(NotificationRecord record) {
- return !(record.getNotification().isGroupSummary() && GroupHelper.AUTOGROUP_KEY.equals(
- record.getNotification().getGroup()));
+ if (notificationForceGrouping()) {
+ boolean isExemptedSummary =
+ ((record.getFlags() & FLAG_AUTOGROUP_SUMMARY) != 0
+ || GroupHelper.isAggregatedGroup(record));
+ return !(record.getNotification().isGroupSummary() && isExemptedSummary);
+ } else {
+ return !(record.getNotification().isGroupSummary()
+ && GroupHelper.AUTOGROUP_KEY.equals(record.getNotification().getGroup()));
+ }
}
}
@@ -8471,16 +8646,26 @@ public class NotificationManagerService extends SystemService {
cancelNotificationLocked(
r, mSendDelete, mReason, mRank, mCount, wasPosted, listenerName,
mCancellationElapsedTimeMs);
- cancelGroupChildrenLocked(r, mCallingUid, mCallingPid, listenerName,
- mSendDelete, childrenFlagChecker, mReason,
- mCancellationElapsedTimeMs);
+ if (r.getNotification().isGroupSummary()) {
+ cancelGroupChildrenLocked(mUserId, mPkg, mCallingUid, mCallingPid,
+ listenerName, mSendDelete, childrenFlagChecker,
+ r.getNotification().getGroup(), mReason,
+ mCancellationElapsedTimeMs);
+ }
mAttentionHelper.updateLightsLocked();
if (mShortcutHelper != null) {
mShortcutHelper.maybeListenForShortcutChangesForBubbles(r,
- true /* isRemoved */,
- mHandler);
+ true /* isRemoved */);
}
} else {
+ if (notificationForceGrouping()) {
+ // No notification was found => maybe it was canceled by forced grouping
+ if (Flags.notificationForceGroupSingletons()) {
+ mGroupHelper.maybeCancelGroupChildrenForCanceledSummary(mPkg, mTag,
+ mId, mUserId, mReason);
+ }
+ }
+
// No notification was found, assume that it is snoozed and cancel it.
if (mReason != REASON_SNOOZED) {
final boolean wasSnoozed = mSnoozeHelper.cancel(mUserId, mPkg, mTag, mId);
@@ -8708,7 +8893,7 @@ public class NotificationManagerService extends SystemService {
boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid);
boolean isCallNotification = isCallNotification(pkg, uid);
boolean posted = false;
- synchronized (mNotificationLock) {
+ synchronized (NotificationManagerService.this.mNotificationLock) {
try {
NotificationRecord r = findNotificationByListLocked(mEnqueuedNotifications,
key);
@@ -8731,6 +8916,29 @@ public class NotificationManagerService extends SystemService {
return false;
}
+ if (notificationForceGrouping()) {
+ if (Flags.notificationForceGroupSingletons()) {
+ // Check if this is an updated for a summary for an aggregated sparse
+ // group and remove it because that summary has been canceled
+ if (mGroupHelper.isUpdateForCanceledSummary(r)) {
+ if (DBG) {
+ Log.w(TAG,
+ "Suppressing notification because summary was canceled: "
+ + r);
+ }
+
+ String groupKey = r.getGroupKey();
+ NotificationRecord groupSummary = mSummaryByGroupKey.get(groupKey);
+ if (groupSummary != null && groupSummary.getKey()
+ .equals(r.getKey())) {
+ mSummaryByGroupKey.remove(groupKey);
+ }
+ return false;
+ }
+ }
+ }
+
+
final boolean isPackageSuspended =
isPackagePausedOrSuspended(r.getSbn().getPackageName(), r.getUid());
r.setHidden(isPackageSuspended);
@@ -8788,18 +8996,38 @@ public class NotificationManagerService extends SystemService {
if (notification.getSmallIcon() != null && !isCritical(r)) {
StatusBarNotification oldSbn = (old != null) ? old.getSbn() : null;
if (oldSbn == null || !Objects.equals(oldSbn.getGroup(), n.getGroup())
+ || !Objects.equals(oldSbn.getNotification().getGroup(),
+ n.getNotification().getGroup())
|| oldSbn.getNotification().flags
!= n.getNotification().flags) {
synchronized (mNotificationLock) {
- boolean willBeAutogrouped = mGroupHelper.onNotificationPosted(n,
- hasAutoGroupSummaryLocked(n));
+ final String autogroupName =
+ notificationForceGrouping() ?
+ GroupHelper.getFullAggregateGroupKey(r)
+ : GroupHelper.AUTOGROUP_KEY;
+ boolean willBeAutogrouped =
+ mGroupHelper.onNotificationPosted(r,
+ hasAutoGroupSummaryLocked(r));
if (willBeAutogrouped) {
// The newly posted notification will be autogrouped, but
// was not autogrouped onPost, to avoid an unnecessary sort.
// We add the autogroup key to the notification without a
// sort here, and it'll be sorted below with extractSignals.
- addAutogroupKeyLocked(key, /* requestSort= */false);
+ addAutogroupKeyLocked(key,
+ autogroupName, /*requestSort=*/false);
+ } else {
+ if (notificationForceGrouping()) {
+ // Wait 3 seconds so that the app has a chance to post
+ // a group summary or children (complete a group)
+ mHandler.postDelayed(() -> {
+ synchronized (mNotificationLock) {
+ mGroupHelper.onNotificationPostedWithDelay(
+ r, mNotificationList, mSummaryByGroupKey);
+ }
+ }, r.getKey(), DELAY_FORCE_REGROUP_TIME);
+ }
}
+
}
}
}
@@ -8835,9 +9063,18 @@ public class NotificationManagerService extends SystemService {
mHandler.post(() -> {
synchronized (mNotificationLock) {
mGroupHelper.onNotificationPosted(
- n, hasAutoGroupSummaryLocked(n));
+ r, hasAutoGroupSummaryLocked(r));
}
});
+
+ if (notificationForceGrouping()) {
+ mHandler.postDelayed(() -> {
+ synchronized (mNotificationLock) {
+ mGroupHelper.onNotificationPostedWithDelay(r,
+ mNotificationList, mSummaryByGroupKey);
+ }
+ }, r.getKey(), DELAY_FORCE_REGROUP_TIME);
+ }
}
}
}
@@ -8846,12 +9083,20 @@ public class NotificationManagerService extends SystemService {
if (old != null && !old.isCanceled) {
mListeners.notifyRemovedLocked(r,
REASON_ERROR, r.getStats());
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mGroupHelper.onNotificationRemoved(n);
- }
- });
+ if (notificationForceGrouping()) {
+ mHandler.post(() -> {
+ synchronized (mNotificationLock) {
+ mGroupHelper.onNotificationRemoved(r, mNotificationList);
+ }
+ });
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mGroupHelper.onNotificationRemoved(r);
+ }
+ });
+ }
}
if (callstyleCallbackApi()) {
@@ -8867,8 +9112,7 @@ public class NotificationManagerService extends SystemService {
if (mShortcutHelper != null) {
mShortcutHelper.maybeListenForShortcutChangesForBubbles(r,
- false /* isRemoved */,
- mHandler);
+ false /* isRemoved */);
}
maybeRecordInterruptionLocked(r);
@@ -9082,6 +9326,18 @@ public class NotificationManagerService extends SystemService {
n.flags &= ~Notification.FLAG_GROUP_SUMMARY;
}
+ if (notificationForceGrouping()) {
+ if (old != null) {
+ // If this is an update to a summary that was forced grouped => remove summary flag
+ boolean wasSummary = (old.mOriginalFlags & FLAG_GROUP_SUMMARY) != 0;
+ boolean wasForcedGrouped = (old.getFlags() & FLAG_GROUP_SUMMARY) == 0
+ && old.getSbn().getOverrideGroupKey() != null;
+ if (n.isGroupSummary() && wasSummary && wasForcedGrouped) {
+ n.flags &= ~FLAG_GROUP_SUMMARY;
+ }
+ }
+ }
+
String group = sbn.getGroupKey();
boolean isSummary = n.isGroupSummary();
@@ -9114,8 +9370,10 @@ public class NotificationManagerService extends SystemService {
// notification was a summary and the new one isn't, or when the old
// notification was a summary and its group key changed.
if (oldIsSummary && (!isSummary || !oldGroup.equals(group))) {
- cancelGroupChildrenLocked(old, callingUid, callingPid, null, false /* sendDelete */,
- childrenFlagChecker, REASON_APP_CANCEL, SystemClock.elapsedRealtime());
+ cancelGroupChildrenLocked(old.getUserId(), old.getSbn().getPackageName(), callingUid,
+ callingPid, null, false /* sendDelete */, childrenFlagChecker,
+ old.getNotification().getGroup(), REASON_APP_CANCEL,
+ SystemClock.elapsedRealtime());
}
}
@@ -9777,12 +10035,21 @@ public class NotificationManagerService extends SystemService {
r.isCanceled = true;
}
mListeners.notifyRemovedLocked(r, reason, r.getStats());
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mGroupHelper.onNotificationRemoved(r.getSbn());
- }
- });
+ if (notificationForceGrouping()) {
+ mHandler.removeCallbacksAndMessages(r.getKey());
+ mHandler.post(() -> {
+ synchronized (NotificationManagerService.this.mNotificationLock) {
+ mGroupHelper.onNotificationRemoved(r, mNotificationList);
+ }
+ });
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mGroupHelper.onNotificationRemoved(r);
+ }
+ });
+ }
if (callstyleCallbackApi()) {
notifyCallNotificationEventListenerOnRemoved(r);
}
@@ -9815,9 +10082,15 @@ public class NotificationManagerService extends SystemService {
}
final ArrayMap<String, String> summaries =
mAutobundledSummaries.get(r.getSbn().getUserId());
+ final String autbundledGroupKey;
+ if (notificationForceGrouping()) {
+ autbundledGroupKey = groupKey;
+ } else {
+ autbundledGroupKey = r.getSbn().getPackageName();
+ }
if (summaries != null && r.getSbn().getKey().equals(
- summaries.get(r.getSbn().getPackageName()))) {
- summaries.remove(r.getSbn().getPackageName());
+ summaries.get(autbundledGroupKey))) {
+ summaries.remove(autbundledGroupKey);
}
// Save it for users of getHistoricalNotifications(), unless the whole channel was deleted
@@ -10081,6 +10354,15 @@ public class NotificationManagerService extends SystemService {
public boolean apply(int flags);
}
+ private static boolean isChildOfGroup(final NotificationRecord childRecord, int userId,
+ String pkg, String groupKey) {
+ return (childRecord.getUser().getIdentifier() == userId
+ && childRecord.getSbn().getPackageName().equals(pkg)
+ && childRecord.getSbn().isGroup()
+ && !childRecord.getNotification().isGroupSummary()
+ && TextUtils.equals(groupKey, childRecord.getNotification().getGroup()));
+ }
+
@GuardedBy("mNotificationLock")
private void cancelAllNotificationsByListLocked(ArrayList<NotificationRecord> notificationList,
@Nullable String pkg, boolean nullPkgIndicatesUserSwitch, @Nullable String channelId,
@@ -10238,43 +10520,34 @@ public class NotificationManagerService extends SystemService {
// Warning: The caller is responsible for invoking updateLightsLocked().
@GuardedBy("mNotificationLock")
- private void cancelGroupChildrenLocked(NotificationRecord r, int callingUid, int callingPid,
- String listenerName, boolean sendDelete, FlagChecker flagChecker, int reason,
- @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
- Notification n = r.getNotification();
- if (!n.isGroupSummary()) {
- return;
- }
-
- String pkg = r.getSbn().getPackageName();
-
+ private void cancelGroupChildrenLocked(int userId, String pkg, int callingUid, int callingPid,
+ String listenerName, boolean sendDelete, FlagChecker flagChecker, String groupKey,
+ int reason, @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
if (pkg == null) {
- if (DBG) Slog.e(TAG, "No package for group summary: " + r.getKey());
+ if (DBG) Slog.e(TAG, "No package for group summary");
return;
}
- cancelGroupChildrenByListLocked(mNotificationList, r, callingUid, callingPid, listenerName,
- sendDelete, true, flagChecker, reason, cancellationElapsedTimeMs);
- cancelGroupChildrenByListLocked(mEnqueuedNotifications, r, callingUid, callingPid,
- listenerName, sendDelete, false, flagChecker, reason, cancellationElapsedTimeMs);
+ cancelGroupChildrenByListLocked(mNotificationList, userId, pkg, callingUid, callingPid,
+ listenerName, sendDelete, true, flagChecker, groupKey,
+ reason, cancellationElapsedTimeMs);
+ cancelGroupChildrenByListLocked(mEnqueuedNotifications, userId, pkg, callingUid, callingPid,
+ listenerName, sendDelete, false, flagChecker, groupKey,
+ reason, cancellationElapsedTimeMs);
}
@GuardedBy("mNotificationLock")
private void cancelGroupChildrenByListLocked(ArrayList<NotificationRecord> notificationList,
- NotificationRecord parentNotification, int callingUid, int callingPid,
+ int userId, String pkg, int callingUid, int callingPid,
String listenerName, boolean sendDelete, boolean wasPosted, FlagChecker flagChecker,
- int reason, @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
- final String pkg = parentNotification.getSbn().getPackageName();
- final int userId = parentNotification.getUserId();
+ String groupKey, int reason, @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
final int childReason = REASON_GROUP_SUMMARY_CANCELED;
for (int i = notificationList.size() - 1; i >= 0; i--) {
final NotificationRecord childR = notificationList.get(i);
final StatusBarNotification childSbn = childR.getSbn();
- if ((childSbn.isGroup() && !childSbn.getNotification().isGroupSummary()) &&
- childR.getGroupKey().equals(parentNotification.getGroupKey())
- && (flagChecker == null || flagChecker.apply(childR.getFlags()))
- && (!childR.getChannel().isImportantConversation()
- || reason != REASON_CANCEL)) {
+ if (isChildOfGroup(childR, userId, pkg, groupKey)
+ && (flagChecker == null || flagChecker.apply(childR.getFlags()))
+ && (!childR.getChannel().isImportantConversation() || reason != REASON_CANCEL)) {
EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, childSbn.getId(),
childSbn.getTag(), userId, 0, 0, childReason, listenerName);
notificationList.remove(i);
@@ -10354,6 +10627,7 @@ public class NotificationManagerService extends SystemService {
!= null) {
return r;
}
+
return null;
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 0d4bdf663679..bd009010a313 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -449,9 +449,16 @@ public final class NotificationRecord {
mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs());
mCreationTimeMs = previous.mCreationTimeMs;
mVisibleSinceMs = previous.mVisibleSinceMs;
- if (previous.getSbn().getOverrideGroupKey() != null && !getSbn().isAppGroup()) {
- getSbn().setOverrideGroupKey(previous.getSbn().getOverrideGroupKey());
+ if (android.service.notification.Flags.notificationForceGrouping()) {
+ if (previous.getSbn().getOverrideGroupKey() != null) {
+ getSbn().setOverrideGroupKey(previous.getSbn().getOverrideGroupKey());
+ }
+ } else {
+ if (previous.getSbn().getOverrideGroupKey() != null && !getSbn().isAppGroup()) {
+ getSbn().setOverrideGroupKey(previous.getSbn().getOverrideGroupKey());
+ }
}
+
// Don't copy importance information or mGlobalSortKey, recompute them.
}
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 9ee05d8759b2..c09504fa36c8 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -17,7 +17,11 @@
package com.android.server.notification;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import static android.app.NotificationChannel.NEWS_ID;
import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
+import static android.app.NotificationChannel.PROMOTIONS_ID;
+import static android.app.NotificationChannel.RECS_ID;
+import static android.app.NotificationChannel.SOCIAL_MEDIA_ID;
import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
@@ -192,9 +196,12 @@ public class PreferencesHelper implements RankingConfig {
int USER_LOCKED_BUBBLE = 0x00000002;
}
+ private final Object mLock = new Object();
// pkg|uid => PackagePreferences
+ @GuardedBy("mLock")
private final ArrayMap<String, PackagePreferences> mPackagePreferences = new ArrayMap<>();
// pkg|userId => PackagePreferences
+ @GuardedBy("mLock")
private final ArrayMap<String, PackagePreferences> mRestoredWithoutUids = new ArrayMap<>();
private final Context mContext;
@@ -266,7 +273,7 @@ public class PreferencesHelper implements RankingConfig {
Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW);
}
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
tag = parser.getName();
if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) {
@@ -488,6 +495,7 @@ public class PreferencesHelper implements RankingConfig {
DEFAULT_BUBBLE_PREFERENCE, mClock.millis());
}
+ @GuardedBy("mLock")
private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg,
@UserIdInt int userId, int uid, int importance, int priority, int visibility,
boolean showBadge, int bubblePreference, long creationTime) {
@@ -657,7 +665,7 @@ public class PreferencesHelper implements RankingConfig {
notifPermissions = mPermissionHelper.getNotificationPermissionValues(userId);
}
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
final int N = mPackagePreferences.size();
for (int i = 0; i < N; i++) {
final PackagePreferences r = mPackagePreferences.valueAt(i);
@@ -666,11 +674,10 @@ public class PreferencesHelper implements RankingConfig {
}
writePackageXml(r, out, notifPermissions, forBackup);
}
- }
- if (Flags.persistIncompleteRestoreData() && !forBackup) {
- synchronized (mRestoredWithoutUids) {
- final int N = mRestoredWithoutUids.size();
- for (int i = 0; i < N; i++) {
+
+ if (Flags.persistIncompleteRestoreData() && !forBackup) {
+ final int M = mRestoredWithoutUids.size();
+ for (int i = 0; i < M; i++) {
final PackagePreferences r = mRestoredWithoutUids.valueAt(i);
writePackageXml(r, out, notifPermissions, false);
}
@@ -773,7 +780,7 @@ public class PreferencesHelper implements RankingConfig {
*/
public void setBubblesAllowed(String pkg, int uid, int bubblePreference) {
boolean changed;
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences p = getOrCreatePackagePreferencesLocked(pkg, uid);
changed = p.bubblePreference != bubblePreference;
p.bubblePreference = bubblePreference;
@@ -793,20 +800,20 @@ public class PreferencesHelper implements RankingConfig {
*/
@Override
public int getBubblePreference(String pkg, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
return getOrCreatePackagePreferencesLocked(pkg, uid).bubblePreference;
}
}
public int getAppLockedFields(String pkg, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
return getOrCreatePackagePreferencesLocked(pkg, uid).lockedAppFields;
}
}
@Override
public boolean canShowBadge(String packageName, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
return getOrCreatePackagePreferencesLocked(packageName, uid).showBadge;
}
}
@@ -814,7 +821,7 @@ public class PreferencesHelper implements RankingConfig {
@Override
public void setShowBadge(String packageName, int uid, boolean showBadge) {
boolean changed = false;
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences pkgPrefs = getOrCreatePackagePreferencesLocked(packageName, uid);
if (pkgPrefs.showBadge != showBadge) {
pkgPrefs.showBadge = showBadge;
@@ -827,28 +834,28 @@ public class PreferencesHelper implements RankingConfig {
}
public boolean isInInvalidMsgState(String packageName, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
return r.hasSentInvalidMessage && !r.hasSentValidMessage;
}
}
public boolean hasUserDemotedInvalidMsgApp(String packageName, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
return isInInvalidMsgState(packageName, uid) ? r.userDemotedMsgApp : false;
}
}
public void setInvalidMsgAppDemoted(String packageName, int uid, boolean isDemoted) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
r.userDemotedMsgApp = isDemoted;
}
}
public boolean setInvalidMessageSent(String packageName, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
boolean valueChanged = r.hasSentInvalidMessage == false;
r.hasSentInvalidMessage = true;
@@ -858,7 +865,7 @@ public class PreferencesHelper implements RankingConfig {
}
public boolean setValidMessageSent(String packageName, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
boolean valueChanged = r.hasSentValidMessage == false;
r.hasSentValidMessage = true;
@@ -869,7 +876,7 @@ public class PreferencesHelper implements RankingConfig {
@VisibleForTesting
boolean hasSentInvalidMsg(String packageName, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
return r.hasSentInvalidMessage;
}
@@ -877,7 +884,7 @@ public class PreferencesHelper implements RankingConfig {
@VisibleForTesting
boolean hasSentValidMsg(String packageName, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
return r.hasSentValidMessage;
}
@@ -885,7 +892,7 @@ public class PreferencesHelper implements RankingConfig {
@VisibleForTesting
boolean didUserEverDemoteInvalidMsgApp(String packageName, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
return r.userDemotedMsgApp;
}
@@ -893,7 +900,7 @@ public class PreferencesHelper implements RankingConfig {
/** Sets whether this package has sent a notification with valid bubble metadata. */
public boolean setValidBubbleSent(String packageName, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
boolean valueChanged = !r.hasSentValidBubble;
r.hasSentValidBubble = true;
@@ -902,14 +909,14 @@ public class PreferencesHelper implements RankingConfig {
}
boolean hasSentValidBubble(String packageName, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
return r.hasSentValidBubble;
}
}
boolean isImportanceLocked(String pkg, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
return r.fixedImportance || r.defaultAppLockedImportance;
}
@@ -920,7 +927,7 @@ public class PreferencesHelper implements RankingConfig {
if (groupId == null) {
return false;
}
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
NotificationChannelGroup group = r.groups.get(groupId);
if (group == null) {
@@ -931,13 +938,13 @@ public class PreferencesHelper implements RankingConfig {
}
int getPackagePriority(String pkg, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
return getOrCreatePackagePreferencesLocked(pkg, uid).priority;
}
}
int getPackageVisibility(String pkg, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
return getOrCreatePackagePreferencesLocked(pkg, uid).visibility;
}
}
@@ -952,7 +959,7 @@ public class PreferencesHelper implements RankingConfig {
throw new IllegalArgumentException("group.getName() can't be empty");
}
boolean needsDndChange = false;
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
if (r == null) {
throw new IllegalArgumentException("Invalid package");
@@ -1006,7 +1013,7 @@ public class PreferencesHelper implements RankingConfig {
&& channel.getImportance() <= IMPORTANCE_MAX, "Invalid importance level");
boolean needsPolicyFileChange = false, wasUndeleted = false, needsDndChange = false;
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
if (r == null) {
throw new IllegalArgumentException("Invalid package");
@@ -1150,7 +1157,7 @@ public class PreferencesHelper implements RankingConfig {
void unlockNotificationChannelImportance(String pkg, int uid, String updatedChannelId) {
Objects.requireNonNull(updatedChannelId);
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
if (r == null) {
throw new IllegalArgumentException("Invalid package");
@@ -1172,7 +1179,7 @@ public class PreferencesHelper implements RankingConfig {
Objects.requireNonNull(updatedChannel.getId());
boolean changed = false;
boolean needsDndChange = false;
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
if (r == null) {
throw new IllegalArgumentException("Invalid package");
@@ -1347,7 +1354,7 @@ public class PreferencesHelper implements RankingConfig {
String channelId, String conversationId, boolean returnParentIfNoConversationChannel,
boolean includeDeleted) {
Preconditions.checkNotNull(pkg);
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
if (r == null) {
return null;
@@ -1388,7 +1395,7 @@ public class PreferencesHelper implements RankingConfig {
Preconditions.checkNotNull(pkg);
Preconditions.checkNotNull(conversationId);
List<NotificationChannel> channels = new ArrayList<>();
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
if (r == null) {
return channels;
@@ -1408,7 +1415,7 @@ public class PreferencesHelper implements RankingConfig {
int callingUid, boolean fromSystemOrSystemUi) {
boolean deletedChannel = false;
boolean channelBypassedDnd = false;
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return false;
@@ -1444,7 +1451,7 @@ public class PreferencesHelper implements RankingConfig {
public void permanentlyDeleteNotificationChannel(String pkg, int uid, String channelId) {
Objects.requireNonNull(pkg);
Objects.requireNonNull(channelId);
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return;
@@ -1456,7 +1463,7 @@ public class PreferencesHelper implements RankingConfig {
@Override
public void permanentlyDeleteNotificationChannels(String pkg, int uid) {
Objects.requireNonNull(pkg);
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return;
@@ -1487,7 +1494,7 @@ public class PreferencesHelper implements RankingConfig {
boolean fixed = mPermissionHelper.isPermissionFixed(
pi.packageName, user.getUserHandle().getIdentifier());
if (fixed) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences p = getOrCreatePackagePreferencesLocked(
pi.packageName, pi.applicationInfo.uid);
p.fixedImportance = true;
@@ -1502,7 +1509,7 @@ public class PreferencesHelper implements RankingConfig {
public void updateDefaultApps(int userId, ArraySet<String> toRemove,
ArraySet<Pair<String, Integer>> toAdd) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
for (PackagePreferences p : mPackagePreferences.values()) {
if (userId == UserHandle.getUserId(p.uid)) {
if (toRemove != null && toRemove.contains(p.pkg)) {
@@ -1532,7 +1539,7 @@ public class PreferencesHelper implements RankingConfig {
public NotificationChannelGroup getNotificationChannelGroupWithChannels(String pkg,
int uid, String groupId, boolean includeDeleted) {
Objects.requireNonNull(pkg);
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null || groupId == null || !r.groups.containsKey(groupId)) {
return null;
@@ -1555,7 +1562,7 @@ public class PreferencesHelper implements RankingConfig {
public NotificationChannelGroup getNotificationChannelGroup(String groupId, String pkg,
int uid) {
Objects.requireNonNull(pkg);
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return null;
@@ -1569,7 +1576,7 @@ public class PreferencesHelper implements RankingConfig {
boolean includeBlocked, Set<String> activeChannelFilter) {
Objects.requireNonNull(pkg);
Map<String, NotificationChannelGroup> groups = new ArrayMap<>();
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return ParceledListSlice.emptyList();
@@ -1581,7 +1588,11 @@ public class PreferencesHelper implements RankingConfig {
boolean includeChannel = (includeDeleted || !nc.isDeleted())
&& (activeChannelFilter == null
|| (includeBlocked && nc.getImportance() == IMPORTANCE_NONE)
- || activeChannelFilter.contains(nc.getId()));
+ || activeChannelFilter.contains(nc.getId()))
+ && !PROMOTIONS_ID.equals(nc.getId())
+ && !NEWS_ID.equals(nc.getId())
+ && !SOCIAL_MEDIA_ID.equals(nc.getId())
+ && !RECS_ID.equals(nc.getId());
if (includeChannel) {
if (nc.getGroup() != null) {
if (r.groups.get(nc.getGroup()) != null) {
@@ -1616,7 +1627,7 @@ public class PreferencesHelper implements RankingConfig {
String groupId, int callingUid, boolean fromSystemOrSystemUi) {
List<NotificationChannel> deletedChannels = new ArrayList<>();
boolean groupBypassedDnd = false;
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null || TextUtils.isEmpty(groupId)) {
return deletedChannels;
@@ -1648,7 +1659,7 @@ public class PreferencesHelper implements RankingConfig {
public Collection<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
int uid) {
List<NotificationChannelGroup> groups = new ArrayList<>();
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return groups;
@@ -1659,7 +1670,7 @@ public class PreferencesHelper implements RankingConfig {
}
public NotificationChannelGroup getGroupForChannel(String pkg, int uid, String channelId) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences p = getPackagePreferencesLocked(pkg, uid);
if (p != null) {
NotificationChannel nc = p.channels.get(channelId);
@@ -1678,7 +1689,7 @@ public class PreferencesHelper implements RankingConfig {
public ArrayList<ConversationChannelWrapper> getConversations(IntArray userIds,
boolean onlyImportant) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
ArrayList<ConversationChannelWrapper> conversations = new ArrayList<>();
for (PackagePreferences p : mPackagePreferences.values()) {
if (userIds.binarySearch(UserHandle.getUserId(p.uid)) >= 0) {
@@ -1722,7 +1733,7 @@ public class PreferencesHelper implements RankingConfig {
public ArrayList<ConversationChannelWrapper> getConversations(String pkg, int uid) {
Objects.requireNonNull(pkg);
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return new ArrayList<>();
@@ -1764,7 +1775,7 @@ public class PreferencesHelper implements RankingConfig {
public @NonNull List<String> deleteConversations(String pkg, int uid,
Set<String> conversationIds, int callingUid, boolean fromSystemOrSystemUi) {
List<String> deletedChannelIds = new ArrayList<>();
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return deletedChannelIds;
@@ -1797,7 +1808,7 @@ public class PreferencesHelper implements RankingConfig {
boolean includeDeleted) {
Objects.requireNonNull(pkg);
List<NotificationChannel> channels = new ArrayList<>();
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return ParceledListSlice.emptyList();
@@ -1819,7 +1830,7 @@ public class PreferencesHelper implements RankingConfig {
public ParceledListSlice<NotificationChannel> getNotificationChannelsBypassingDnd(String pkg,
int uid) {
List<NotificationChannel> channels = new ArrayList<>();
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
final PackagePreferences r = mPackagePreferences.get(
packagePreferencesKey(pkg, uid));
if (r != null) {
@@ -1840,7 +1851,7 @@ public class PreferencesHelper implements RankingConfig {
* upgrades.
*/
public boolean onlyHasDefaultChannel(String pkg, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
if (r.channels.size() == (notificationClassification() ? 5 : 1)
&& r.channels.containsKey(NotificationChannel.DEFAULT_CHANNEL_ID)) {
@@ -1853,7 +1864,7 @@ public class PreferencesHelper implements RankingConfig {
public int getDeletedChannelCount(String pkg, int uid) {
Objects.requireNonNull(pkg);
int deletedCount = 0;
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return deletedCount;
@@ -1872,7 +1883,7 @@ public class PreferencesHelper implements RankingConfig {
public int getBlockedChannelCount(String pkg, int uid) {
Objects.requireNonNull(pkg);
int blockedCount = 0;
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return blockedCount;
@@ -1915,7 +1926,7 @@ public class PreferencesHelper implements RankingConfig {
ArraySet<Pair<String, Integer>> candidatePkgs = new ArraySet<>();
final IntArray currentUserIds = mUserProfiles.getCurrentProfileIds();
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
final int numPackagePreferences = mPackagePreferences.size();
for (int i = 0; i < numPackagePreferences; i++) {
final PackagePreferences r = mPackagePreferences.valueAt(i);
@@ -1984,7 +1995,7 @@ public class PreferencesHelper implements RankingConfig {
* considered for sentiment adjustments (and thus never show a blocking helper).
*/
public void setAppImportanceLocked(String packageName, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences prefs = getOrCreatePackagePreferencesLocked(packageName, uid);
if ((prefs.lockedAppFields & LockableAppFields.USER_LOCKED_IMPORTANCE) != 0) {
return;
@@ -2000,7 +2011,7 @@ public class PreferencesHelper implements RankingConfig {
* Returns the delegate for a given package, if it's allowed by the package and the user.
*/
public @Nullable String getNotificationDelegate(String sourcePkg, int sourceUid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences prefs = getPackagePreferencesLocked(sourcePkg, sourceUid);
if (prefs == null || prefs.delegate == null) {
@@ -2018,7 +2029,7 @@ public class PreferencesHelper implements RankingConfig {
*/
public void setNotificationDelegate(String sourcePkg, int sourceUid,
String delegatePkg, int delegateUid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences prefs = getOrCreatePackagePreferencesLocked(sourcePkg, sourceUid);
prefs.delegate = new Delegate(delegatePkg, delegateUid, true);
}
@@ -2028,7 +2039,7 @@ public class PreferencesHelper implements RankingConfig {
* Used by an app to turn off its notification delegate.
*/
public void revokeNotificationDelegate(String sourcePkg, int sourceUid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences prefs = getPackagePreferencesLocked(sourcePkg, sourceUid);
if (prefs != null && prefs.delegate != null) {
prefs.delegate.mEnabled = false;
@@ -2042,7 +2053,7 @@ public class PreferencesHelper implements RankingConfig {
*/
public boolean isDelegateAllowed(String sourcePkg, int sourceUid,
String potentialDelegatePkg, int potentialDelegateUid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences prefs = getPackagePreferencesLocked(sourcePkg, sourceUid);
return prefs != null && prefs.isValidDelegate(potentialDelegatePkg,
@@ -2088,24 +2099,25 @@ public class PreferencesHelper implements RankingConfig {
pw.println("per-package config version: " + XML_VERSION);
pw.println("PackagePreferences:");
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
dumpPackagePreferencesLocked(pw, prefix, filter, mPackagePreferences, pkgPermissions);
+ pw.println("Restored without uid:");
+ dumpPackagePreferencesLocked(pw, prefix, filter, mRestoredWithoutUids, null);
}
- pw.println("Restored without uid:");
- dumpPackagePreferencesLocked(pw, prefix, filter, mRestoredWithoutUids, null);
}
public void dump(ProtoOutputStream proto,
@NonNull NotificationManagerService.DumpFilter filter,
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
dumpPackagePreferencesLocked(proto, RankingHelperProto.RECORDS, filter,
mPackagePreferences, pkgPermissions);
+ dumpPackagePreferencesLocked(proto, RankingHelperProto.RECORDS_RESTORED_WITHOUT_UID,
+ filter, mRestoredWithoutUids, null);
}
- dumpPackagePreferencesLocked(proto, RankingHelperProto.RECORDS_RESTORED_WITHOUT_UID, filter,
- mRestoredWithoutUids, null);
}
+ @GuardedBy("mLock")
private void dumpPackagePreferencesLocked(PrintWriter pw, String prefix,
@NonNull NotificationManagerService.DumpFilter filter,
ArrayMap<String, PackagePreferences> packagePreferences,
@@ -2290,7 +2302,7 @@ public class PreferencesHelper implements RankingConfig {
pkgsWithPermissionsToHandle = pkgPermissions.keySet();
}
int pulledEvents = 0;
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
for (int i = 0; i < mPackagePreferences.size(); i++) {
if (pulledEvents > NOTIFICATION_PREFERENCES_PULL_LIMIT) {
break;
@@ -2370,7 +2382,7 @@ public class PreferencesHelper implements RankingConfig {
* {@link StatsEvent}.
*/
public void pullPackageChannelPreferencesStats(List<StatsEvent> events) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
int totalChannelsPulled = 0;
for (int i = 0; i < mPackagePreferences.size(); i++) {
if (totalChannelsPulled > NOTIFICATION_CHANNEL_PULL_LIMIT) {
@@ -2406,7 +2418,7 @@ public class PreferencesHelper implements RankingConfig {
* {@link StatsEvent}.
*/
public void pullPackageChannelGroupPreferencesStats(List<StatsEvent> events) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
int totalGroupsPulled = 0;
for (int i = 0; i < mPackagePreferences.size(); i++) {
if (totalGroupsPulled > NOTIFICATION_CHANNEL_GROUP_PULL_LIMIT) {
@@ -2435,10 +2447,12 @@ public class PreferencesHelper implements RankingConfig {
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
JSONObject ranking = new JSONObject();
JSONArray PackagePreferencess = new JSONArray();
- try {
- ranking.put("noUid", mRestoredWithoutUids.size());
- } catch (JSONException e) {
- // pass
+ synchronized (mLock) {
+ try {
+ ranking.put("noUid", mRestoredWithoutUids.size());
+ } catch (JSONException e) {
+ // pass
+ }
}
// Track data that we've handled from the permissions-based list
@@ -2447,7 +2461,7 @@ public class PreferencesHelper implements RankingConfig {
pkgsWithPermissionsToHandle = pkgPermissions.keySet();
}
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
final int N = mPackagePreferences.size();
for (int i = 0; i < N; i++) {
final PackagePreferences r = mPackagePreferences.valueAt(i);
@@ -2553,7 +2567,7 @@ public class PreferencesHelper implements RankingConfig {
}
public Map<Integer, String> getPackageBans() {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
final int N = mPackagePreferences.size();
ArrayMap<Integer, String> packageBans = new ArrayMap<>(N);
for (int i = 0; i < N; i++) {
@@ -2612,7 +2626,7 @@ public class PreferencesHelper implements RankingConfig {
private Map<String, Integer> getPackageChannels() {
ArrayMap<String, Integer> packageChannels = new ArrayMap<>();
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
for (int i = 0; i < mPackagePreferences.size(); i++) {
final PackagePreferences r = mPackagePreferences.valueAt(i);
int channelCount = 0;
@@ -2628,7 +2642,7 @@ public class PreferencesHelper implements RankingConfig {
}
public void onUserRemoved(int userId) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
int N = mPackagePreferences.size();
for (int i = N - 1; i >= 0; i--) {
PackagePreferences PackagePreferences = mPackagePreferences.valueAt(i);
@@ -2640,7 +2654,7 @@ public class PreferencesHelper implements RankingConfig {
}
protected void onLocaleChanged(Context context, int userId) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
int N = mPackagePreferences.size();
for (int i = 0; i < N; i++) {
PackagePreferences PackagePreferences = mPackagePreferences.valueAt(i);
@@ -2670,22 +2684,24 @@ public class PreferencesHelper implements RankingConfig {
for (int i = 0; i < size; i++) {
final String pkg = pkgList[i];
final int uid = uidList[i];
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
mPackagePreferences.remove(packagePreferencesKey(pkg, uid));
+ mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId));
}
- mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId));
updated = true;
}
} else {
for (String pkg : pkgList) {
- // Package install
- final PackagePreferences r =
- mRestoredWithoutUids.get(unrestoredPackageKey(pkg, changeUserId));
- if (r != null) {
- try {
- r.uid = mPm.getPackageUidAsUser(r.pkg, changeUserId);
- mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId));
- synchronized (mPackagePreferences) {
+ try {
+ // Package install
+ int uid = mPm.getPackageUidAsUser(pkg, changeUserId);
+ PackagePermission p = null;
+ synchronized (mLock) {
+ final PackagePreferences r =
+ mRestoredWithoutUids.get(unrestoredPackageKey(pkg, changeUserId));
+ if (r != null) {
+ r.uid = uid;
+ mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId));
mPackagePreferences.put(packagePreferencesKey(r.pkg, r.uid), r);
// Try to restore any unrestored sound resources
@@ -2707,32 +2723,29 @@ public class PreferencesHelper implements RankingConfig {
channel.setSound(restoredUri, channel.getAudioAttributes());
}
}
- }
- if (r.migrateToPm) {
- try {
- PackagePermission p = new PackagePermission(
+
+ if (r.migrateToPm) {
+ p = new PackagePermission(
r.pkg, UserHandle.getUserId(r.uid),
r.importance != IMPORTANCE_NONE,
hasUserConfiguredSettings(r));
- mPermissionHelper.setNotificationPermission(p);
- } catch (Exception e) {
- Slog.e(TAG, "could not migrate setting for " + r.pkg, e);
}
+ updated = true;
}
- updated = true;
- } catch (Exception e) {
- Slog.e(TAG, "could not restore " + r.pkg, e);
}
+ if (p != null) {
+ mPermissionHelper.setNotificationPermission(p);
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "could not restore " + pkg, e);
}
// Package upgrade
try {
- synchronized (mPackagePreferences) {
- PackagePreferences fullPackagePreferences = getPackagePreferencesLocked(pkg,
- mPm.getPackageUidAsUser(pkg, changeUserId));
- if (fullPackagePreferences != null) {
- updated |= createDefaultChannelIfNeededLocked(fullPackagePreferences);
- updated |= deleteDefaultChannelIfNeededLocked(fullPackagePreferences);
- }
+ PackagePreferences fullPackagePreferences = getPackagePreferencesLocked(pkg,
+ mPm.getPackageUidAsUser(pkg, changeUserId));
+ if (fullPackagePreferences != null) {
+ updated |= createDefaultChannelIfNeededLocked(fullPackagePreferences);
+ updated |= deleteDefaultChannelIfNeededLocked(fullPackagePreferences);
}
} catch (PackageManager.NameNotFoundException e) {
}
@@ -2746,7 +2759,7 @@ public class PreferencesHelper implements RankingConfig {
}
public void clearData(String pkg, int uid) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences p = getPackagePreferencesLocked(pkg, uid);
if (p != null) {
p.channels = new ArrayMap<>();
@@ -2933,7 +2946,7 @@ public class PreferencesHelper implements RankingConfig {
}
public void unlockAllNotificationChannels() {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
final int numPackagePreferences = mPackagePreferences.size();
for (int i = 0; i < numPackagePreferences; i++) {
final PackagePreferences r = mPackagePreferences.valueAt(i);
@@ -2950,7 +2963,7 @@ public class PreferencesHelper implements RankingConfig {
PackageManager.PackageInfoFlags.of(PackageManager.MATCH_ALL),
user.getUserHandle().getIdentifier());
for (PackageInfo pi : packages) {
- synchronized (mPackagePreferences) {
+ synchronized (mLock) {
PackagePreferences p = getOrCreatePackagePreferencesLocked(
pi.packageName, pi.applicationInfo.uid);
if (p.migrateToPm && p.uid != UNKNOWN_UID) {
diff --git a/services/core/java/com/android/server/notification/ShortcutHelper.java b/services/core/java/com/android/server/notification/ShortcutHelper.java
index 86dcecf9290a..857e3198d55b 100644
--- a/services/core/java/com/android/server/notification/ShortcutHelper.java
+++ b/services/core/java/com/android/server/notification/ShortcutHelper.java
@@ -27,7 +27,6 @@ import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
import android.os.Binder;
-import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
@@ -65,85 +64,34 @@ public class ShortcutHelper {
void onShortcutRemoved(String key);
}
+ private final ShortcutListener mShortcutListener;
private LauncherApps mLauncherAppsService;
- private ShortcutListener mShortcutListener;
private ShortcutServiceInternal mShortcutServiceInternal;
private UserManager mUserManager;
- // Key: packageName Value: <shortcutId, notifId>
- private HashMap<String, HashMap<String, String>> mActiveShortcutBubbles = new HashMap<>();
- private boolean mLauncherAppsCallbackRegistered;
+ // Key: packageName|userId Value: <shortcutId, notifId>
+ private final HashMap<String, HashMap<String, String>> mActiveShortcutBubbles = new HashMap<>();
+ private boolean mShortcutChangedCallbackRegistered;
// Bubbles can be created based on a shortcut, we need to listen for changes to
// that shortcut so that we may update the bubble appropriately.
- private final LauncherApps.Callback mLauncherAppsCallback = new LauncherApps.Callback() {
- @Override
- public void onPackageRemoved(String packageName, UserHandle user) {
- }
-
- @Override
- public void onPackageAdded(String packageName, UserHandle user) {
- }
-
- @Override
- public void onPackageChanged(String packageName, UserHandle user) {
- }
-
- @Override
- public void onPackagesAvailable(String[] packageNames, UserHandle user,
- boolean replacing) {
- }
-
- @Override
- public void onPackagesUnavailable(String[] packageNames, UserHandle user,
- boolean replacing) {
- }
+ private final LauncherApps.ShortcutChangeCallback mShortcutChangeCallback =
+ new LauncherApps.ShortcutChangeCallback() {
- @Override
- public void onShortcutsChanged(@NonNull String packageName,
- @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) {
- HashMap<String, String> shortcutBubbles = mActiveShortcutBubbles.get(packageName);
- ArrayList<String> bubbleKeysToRemove = new ArrayList<>();
- if (shortcutBubbles != null) {
- // Copy to avoid a concurrent modification exception when we remove bubbles from
- // shortcutBubbles.
- final Set<String> shortcutIds = new HashSet<>(shortcutBubbles.keySet());
-
- // If we can't find one of our bubbles in the shortcut list, that bubble needs
- // to be removed.
- for (String shortcutId : shortcutIds) {
- boolean foundShortcut = false;
- for (int i = 0; i < shortcuts.size(); i++) {
- if (shortcuts.get(i).getId().equals(shortcutId)) {
- foundShortcut = true;
- break;
- }
- }
- if (!foundShortcut) {
- bubbleKeysToRemove.add(shortcutBubbles.get(shortcutId));
- shortcutBubbles.remove(shortcutId);
- if (shortcutBubbles.isEmpty()) {
- mActiveShortcutBubbles.remove(packageName);
- if (mLauncherAppsCallbackRegistered
- && mActiveShortcutBubbles.isEmpty()) {
- mLauncherAppsService.unregisterCallback(mLauncherAppsCallback);
- mLauncherAppsCallbackRegistered = false;
- }
- }
- }
+ @Override
+ public void onShortcutsAddedOrUpdated(@NonNull String packageName,
+ @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) {
}
- }
- // Let NoMan know about the updates
- for (int i = 0; i < bubbleKeysToRemove.size(); i++) {
- // update flag bubble
- String bubbleKey = bubbleKeysToRemove.get(i);
- if (mShortcutListener != null) {
- mShortcutListener.onShortcutRemoved(bubbleKey);
+ public void onShortcutsRemoved(@NonNull String packageName,
+ @NonNull List<ShortcutInfo> removedShortcuts, @NonNull UserHandle user) {
+ final String packageUserKey = getPackageUserKey(packageName, user);
+ if (mActiveShortcutBubbles.get(packageUserKey) == null) return;
+ for (ShortcutInfo info : removedShortcuts) {
+ onShortcutRemoved(packageUserKey, info.getId());
+ }
}
- }
- }
- };
+ };
ShortcutHelper(LauncherApps launcherApps, ShortcutListener listener,
ShortcutServiceInternal shortcutServiceInternal, UserManager userManager) {
@@ -172,14 +120,14 @@ public class ShortcutHelper {
* Returns whether the given shortcut info is a conversation shortcut.
*/
public static boolean isConversationShortcut(
- ShortcutInfo shortcutInfo, ShortcutServiceInternal mShortcutServiceInternal,
+ ShortcutInfo shortcutInfo, ShortcutServiceInternal shortcutServiceInternal,
int callingUserId) {
if (shortcutInfo == null || !shortcutInfo.isLongLived() || !shortcutInfo.isEnabled()) {
return false;
}
// TODO (b/155016294) uncomment when sharing shortcuts are required
/*
- mShortcutServiceInternal.isSharingShortcut(callingUserId, "android",
+ shortcutServiceInternal.isSharingShortcut(callingUserId, "android",
shortcutInfo.getPackage(), shortcutInfo.getId(), shortcutInfo.getUserId(),
SHARING_FILTER);
*/
@@ -233,34 +181,30 @@ public class ShortcutHelper {
*
* @param r the notification record to check
* @param removedNotification true if this notification is being removed
- * @param handler handler to register the callback with
*/
void maybeListenForShortcutChangesForBubbles(NotificationRecord r,
- boolean removedNotification,
- Handler handler) {
+ boolean removedNotification) {
final String shortcutId = r.getNotification().getBubbleMetadata() != null
? r.getNotification().getBubbleMetadata().getShortcutId()
: null;
+ final String packageUserKey = getPackageUserKey(r.getSbn().getPackageName(), r.getUser());
if (!removedNotification
&& !TextUtils.isEmpty(shortcutId)
&& r.getShortcutInfo() != null
&& r.getShortcutInfo().getId().equals(shortcutId)) {
// Must track shortcut based bubbles in case the shortcut is removed
HashMap<String, String> packageBubbles = mActiveShortcutBubbles.get(
- r.getSbn().getPackageName());
+ packageUserKey);
if (packageBubbles == null) {
packageBubbles = new HashMap<>();
}
packageBubbles.put(shortcutId, r.getKey());
- mActiveShortcutBubbles.put(r.getSbn().getPackageName(), packageBubbles);
- if (!mLauncherAppsCallbackRegistered) {
- mLauncherAppsService.registerCallback(mLauncherAppsCallback, handler);
- mLauncherAppsCallbackRegistered = true;
- }
+ mActiveShortcutBubbles.put(packageUserKey, packageBubbles);
+ registerCallbackIfNeeded();
} else {
// No longer track shortcut
HashMap<String, String> packageBubbles = mActiveShortcutBubbles.get(
- r.getSbn().getPackageName());
+ packageUserKey);
if (packageBubbles != null) {
if (!TextUtils.isEmpty(shortcutId)) {
packageBubbles.remove(shortcutId);
@@ -278,20 +222,62 @@ public class ShortcutHelper {
}
}
if (packageBubbles.isEmpty()) {
- mActiveShortcutBubbles.remove(r.getSbn().getPackageName());
+ mActiveShortcutBubbles.remove(packageUserKey);
}
}
- if (mLauncherAppsCallbackRegistered && mActiveShortcutBubbles.isEmpty()) {
- mLauncherAppsService.unregisterCallback(mLauncherAppsCallback);
- mLauncherAppsCallbackRegistered = false;
+ unregisterCallbackIfNeeded();
+ }
+ }
+
+ private String getPackageUserKey(String packageName, UserHandle user) {
+ return packageName + "|" + user.getIdentifier();
+ }
+
+ private void onShortcutRemoved(String packageUserKey, String shortcutId) {
+ HashMap<String, String> shortcutBubbles = mActiveShortcutBubbles.get(packageUserKey);
+ ArrayList<String> bubbleKeysToRemove = new ArrayList<>();
+ if (shortcutBubbles != null) {
+ if (shortcutBubbles.containsKey(shortcutId)) {
+ bubbleKeysToRemove.add(shortcutBubbles.get(shortcutId));
+ shortcutBubbles.remove(shortcutId);
+ if (shortcutBubbles.isEmpty()) {
+ mActiveShortcutBubbles.remove(packageUserKey);
+ unregisterCallbackIfNeeded();
+ }
}
+ notifyNoMan(bubbleKeysToRemove);
+ }
+ }
+
+ private void registerCallbackIfNeeded() {
+ if (!mShortcutChangedCallbackRegistered) {
+ mShortcutChangedCallbackRegistered = true;
+ mShortcutServiceInternal.addShortcutChangeCallback(mShortcutChangeCallback);
+ }
+ }
+
+ private void unregisterCallbackIfNeeded() {
+ if (mShortcutChangedCallbackRegistered && mActiveShortcutBubbles.isEmpty()) {
+ mShortcutServiceInternal.removeShortcutChangeCallback(mShortcutChangeCallback);
+ mShortcutChangedCallbackRegistered = false;
}
}
void destroy() {
- if (mLauncherAppsCallbackRegistered) {
- mLauncherAppsService.unregisterCallback(mLauncherAppsCallback);
- mLauncherAppsCallbackRegistered = false;
+ if (mShortcutChangedCallbackRegistered) {
+ mShortcutServiceInternal.removeShortcutChangeCallback(mShortcutChangeCallback);
+ mShortcutChangedCallbackRegistered = false;
+ }
+ }
+
+ private void notifyNoMan(List<String> bubbleKeysToRemove) {
+ // Let NoMan know about the updates
+ for (int i = 0; i < bubbleKeysToRemove.size(); i++) {
+ // update flag bubble
+ String bubbleKey = bubbleKeysToRemove.get(i);
+ if (mShortcutListener != null) {
+ mShortcutListener.onShortcutRemoved(bubbleKey);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/notification/TimeToLiveHelper.java b/services/core/java/com/android/server/notification/TimeToLiveHelper.java
index a4460b23c73d..cabe766289f7 100644
--- a/services/core/java/com/android/server/notification/TimeToLiveHelper.java
+++ b/services/core/java/com/android/server/notification/TimeToLiveHelper.java
@@ -177,13 +177,16 @@ public class TimeToLiveHelper {
if (ACTION.equals(action)) {
String timeoutKey = null;
synchronized (mLock) {
- Pair<Long, String> earliest = mKeys.first();
- String key = intent.getStringExtra(EXTRA_KEY);
- if (!earliest.second.equals(key)) {
- Slog.wtf(TAG, "Alarm triggered but wasn't the earliest we were tracking");
+ if (!mKeys.isEmpty()) {
+ Pair<Long, String> earliest = mKeys.first();
+ String key = intent.getStringExtra(EXTRA_KEY);
+ if (!earliest.second.equals(key)) {
+ Slog.wtf(TAG,
+ "Alarm triggered but wasn't the earliest we were tracking");
+ }
+ removeMatchingEntry(key);
+ timeoutKey = earliest.second;
}
- removeMatchingEntry(key);
- timeoutKey = earliest.second;
}
mNm.timeoutNotification(timeoutKey);
}
diff --git a/services/core/java/com/android/server/notification/ZenModeEventLogger.java b/services/core/java/com/android/server/notification/ZenModeEventLogger.java
index ec5d96df3430..4a82057ed2a2 100644
--- a/services/core/java/com/android/server/notification/ZenModeEventLogger.java
+++ b/services/core/java/com/android/server/notification/ZenModeEventLogger.java
@@ -106,11 +106,11 @@ class ZenModeEventLogger {
/**
* Potentially log a zen mode change if the provided config and policy changes warrant it.
*
- * @param prevInfo ZenModeInfo (zen mode setting, config, policy) prior to this change
- * @param newInfo ZenModeInfo after this change takes effect
- * @param callingUid the calling UID associated with the change; may be used to attribute the
- * change to a particular package or determine if this is a user action
- * @param origin The origin of the Zen change.
+ * @param prevInfo ZenModeInfo (zen mode setting, config, policy) prior to this change
+ * @param newInfo ZenModeInfo after this change takes effect
+ * @param callingUid the calling UID associated with the change; may be used to attribute the
+ * change to a particular package or determine if this is a user action
+ * @param origin The origin of the Zen change.
*/
public final void maybeLogZenChange(ZenModeInfo prevInfo, ZenModeInfo newInfo, int callingUid,
@ConfigChangeOrigin int origin) {
@@ -127,6 +127,9 @@ class ZenModeEventLogger {
/**
* Reassign callingUid in mChangeState if we have more specific information that warrants it
* (for instance, if the change is automatic and due to an automatic rule change).
+ *
+ * <p>When Flags.modesUi() is enabled, we reassign the calling UID to the package UID in all
+ * changes whose source is not system or system UI, as long as there is only one rule changed.
*/
private void maybeReassignCallingUid() {
int userId = Process.INVALID_UID;
@@ -145,12 +148,23 @@ class ZenModeEventLogger {
userId = mChangeState.mNewConfig.user; // mNewConfig must not be null if enabler exists
}
- // The conditions where we should consider reassigning UID for an automatic rule change:
+ // The conditions where we should consider reassigning UID for an automatic rule change
+ // (pre-modes_ui):
// - we've determined it's not a user action
// - our current best guess is that the calling uid is system/sysui
+ // When Flags.modesUi() is true, we get the package UID for the changed rule, as long as:
+ // - the change does not originate from the system based on change origin
+ // - there is only one rule changed
if (mChangeState.getChangedRuleType() == RULE_TYPE_AUTOMATIC) {
- if (mChangeState.getIsUserAction() || !mChangeState.isFromSystemOrSystemUi()) {
- return;
+ if (Flags.modesUi()) {
+ // ignore anything whose origin is system
+ if (mChangeState.isFromSystemOrSystemUi()) {
+ return;
+ }
+ } else {
+ if (mChangeState.getIsUserAction() || !mChangeState.isFromSystemOrSystemUi()) {
+ return;
+ }
}
// Only try to get the package UID if there's exactly one changed automatic rule. If
@@ -202,7 +216,8 @@ class ZenModeEventLogger {
/* int32 package_uid = 7 */ mChangeState.getPackageUid(),
/* DNDPolicyProto current_policy = 8 */ mChangeState.getDNDPolicyProto(),
/* bool are_channels_bypassing = 9 */ mChangeState.getAreChannelsBypassing(),
- /* ActiveRuleType active_rule_types = 10 */ mChangeState.getActiveRuleTypes());
+ /* ActiveRuleType active_rule_types = 10 */ mChangeState.getActiveRuleTypes(),
+ /* ChangeOrigin change_origin = 11 */ mChangeState.getChangeOrigin());
}
/**
@@ -235,7 +250,8 @@ class ZenModeEventLogger {
ZenModeConfig mPrevConfig, mNewConfig;
NotificationManager.Policy mPrevPolicy, mNewPolicy;
int mCallingUid = Process.INVALID_UID;
- @ConfigChangeOrigin int mOrigin = ZenModeConfig.UPDATE_ORIGIN_UNKNOWN;
+ @ConfigChangeOrigin
+ int mOrigin = ZenModeConfig.UPDATE_ORIGIN_UNKNOWN;
private void init(ZenModeInfo prevInfo, ZenModeInfo newInfo, int callingUid,
@ConfigChangeOrigin int origin) {
@@ -388,7 +404,8 @@ class ZenModeEventLogger {
* rules available.
*/
@SuppressLint("WrongConstant") // special case for log-only type on manual rule
- @NonNull List<ZenRule> activeRulesList(ZenModeConfig config) {
+ @NonNull
+ List<ZenRule> activeRulesList(ZenModeConfig config) {
ArrayList<ZenRule> rules = new ArrayList<>();
if (config == null) {
return rules;
@@ -548,6 +565,17 @@ class ZenModeEventLogger {
}
/**
+ * Get the config change origin associated with this change, which is stored in mOrigin.
+ * Only useable if modes_ui is true.
+ */
+ int getChangeOrigin() {
+ if (Flags.modesUi()) {
+ return mOrigin;
+ }
+ return 0;
+ }
+
+ /**
* Convert the new policy to a DNDPolicyProto format for output in logs.
*
* <p>If {@code mNewZenMode} is {@code ZEN_MODE_OFF} (which can mean either no rules
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index bf6b6521c19a..7265cff19077 100644
--- a/services/core/java/com/android/server/notification/flags.aconfig
+++ b/services/core/java/com/android/server/notification/flags.aconfig
@@ -141,4 +141,11 @@ flag {
namespace: "systemui"
description: "This flag does not allow notifications older than 2 weeks old to be posted"
bug: "339833083"
-} \ No newline at end of file
+}
+
+flag {
+ name: "notification_force_group_singletons"
+ namespace: "systemui"
+ description: "This flag enables forced auto-grouping singleton groups"
+ bug: "336488844"
+}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 56e459057bfa..46585a50ea36 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -80,6 +80,7 @@ import android.util.EventLog;
import android.util.Slog;
import android.util.SparseArray;
+import com.android.internal.annotations.KeepForWeakReference;
import com.android.internal.content.PackageMonitor;
import com.android.internal.content.om.OverlayConfig;
import com.android.internal.util.ArrayUtils;
@@ -261,6 +262,7 @@ public final class OverlayManagerService extends SystemService {
private final OverlayActorEnforcer mActorEnforcer;
+ @KeepForWeakReference
private final PackageMonitor mPackageMonitor = new OverlayManagerPackageMonitor();
private int mPrevStartedUserId = -1;
diff --git a/services/core/java/com/android/server/pdb/PersistentDataBlockService.java b/services/core/java/com/android/server/pdb/PersistentDataBlockService.java
index c5e2bb87afd3..8410cff74265 100644
--- a/services/core/java/com/android/server/pdb/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/pdb/PersistentDataBlockService.java
@@ -34,6 +34,7 @@ import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
@@ -370,8 +371,13 @@ public class PersistentDataBlockService extends SystemService {
}
private void enforceUid(int callingUid) {
- if (callingUid != mAllowedUid && callingUid != UserHandle.AID_ROOT) {
- throw new SecurityException("uid " + callingUid + " not allowed to access PDB");
+ enforceUid(callingUid, /* allowShell= */ false);
+ }
+
+ private void enforceUid(int callingUid, boolean allowShell) {
+ if (callingUid != mAllowedUid && callingUid != UserHandle.AID_ROOT
+ && (callingUid != Process.SHELL_UID || !allowShell)) {
+ throw new SecurityException("Uid " + callingUid + " not allowed to access PDB");
}
}
@@ -864,7 +870,8 @@ public class PersistentDataBlockService extends SystemService {
private final IBinder mService = new IPersistentDataBlockService.Stub() {
private int printFrpStatus(PrintWriter pw, boolean printSecrets) {
- enforceUid(Binder.getCallingUid());
+ // Only allow SHELL_UID to print the status if printing the secrets is disabled
+ enforceUid(Binder.getCallingUid(), /* allowShell= */ !printSecrets);
pw.println("FRP state");
pw.println("=========");
@@ -872,8 +879,14 @@ public class PersistentDataBlockService extends SystemService {
pw.println("FRP state: " + mFrpActive);
printFrpDataFilesContents(pw, printSecrets);
printFrpSecret(pw, printSecrets);
- pw.println("OEM unlock state: " + getOemUnlockEnabled());
- pw.println("Bootloader lock state: " + getFlashLockState());
+
+ // Do not print OEM unlock state and flash lock state if the caller is a non-root
+ // shell - it likely won't have permissions anyways.
+ if (Binder.getCallingUid() != Process.SHELL_UID) {
+ pw.println("OEM unlock state: " + getOemUnlockEnabled());
+ pw.println("Bootloader lock state: " + getFlashLockState());
+ }
+
pw.println("Verified boot state: " + getVerifiedBootState());
pw.println("Has FRP credential handle: " + hasFrpCredentialHandle());
pw.println("FRP challenge block size: " + getDataBlockSize());
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 173fc5c86dd3..8d3f07edb687 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -801,8 +801,9 @@ final class InstallPackageHelper {
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- target.sendIntent(context, 0, fillIn, null /* onFinished*/, null /* handler */,
- null /* requiredPermission */, options.toBundle());
+ target.sendIntent(context, 0, fillIn,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (IntentSender.SendIntentException ignored) {
}
}
@@ -2260,6 +2261,12 @@ final class InstallPackageHelper {
installRequest.getNewUsers());
mPm.updateSequenceNumberLP(ps, installRequest.getNewUsers());
mPm.updateInstantAppInstallerLocked(packageName);
+
+ // The installation is success, remove the split info copy stored in package
+ // setting for the downgrade version check of DELETE_KEEP_DATA and archived app
+ // cases.
+ ps.setSplitNames(null);
+ ps.setSplitRevisionCodes(null);
}
installRequest.onCommitFinished();
}
@@ -2628,18 +2635,28 @@ final class InstallPackageHelper {
String packageName = pkgLite.packageName;
synchronized (mPm.mLock) {
- // Package which currently owns the data that the new package will own if installed.
- // If an app is uninstalled while keeping data (e.g. adb uninstall -k), installedPkg
- // will be null whereas dataOwnerPkg will contain information about the package
- // which was uninstalled while keeping its data.
- AndroidPackage dataOwnerPkg = mPm.mPackages.get(packageName);
PackageSetting dataOwnerPs = mPm.mSettings.getPackageLPr(packageName);
- if (dataOwnerPkg == null) {
- if (dataOwnerPs != null) {
- dataOwnerPkg = dataOwnerPs.getPkg();
+ if (dataOwnerPs == null) {
+ if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
+ String errorMsg = "Required installed version code was "
+ + requiredInstalledVersionCode
+ + " but package is not installed";
+ Slog.w(TAG, errorMsg);
+ return Pair.create(
+ PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg);
}
+ // The package doesn't exist in the system, don't need to check the version
+ // replacing.
+ return Pair.create(PackageManager.INSTALL_SUCCEEDED, null);
}
+ // Package which currently owns the data that the new package will own if installed.
+ // If an app is uninstalled while keeping data (e.g. adb uninstall -k), dataOwnerPkg
+ // will be null whereas dataOwnerPs will contain information about the package
+ // which was uninstalled while keeping its data. The AndroidPackage object that the
+ // PackageSetting refers to is the same object that is stored in mPackages.
+ AndroidPackage dataOwnerPkg = dataOwnerPs.getPkg();
+
if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
if (dataOwnerPkg == null) {
String errorMsg = "Required installed version code was "
@@ -2661,7 +2678,27 @@ final class InstallPackageHelper {
}
}
- if (dataOwnerPkg != null && !dataOwnerPkg.isSdkLibrary()) {
+ // If dataOwnerPkg is null but dataOwnerPs is not null, there is always data on
+ // some users. Wwe should do the downgrade check. E.g. DELETE_KEEP_DATA and
+ // archived apps
+ if (dataOwnerPkg == null) {
+ if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
+ dataOwnerPs.isDebuggable())) {
+ // The data exists on some users and downgrade is not permitted; a lower
+ // version of the app will not be allowed.
+ try {
+ PackageManagerServiceUtils.checkDowngrade(dataOwnerPs, pkgLite);
+ } catch (PackageManagerException e) {
+ String errorMsg = "Downgrade detected on app uninstalled with"
+ + " DELETE_KEEP_DATA: " + e.getMessage();
+ Slog.w(TAG, errorMsg);
+ return Pair.create(
+ PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg);
+ }
+ }
+ // dataOwnerPs.getPkg() is not null on system apps case. Don't need to consider
+ // system apps case like below.
+ } else if (dataOwnerPkg != null && !dataOwnerPkg.isSdkLibrary()) {
if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
dataOwnerPkg.isDebuggable())) {
// Downgrade is not permitted; a lower version of the app will not be allowed
@@ -4568,7 +4605,7 @@ final class InstallPackageHelper {
PackageManagerException.INTERNAL_ERROR_SYSTEM_OVERLAY_STATIC);
}
} else {
- if ((scanFlags & SCAN_AS_VENDOR) != 0) {
+ if ((scanFlags & (SCAN_AS_VENDOR | SCAN_AS_ODM)) != 0) {
if (pkg.getTargetSdkVersion() < ScanPackageUtils.getVendorPartitionVersion()) {
Slog.w(TAG, "System overlay " + pkg.getPackageName()
+ " targets an SDK below the required SDK level of vendor"
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 563cfa4d0ecd..023f7655c7a8 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -71,6 +71,7 @@ import android.content.pm.IPackageInstallerCallback;
import android.content.pm.IPackageManager;
import android.content.pm.IShortcutChangeCallback;
import android.content.pm.IncrementalStatesInfo;
+import android.content.pm.InstallSourceInfo;
import android.content.pm.LauncherActivityInfoInternal;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps.ShortcutQuery;
@@ -1856,9 +1857,11 @@ public class LauncherAppsService extends SystemService {
private String getInstallerPackage(@NonNull String packageName, int callingUserId) {
String installerPackageName = null;
try {
- installerPackageName =
- mIPM.getInstallSourceInfo(packageName, callingUserId)
- .getInstallingPackageName();
+ InstallSourceInfo info = mIPM.getInstallSourceInfo(packageName, callingUserId);
+ if (info == null) {
+ return installerPackageName;
+ }
+ installerPackageName = info.getInstallingPackageName();
} catch (RemoteException re) {
Slog.e(TAG, "Couldn't find installer for " + packageName, re);
}
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index c10dfcb5e9bf..e8fc577d9f0f 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -27,6 +27,7 @@ per-file CrossProfile* = file:MULTIUSER_AND_ENTERPRISE_OWNERS
per-file RestrictionsSet.java = file:MULTIUSER_AND_ENTERPRISE_OWNERS
per-file UserRestriction* = file:MULTIUSER_AND_ENTERPRISE_OWNERS
per-file User* = file:/MULTIUSER_OWNERS
+per-file BackgroundUser* = file:/MULTIUSER_OWNERS
# security
per-file KeySetHandle.java = cbrubaker@google.com, nnk@google.com
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index 0d1095f5656d..6b7b702b9157 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -1194,8 +1194,9 @@ public class PackageArchiver {
MODE_BACKGROUND_ACTIVITY_START_DENIED);
for (IntentSender intentSender : unarchiveIntentSenders) {
try {
- intentSender.sendIntent(mContext, 0, broadcastIntent, /* onFinished= */ null,
- /* handler= */ null, /* requiredPermission= */ null, options.toBundle());
+ intentSender.sendIntent(mContext, 0, broadcastIntent,
+ /* requiredPermission */ null, options.toBundle(),
+ /* executor */ null, /* onFinished */ null);
} catch (IntentSender.SendIntentException e) {
Slog.e(TAG, TextUtils.formatSimple("Failed to send unarchive intent"), e);
} finally {
@@ -1328,8 +1329,9 @@ public class PackageArchiver {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityStartMode(
MODE_BACKGROUND_ACTIVITY_START_DENIED);
- statusReceiver.sendIntent(mContext, 0, intent, /* onFinished= */ null,
- /* handler= */ null, /* requiredPermission= */ null, options.toBundle());
+ statusReceiver.sendIntent(mContext, 0, intent,
+ /* requiredPermission */ null, options.toBundle(),
+ /* executor */ null, /* onFinished */ null);
} catch (IntentSender.SendIntentException e) {
Slog.e(
TAG,
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index b93dcdc93a82..f615ca1da2e2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -1581,8 +1581,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- callback.sendIntent(mContext, 0, intent, null /* onFinished*/,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ callback.sendIntent(mContext, 0, intent,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (SendIntentException ignore) {
}
});
@@ -1912,8 +1913,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ mTarget.sendIntent(mContext, 0, fillIn,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (SendIntentException ignored) {
}
}
@@ -1945,8 +1947,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ mTarget.sendIntent(mContext, 0, fillIn,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (SendIntentException ignored) {
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 00e9d8d595f1..ff8a69de35bc 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -1060,7 +1060,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final boolean isInstallDpcPackagesPermissionGranted = (snapshot.checkUidPermission(
android.Manifest.permission.INSTALL_DPC_PACKAGES, mInstallerUid)
== PackageManager.PERMISSION_GRANTED);
- final int targetPackageUid = snapshot.getPackageUid(packageName, 0, userId);
+ // Also query the package uid for archived packages, so that the user confirmation
+ // dialog can be displayed for updating archived apps.
+ final int targetPackageUid = snapshot.getPackageUid(packageName,
+ PackageManager.MATCH_ARCHIVED_PACKAGES, userId);
final boolean isUpdate = targetPackageUid != -1 || isApexSession();
final InstallSourceInfo existingInstallSourceInfo = isUpdate
? snapshot.getInstallSourceInfo(packageName, userId)
@@ -5050,8 +5053,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- target.sendIntent(mContext, 0 /* code */, intent, null /* onFinished */,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ target.sendIntent(mContext, 0 /* code */, intent,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (IntentSender.SendIntentException ignored) {
}
}
@@ -5444,8 +5448,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- target.sendIntent(context, 0, fillIn, null /* onFinished */,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ target.sendIntent(context, 0, fillIn,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (IntentSender.SendIntentException ignored) {
}
}
@@ -5493,8 +5498,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- target.sendIntent(context, 0, fillIn, null /* onFinished */,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ target.sendIntent(context, 0, fillIn,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (IntentSender.SendIntentException ignored) {
}
}
@@ -5530,8 +5536,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- target.sendIntent(context, 0, intent, null /* onFinished */,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ target.sendIntent(context, 0, intent,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (IntentSender.SendIntentException ignored) {
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c0b8034b9a56..33ca8a8e0f9e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -31,6 +31,7 @@ import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
+import static android.crashrecovery.flags.Flags.refactorCrashrecovery;
import static android.os.Process.INVALID_UID;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
@@ -3037,7 +3038,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mCompilerStats.writeNow();
mDexManager.writePackageDexUsageNow();
mDynamicCodeLogger.writeNow();
- PackageWatchdog.getInstance(mContext).writeNow();
+ if (!refactorCrashrecovery()) {
+ PackageWatchdog.getInstance(mContext).writeNow();
+ }
synchronized (mLock) {
mPackageUsage.writeNow(mSettings.getPackagesLocked());
@@ -4492,8 +4495,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
void setSystemAppHiddenUntilInstalled(@NonNull Computer snapshot, String packageName,
boolean hidden) {
final int callingUid = Binder.getCallingUid();
- final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
- || callingUid == Process.SYSTEM_UID;
+ final boolean calledFromSystemOrPhone = isSystemOrPhone(callingUid);
if (!calledFromSystemOrPhone) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
"setSystemAppHiddenUntilInstalled");
@@ -4518,8 +4520,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
boolean setSystemAppInstallState(@NonNull Computer snapshot, String packageName,
boolean installed, int userId) {
final int callingUid = Binder.getCallingUid();
- final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
- || callingUid == Process.SYSTEM_UID;
+ final boolean calledFromSystemOrPhone = isSystemOrPhone(callingUid);
if (!calledFromSystemOrPhone) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
"setSystemAppHiddenUntilInstalled");
@@ -5034,8 +5035,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
pi.sendIntent(null, success ? 1 : 0, null /* intent */,
- null /* onFinished*/, null /* handler */,
- null /* requiredPermission */, options.toBundle());
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (SendIntentException e) {
Slog.w(TAG, e);
}
@@ -8123,4 +8124,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService
PackageManager.VERSION_CODE_HIGHEST, UserHandle.USER_SYSTEM,
PackageManager.DELETE_ALL_USERS, true /*removedBySystem*/);
}
+
+ private static boolean isSystemOrPhone(int uid) {
+ return UserHandle.isSameApp(uid, Process.SYSTEM_UID)
+ || UserHandle.isSameApp(uid, Process.PHONE_UID);
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index ff8abf879487..a1dffc6c25be 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -92,6 +92,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.content.InstallLocationUtils;
import com.android.internal.content.NativeLibraryHelper;
+import com.android.internal.telephony.TelephonyPermissions;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.HexDump;
@@ -356,7 +357,7 @@ public class PackageManagerServiceUtils {
* If not, throws a {@link SecurityException}.
*/
public static void enforceSystemOrPhoneCaller(String methodName, int callingUid) {
- if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
+ if (!TelephonyPermissions.isSystemOrPhone(callingUid)) {
throw new SecurityException(
"Cannot call " + methodName + " from UID " + callingUid);
}
@@ -1418,32 +1419,49 @@ public class PackageManagerServiceUtils {
/**
* Check and throw if the given before/after packages would be considered a
- * downgrade.
+ * downgrade with {@link PackageSetting}.
*/
- public static void checkDowngrade(AndroidPackage before, PackageInfoLite after)
- throws PackageManagerException {
- if (after.getLongVersionCode() < before.getLongVersionCode()) {
+ public static void checkDowngrade(@NonNull PackageSetting before,
+ @NonNull PackageInfoLite after) throws PackageManagerException {
+ checkDowngrade(before.getVersionCode(), before.getBaseRevisionCode(),
+ before.getSplitNames(), before.getSplitRevisionCodes(), after);
+ }
+
+ /**
+ * Check and throw if the given before/after packages would be considered a
+ * downgrade with {@link AndroidPackage}.
+ */
+ public static void checkDowngrade(@NonNull AndroidPackage before,
+ @NonNull PackageInfoLite after) throws PackageManagerException {
+ checkDowngrade(before.getLongVersionCode(), before.getBaseRevisionCode(),
+ before.getSplitNames(), before.getSplitRevisionCodes(), after);
+ }
+
+ private static void checkDowngrade(long beforeVersionCode, int beforeBaseRevisionCode,
+ @NonNull String[] beforeSplitNames, @NonNull int[] beforeSplitRevisionCodes,
+ @NonNull PackageInfoLite after) throws PackageManagerException {
+ if (after.getLongVersionCode() < beforeVersionCode) {
throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
"Update version code " + after.versionCode + " is older than current "
- + before.getLongVersionCode());
- } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
- if (after.baseRevisionCode < before.getBaseRevisionCode()) {
+ + beforeVersionCode);
+ } else if (after.getLongVersionCode() == beforeVersionCode) {
+ if (after.baseRevisionCode < beforeBaseRevisionCode) {
throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
"Update base revision code " + after.baseRevisionCode
- + " is older than current " + before.getBaseRevisionCode());
+ + " is older than current " + beforeBaseRevisionCode);
}
if (!ArrayUtils.isEmpty(after.splitNames)) {
for (int i = 0; i < after.splitNames.length; i++) {
final String splitName = after.splitNames[i];
- final int j = ArrayUtils.indexOf(before.getSplitNames(), splitName);
+ final int j = ArrayUtils.indexOf(beforeSplitNames, splitName);
if (j != -1) {
- if (after.splitRevisionCodes[i] < before.getSplitRevisionCodes()[j]) {
+ if (after.splitRevisionCodes[i] < beforeSplitRevisionCodes[j]) {
throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
"Update split " + splitName + " revision code "
+ after.splitRevisionCodes[i]
+ " is older than current "
- + before.getSplitRevisionCodes()[j]);
+ + beforeSplitRevisionCodes[j]);
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 7870b1735af4..9f10e0166120 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -97,6 +97,7 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
FORCE_QUERYABLE_OVERRIDE,
SCANNED_AS_STOPPED_SYSTEM_APP,
PENDING_RESTORE,
+ DEBUGGABLE,
})
public @interface Flags {
}
@@ -105,6 +106,7 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
private static final int FORCE_QUERYABLE_OVERRIDE = 1 << 2;
private static final int SCANNED_AS_STOPPED_SYSTEM_APP = 1 << 3;
private static final int PENDING_RESTORE = 1 << 4;
+ private static final int DEBUGGABLE = 1 << 5;
}
private int mBooleans;
@@ -232,6 +234,22 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
@Nullable
private byte[] mRestrictUpdateHash;
+ // This is the copy of the same data stored in AndroidPackage. It is not null if the
+ // AndroidPackage is deleted in cases of DELETE_KEEP_DATA. When AndroidPackage is not null,
+ // the field will be null, and the getter method will return the data from AndroidPackage
+ // instead.
+ @Nullable
+ private String[] mSplitNames;
+
+ // This is the copy of the same data stored in AndroidPackage. It is not null if the
+ // AndroidPackage is deleted in cases of DELETE_KEEP_DATA. When AndroidPackage is not null,
+ // the field will be null, and the getter method will return the data from AndroidPackage
+ // instead.
+ @Nullable
+ private int[] mSplitRevisionCodes;
+
+ private int mBaseRevisionCode;
+
/**
* Snapshot support.
*/
@@ -562,6 +580,76 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
return getBoolean(Booleans.PENDING_RESTORE);
}
+ /**
+ * @see PackageState#isDebuggable
+ */
+ public PackageSetting setDebuggable(boolean value) {
+ setBoolean(Booleans.DEBUGGABLE, value);
+ onChanged();
+ return this;
+ }
+
+ @Override
+ public boolean isDebuggable() {
+ return getBoolean(Booleans.DEBUGGABLE);
+ }
+
+ /**
+ * @see AndroidPackage#getBaseRevisionCode
+ */
+ public PackageSetting setBaseRevisionCode(int value) {
+ mBaseRevisionCode = value;
+ onChanged();
+ return this;
+ }
+
+ /**
+ * @see AndroidPackage#getBaseRevisionCode
+ */
+ public int getBaseRevisionCode() {
+ return mBaseRevisionCode;
+ }
+
+ /**
+ * @see AndroidPackage#getSplitNames
+ */
+ public PackageSetting setSplitNames(String[] value) {
+ mSplitNames = value;
+ onChanged();
+ return this;
+ }
+
+ /**
+ * @see AndroidPackage#getSplitNames
+ */
+ @NonNull
+ public String[] getSplitNames() {
+ if (pkg != null) {
+ return pkg.getSplitNames();
+ }
+ return mSplitNames == null ? EmptyArray.STRING : mSplitNames;
+ }
+
+ /**
+ * @see AndroidPackage#getSplitRevisionCodes
+ */
+ public PackageSetting setSplitRevisionCodes(int[] value) {
+ mSplitRevisionCodes = value;
+ onChanged();
+ return this;
+ }
+
+ /**
+ * @see AndroidPackage#getSplitRevisionCodes
+ */
+ @NonNull
+ public int[] getSplitRevisionCodes() {
+ if (pkg != null) {
+ return pkg.getSplitRevisionCodes();
+ }
+ return mSplitRevisionCodes == null ? EmptyArray.INT : mSplitRevisionCodes;
+ }
+
@Override
public String toString() {
return "PackageSetting{"
@@ -723,6 +811,11 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
mTargetSdkVersion = other.mTargetSdkVersion;
mRestrictUpdateHash = other.mRestrictUpdateHash == null
? null : other.mRestrictUpdateHash.clone();
+ mBaseRevisionCode = other.mBaseRevisionCode;
+ mSplitNames = other.mSplitNames != null
+ ? Arrays.copyOf(other.mSplitNames, other.mSplitNames.length) : null;
+ mSplitRevisionCodes = other.mSplitRevisionCodes != null
+ ? Arrays.copyOf(other.mSplitRevisionCodes, other.mSplitRevisionCodes.length) : null;
usesSdkLibraries = other.usesSdkLibraries != null
? Arrays.copyOf(other.usesSdkLibraries,
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 2f2c451ca7f3..7afc35819aa7 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -432,6 +432,13 @@ final class RemovePackageHelper {
}
deletedPs.setInstalled(/* installed= */ false, userId);
}
+
+ // Preserve split apk information for downgrade check with DELETE_KEEP_DATA and archived
+ // app cases
+ if (deletedPkg.getSplitNames() != null) {
+ deletedPs.setSplitNames(deletedPkg.getSplitNames());
+ deletedPs.setSplitRevisionCodes(deletedPkg.getSplitRevisionCodes());
+ }
}
// make sure to preserve per-user installed state if this removal was just
diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java
index 9ab6016f3d57..95561f5fe0e3 100644
--- a/services/core/java/com/android/server/pm/ScanPackageUtils.java
+++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java
@@ -437,6 +437,10 @@ final class ScanPackageUtils {
pkgSetting.setIsOrphaned(true);
}
+ // update debuggable and BaseRevisionCode to packageSetting
+ pkgSetting.setDebuggable(parsedPackage.isDebuggable());
+ pkgSetting.setBaseRevisionCode(parsedPackage.getBaseRevisionCode());
+
// Take care of first install / last update times.
final long scanFileTime = getLastModifiedTime(parsedPackage);
final long existingFirstInstallTime = userId == UserHandle.USER_ALL
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 39565526f33e..9177e2b75891 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -325,6 +325,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
private static final String TAG_MIME_TYPE = "mime-type";
private static final String TAG_ARCHIVE_STATE = "archive-state";
private static final String TAG_ARCHIVE_ACTIVITY_INFO = "archive-activity-info";
+ private static final String TAG_SPLIT_VERSION = "split-version";
public static final String ATTR_NAME = "name";
public static final String ATTR_PACKAGE = "package";
@@ -3255,9 +3256,15 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
if (pkg.isPendingRestore()) {
serializer.attributeBoolean(null, "pendingRestore", true);
}
+ if (pkg.isDebuggable()) {
+ serializer.attributeBoolean(null, "debuggable", true);
+ }
if (pkg.isLoading()) {
serializer.attributeBoolean(null, "isLoading", true);
}
+ if (pkg.getBaseRevisionCode() != 0) {
+ serializer.attributeInt(null, "baseRevisionCode", pkg.getBaseRevisionCode());
+ }
serializer.attributeFloat(null, "loadingProgress", pkg.getLoadingProgress());
serializer.attributeLongHex(null, "loadingCompletedTime", pkg.getLoadingCompletedTime());
@@ -3269,7 +3276,6 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
serializer.attributeInt(null, "appMetadataSource",
pkg.getAppMetadataSource());
-
writeUsesSdkLibLPw(serializer, pkg.getUsesSdkLibraries(),
pkg.getUsesSdkLibrariesVersionsMajor(), pkg.getUsesSdkLibrariesOptional());
@@ -3287,7 +3293,12 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
writeUpgradeKeySetsLPr(serializer, pkg.getKeySetData());
writeKeySetAliasesLPr(serializer, pkg.getKeySetData());
writeMimeGroupLPr(serializer, pkg.getMimeGroups());
-
+ // If getPkg is not NULL, these values are from the getPkg. And these values are preserved
+ // for the downgrade check for DELETE_KEEP_DATA and archived app cases. If the getPkg is
+ // not NULL, we don't need to preserve it.
+ if (pkg.getPkg() == null) {
+ writeSplitVersionsLPr(serializer, pkg.getSplitNames(), pkg.getSplitRevisionCodes());
+ }
serializer.endTag(null, "package");
}
@@ -4059,6 +4070,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
long versionCode = 0;
boolean installedForceQueryable = false;
boolean isPendingRestore = false;
+ boolean isDebuggable = false;
float loadingProgress = 0;
long loadingCompletedTime = 0;
UUID domainSetId;
@@ -4068,6 +4080,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
byte[] restrictUpdateHash = null;
boolean isScannedAsStoppedSystemApp = false;
boolean isSdkLibrary = false;
+ int baseRevisionCode = 0;
try {
name = parser.getAttributeValue(null, ATTR_NAME);
realName = parser.getAttributeValue(null, "realName");
@@ -4085,6 +4098,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
updateAvailable = parser.getAttributeBoolean(null, "updateAvailable", false);
installedForceQueryable = parser.getAttributeBoolean(null, "forceQueryable", false);
isPendingRestore = parser.getAttributeBoolean(null, "pendingRestore", false);
+ isDebuggable = parser.getAttributeBoolean(null, "debuggable", false);
loadingProgress = parser.getAttributeFloat(null, "loadingProgress", 0);
loadingCompletedTime = parser.getAttributeLongHex(null, "loadingCompletedTime", 0);
@@ -4112,6 +4126,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
appMetadataFilePath = parser.getAttributeValue(null, "appMetadataFilePath");
appMetadataSource = parser.getAttributeInt(null, "appMetadataSource",
PackageManager.APP_METADATA_SOURCE_UNKNOWN);
+ baseRevisionCode = parser.getAttributeInt(null, "baseRevisionCode", 0);
isScannedAsStoppedSystemApp = parser.getAttributeBoolean(null,
"scannedAsStoppedSystemApp", false);
@@ -4259,11 +4274,13 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
.setUpdateAvailable(updateAvailable)
.setForceQueryableOverride(installedForceQueryable)
.setPendingRestore(isPendingRestore)
+ .setDebuggable(isDebuggable)
.setLoadingProgress(loadingProgress)
.setLoadingCompletedTime(loadingCompletedTime)
.setAppMetadataFilePath(appMetadataFilePath)
.setAppMetadataSource(appMetadataSource)
.setTargetSdkVersion(targetSdkVersion)
+ .setBaseRevisionCode(baseRevisionCode)
.setRestrictUpdateHash(restrictUpdateHash)
.setScannedAsStoppedSystemApp(isScannedAsStoppedSystemApp);
// Handle legacy string here for single-user mode
@@ -4369,6 +4386,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
readUsesStaticLibLPw(parser, packageSetting);
} else if (tagName.equals(TAG_USES_SDK_LIB)) {
readUsesSdkLibLPw(parser, packageSetting);
+ } else if (tagName.equals(TAG_SPLIT_VERSION)) {
+ readSplitVersionsLPw(parser, packageSetting);
} else {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Unknown element under <package>: " + parser.getName());
@@ -4465,6 +4484,37 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
}
}
+ private void readSplitVersionsLPw(TypedXmlPullParser parser, PackageSetting outPs)
+ throws IOException, XmlPullParserException {
+ String splitName = parser.getAttributeValue(null, ATTR_NAME);
+ int splitRevision = parser.getAttributeInt(null, ATTR_VERSION, -1);
+ if (splitName != null && splitRevision >= 0) {
+ outPs.setSplitNames(ArrayUtils.appendElement(String.class,
+ outPs.getSplitNames(), splitName));
+ outPs.setSplitRevisionCodes(ArrayUtils.appendInt(
+ outPs.getSplitRevisionCodes(), splitRevision));
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+ }
+
+ private void writeSplitVersionsLPr(TypedXmlSerializer serializer, String[] splitNames,
+ int[] splitRevisionCodes) throws IOException {
+ if (ArrayUtils.isEmpty(splitNames) || ArrayUtils.isEmpty(splitRevisionCodes)
+ || splitNames.length != splitRevisionCodes.length) {
+ return;
+ }
+ final int libLength = splitNames.length;
+ for (int i = 0; i < libLength; i++) {
+ final String splitName = splitNames[i];
+ final int splitRevision = splitRevisionCodes[i];
+ serializer.startTag(null, TAG_SPLIT_VERSION);
+ serializer.attribute(null, ATTR_NAME, splitName);
+ serializer.attributeInt(null, ATTR_VERSION, splitRevision);
+ serializer.endTag(null, TAG_SPLIT_VERSION);
+ }
+ }
+
private void readDisabledComponentsLPw(PackageSetting packageSetting, TypedXmlPullParser parser,
int userId) throws IOException, XmlPullParserException {
int outerDepth = parser.getDepth();
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 1cd77ffcedaa..021f7aa9c215 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -3443,6 +3443,14 @@ public class ShortcutService extends IShortcutService.Stub {
}
@Override
+ public void removeShortcutChangeCallback(
+ @NonNull LauncherApps.ShortcutChangeCallback callback) {
+ synchronized (mServiceLock) {
+ mShortcutChangeCallbacks.remove(Objects.requireNonNull(callback));
+ }
+ }
+
+ @Override
public int getShortcutIconResId(int launcherUserId, @NonNull String callingPackage,
@NonNull String packageName, @NonNull String shortcutId, int userId) {
Objects.requireNonNull(callingPackage, "callingPackage");
@@ -4482,8 +4490,9 @@ public class ShortcutService extends IShortcutService.Stub {
ActivityOptions options = ActivityOptions.makeBasic()
.setPendingIntentBackgroundActivityStartMode(
MODE_BACKGROUND_ACTIVITY_START_DENIED);
- intentSender.sendIntent(mContext, /* code= */ 0, extras,
- /* onFinished=*/ null, /* handler= */ null, null, options.toBundle());
+ intentSender.sendIntent(mContext, 0 /* code */, extras,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (SendIntentException e) {
Slog.w(TAG, "sendIntent failed().", e);
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index e215ca38fd46..dde9943ccd7b 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -58,6 +58,7 @@ import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
+import android.app.AlarmManager;
import android.app.BroadcastOptions;
import android.app.IActivityManager;
import android.app.IStopUserCallback;
@@ -326,6 +327,12 @@ public class UserManagerService extends IUserManager.Stub {
*/
private static final long PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_TIMEOUT_MS = 5 * 60 * 1000;
+ /**
+ * The time duration (in milliseconds) of the window length for the auto-lock message alarm
+ */
+ private static final long PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_ALARM_WINDOW_MS =
+ TimeUnit.SECONDS.toMillis(55);
+
// Tron counters
private static final String TRON_GUEST_CREATED = "users_guest_created";
private static final String TRON_USER_CREATED = "users_user_created";
@@ -557,8 +564,15 @@ public class UserManagerService extends IUserManager.Stub {
private KeyguardManager.KeyguardLockedStateListener mKeyguardLockedStateListener;
- /** Token to identify and remove already scheduled private space auto-lock messages */
- private static final Object PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN = new Object();
+ /**
+ * {@link android.app.AlarmManager.OnAlarmListener} to schedule an alarm to enable
+ * auto-locking private space after screen timeout
+ */
+ private PrivateSpaceAutoLockTimer mPrivateSpaceAutoLockTimer;
+
+ /** Tag representing the alarm manager timer for auto-locking private space */
+ private static final String PRIVATE_SPACE_AUTO_LOCK_TIMER_TAG = "PrivateSpaceAutoLockTimer";
+
/** Content observer to get callbacks for privte space autolock settings changes */
private final SettingsObserver mPrivateSpaceAutoLockSettingsObserver;
@@ -609,22 +623,28 @@ public class UserManagerService extends IUserManager.Stub {
public void onReceive(Context context, Intent intent) {
if (isAutoLockForPrivateSpaceEnabled()) {
if (ACTION_SCREEN_OFF.equals(intent.getAction())) {
- Slog.d(LOG_TAG, "SCREEN_OFF broadcast received");
- maybeScheduleMessageToAutoLockPrivateSpace();
+ maybeScheduleAlarmToAutoLockPrivateSpace();
} else if (ACTION_SCREEN_ON.equals(intent.getAction())) {
Slog.d(LOG_TAG, "SCREEN_ON broadcast received, "
- + "removing queued message to auto-lock private space");
- // Remove any queued messages since the device is interactive again
- mHandler.removeCallbacksAndMessages(PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN);
+ + "removing pending alarms to auto-lock private space");
+ // Remove any pending alarm since the device is interactive again
+ cancelPendingAutoLockAlarms();
}
}
}
};
+ private void cancelPendingAutoLockAlarms() {
+ final AlarmManager alarmManager = mContext.getSystemService(AlarmManager.class);
+ if (alarmManager != null && mPrivateSpaceAutoLockTimer != null) {
+ alarmManager.cancel(mPrivateSpaceAutoLockTimer);
+ }
+ }
+
@VisibleForTesting
- void maybeScheduleMessageToAutoLockPrivateSpace() {
+ void maybeScheduleAlarmToAutoLockPrivateSpace() {
// No action needed if auto-lock on inactivity not selected
- int privateSpaceAutoLockPreference =
+ final int privateSpaceAutoLockPreference =
Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.PRIVATE_SPACE_AUTO_LOCK,
Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART,
@@ -637,26 +657,65 @@ public class UserManagerService extends IUserManager.Stub {
}
int privateProfileUserId = getPrivateProfileUserId();
if (privateProfileUserId != UserHandle.USER_NULL) {
- scheduleMessageToAutoLockPrivateSpace(privateProfileUserId,
- PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN,
+ if (isQuietModeEnabled(privateProfileUserId)) {
+ Slogf.d(LOG_TAG, "Not scheduling auto-lock alarm for %d, "
+ + "quiet mode already enabled", privateProfileUserId);
+ return;
+ }
+ scheduleAlarmToAutoLockPrivateSpace(privateProfileUserId,
PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_TIMEOUT_MS);
}
}
@VisibleForTesting
- void scheduleMessageToAutoLockPrivateSpace(int userId, Object token,
- long delayInMillis) {
- Slog.i(LOG_TAG, "Scheduling auto-lock message");
- mHandler.postDelayed(() -> {
+ void scheduleAlarmToAutoLockPrivateSpace(int userId, long delayInMillis) {
+ final AlarmManager alarmManager = mContext.getSystemService(AlarmManager.class);
+ if (alarmManager == null) {
+ Slog.e(LOG_TAG, "AlarmManager not available, cannot schedule auto-lock alarm");
+ return;
+ }
+ initPrivateSpaceAutoLockTimer(userId);
+ final long alarmWindowStartTime = SystemClock.elapsedRealtime() + delayInMillis;
+ alarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ alarmWindowStartTime,
+ PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_ALARM_WINDOW_MS,
+ PRIVATE_SPACE_AUTO_LOCK_TIMER_TAG,
+ new HandlerExecutor(mHandler),
+ mPrivateSpaceAutoLockTimer);
+ }
+
+ private void initPrivateSpaceAutoLockTimer(int userId) {
+ cancelPendingAutoLockAlarms();
+ if (mPrivateSpaceAutoLockTimer == null
+ || mPrivateSpaceAutoLockTimer.getUserId() != userId) {
+ mPrivateSpaceAutoLockTimer = new PrivateSpaceAutoLockTimer(userId);
+ }
+ }
+
+ private class PrivateSpaceAutoLockTimer implements AlarmManager.OnAlarmListener {
+
+ private final int mUserId;
+
+ PrivateSpaceAutoLockTimer(int userId) {
+ mUserId = userId;
+ }
+
+ int getUserId() {
+ return mUserId;
+ }
+
+ @Override
+ public void onAlarm() {
final PowerManager powerManager = mContext.getSystemService(PowerManager.class);
if (powerManager != null && !powerManager.isInteractive()) {
- Slog.i(LOG_TAG, "Auto-locking private space with user-id " + userId);
- setQuietModeEnabledAsync(userId, true,
+ Slog.i(LOG_TAG, "Auto-locking private space with user-id " + mUserId);
+ setQuietModeEnabledAsync(mUserId, true,
/* target */ null, mContext.getPackageName());
} else {
- Slog.i(LOG_TAG, "Device is interactive, skipping auto-lock");
+ Slog.i(LOG_TAG, "Device is interactive, skipping auto-lock for profile user "
+ + mUserId);
}
- }, token, delayInMillis);
+ }
}
@RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
@@ -702,7 +761,7 @@ public class UserManagerService extends IUserManager.Stub {
// Unregister device inactivity broadcasts
if (mIsDeviceInactivityBroadcastReceiverRegistered) {
Slog.i(LOG_TAG, "Removing device inactivity broadcast receivers");
- mHandler.removeCallbacksAndMessages(PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN);
+ cancelPendingAutoLockAlarms();
mContext.unregisterReceiver(mDeviceInactivityBroadcastReceiver);
mIsDeviceInactivityBroadcastReceiverRegistered = false;
}
@@ -1117,6 +1176,30 @@ public class UserManagerService extends IUserManager.Stub {
}
}
+ /** Marks the user as slated for deletion during boot if necessary. **/
+ @GuardedBy("mUsersLock")
+ private void markUserForRemovalIfNecessaryLU(UserInfo ui) {
+ if (!ui.isEphemeral()) {
+ // User should be ephemeral to be marked for removal.
+ return;
+ }
+ if (ui.preCreated) {
+ // Avoid marking pre-created users for removal.
+ return;
+ }
+ if (ui.lastLoggedInTime == 0 && ui.isGuest() && Resources.getSystem().getBoolean(
+ com.android.internal.R.bool.config_guestUserAutoCreated)) {
+ // Avoid marking auto-created but not-yet-logged-in guest user for removal. Because a
+ // new one will be created anyway, and this one doesn't have any personal data in it yet
+ // due to not being logged in.
+ return;
+ }
+ // Mark the user for removal.
+ addRemovingUserIdLocked(ui.id);
+ ui.partial = true;
+ ui.flags |= UserInfo.FLAG_DISABLED;
+ }
+
/* Prunes out any partially created or partially removed users. */
private void cleanupPartialUsers() {
ArrayList<UserInfo> partials = new ArrayList<>();
@@ -1842,6 +1925,7 @@ public class UserManagerService extends IUserManager.Stub {
Slog.i(LOG_TAG, "Quiet mode is already " + enableQuietMode);
return;
}
+ UserManager.invalidateQuietModeEnabledCache();
profile.flags ^= UserInfo.FLAG_QUIET_MODE;
profileUserData = getUserDataLU(profile.id);
}
@@ -4281,13 +4365,7 @@ public class UserManagerService extends IUserManager.Stub {
|| mNextSerialNumber <= userData.info.id) {
mNextSerialNumber = userData.info.id + 1;
}
- if (userData.info.isEphemeral() && !userData.info.preCreated
- && userData.info.id != UserHandle.USER_SYSTEM) {
- // Mark ephemeral user as slated for deletion.
- addRemovingUserIdLocked(userData.info.id);
- userData.info.partial = true;
- userData.info.flags |= UserInfo.FLAG_DISABLED;
- }
+ markUserForRemovalIfNecessaryLU(userData.info);
}
}
} else if (name.equals(TAG_GUEST_RESTRICTIONS)) {
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 4d07ab5cbb30..8be20b0e4904 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -1637,10 +1637,12 @@ final class DefaultPermissionGrantPolicy {
private boolean isSystemOrCertificateMatchingPackage(PackageInfo pi, String cert) {
if (cert == null) {
return pi.applicationInfo.isSystemApp();
+ } else if (Objects.equals(cert, "platform")) {
+ return mServiceInternal.isPlatformSigned(pi.packageName);
+ } else {
+ return mContext.getPackageManager().hasSigningCertificate(pi.packageName, HexEncoding.
+ decode(cert.replace(":", "")), PackageManager.CERT_INPUT_SHA256);
}
-
- return mContext.getPackageManager().hasSigningCertificate(pi.packageName, HexEncoding.
- decode(cert.replace(":", "")), PackageManager.CERT_INPUT_SHA256);
}
private static boolean doesPackageSupportRuntimePermissions(PackageInfo pkg) {
diff --git a/services/core/java/com/android/server/pm/pkg/PackageState.java b/services/core/java/com/android/server/pm/pkg/PackageState.java
index e0ee199a343d..58761886ecb9 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageState.java
@@ -274,6 +274,14 @@ public interface PackageState {
boolean isPendingRestore();
/**
+ * @see ApplicationInfo#FLAG_DEBUGGABLE
+ * @see R.styleable#AndroidManifestApplication_debuggable
+ * @see AndroidPackage#isDebuggable
+ * @hide
+ */
+ boolean isDebuggable();
+
+ /**
* Retrieves the shared user app ID. Note that the actual shared user data is not available here
* and must be queried separately.
*
diff --git a/services/core/java/com/android/server/policy/ModifierShortcutManager.java b/services/core/java/com/android/server/policy/ModifierShortcutManager.java
index 3a79d0df4819..fde23b726572 100644
--- a/services/core/java/com/android/server/policy/ModifierShortcutManager.java
+++ b/services/core/java/com/android/server/policy/ModifierShortcutManager.java
@@ -22,8 +22,10 @@ import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Icon;
import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.RemoteException;
@@ -36,7 +38,11 @@ import android.util.SparseArray;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
+import android.view.KeyboardShortcutInfo;
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.IShortcutService;
import com.android.internal.util.XmlUtils;
import com.android.server.input.KeyboardMetricsCollector;
@@ -46,7 +52,9 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -183,8 +191,12 @@ public class ModifierShortcutManager {
String rolePackage = mRoleManager.getDefaultApplication(role);
if (rolePackage != null) {
intent = mPackageManager.getLaunchIntentForPackage(rolePackage);
- intent.putExtra(EXTRA_ROLE, role);
- mRoleIntents.put(role, intent);
+ if (intent != null) {
+ intent.putExtra(EXTRA_ROLE, role);
+ mRoleIntents.put(role, intent);
+ } else {
+ Log.w(TAG, "No launch intent for role " + role);
+ }
} else {
Log.w(TAG, "No default application for role " + role);
}
@@ -198,8 +210,7 @@ public class ModifierShortcutManager {
private void loadShortcuts() {
try {
- XmlResourceParser parser = mContext.getResources().getXml(
- com.android.internal.R.xml.bookmarks);
+ XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks);
XmlUtils.beginDocument(parser, TAG_BOOKMARKS);
while (true) {
@@ -270,6 +281,9 @@ public class ModifierShortcutManager {
continue;
}
intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, categoryName);
+ if (intent == null) {
+ Log.w(TAG, "Null selector intent for " + categoryName);
+ }
} else if (roleName != null) {
// We can't resolve the role at the time of this file being parsed as the
// device hasn't finished booting, so we will look it up lazily.
@@ -466,4 +480,131 @@ public class ModifierShortcutManager {
return false;
}
+
+ /**
+ * @param deviceId The input device id of the input device that will handle the shortcuts.
+ *
+ * @return a {@link KeyboardShortcutGroup} containing the application launch keyboard
+ * shortcuts parsed at boot time from {@code bookmarks.xml}.
+ */
+ public KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId) {
+ List<KeyboardShortcutInfo> shortcuts = new ArrayList();
+ for (int i = 0; i < mIntentShortcuts.size(); i++) {
+ KeyboardShortcutInfo info = shortcutInfoFromIntent(
+ (char) (mIntentShortcuts.keyAt(i)), mIntentShortcuts.valueAt(i), false);
+ if (info != null) {
+ shortcuts.add(info);
+ }
+ }
+
+ for (int i = 0; i < mShiftShortcuts.size(); i++) {
+ KeyboardShortcutInfo info = shortcutInfoFromIntent(
+ (char) (mShiftShortcuts.keyAt(i)), mShiftShortcuts.valueAt(i), true);
+ if (info != null) {
+ shortcuts.add(info);
+ }
+ }
+
+ for (int i = 0; i < mRoleShortcuts.size(); i++) {
+ String role = mRoleShortcuts.valueAt(i);
+ KeyboardShortcutInfo info = shortcutInfoFromIntent(
+ (char) (mRoleShortcuts.keyAt(i)), getRoleLaunchIntent(role), false);
+ if (info != null) {
+ shortcuts.add(info);
+ }
+ }
+
+ for (int i = 0; i < mShiftRoleShortcuts.size(); i++) {
+ String role = mShiftRoleShortcuts.valueAt(i);
+ KeyboardShortcutInfo info = shortcutInfoFromIntent(
+ (char) (mShiftRoleShortcuts.keyAt(i)), getRoleLaunchIntent(role), true);
+ if (info != null) {
+ shortcuts.add(info);
+ }
+ }
+
+ return new KeyboardShortcutGroup(
+ mContext.getString(R.string.keyboard_shortcut_group_applications),
+ shortcuts);
+ }
+
+ /**
+ * Given an intent to launch an application and the character and shift state that should
+ * trigger it, return a suitable {@link KeyboardShortcutInfo} that contains the label and
+ * icon for the target application.
+ *
+ * @param baseChar the character that triggers the shortcut
+ * @param intent the application launch intent
+ * @param shift whether the shift key is required to be presed.
+ */
+ @VisibleForTesting
+ KeyboardShortcutInfo shortcutInfoFromIntent(char baseChar, Intent intent, boolean shift) {
+ if (intent == null) {
+ return null;
+ }
+
+ CharSequence label;
+ Icon icon;
+ ActivityInfo resolvedActivity = intent.resolveActivityInfo(
+ mPackageManager, PackageManager.MATCH_DEFAULT_ONLY);
+ if (resolvedActivity == null) {
+ return null;
+ }
+ boolean isResolver = com.android.internal.app.ResolverActivity.class.getName().equals(
+ resolvedActivity.name);
+ if (isResolver) {
+ label = getIntentCategoryLabel(mContext,
+ intent.getSelector().getCategories().iterator().next());
+ if (label == null) {
+ return null;
+ }
+ icon = Icon.createWithResource(mContext, R.drawable.sym_def_app_icon);
+
+ } else {
+ label = resolvedActivity.loadLabel(mPackageManager);
+ icon = Icon.createWithResource(
+ resolvedActivity.packageName, resolvedActivity.getIconResource());
+ }
+ int modifiers = KeyEvent.META_META_ON;
+ if (shift) {
+ modifiers |= KeyEvent.META_SHIFT_ON;
+ }
+ return new KeyboardShortcutInfo(label, icon, baseChar, modifiers);
+ }
+
+ @VisibleForTesting
+ static String getIntentCategoryLabel(Context context, CharSequence category) {
+ int resid;
+ switch (category.toString()) {
+ case Intent.CATEGORY_APP_BROWSER:
+ resid = R.string.keyboard_shortcut_group_applications_browser;
+ break;
+ case Intent.CATEGORY_APP_CONTACTS:
+ resid = R.string.keyboard_shortcut_group_applications_contacts;
+ break;
+ case Intent.CATEGORY_APP_EMAIL:
+ resid = R.string.keyboard_shortcut_group_applications_email;
+ break;
+ case Intent.CATEGORY_APP_CALENDAR:
+ resid = R.string.keyboard_shortcut_group_applications_calendar;
+ break;
+ case Intent.CATEGORY_APP_MAPS:
+ resid = R.string.keyboard_shortcut_group_applications_maps;
+ break;
+ case Intent.CATEGORY_APP_MUSIC:
+ resid = R.string.keyboard_shortcut_group_applications_music;
+ break;
+ case Intent.CATEGORY_APP_MESSAGING:
+ resid = R.string.keyboard_shortcut_group_applications_sms;
+ break;
+ case Intent.CATEGORY_APP_CALCULATOR:
+ resid = R.string.keyboard_shortcut_group_applications_calculator;
+ break;
+ default:
+ Log.e(TAG, ("No label for app category " + category));
+ return null;
+ }
+ return context.getString(resid);
+ };
+
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 0cda30f3affc..8419a608dc41 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -189,6 +189,7 @@ import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyCharacterMap.FallbackAction;
import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.WindowManager;
@@ -932,8 +933,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public void onWakeUp() {
synchronized (mLock) {
if (shouldEnableWakeGestureLp()) {
- performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, false,
- "Wake Up");
+ performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, "Wake Up");
mWindowWakeUpPolicy.wakeUpFromWakeGesture();
}
}
@@ -1402,7 +1402,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
break;
case LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, false,
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON,
"Power - Long Press - Global Actions");
showGlobalActions();
break;
@@ -1414,14 +1414,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (ActivityManager.isUserAMonkey()) {
break;
}
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, false,
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON,
"Power - Long Press - Shut Off");
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
break;
case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:
mPowerKeyHandled = true;
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, false,
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON,
"Power - Long Press - Go To Voice Assist");
// Some devices allow the voice assistant intent during setup (and use that intent
// to launch something else, like Settings). So we explicitly allow that via the
@@ -1430,7 +1430,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
break;
case LONG_PRESS_POWER_ASSISTANT:
mPowerKeyHandled = true;
- performHapticFeedback(HapticFeedbackConstants.ASSISTANT_BUTTON, false,
+ performHapticFeedback(HapticFeedbackConstants.ASSISTANT_BUTTON,
"Power - Long Press - Go To Assistant");
final int powerKeyDeviceId = INVALID_INPUT_DEVICE_ID;
launchAssistAction(null, powerKeyDeviceId, eventTime,
@@ -1445,7 +1445,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
break;
case VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, false,
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON,
"Power - Very Long Press - Show Global Actions");
showGlobalActions();
break;
@@ -1598,8 +1598,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY:
mTalkbackShortcutController.toggleTalkback(mCurrentUserId);
if (mTalkbackShortcutController.isTalkBackShortcutGestureEnabled()) {
- performHapticFeedback(HapticFeedbackConstants.CONFIRM, /* always = */
- false, /* reason = */
+ performHapticFeedback(HapticFeedbackConstants.CONFIRM,
"Stem primary - Triple Press - Toggle Accessibility");
}
break;
@@ -1770,7 +1769,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public void run() {
mEndCallKeyHandled = true;
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
"End Call - Long Press - Show Global Actions");
showGlobalActionsInternal();
}
@@ -2086,8 +2085,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return;
}
mHomeConsumed = true;
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
- "Home - Long Press");
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, "Home - Long Press");
switch (mLongPressOnHomeBehavior) {
case LONG_PRESS_HOME_ALL_APPS:
if (mHasFeatureLeanback) {
@@ -2529,7 +2527,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
break;
case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS:
performHapticFeedback(
- HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, false,
+ HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON,
"Power + Volume Up - Global Actions");
showGlobalActions();
mPowerKeyHandled = true;
@@ -3321,6 +3319,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
eventToLog).sendToTarget();
}
+ @Override
+ public KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId) {
+ return mModifierShortcutManager.getApplicationLaunchKeyboardShortcuts(deviceId);
+ }
+
// TODO(b/117479243): handle it in InputPolicy
// TODO (b/283241997): Add the remaining keyboard shortcut logging after refactoring
/** {@inheritDoc} */
@@ -3568,24 +3571,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Slog.wtf(TAG, "KEYCODE_VOICE_ASSIST should be handled in"
+ " interceptKeyBeforeQueueing");
return true;
- case KeyEvent.KEYCODE_VIDEO_APP_1:
- case KeyEvent.KEYCODE_VIDEO_APP_2:
- case KeyEvent.KEYCODE_VIDEO_APP_3:
- case KeyEvent.KEYCODE_VIDEO_APP_4:
- case KeyEvent.KEYCODE_VIDEO_APP_5:
- case KeyEvent.KEYCODE_VIDEO_APP_6:
- case KeyEvent.KEYCODE_VIDEO_APP_7:
- case KeyEvent.KEYCODE_VIDEO_APP_8:
- case KeyEvent.KEYCODE_FEATURED_APP_1:
- case KeyEvent.KEYCODE_FEATURED_APP_2:
- case KeyEvent.KEYCODE_FEATURED_APP_3:
- case KeyEvent.KEYCODE_FEATURED_APP_4:
- case KeyEvent.KEYCODE_DEMO_APP_1:
- case KeyEvent.KEYCODE_DEMO_APP_2:
- case KeyEvent.KEYCODE_DEMO_APP_3:
- case KeyEvent.KEYCODE_DEMO_APP_4:
- Slog.wtf(TAG, "KEYCODE_APP_X should be handled in interceptKeyBeforeQueueing");
- return true;
case KeyEvent.KEYCODE_BRIGHTNESS_UP:
case KeyEvent.KEYCODE_BRIGHTNESS_DOWN:
if (down) {
@@ -5090,8 +5075,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
if (useHapticFeedback) {
- performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, false,
- "Virtual Key - Press");
+ performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, "Virtual Key - Press");
}
if (isWakeKey) {
@@ -5496,9 +5480,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// In case startedGoingToSleep is called after screenTurnedOff (the source caller is in
// order but the methods run on different threads) and updateScreenOffSleepToken was
// skipped. Then acquire sleep token if screen was off.
- if (!mDefaultDisplayPolicy.isScreenOnFully() && !mDefaultDisplayPolicy.isScreenOnEarly()
- && com.android.window.flags.Flags.skipSleepingWhenSwitchingDisplay()) {
- updateScreenOffSleepToken(true /* acquire */, false /* isSwappingDisplay */);
+ if (!mDefaultDisplayPolicy.isScreenOnFully() && !mDefaultDisplayPolicy.isScreenOnEarly()) {
+ updateScreenOffSleepToken(true /* acquire */);
}
if (mKeyguardDelegate != null) {
@@ -5661,9 +5644,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (DEBUG_WAKEUP) Slog.i(TAG, "Display" + displayId + " turned off...");
if (displayId == DEFAULT_DISPLAY) {
- if (!isSwappingDisplay || mIsGoingToSleepDefaultDisplay
- || !com.android.window.flags.Flags.skipSleepingWhenSwitchingDisplay()) {
- updateScreenOffSleepToken(true /* acquire */, isSwappingDisplay);
+ if (!isSwappingDisplay || mIsGoingToSleepDefaultDisplay) {
+ updateScreenOffSleepToken(true /* acquire */);
}
mRequestedOrSleepingDefaultDisplay = false;
mDefaultDisplayPolicy.screenTurnedOff();
@@ -5722,7 +5704,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (displayId == DEFAULT_DISPLAY) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn",
0 /* cookie */);
- updateScreenOffSleepToken(false /* acquire */, false /* isSwappingDisplay */);
+ updateScreenOffSleepToken(false /* acquire */);
mDefaultDisplayPolicy.screenTurningOn(screenOnListener);
mBootAnimationDismissable = false;
@@ -5985,8 +5967,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public void setSafeMode(boolean safeMode) {
mSafeMode = safeMode;
if (safeMode) {
- performHapticFeedback(HapticFeedbackConstants.SAFE_MODE_ENABLED, true,
- "Safe Mode Enabled");
+ performHapticFeedback(Process.myUid(), mContext.getOpPackageName(),
+ HapticFeedbackConstants.SAFE_MODE_ENABLED,
+ "Safe Mode Enabled", HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING,
+ 0 /* privFlags */);
}
}
@@ -6228,9 +6212,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
// TODO (multidisplay): Support multiple displays in WindowManagerPolicy.
- private void updateScreenOffSleepToken(boolean acquire, boolean isSwappingDisplay) {
+ private void updateScreenOffSleepToken(boolean acquire) {
if (acquire) {
- mScreenOffSleepTokenAcquirer.acquire(DEFAULT_DISPLAY, isSwappingDisplay);
+ mScreenOffSleepTokenAcquirer.acquire(DEFAULT_DISPLAY);
} else {
mScreenOffSleepTokenAcquirer.release(DEFAULT_DISPLAY);
}
@@ -6455,9 +6439,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Settings.Global.THEATER_MODE_ON, 0) == 1;
}
- private boolean performHapticFeedback(int effectId, boolean always, String reason) {
+ private boolean performHapticFeedback(int effectId, String reason) {
return performHapticFeedback(Process.myUid(), mContext.getOpPackageName(),
- effectId, always, reason, false /* fromIme */);
+ effectId, reason, 0 /* flags */, 0 /* privFlags */);
}
@Override
@@ -6466,8 +6450,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
- public boolean performHapticFeedback(int uid, String packageName, int effectId,
- boolean always, String reason, boolean fromIme) {
+ public boolean performHapticFeedback(int uid, String packageName, int effectId, String reason,
+ int flags, int privFlags) {
if (!mVibrator.hasVibrator()) {
return false;
}
@@ -6478,7 +6462,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
VibrationAttributes attrs =
mHapticFeedbackVibrationProvider.getVibrationAttributesForHapticFeedback(
- effectId, /* bypassVibrationIntensitySetting= */ always, fromIme);
+ effectId, flags, privFlags);
VibratorFrameworkStatsLogger.logPerformHapticsFeedbackIfKeyboard(uid, effectId);
mVibrator.vibrate(uid, packageName, effect, reason, attrs);
return true;
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 9ca4e273ac39..1b394f65c5eb 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -80,8 +80,10 @@ import android.os.RemoteException;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
+import android.view.HapticFeedbackConstants;
import android.view.IDisplayFoldListener;
import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicyConstants;
@@ -698,6 +700,15 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags);
/**
+ * Return the set of applicaition launch keyboard shortcuts the system supports.
+ *
+ * @param deviceId The id of the {@link InputDevice} that will trigger the shortcut.
+ *
+ * @return {@link KeyboardShortcutGroup} containing the shortcuts.
+ */
+ KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId);
+
+ /**
* Called from the input reader thread before a motion is enqueued when the device is in a
* non-interactive state.
*
@@ -1069,7 +1080,8 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
* Call from application to perform haptic feedback on its window.
*/
public boolean performHapticFeedback(int uid, String packageName, int effectId,
- boolean always, String reason, boolean fromIme);
+ String reason, @HapticFeedbackConstants.Flags int flags,
+ @HapticFeedbackConstants.PrivateFlags int privFlags);
/**
* Called when we have started keeping the screen on because a window
diff --git a/services/core/java/com/android/server/power/LowPowerStandbyController.java b/services/core/java/com/android/server/power/LowPowerStandbyController.java
index fa94b43b6d0e..421471e2eeec 100644
--- a/services/core/java/com/android/server/power/LowPowerStandbyController.java
+++ b/services/core/java/com/android/server/power/LowPowerStandbyController.java
@@ -1380,10 +1380,7 @@ public class LowPowerStandbyController {
Slog.d(TAG, "notifyStandbyPortsChanged");
}
- final Intent intent = new Intent(PowerManager.ACTION_LOW_POWER_STANDBY_PORTS_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
- Manifest.permission.MANAGE_LOW_POWER_STANDBY);
+ sendExplicitBroadcast(PowerManager.ACTION_LOW_POWER_STANDBY_PORTS_CHANGED);
}
/**
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index f85b8cc9c1bb..aa5f5a24f179 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -206,7 +206,6 @@ public class Notifier {
mPolicy = policy;
mFaceDownDetector = faceDownDetector;
mScreenUndimDetector = screenUndimDetector;
- mWakefulnessSessionObserver = new WakefulnessSessionObserver(mContext, null);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
@@ -214,6 +213,7 @@ public class Notifier {
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mTrustManager = mContext.getSystemService(TrustManager.class);
mVibrator = mContext.getSystemService(Vibrator.class);
+ mWakefulnessSessionObserver = new WakefulnessSessionObserver(mContext, null);
mHandler = new NotifierHandler(looper);
mBackgroundExecutor = backgroundExecutor;
@@ -813,6 +813,8 @@ public class Notifier {
if (DEBUG) {
Slog.d(TAG, "onScreenPolicyUpdate: newPolicy=" + newPolicy);
}
+ mWakefulnessSessionObserver.onScreenPolicyUpdate(
+ SystemClock.uptimeMillis(), displayGroupId, newPolicy);
synchronized (mLock) {
Message msg = mHandler.obtainMessage(MSG_SCREEN_POLICY);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index ce0120c245d6..6fe1ccde7a4a 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -33,6 +33,7 @@ import static android.os.PowerManagerInternal.wakefulnessToString;
import static com.android.internal.util.LatencyTracker.ACTION_TURN_ON_SCREEN;
import static com.android.server.deviceidle.Flags.disableWakelocksInLightIdle;
+import static com.android.server.display.DisplayDeviceConfig.INVALID_BRIGHTNESS_IN_CONFIG;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -239,9 +240,6 @@ public final class PowerManagerService extends SystemService
// This should perhaps be a setting.
private static final int SCREEN_BRIGHTNESS_BOOST_TIMEOUT = 5 * 1000;
- // Float.NaN cannot be stored in config.xml so -2 is used instead
- private static final float INVALID_BRIGHTNESS_IN_CONFIG = -2f;
-
// How long a partial wake lock must be held until we consider it a long wake lock.
static final long MIN_LONG_WAKE_CHECK_INTERVAL = 60*1000;
@@ -619,7 +617,6 @@ public final class PowerManagerService extends SystemService
public final float mScreenBrightnessMinimum;
public final float mScreenBrightnessMaximum;
public final float mScreenBrightnessDefault;
- public final float mScreenBrightnessDoze;
public final float mScreenBrightnessDim;
// Value we store for tracking face down behavior.
@@ -1219,8 +1216,6 @@ public final class PowerManagerService extends SystemService
.config_screenBrightnessSettingMaximumFloat);
final float def = mContext.getResources().getFloat(com.android.internal.R.dimen
.config_screenBrightnessSettingDefaultFloat);
- final float doze = mContext.getResources().getFloat(com.android.internal.R.dimen
- .config_screenBrightnessDozeFloat);
final float dim = mContext.getResources().getFloat(com.android.internal.R.dimen
.config_screenBrightnessDimFloat);
@@ -1240,13 +1235,6 @@ public final class PowerManagerService extends SystemService
mScreenBrightnessMaximum = max;
mScreenBrightnessDefault = def;
}
- if (doze == INVALID_BRIGHTNESS_IN_CONFIG) {
- mScreenBrightnessDoze = BrightnessSynchronizer.brightnessIntToFloat(
- mContext.getResources().getInteger(com.android.internal.R.integer
- .config_screenBrightnessDoze));
- } else {
- mScreenBrightnessDoze = doze;
- }
if (dim == INVALID_BRIGHTNESS_IN_CONFIG) {
mScreenBrightnessDim = BrightnessSynchronizer.brightnessIntToFloat(
mContext.getResources().getInteger(com.android.internal.R.integer
@@ -6090,8 +6078,6 @@ public final class PowerManagerService extends SystemService
return mScreenBrightnessDefault;
case PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DIM:
return mScreenBrightnessDim;
- case PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE:
- return mScreenBrightnessDoze;
default:
return PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
diff --git a/services/core/java/com/android/server/power/WakefulnessSessionObserver.java b/services/core/java/com/android/server/power/WakefulnessSessionObserver.java
index d57cd5df41db..3546565480ad 100644
--- a/services/core/java/com/android/server/power/WakefulnessSessionObserver.java
+++ b/services/core/java/com/android/server/power/WakefulnessSessionObserver.java
@@ -16,8 +16,11 @@
package com.android.server.power;
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DIM;
import static android.os.PowerManager.USER_ACTIVITY_EVENT_OTHER;
import static android.os.PowerManagerInternal.isInteractive;
+import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.server.power.PowerManagerService.DEFAULT_SCREEN_OFF_TIMEOUT;
import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_NON_INTERACTIVE;
@@ -34,6 +37,9 @@ import android.app.ActivityManager;
import android.app.SynchronousUserSwitchObserver;
import android.content.Context;
import android.database.ContentObserver;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManagerInternal;
+import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
@@ -44,9 +50,13 @@ import android.provider.Settings;
import android.util.IndentingPrintWriter;
import android.util.SparseArray;
import android.view.Display;
+import android.view.DisplayAddress;
+import android.view.DisplayInfo;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.LocalServices;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -117,9 +127,42 @@ public class WakefulnessSessionObserver {
@Retention(RetentionPolicy.SOURCE)
private @interface OverrideOutcome {}
- private static final int DEFAULT_USER_ACTIVITY = USER_ACTIVITY_EVENT_OTHER;
- private static final long TIMEOUT_USER_INITIATED_REVERT_THRESHOLD_MILLIS = 5000L;
+ private static final int POLICY_REASON_UNKNOWN = FrameworkStatsLog
+ .SCREEN_DIM_REPORTED__POLICY_REASON__UNKNOWN;
+ @VisibleForTesting
+ protected static final int POLICY_REASON_OFF_TIMEOUT = FrameworkStatsLog
+ .SCREEN_DIM_REPORTED__POLICY_REASON__OFF_TIMEOUT;
+ @VisibleForTesting
+ protected static final int POLICY_REASON_OFF_POWER_BUTTON = FrameworkStatsLog
+ .SCREEN_DIM_REPORTED__POLICY_REASON__OFF_POWER_BUTTON;
+ @VisibleForTesting
+ protected static final int POLICY_REASON_BRIGHT_UNDIM = FrameworkStatsLog
+ .SCREEN_DIM_REPORTED__POLICY_REASON__BRIGHT_UNDIM;
+ @VisibleForTesting
+ protected static final int POLICY_REASON_BRIGHT_INITIATED_REVERT = FrameworkStatsLog
+ .SCREEN_DIM_REPORTED__POLICY_REASON__BRIGHT_INITIATED_REVERT;
+
+ /**
+ * Policy Reason
+ * {@link android.os.statsd.power.ScreenDimReported.PolicyReason}.
+ */
+ @IntDef(prefix = {"POLICY_REASON_"}, value = {
+ POLICY_REASON_UNKNOWN,
+ POLICY_REASON_OFF_TIMEOUT,
+ POLICY_REASON_OFF_POWER_BUTTON,
+ POLICY_REASON_BRIGHT_UNDIM,
+ POLICY_REASON_BRIGHT_INITIATED_REVERT
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface PolicyReason {}
+
+ @VisibleForTesting protected static final int DEFAULT_USER_ACTIVITY = USER_ACTIVITY_EVENT_OTHER;
+ private static final long USER_INITIATED_REVERT_THRESHOLD_MILLIS = 5000L;
private static final long SEND_OVERRIDE_TIMEOUT_LOG_THRESHOLD_MILLIS = 1000L;
+ @VisibleForTesting
+ protected static final long SCREEN_POLICY_DIM_POWER_OFF_BRIGHT_THRESHOLD_MILLIS = 500L;
+
+ @VisibleForTesting protected static final Object HANDLER_TOKEN = new Object();
private Context mContext;
private int mScreenOffTimeoutMs;
@@ -130,17 +173,24 @@ public class WakefulnessSessionObserver {
protected WakefulnessSessionFrameworkStatsLogger mWakefulnessSessionFrameworkStatsLogger;
private final Clock mClock;
private final Object mLock = new Object();
+ private final Handler mHandler;
- public WakefulnessSessionObserver(Context context, Injector injector) {
+ private DisplayManagerInternal mDisplayManagerInternal;
+ private int mPhysicalDisplayPortIdForDefaultDisplay;
+
+ public WakefulnessSessionObserver(
+ Context context, Injector injector) {
if (injector == null) {
injector = new Injector();
}
mContext = context;
+ mDisplayManagerInternal = injector.getDisplayManagerInternal();
mWakefulnessSessionFrameworkStatsLogger = injector
.getWakefulnessSessionFrameworkStatsLogger();
mClock = injector.getClock();
- updateSettingScreenOffTimeout(context);
+ mHandler = injector.getHandler();
+ updateSettingScreenOffTimeout(mContext);
try {
final UserSwitchObserver observer = new UserSwitchObserver();
@@ -164,6 +214,31 @@ public class WakefulnessSessionObserver {
},
UserHandle.USER_ALL);
+ mPhysicalDisplayPortIdForDefaultDisplay = getPhysicalDisplayPortId(DEFAULT_DISPLAY);
+ DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+ if (displayManager != null) {
+ displayManager.registerDisplayListener(
+ new DisplayManager.DisplayListener() {
+ @Override
+ public void onDisplayChanged(int displayId) {
+ if (displayId == DEFAULT_DISPLAY) {
+ mPhysicalDisplayPortIdForDefaultDisplay = getPhysicalDisplayPortId(
+ DEFAULT_DISPLAY);
+ }
+ }
+
+ @Override
+ public void onDisplayAdded(int i) {
+ }
+
+ @Override
+ public void onDisplayRemoved(int i) {
+ }
+ },
+ mHandler,
+ DisplayManager.EVENT_FLAG_DISPLAY_CHANGED);
+ }
+
mPowerGroups.append(
Display.DEFAULT_DISPLAY_GROUP,
new WakefulnessSessionPowerGroup(Display.DEFAULT_DISPLAY_GROUP));
@@ -186,6 +261,20 @@ public class WakefulnessSessionObserver {
}
/**
+ * Track the screen policy
+ *
+ * @param eventTime policy changing time, in uptime millis.
+ * @param powerGroupId Power Group Id for this screen policy
+ * @param newPolicy Screen Policy defined in {@link DisplayPowerRequest}
+ */
+ public void onScreenPolicyUpdate(long eventTime, int powerGroupId, int newPolicy) {
+ if (!mPowerGroups.contains(powerGroupId)) {
+ mPowerGroups.append(powerGroupId, new WakefulnessSessionPowerGroup(powerGroupId));
+ }
+ mPowerGroups.get(powerGroupId).onScreenPolicyUpdate(eventTime, newPolicy);
+ }
+
+ /**
* Track the system wakefulness
*
* @param powerGroupId Power Group Id for this wakefulness changes
@@ -267,6 +356,14 @@ public class WakefulnessSessionObserver {
}
}
+ private int getPhysicalDisplayPortId(int displayId) {
+ if (mDisplayManagerInternal == null) {
+ return -1;
+ }
+ DisplayInfo display = mDisplayManagerInternal.getDisplayInfo(displayId);
+ return ((DisplayAddress.Physical) display.address).getPort();
+ }
+
private int getScreenOffTimeout() {
synchronized (mLock) {
return mScreenOffTimeoutMs;
@@ -277,10 +374,9 @@ public class WakefulnessSessionObserver {
@VisibleForTesting
protected class WakefulnessSessionPowerGroup {
private static final long TIMEOUT_OFF_RESET_TIMESTAMP = -1;
-
private int mPowerGroupId;
private int mCurrentWakefulness;
- private boolean mIsInteractive = false;
+ @VisibleForTesting protected boolean mIsInteractive = false;
// state on start timestamp: will be used in state off to calculate the duration of state on
private long mInteractiveStateOnStartTimestamp;
@VisibleForTesting
@@ -295,6 +391,17 @@ public class WakefulnessSessionObserver {
private int mTimeoutOverrideWakeLockCounter = 0;
// The timestamp when Override Timeout is set to false
private @ScreenTimeoutOverridePolicy.ReleaseReason int mTimeoutOverrideReleaseReason;
+ // The timestamp when current screen policy is set
+ private long mCurrentScreenPolicyTimestamp;
+ // current screen policy
+ private int mCurrentScreenPolicy;
+ // The screen policy before the current one
+ private int mPrevScreenPolicy;
+ // The previous screen policy duration
+ private int mPrevScreenPolicyDurationMs;
+ // The past dim duration
+ @VisibleForTesting protected int mPastDimDurationMs;
+ private long mInteractiveOffTimestamp;
// The timestamp when state off by timeout occurs
// will set TIMEOUT_OFF_RESET_TIMESTAMP if state on or state off by power button
private long mTimeoutOffTimestamp;
@@ -307,6 +414,10 @@ public class WakefulnessSessionObserver {
mPrevUserActivityEvent = DEFAULT_USER_ACTIVITY;
mPrevUserActivityTimestamp = -1;
mPowerGroupId = powerGroupId;
+ mCurrentScreenPolicy = mPrevScreenPolicy = POLICY_BRIGHT;
+ mCurrentScreenPolicyTimestamp = 0;
+ mPrevScreenPolicyDurationMs = 0;
+ mPastDimDurationMs = 0;
}
public void notifyUserActivity(long eventTime, @PowerManager.UserActivityEvent int event) {
@@ -320,6 +431,21 @@ public class WakefulnessSessionObserver {
mCurrentUserActivityTimestamp = eventTime;
}
+ public void onScreenPolicyUpdate(long eventTime, int newPolicy) {
+ if (newPolicy == mCurrentScreenPolicy) {
+ return;
+ }
+
+ if (newPolicy == POLICY_BRIGHT) {
+ checkAndLogDimIfQualified(POLICY_REASON_BRIGHT_UNDIM, eventTime);
+ }
+
+ mPrevScreenPolicy = mCurrentScreenPolicy;
+ mCurrentScreenPolicy = newPolicy;
+ mPrevScreenPolicyDurationMs = (int) (eventTime - mCurrentScreenPolicyTimestamp);
+ mCurrentScreenPolicyTimestamp = eventTime;
+ }
+
public void onWakefulnessChangeStarted(int wakefulness, int changeReason, long eventTime) {
mCurrentWakefulness = wakefulness;
if (mIsInteractive == isInteractive(wakefulness)) {
@@ -331,10 +457,10 @@ public class WakefulnessSessionObserver {
mInteractiveStateOnStartTimestamp = eventTime;
// Log the outcome of screen timeout override (USER INITIATED REVERT),
- // when user initiates to revert the screen off state in a short period.
+ // when user initiates to revert the off state in a short period.
if (mTimeoutOffTimestamp != TIMEOUT_OFF_RESET_TIMESTAMP) {
- long offToOnDurationMs = eventTime - mTimeoutOffTimestamp;
- if (offToOnDurationMs < TIMEOUT_USER_INITIATED_REVERT_THRESHOLD_MILLIS) {
+ long timeoutOffToOnDurationMs = eventTime - mTimeoutOffTimestamp;
+ if (timeoutOffToOnDurationMs < USER_INITIATED_REVERT_THRESHOLD_MILLIS) {
mWakefulnessSessionFrameworkStatsLogger.logTimeoutOverrideEvent(
mPowerGroupId,
OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT,
@@ -344,11 +470,15 @@ public class WakefulnessSessionObserver {
}
mTimeoutOffTimestamp = TIMEOUT_OFF_RESET_TIMESTAMP;
}
+
+ checkAndLogDimIfQualified(POLICY_REASON_BRIGHT_INITIATED_REVERT, eventTime);
+
} else {
int lastUserActivity = mCurrentUserActivityEvent;
long lastUserActivityDurationMs = eventTime - mCurrentUserActivityTimestamp;
@OffReason int interactiveStateOffReason = OFF_REASON_UNKNOWN;
int reducedInteractiveStateOnDurationMs = 0;
+ mInteractiveOffTimestamp = eventTime;
if (changeReason == PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON) {
interactiveStateOffReason = OFF_REASON_POWER_BUTTON;
@@ -369,6 +499,9 @@ public class WakefulnessSessionObserver {
mSendOverrideTimeoutLogTimestamp = eventTime;
mTimeoutOverrideReleaseReason = RELEASE_REASON_UNKNOWN; // reset the reason
}
+
+ checkAndLogDimIfQualified(POLICY_REASON_OFF_POWER_BUTTON, eventTime);
+
} else if (changeReason == PowerManager.GO_TO_SLEEP_REASON_TIMEOUT) {
// Interactive Off reason is timeout
interactiveStateOffReason = OFF_REASON_TIMEOUT;
@@ -393,6 +526,8 @@ public class WakefulnessSessionObserver {
// state instantly
mTimeoutOffTimestamp = eventTime;
}
+
+ checkAndLogDimIfQualified(POLICY_REASON_OFF_TIMEOUT, eventTime);
}
long interactiveStateOnDurationMs =
@@ -462,6 +597,106 @@ public class WakefulnessSessionObserver {
}
}
+ private void checkAndLogDimIfQualified(
+ @PolicyReason int reasonToBeChecked, long eventTime) {
+ // Only log dim event when DEFAULT_DISPLAY
+ if (mPowerGroupId != DEFAULT_DISPLAY) {
+ return;
+ }
+
+ int dimDurationMs = 0;
+ int lastUserActivity = mCurrentUserActivityEvent;
+ int lastUserActivityDurationMs = (int) (eventTime - mCurrentUserActivityTimestamp);
+ switch (reasonToBeChecked) {
+ case POLICY_REASON_OFF_TIMEOUT: {
+ // The policy ordering:
+ // (1) --DIM--OFF/DOZE->| or (2) --DIM->| because OFF/DOZE hasn't been updated.
+ dimDurationMs = (int) (eventTime - mCurrentScreenPolicyTimestamp); //(1)--DIM->|
+ if (mPrevScreenPolicy == POLICY_DIM) { // for (2) --DIM--OFF/DOZE->|
+ dimDurationMs = mPrevScreenPolicyDurationMs;
+ }
+ mWakefulnessSessionFrameworkStatsLogger.logDimEvent(
+ mPhysicalDisplayPortIdForDefaultDisplay,
+ reasonToBeChecked,
+ lastUserActivity,
+ lastUserActivityDurationMs,
+ dimDurationMs,
+ mScreenOffTimeoutMs);
+ mPastDimDurationMs = dimDurationMs;
+ return;
+ }
+ case POLICY_REASON_OFF_POWER_BUTTON: {
+ // Power Off will be triggered by USER_ACTIVITY_EVENT_BUTTON
+ // The metric wants to record the previous activity before EVENT_BUTTON
+ lastUserActivity = mPrevUserActivityEvent;
+ lastUserActivityDurationMs = (int) (eventTime - mPrevUserActivityTimestamp);
+ // the policy ordering:
+ // (1) ---BRIGHT->| or (2) ---DIM->| because OFF/DOZE hasn't been updated
+ dimDurationMs = 0; // for (1) ---BRIGHT->| which doesn't have dim (no need log)
+ if (mCurrentScreenPolicy == POLICY_DIM) { // for (2) ---DIM->|
+ dimDurationMs = (int) (eventTime - mCurrentScreenPolicyTimestamp);
+ mWakefulnessSessionFrameworkStatsLogger.logDimEvent(
+ mPhysicalDisplayPortIdForDefaultDisplay,
+ reasonToBeChecked,
+ lastUserActivity,
+ lastUserActivityDurationMs,
+ dimDurationMs,
+ mScreenOffTimeoutMs);
+ mHandler.removeCallbacksAndMessages(HANDLER_TOKEN);
+ }
+
+ mPastDimDurationMs = dimDurationMs;
+ return;
+ }
+ case POLICY_REASON_BRIGHT_UNDIM: {
+ // Has checked the latest screen policy is POLICY_BRIGHT in onScreenPolicyUpdate
+ if (mCurrentScreenPolicy == POLICY_DIM) { // policy ordering: --DIM--BRIGHT->|
+ int savedDimDurationMs = (int) (eventTime - mCurrentScreenPolicyTimestamp);
+ int savedLastUserActivity = lastUserActivity;
+ int savedLastUserActivityDurationMs = lastUserActivityDurationMs;
+
+ // For the undim case --DIM--BRIGHT->|, it needs wait 500 ms to
+ // differentiate between "power button off" case, which is
+ // --DIM--BRIGHT(<500ms)--OFF/DOZE->|
+ // [Method] Wait 500 ms to see whether triggers power button off or not.
+ // [Reason] We got --DIM--BRIGHT->|. However, if BRIGHT is so short (<500ms)
+ // and follows OFF/DOZE, it represents power button off, not undim.
+ // It is normal to have a short BRIGHT for power button off because
+ // the system need to play an animation before off.
+ mHandler.postDelayed(() -> {
+ mWakefulnessSessionFrameworkStatsLogger.logDimEvent(
+ mPhysicalDisplayPortIdForDefaultDisplay,
+ reasonToBeChecked,
+ savedLastUserActivity,
+ savedLastUserActivityDurationMs,
+ savedDimDurationMs,
+ mScreenOffTimeoutMs);
+ mPastDimDurationMs = savedDimDurationMs;
+ }, HANDLER_TOKEN, SCREEN_POLICY_DIM_POWER_OFF_BRIGHT_THRESHOLD_MILLIS);
+ }
+ return;
+ }
+ case POLICY_REASON_BRIGHT_INITIATED_REVERT: {
+ // the dimDuration in BRIGHT_INITIATE_REVERT is for the dim duration before
+ // screen interactive off (mPastDimDurationMs)
+ long offToOnDurationMs = eventTime - mInteractiveOffTimestamp;
+ if (mPastDimDurationMs > 0
+ && offToOnDurationMs < USER_INITIATED_REVERT_THRESHOLD_MILLIS) {
+ mWakefulnessSessionFrameworkStatsLogger.logDimEvent(
+ mPhysicalDisplayPortIdForDefaultDisplay,
+ reasonToBeChecked,
+ lastUserActivity,
+ lastUserActivityDurationMs,
+ mPastDimDurationMs,
+ mScreenOffTimeoutMs);
+ }
+ return;
+ }
+ default:
+ return;
+ }
+ }
+
void dump(IndentingPrintWriter writer) {
final long now = mClock.uptimeMillis();
@@ -475,6 +710,12 @@ public class WakefulnessSessionObserver {
final long prevUserActivityDurationMs = now - mPrevUserActivityTimestamp;
writer.println("previous user activity duration: " + prevUserActivityDurationMs);
writer.println("is in override timeout: " + isInOverrideTimeout());
+ writer.println("mIsInteractive: " + mIsInteractive);
+ writer.println("current screen policy: " + mCurrentScreenPolicy);
+ final long currentScreenPolicyDurationMs = now - mCurrentScreenPolicyTimestamp;
+ writer.println("current screen policy duration: " + currentScreenPolicyDurationMs);
+ writer.println("previous screen policy: " + mPrevScreenPolicy);
+ writer.println("past screen policy duration: " + mPrevScreenPolicyDurationMs);
writer.decreaseIndent();
}
}
@@ -512,6 +753,24 @@ public class WakefulnessSessionObserver {
(long) defaultTimeoutMs);
}
+ public void logDimEvent(
+ int physicalDisplayPortId,
+ @PolicyReason int policyReason,
+ @PowerManager.UserActivityEvent int userActivityEvent,
+ int lastUserActivityEventDurationMs,
+ int dimDurationMs,
+ int defaultTimeoutMs) {
+ int logUserActivityEvent = convertToLogUserActivityEvent(userActivityEvent);
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.SCREEN_DIM_REPORTED,
+ physicalDisplayPortId,
+ policyReason,
+ logUserActivityEvent,
+ lastUserActivityEventDurationMs,
+ dimDurationMs,
+ defaultTimeoutMs);
+ }
+
private static final int USER_ACTIVITY_OTHER = FrameworkStatsLog
.SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__OTHER;
@@ -591,5 +850,13 @@ public class WakefulnessSessionObserver {
Clock getClock() {
return SystemClock::uptimeMillis;
}
+
+ Handler getHandler() {
+ return BackgroundThread.getHandler();
+ }
+
+ DisplayManagerInternal getDisplayManagerInternal() {
+ return LocalServices.getService(DisplayManagerInternal.class);
+ }
}
}
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index 7e27407fc57f..f6c3d8ef1249 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -76,6 +76,7 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
+import java.util.PriorityQueue;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
@@ -109,12 +110,31 @@ public final class HintManagerService extends SystemService {
@GuardedBy("mChannelMapLock")
private ArrayMap<Integer, TreeMap<Integer, ChannelItem>> mChannelMap;
+ /*
+ * Multi-level map storing the session statistics since last pull from StatsD.
+ * The first level is keyed by the UID of the process owning the session.
+ * The second level is keyed by the tag of the session. The point of separating different
+ * tags is that since different categories (e.g. HWUI vs APP) of the sessions may have different
+ * behaviors.
+ */
+ @GuardedBy("mSessionSnapshotMapLock")
+ private ArrayMap<Integer, ArrayMap<Integer, AppHintSessionSnapshot>> mSessionSnapshotMap;
+
/** Lock to protect mActiveSessions and the UidObserver. */
private final Object mLock = new Object();
/** Lock to protect mChannelMap. */
private final Object mChannelMapLock = new Object();
+ /*
+ * Lock to protect mSessionSnapshotMap.
+ * Nested acquisition of mSessionSnapshotMapLock and mLock should be avoided.
+ * We should grab these separately.
+ * When we need to have nested acquisitions, we should always follow the order of acquiring
+ * mSessionSnapshotMapLock first then mLock.
+ */
+ private final Object mSessionSnapshotMapLock = new Object();
+
@GuardedBy("mNonIsolatedTidsLock")
private final Map<Integer, Set<Long>> mNonIsolatedTids;
@@ -135,6 +155,8 @@ public final class HintManagerService extends SystemService {
private int mPowerHalVersion;
private final PackageManager mPackageManager;
+ private boolean mUsesFmq;
+
private static final String PROPERTY_SF_ENABLE_CPU_HINT = "debug.sf.enable_adpf_cpu_hint";
private static final String PROPERTY_HWUI_ENABLE_HINT_MANAGER = "debug.hwui.use_hint_manager";
@@ -162,6 +184,7 @@ public final class HintManagerService extends SystemService {
}
mActiveSessions = new ArrayMap<>();
mChannelMap = new ArrayMap<>();
+ mSessionSnapshotMap = new ArrayMap<>();
mNativeWrapper = injector.createNativeWrapper();
mNativeWrapper.halInit();
mHintSessionPreferredRate = mNativeWrapper.halGetHintSessionPreferredRate();
@@ -170,6 +193,7 @@ public final class HintManagerService extends SystemService {
LocalServices.getService(ActivityManagerInternal.class));
mPowerHal = injector.createIPower();
mPowerHalVersion = 0;
+ mUsesFmq = false;
if (mPowerHal != null) {
try {
mPowerHalVersion = mPowerHal.getInterfaceVersion();
@@ -197,6 +221,134 @@ public final class HintManagerService extends SystemService {
}
}
+ private class AppHintSessionSnapshot {
+ /*
+ * Per-Uid and Per-SessionTag snapshot that tracks metrics including
+ * number of created sessions, number of power efficienct sessions, and
+ * maximum number of threads in a session.
+ * Given that it's Per-SessionTag, each uid can have multiple snapshots.
+ */
+ int mCurrentSessionCount;
+ int mMaxConcurrentSession;
+ int mMaxThreadCount;
+ int mPowerEfficientSessionCount;
+
+ final int mTargetDurationNsCountPQSize = 100;
+ PriorityQueue<TargetDurationRecord> mTargetDurationNsCountPQ;
+
+ class TargetDurationRecord implements Comparable<TargetDurationRecord> {
+ long mTargetDurationNs;
+ long mTimestamp;
+ int mCount;
+ TargetDurationRecord(long targetDurationNs) {
+ mTargetDurationNs = targetDurationNs;
+ mTimestamp = System.currentTimeMillis();
+ mCount = 1;
+ }
+
+ @Override
+ public int compareTo(TargetDurationRecord t) {
+ int tCount = t.getCount();
+ int thisCount = this.getCount();
+ // Here we sort in the order of number of count in ascending order.
+ // i.e. the lowest count of target duration is at the head of the queue.
+ // Upon same count, the tiebreaker is the timestamp, the older item will be at the
+ // front of the queue.
+ if (tCount == thisCount) {
+ return (t.getTimestamp() < this.getTimestamp()) ? 1 : -1;
+ }
+ return (tCount < thisCount) ? 1 : -1;
+ }
+ long getTargetDurationNs() {
+ return mTargetDurationNs;
+ }
+
+ int getCount() {
+ return mCount;
+ }
+
+ long getTimestamp() {
+ return mTimestamp;
+ }
+
+ void setCount(int count) {
+ mCount = count;
+ }
+
+ void setTimestamp() {
+ mTimestamp = System.currentTimeMillis();
+ }
+
+ void setTargetDurationNs(long targetDurationNs) {
+ mTargetDurationNs = targetDurationNs;
+ }
+ }
+
+ AppHintSessionSnapshot() {
+ mCurrentSessionCount = 0;
+ mMaxConcurrentSession = 0;
+ mMaxThreadCount = 0;
+ mPowerEfficientSessionCount = 0;
+ mTargetDurationNsCountPQ = new PriorityQueue<>(1);
+ }
+
+ void updateUponSessionCreation(int threadCount, long targetDuration) {
+ mCurrentSessionCount += 1;
+ mMaxConcurrentSession = Math.max(mMaxConcurrentSession, mCurrentSessionCount);
+ mMaxThreadCount = Math.max(mMaxThreadCount, threadCount);
+ updateTargetDurationNs(targetDuration);
+ }
+
+ void updateUponSessionClose() {
+ mCurrentSessionCount -= 1;
+ }
+
+ void logPowerEfficientSession() {
+ mPowerEfficientSessionCount += 1;
+ }
+
+ void updateThreadCount(int threadCount) {
+ mMaxThreadCount = Math.max(mMaxThreadCount, threadCount);
+ }
+
+ void updateTargetDurationNs(long targetDurationNs) {
+ for (TargetDurationRecord t : mTargetDurationNsCountPQ) {
+ if (t.getTargetDurationNs() == targetDurationNs) {
+ t.setCount(t.getCount() + 1);
+ t.setTimestamp();
+ return;
+ }
+ }
+ if (mTargetDurationNsCountPQ.size() == mTargetDurationNsCountPQSize) {
+ mTargetDurationNsCountPQ.poll();
+ }
+ mTargetDurationNsCountPQ.add(new TargetDurationRecord(targetDurationNs));
+ }
+
+ int getMaxConcurrentSession() {
+ return mMaxConcurrentSession;
+ }
+
+ int getMaxThreadCount() {
+ return mMaxThreadCount;
+ }
+
+ int getPowerEfficientSessionCount() {
+ return mPowerEfficientSessionCount;
+ }
+
+ long[] targetDurationNsList() {
+ final int listSize = 5;
+ long[] targetDurations = new long[listSize];
+ while (mTargetDurationNsCountPQ.size() > listSize) {
+ mTargetDurationNsCountPQ.poll();
+ }
+ for (int i = 0; i < listSize && !mTargetDurationNsCountPQ.isEmpty(); ++i) {
+ targetDurations[i] = mTargetDurationNsCountPQ.poll().getTargetDurationNs();
+ }
+ return targetDurations;
+ }
+ }
private boolean isHalSupported() {
return mHintSessionPreferredRate != -1;
}
@@ -235,6 +387,11 @@ public final class HintManagerService extends SystemService {
null, // use default PullAtomMetadata values
DIRECT_EXECUTOR,
this::onPullAtom);
+ statsManager.setPullAtomCallback(
+ FrameworkStatsLog.ADPF_SESSION_SNAPSHOT,
+ null, // use default PullAtomMetadata values
+ DIRECT_EXECUTOR,
+ this::onPullAtom);
}
private int onPullAtom(int atomTag, @NonNull List<StatsEvent> data) {
@@ -247,11 +404,82 @@ public final class HintManagerService extends SystemService {
data.add(FrameworkStatsLog.buildStatsEvent(
FrameworkStatsLog.ADPF_SYSTEM_COMPONENT_INFO,
isSurfaceFlingerUsingCpuHint,
- isHwuiHintManagerEnabled));
+ isHwuiHintManagerEnabled,
+ getFmqUsage()));
+ }
+ if (atomTag == FrameworkStatsLog.ADPF_SESSION_SNAPSHOT) {
+ synchronized (mSessionSnapshotMapLock) {
+ for (int i = 0; i < mSessionSnapshotMap.size(); ++i) {
+ final int uid = mSessionSnapshotMap.keyAt(i);
+ final ArrayMap<Integer, AppHintSessionSnapshot> sessionSnapshots =
+ mSessionSnapshotMap.valueAt(i);
+ for (int j = 0; j < sessionSnapshots.size(); ++j) {
+ final int sessionTag = sessionSnapshots.keyAt(j);
+ final AppHintSessionSnapshot sessionSnapshot = sessionSnapshots.valueAt(j);
+ data.add(FrameworkStatsLog.buildStatsEvent(
+ FrameworkStatsLog.ADPF_SESSION_SNAPSHOT,
+ uid,
+ sessionTag,
+ sessionSnapshot.getMaxConcurrentSession(),
+ sessionSnapshot.getMaxThreadCount(),
+ sessionSnapshot.getPowerEfficientSessionCount(),
+ sessionSnapshot.targetDurationNsList()
+ ));
+ }
+ }
+ }
+ restoreSessionSnapshot();
}
return android.app.StatsManager.PULL_SUCCESS;
}
+ private int getFmqUsage() {
+ if (mUsesFmq) {
+ return FrameworkStatsLog.ADPFSYSTEM_COMPONENT_INFO__FMQ_SUPPORTED__SUPPORTED;
+ } else if (mPowerHalVersion < 5) {
+ return FrameworkStatsLog.ADPFSYSTEM_COMPONENT_INFO__FMQ_SUPPORTED__HAL_VERSION_NOT_MET;
+ } else {
+ return FrameworkStatsLog.ADPFSYSTEM_COMPONENT_INFO__FMQ_SUPPORTED__UNSUPPORTED;
+ }
+ }
+
+ private void restoreSessionSnapshot() {
+ // clean up snapshot map and rebuild with current active sessions
+ synchronized (mSessionSnapshotMapLock) {
+ mSessionSnapshotMap.clear();
+ synchronized (mLock) {
+ for (int i = 0; i < mActiveSessions.size(); i++) {
+ ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap =
+ mActiveSessions.valueAt(i);
+ for (int j = 0; j < tokenMap.size(); j++) {
+ ArraySet<AppHintSession> sessionSet = tokenMap.valueAt(j);
+ for (int k = 0; k < sessionSet.size(); ++k) {
+ AppHintSession appHintSession = sessionSet.valueAt(k);
+ final int tag = appHintSession.getTag();
+ final int uid = appHintSession.getUid();
+ final long targetDuationNs =
+ appHintSession.getTargetDurationNs();
+ final int threadCount = appHintSession.getThreadIds().length;
+ ArrayMap<Integer, AppHintSessionSnapshot> snapshots =
+ mSessionSnapshotMap.get(uid);
+ if (snapshots == null) {
+ snapshots = new ArrayMap<>();
+ mSessionSnapshotMap.put(uid, snapshots);
+ }
+ AppHintSessionSnapshot snapshot = snapshots.get(tag);
+ if (snapshot == null) {
+ snapshot = new AppHintSessionSnapshot();
+ snapshots.put(tag, snapshot);
+ }
+ snapshot.updateUponSessionCreation(threadCount,
+ targetDuationNs);
+ }
+ }
+ }
+ }
+ }
+ }
+
/**
* Wrapper around the static-native methods from native.
*
@@ -833,17 +1061,13 @@ public final class HintManagerService extends SystemService {
// we change the session tag to SessionTag.GAME
// as it was not previously classified
switch (getUidApplicationCategory(callingUid)) {
- case ApplicationInfo.CATEGORY_GAME:
- tag = SessionTag.GAME;
- break;
- case ApplicationInfo.CATEGORY_UNDEFINED:
+ case ApplicationInfo.CATEGORY_GAME -> tag = SessionTag.GAME;
+ case ApplicationInfo.CATEGORY_UNDEFINED ->
// We use CATEGORY_UNDEFINED to filter the case when
// PackageManager.NameNotFoundException is caught,
// which should not happen.
tag = SessionTag.APP;
- break;
- default:
- tag = SessionTag.APP;
+ default -> tag = SessionTag.APP;
}
}
@@ -889,9 +1113,15 @@ public final class HintManagerService extends SystemService {
logPerformanceHintSessionAtom(
callingUid, sessionId, durationNanos, tids, tag);
+ synchronized (mSessionSnapshotMapLock) {
+ // Update session snapshot upon session creation
+ mSessionSnapshotMap.computeIfAbsent(callingUid, k -> new ArrayMap<>())
+ .computeIfAbsent(tag, k -> new AppHintSessionSnapshot())
+ .updateUponSessionCreation(tids.length, durationNanos);
+ }
synchronized (mLock) {
- AppHintSession hs = new AppHintSession(callingUid, callingTgid, tids, token,
- halSessionPtr, durationNanos);
+ AppHintSession hs = new AppHintSession(callingUid, callingTgid, tag, tids,
+ token, halSessionPtr, durationNanos);
ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap =
mActiveSessions.get(callingUid);
if (tokenMap == null) {
@@ -904,6 +1134,8 @@ public final class HintManagerService extends SystemService {
tokenMap.put(token, sessionSet);
}
sessionSet.add(hs);
+ mUsesFmq = mUsesFmq || hasChannel(callingTgid, callingUid);
+
return hs;
}
} finally {
@@ -996,6 +1228,7 @@ public final class HintManagerService extends SystemService {
final class AppHintSession extends IHintSession.Stub implements IBinder.DeathRecipient {
protected final int mUid;
protected final int mPid;
+ protected final int mTag;
protected int[] mThreadIds;
protected final IBinder mToken;
protected long mHalSessionPtr;
@@ -1003,6 +1236,7 @@ public final class HintManagerService extends SystemService {
protected boolean mUpdateAllowedByProcState;
protected int[] mNewThreadIds;
protected boolean mPowerEfficient;
+ protected boolean mHasBeenPowerEfficient;
protected boolean mShouldForcePause;
private enum SessionModes {
@@ -1010,16 +1244,18 @@ public final class HintManagerService extends SystemService {
};
protected AppHintSession(
- int uid, int pid, int[] threadIds, IBinder token,
+ int uid, int pid, int sessionTag, int[] threadIds, IBinder token,
long halSessionPtr, long durationNanos) {
mUid = uid;
mPid = pid;
+ mTag = sessionTag;
mToken = token;
mThreadIds = threadIds;
mHalSessionPtr = halSessionPtr;
mTargetDurationNanos = durationNanos;
mUpdateAllowedByProcState = true;
mPowerEfficient = false;
+ mHasBeenPowerEfficient = false;
mShouldForcePause = false;
final boolean allowed = mUidObserver.isUidForeground(mUid);
updateHintAllowedByProcState(allowed);
@@ -1056,6 +1292,20 @@ public final class HintManagerService extends SystemService {
mNativeWrapper.halUpdateTargetWorkDuration(mHalSessionPtr, targetDurationNanos);
mTargetDurationNanos = targetDurationNanos;
}
+ synchronized (mSessionSnapshotMapLock) {
+ ArrayMap<Integer, AppHintSessionSnapshot> sessionSnapshots =
+ mSessionSnapshotMap.get(mUid);
+ if (sessionSnapshots == null) {
+ Slogf.w(TAG, "Session snapshot map is null for uid " + mUid);
+ return;
+ }
+ AppHintSessionSnapshot sessionSnapshot = sessionSnapshots.get(mTag);
+ if (sessionSnapshot == null) {
+ Slogf.w(TAG, "Session snapshot is null for uid " + mUid + " and tag " + mTag);
+ return;
+ }
+ sessionSnapshot.updateTargetDurationNs(mTargetDurationNanos);
+ }
}
@Override
@@ -1108,6 +1358,20 @@ public final class HintManagerService extends SystemService {
if (sessionSet.isEmpty()) tokenMap.remove(mToken);
if (tokenMap.isEmpty()) mActiveSessions.remove(mUid);
}
+ synchronized (mSessionSnapshotMapLock) {
+ ArrayMap<Integer, AppHintSessionSnapshot> sessionSnapshots =
+ mSessionSnapshotMap.get(mUid);
+ if (sessionSnapshots == null) {
+ Slogf.w(TAG, "Session snapshot map is null for uid " + mUid);
+ return;
+ }
+ AppHintSessionSnapshot sessionSnapshot = sessionSnapshots.get(mTag);
+ if (sessionSnapshot == null) {
+ Slogf.w(TAG, "Session snapshot is null for uid " + mUid + " and tag " + mTag);
+ return;
+ }
+ sessionSnapshot.updateUponSessionClose();
+ }
if (powerhintThreadCleanup()) {
synchronized (mNonIsolatedTidsLock) {
final int[] tids = getTidsInternal();
@@ -1191,6 +1455,21 @@ public final class HintManagerService extends SystemService {
mShouldForcePause = false;
}
}
+ synchronized (mSessionSnapshotMapLock) {
+ ArrayMap<Integer, AppHintSessionSnapshot> sessionSnapshots =
+ mSessionSnapshotMap.get(mUid);
+ if (sessionSnapshots == null) {
+ Slogf.w(TAG, "Session snapshot map is null for uid " + mUid);
+ return;
+ }
+ AppHintSessionSnapshot sessionSnapshot = sessionSnapshots.get(mTag);
+ if (sessionSnapshot == null) {
+ Slogf.w(TAG, "Session snapshot is null for uid " + mUid + " and tag "
+ + mTag);
+ return;
+ }
+ sessionSnapshot.updateThreadCount(tids.length);
+ }
}
public int[] getThreadIds() {
@@ -1231,6 +1510,26 @@ public final class HintManagerService extends SystemService {
}
mNativeWrapper.halSetMode(mHalSessionPtr, mode, enabled);
}
+ if (enabled && (mode == SessionModes.POWER_EFFICIENCY.ordinal())) {
+ if (!mHasBeenPowerEfficient) {
+ mHasBeenPowerEfficient = true;
+ synchronized (mSessionSnapshotMapLock) {
+ ArrayMap<Integer, AppHintSessionSnapshot> sessionSnapshots =
+ mSessionSnapshotMap.get(mUid);
+ if (sessionSnapshots == null) {
+ Slogf.w(TAG, "Session snapshot map is null for uid " + mUid);
+ return;
+ }
+ AppHintSessionSnapshot sessionSnapshot = sessionSnapshots.get(mTag);
+ if (sessionSnapshot == null) {
+ Slogf.w(TAG, "Session snapshot is null for uid " + mUid
+ + " and tag " + mTag);
+ return;
+ }
+ sessionSnapshot.logPowerEfficientSession();
+ }
+ }
+ }
}
@Override
@@ -1254,6 +1553,20 @@ public final class HintManagerService extends SystemService {
}
}
+ public int getUid() {
+ return mUid;
+ }
+
+ public int getTag() {
+ return mTag;
+ }
+
+ public long getTargetDurationNs() {
+ synchronized (this) {
+ return mTargetDurationNanos;
+ }
+ }
+
void validateWorkDuration(WorkDuration workDuration) {
if (DEBUG) {
Slogf.d(TAG, "WorkDuration("
diff --git a/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java
index 6d519ee200c2..90981ada7c31 100644
--- a/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java
+++ b/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java
@@ -86,8 +86,7 @@ public class WifiPowerStatsCollector extends PowerStatsCollector {
private ConsumedEnergyRetriever mConsumedEnergyRetriever;
private IntSupplier mVoltageSupplier;
private int[] mEnergyConsumerIds = new int[0];
- private WifiActivityEnergyInfo mLastWifiActivityInfo =
- new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0);
+ private WifiActivityEnergyInfo mLastWifiActivityInfo;
private NetworkStats mLastNetworkStats;
private long[] mLastConsumedEnergyUws;
private int mLastVoltageMv;
@@ -206,14 +205,21 @@ public class WifiPowerStatsCollector extends PowerStatsCollector {
return null;
}
- long rxDuration = activityInfo.getControllerRxDurationMillis()
- - mLastWifiActivityInfo.getControllerRxDurationMillis();
- long txDuration = activityInfo.getControllerTxDurationMillis()
- - mLastWifiActivityInfo.getControllerTxDurationMillis();
- long scanDuration = activityInfo.getControllerScanDurationMillis()
- - mLastWifiActivityInfo.getControllerScanDurationMillis();
- long idleDuration = activityInfo.getControllerIdleDurationMillis()
- - mLastWifiActivityInfo.getControllerIdleDurationMillis();
+ long rxDuration = 0;
+ long txDuration = 0;
+ long scanDuration = 0;
+ long idleDuration = 0;
+
+ if (mLastWifiActivityInfo != null) {
+ rxDuration = activityInfo.getControllerRxDurationMillis()
+ - mLastWifiActivityInfo.getControllerRxDurationMillis();
+ txDuration = activityInfo.getControllerTxDurationMillis()
+ - mLastWifiActivityInfo.getControllerTxDurationMillis();
+ scanDuration = activityInfo.getControllerScanDurationMillis()
+ - mLastWifiActivityInfo.getControllerScanDurationMillis();
+ idleDuration = activityInfo.getControllerIdleDurationMillis()
+ - mLastWifiActivityInfo.getControllerIdleDurationMillis();
+ }
mLayout.setDeviceRxTime(mDeviceStats, rxDuration);
mLayout.setDeviceTxTime(mDeviceStats, txDuration);
diff --git a/services/core/java/com/android/server/power/stats/flags.aconfig b/services/core/java/com/android/server/power/stats/flags.aconfig
index 6a5a7ac8d240..d34498a3764b 100644
--- a/services/core/java/com/android/server/power/stats/flags.aconfig
+++ b/services/core/java/com/android/server/power/stats/flags.aconfig
@@ -47,3 +47,10 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "add_battery_usage_stats_slice_atom"
+ namespace: "backstage_power"
+ description: "Adds battery_usage_stats_slice atom"
+ bug: "324602949"
+}
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index 8f39ffb3f53c..685ab3a9424f 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -16,6 +16,8 @@
package com.android.server.rollback;
+import static android.crashrecovery.flags.Flags.deprecateFlagsAndSettingsResets;
+
import static com.android.server.rollback.RollbackManagerServiceImpl.sendFailure;
import android.Manifest;
@@ -623,8 +625,10 @@ class Rollback {
parentSession.addChildSessionId(sessionId);
}
- // Clear flags.
- RescueParty.resetDeviceConfigForPackages(packageNames);
+ if (!deprecateFlagsAndSettingsResets()) {
+ // Clear flags.
+ RescueParty.resetDeviceConfigForPackages(packageNames);
+ }
Consumer<Intent> onResult = result -> {
mHandler.post(() -> {
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index c85ceac9ea55..4f28e023da92 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -154,12 +154,22 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
}
}
+ Slog.i(TAG, "Checking available remediations for health check failure."
+ + " failedPackage: "
+ + (failedPackage == null ? null : failedPackage.getPackageName())
+ + " failureReason: " + failureReason
+ + " available impact: " + impact);
return impact;
}
@Override
public boolean execute(@Nullable VersionedPackage failedPackage,
@FailureReasons int rollbackReason, int mitigationCount) {
+ Slog.i(TAG, "Executing remediation."
+ + " failedPackage: "
+ + (failedPackage == null ? null : failedPackage.getPackageName())
+ + " rollbackReason: " + rollbackReason
+ + " mitigationCount: " + mitigationCount);
if (Flags.recoverabilityDetection()) {
List<RollbackInfo> availableRollbacks = getAvailableRollbacks();
if (rollbackReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH) {
@@ -503,6 +513,10 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
@FailureReasons int rollbackReason) {
assertInWorkerThread();
+ Slog.i(TAG, "Rolling back package. RollbackId: " + rollback.getRollbackId()
+ + " failedPackage: "
+ + (failedPackage == null ? null : failedPackage.getPackageName())
+ + " rollbackReason: " + rollbackReason);
final RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
int reasonToLog = WatchdogRollbackLogger.mapFailureReasonToMetric(rollbackReason);
final String failedPackageToLog;
diff --git a/services/core/java/com/android/server/stats/pull/RawSettingsTelemetryUtil.java b/services/core/java/com/android/server/stats/pull/RawSettingsTelemetryUtil.java
new file mode 100644
index 000000000000..905f38a0b646
--- /dev/null
+++ b/services/core/java/com/android/server/stats/pull/RawSettingsTelemetryUtil.java
@@ -0,0 +1,83 @@
+/*
+ * 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.stats.pull;
+
+import static android.provider.Settings.System.PEAK_REFRESH_RATE;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.util.Log;
+
+import com.android.internal.display.RefreshRateSettingsUtils;
+
+/**
+ * Utility methods for processing raw settings values to the format that
+ * is acceptable for telemetry system.
+ * For instance, raw setting values could be hard to visualize on dashboards, etc.
+ */
+public final class RawSettingsTelemetryUtil {
+
+ private static final String TAG = "SettingsTelemetryUtil";
+
+ /**
+ * Get string that should be written as a value of settingKey and should be sent to telemetry
+ * system.
+ *
+ * @param context The context
+ * @param key The setting key
+ * @param value The setting raw value that was parsed from Settings.
+ * @return The setting string value that should be sent to telemetry system.
+ */
+ @Nullable
+ public static String getTelemetrySettingFromRawVal(Context context, String key, String value) {
+ if (key == null) {
+ return null;
+ }
+
+ if (key.equals(PEAK_REFRESH_RATE)) {
+ return getPeakRefreshRateSetting(context, value);
+ }
+
+ return value;
+ }
+
+ /**
+ * Get string that should be written as a value of "peak_refresh_setting" setting
+ * and should be sent to telemetry.
+ * system.
+ *
+ * @param context The context
+ * @param settingRawValue The setting raw value that was parsed from Settings.
+ * @return The "peak_refresh_setting" string value that should be sent to telemetry system.
+ */
+ @Nullable
+ private static String getPeakRefreshRateSetting(Context context, String settingRawValue) {
+ if (settingRawValue == null) {
+ Log.e(TAG, "PEAK_REFRESH_RATE value is null");
+ return null;
+ }
+
+ String floatInfinityStr = Float.toString(Float.POSITIVE_INFINITY);
+ if (settingRawValue.equals(floatInfinityStr)) {
+ float max_refresh_rate =
+ RefreshRateSettingsUtils.findHighestRefreshRateAmongAllBuiltInDisplays(context);
+ return Float.toString(max_refresh_rate);
+ }
+
+ return settingRawValue;
+ }
+}
diff --git a/services/core/java/com/android/server/stats/pull/SettingsStatsUtil.java b/services/core/java/com/android/server/stats/pull/SettingsStatsUtil.java
index 7cdb84ba0404..2a4a39c1d5e9 100644
--- a/services/core/java/com/android/server/stats/pull/SettingsStatsUtil.java
+++ b/services/core/java/com/android/server/stats/pull/SettingsStatsUtil.java
@@ -107,7 +107,9 @@ final class SettingsStatsUtil {
}
for (String key : proto.element) {
final String value = Settings.System.getStringForUser(resolver, key, userId);
- output.add(createStatsEvent(atomTag, key, value, userId,
+ final String telemetryValue =
+ RawSettingsTelemetryUtil.getTelemetrySettingFromRawVal(context, key, value);
+ output.add(createStatsEvent(atomTag, key, telemetryValue, userId,
flagsData.mDataType));
}
}
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 0041d39f4b2b..bca81f52a1ac 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -1283,7 +1283,7 @@ public class StatsPullAtomService extends SystemService {
}
case FrameworkStatsLog.PROXY_BYTES_TRANSFER_BY_FG_BG: {
final NetworkStats stats = getUidNetworkStatsSnapshotForTemplate(
- new NetworkTemplate.Builder(MATCH_PROXY).build(), /*includeTags=*/true);
+ new NetworkTemplate.Builder(MATCH_PROXY).build(), /*includeTags=*/false);
if (stats != null) {
ret.add(new NetworkStatsExt(sliceNetworkStatsByUidTagAndMetered(stats),
new int[]{TRANSPORT_BLUETOOTH},
@@ -1542,6 +1542,11 @@ public class StatsPullAtomService extends SystemService {
final long bucketDuration = Settings.Global.getLong(mContext.getContentResolver(),
NETSTATS_UID_BUCKET_DURATION, NETSTATS_UID_DEFAULT_BUCKET_DURATION_MS);
+ // Set startTime before boot so that NetworkStats includes at least one full bucket.
+ // Set endTime in the future so that NetworkStats includes everything in the active bucket.
+ final long startTime = currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration;
+ final long endTime = currentTimeInMillis + bucketDuration;
+
// TODO (b/156313635): This is short-term hack to allow perfd gets updated networkStats
// history when query in every second in order to show realtime statistics. However,
// this is not a good long-term solution since NetworkStatsService will make frequent
@@ -1552,9 +1557,7 @@ public class StatsPullAtomService extends SystemService {
}
final android.app.usage.NetworkStats queryNonTaggedStats =
- getNetworkStatsManager().querySummary(
- template, currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration,
- currentTimeInMillis);
+ getNetworkStatsManager().querySummary(template, startTime, endTime);
final NetworkStats nonTaggedStats =
NetworkStatsUtils.fromPublicNetworkStats(queryNonTaggedStats);
@@ -1562,9 +1565,7 @@ public class StatsPullAtomService extends SystemService {
if (!includeTags) return nonTaggedStats;
final android.app.usage.NetworkStats queryTaggedStats =
- getNetworkStatsManager().queryTaggedSummary(template,
- currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration,
- currentTimeInMillis);
+ getNetworkStatsManager().queryTaggedSummary(template, startTime, endTime);
final NetworkStats taggedStats =
NetworkStatsUtils.fromPublicNetworkStats(queryTaggedStats);
queryTaggedStats.close();
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index ddbd8091b601..953aae9588dd 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.trust;
+import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth;
import static android.service.trust.GrantTrustResult.STATUS_UNLOCKED_BY_GRANT;
import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;
@@ -84,6 +85,9 @@ import com.android.internal.content.PackageMonitor;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockSettingsInternal;
+import com.android.internal.widget.LockSettingsStateListener;
+import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.servicewatcher.CurrentUserServiceSupplier;
import com.android.server.servicewatcher.ServiceWatcher;
@@ -159,6 +163,7 @@ public class TrustManagerService extends SystemService {
/* package */ final TrustArchive mArchive = new TrustArchive();
private final Context mContext;
+ private final LockSettingsInternal mLockSettings;
private final LockPatternUtils mLockPatternUtils;
private final KeyStoreAuthorization mKeyStoreAuthorization;
private final UserManager mUserManager;
@@ -250,6 +255,20 @@ public class TrustManagerService extends SystemService {
private final StrongAuthTracker mStrongAuthTracker;
+ // Used to subscribe to device credential auth attempts.
+ private final LockSettingsStateListener mLockSettingsStateListener =
+ new LockSettingsStateListener() {
+ @Override
+ public void onAuthenticationSucceeded(int userId) {
+ mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, 1, userId).sendToTarget();
+ }
+
+ @Override
+ public void onAuthenticationFailed(int userId) {
+ mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, 0, userId).sendToTarget();
+ }
+ };
+
private boolean mTrustAgentsCanRun = false;
private int mCurrentUser = UserHandle.USER_SYSTEM;
@@ -294,6 +313,7 @@ public class TrustManagerService extends SystemService {
mHandler = createHandler(injector.getLooper());
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+ mLockSettings = LocalServices.getService(LockSettingsInternal.class);
mLockPatternUtils = injector.getLockPatternUtils();
mKeyStoreAuthorization = injector.getKeyStoreAuthorization();
mStrongAuthTracker = new StrongAuthTracker(context, injector.getLooper());
@@ -315,6 +335,9 @@ public class TrustManagerService extends SystemService {
checkNewAgents();
mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
mReceiver.register(mContext);
+ if (shouldTrustManagerListenForPrimaryAuth()) {
+ mLockSettings.registerLockSettingsStateListener(mLockSettingsStateListener);
+ }
mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
mFingerprintManager = mContext.getSystemService(FingerprintManager.class);
mFaceManager = mContext.getSystemService(FaceManager.class);
diff --git a/services/core/java/com/android/server/updates/Android.bp b/services/core/java/com/android/server/updates/Android.bp
new file mode 100644
index 000000000000..10beebb82711
--- /dev/null
+++ b/services/core/java/com/android/server/updates/Android.bp
@@ -0,0 +1,11 @@
+aconfig_declarations {
+ name: "updates_flags",
+ package: "com.android.server.updates",
+ container: "system",
+ srcs: ["*.aconfig"],
+}
+
+java_aconfig_library {
+ name: "updates_flags_lib",
+ aconfig_declarations: "updates_flags",
+}
diff --git a/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java b/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java
index bf32045146f6..af4025e1db7c 100644
--- a/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java
@@ -16,17 +16,15 @@
package com.android.server.updates;
+import android.content.Context;
+import android.content.Intent;
import android.os.FileUtils;
import android.system.ErrnoException;
import android.system.Os;
-import android.util.Base64;
import android.util.Slog;
-import com.android.internal.util.HexDump;
-
import libcore.io.Streams;
-import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -36,10 +34,7 @@ import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
public class CertificateTransparencyLogInstallReceiver extends ConfigUpdateInstallReceiver {
@@ -47,36 +42,36 @@ public class CertificateTransparencyLogInstallReceiver extends ConfigUpdateInsta
private static final String LOGDIR_PREFIX = "logs-";
public CertificateTransparencyLogInstallReceiver() {
- super("/data/misc/keychain/trusted_ct_logs/", "ct_logs", "metadata/", "version");
+ super("/data/misc/keychain/ct/", "ct_logs", "metadata/", "version");
}
@Override
protected void install(InputStream inputStream, int version) throws IOException {
- /* Install is complicated here because we translate the input, which is a JSON file
- * containing log information to a directory with a file per log. To support atomically
- * replacing the old configuration directory with the new there's a bunch of steps. We
- * create a new directory with the logs and then do an atomic update of the current symlink
- * to point to the new directory.
- */
+ if (!Flags.certificateTransparencyInstaller()) {
+ return;
+ }
+ // To support atomically replacing the old configuration directory with the new there's a
+ // bunch of steps. We create a new directory with the logs and then do an atomic update of
+ // the current symlink to point to the new directory.
// 1. Ensure that the update dir exists and is readable
updateDir.mkdir();
if (!updateDir.isDirectory()) {
throw new IOException("Unable to make directory " + updateDir.getCanonicalPath());
}
if (!updateDir.setReadable(true, false)) {
- throw new IOException("Unable to set permissions on " +
- updateDir.getCanonicalPath());
+ throw new IOException("Unable to set permissions on " + updateDir.getCanonicalPath());
}
File currentSymlink = new File(updateDir, "current");
File newVersion = new File(updateDir, LOGDIR_PREFIX + String.valueOf(version));
- File oldDirectory;
// 2. Handle the corner case where the new directory already exists.
if (newVersion.exists()) {
// If the symlink has already been updated then the update died between steps 7 and 8
// and so we cannot delete the directory since its in use. Instead just bump the version
// and return.
if (newVersion.getCanonicalPath().equals(currentSymlink.getCanonicalPath())) {
- writeUpdate(updateDir, updateVersion,
+ writeUpdate(
+ updateDir,
+ updateVersion,
new ByteArrayInputStream(Long.toString(version).getBytes()));
deleteOldLogDirectories();
return;
@@ -85,28 +80,18 @@ public class CertificateTransparencyLogInstallReceiver extends ConfigUpdateInsta
}
}
try {
- // 3. Create /data/misc/keychain/trusted_ct_logs/<new_version>/ .
+ // 3. Create /data/misc/keychain/ct/<new_version>/ .
newVersion.mkdir();
if (!newVersion.isDirectory()) {
throw new IOException("Unable to make directory " + newVersion.getCanonicalPath());
}
if (!newVersion.setReadable(true, false)) {
- throw new IOException("Failed to set " +newVersion.getCanonicalPath() +
- " readable");
+ throw new IOException(
+ "Failed to set " + newVersion.getCanonicalPath() + " readable");
}
- // 4. For each log in the log file create the corresponding file in <new_version>/ .
- try {
- byte[] content = Streams.readFullyNoClose(inputStream);
- JSONObject json = new JSONObject(new String(content, StandardCharsets.UTF_8));
- JSONArray logs = json.getJSONArray("logs");
- for (int i = 0; i < logs.length(); i++) {
- JSONObject log = logs.getJSONObject(i);
- installLog(newVersion, log);
- }
- } catch (JSONException e) {
- throw new IOException("Failed to parse logs", e);
- }
+ // 4. Validate the log list json and move the file in <new_version>/ .
+ installLogList(newVersion, inputStream);
// 5. Create the temp symlink. We'll rename this to the target symlink to get an atomic
// update.
@@ -125,62 +110,53 @@ public class CertificateTransparencyLogInstallReceiver extends ConfigUpdateInsta
}
Slog.i(TAG, "CT log directory updated to " + newVersion.getAbsolutePath());
// 7. Update the current version information
- writeUpdate(updateDir, updateVersion,
+ writeUpdate(
+ updateDir,
+ updateVersion,
new ByteArrayInputStream(Long.toString(version).getBytes()));
// 8. Cleanup
deleteOldLogDirectories();
}
- private void installLog(File directory, JSONObject logObject) throws IOException {
+ @Override
+ protected void postInstall(Context context, Intent intent) {
+ if (!Flags.certificateTransparencyInstaller()) {
+ return;
+ }
+ }
+
+ private void installLogList(File directory, InputStream inputStream) throws IOException {
try {
- String logFilename = getLogFileName(logObject.getString("key"));
- File file = new File(directory, logFilename);
- try (OutputStreamWriter out =
- new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)) {
- writeLogEntry(out, "key", logObject.getString("key"));
- writeLogEntry(out, "url", logObject.getString("url"));
- writeLogEntry(out, "description", logObject.getString("description"));
+ byte[] content = Streams.readFullyNoClose(inputStream);
+ if (new JSONObject(new String(content, StandardCharsets.UTF_8)).length() == 0) {
+ throw new IOException("Log list data not valid");
+ }
+
+ File file = new File(directory, "log_list.json");
+ try (FileOutputStream outputStream = new FileOutputStream(file)) {
+ outputStream.write(content);
}
if (!file.setReadable(true, false)) {
throw new IOException("Failed to set permissions on " + file.getCanonicalPath());
}
} catch (JSONException e) {
- throw new IOException("Failed to parse log", e);
- }
-
- }
-
- /**
- * Get the filename for a log based on its public key. This must be kept in sync with
- * org.conscrypt.ct.CTLogStoreImpl.
- */
- private String getLogFileName(String base64PublicKey) {
- byte[] keyBytes = Base64.decode(base64PublicKey, Base64.DEFAULT);
- try {
- byte[] id = MessageDigest.getInstance("SHA-256").digest(keyBytes);
- return HexDump.toHexString(id, false);
- } catch (NoSuchAlgorithmException e) {
- // SHA-256 is guaranteed to be available.
- throw new RuntimeException(e);
+ throw new IOException("Malformed json in log list", e);
}
}
- private void writeLogEntry(OutputStreamWriter out, String key, String value)
- throws IOException {
- out.write(key + ":" + value + "\n");
- }
-
private void deleteOldLogDirectories() throws IOException {
if (!updateDir.exists()) {
return;
}
File currentTarget = new File(updateDir, "current").getCanonicalFile();
- FileFilter filter = new FileFilter() {
- @Override
- public boolean accept(File file) {
- return !currentTarget.equals(file) && file.getName().startsWith(LOGDIR_PREFIX);
- }
- };
+ FileFilter filter =
+ new FileFilter() {
+ @Override
+ public boolean accept(File file) {
+ return !currentTarget.equals(file)
+ && file.getName().startsWith(LOGDIR_PREFIX);
+ }
+ };
for (File f : updateDir.listFiles(filter)) {
FileUtils.deleteContentsAndDir(f);
}
diff --git a/services/core/java/com/android/server/updates/flags.aconfig b/services/core/java/com/android/server/updates/flags.aconfig
new file mode 100644
index 000000000000..476cb3723c97
--- /dev/null
+++ b/services/core/java/com/android/server/updates/flags.aconfig
@@ -0,0 +1,10 @@
+package: "com.android.server.updates"
+container: "system"
+
+flag {
+ name: "certificate_transparency_installer"
+ is_exported: true
+ namespace: "network_security"
+ description: "Enable certificate transparency installer for log list data"
+ bug: "319829948"
+}
diff --git a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java
index 8138168f609e..98a2ba0d62cf 100644
--- a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java
+++ b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java
@@ -186,13 +186,13 @@ public final class HapticFeedbackVibrationProvider {
*
* @param effectId the haptic feedback effect ID whose respective vibration attributes we want
* to get.
- * @param bypassVibrationIntensitySetting {@code true} if the returned attribute should bypass
- * vibration intensity settings. {@code false} otherwise.
- * @param fromIme the haptic feedback is performed from an IME.
+ * @param flags Additional flags as per {@link HapticFeedbackConstants}.
+ * @param privFlags Additional private flags as per {@link HapticFeedbackConstants}.
* @return the {@link VibrationAttributes} that should be used for the provided haptic feedback.
*/
- public VibrationAttributes getVibrationAttributesForHapticFeedback(
- int effectId, boolean bypassVibrationIntensitySetting, boolean fromIme) {
+ public VibrationAttributes getVibrationAttributesForHapticFeedback(int effectId,
+ @HapticFeedbackConstants.Flags int flags,
+ @HapticFeedbackConstants.PrivateFlags int privFlags) {
VibrationAttributes attrs;
switch (effectId) {
case HapticFeedbackConstants.EDGE_SQUEEZE:
@@ -208,7 +208,7 @@ public final class HapticFeedbackVibrationProvider {
break;
case HapticFeedbackConstants.KEYBOARD_TAP:
case HapticFeedbackConstants.KEYBOARD_RELEASE:
- attrs = createKeyboardVibrationAttributes(fromIme);
+ attrs = createKeyboardVibrationAttributes(privFlags);
break;
case HapticFeedbackConstants.BIOMETRIC_CONFIRM:
case HapticFeedbackConstants.BIOMETRIC_REJECT:
@@ -218,18 +218,23 @@ public final class HapticFeedbackVibrationProvider {
attrs = TOUCH_VIBRATION_ATTRIBUTES;
}
- int flags = 0;
+ int vibFlags = 0;
+ boolean fromIme =
+ (privFlags & HapticFeedbackConstants.PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS) != 0;
+ boolean bypassVibrationIntensitySetting =
+ (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0;
if (bypassVibrationIntensitySetting) {
- flags |= VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF;
+ vibFlags |= VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF;
}
if (shouldBypassInterruptionPolicy(effectId)) {
- flags |= VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
+ vibFlags |= VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
}
if (shouldBypassIntensityScale(effectId, fromIme)) {
- flags |= VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE;
+ vibFlags |= VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE;
}
- return flags == 0 ? attrs : new VibrationAttributes.Builder(attrs).setFlags(flags).build();
+ return vibFlags == 0 ? attrs : new VibrationAttributes.Builder(attrs)
+ .setFlags(vibFlags).build();
}
/**
@@ -373,12 +378,16 @@ public final class HapticFeedbackVibrationProvider {
return false;
}
- private VibrationAttributes createKeyboardVibrationAttributes(boolean fromIme) {
- // Use touch attribute when the keyboard category is disable or it's not from an IME.
- if (!Flags.keyboardCategoryEnabled() || !fromIme) {
+ private VibrationAttributes createKeyboardVibrationAttributes(
+ @HapticFeedbackConstants.PrivateFlags int privFlags) {
+ // Use touch attribute when the keyboard category is disable.
+ if (!Flags.keyboardCategoryEnabled()) {
+ return TOUCH_VIBRATION_ATTRIBUTES;
+ }
+ // Use touch attribute when the haptic is not apply to IME.
+ if ((privFlags & HapticFeedbackConstants.PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS) == 0) {
return TOUCH_VIBRATION_ATTRIBUTES;
}
-
return new VibrationAttributes.Builder(TOUCH_VIBRATION_ATTRIBUTES)
.setCategory(VibrationAttributes.CATEGORY_KEYBOARD)
.build();
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index 2fc183d9113f..02061555a37f 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -532,7 +532,8 @@ final class VibrationSettings {
return false;
}
- if (Flags.keyboardCategoryEnabled() && mVibrationConfig.hasFixedKeyboardAmplitude()) {
+ if (Flags.keyboardCategoryEnabled()
+ && mVibrationConfig.isKeyboardVibrationSettingsSupported()) {
int category = callerInfo.attrs.getCategory();
if (usage == USAGE_TOUCH && category == CATEGORY_KEYBOARD) {
// Keyboard touch has a different user setting.
@@ -556,8 +557,8 @@ final class VibrationSettings {
mVibrateInputDevices =
loadSystemSetting(Settings.System.VIBRATE_INPUT_DEVICES, 0, userHandle) > 0;
mVibrateOn = loadSystemSetting(Settings.System.VIBRATE_ON, 1, userHandle) > 0;
- mKeyboardVibrationOn = loadSystemSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED,
- mVibrationConfig.isDefaultKeyboardVibrationEnabled() ? 1 : 0, userHandle) > 0;
+ mKeyboardVibrationOn = loadSystemSetting(
+ Settings.System.KEYBOARD_VIBRATION_ENABLED, 1, userHandle) > 0;
int alarmIntensity = toIntensity(
loadSystemSetting(Settings.System.ALARM_VIBRATION_INTENSITY, -1, userHandle),
@@ -644,12 +645,10 @@ final class VibrationSettings {
.append("), ");
}
vibrationIntensitiesString.append('}');
- String keyboardVibrationOnString = mKeyboardVibrationOn
- + " (default: " + mVibrationConfig.isDefaultKeyboardVibrationEnabled() + ")";
return "VibrationSettings{"
+ "mVibratorConfig=" + mVibrationConfig
+ ", mVibrateOn=" + mVibrateOn
- + ", mKeyboardVibrationOn=" + keyboardVibrationOnString
+ + ", mKeyboardVibrationOn=" + mKeyboardVibrationOn
+ ", mVibrateInputDevices=" + mVibrateInputDevices
+ ", mBatterySaverMode=" + mBatterySaverMode
+ ", mRingerMode=" + ringerModeToString(mRingerMode)
@@ -666,8 +665,7 @@ final class VibrationSettings {
pw.println("VibrationSettings:");
pw.increaseIndent();
pw.println("vibrateOn = " + mVibrateOn);
- pw.println("keyboardVibrationOn = " + mKeyboardVibrationOn
- + ", default: " + mVibrationConfig.isDefaultKeyboardVibrationEnabled());
+ pw.println("keyboardVibrationOn = " + mKeyboardVibrationOn);
pw.println("vibrateInputDevices = " + mVibrateInputDevices);
pw.println("batterySaverMode = " + mBatterySaverMode);
pw.println("ringerMode = " + ringerModeToString(mRingerMode));
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 5c15ccb55c65..4437a2ddf3a7 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -65,6 +65,7 @@ import android.util.IndentingPrintWriter;
import android.util.Slog;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
+import android.view.HapticFeedbackConstants;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -439,13 +440,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
@Override // Binder call
public void performHapticFeedback(int uid, int deviceId, String opPkg, int constant,
- boolean always, String reason, boolean fromIme) {
+ String reason, int flags, int privFlags) {
// Note that the `performHapticFeedback` method does not take a token argument from the
// caller, and instead, uses this service as the token. This is to mitigate performance
// impact that would otherwise be caused due to marshal latency. Haptic feedback effects are
// short-lived, so we don't need to cancel when the process dies.
- performHapticFeedbackInternal(
- uid, deviceId, opPkg, constant, always, reason, /* token= */ this, fromIme);
+ performHapticFeedbackInternal(uid, deviceId, opPkg, constant, reason, /* token= */
+ this, flags, privFlags);
}
/**
@@ -456,8 +457,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
@VisibleForTesting
@Nullable
HalVibration performHapticFeedbackInternal(
- int uid, int deviceId, String opPkg, int constant, boolean always, String reason,
- IBinder token, boolean fromIme) {
+ int uid, int deviceId, String opPkg, int constant, String reason,
+ IBinder token, int flags, int privFlags) {
HapticFeedbackVibrationProvider hapticVibrationProvider = getHapticVibrationProvider();
if (hapticVibrationProvider == null) {
Slog.e(TAG, "performHapticFeedback; haptic vibration provider not ready.");
@@ -474,9 +475,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
return null;
}
CombinedVibration vib = CombinedVibration.createParallel(effect);
- VibrationAttributes attrs =
- hapticVibrationProvider.getVibrationAttributesForHapticFeedback(
- constant, /* bypassVibrationIntensitySetting= */ always, fromIme);
+ VibrationAttributes attrs = hapticVibrationProvider.getVibrationAttributesForHapticFeedback(
+ constant, flags, privFlags);
reason = "performHapticFeedback(constant=" + constant + "): " + reason;
VibratorFrameworkStatsLogger.logPerformHapticsFeedbackIfKeyboard(uid, constant);
return vibrateWithoutPermissionCheck(uid, deviceId, opPkg, vib, attrs, reason, token);
@@ -2295,10 +2295,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
IBinder deathBinder = commonOptions.background ? VibratorManagerService.this
: mShellCallbacksToken;
+ int flags = commonOptions.force
+ ? HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING : 0;
HalVibration vib = performHapticFeedbackInternal(Binder.getCallingUid(),
Context.DEVICE_ID_DEFAULT, SHELL_PACKAGE_NAME, constant,
- /* always= */ commonOptions.force, /* reason= */ commonOptions.description,
- deathBinder, false /* fromIme */);
+ /* reason= */ commonOptions.description, deathBinder, flags, /* privFlags */ 0);
maybeWaitOnVibration(vib, commonOptions);
return 0;
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
index 0e0b78fb3206..2d8aa3f06de3 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
+++ b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
@@ -382,12 +382,6 @@ abstract class AbsAppSnapshotController<TYPE extends WindowContainer,
}
return null;
}
- if (activity.hasCommittedReparentToAnimationLeash()) {
- if (DEBUG_SCREENSHOT) {
- Slog.w(TAG_WM, "Failed to take screenshot. App is animating " + activity);
- }
- return null;
- }
final WindowState mainWindow = activity.findMainWindow();
if (mainWindow == null) {
Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + source);
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 5be5bc5e3952..2c734127b7ea 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -47,7 +47,7 @@ import static com.android.server.accessibility.AccessibilityTraceProto.WHERE;
import static com.android.server.accessibility.AccessibilityTraceProto.WINDOW_MANAGER_SERVICE;
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.WindowTracing.WINSCOPE_EXT;
+import static com.android.server.wm.WindowTracingLegacy.WINSCOPE_EXT;
import android.accessibilityservice.AccessibilityTrace;
import android.animation.ObjectAnimator;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 5f19924fc538..3076b873058d 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -53,7 +53,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.activityTypeToString;
-import static android.app.WindowConfiguration.isFloating;
import static android.app.admin.DevicePolicyResources.Drawables.Source.PROFILE_SWITCH_ANIMATION;
import static android.app.admin.DevicePolicyResources.Drawables.Style.OUTLINE;
import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON;
@@ -65,6 +64,7 @@ import static android.content.Intent.CATEGORY_SECONDARY_HOME;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
+import static android.content.pm.ActivityInfo.CONFIG_RESOURCES_UNUSED;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
@@ -89,12 +89,6 @@ import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_INSETS_DECOUPLED_CONFIGURATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN;
import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS;
import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
@@ -114,7 +108,6 @@ import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.content.res.Configuration.UI_MODE_TYPE_DESK;
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
-import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
import static android.os.Build.VERSION_CODES.HONEYCOMB;
import static android.os.Build.VERSION_CODES.O;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
@@ -240,11 +233,10 @@ import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_F
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
import static com.android.server.wm.ActivityTaskManagerService.getInputDispatchingTimeoutMillisLocked;
+import static com.android.server.wm.DesktopModeLaunchParamsModifier.canEnterDesktopMode;
import static com.android.server.wm.IdentifierProto.HASH_CODE;
import static com.android.server.wm.IdentifierProto.TITLE;
import static com.android.server.wm.IdentifierProto.USER_ID;
-import static com.android.server.wm.LetterboxConfiguration.DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW;
-import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
import static com.android.server.wm.StartingData.AFTER_TRANSACTION_COPY_TO_CLIENT;
import static com.android.server.wm.StartingData.AFTER_TRANSACTION_REMOVE_DIRECTLY;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
@@ -343,7 +335,6 @@ import android.service.contentcapture.ActivityEvent;
import android.service.dreams.DreamActivity;
import android.service.voice.IVoiceInteractionSession;
import android.util.ArraySet;
-import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.util.MergedConfiguration;
@@ -485,9 +476,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// finished destroying itself.
private static final int DESTROY_TIMEOUT = 10 * 1000;
- // Rounding tolerance to be used in aspect ratio computations
- private static final float ASPECT_RATIO_ROUNDING_TOLERANCE = 0.005f;
-
final ActivityTaskManagerService mAtmService;
final ActivityCallerState mCallerState;
@NonNull
@@ -734,6 +722,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
*/
private boolean mOccludesParent;
+ /** Whether the activity have style floating */
+ private boolean mStyleFloating;
+
/**
* Unlike {@link #mOccludesParent} which can be changed at runtime. This is a static attribute
* from the style of activity. Because we don't want {@link WindowContainer#getOrientation()}
@@ -828,26 +819,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// naturally.
private boolean mInSizeCompatModeForBounds = false;
- // Whether the aspect ratio restrictions applied to the activity bounds in applyAspectRatio().
- private boolean mIsAspectRatioApplied = false;
-
- // Bounds populated in resolveFixedOrientationConfiguration when this activity is letterboxed
- // for fixed orientation. If not null, they are used as parent container in
- // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets. If
- // letterboxed due to fixed orientation then aspect ratio restrictions are also respected.
- // This happens when an activity has fixed orientation which doesn't match orientation of the
- // parent because a display is ignoring orientation request or fixed to user rotation.
- // See WindowManagerService#getIgnoreOrientationRequest and
- // WindowManagerService#getFixedToUserRotation for more context.
- @Nullable
- private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;
-
- // Bounds populated in resolveAspectRatioRestriction when this activity is letterboxed for
- // aspect ratio. If not null, they are used as parent container in
- // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets.
- @Nullable
- private Rect mLetterboxBoundsForAspectRatio;
-
// Whether the activity is eligible to be letterboxed for fixed orientation with respect to its
// requested orientation, even when it's letterbox for another reason (e.g., size compat mode)
// and therefore #isLetterboxedForFixedOrientationAndAspectRatio returns false.
@@ -889,8 +860,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
/** The last set {@link DropInputMode} for this activity surface. */
@DropInputMode
private int mLastDropInputMode = DropInputMode.NONE;
- /** Whether the input to this activity will be dropped during the current playing animation. */
- private boolean mIsInputDroppedForAnimation;
/**
* Whether the application has desk mode resources. Calculated and cached when
@@ -1133,11 +1102,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
pw.println(prefix + "mLastReportedConfigurations:");
mLastReportedConfiguration.dump(pw, prefix + " ");
- if (Flags.activityWindowInfoFlag()) {
- pw.print(prefix);
- pw.print("mLastReportedActivityWindowInfo=");
- pw.println(mLastReportedActivityWindowInfo);
- }
+ pw.print(prefix);
+ pw.print("mLastReportedActivityWindowInfo=");
+ pw.println(mLastReportedActivityWindowInfo);
pw.print(prefix); pw.print("CurrentConfiguration="); pw.println(getConfiguration());
if (!getRequestedOverrideConfiguration().equals(EMPTY)) {
@@ -1730,15 +1697,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
- /** Sets if all input will be dropped as a protection during the client-driven animation. */
- void setDropInputForAnimation(boolean isInputDroppedForAnimation) {
- if (mIsInputDroppedForAnimation == isInputDroppedForAnimation) {
- return;
- }
- mIsInputDroppedForAnimation = isInputDroppedForAnimation;
- updateUntrustedEmbeddingInputProtection();
- }
-
/**
* Sets to drop input when obscured to activity if it is embedded in untrusted mode.
*
@@ -1751,10 +1709,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (getSurfaceControl() == null) {
return;
}
- if (mIsInputDroppedForAnimation) {
- // Disable all input during the animation.
- setDropInputMode(DropInputMode.ALL);
- } else if (isEmbeddedInUntrustedMode()) {
+ if (isEmbeddedInUntrustedMode()) {
// Set drop input to OBSCURED when untrusted embedded.
setDropInputMode(DropInputMode.OBSCURED);
} else {
@@ -2188,7 +2143,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
realTheme, com.android.internal.R.styleable.Window, mUserId);
if (ent != null) {
- mOccludesParent = !ActivityInfo.isTranslucentOrFloating(ent.array)
+ final boolean styleTranslucent = ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsTranslucent, false);
+ mStyleFloating = ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsFloating, false);
+ mOccludesParent = !(styleTranslucent || mStyleFloating)
// This style is propagated to the main window attributes with
// FLAG_SHOW_WALLPAPER from PhoneWindow#generateLayout.
|| ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
@@ -2197,6 +2156,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mOptOutEdgeToEdge = ent.array.getBoolean(
R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false);
} else {
+ mStyleFloating = false;
mStyleFillsParent = mOccludesParent = true;
noDisplay = false;
mOptOutEdgeToEdge = false;
@@ -2917,14 +2877,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
/** Makes starting window always fill the associated task. */
private void attachStartingSurfaceToAssociatedTask() {
- if (mSyncState == SYNC_STATE_NONE && isEmbedded()) {
- // Collect this activity since it's starting window will reparent to task. To ensure
- // any starting window's transaction will occur in order.
- mTransitionController.collect(this);
- }
+ mTransitionController.collect(mStartingWindow);
// Associate the configuration of starting window with the task.
overrideConfigurationPropagation(mStartingWindow, mStartingData.mAssociatedTask);
- getSyncTransaction().reparent(mStartingWindow.mSurfaceControl,
+ mStartingWindow.getSyncTransaction().reparent(mStartingWindow.mSurfaceControl,
mStartingData.mAssociatedTask.mSurfaceControl);
}
@@ -3203,7 +3159,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
@NonNull
ActivityWindowInfo getActivityWindowInfo() {
- if (!Flags.activityWindowInfoFlag() || !isAttached()) {
+ if (!isAttached()) {
return mTmpActivityWindowInfo;
}
if (isFixedRotationTransforming()) {
@@ -3237,6 +3193,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return occludesParent(true /* includingFinishing */);
}
+ boolean isStyleFloating() {
+ return mStyleFloating;
+ }
+
/** Returns true if this activity is not finishing, is opaque and fills the entire space of
* this task. */
boolean occludesParent() {
@@ -6527,9 +6487,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// and the token could be null.
return;
}
- if (r.mDisplayContent.mActivityRefresher != null) {
- r.mDisplayContent.mActivityRefresher.onActivityRefreshed(r);
- }
+ r.mDisplayContent.mAppCompatCameraPolicy.onActivityRefreshed(r);
}
static void splashScreenAttachedLocked(IBinder token) {
@@ -6748,6 +6706,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
destroySurfaces();
// Remove any starting window that was added for this app if they are still around.
removeStartingWindow();
+ // This is unlikely to happen because the sequence of lifecycle should invoke
+ // finishRelaunching before being stopped. Reset the potential unpaired count in case
+ // the binder transaction of relaunch is failed, so the transition won't be blocked.
+ if (mPendingRelaunchCount > 0) {
+ Slog.i(TAG, "Clear pending relaunch count on stopped " + this);
+ clearRelaunching();
+ }
if (finishing) {
abortAndClearOptionsAnimation();
@@ -7208,7 +7173,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawn()
+ ", isAnimationSet=" + isAnimationSet);
if (!w.isDrawn()) {
- Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
+ Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
+ " pv=" + w.isVisibleByPolicy()
+ " mDrawState=" + winAnimator.drawStateToString()
+ " ph=" + w.isParentWindowHidden() + " th=" + mVisibleRequested
@@ -8179,7 +8144,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
- if (mAppCompatController.getAppCompatOrientationOverrides()
+ if (mAppCompatController.getOrientationPolicy()
.shouldIgnoreRequestedOrientation(requestedOrientation)) {
return;
}
@@ -8317,9 +8282,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
void setLastReportedActivityWindowInfo(@NonNull ActivityWindowInfo activityWindowInfo) {
- if (Flags.activityWindowInfoFlag()) {
- mLastReportedActivityWindowInfo.set(activityWindowInfo);
- }
+ mLastReportedActivityWindowInfo.set(activityWindowInfo);
}
@Nullable
@@ -8379,7 +8342,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* aspect ratio.
*/
boolean shouldCreateCompatDisplayInsets() {
- if (mLetterboxUiController.hasFullscreenOverride()) {
+ if (mAppCompatController.getAppCompatAspectRatioOverrides().hasFullscreenOverride()) {
// If the user has forced the applications aspect ratio to be fullscreen, don't use size
// compatibility mode in any situation. The user has been warned and therefore accepts
// the risk of the application misbehaving.
@@ -8468,10 +8431,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
fullConfig.windowConfiguration.getRotation());
}
- final Rect letterboxedContainerBounds =
- mLetterboxBoundsForFixedOrientationAndAspectRatio != null
- ? mLetterboxBoundsForFixedOrientationAndAspectRatio
- : mLetterboxBoundsForAspectRatio;
+ final Rect letterboxedContainerBounds = mAppCompatController
+ .getAppCompatAspectRatioPolicy().getLetterboxedContainerBounds();
+
// The role of CompatDisplayInsets is like the override bounds.
mCompatDisplayInsets =
new CompatDisplayInsets(
@@ -8545,10 +8507,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
newParentConfiguration = mTmpConfig;
}
- mIsAspectRatioApplied = false;
+ mAppCompatController.getAppCompatAspectRatioPolicy().reset();
mIsEligibleForFixedOrientationLetterbox = false;
- mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
- mLetterboxBoundsForAspectRatio = null;
mResolveConfigHint.resolveTmpOverrides(mDisplayContent, newParentConfiguration,
isFixedRotationTransforming());
@@ -8581,8 +8541,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// If activity in fullscreen mode is letterboxed because of fixed orientation then bounds
// are already calculated in resolveFixedOrientationConfiguration.
// Don't apply aspect ratio if app is overridden to fullscreen by device user/manufacturer.
- if (Flags.immersiveAppRepositioning() && !isLetterboxedForFixedOrientationAndAspectRatio()
- && !mLetterboxUiController.hasFullscreenOverride()) {
+ if (Flags.immersiveAppRepositioning()
+ && !mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()
+ && !mAppCompatController.getAppCompatAspectRatioOverrides()
+ .hasFullscreenOverride()) {
resolveAspectRatioRestriction(newParentConfiguration);
}
final CompatDisplayInsets compatDisplayInsets = getCompatDisplayInsets();
@@ -8602,8 +8565,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// are already calculated in resolveFixedOrientationConfiguration, or if in size compat
// mode, it should already be calculated in resolveSizeCompatModeConfiguration.
// Don't apply aspect ratio if app is overridden to fullscreen by device user/manufacturer.
- if (!Flags.immersiveAppRepositioning() && !isLetterboxedForFixedOrientationAndAspectRatio()
- && !mInSizeCompatModeForBounds && !mLetterboxUiController.hasFullscreenOverride()) {
+ if (!Flags.immersiveAppRepositioning()
+ && !mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()
+ && !mInSizeCompatModeForBounds
+ && !mAppCompatController.getAppCompatAspectRatioOverrides()
+ .hasFullscreenOverride()) {
resolveAspectRatioRestriction(newParentConfiguration);
}
@@ -8620,14 +8587,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Fixed orientation letterboxing is possible on both large screen devices
// with ignoreOrientationRequest enabled and on phones in split screen even with
// ignoreOrientationRequest disabled.
- && (mLetterboxBoundsForFixedOrientationAndAspectRatio != null
+ && (mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()
// Limiting check for aspect ratio letterboxing to devices with enabled
// ignoreOrientationRequest. This avoids affecting phones where apps may
// not expect the change of smallestScreenWidthDp after rotation which is
// possible with this logic. Not having smallestScreenWidthDp completely
// accurate on phones shouldn't make the big difference and is expected
// to be already well-tested by apps.
- || (isIgnoreOrientationRequest && mIsAspectRatioApplied))) {
+ || (isIgnoreOrientationRequest
+ && mAppCompatController.getAppCompatAspectRatioPolicy().isAspectRatioApplied()))) {
// TODO(b/264034555): Use mDisplayContent to calculate smallestScreenWidthDp from all
// rotations and only re-calculate if parent bounds have non-orientation size change.
resolvedConfig.smallestScreenWidthDp =
@@ -8668,7 +8637,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
resolvedConfig.windowConfiguration.setMaxBounds(mTmpBounds);
}
- applySizeOverrideIfNeeded(newParentConfiguration, parentWindowingMode, resolvedConfig);
+ applySizeOverrideIfNeeded(
+ mDisplayContent,
+ info.applicationInfo,
+ newParentConfiguration,
+ resolvedConfig,
+ mOptOutEdgeToEdge,
+ hasFixedRotationTransform(),
+ getCompatDisplayInsets() != null);
mResolveConfigHint.resetTmpOverrides();
logAppCompatState();
@@ -8678,100 +8654,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return Rect.copyOrNull(mResolveConfigHint.mParentAppBoundsOverride);
}
- /**
- * If necessary, override configuration fields related to app bounds.
- * This will happen when the app is targeting SDK earlier than 35.
- * The insets and configuration has decoupled since SDK level 35, to make the system
- * compatible to existing apps, override the configuration with legacy metrics. In legacy
- * metrics, fields such as appBounds will exclude some of the system bar areas.
- * The override contains all potentially affected fields in Configuration, including
- * screenWidthDp, screenHeightDp, smallestScreenWidthDp, and orientation.
- * All overrides to those fields should be in this method.
- *
- * TODO: Consider integrate this with computeConfigByResolveHint()
- */
- private void applySizeOverrideIfNeeded(Configuration newParentConfiguration,
- int parentWindowingMode, Configuration inOutConfig) {
- if (mDisplayContent == null) {
- return;
- }
- final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds();
- int rotation = newParentConfiguration.windowConfiguration.getRotation();
- if (rotation == ROTATION_UNDEFINED && !isFixedRotationTransforming()) {
- rotation = mDisplayContent.getRotation();
- }
- if (!mOptOutEdgeToEdge && (!mResolveConfigHint.mUseOverrideInsetsForConfig
- || getCompatDisplayInsets() != null
- || (isFloating(parentWindowingMode)
- // Check the requested windowing mode of activity as well in case it is
- // switching between PiP and fullscreen.
- && (inOutConfig.windowConfiguration.getWindowingMode()
- == WINDOWING_MODE_UNDEFINED
- || isFloating(inOutConfig.windowConfiguration.getWindowingMode())))
- || rotation == ROTATION_UNDEFINED)) {
- // If the insets configuration decoupled logic is not enabled for the app, or the app
- // already has a compat override, or the context doesn't contain enough info to
- // calculate the override, skip the override.
- return;
- }
- // Make sure the orientation related fields will be updated by the override insets, because
- // fixed rotation has assigned the fields from display's configuration.
- if (hasFixedRotationTransform()) {
- inOutConfig.windowConfiguration.setAppBounds(null);
- inOutConfig.screenWidthDp = Configuration.SCREEN_WIDTH_DP_UNDEFINED;
- inOutConfig.screenHeightDp = Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
- inOutConfig.smallestScreenWidthDp = Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
- inOutConfig.orientation = ORIENTATION_UNDEFINED;
- }
-
- // Override starts here.
- final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
- final int dw = rotated ? mDisplayContent.mBaseDisplayHeight
- : mDisplayContent.mBaseDisplayWidth;
- final int dh = rotated ? mDisplayContent.mBaseDisplayWidth
- : mDisplayContent.mBaseDisplayHeight;
- final Rect nonDecorInsets = mDisplayContent.getDisplayPolicy()
- .getDecorInsetsInfo(rotation, dw, dh).mOverrideNonDecorInsets;
- // This should be the only place override the configuration for ActivityRecord. Override
- // the value if not calculated yet.
- Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
- if (outAppBounds == null || outAppBounds.isEmpty()) {
- inOutConfig.windowConfiguration.setAppBounds(parentBounds);
- outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
- outAppBounds.inset(nonDecorInsets);
- }
- float density = inOutConfig.densityDpi;
- if (density == Configuration.DENSITY_DPI_UNDEFINED) {
- density = newParentConfiguration.densityDpi;
- }
- density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;
- if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
- inOutConfig.screenWidthDp = (int) (outAppBounds.width() / density + 0.5f);
- }
- if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
- inOutConfig.screenHeightDp = (int) (outAppBounds.height() / density + 0.5f);
- }
- if (inOutConfig.smallestScreenWidthDp
- == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
- && parentWindowingMode == WINDOWING_MODE_FULLSCREEN) {
- // For the case of PIP transition and multi-window environment, the
- // smallestScreenWidthDp is handled already. Override only if the app is in
- // fullscreen.
- final DisplayInfo info = new DisplayInfo(mDisplayContent.getDisplayInfo());
- mDisplayContent.computeSizeRanges(info, rotated, dw, dh,
- mDisplayContent.getDisplayMetrics().density,
- inOutConfig, true /* overrideConfig */);
- }
-
- // It's possible that screen size will be considered in different orientation with or
- // without considering the system bar insets. Override orientation as well.
- if (inOutConfig.orientation == ORIENTATION_UNDEFINED) {
- inOutConfig.orientation =
- (inOutConfig.screenWidthDp <= inOutConfig.screenHeightDp)
- ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
- }
- }
-
private void computeConfigByResolveHint(@NonNull Configuration resolvedConfig,
@NonNull Configuration parentConfig) {
task.computeConfigResourceOverrides(resolvedConfig, parentConfig, mResolveConfigHint);
@@ -8831,11 +8713,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// letterboxed for fixed orientation. Aspect ratio restrictions are also applied if
// present. But this doesn't return true when the activity is letterboxed only because
// of aspect ratio restrictions.
- if (isLetterboxedForFixedOrientationAndAspectRatio()) {
+ if (mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()) {
return APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_FIXED_ORIENTATION;
}
// Letterbox for limited aspect ratio.
- if (isLetterboxedForAspectRatioOnly()) {
+ if (mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForAspectRatioOnly()) {
return APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_ASPECT_RATIO;
}
@@ -8985,36 +8869,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return inTransitionSelfOrParent();
}
- boolean isDisplaySleepingAndSwapping() {
- for (int i = mDisplayContent.mAllSleepTokens.size() - 1; i >= 0; i--) {
- RootWindowContainer.SleepToken sleepToken = mDisplayContent.mAllSleepTokens.get(i);
- if (sleepToken.isDisplaySwapping()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Whether this activity is letterboxed for fixed orientation. If letterboxed due to fixed
- * orientation then aspect ratio restrictions are also already respected.
- *
- * <p>This happens when an activity has fixed orientation which doesn't match orientation of the
- * parent because a display setting 'ignoreOrientationRequest' is set to true. See {@link
- * WindowManagerService#getIgnoreOrientationRequest} for more context.
- */
- boolean isLetterboxedForFixedOrientationAndAspectRatio() {
- return mLetterboxBoundsForFixedOrientationAndAspectRatio != null;
- }
-
- boolean isLetterboxedForAspectRatioOnly() {
- return mLetterboxBoundsForAspectRatio != null;
- }
-
- boolean isAspectRatioApplied() {
- return mIsAspectRatioApplied;
- }
-
/**
* Whether this activity is eligible for letterbox eduction.
*
@@ -9047,7 +8901,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* @param parentBounds are the new parent bounds passed down to the activity and should be used
* to compute the stable bounds.
* @param outStableBounds will store the stable bounds, which are the bounds with insets
- * applied, if orientation is not respected when insets are applied.
+ * applied, if orientation is not respected when insets are applied.g
* Stable bounds should be used to compute letterboxed bounds if
* orientation is not respected when insets are applied.
* @param outNonDecorBounds will store the non decor bounds, which are the bounds with non
@@ -9200,23 +9054,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final Rect prevResolvedBounds = new Rect(resolvedBounds);
resolvedBounds.set(containingBounds);
- final float letterboxAspectRatioOverride =
- mLetterboxUiController.getFixedOrientationLetterboxAspectRatio(newParentConfig);
-
- // Aspect ratio as suggested by the system. Apps requested mix/max aspect ratio will
- // be respected in #applyAspectRatio.
- final float desiredAspectRatio;
- if (isDefaultMultiWindowLetterboxAspectRatioDesired(newParentConfig)) {
- desiredAspectRatio = DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW;
- } else if (letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) {
- desiredAspectRatio = letterboxAspectRatioOverride;
- } else {
- desiredAspectRatio = computeAspectRatio(parentBounds);
- }
-
- // Apply aspect ratio to resolved bounds
- mIsAspectRatioApplied = applyAspectRatio(resolvedBounds, containingBoundsWithInsets,
- containingBounds, desiredAspectRatio);
+ mAppCompatController.getAppCompatAspectRatioPolicy()
+ .applyDesiredAspectRatio(newParentConfig, parentBounds, resolvedBounds,
+ containingBoundsWithInsets, containingBounds);
if (compatDisplayInsets != null) {
compatDisplayInsets.getBoundsByRotation(mTmpBounds,
@@ -9244,21 +9084,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// for comparison with size compat app bounds in {@link resolveSizeCompatModeConfiguration}.
mResolveConfigHint.mTmpCompatInsets = compatDisplayInsets;
computeConfigByResolveHint(getResolvedOverrideConfiguration(), newParentConfig);
- mLetterboxBoundsForFixedOrientationAndAspectRatio = new Rect(resolvedBounds);
- }
-
- /**
- * Returns {@code true} if the default aspect ratio for a letterboxed app in multi-window mode
- * should be used.
- */
- private boolean isDefaultMultiWindowLetterboxAspectRatioDesired(
- @NonNull Configuration parentConfig) {
- if (mDisplayContent == null) {
- return false;
- }
- final int windowingMode = parentConfig.windowConfiguration.getWindowingMode();
- return WindowConfiguration.inMultiWindowMode(windowingMode)
- && !mDisplayContent.getIgnoreOrientationRequest();
+ mAppCompatController.getAppCompatAspectRatioPolicy()
+ .setLetterboxBoundsForFixedOrientationAndAspectRatio(new Rect(resolvedBounds));
}
/**
@@ -9275,7 +9102,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Use tmp bounds to calculate aspect ratio so we can know whether the activity should use
// restricted size (resolved bounds may be the requested override bounds).
mTmpBounds.setEmpty();
- mIsAspectRatioApplied = applyAspectRatio(mTmpBounds, parentAppBounds, parentBounds);
+ mAppCompatController.getAppCompatAspectRatioPolicy()
+ .applyAspectRatioForLetterbox(mTmpBounds, parentAppBounds, parentBounds);
// If the out bounds is not empty, it means the activity cannot fill parent's app bounds,
// then they should be aligned later in #updateResolvedBoundsPosition()
if (!mTmpBounds.isEmpty()) {
@@ -9286,7 +9114,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// restrict, the bounds should be the requested override bounds.
mResolveConfigHint.mTmpOverrideDisplayInfo = getFixedRotationTransformDisplayInfo();
computeConfigByResolveHint(resolvedConfig, newParentConfiguration);
- mLetterboxBoundsForAspectRatio = new Rect(resolvedBounds);
+ mAppCompatController.getAppCompatAspectRatioPolicy()
+ .setLetterboxBoundsForAspectRatio(new Rect(resolvedBounds));
}
}
@@ -9304,7 +9133,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// activity will be displayed within them even if it is in size compat mode. They should be
// saved here before resolved bounds are overridden below.
final boolean useResolvedBounds = Flags.immersiveAppRepositioning()
- ? isAspectRatioApplied() : isLetterboxedForFixedOrientationAndAspectRatio();
+ ? mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isAspectRatioApplied()
+ : mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio();
final Rect containerBounds = useResolvedBounds
? new Rect(resolvedBounds)
: newParentConfiguration.windowConfiguration.getBounds();
@@ -9348,8 +9180,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
resolvedBounds.set(containingBounds);
// The size of floating task is fixed (only swap), so the aspect ratio is already correct.
if (!compatDisplayInsets.mIsFloating) {
- mIsAspectRatioApplied =
- applyAspectRatio(resolvedBounds, containingAppBounds, containingBounds);
+ mAppCompatController.getAppCompatAspectRatioPolicy()
+ .applyAspectRatioForLetterbox(resolvedBounds, containingAppBounds,
+ containingBounds);
}
// Use resolvedBounds to compute other override configurations such as appBounds. The bounds
@@ -9434,18 +9267,24 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
void updateSizeCompatScale(Rect resolvedAppBounds, Rect containerAppBounds) {
- // Only allow to scale down.
mSizeCompatScale = mAppCompatController.getTransparentPolicy()
.findOpaqueNotFinishingActivityBelow()
.map(activityRecord -> activityRecord.mSizeCompatScale)
- .orElseGet(() -> {
- final int contentW = resolvedAppBounds.width();
- final int contentH = resolvedAppBounds.height();
- final int viewportW = containerAppBounds.width();
- final int viewportH = containerAppBounds.height();
- return (contentW <= viewportW && contentH <= viewportH) ? 1f : Math.min(
- (float) viewportW / contentW, (float) viewportH / contentH);
- });
+ .orElseGet(() -> calculateSizeCompatScale(resolvedAppBounds, containerAppBounds));
+ }
+
+ private float calculateSizeCompatScale(Rect resolvedAppBounds, Rect containerAppBounds) {
+ final int contentW = resolvedAppBounds.width();
+ final int contentH = resolvedAppBounds.height();
+ final int viewportW = containerAppBounds.width();
+ final int viewportH = containerAppBounds.height();
+ // Allow an application to be up-scaled if its window is smaller than its
+ // original container or if it's a freeform window in desktop mode.
+ boolean shouldAllowUpscaling = !(contentW <= viewportW && contentH <= viewportH)
+ || (canEnterDesktopMode(mAtmService.mContext)
+ && getWindowingMode() == WINDOWING_MODE_FREEFORM);
+ return shouldAllowUpscaling ? Math.min(
+ (float) viewportW / contentW, (float) viewportH / contentH) : 1f;
}
private boolean isInSizeCompatModeForBounds(final Rect appBounds, final Rect containerBounds) {
@@ -9753,190 +9592,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return mPauseConfigurationDispatchCount > 0;
}
- private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
- Rect containingBounds) {
- return applyAspectRatio(outBounds, containingAppBounds, containingBounds,
- 0 /* desiredAspectRatio */);
- }
-
- /**
- * Applies aspect ratio restrictions to outBounds. If no restrictions, then no change is
- * made to outBounds.
- *
- * @return {@code true} if aspect ratio restrictions were applied.
- */
- // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
- private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
- Rect containingBounds, float desiredAspectRatio) {
- final float maxAspectRatio = getMaxAspectRatio();
- final Task rootTask = getRootTask();
- final float minAspectRatio = getMinAspectRatio();
- final TaskFragment organizedTf = getOrganizedTaskFragment();
- float aspectRatioToApply = desiredAspectRatio;
- if (task == null || rootTask == null
- || (maxAspectRatio < 1 && minAspectRatio < 1 && aspectRatioToApply < 1)
- // Don't set aspect ratio if we are in VR mode.
- || isInVrUiMode(getConfiguration())
- // TODO(b/232898850): Always respect aspect ratio requests.
- // Don't set aspect ratio for activity in ActivityEmbedding split.
- || (organizedTf != null && !organizedTf.fillsParent())) {
- return false;
- }
-
- final int containingAppWidth = containingAppBounds.width();
- final int containingAppHeight = containingAppBounds.height();
- final float containingRatio = computeAspectRatio(containingAppBounds);
-
- if (aspectRatioToApply < 1) {
- aspectRatioToApply = containingRatio;
- }
-
- if (maxAspectRatio >= 1 && aspectRatioToApply > maxAspectRatio) {
- aspectRatioToApply = maxAspectRatio;
- } else if (minAspectRatio >= 1 && aspectRatioToApply < minAspectRatio) {
- aspectRatioToApply = minAspectRatio;
- }
-
- int activityWidth = containingAppWidth;
- int activityHeight = containingAppHeight;
-
- if (containingRatio - aspectRatioToApply > ASPECT_RATIO_ROUNDING_TOLERANCE) {
- if (containingAppWidth < containingAppHeight) {
- // Width is the shorter side, so we use that to figure-out what the max. height
- // should be given the aspect ratio.
- activityHeight = (int) ((activityWidth * aspectRatioToApply) + 0.5f);
- } else {
- // Height is the shorter side, so we use that to figure-out what the max. width
- // should be given the aspect ratio.
- activityWidth = (int) ((activityHeight * aspectRatioToApply) + 0.5f);
- }
- } else if (aspectRatioToApply - containingRatio > ASPECT_RATIO_ROUNDING_TOLERANCE) {
- boolean adjustWidth;
- switch (getRequestedConfigurationOrientation()) {
- case ORIENTATION_LANDSCAPE:
- // Width should be the longer side for this landscape app, so we use the width
- // to figure-out what the max. height should be given the aspect ratio.
- adjustWidth = false;
- break;
- case ORIENTATION_PORTRAIT:
- // Height should be the longer side for this portrait app, so we use the height
- // to figure-out what the max. width should be given the aspect ratio.
- adjustWidth = true;
- break;
- default:
- // This app doesn't have a preferred orientation, so we keep the length of the
- // longer side, and use it to figure-out the length of the shorter side.
- if (containingAppWidth < containingAppHeight) {
- // Width is the shorter side, so we use the height to figure-out what the
- // max. width should be given the aspect ratio.
- adjustWidth = true;
- } else {
- // Height is the shorter side, so we use the width to figure-out what the
- // max. height should be given the aspect ratio.
- adjustWidth = false;
- }
- break;
- }
- if (adjustWidth) {
- activityWidth = (int) ((activityHeight / aspectRatioToApply) + 0.5f);
- } else {
- activityHeight = (int) ((activityWidth / aspectRatioToApply) + 0.5f);
- }
- }
-
- if (containingAppWidth <= activityWidth && containingAppHeight <= activityHeight) {
- // The display matches or is less than the activity aspect ratio, so nothing else to do.
- return false;
- }
-
- // Compute configuration based on max or min supported width and height.
- // Also account for the insets (e.g. display cutouts, navigation bar), which will be
- // clipped away later in {@link Task#computeConfigResourceOverrides()}, i.e., the out
- // bounds are the app bounds restricted by aspect ratio + clippable insets. Otherwise,
- // the app bounds would end up too small. To achieve this we will also add clippable insets
- // when the corresponding dimension fully fills the parent
-
- int right = activityWidth + containingAppBounds.left;
- int left = containingAppBounds.left;
- if (right >= containingAppBounds.right) {
- right = containingBounds.right;
- left = containingBounds.left;
- }
- int bottom = activityHeight + containingAppBounds.top;
- int top = containingAppBounds.top;
- if (bottom >= containingAppBounds.bottom) {
- bottom = containingBounds.bottom;
- top = containingBounds.top;
- }
- outBounds.set(left, top, right, bottom);
- return true;
- }
-
/**
* Returns the min aspect ratio of this activity.
*/
float getMinAspectRatio() {
- if (mAppCompatController.getTransparentPolicy().isRunning()) {
- return mAppCompatController.getTransparentPolicy().getInheritedMinAspectRatio();
- }
- if (info.applicationInfo == null) {
- return info.getMinAspectRatio();
- }
- if (mLetterboxUiController.shouldApplyUserMinAspectRatioOverride()) {
- return mLetterboxUiController.getUserMinAspectRatio();
- }
- if (!mLetterboxUiController.shouldOverrideMinAspectRatio()
- && !mAppCompatController.getAppCompatCameraOverrides()
- .shouldOverrideMinAspectRatioForCamera()) {
- return info.getMinAspectRatio();
- }
- if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY)
- && !ActivityInfo.isFixedOrientationPortrait(
- getOverrideOrientation())) {
- return info.getMinAspectRatio();
- }
-
- if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN)
- && isParentFullscreenPortrait()) {
- // We are using the parent configuration here as this is the most recent one that gets
- // passed to onConfigurationChanged when a relevant change takes place
- return info.getMinAspectRatio();
- }
-
- if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN)) {
- return Math.max(mLetterboxUiController.getSplitScreenAspectRatio(),
- info.getMinAspectRatio());
- }
-
- if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_LARGE)) {
- return Math.max(ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
- info.getMinAspectRatio());
- }
-
- if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_MEDIUM)) {
- return Math.max(ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE,
- info.getMinAspectRatio());
- }
-
- if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_SMALL)) {
- return Math.max(ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL_VALUE,
- info.getMinAspectRatio());
- }
- return info.getMinAspectRatio();
- }
-
- private boolean isParentFullscreenPortrait() {
- final WindowContainer parent = getParent();
- return parent != null
- && parent.getConfiguration().orientation == ORIENTATION_PORTRAIT
- && parent.getWindowConfiguration().getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
+ return mAppCompatController.getAppCompatAspectRatioPolicy().getMinAspectRatio();
}
float getMaxAspectRatio() {
- if (mAppCompatController.getTransparentPolicy().isRunning()) {
- return mAppCompatController.getTransparentPolicy().getInheritedMaxAspectRatio();
- }
- return info.getMaxAspectRatio();
+ return mAppCompatController.getAppCompatAspectRatioPolicy().getMaxAspectRatio();
}
/**
@@ -9947,18 +9611,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
/**
- * Returns the aspect ratio of the given {@code rect}.
- */
- static float computeAspectRatio(Rect rect) {
- final int width = rect.width();
- final int height = rect.height();
- if (width == 0 || height == 0) {
- return 0;
- }
- return Math.max(width, height) / (float) Math.min(width, height);
- }
-
- /**
* @return {@code true} if this activity was reparented to another display but
* {@link #ensureActivityConfiguration} is not called.
*/
@@ -10015,16 +9667,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return updateReportedConfigurationAndSend();
}
- /**
- * @return {@code true} if the Camera is active for the current activity
- */
- boolean isCameraActive() {
- return mDisplayContent != null
- && mDisplayContent.getDisplayRotationCompatPolicy() != null
- && mDisplayContent.getDisplayRotationCompatPolicy()
- .isCameraActive(this, /* mustBeFullscreen */ true);
- }
-
boolean updateReportedConfigurationAndSend() {
if (isConfigurationDispatchPaused()) {
Slog.wtf(TAG, "trying to update reported(client) config while dispatch is paused");
@@ -10056,8 +9698,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// the combine configurations are equal, but would otherwise differ in the override config
mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
final ActivityWindowInfo newActivityWindowInfo = getActivityWindowInfo();
- final boolean isActivityWindowInfoChanged = Flags.activityWindowInfoFlag()
- && !mLastReportedActivityWindowInfo.equals(newActivityWindowInfo);
+ final boolean isActivityWindowInfoChanged =
+ !mLastReportedActivityWindowInfo.equals(newActivityWindowInfo);
if (!displayChanged && !isActivityWindowInfoChanged
&& getConfiguration().equals(mTmpConfig)) {
ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration & display "
@@ -10172,11 +9814,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
private void notifyActivityRefresherAboutConfigurationChange(
Configuration newConfig, Configuration lastReportedConfig) {
- if (mDisplayContent.mActivityRefresher == null
- || !shouldBeResumed(/* activeActivity */ null)) {
+ if (!shouldBeResumed(/* activeActivity */ null)) {
return;
}
- mDisplayContent.mActivityRefresher.onActivityConfigurationChanging(
+ mDisplayContent.mAppCompatCameraPolicy.onActivityConfigurationChanging(
this, newConfig, lastReportedConfig);
}
@@ -10195,6 +9836,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
*/
private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
int configChanged = info.getRealConfigChanged();
+ if (android.content.res.Flags.handleAllConfigChanges()) {
+ if ((configChanged & CONFIG_RESOURCES_UNUSED) != 0) {
+ // Don't relaunch any activities that claim they do not use resources at all.
+ // If they still do, the onConfigurationChanged() callback will get called to
+ // let them know anyway.
+ return false;
+ }
+ }
+
boolean onlyVrUiModeChanged = onlyVrUiModeChanged(changes, changesConfig);
// Override for apps targeting pre-O sdks
@@ -10223,8 +9873,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
*/
private boolean onlyVrUiModeChanged(int changes, Configuration lastReportedConfig) {
final Configuration currentConfig = getConfiguration();
- return changes == CONFIG_UI_MODE && (isInVrUiMode(currentConfig)
- != isInVrUiMode(lastReportedConfig));
+ return changes == CONFIG_UI_MODE && (AppCompatUtils.isInVrUiMode(currentConfig)
+ != AppCompatUtils.isInVrUiMode(lastReportedConfig));
}
/**
@@ -10596,10 +10246,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return r;
}
- private static boolean isInVrUiMode(Configuration config) {
- return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
- }
-
private static boolean isInDeskUiMode(Configuration config) {
return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_DESK;
}
@@ -10823,16 +10469,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mAppCompatController.getAppCompatCameraOverrides()
.shouldRefreshActivityViaPauseForCameraCompat());
proto.write(SHOULD_OVERRIDE_MIN_ASPECT_RATIO,
- mLetterboxUiController.shouldOverrideMinAspectRatio());
+ mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldOverrideMinAspectRatio());
proto.write(SHOULD_IGNORE_ORIENTATION_REQUEST_LOOP,
mAppCompatController.getAppCompatOrientationOverrides()
.shouldIgnoreOrientationRequestLoop());
proto.write(SHOULD_OVERRIDE_FORCE_RESIZE_APP,
mLetterboxUiController.shouldOverrideForceResizeApp());
proto.write(SHOULD_ENABLE_USER_ASPECT_RATIO_SETTINGS,
- mLetterboxUiController.shouldEnableUserAspectRatioSettings());
+ mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldEnableUserAspectRatioSettings());
proto.write(IS_USER_FULLSCREEN_OVERRIDE_ENABLED,
- mLetterboxUiController.isUserFullscreenOverrideEnabled());
+ mAppCompatController.getAppCompatAspectRatioOverrides()
+ .isUserFullscreenOverrideEnabled());
}
@Override
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index c0881180af94..3b0b727597a5 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -145,13 +145,6 @@ public abstract class ActivityTaskManagerInternal {
void acquire(int displayId);
/**
- * Acquires a sleep token.
- * @param displayId The display to apply to.
- * @param isSwappingDisplay Whether the display is swapping to another physical display.
- */
- void acquire(int displayId, boolean isSwappingDisplay);
-
- /**
* Releases the sleep token.
* @param displayId The display to apply to.
*/
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index ded205e5eafd..ff46b33571f3 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4709,6 +4709,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// Update stored global config and notify everyone about the change.
mRootWindowContainer.onConfigurationChanged(mTempConfig);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ if ((changes & ActivityInfo.CONFIG_ORIENTATION) != 0) {
+ FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_ORIENTATION_CHANGED,
+ values.orientation);
+ }
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
return changes;
@@ -5056,16 +5060,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public void acquire(int displayId) {
- acquire(displayId, false /* isSwappingDisplay */);
- }
-
- @Override
- public void acquire(int displayId, boolean isSwappingDisplay) {
synchronized (mGlobalLock) {
if (!mSleepTokens.contains(displayId)) {
mSleepTokens.append(displayId,
- mRootWindowContainer.createSleepToken(mTag, displayId,
- isSwappingDisplay));
+ mRootWindowContainer.createSleepToken(mTag, displayId));
updateSleepIfNeededLocked();
}
}
@@ -5189,6 +5187,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
String hostingType) {
if (!mStartingProcessActivities.contains(activity)) {
mStartingProcessActivities.add(activity);
+ // Let the activity with higher z-order be started first.
+ if (mStartingProcessActivities.size() > 1) {
+ mStartingProcessActivities.sort(null /* by WindowContainer#compareTo */);
+ }
} else if (mProcessNames.get(
activity.processName, activity.info.applicationInfo.uid) != null) {
// The process is already starting. Wait for it to attach.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index d65a106a1079..e81b440f6d6d 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -38,6 +38,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.Intent.ACTION_VIEW;
import static android.content.pm.PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -121,6 +122,7 @@ import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.SensorPrivacyManager;
import android.hardware.SensorPrivacyManagerInternal;
+import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -142,6 +144,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.Display;
+import android.webkit.URLUtil;
import android.window.ActivityWindowInfo;
import com.android.internal.R;
@@ -158,6 +161,7 @@ import com.android.server.am.UserState;
import com.android.server.pm.SaferIntentUtils;
import com.android.server.utils.Slogf;
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
+import com.android.window.flags.Flags;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -189,9 +193,6 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// How long we can hold the launch wake lock before giving up.
private static final int LAUNCH_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
- // How long we delay processing the stopping and finishing activities.
- private static final int SCHEDULE_FINISHING_STOPPING_ACTIVITY_MS = 200;
-
/** How long we wait until giving up on the activity telling us it released the top state. */
private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT = 500;
@@ -2093,7 +2094,6 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
boolean processPausingActivities, String reason) {
// Stop any activities that are scheduled to do so but have been waiting for the transition
// animation to finish.
- boolean displaySwapping = false;
ArrayList<ActivityRecord> readyToStopActivities = null;
for (int i = 0; i < mStoppingActivities.size(); i++) {
final ActivityRecord s = mStoppingActivities.get(i);
@@ -2101,10 +2101,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// send onStop before any configuration change when removing pip transition is ongoing.
final boolean animating = s.isInTransition()
&& s.getTask() != null && !s.getTask().isForceHidden();
- displaySwapping |= s.isDisplaySleepingAndSwapping();
ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
+ "finishing=%s", s, s.nowVisible, animating, s.finishing);
- if ((!animating && !displaySwapping) || mService.mShuttingDown
+ if (!animating || mService.mShuttingDown
|| s.getRootTask().isForceHiddenForPinnedTask()) {
if (!processPausingActivities && s.isState(PAUSING)) {
// Defer processing pausing activities in this iteration and reschedule
@@ -2125,16 +2124,6 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
}
}
- // Stopping activities are deferred processing if the display is swapping. Check again
- // later to ensure the stopping activities can be stopped after display swapped.
- if (displaySwapping) {
- mHandler.postDelayed(() -> {
- synchronized (mService.mGlobalLock) {
- scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
- }
- }, SCHEDULE_FINISHING_STOPPING_ACTIVITY_MS);
- }
-
final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
for (int i = 0; i < numReadyStops; i++) {
final ActivityRecord r = readyToStopActivities.get(i);
@@ -2737,9 +2726,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
final ActivityOptions activityOptions = options != null
? options.getOptions(this)
: null;
- boolean moveHomeTaskForward = true;
synchronized (mService.mGlobalLock) {
final boolean isCallerRecents = mRecentTasks.isCallerRecents(callingUid);
+ boolean moveHomeTaskForward = isCallerRecents;
int activityType = ACTIVITY_TYPE_UNDEFINED;
if (activityOptions != null) {
activityType = activityOptions.getLaunchActivityType();
@@ -2915,6 +2904,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
@Override
public void accept(ActivityRecord r) {
+ if (Flags.enableDesktopWindowingAppToWeb() && mInfo.capturedLink == null) {
+ setCapturedLink(r);
+ }
if (r.mLaunchCookie != null) {
mInfo.addLaunchCookie(r.mLaunchCookie);
}
@@ -2927,6 +2919,16 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
mTopRunning = r;
}
}
+
+ private void setCapturedLink(ActivityRecord r) {
+ final Uri uri = r.intent.getData();
+ if (uri == null || !ACTION_VIEW.equals(r.intent.getAction())
+ || !URLUtil.isNetworkUrl(uri.toString())) {
+ return;
+ }
+ mInfo.capturedLink = uri;
+ mInfo.capturedLinkTimestamp = r.lastLaunchTime;
+ }
}
/**
diff --git a/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java
new file mode 100644
index 000000000000..cf008e73321e
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java
@@ -0,0 +1,304 @@
+/*
+ * 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.wm;
+
+import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION_TO_USER;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
+import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_4_3;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_APP_DEFAULT;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_DISPLAY_SIZE;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;
+
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_POSITION_MULTIPLIER_CENTER;
+import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
+
+import android.annotation.NonNull;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wm.utils.OptPropFactory;
+
+import java.util.function.Function;
+
+/**
+ * Encapsulates app compat configurations and overrides related to aspect ratio.
+ */
+class AppCompatAspectRatioOverrides {
+
+ private static final String TAG =
+ TAG_WITH_CLASS_NAME ? "AppCompatAspectRatioOverrides" : TAG_ATM;
+
+ @NonNull
+ private final ActivityRecord mActivityRecord;
+ @NonNull
+ private final LetterboxConfiguration mLetterboxConfiguration;
+ @NonNull
+ private final UserAspectRatioState mUserAspectRatioState;
+
+ @NonNull
+ private final OptPropFactory.OptProp mAllowMinAspectRatioOverrideOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mAllowUserAspectRatioOverrideOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mAllowUserAspectRatioFullscreenOverrideOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mAllowOrientationOverrideOptProp;
+ @NonNull
+ private final Function<Boolean, Boolean> mIsDisplayFullScreenAndInPostureProvider;
+ @NonNull
+ private final Function<Configuration, Float> mGetHorizontalPositionMultiplierProvider;
+
+ AppCompatAspectRatioOverrides(@NonNull ActivityRecord activityRecord,
+ @NonNull LetterboxConfiguration letterboxConfiguration,
+ @NonNull OptPropFactory optPropBuilder,
+ @NonNull Function<Boolean, Boolean> isDisplayFullScreenAndInPostureProvider,
+ @NonNull Function<Configuration, Float> getHorizontalPositionMultiplierProvider) {
+ mActivityRecord = activityRecord;
+ mLetterboxConfiguration = letterboxConfiguration;
+ mUserAspectRatioState = new UserAspectRatioState();
+ mIsDisplayFullScreenAndInPostureProvider = isDisplayFullScreenAndInPostureProvider;
+ mGetHorizontalPositionMultiplierProvider = getHorizontalPositionMultiplierProvider;
+ mAllowMinAspectRatioOverrideOptProp = optPropBuilder.create(
+ PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE);
+ mAllowUserAspectRatioOverrideOptProp = optPropBuilder.create(
+ PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE,
+ mLetterboxConfiguration::isUserAppAspectRatioSettingsEnabled);
+ mAllowUserAspectRatioFullscreenOverrideOptProp = optPropBuilder.create(
+ PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
+ mLetterboxConfiguration::isUserAppAspectRatioFullscreenEnabled);
+ mAllowOrientationOverrideOptProp = optPropBuilder.create(
+ PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
+ }
+
+ /**
+ * Whether we should apply the min aspect ratio per-app override. When this override is applied
+ * the min aspect ratio given in the app's manifest will be overridden to the largest enabled
+ * aspect ratio treatment unless the app's manifest value is higher. The treatment will also
+ * apply if no value is provided in the manifest.
+ *
+ * <p>This method returns {@code true} when the following conditions are met:
+ * <ul>
+ * <li>Opt-out component property isn't enabled
+ * <li>Per-app override is enabled
+ * </ul>
+ */
+ boolean shouldOverrideMinAspectRatio() {
+ return mAllowMinAspectRatioOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
+ isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO));
+ }
+
+ /**
+ * Whether we should apply the user aspect ratio override to the min aspect ratio for the
+ * current app.
+ */
+ boolean shouldApplyUserMinAspectRatioOverride() {
+ if (!shouldEnableUserAspectRatioSettings()) {
+ return false;
+ }
+
+ mUserAspectRatioState.mUserAspectRatio = getUserMinAspectRatioOverrideCode();
+
+ return mUserAspectRatioState.mUserAspectRatio != USER_MIN_ASPECT_RATIO_UNSET
+ && mUserAspectRatioState.mUserAspectRatio != USER_MIN_ASPECT_RATIO_APP_DEFAULT
+ && mUserAspectRatioState.mUserAspectRatio != USER_MIN_ASPECT_RATIO_FULLSCREEN;
+ }
+
+ boolean shouldApplyUserFullscreenOverride() {
+ if (isUserFullscreenOverrideEnabled()) {
+ mUserAspectRatioState.mUserAspectRatio = getUserMinAspectRatioOverrideCode();
+
+ return mUserAspectRatioState.mUserAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN;
+ }
+
+ return false;
+ }
+
+ boolean isUserFullscreenOverrideEnabled() {
+ if (mAllowUserAspectRatioOverrideOptProp.isFalse()
+ || mAllowUserAspectRatioFullscreenOverrideOptProp.isFalse()
+ || !mLetterboxConfiguration.isUserAppAspectRatioFullscreenEnabled()) {
+ return false;
+ }
+ return true;
+ }
+
+ boolean isSystemOverrideToFullscreenEnabled() {
+ return isCompatChangeEnabled(OVERRIDE_ANY_ORIENTATION_TO_USER)
+ && !mAllowOrientationOverrideOptProp.isFalse()
+ && (mUserAspectRatioState.mUserAspectRatio == USER_MIN_ASPECT_RATIO_UNSET
+ || mUserAspectRatioState.mUserAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN);
+ }
+
+ /**
+ * Whether we should enable users to resize the current app.
+ */
+ boolean shouldEnableUserAspectRatioSettings() {
+ // We use mBooleanPropertyAllowUserAspectRatioOverride to allow apps to opt-out which has
+ // effect only if explicitly false. If mBooleanPropertyAllowUserAspectRatioOverride is null,
+ // the current app doesn't opt-out so the first part of the predicate is true.
+ return !mAllowUserAspectRatioOverrideOptProp.isFalse()
+ && mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled()
+ && mActivityRecord.mDisplayContent != null
+ && mActivityRecord.mDisplayContent.getIgnoreOrientationRequest();
+ }
+
+ boolean hasFullscreenOverride() {
+ // `mUserAspectRatio` is always initialized first in `shouldApplyUserFullscreenOverride()`.
+ return shouldApplyUserFullscreenOverride() || isSystemOverrideToFullscreenEnabled();
+ }
+
+ float getUserMinAspectRatio() {
+ switch (mUserAspectRatioState.mUserAspectRatio) {
+ case USER_MIN_ASPECT_RATIO_DISPLAY_SIZE:
+ return getDisplaySizeMinAspectRatio();
+ case USER_MIN_ASPECT_RATIO_SPLIT_SCREEN:
+ return getSplitScreenAspectRatio();
+ case USER_MIN_ASPECT_RATIO_16_9:
+ return 16 / 9f;
+ case USER_MIN_ASPECT_RATIO_4_3:
+ return 4 / 3f;
+ case USER_MIN_ASPECT_RATIO_3_2:
+ return 3 / 2f;
+ default:
+ throw new AssertionError("Unexpected user min aspect ratio override: "
+ + mUserAspectRatioState.mUserAspectRatio);
+ }
+ }
+
+ float getSplitScreenAspectRatio() {
+ // Getting the same aspect ratio that apps get in split screen.
+ final DisplayArea displayArea = mActivityRecord.getDisplayArea();
+ if (displayArea == null) {
+ return getDefaultMinAspectRatioForUnresizableApps();
+ }
+ int dividerWindowWidth =
+ getResources().getDimensionPixelSize(R.dimen.docked_stack_divider_thickness);
+ int dividerInsets =
+ getResources().getDimensionPixelSize(R.dimen.docked_stack_divider_insets);
+ int dividerSize = dividerWindowWidth - dividerInsets * 2;
+ final Rect bounds = new Rect(displayArea.getWindowConfiguration().getAppBounds());
+ if (bounds.width() >= bounds.height()) {
+ bounds.inset(/* dx */ dividerSize / 2, /* dy */ 0);
+ bounds.right = bounds.centerX();
+ } else {
+ bounds.inset(/* dx */ 0, /* dy */ dividerSize / 2);
+ bounds.bottom = bounds.centerY();
+ }
+ return AppCompatUtils.computeAspectRatio(bounds);
+ }
+
+ float getFixedOrientationLetterboxAspectRatio(@NonNull Configuration parentConfiguration) {
+ return shouldUseSplitScreenAspectRatio(parentConfiguration)
+ ? getSplitScreenAspectRatio()
+ : mActivityRecord.shouldCreateCompatDisplayInsets()
+ ? getDefaultMinAspectRatioForUnresizableApps()
+ : getDefaultMinAspectRatio();
+ }
+
+ private float getDisplaySizeMinAspectRatio() {
+ final DisplayArea displayArea = mActivityRecord.getDisplayArea();
+ if (displayArea == null) {
+ return mActivityRecord.info.getMinAspectRatio();
+ }
+ final Rect bounds = new Rect(displayArea.getWindowConfiguration().getAppBounds());
+ return AppCompatUtils.computeAspectRatio(bounds);
+ }
+
+ private boolean shouldUseSplitScreenAspectRatio(@NonNull Configuration parentConfiguration) {
+ final boolean isBookMode = mIsDisplayFullScreenAndInPostureProvider
+ .apply(/* isTabletop */false);
+ final boolean isNotCenteredHorizontally = mGetHorizontalPositionMultiplierProvider.apply(
+ parentConfiguration) != LETTERBOX_POSITION_MULTIPLIER_CENTER;
+ final boolean isTabletopMode = mIsDisplayFullScreenAndInPostureProvider
+ .apply(/* isTabletop */ true);
+ final boolean isLandscape = isFixedOrientationLandscape(
+ mActivityRecord.getOverrideOrientation());
+ final AppCompatCameraOverrides cameraOverrides =
+ mActivityRecord.mAppCompatController.getAppCompatCameraOverrides();
+ final AppCompatCameraPolicy cameraPolicy =
+ mActivityRecord.mAppCompatController.getAppCompatCameraPolicy();
+ // Don't resize to split screen size when in book mode if letterbox position is centered
+ return (isBookMode && isNotCenteredHorizontally || isTabletopMode && isLandscape)
+ || cameraOverrides.isCameraCompatSplitScreenAspectRatioAllowed()
+ && (cameraPolicy != null
+ && cameraPolicy.isTreatmentEnabledForActivity(mActivityRecord));
+ }
+
+ @VisibleForTesting
+ int getUserMinAspectRatioOverrideCode() {
+ try {
+ return mActivityRecord.mAtmService.getPackageManager()
+ .getUserMinAspectRatio(mActivityRecord.packageName, mActivityRecord.mUserId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Exception thrown retrieving aspect ratio user override " + this, e);
+ }
+ return mUserAspectRatioState.mUserAspectRatio;
+ }
+
+ private float getDefaultMinAspectRatioForUnresizableApps() {
+ if (!mLetterboxConfiguration.getIsSplitScreenAspectRatioForUnresizableAppsEnabled()
+ || mActivityRecord.getDisplayArea() == null) {
+ return mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
+ > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
+ ? mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
+ : getDefaultMinAspectRatio();
+ }
+
+ return getSplitScreenAspectRatio();
+ }
+
+ private float getDefaultMinAspectRatio() {
+ if (mActivityRecord.getDisplayArea() == null
+ || !mLetterboxConfiguration
+ .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox()) {
+ return mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
+ }
+ return getDisplaySizeMinAspectRatio();
+ }
+
+ private static class UserAspectRatioState {
+ // TODO(b/315140179): Make mUserAspectRatio final
+ // The min aspect ratio override set by user
+ @PackageManager.UserMinAspectRatio
+ private int mUserAspectRatio = USER_MIN_ASPECT_RATIO_UNSET;
+ }
+
+ private boolean isCompatChangeEnabled(long overrideChangeId) {
+ return mActivityRecord.info.isChangeEnabled(overrideChangeId);
+ }
+
+ private Resources getResources() {
+ return mActivityRecord.mWmService.mContext.getResources();
+ }
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java b/services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java
new file mode 100644
index 000000000000..a7d2ecce4984
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java
@@ -0,0 +1,379 @@
+/*
+ * 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.wm;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+
+import static com.android.server.wm.LetterboxConfiguration.DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW;
+import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.WindowConfiguration;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+
+/**
+ * Encapsulate app compat policy logic related to aspect ratio.
+ */
+class AppCompatAspectRatioPolicy {
+
+ // Rounding tolerance to be used in aspect ratio computations
+ private static final float ASPECT_RATIO_ROUNDING_TOLERANCE = 0.005f;
+
+ @NonNull
+ private final ActivityRecord mActivityRecord;
+ @NonNull
+ private final TransparentPolicy mTransparentPolicy;
+ @NonNull
+ private final AppCompatOverrides mAppCompatOverrides;
+ @NonNull
+ private final AppCompatAspectRatioState mAppCompatAspectRatioState;
+
+ AppCompatAspectRatioPolicy(@NonNull ActivityRecord activityRecord,
+ @NonNull TransparentPolicy transparentPolicy,
+ @NonNull AppCompatOverrides appCompatOverrides) {
+ mActivityRecord = activityRecord;
+ mTransparentPolicy = transparentPolicy;
+ mAppCompatOverrides = appCompatOverrides;
+ mAppCompatAspectRatioState = new AppCompatAspectRatioState();
+ }
+
+ /**
+ * Starts the evaluation of app compat aspect ratio when a new configuration needs to be
+ * resolved.
+ */
+ void reset() {
+ mAppCompatAspectRatioState.reset();
+ }
+
+ float getDesiredAspectRatio(@NonNull Configuration newParentConfig,
+ @NonNull Rect parentBounds) {
+ final float letterboxAspectRatioOverride =
+ mAppCompatOverrides.getAppCompatAspectRatioOverrides()
+ .getFixedOrientationLetterboxAspectRatio(newParentConfig);
+ // Aspect ratio as suggested by the system. Apps requested mix/max aspect ratio will
+ // be respected in #applyAspectRatio.
+ if (isDefaultMultiWindowLetterboxAspectRatioDesired(newParentConfig)) {
+ return DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW;
+ } else if (letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) {
+ return letterboxAspectRatioOverride;
+ }
+ return AppCompatUtils.computeAspectRatio(parentBounds);
+ }
+
+ void applyDesiredAspectRatio(@NonNull Configuration newParentConfig, @NonNull Rect parentBounds,
+ @NonNull Rect resolvedBounds, @NonNull Rect containingBoundsWithInsets,
+ @NonNull Rect containingBounds) {
+ final float desiredAspectRatio = getDesiredAspectRatio(newParentConfig, parentBounds);
+ mAppCompatAspectRatioState.mIsAspectRatioApplied = applyAspectRatio(resolvedBounds,
+ containingBoundsWithInsets, containingBounds, desiredAspectRatio);
+ }
+
+ void applyAspectRatioForLetterbox(Rect outBounds, Rect containingAppBounds,
+ Rect containingBounds) {
+ mAppCompatAspectRatioState.mIsAspectRatioApplied = applyAspectRatio(outBounds,
+ containingAppBounds, containingBounds, 0 /* desiredAspectRatio */);
+ }
+
+ /**
+ * @return {@code true} when an app compat aspect ratio has been applied.
+ */
+ boolean isAspectRatioApplied() {
+ return mAppCompatAspectRatioState.mIsAspectRatioApplied;
+ }
+
+ /**
+ * Returns the min aspect ratio of this activity.
+ */
+ float getMinAspectRatio() {
+ if (mTransparentPolicy.isRunning()) {
+ return mTransparentPolicy.getInheritedMinAspectRatio();
+ }
+ final ActivityInfo info = mActivityRecord.info;
+ if (info.applicationInfo == null) {
+ return info.getMinAspectRatio();
+ }
+ final AppCompatAspectRatioOverrides aspectRatioOverrides =
+ mAppCompatOverrides.getAppCompatAspectRatioOverrides();
+ if (aspectRatioOverrides.shouldApplyUserMinAspectRatioOverride()) {
+ return aspectRatioOverrides.getUserMinAspectRatio();
+ }
+ if (!aspectRatioOverrides.shouldOverrideMinAspectRatio()
+ && !mAppCompatOverrides.getAppCompatCameraOverrides()
+ .shouldOverrideMinAspectRatioForCamera()) {
+ return info.getMinAspectRatio();
+ }
+
+ if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY)
+ && !ActivityInfo.isFixedOrientationPortrait(
+ mActivityRecord.getOverrideOrientation())) {
+ return info.getMinAspectRatio();
+ }
+
+ if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN)
+ && isParentFullscreenPortrait()) {
+ // We are using the parent configuration here as this is the most recent one that gets
+ // passed to onConfigurationChanged when a relevant change takes place
+ return info.getMinAspectRatio();
+ }
+
+ if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN)) {
+ return Math.max(aspectRatioOverrides.getSplitScreenAspectRatio(),
+ info.getMinAspectRatio());
+ }
+
+ if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_LARGE)) {
+ return Math.max(ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
+ info.getMinAspectRatio());
+ }
+
+ if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_MEDIUM)) {
+ return Math.max(ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE,
+ info.getMinAspectRatio());
+ }
+
+ if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_SMALL)) {
+ return Math.max(ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL_VALUE,
+ info.getMinAspectRatio());
+ }
+ return info.getMinAspectRatio();
+ }
+
+ float getMaxAspectRatio() {
+ if (mTransparentPolicy.isRunning()) {
+ return mTransparentPolicy.getInheritedMaxAspectRatio();
+ }
+ return mActivityRecord.info.getMaxAspectRatio();
+ }
+
+ @Nullable
+ Rect getLetterboxedContainerBounds() {
+ return mAppCompatAspectRatioState.getLetterboxedContainerBounds();
+ }
+
+ /**
+ * Whether this activity is letterboxed for fixed orientation. If letterboxed due to fixed
+ * orientation then aspect ratio restrictions are also already respected.
+ *
+ * <p>This happens when an activity has fixed orientation which doesn't match orientation of the
+ * parent because a display setting 'ignoreOrientationRequest' is set to true. See {@link
+ * WindowManagerService#getIgnoreOrientationRequest} for more context.
+ */
+ boolean isLetterboxedForFixedOrientationAndAspectRatio() {
+ return mAppCompatAspectRatioState.isLetterboxedForFixedOrientationAndAspectRatio();
+ }
+
+ boolean isLetterboxedForAspectRatioOnly() {
+ return mAppCompatAspectRatioState.isLetterboxedForAspectRatioOnly();
+ }
+
+ void setLetterboxBoundsForFixedOrientationAndAspectRatio(@NonNull Rect bounds) {
+ mAppCompatAspectRatioState.mLetterboxBoundsForFixedOrientationAndAspectRatio = bounds;
+ }
+
+ void setLetterboxBoundsForAspectRatio(@NonNull Rect bounds) {
+ mAppCompatAspectRatioState.mLetterboxBoundsForAspectRatio = bounds;
+ }
+
+ private boolean isParentFullscreenPortrait() {
+ final WindowContainer<?> parent = mActivityRecord.getParent();
+ return parent != null
+ && parent.getConfiguration().orientation == ORIENTATION_PORTRAIT
+ && parent.getWindowConfiguration().getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
+ }
+
+ /**
+ * Applies aspect ratio restrictions to outBounds. If no restrictions, then no change is
+ * made to outBounds.
+ *
+ * @return {@code true} if aspect ratio restrictions were applied.
+ */
+ private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
+ Rect containingBounds, float desiredAspectRatio) {
+ final float maxAspectRatio = getMaxAspectRatio();
+ final Task rootTask = mActivityRecord.getRootTask();
+ final Task task = mActivityRecord.getTask();
+ final float minAspectRatio = getMinAspectRatio();
+ final TaskFragment organizedTf = mActivityRecord.getOrganizedTaskFragment();
+ float aspectRatioToApply = desiredAspectRatio;
+ if (task == null || rootTask == null
+ || (maxAspectRatio < 1 && minAspectRatio < 1 && aspectRatioToApply < 1)
+ // Don't set aspect ratio if we are in VR mode.
+ || AppCompatUtils.isInVrUiMode(mActivityRecord.getConfiguration())
+ // TODO(b/232898850): Always respect aspect ratio requests.
+ // Don't set aspect ratio for activity in ActivityEmbedding split.
+ || (organizedTf != null && !organizedTf.fillsParent())) {
+ return false;
+ }
+
+ final int containingAppWidth = containingAppBounds.width();
+ final int containingAppHeight = containingAppBounds.height();
+ final float containingRatio = AppCompatUtils.computeAspectRatio(containingAppBounds);
+
+ if (aspectRatioToApply < 1) {
+ aspectRatioToApply = containingRatio;
+ }
+
+ if (maxAspectRatio >= 1 && aspectRatioToApply > maxAspectRatio) {
+ aspectRatioToApply = maxAspectRatio;
+ } else if (minAspectRatio >= 1 && aspectRatioToApply < minAspectRatio) {
+ aspectRatioToApply = minAspectRatio;
+ }
+
+ int activityWidth = containingAppWidth;
+ int activityHeight = containingAppHeight;
+
+ if (containingRatio - aspectRatioToApply > ASPECT_RATIO_ROUNDING_TOLERANCE) {
+ if (containingAppWidth < containingAppHeight) {
+ // Width is the shorter side, so we use that to figure-out what the max. height
+ // should be given the aspect ratio.
+ activityHeight = (int) ((activityWidth * aspectRatioToApply) + 0.5f);
+ } else {
+ // Height is the shorter side, so we use that to figure-out what the max. width
+ // should be given the aspect ratio.
+ activityWidth = (int) ((activityHeight * aspectRatioToApply) + 0.5f);
+ }
+ } else if (aspectRatioToApply - containingRatio > ASPECT_RATIO_ROUNDING_TOLERANCE) {
+ boolean adjustWidth;
+ switch (mActivityRecord.getRequestedConfigurationOrientation()) {
+ case ORIENTATION_LANDSCAPE:
+ // Width should be the longer side for this landscape app, so we use the width
+ // to figure-out what the max. height should be given the aspect ratio.
+ adjustWidth = false;
+ break;
+ case ORIENTATION_PORTRAIT:
+ // Height should be the longer side for this portrait app, so we use the height
+ // to figure-out what the max. width should be given the aspect ratio.
+ adjustWidth = true;
+ break;
+ default:
+ // This app doesn't have a preferred orientation, so we keep the length of the
+ // longer side, and use it to figure-out the length of the shorter side.
+ if (containingAppWidth < containingAppHeight) {
+ // Width is the shorter side, so we use the height to figure-out what the
+ // max. width should be given the aspect ratio.
+ adjustWidth = true;
+ } else {
+ // Height is the shorter side, so we use the width to figure-out what the
+ // max. height should be given the aspect ratio.
+ adjustWidth = false;
+ }
+ break;
+ }
+ if (adjustWidth) {
+ activityWidth = (int) ((activityHeight / aspectRatioToApply) + 0.5f);
+ } else {
+ activityHeight = (int) ((activityWidth / aspectRatioToApply) + 0.5f);
+ }
+ }
+
+ if (containingAppWidth <= activityWidth && containingAppHeight <= activityHeight) {
+ // The display matches or is less than the activity aspect ratio, so nothing else to do.
+ return false;
+ }
+
+ // Compute configuration based on max or min supported width and height.
+ // Also account for the insets (e.g. display cutouts, navigation bar), which will be
+ // clipped away later in {@link Task#computeConfigResourceOverrides()}, i.e., the out
+ // bounds are the app bounds restricted by aspect ratio + clippable insets. Otherwise,
+ // the app bounds would end up too small. To achieve this we will also add clippable insets
+ // when the corresponding dimension fully fills the parent
+
+ int right = activityWidth + containingAppBounds.left;
+ int left = containingAppBounds.left;
+ if (right >= containingAppBounds.right) {
+ right = containingBounds.right;
+ left = containingBounds.left;
+ }
+ int bottom = activityHeight + containingAppBounds.top;
+ int top = containingAppBounds.top;
+ if (bottom >= containingAppBounds.bottom) {
+ bottom = containingBounds.bottom;
+ top = containingBounds.top;
+ }
+ outBounds.set(left, top, right, bottom);
+ return true;
+ }
+
+ /**
+ * Returns {@code true} if the default aspect ratio for a letterboxed app in multi-window mode
+ * should be used.
+ */
+ private boolean isDefaultMultiWindowLetterboxAspectRatioDesired(
+ @NonNull Configuration parentConfig) {
+ final DisplayContent dc = mActivityRecord.mDisplayContent;
+ if (dc == null) {
+ return false;
+ }
+ final int windowingMode = parentConfig.windowConfiguration.getWindowingMode();
+ return WindowConfiguration.inMultiWindowMode(windowingMode)
+ && !dc.getIgnoreOrientationRequest();
+ }
+
+ private static class AppCompatAspectRatioState {
+ // Whether the aspect ratio restrictions applied to the activity bounds
+ // in applyAspectRatio().
+ private boolean mIsAspectRatioApplied = false;
+
+ // Bounds populated in resolveAspectRatioRestriction when this activity is letterboxed for
+ // aspect ratio. If not null, they are used as parent container in
+ // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets.
+ @Nullable
+ private Rect mLetterboxBoundsForAspectRatio;
+ // Bounds populated in resolveFixedOrientationConfiguration when this activity is
+ // letterboxed for fixed orientation. If not null, they are used as parent container in
+ // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets. If
+ // letterboxed due to fixed orientation then aspect ratio restrictions are also respected.
+ // This happens when an activity has fixed orientation which doesn't match orientation of
+ // the parent because a display is ignoring orientation request or fixed to user rotation.
+ // See WindowManagerService#getIgnoreOrientationRequest and
+ // WindowManagerService#getFixedToUserRotation for more context.
+ @Nullable
+ private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;
+
+ @Nullable
+ Rect getLetterboxedContainerBounds() {
+ return mLetterboxBoundsForFixedOrientationAndAspectRatio != null
+ ? mLetterboxBoundsForFixedOrientationAndAspectRatio
+ : mLetterboxBoundsForAspectRatio;
+ }
+
+ void reset() {
+ mIsAspectRatioApplied = false;
+ mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
+ mLetterboxBoundsForAspectRatio = null;
+ }
+
+ boolean isLetterboxedForFixedOrientationAndAspectRatio() {
+ return mLetterboxBoundsForFixedOrientationAndAspectRatio != null;
+ }
+
+ boolean isLetterboxedForAspectRatioOnly() {
+ return mLetterboxBoundsForAspectRatio != null;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
index c0e5005cd01e..0d108e1d9fd9 100644
--- a/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
@@ -97,8 +97,7 @@ class AppCompatCameraOverrides {
* </ul>
*/
boolean shouldOverrideMinAspectRatioForCamera() {
- return mActivityRecord.isCameraActive()
- && mAllowMinAspectRatioOverrideOptProp
+ return isCameraActive() && mAllowMinAspectRatioOverrideOptProp
.shouldEnableWithOptInOverrideAndOptOutProperty(
isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA));
}
@@ -174,6 +173,15 @@ class AppCompatCameraOverrides {
}
/**
+ * @return {@code true} if the Camera is active for the current activity
+ */
+ boolean isCameraActive() {
+ return mActivityRecord.mDisplayContent != null
+ && mActivityRecord.mDisplayContent.mAppCompatCameraPolicy
+ .isCameraActive(mActivityRecord, /* mustBeFullscreen */ true);
+ }
+
+ /**
* @return {@code true} if the configuration needs to be recomputed after a camera state update.
*/
boolean shouldRecomputeConfigurationForCameraCompat() {
diff --git a/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java b/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java
index ee523a29c4d9..53729a2a971c 100644
--- a/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java
@@ -16,34 +16,158 @@
package com.android.server.wm;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.ScreenOrientation;
+import android.content.res.Configuration;
+import android.widget.Toast;
+
+import com.android.window.flags.Flags;
/**
- * Encapsulate the app compat logic related to camera.
+ * Encapsulate policy logic related to app compat display rotation.
*/
class AppCompatCameraPolicy {
- private static final String TAG = TAG_WITH_CLASS_NAME
- ? "AppCompatCameraPolicy" : TAG_ATM;
+ @Nullable
+ private final CameraStateMonitor mCameraStateMonitor;
+ @Nullable
+ private final ActivityRefresher mActivityRefresher;
+ @Nullable
+ final DisplayRotationCompatPolicy mDisplayRotationCompatPolicy;
+ @Nullable
+ final CameraCompatFreeformPolicy mCameraCompatFreeformPolicy;
- @NonNull
- private final ActivityRecord mActivityRecord;
+ AppCompatCameraPolicy(@NonNull WindowManagerService wmService,
+ @NonNull DisplayContent displayContent) {
+ // Not checking DeviceConfig value here to allow enabling via DeviceConfig
+ // without the need to restart the device.
+ final boolean needsDisplayRotationCompatPolicy =
+ wmService.mLetterboxConfiguration.isCameraCompatTreatmentEnabledAtBuildTime();
+ final boolean needsCameraCompatFreeformPolicy = Flags.cameraCompatForFreeform()
+ && DesktopModeLaunchParamsModifier.canEnterDesktopMode(wmService.mContext);
+ if (needsDisplayRotationCompatPolicy || needsCameraCompatFreeformPolicy) {
+ mCameraStateMonitor = new CameraStateMonitor(displayContent, wmService.mH);
+ mActivityRefresher = new ActivityRefresher(wmService, wmService.mH);
+ mDisplayRotationCompatPolicy =
+ needsDisplayRotationCompatPolicy ? new DisplayRotationCompatPolicy(
+ displayContent, mCameraStateMonitor, mActivityRefresher) : null;
+ mCameraCompatFreeformPolicy =
+ needsCameraCompatFreeformPolicy ? new CameraCompatFreeformPolicy(displayContent,
+ mCameraStateMonitor, mActivityRefresher) : null;
+ } else {
+ mDisplayRotationCompatPolicy = null;
+ mCameraCompatFreeformPolicy = null;
+ mCameraStateMonitor = null;
+ mActivityRefresher = null;
+ }
+ }
- @NonNull
- private final AppCompatCameraOverrides mAppCompatCameraOverrides;
+ void onActivityRefreshed(@NonNull ActivityRecord activity) {
+ if (mActivityRefresher != null) {
+ mActivityRefresher.onActivityRefreshed(activity);
+ }
+ }
- AppCompatCameraPolicy(@NonNull ActivityRecord activityRecord,
- @NonNull AppCompatCameraOverrides appCompatCameraOverrides) {
- mActivityRecord = activityRecord;
- mAppCompatCameraOverrides = appCompatCameraOverrides;
+ /**
+ * "Refreshes" activity by going through "stopped -> resumed" or "paused -> resumed" cycle.
+ * This allows to clear cached values in apps (e.g. display or camera rotation) that influence
+ * camera preview and can lead to sideways or stretching issues persisting even after force
+ * rotation.
+ */
+ void onActivityConfigurationChanging(@NonNull ActivityRecord activity,
+ @NonNull Configuration newConfig, @NonNull Configuration lastReportedConfig) {
+ if (mActivityRefresher != null) {
+ mActivityRefresher.onActivityConfigurationChanging(activity, newConfig,
+ lastReportedConfig);
+ }
+ }
+
+ /**
+ * Notifies that animation in {@link ScreenRotationAnimation} has finished.
+ *
+ * <p>This class uses this signal as a trigger for notifying the user about forced rotation
+ * reason with the {@link Toast}.
+ */
+ void onScreenRotationAnimationFinished() {
+ if (mDisplayRotationCompatPolicy != null) {
+ mDisplayRotationCompatPolicy.onScreenRotationAnimationFinished();
+ }
}
- void recomputeConfigurationForCameraCompatIfNeeded() {
- if (mAppCompatCameraOverrides.shouldRecomputeConfigurationForCameraCompat()) {
- mActivityRecord.recomputeConfiguration();
+ boolean isActivityEligibleForOrientationOverride(@NonNull ActivityRecord activity) {
+ if (mDisplayRotationCompatPolicy != null) {
+ return mDisplayRotationCompatPolicy.isActivityEligibleForOrientationOverride(activity);
}
+ return false;
}
+
+ /**
+ * Whether camera compat treatment is applicable for the given activity.
+ *
+ * <p>Conditions that need to be met:
+ * <ul>
+ * <li>Camera is active for the package.
+ * <li>The activity is in fullscreen
+ * <li>The activity has fixed orientation but not "locked" or "nosensor" one.
+ * </ul>
+ */
+ boolean isTreatmentEnabledForActivity(@Nullable ActivityRecord activity) {
+ if (mDisplayRotationCompatPolicy != null) {
+ return mDisplayRotationCompatPolicy.isTreatmentEnabledForActivity(activity);
+ }
+ return false;
+ }
+
+ void start() {
+ if (mCameraCompatFreeformPolicy != null) {
+ mCameraCompatFreeformPolicy.start();
+ }
+ if (mCameraStateMonitor != null) {
+ mCameraStateMonitor.startListeningToCameraState();
+ }
+ }
+
+ void dispose() {
+ if (mDisplayRotationCompatPolicy != null) {
+ mDisplayRotationCompatPolicy.dispose();
+ }
+ if (mCameraCompatFreeformPolicy != null) {
+ mCameraCompatFreeformPolicy.dispose();
+ }
+ if (mCameraStateMonitor != null) {
+ mCameraStateMonitor.dispose();
+ }
+ }
+
+ boolean hasDisplayRotationCompatPolicy() {
+ return mDisplayRotationCompatPolicy != null;
+ }
+
+ boolean hasCameraCompatFreeformPolicy() {
+ return mCameraCompatFreeformPolicy != null;
+ }
+
+ @ScreenOrientation
+ int getOrientation() {
+ return mDisplayRotationCompatPolicy != null
+ ? mDisplayRotationCompatPolicy.getOrientation()
+ : SCREEN_ORIENTATION_UNSPECIFIED;
+ }
+
+ boolean isCameraActive(@NonNull ActivityRecord activity, boolean mustBeFullscreen) {
+ return mDisplayRotationCompatPolicy != null
+ && mDisplayRotationCompatPolicy.isCameraActive(activity, mustBeFullscreen);
+ }
+
+ @Nullable
+ String getSummaryForDisplayRotationHistoryRecord() {
+ if (mDisplayRotationCompatPolicy != null) {
+ return mDisplayRotationCompatPolicy.getSummaryForDisplayRotationHistoryRecord();
+ }
+ return null;
+ }
+
}
diff --git a/services/core/java/com/android/server/wm/AppCompatController.java b/services/core/java/com/android/server/wm/AppCompatController.java
index d8c0c175e511..3eed96dd90c2 100644
--- a/services/core/java/com/android/server/wm/AppCompatController.java
+++ b/services/core/java/com/android/server/wm/AppCompatController.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.pm.PackageManager;
import com.android.server.wm.utils.OptPropFactory;
@@ -26,16 +27,19 @@ import com.android.server.wm.utils.OptPropFactory;
class AppCompatController {
@NonNull
+ private final ActivityRecord mActivityRecord;
+ @NonNull
private final TransparentPolicy mTransparentPolicy;
@NonNull
private final AppCompatOrientationPolicy mOrientationPolicy;
@NonNull
- private final AppCompatOverrides mAppCompatOverrides;
+ private final AppCompatAspectRatioPolicy mAppCompatAspectRatioPolicy;
@NonNull
- private final AppCompatCameraPolicy mAppCompatCameraPolicy;
+ private final AppCompatOverrides mAppCompatOverrides;
AppCompatController(@NonNull WindowManagerService wmService,
@NonNull ActivityRecord activityRecord) {
+ mActivityRecord = activityRecord;
final PackageManager packageManager = wmService.mContext.getPackageManager();
final OptPropFactory optPropBuilder = new OptPropFactory(packageManager,
activityRecord.packageName);
@@ -43,14 +47,9 @@ class AppCompatController {
wmService.mLetterboxConfiguration);
mAppCompatOverrides = new AppCompatOverrides(activityRecord,
wmService.mLetterboxConfiguration, optPropBuilder);
- // TODO(b/341903757) Remove BooleanSuppliers after fixing dependency with aspectRatio.
- final LetterboxUiController tmpController = activityRecord.mLetterboxUiController;
- mOrientationPolicy = new AppCompatOrientationPolicy(activityRecord,
- mAppCompatOverrides, tmpController::shouldApplyUserFullscreenOverride,
- tmpController::shouldApplyUserMinAspectRatioOverride,
- tmpController::isSystemOverrideToFullscreenEnabled);
- mAppCompatCameraPolicy = new AppCompatCameraPolicy(activityRecord,
- mAppCompatOverrides.getAppCompatCameraOverrides());
+ mOrientationPolicy = new AppCompatOrientationPolicy(activityRecord, mAppCompatOverrides);
+ mAppCompatAspectRatioPolicy = new AppCompatAspectRatioPolicy(activityRecord,
+ mTransparentPolicy, mAppCompatOverrides);
}
@NonNull
@@ -64,8 +63,8 @@ class AppCompatController {
}
@NonNull
- AppCompatCameraPolicy getAppCompatCameraPolicy() {
- return mAppCompatCameraPolicy;
+ AppCompatAspectRatioPolicy getAppCompatAspectRatioPolicy() {
+ return mAppCompatAspectRatioPolicy;
}
@NonNull
@@ -82,4 +81,17 @@ class AppCompatController {
AppCompatCameraOverrides getAppCompatCameraOverrides() {
return mAppCompatOverrides.getAppCompatCameraOverrides();
}
+
+ @NonNull
+ AppCompatAspectRatioOverrides getAppCompatAspectRatioOverrides() {
+ return mAppCompatOverrides.getAppCompatAspectRatioOverrides();
+ }
+
+ @Nullable
+ AppCompatCameraPolicy getAppCompatCameraPolicy() {
+ if (mActivityRecord.mDisplayContent != null) {
+ return mActivityRecord.mDisplayContent.mAppCompatCameraPolicy;
+ }
+ return null;
+ }
}
diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java b/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java
index b0fdbb5dff87..9bf80119e431 100644
--- a/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java
@@ -22,7 +22,6 @@ import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQU
import static android.content.pm.ActivityInfo.OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE;
import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR;
import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT;
-import static android.content.pm.ActivityInfo.screenOrientationToString;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
@@ -31,8 +30,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
import static com.android.server.wm.AppCompatUtils.asLazy;
import android.annotation.NonNull;
-import android.content.pm.ActivityInfo;
-import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wm.utils.OptPropFactory;
@@ -51,7 +48,8 @@ class AppCompatOrientationOverrides {
@NonNull
private final ActivityRecord mActivityRecord;
-
+ @NonNull
+ private final AppCompatCameraOverrides mAppCompatCameraOverrides;
@NonNull
private final OptPropFactory.OptProp mIgnoreRequestedOrientationOptProp;
@NonNull
@@ -62,8 +60,10 @@ class AppCompatOrientationOverrides {
AppCompatOrientationOverrides(@NonNull ActivityRecord activityRecord,
@NonNull LetterboxConfiguration letterboxConfiguration,
- @NonNull OptPropFactory optPropBuilder) {
+ @NonNull OptPropFactory optPropBuilder,
+ @NonNull AppCompatCameraOverrides appCompatCameraOverrides) {
mActivityRecord = activityRecord;
+ mAppCompatCameraOverrides = appCompatCameraOverrides;
mOrientationOverridesState = new OrientationOverridesState(mActivityRecord,
System::currentTimeMillis);
final BooleanSupplier isPolicyForIgnoringRequestedOrientationEnabled = asLazy(
@@ -76,59 +76,9 @@ class AppCompatOrientationOverrides {
isPolicyForIgnoringRequestedOrientationEnabled);
}
- /**
- * Whether should ignore app requested orientation in response to an app
- * calling {@link android.app.Activity#setRequestedOrientation}.
- *
- * <p>This is needed to avoid getting into {@link android.app.Activity#setRequestedOrientation}
- * loop when {@link DisplayContent#getIgnoreOrientationRequest} is enabled or device has
- * landscape natural orientation which app developers don't expect. For example, the loop can
- * look like this:
- * <ol>
- * <li>App sets default orientation to "unspecified" at runtime
- * <li>App requests to "portrait" after checking some condition (e.g. display rotation).
- * <li>(2) leads to fullscreen -> letterboxed bounds change and activity relaunch because
- * app can't handle the corresponding config changes.
- * <li>Loop goes back to (1)
- * </ol>
- *
- * <p>This treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Flag gating the treatment is enabled
- * <li>Opt-out component property isn't enabled
- * <li>Opt-in component property or per-app override are enabled
- * <li>Activity is relaunched after {@link android.app.Activity#setRequestedOrientation}
- * call from an app or camera compat force rotation treatment is active for the activity.
- * <li>Orientation request loop detected and is not letterboxed for fixed orientation
- * </ul>
- */
- boolean shouldIgnoreRequestedOrientation(
- @ActivityInfo.ScreenOrientation int requestedOrientation) {
- if (mIgnoreRequestedOrientationOptProp.shouldEnableWithOverrideAndProperty(
- isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION))) {
- if (mOrientationOverridesState.mIsRelaunchingAfterRequestedOrientationChanged) {
- Slog.w(TAG, "Ignoring orientation update to "
- + screenOrientationToString(requestedOrientation)
- + " due to relaunching after setRequestedOrientation for "
- + mActivityRecord);
- return true;
- }
- if (isCameraCompatTreatmentActive()) {
- Slog.w(TAG, "Ignoring orientation update to "
- + screenOrientationToString(requestedOrientation)
- + " due to camera compat treatment for " + mActivityRecord);
- return true;
- }
- }
-
- if (shouldIgnoreOrientationRequestLoop()) {
- Slog.w(TAG, "Ignoring orientation update to "
- + screenOrientationToString(requestedOrientation)
- + " as orientation request loop was detected for "
- + mActivityRecord);
- return true;
- }
- return false;
+ boolean shouldEnableIgnoreOrientationRequest() {
+ return mIgnoreRequestedOrientationOptProp.shouldEnableWithOverrideAndProperty(
+ isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION));
}
/**
@@ -158,7 +108,8 @@ class AppCompatOrientationOverrides {
mOrientationOverridesState.updateOrientationRequestLoopState();
return mOrientationOverridesState.shouldIgnoreRequestInLoop()
- && !mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio();
+ && !mActivityRecord.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio();
}
/**
@@ -183,20 +134,6 @@ class AppCompatOrientationOverrides {
return mActivityRecord.info.isChangeEnabled(overrideChangeId);
}
- /**
- * @return {@code true} if the App Compat Camera Policy is active for the current activity.
- */
- // TODO(b/346253439): Remove after defining dependency with Camera capabilities.
- private boolean isCameraCompatTreatmentActive() {
- DisplayContent displayContent = mActivityRecord.mDisplayContent;
- if (displayContent == null) {
- return false;
- }
- return displayContent.mDisplayRotationCompatPolicy != null
- && displayContent.mDisplayRotationCompatPolicy
- .isTreatmentEnabledForActivity(mActivityRecord);
- }
-
static class OrientationOverridesState {
// Corresponds to OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR
final boolean mIsOverrideToNosensorOrientationEnabled;
diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
index 960ef5abb58f..17f0d970d043 100644
--- a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
@@ -32,8 +32,6 @@ import android.annotation.NonNull;
import android.content.pm.ActivityInfo;
import android.util.Slog;
-import java.util.function.BooleanSupplier;
-
/**
* Contains all the logic related to orientation in the context of app compatibility
*/
@@ -47,24 +45,10 @@ class AppCompatOrientationPolicy {
@NonNull
private final AppCompatOverrides mAppCompatOverrides;
- @NonNull
- private final BooleanSupplier mShouldApplyUserFullscreenOverride;
- @NonNull
- private final BooleanSupplier mShouldApplyUserMinAspectRatioOverride;
- @NonNull
- private final BooleanSupplier mIsSystemOverrideToFullscreenEnabled;
-
- // TODO(b/341903757) Remove BooleanSuppliers after fixing dependency with spectRatio component
AppCompatOrientationPolicy(@NonNull ActivityRecord activityRecord,
- @NonNull AppCompatOverrides appCompatOverrides,
- @NonNull BooleanSupplier shouldApplyUserFullscreenOverride,
- @NonNull BooleanSupplier shouldApplyUserMinAspectRatioOverride,
- @NonNull BooleanSupplier isSystemOverrideToFullscreenEnabled) {
+ @NonNull AppCompatOverrides appCompatOverrides) {
mActivityRecord = activityRecord;
mAppCompatOverrides = appCompatOverrides;
- mShouldApplyUserFullscreenOverride = shouldApplyUserFullscreenOverride;
- mShouldApplyUserMinAspectRatioOverride = shouldApplyUserMinAspectRatioOverride;
- mIsSystemOverrideToFullscreenEnabled = isSystemOverrideToFullscreenEnabled;
}
@ActivityInfo.ScreenOrientation
@@ -72,13 +56,15 @@ class AppCompatOrientationPolicy {
final DisplayContent displayContent = mActivityRecord.mDisplayContent;
final boolean isIgnoreOrientationRequestEnabled = displayContent != null
&& displayContent.getIgnoreOrientationRequest();
- if (mShouldApplyUserFullscreenOverride.getAsBoolean() && isIgnoreOrientationRequestEnabled
+ final boolean shouldApplyUserFullscreenOverride = mAppCompatOverrides
+ .getAppCompatAspectRatioOverrides().shouldApplyUserFullscreenOverride();
+ if (shouldApplyUserFullscreenOverride && isIgnoreOrientationRequestEnabled
// Do not override orientation to fullscreen for camera activities.
// Fixed-orientation activities are rarely tested in other orientations, and it
// often results in sideways or stretched previews. As the camera compat treatment
// targets fixed-orientation activities, overriding the orientation disables the
// treatment.
- && !mActivityRecord.isCameraActive()) {
+ && !mAppCompatOverrides.getAppCompatCameraOverrides().isCameraActive()) {
Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate)
+ " for " + mActivityRecord + " is overridden to "
+ screenOrientationToString(SCREEN_ORIENTATION_USER)
@@ -89,8 +75,9 @@ class AppCompatOrientationPolicy {
// In some cases (e.g. Kids app) we need to map the candidate orientation to some other
// orientation.
candidate = mActivityRecord.mWmService.mapOrientationRequest(candidate);
-
- if (mShouldApplyUserMinAspectRatioOverride.getAsBoolean() && (!isFixedOrientation(candidate)
+ final boolean shouldApplyUserMinAspectRatioOverride = mAppCompatOverrides
+ .getAppCompatAspectRatioOverrides().shouldApplyUserMinAspectRatioOverride();
+ if (shouldApplyUserMinAspectRatioOverride && (!isFixedOrientation(candidate)
|| candidate == SCREEN_ORIENTATION_LOCKED)) {
Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate)
+ " for " + mActivityRecord + " is overridden to "
@@ -103,24 +90,26 @@ class AppCompatOrientationPolicy {
return candidate;
}
- if (displayContent != null && mAppCompatOverrides.getAppCompatCameraOverrides()
- .isOverrideOrientationOnlyForCameraEnabled()
- && (displayContent.mDisplayRotationCompatPolicy == null
- || !displayContent.mDisplayRotationCompatPolicy
- .isActivityEligibleForOrientationOverride(mActivityRecord))) {
+ if (displayContent != null
+ && mAppCompatOverrides.getAppCompatCameraOverrides()
+ .isOverrideOrientationOnlyForCameraEnabled()
+ && !displayContent.mAppCompatCameraPolicy
+ .isActivityEligibleForOrientationOverride(mActivityRecord)) {
return candidate;
}
// mUserAspectRatio is always initialized first in shouldApplyUserFullscreenOverride(),
// which will always come first before this check as user override > device
// manufacturer override.
- if (mIsSystemOverrideToFullscreenEnabled.getAsBoolean() && isIgnoreOrientationRequestEnabled
+ final boolean isSystemOverrideToFullscreenEnabled = mAppCompatOverrides
+ .getAppCompatAspectRatioOverrides().isSystemOverrideToFullscreenEnabled();
+ if (isSystemOverrideToFullscreenEnabled && isIgnoreOrientationRequestEnabled
// Do not override orientation to fullscreen for camera activities.
// Fixed-orientation activities are rarely tested in other orientations, and it
// often results in sideways or stretched previews. As the camera compat treatment
// targets fixed-orientation activities, overriding the orientation disables the
// treatment.
- && !mActivityRecord.isCameraActive()) {
+ && !mAppCompatOverrides.getAppCompatCameraOverrides().isCameraActive()) {
Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate)
+ " for " + mActivityRecord + " is overridden to "
+ screenOrientationToString(SCREEN_ORIENTATION_USER));
@@ -161,4 +150,62 @@ class AppCompatOrientationPolicy {
return candidate;
}
+ /**
+ * Whether should ignore app requested orientation in response to an app
+ * calling {@link android.app.Activity#setRequestedOrientation}.
+ *
+ * <p>This is needed to avoid getting into {@link android.app.Activity#setRequestedOrientation}
+ * loop when {@link DisplayContent#getIgnoreOrientationRequest} is enabled or device has
+ * landscape natural orientation which app developers don't expect. For example, the loop can
+ * look like this:
+ * <ol>
+ * <li>App sets default orientation to "unspecified" at runtime
+ * <li>App requests to "portrait" after checking some condition (e.g. display rotation).
+ * <li>(2) leads to fullscreen -> letterboxed bounds change and activity relaunch because
+ * app can't handle the corresponding config changes.
+ * <li>Loop goes back to (1)
+ * </ol>
+ *
+ * <p>This treatment is enabled when the following conditions are met:
+ * <ul>
+ * <li>Flag gating the treatment is enabled
+ * <li>Opt-out component property isn't enabled
+ * <li>Opt-in component property or per-app override are enabled
+ * <li>Activity is relaunched after {@link android.app.Activity#setRequestedOrientation}
+ * call from an app or camera compat force rotation treatment is active for the activity.
+ * <li>Orientation request loop detected and is not letterboxed for fixed orientation
+ * </ul>
+ */
+ boolean shouldIgnoreRequestedOrientation(
+ @ActivityInfo.ScreenOrientation int requestedOrientation) {
+ final AppCompatOrientationOverrides orientationOverrides =
+ mAppCompatOverrides.getAppCompatOrientationOverrides();
+ if (orientationOverrides.shouldEnableIgnoreOrientationRequest()) {
+ if (orientationOverrides.getIsRelaunchingAfterRequestedOrientationChanged()) {
+ Slog.w(TAG, "Ignoring orientation update to "
+ + screenOrientationToString(requestedOrientation)
+ + " due to relaunching after setRequestedOrientation for "
+ + mActivityRecord);
+ return true;
+ }
+ final AppCompatCameraPolicy cameraPolicy = mActivityRecord.mAppCompatController
+ .getAppCompatCameraPolicy();
+ if (cameraPolicy != null
+ && cameraPolicy.isTreatmentEnabledForActivity(mActivityRecord)) {
+ Slog.w(TAG, "Ignoring orientation update to "
+ + screenOrientationToString(requestedOrientation)
+ + " due to camera compat treatment for " + mActivityRecord);
+ return true;
+ }
+ }
+ if (orientationOverrides.shouldIgnoreOrientationRequestLoop()) {
+ Slog.w(TAG, "Ignoring orientation update to "
+ + screenOrientationToString(requestedOrientation)
+ + " as orientation request loop was detected for "
+ + mActivityRecord);
+ return true;
+ }
+ return false;
+ }
+
}
diff --git a/services/core/java/com/android/server/wm/AppCompatOverrides.java b/services/core/java/com/android/server/wm/AppCompatOverrides.java
index c20da7c3df2d..f6f93f9eda7c 100644
--- a/services/core/java/com/android/server/wm/AppCompatOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatOverrides.java
@@ -18,20 +18,13 @@ package com.android.server.wm;
import static android.content.pm.ActivityInfo.FORCE_NON_RESIZE_APP;
import static android.content.pm.ActivityInfo.FORCE_RESIZE_APP;
-import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION_TO_USER;
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
import static android.content.pm.ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTATION;
import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
@@ -61,17 +54,13 @@ public class AppCompatOverrides {
@NonNull
private final OptPropFactory.OptProp mAllowDisplayOrientationOverrideOptProp;
@NonNull
- private final OptPropFactory.OptProp mAllowMinAspectRatioOverrideOptProp;
- @NonNull
private final OptPropFactory.OptProp mAllowForceResizeOverrideOptProp;
@NonNull
- private final OptPropFactory.OptProp mAllowUserAspectRatioOverrideOptProp;
- @NonNull
- private final OptPropFactory.OptProp mAllowUserAspectRatioFullscreenOverrideOptProp;
- @NonNull
private final AppCompatOrientationOverrides mAppCompatOrientationOverrides;
@NonNull
private final AppCompatCameraOverrides mAppCompatCameraOverrides;
+ @NonNull
+ private final AppCompatAspectRatioOverrides mAppCompatAspectRatioOverrides;
AppCompatOverrides(@NonNull ActivityRecord activityRecord,
@NonNull LetterboxConfiguration letterboxConfiguration,
@@ -79,10 +68,15 @@ public class AppCompatOverrides {
mLetterboxConfiguration = letterboxConfiguration;
mActivityRecord = activityRecord;
- mAppCompatOrientationOverrides = new AppCompatOrientationOverrides(mActivityRecord,
- mLetterboxConfiguration, optPropBuilder);
mAppCompatCameraOverrides = new AppCompatCameraOverrides(mActivityRecord,
mLetterboxConfiguration, optPropBuilder);
+ mAppCompatOrientationOverrides = new AppCompatOrientationOverrides(mActivityRecord,
+ mLetterboxConfiguration, optPropBuilder, mAppCompatCameraOverrides);
+ // TODO(b/341903757) Remove BooleanSuppliers after fixing dependency with reachability.
+ mAppCompatAspectRatioOverrides = new AppCompatAspectRatioOverrides(activityRecord,
+ mLetterboxConfiguration, optPropBuilder,
+ activityRecord.mLetterboxUiController::isDisplayFullScreenAndInPosture,
+ activityRecord.mLetterboxUiController::getHorizontalPositionMultiplier);
mFakeFocusOptProp = optPropBuilder.create(PROPERTY_COMPAT_ENABLE_FAKE_FOCUS,
mLetterboxConfiguration::isCompatFakeFocusEnabled);
@@ -101,29 +95,8 @@ public class AppCompatOverrides {
== ORIENTATION_LANDSCAPE
);
- mAllowMinAspectRatioOverrideOptProp = optPropBuilder.create(
- PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE);
mAllowForceResizeOverrideOptProp = optPropBuilder.create(
PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES);
- mAllowUserAspectRatioOverrideOptProp = optPropBuilder.create(
- PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE,
- mLetterboxConfiguration::isUserAppAspectRatioSettingsEnabled);
- mAllowUserAspectRatioFullscreenOverrideOptProp = optPropBuilder.create(
- PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
- mLetterboxConfiguration::isUserAppAspectRatioFullscreenEnabled);
- }
-
- /**
- * @return {@code true} if the App Compat Camera Policy is active for the current activity.
- */
- boolean isCameraCompatTreatmentActive() {
- final DisplayContent displayContent = mActivityRecord.mDisplayContent;
- if (displayContent == null) {
- return false;
- }
- return displayContent.mDisplayRotationCompatPolicy != null
- && displayContent.mDisplayRotationCompatPolicy
- .isTreatmentEnabledForActivity(mActivityRecord);
}
@NonNull
@@ -136,6 +109,11 @@ public class AppCompatOverrides {
return mAppCompatCameraOverrides;
}
+ @NonNull
+ AppCompatAspectRatioOverrides getAppCompatAspectRatioOverrides() {
+ return mAppCompatAspectRatioOverrides;
+ }
+
/**
* Whether sending compat fake focus for split screen resumed activities is enabled. Needed
* because some game engines wait to get focus before drawing the content of the app which isn't
@@ -153,34 +131,10 @@ public class AppCompatOverrides {
isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS));
}
- boolean isSystemOverrideToFullscreenEnabled(int userAspectRatio) {
- return isCompatChangeEnabled(OVERRIDE_ANY_ORIENTATION_TO_USER)
- && !mAllowOrientationOverrideOptProp.isFalse()
- && (userAspectRatio == USER_MIN_ASPECT_RATIO_UNSET
- || userAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN);
- }
-
boolean isAllowOrientationOverrideOptOut() {
return mAllowOrientationOverrideOptProp.isFalse();
}
- /**
- * Whether we should apply the min aspect ratio per-app override. When this override is applied
- * the min aspect ratio given in the app's manifest will be overridden to the largest enabled
- * aspect ratio treatment unless the app's manifest value is higher. The treatment will also
- * apply if no value is provided in the manifest.
- *
- * <p>This method returns {@code true} when the following conditions are met:
- * <ul>
- * <li>Opt-out component property isn't enabled
- * <li>Per-app override is enabled
- * </ul>
- */
- boolean shouldOverrideMinAspectRatio() {
- return mAllowMinAspectRatioOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
- isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO));
- }
-
boolean isOverrideRespectRequestedOrientationEnabled() {
return isCompatChangeEnabled(OVERRIDE_RESPECT_REQUESTED_ORIENTATION);
}
@@ -222,28 +176,6 @@ public class AppCompatOverrides {
}
/**
- * Whether we should enable users to resize the current app.
- */
- boolean shouldEnableUserAspectRatioSettings() {
- // We use mBooleanPropertyAllowUserAspectRatioOverride to allow apps to opt-out which has
- // effect only if explicitly false. If mBooleanPropertyAllowUserAspectRatioOverride is null,
- // the current app doesn't opt-out so the first part of the predicate is true.
- return !mAllowUserAspectRatioOverrideOptProp.isFalse()
- && mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled()
- && mActivityRecord.mDisplayContent != null
- && mActivityRecord.mDisplayContent.getIgnoreOrientationRequest();
- }
-
- boolean isUserFullscreenOverrideEnabled() {
- if (mAllowUserAspectRatioOverrideOptProp.isFalse()
- || mAllowUserAspectRatioFullscreenOverrideOptProp.isFalse()
- || !mLetterboxConfiguration.isUserAppAspectRatioFullscreenEnabled()) {
- return false;
- }
- return true;
- }
-
- /**
* Whether we should apply the force non resize per-app override. When this override is applied
* it forces the packages it is applied to to be non-resizable.
*
diff --git a/services/core/java/com/android/server/wm/AppCompatUtils.java b/services/core/java/com/android/server/wm/AppCompatUtils.java
index be51dd3bcf1c..1b30a20d3e9a 100644
--- a/services/core/java/com/android/server/wm/AppCompatUtils.java
+++ b/services/core/java/com/android/server/wm/AppCompatUtils.java
@@ -16,7 +16,12 @@
package com.android.server.wm;
+import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
+import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
+
import android.annotation.NonNull;
+import android.content.res.Configuration;
+import android.graphics.Rect;
import java.util.function.BooleanSupplier;
@@ -48,4 +53,24 @@ class AppCompatUtils {
}
};
}
+
+ /**
+ * Returns the aspect ratio of the given {@code rect}.
+ */
+ static float computeAspectRatio(Rect rect) {
+ final int width = rect.width();
+ final int height = rect.height();
+ if (width == 0 || height == 0) {
+ return 0;
+ }
+ return Math.max(width, height) / (float) Math.min(width, height);
+ }
+
+ /**
+ * @param config The current {@link Configuration}
+ * @return {@code true} if using a VR headset.
+ */
+ static boolean isInVrUiMode(Configuration config) {
+ return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
+ }
}
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 44b414f1ea7e..78636a7870cf 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -98,7 +98,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.function.Consumer;
import java.util.function.Predicate;
/**
@@ -290,12 +289,10 @@ public class AppTransitionController {
getTopApp(mDisplayContent.mChangingContainers, false /* ignoreHidden */);
final WindowManager.LayoutParams animLp = getAnimLp(animLpActivity);
- // Check if there is any override
- if (!overrideWithTaskFragmentRemoteAnimation(transit, activityTypes)) {
- // Unfreeze the windows that were previously frozen for TaskFragment animation.
- unfreezeEmbeddedChangingWindows();
- overrideWithRemoteAnimationIfSet(animLpActivity, transit, activityTypes);
- }
+ // No AE remote animation with Shell transition.
+ // Unfreeze the windows that were previously frozen for TaskFragment animation.
+ unfreezeEmbeddedChangingWindows();
+ overrideWithRemoteAnimationIfSet(animLpActivity, transit, activityTypes);
final boolean voiceInteraction = containsVoiceInteraction(mDisplayContent.mClosingApps)
|| containsVoiceInteraction(mDisplayContent.mOpeningApps);
@@ -726,64 +723,6 @@ public class AppTransitionController {
}
/**
- * Overrides the pending transition with the remote animation defined by the
- * {@link ITaskFragmentOrganizer} if all windows in the transition are children of
- * {@link TaskFragment} that are organized by the same organizer.
- *
- * @return {@code true} if the transition is overridden.
- */
- private boolean overrideWithTaskFragmentRemoteAnimation(@TransitionOldType int transit,
- ArraySet<Integer> activityTypes) {
- if (transitionMayContainNonAppWindows(transit)) {
- return false;
- }
- if (!transitionContainsTaskFragmentWithBoundsOverride()) {
- // No need to play TaskFragment remote animation if all embedded TaskFragment in the
- // transition fill the Task.
- return false;
- }
-
- final Task task = findParentTaskForAllEmbeddedWindows();
- final ITaskFragmentOrganizer organizer = findTaskFragmentOrganizer(task);
- final RemoteAnimationDefinition definition = organizer != null
- ? mDisplayContent.mAtmService.mTaskFragmentOrganizerController
- .getRemoteAnimationDefinition(organizer)
- : null;
- final RemoteAnimationAdapter adapter = definition != null
- ? definition.getAdapter(transit, activityTypes)
- : null;
- if (adapter == null) {
- return false;
- }
- mDisplayContent.mAppTransition.overridePendingAppTransitionRemote(
- adapter, false /* sync */, true /*isActivityEmbedding*/);
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
- "Override with TaskFragment remote animation for transit=%s",
- AppTransition.appTransitionOldToString(transit));
-
- final int organizerUid = mDisplayContent.mAtmService.mTaskFragmentOrganizerController
- .getTaskFragmentOrganizerUid(organizer);
- final boolean shouldDisableInputForRemoteAnimation = !task.isFullyTrustedEmbedding(
- organizerUid);
- final RemoteAnimationController remoteAnimationController =
- mDisplayContent.mAppTransition.getRemoteAnimationController();
- if (shouldDisableInputForRemoteAnimation && remoteAnimationController != null) {
- // We are going to use client-driven animation, Disable all input on activity windows
- // during the animation (unless it is fully trusted) to ensure it is safe to allow
- // client to animate the surfaces.
- // This is needed for all activity windows in the animation Task.
- remoteAnimationController.setOnRemoteAnimationReady(() -> {
- final Consumer<ActivityRecord> updateActivities =
- activity -> activity.setDropInputForAnimation(true);
- task.forAllActivities(updateActivities);
- });
- ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "Task=%d contains embedded TaskFragment."
- + " Disabled all input during TaskFragment remote animation.", task.mTaskId);
- }
- return true;
- }
-
- /**
* Overrides the pending transition with the remote animation defined for the transition in the
* set of defined remote animations in the app window token.
*/
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index cb690394480e..8421765060ce 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -210,6 +210,9 @@ class BackNavigationController {
+ "topRunningActivity=%s, callbackInfo=%s, currentFocus=%s",
currentTask, currentActivity, callbackInfo, window);
+ // Clear the pointer down outside focus if any.
+ mWindowManagerService.clearPointerDownOutsideFocusRunnable();
+
// If we don't need to set up the animation, we return early. This is the case when
// - We have an application callback.
// - We don't have any ActivityRecord or Task to animate.
@@ -357,8 +360,7 @@ class BackNavigationController {
removedWindowContainer);
mBackAnimationInProgress = builder != null;
if (mBackAnimationInProgress) {
- if (removedWindowContainer.hasCommittedReparentToAnimationLeash()
- || removedWindowContainer.mTransitionController.inTransition()
+ if (removedWindowContainer.mTransitionController.inTransition()
|| mWindowManagerService.mSyncEngine.hasPendingSyncSets()) {
ProtoLog.w(WM_DEBUG_BACK_PREVIEW,
"Pending back animation due to another animation is running");
@@ -1336,12 +1338,16 @@ class BackNavigationController {
}
// If there is only one adaptor, attach the windowless window to top activity,
// because fixed rotation only applies on activity.
- // Note that embedded activity won't use fixed rotation.
- final Configuration openConfig = mAdaptors.length == 1
+ // Note that embedded activity won't use fixed rotation. Also, there is only one
+ // animation target for closing task.
+ final boolean chooseActivity = mAdaptors.length == 1
+ && (switchType == ACTIVITY_SWITCH || mainActivity.mDisplayContent
+ .isFixedRotationLaunchingApp(mainActivity));
+ final Configuration openConfig = chooseActivity
? mainActivity.getConfiguration() : openTask.getConfiguration();
mRequestedStartingSurfaceId = openTask.mAtmService.mTaskOrganizerController
.addWindowlessStartingSurface(openTask, mainActivity,
- mAdaptors.length == 1 ? mainActivity.getSurfaceControl()
+ chooseActivity ? mainActivity.getSurfaceControl()
: mRemoteAnimationTarget.leash, snapshot, openConfig,
new IWindowlessStartingSurfaceCallback.Stub() {
// Once the starting surface has been created in shell, it will call
@@ -1358,6 +1364,8 @@ class BackNavigationController {
synchronized (openTask.mWmService.mGlobalLock) {
if (mRequestedStartingSurfaceId != INVALID_TASK_ID) {
mStartingSurface = sc;
+ } else {
+ sc.release();
}
}
}
@@ -1596,12 +1604,20 @@ class BackNavigationController {
@NonNull ActivityRecord[] visibleOpenActivities) {
boolean needsLaunchBehind = true;
if (isSupportWindowlessSurface() && mShowWindowlessSurface && !mIsLaunchBehind) {
+ boolean activitiesAreDrawn = false;
+ for (int i = visibleOpenActivities.length - 1; i >= 0; --i) {
+ // If the activity hasn't stopped, it's window should remain drawn.
+ activitiesAreDrawn |= visibleOpenActivities[i].firstWindowDrawn;
+ }
final WindowContainer mainOpen = openAnimationAdaptor.mAdaptors[0].mTarget;
final TaskSnapshot snapshot = getSnapshot(mainOpen, visibleOpenActivities);
- openAnimationAdaptor.createStartingSurface(snapshot);
- // set LaunchBehind if we are creating splash screen surface.
- needsLaunchBehind = snapshot == null
- && openAnimationAdaptor.mRequestedStartingSurfaceId != INVALID_TASK_ID;
+ // Don't create starting surface if previous activities haven't stopped or
+ // the snapshot does not exist.
+ if (snapshot != null || !activitiesAreDrawn) {
+ openAnimationAdaptor.createStartingSurface(snapshot);
+ }
+ // Only use LaunchBehind if snapshot does not exist.
+ needsLaunchBehind = snapshot == null;
}
if (needsLaunchBehind) {
for (int i = visibleOpenActivities.length - 1; i >= 0; --i) {
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index a4fb95964a5c..54024e92f95f 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -128,21 +128,24 @@ public class BackgroundActivityStartController {
// TODO(b/263368846) Rename when ASM logic is moved in
@Retention(SOURCE)
- @IntDef({BAL_BLOCK,
- BAL_ALLOW_DEFAULT,
- BAL_ALLOW_ALLOWLISTED_UID,
+ @IntDef({
BAL_ALLOW_ALLOWLISTED_COMPONENT,
- BAL_ALLOW_VISIBLE_WINDOW,
+ BAL_ALLOW_ALLOWLISTED_UID,
+ BAL_ALLOW_BOUND_BY_FOREGROUND,
+ BAL_ALLOW_DEFAULT,
+ BAL_ALLOW_FOREGROUND,
+ BAL_ALLOW_GRACE_PERIOD,
BAL_ALLOW_PENDING_INTENT,
BAL_ALLOW_PERMISSION,
BAL_ALLOW_SAW_PERMISSION,
- BAL_ALLOW_GRACE_PERIOD,
- BAL_ALLOW_FOREGROUND,
- BAL_ALLOW_SDK_SANDBOX
+ BAL_ALLOW_SDK_SANDBOX,
+ BAL_ALLOW_TOKEN,
+ BAL_ALLOW_VISIBLE_WINDOW,
+ BAL_BLOCK
})
public @interface BalCode {}
- static final int BAL_BLOCK = 0;
+ static final int BAL_BLOCK = FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_BLOCKED;
static final int BAL_ALLOW_DEFAULT =
FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_DEFAULT;
@@ -195,10 +198,19 @@ public class BackgroundActivityStartController {
static final int BAL_ALLOW_NON_APP_VISIBLE_WINDOW =
FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_NON_APP_VISIBLE_WINDOW;
+ /** Process belongs to a SDK sandbox */
+ static final int BAL_ALLOW_TOKEN =
+ FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_TOKEN;
+
+ /** Process belongs to a SDK sandbox */
+ static final int BAL_ALLOW_BOUND_BY_FOREGROUND =
+ FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_BOUND_BY_FOREGROUND;
+
static String balCodeToString(@BalCode int balCode) {
return switch (balCode) {
case BAL_ALLOW_ALLOWLISTED_COMPONENT -> "BAL_ALLOW_ALLOWLISTED_COMPONENT";
case BAL_ALLOW_ALLOWLISTED_UID -> "BAL_ALLOW_ALLOWLISTED_UID";
+ case BAL_ALLOW_BOUND_BY_FOREGROUND -> "BAL_ALLOW_BOUND_BY_FOREGROUND";
case BAL_ALLOW_DEFAULT -> "BAL_ALLOW_DEFAULT";
case BAL_ALLOW_FOREGROUND -> "BAL_ALLOW_FOREGROUND";
case BAL_ALLOW_GRACE_PERIOD -> "BAL_ALLOW_GRACE_PERIOD";
@@ -207,6 +219,7 @@ public class BackgroundActivityStartController {
case BAL_ALLOW_PERMISSION -> "BAL_ALLOW_PERMISSION";
case BAL_ALLOW_SAW_PERMISSION -> "BAL_ALLOW_SAW_PERMISSION";
case BAL_ALLOW_SDK_SANDBOX -> "BAL_ALLOW_SDK_SANDBOX";
+ case BAL_ALLOW_TOKEN -> "BAL_ALLOW_TOKEN";
case BAL_ALLOW_VISIBLE_WINDOW -> "BAL_ALLOW_VISIBLE_WINDOW";
case BAL_BLOCK -> "BAL_BLOCK";
default -> throw new IllegalArgumentException("Unexpected value: " + balCode);
@@ -1042,7 +1055,9 @@ public class BackgroundActivityStartController {
|| balCode == BAL_ALLOW_PENDING_INTENT
|| balCode == BAL_ALLOW_SAW_PERMISSION
|| balCode == BAL_ALLOW_VISIBLE_WINDOW
- || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW) {
+ || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW
+ || balCode == BAL_ALLOW_TOKEN
+ || balCode == BAL_ALLOW_BOUND_BY_FOREGROUND) {
return true;
}
}
@@ -1266,7 +1281,8 @@ public class BackgroundActivityStartController {
|| balCode == BAL_ALLOW_PERMISSION
|| balCode == BAL_ALLOW_SAW_PERMISSION
|| balCode == BAL_ALLOW_VISIBLE_WINDOW
- || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW) {
+ || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW
+ || balCode == BAL_ALLOW_BOUND_BY_FOREGROUND) {
return;
}
@@ -1572,7 +1588,7 @@ public class BackgroundActivityStartController {
}
if (balCode == BAL_ALLOW_VISIBLE_WINDOW || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW
- || balCode == BAL_ALLOW_FOREGROUND) {
+ || balCode == BAL_ALLOW_FOREGROUND || balCode == BAL_ALLOW_BOUND_BY_FOREGROUND) {
Task task = sourceRecord != null ? sourceRecord.getTask() : targetTask;
if (task != null && task.getDisplayArea() != null) {
joiner.add(prefix + "Tasks: ");
@@ -1659,6 +1675,8 @@ public class BackgroundActivityStartController {
activityName = "";
}
writeBalAllowedLog(activityName, finalVerdict.getCode(), state);
+ } else {
+ writeBalAllowedLogMinimal(state);
}
} else {
@BalCode int code = finalVerdict.getCode();
@@ -1723,6 +1741,24 @@ public class BackgroundActivityStartController {
);
}
+ @VisibleForTesting void writeBalAllowedLogMinimal(BalState state) {
+ FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
+ "",
+ BAL_ALLOW_DEFAULT,
+ NO_PROCESS_UID,
+ NO_PROCESS_UID,
+ state.mResultForCaller == null ? BAL_BLOCK : state.mResultForCaller.getRawCode(),
+ state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts(),
+ state.callerExplicitOptInOrOut(),
+ state.mResultForRealCaller == null ? BAL_BLOCK
+ : state.mResultForRealCaller.getRawCode(),
+ state.mBalAllowedByPiSender.allowsBackgroundActivityStarts(),
+ state.realCallerExplicitOptInOrOut(),
+ getTargetSdk(state.mCallingPackage),
+ getTargetSdk(state.mRealCallingPackage)
+ );
+ }
+
/**
* Called whenever an activity finishes. Stores the record, so it can be used by ASM grace
* period checks.
diff --git a/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
index 478524b7bd1c..4a870a3a5b6e 100644
--- a/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
+++ b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
@@ -23,10 +23,13 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START_GRACE_PERIOD_MS;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_DISALLOW;
+import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_BOUND_BY_FOREGROUND;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_FOREGROUND;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_GRACE_PERIOD;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION;
+import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_TOKEN;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW;
+import static com.android.window.flags.Flags.balImprovedMetrics;
import static java.util.Objects.requireNonNull;
@@ -110,8 +113,8 @@ class BackgroundLaunchProcessController {
}
// Allow if the flag was explicitly set.
if (isBackgroundStartAllowedByToken(uid, packageName, isCheckingForFgsStart)) {
- return new BalVerdict(BAL_ALLOW_PERMISSION, /*background*/ true,
- "process allowed by token");
+ return new BalVerdict(balImprovedMetrics() ? BAL_ALLOW_TOKEN : BAL_ALLOW_PERMISSION,
+ /*background*/ true, "process allowed by token");
}
// Allow if the caller is bound by a UID that's currently foreground.
// But still respect the appSwitchState.
@@ -120,7 +123,8 @@ class BackgroundLaunchProcessController {
? appSwitchState != APP_SWITCH_DISALLOW && isBoundByForegroundUid()
: isBoundByForegroundUid();
if (allowBoundByForegroundUid) {
- return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false,
+ return new BalVerdict(balImprovedMetrics() ? BAL_ALLOW_BOUND_BY_FOREGROUND
+ : BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false,
"process bound by foreground uid");
}
// Allow if the caller has an activity in any foreground task.
diff --git a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
index 68a417289c55..2755a80ea705 100644
--- a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
+++ b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
@@ -26,13 +26,14 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.CameraCompatTaskInfo;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.ProtoLogGroup;
import com.android.internal.protolog.ProtoLog;
+import com.android.internal.protolog.ProtoLogGroup;
import com.android.window.flags.Flags;
/**
@@ -56,6 +57,9 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
private boolean mIsCameraCompatTreatmentPending = false;
+ @Nullable
+ private Task mCameraTask;
+
CameraCompatFreeformPolicy(@NonNull DisplayContent displayContent,
@NonNull CameraStateMonitor cameraStateMonitor,
@NonNull ActivityRefresher activityRefresher) {
@@ -116,6 +120,7 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
final int newCameraCompatMode = getCameraCompatMode(cameraActivity);
if (newCameraCompatMode != existingCameraCompatMode) {
mIsCameraCompatTreatmentPending = true;
+ mCameraTask = cameraActivity.getTask();
cameraActivity.mAppCompatController.getAppCompatCameraOverrides()
.setFreeformCameraCompatMode(newCameraCompatMode);
forceUpdateActivityAndTask(cameraActivity);
@@ -127,18 +132,22 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
}
@Override
- public boolean onCameraClosed(@NonNull ActivityRecord cameraActivity,
- @NonNull String cameraId) {
- if (isActivityForCameraIdRefreshing(cameraId)) {
- ProtoLog.v(ProtoLogGroup.WM_DEBUG_STATES,
- "Display id=%d is notified that Camera %s is closed but activity is"
- + " still refreshing. Rescheduling an update.",
- mDisplayContent.mDisplayId, cameraId);
- return false;
+ public boolean onCameraClosed(@NonNull String cameraId) {
+ // Top activity in the same task as the camera activity, or `null` if the task is
+ // closed.
+ final ActivityRecord topActivity = mCameraTask != null
+ ? mCameraTask.getTopActivity(/* isFinishing */ false, /* includeOverlays */ false)
+ : null;
+ if (topActivity != null) {
+ if (isActivityForCameraIdRefreshing(topActivity, cameraId)) {
+ ProtoLog.v(ProtoLogGroup.WM_DEBUG_STATES,
+ "Display id=%d is notified that Camera %s is closed but activity is"
+ + " still refreshing. Rescheduling an update.",
+ mDisplayContent.mDisplayId, cameraId);
+ return false;
+ }
}
- cameraActivity.mAppCompatController.getAppCompatCameraOverrides()
- .setFreeformCameraCompatMode(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE);
- forceUpdateActivityAndTask(cameraActivity);
+ mCameraTask = null;
mIsCameraCompatTreatmentPending = false;
return true;
}
@@ -186,10 +195,9 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
&& !activity.isEmbedded();
}
- private boolean isActivityForCameraIdRefreshing(@NonNull String cameraId) {
- final ActivityRecord topActivity = mDisplayContent.topRunningActivity(
- /* considerKeyguardState= */ true);
- if (topActivity == null || !isTreatmentEnabledForActivity(topActivity)
+ private boolean isActivityForCameraIdRefreshing(@NonNull ActivityRecord topActivity,
+ @NonNull String cameraId) {
+ if (!isTreatmentEnabledForActivity(topActivity)
|| mCameraStateMonitor.isCameraWithIdRunningForActivity(topActivity, cameraId)) {
return false;
}
diff --git a/services/core/java/com/android/server/wm/CameraStateMonitor.java b/services/core/java/com/android/server/wm/CameraStateMonitor.java
index a54141ce5230..068fc001ae2c 100644
--- a/services/core/java/com/android/server/wm/CameraStateMonitor.java
+++ b/services/core/java/com/android/server/wm/CameraStateMonitor.java
@@ -61,9 +61,6 @@ class CameraStateMonitor {
@NonNull
private final Handler mHandler;
- @Nullable
- private ActivityRecord mCameraActivity;
-
// Bi-directional map between package names and active camera IDs since we need to 1) get a
// camera id by a package name when resizing the window; 2) get a package name by a camera id
// when camera connection is closed and we need to clean up our records.
@@ -91,13 +88,13 @@ class CameraStateMonitor {
@Override
public void onCameraOpened(@NonNull String cameraId, @NonNull String packageId) {
synchronized (mWmService.mGlobalLock) {
- notifyCameraOpened(cameraId, packageId);
+ notifyCameraOpenedWithDelay(cameraId, packageId);
}
}
@Override
public void onCameraClosed(@NonNull String cameraId) {
synchronized (mWmService.mGlobalLock) {
- notifyCameraClosed(cameraId);
+ notifyCameraClosedWithDelay(cameraId);
}
}
};
@@ -131,8 +128,8 @@ class CameraStateMonitor {
mCameraStateListeners.remove(listener);
}
- private void notifyCameraOpened(
- @NonNull String cameraId, @NonNull String packageName) {
+ private void notifyCameraOpenedWithDelay(@NonNull String cameraId,
+ @NonNull String packageName) {
// If an activity is restarting or camera is flipping, the camera connection can be
// quickly closed and reopened.
mScheduledToBeRemovedCameraIdSet.remove(cameraId);
@@ -142,25 +139,30 @@ class CameraStateMonitor {
// Some apps can’t handle configuration changes coming at the same time with Camera setup so
// delaying orientation update to accommodate for that.
mScheduledCompatModeUpdateCameraIdSet.add(cameraId);
- mHandler.postDelayed(
- () -> {
- synchronized (mWmService.mGlobalLock) {
- if (!mScheduledCompatModeUpdateCameraIdSet.remove(cameraId)) {
- // Camera compat mode update has happened already or was cancelled
- // because camera was closed.
- return;
- }
- mCameraIdPackageBiMapping.put(packageName, cameraId);
- mCameraActivity = findCameraActivity(packageName);
- if (mCameraActivity == null || mCameraActivity.getTask() == null) {
- return;
- }
- notifyListenersCameraOpened(mCameraActivity, cameraId);
- }
- },
+ mHandler.postDelayed(() -> notifyCameraOpenedInternal(cameraId, packageName),
CAMERA_OPENED_LETTERBOX_UPDATE_DELAY_MS);
}
+ private void notifyCameraOpenedInternal(@NonNull String cameraId, @NonNull String packageName) {
+ synchronized (mWmService.mGlobalLock) {
+ if (!mScheduledCompatModeUpdateCameraIdSet.remove(cameraId)) {
+ // Camera compat mode update has happened already or was cancelled
+ // because camera was closed.
+ return;
+ }
+ mCameraIdPackageBiMapping.put(packageName, cameraId);
+ // If there are multiple activities of the same package name and none of
+ // them are the top running activity, we do not apply treatment (rather than
+ // guessing and applying it to the wrong activity).
+ final ActivityRecord cameraActivity =
+ findUniqueActivityWithPackageName(packageName);
+ if (cameraActivity == null || cameraActivity.getTask() == null) {
+ return;
+ }
+ notifyListenersCameraOpened(cameraActivity, cameraId);
+ }
+ }
+
private void notifyListenersCameraOpened(@NonNull ActivityRecord cameraActivity,
@NonNull String cameraId) {
for (int i = 0; i < mCameraStateListeners.size(); i++) {
@@ -174,7 +176,13 @@ class CameraStateMonitor {
}
}
- private void notifyCameraClosed(@NonNull String cameraId) {
+ /**
+ * Processes camera closed, and schedules notifying listeners.
+ *
+ * <p>The delay is introduced to avoid flickering when switching between front and back camera,
+ * and when an activity is refreshed due to camera compat treatment.
+ */
+ private void notifyCameraClosedWithDelay(@NonNull String cameraId) {
ProtoLog.v(WM_DEBUG_STATES,
"Display id=%d is notified that Camera %s is closed.",
mDisplayContent.mDisplayId, cameraId);
@@ -217,9 +225,10 @@ class CameraStateMonitor {
// Already reconnected to this camera, no need to clean up.
return;
}
- if (mCameraActivity != null && mCurrentListenerForCameraActivity != null) {
+
+ if (mCurrentListenerForCameraActivity != null) {
boolean closeSuccessful =
- mCurrentListenerForCameraActivity.onCameraClosed(mCameraActivity, cameraId);
+ mCurrentListenerForCameraActivity.onCameraClosed(cameraId);
if (closeSuccessful) {
mCameraIdPackageBiMapping.removeCameraId(cameraId);
mCurrentListenerForCameraActivity = null;
@@ -231,8 +240,14 @@ class CameraStateMonitor {
}
// TODO(b/335165310): verify that this works in multi instance and permission dialogs.
+ /**
+ * Finds a visible activity with the given package name.
+ *
+ * <p>If there are multiple visible activities with a given package name, and none of them are
+ * the `topRunningActivity`, returns null.
+ */
@Nullable
- private ActivityRecord findCameraActivity(@NonNull String packageName) {
+ private ActivityRecord findUniqueActivityWithPackageName(@NonNull String packageName) {
final ActivityRecord topActivity = mDisplayContent.topRunningActivity(
/* considerKeyguardState= */ true);
if (topActivity != null && topActivity.packageName.equals(packageName)) {
@@ -277,11 +292,11 @@ class CameraStateMonitor {
// TODO(b/336474959): try to decouple `cameraId` from the listeners.
boolean onCameraOpened(@NonNull ActivityRecord cameraActivity, @NonNull String cameraId);
/**
- * Notifies the compat listener that an activity has closed the camera.
+ * Notifies the compat listener that camera is closed.
*
* @return true if cleanup has been successful - the notifier might try again if false.
*/
// TODO(b/336474959): try to decouple `cameraId` from the listeners.
- boolean onCameraClosed(@NonNull ActivityRecord cameraActivity, @NonNull String cameraId);
+ boolean onCameraClosed(@NonNull String cameraId);
}
}
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index efd52026cfec..a38ac9ba4b75 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -22,14 +22,23 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.activityTypeToString;
+import static android.app.WindowConfiguration.isFloating;
import static android.app.WindowConfiguration.windowingModeToString;
import static android.app.WindowConfigurationProto.WINDOWING_MODE;
import static android.content.ConfigurationProto.WINDOW_CONFIGURATION;
+import static android.content.pm.ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_INSETS_DECOUPLED_CONFIGURATION;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
import static com.android.server.wm.ConfigurationContainerProto.FULL_CONFIGURATION;
import static com.android.server.wm.ConfigurationContainerProto.MERGED_OVERRIDE_CONFIGURATION;
@@ -38,11 +47,14 @@ import static com.android.server.wm.ConfigurationContainerProto.OVERRIDE_CONFIGU
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.app.WindowConfiguration;
+import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.LocaleList;
+import android.util.DisplayMetrics;
import android.util.proto.ProtoOutputStream;
+import android.view.DisplayInfo;
import com.android.internal.annotations.VisibleForTesting;
@@ -173,6 +185,111 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
mResolvedOverrideConfiguration.setTo(mRequestedOverrideConfiguration);
}
+ /**
+ * If necessary, override configuration fields related to app bounds.
+ * This will happen when the app is targeting SDK earlier than 35.
+ * The insets and configuration has decoupled since SDK level 35, to make the system
+ * compatible to existing apps, override the configuration with legacy metrics. In legacy
+ * metrics, fields such as appBounds will exclude some of the system bar areas.
+ * The override contains all potentially affected fields in Configuration, including
+ * screenWidthDp, screenHeightDp, smallestScreenWidthDp, and orientation.
+ * All overrides to those fields should be in this method.
+ *
+ * TODO: Consider integrate this with computeConfigByResolveHint()
+ */
+ static void applySizeOverrideIfNeeded(DisplayContent displayContent, ApplicationInfo appInfo,
+ Configuration newParentConfiguration, Configuration inOutConfig,
+ boolean optOutEdgeToEdge, boolean hasFixedRotationTransform,
+ boolean hasCompatDisplayInsets) {
+ if (displayContent == null) {
+ return;
+ }
+ final boolean useOverrideInsetsForConfig =
+ displayContent.mWmService.mFlags.mInsetsDecoupledConfiguration
+ ? !appInfo.isChangeEnabled(INSETS_DECOUPLED_CONFIGURATION_ENFORCED)
+ && !appInfo.isChangeEnabled(
+ OVERRIDE_ENABLE_INSETS_DECOUPLED_CONFIGURATION)
+ : appInfo.isChangeEnabled(OVERRIDE_ENABLE_INSETS_DECOUPLED_CONFIGURATION);
+ final int parentWindowingMode =
+ newParentConfiguration.windowConfiguration.getWindowingMode();
+ final boolean isFloating = isFloating(parentWindowingMode)
+ // Check the requested windowing mode of activity as well in case it is
+ // switching between PiP and fullscreen.
+ && (inOutConfig.windowConfiguration.getWindowingMode() == WINDOWING_MODE_UNDEFINED
+ || isFloating(inOutConfig.windowConfiguration.getWindowingMode()));
+ final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds();
+ int rotation = newParentConfiguration.windowConfiguration.getRotation();
+ if (rotation == ROTATION_UNDEFINED && !hasFixedRotationTransform) {
+ rotation = displayContent.getRotation();
+ }
+ if (!optOutEdgeToEdge && (!useOverrideInsetsForConfig
+ || hasCompatDisplayInsets
+ || isFloating
+ || rotation == ROTATION_UNDEFINED)) {
+ // If the insets configuration decoupled logic is not enabled for the app, or the app
+ // already has a compat override, or the context doesn't contain enough info to
+ // calculate the override, skip the override.
+ return;
+ }
+ // Make sure the orientation related fields will be updated by the override insets, because
+ // fixed rotation has assigned the fields from display's configuration.
+ if (hasFixedRotationTransform) {
+ inOutConfig.windowConfiguration.setAppBounds(null);
+ inOutConfig.screenWidthDp = Configuration.SCREEN_WIDTH_DP_UNDEFINED;
+ inOutConfig.screenHeightDp = Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
+ inOutConfig.smallestScreenWidthDp = Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
+ inOutConfig.orientation = ORIENTATION_UNDEFINED;
+ }
+
+ // Override starts here.
+ final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
+ final int dw = rotated
+ ? displayContent.mBaseDisplayHeight
+ : displayContent.mBaseDisplayWidth;
+ final int dh = rotated
+ ? displayContent.mBaseDisplayWidth
+ : displayContent.mBaseDisplayHeight;
+ final Rect nonDecorFrame = displayContent.getDisplayPolicy()
+ .getDecorInsetsInfo(rotation, dw, dh).mOverrideNonDecorFrame;
+ // This should be the only place override the configuration for ActivityRecord. Override
+ // the value if not calculated yet.
+ Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
+ if (outAppBounds == null || outAppBounds.isEmpty()) {
+ inOutConfig.windowConfiguration.setAppBounds(parentBounds);
+ outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
+ outAppBounds.intersect(nonDecorFrame);
+ }
+ float density = inOutConfig.densityDpi;
+ if (density == Configuration.DENSITY_DPI_UNDEFINED) {
+ density = newParentConfiguration.densityDpi;
+ }
+ density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;
+ if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
+ inOutConfig.screenWidthDp = (int) (outAppBounds.width() / density + 0.5f);
+ }
+ if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
+ inOutConfig.screenHeightDp = (int) (outAppBounds.height() / density + 0.5f);
+ }
+ if (inOutConfig.smallestScreenWidthDp == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
+ && parentWindowingMode == WINDOWING_MODE_FULLSCREEN) {
+ // For the case of PIP transition and multi-window environment, the
+ // smallestScreenWidthDp is handled already. Override only if the app is in
+ // fullscreen.
+ final DisplayInfo info = new DisplayInfo(displayContent.getDisplayInfo());
+ displayContent.computeSizeRanges(info, rotated, dw, dh,
+ displayContent.getDisplayMetrics().density,
+ inOutConfig, true /* overrideConfig */);
+ }
+
+ // It's possible that screen size will be considered in different orientation with or
+ // without considering the system bar insets. Override orientation as well.
+ if (inOutConfig.orientation == ORIENTATION_UNDEFINED) {
+ inOutConfig.orientation = (inOutConfig.screenWidthDp <= inOutConfig.screenHeightDp)
+ ? ORIENTATION_PORTRAIT
+ : ORIENTATION_LANDSCAPE;
+ }
+ }
+
/** Returns {@code true} if requested override override configuration is not empty. */
boolean hasRequestedOverrideConfiguration() {
return mHasOverrideConfiguration;
diff --git a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
index 50ac801a9d04..66653caaa73d 100644
--- a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
@@ -164,17 +164,16 @@ public class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
private void calculateAndCentreInitialBounds(Task task,
LaunchParamsController.LaunchParams outParams) {
// TODO(b/319819547): Account for app constraints so apps do not become letterboxed
- final Rect stableBounds = new Rect();
- task.getDisplayArea().getStableRect(stableBounds);
+ final Rect screenBounds = task.getDisplayArea().getBounds();
// The desired dimensions that a fully resizable window should take when initially entering
// desktop mode. Calculated as a percentage of the available display area as defined by the
// DESKTOP_MODE_INITIAL_BOUNDS_SCALE.
- final int desiredWidth = (int) (stableBounds.width() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
- final int desiredHeight = (int) (stableBounds.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
+ final int desiredWidth = (int) (screenBounds.width() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
+ final int desiredHeight = (int) (screenBounds.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
outParams.mBounds.right = desiredWidth;
outParams.mBounds.bottom = desiredHeight;
- outParams.mBounds.offset(stableBounds.centerX() - outParams.mBounds.centerX(),
- stableBounds.centerY() - outParams.mBounds.centerY());
+ outParams.mBounds.offset(screenBounds.centerX() - outParams.mBounds.centerX(),
+ screenBounds.centerY() - outParams.mBounds.centerY());
}
private void initLogBuilder(Task task, ActivityRecord activity) {
diff --git a/services/core/java/com/android/server/wm/DeviceStateController.java b/services/core/java/com/android/server/wm/DeviceStateController.java
index 857e03d71f3f..475a50473780 100644
--- a/services/core/java/com/android/server/wm/DeviceStateController.java
+++ b/services/core/java/com/android/server/wm/DeviceStateController.java
@@ -16,9 +16,19 @@
package com.android.server.wm;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN;
+
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
+import android.hardware.devicestate.DeviceStateManager;
+import android.hardware.devicestate.feature.flags.FeatureFlags;
+import android.hardware.devicestate.feature.flags.FeatureFlagsImpl;
import android.util.ArrayMap;
import android.util.Pair;
@@ -28,6 +38,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
@@ -43,16 +54,16 @@ final class DeviceStateController {
@NonNull
private final WindowManagerGlobalLock mWmLock;
@NonNull
- private final int[] mOpenDeviceStates;
+ private final List<Integer> mOpenDeviceStates;
@NonNull
- private final int[] mHalfFoldedDeviceStates;
+ private final List<Integer> mHalfFoldedDeviceStates;
@NonNull
- private final int[] mFoldedDeviceStates;
+ private final List<Integer> mFoldedDeviceStates;
@NonNull
- private final int[] mRearDisplayDeviceStates;
- private final int mConcurrentDisplayDeviceState;
+ private final List<Integer> mRearDisplayDeviceStates;
+ private final List<Integer> mConcurrentDisplayDeviceStates;
@NonNull
- private final int[] mReverseRotationAroundZAxisStates;
+ private final List<Integer> mReverseRotationAroundZAxisStates;
@GuardedBy("mWmLock")
@NonNull
@VisibleForTesting
@@ -76,18 +87,55 @@ final class DeviceStateController {
DeviceStateController(@NonNull Context context, @NonNull WindowManagerGlobalLock wmLock) {
mWmLock = wmLock;
- mOpenDeviceStates = context.getResources()
- .getIntArray(R.array.config_openDeviceStates);
- mHalfFoldedDeviceStates = context.getResources()
- .getIntArray(R.array.config_halfFoldedDeviceStates);
- mFoldedDeviceStates = context.getResources()
- .getIntArray(R.array.config_foldedDeviceStates);
- mRearDisplayDeviceStates = context.getResources()
- .getIntArray(R.array.config_rearDisplayDeviceStates);
- mConcurrentDisplayDeviceState = context.getResources()
- .getInteger(R.integer.config_deviceStateConcurrentRearDisplay);
- mReverseRotationAroundZAxisStates = context.getResources()
- .getIntArray(R.array.config_deviceStatesToReverseDefaultDisplayRotationAroundZAxis);
+ final FeatureFlags deviceStateManagerFlags = new FeatureFlagsImpl();
+ if (deviceStateManagerFlags.deviceStatePropertyMigration()) {
+ mOpenDeviceStates = new ArrayList<>();
+ mHalfFoldedDeviceStates = new ArrayList<>();
+ mFoldedDeviceStates = new ArrayList<>();
+ mRearDisplayDeviceStates = new ArrayList<>();
+ mConcurrentDisplayDeviceStates = new ArrayList<>();
+
+ final DeviceStateManager deviceStateManager =
+ context.getSystemService(DeviceStateManager.class);
+ final List<android.hardware.devicestate.DeviceState> deviceStates =
+ deviceStateManager.getSupportedDeviceStates();
+
+ for (int i = 0; i < deviceStates.size(); i++) {
+ final android.hardware.devicestate.DeviceState state = deviceStates.get(i);
+ if (state.hasProperty(
+ PROPERTY_FEATURE_REAR_DISPLAY)) {
+ mRearDisplayDeviceStates.add(state.getIdentifier());
+ } else if (state.hasProperty(
+ PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT)) {
+ mConcurrentDisplayDeviceStates.add(state.getIdentifier());
+ } else if (state.hasProperty(
+ PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY)) {
+ mFoldedDeviceStates.add(state.getIdentifier());
+ } else if (state.hasProperty(
+ PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY)) {
+ if (state.hasProperty(
+ PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN)) {
+ mHalfFoldedDeviceStates.add(state.getIdentifier());
+ } else {
+ mOpenDeviceStates.add(state.getIdentifier());
+ }
+ }
+ }
+ } else {
+ mOpenDeviceStates = copyIntArrayToList(context.getResources()
+ .getIntArray(R.array.config_openDeviceStates));
+ mHalfFoldedDeviceStates = copyIntArrayToList(context.getResources()
+ .getIntArray(R.array.config_halfFoldedDeviceStates));
+ mFoldedDeviceStates = copyIntArrayToList(context.getResources()
+ .getIntArray(R.array.config_foldedDeviceStates));
+ mRearDisplayDeviceStates = copyIntArrayToList(context.getResources()
+ .getIntArray(R.array.config_rearDisplayDeviceStates));
+ mConcurrentDisplayDeviceStates = new ArrayList<>(List.of(context.getResources()
+ .getInteger(R.integer.config_deviceStateConcurrentRearDisplay)));
+ }
+
+ mReverseRotationAroundZAxisStates = copyIntArrayToList(context.getResources().getIntArray(
+ R.array.config_deviceStatesToReverseDefaultDisplayRotationAroundZAxis));
mMatchBuiltInDisplayOrientationToDefaultDisplay = context.getResources()
.getBoolean(R.bool
.config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay);
@@ -145,7 +193,6 @@ final class DeviceStateController {
*/
public void onDeviceStateReceivedByDisplayManager(int state) {
mCurrentState = state;
-
final DeviceState deviceState;
if (ArrayUtils.contains(mHalfFoldedDeviceStates, state)) {
deviceState = DeviceState.HALF_FOLDED;
@@ -155,9 +202,10 @@ final class DeviceStateController {
deviceState = DeviceState.REAR;
} else if (ArrayUtils.contains(mOpenDeviceStates, state)) {
deviceState = DeviceState.OPEN;
- } else if (state == mConcurrentDisplayDeviceState) {
+ } else if (ArrayUtils.contains(mConcurrentDisplayDeviceStates, state)) {
deviceState = DeviceState.CONCURRENT;
} else {
+
deviceState = DeviceState.UNKNOWN;
}
@@ -190,4 +238,16 @@ final class DeviceStateController {
}
return entries;
}
+
+ @NonNull
+ private List<Integer> copyIntArrayToList(@Nullable int[] values) {
+ if (values == null) {
+ return Collections.emptyList();
+ }
+ final List<Integer> valueList = new ArrayList<>();
+ for (int i = 0; i < values.length; i++) {
+ valueList.add(values[i]);
+ }
+ return valueList;
+ }
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index b5b937775333..93711497f590 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -263,7 +263,6 @@ import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.utils.RegionUtils;
import com.android.server.wm.utils.RotationCache;
import com.android.server.wm.utils.WmDisplayCutout;
-import com.android.window.flags.Flags;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -475,14 +474,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
private final DisplayPolicy mDisplayPolicy;
private final DisplayRotation mDisplayRotation;
- @Nullable
- final DisplayRotationCompatPolicy mDisplayRotationCompatPolicy;
- @Nullable
- final CameraCompatFreeformPolicy mCameraCompatFreeformPolicy;
- @Nullable
- final CameraStateMonitor mCameraStateMonitor;
- @Nullable
- final ActivityRefresher mActivityRefresher;
+ @NonNull
+ AppCompatCameraPolicy mAppCompatCameraPolicy;
DisplayFrames mDisplayFrames;
final DisplayUpdater mDisplayUpdater;
@@ -1191,6 +1184,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mDeviceStateController = deviceStateController;
+ mAppCompatCameraPolicy = new AppCompatCameraPolicy(mWmService, this);
mDisplayPolicy = new DisplayPolicy(mWmService, this);
mDisplayRotation = new DisplayRotation(mWmService, this, mDisplayInfo.address,
mDeviceStateController, root.getDisplayRotationCoordinator());
@@ -1231,40 +1225,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
onDisplayChanged(this);
updateDisplayAreaOrganizers();
- // Not checking DeviceConfig value here to allow enabling via DeviceConfig
- // without the need to restart the device.
- final boolean shouldCreateDisplayRotationCompatPolicy =
- mWmService.mLetterboxConfiguration.isCameraCompatTreatmentEnabledAtBuildTime();
- final boolean shouldCreateCameraCompatFreeformPolicy = Flags.cameraCompatForFreeform()
- && DesktopModeLaunchParamsModifier.canEnterDesktopMode(mWmService.mContext);
- if (shouldCreateDisplayRotationCompatPolicy || shouldCreateCameraCompatFreeformPolicy) {
- mCameraStateMonitor = new CameraStateMonitor(this, mWmService.mH);
- mActivityRefresher = new ActivityRefresher(mWmService, mWmService.mH);
- if (shouldCreateDisplayRotationCompatPolicy) {
- mDisplayRotationCompatPolicy = new DisplayRotationCompatPolicy(this,
- mCameraStateMonitor, mActivityRefresher);
- mDisplayRotationCompatPolicy.start();
- } else {
- mDisplayRotationCompatPolicy = null;
- }
-
- if (shouldCreateCameraCompatFreeformPolicy) {
- mCameraCompatFreeformPolicy = new CameraCompatFreeformPolicy(this,
- mCameraStateMonitor, mActivityRefresher);
- mCameraCompatFreeformPolicy.start();
- } else {
- mCameraCompatFreeformPolicy = null;
- }
-
- mCameraStateMonitor.startListeningToCameraState();
- } else {
- // These are to satisfy the `final` check.
- mCameraStateMonitor = null;
- mActivityRefresher = null;
- mDisplayRotationCompatPolicy = null;
- mCameraCompatFreeformPolicy = null;
- }
-
mRotationReversionController = new DisplayRotationReversionController(this);
mInputMonitor = new InputMonitor(mWmService, this);
@@ -1280,6 +1240,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
R.bool.config_defaultInTouchMode);
mWmService.mInputManager.setInTouchMode(mInTouchMode, mWmService.MY_PID, mWmService.MY_UID,
/* hasPermission= */ true, mDisplayId);
+ mAppCompatCameraPolicy.start();
}
private void beginHoldScreenUpdate() {
@@ -1314,15 +1275,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
}
- /**
- * @return The {@link DisplayRotationCompatPolicy} for this DisplayContent
- */
- // TODO(b/335387481) Allow access to DisplayRotationCompatPolicy only with getters
- @Nullable
- DisplayRotationCompatPolicy getDisplayRotationCompatPolicy() {
- return mDisplayRotationCompatPolicy;
- }
-
@Override
void migrateToNewSurfaceControl(Transaction t) {
t.remove(mSurfaceControl);
@@ -1802,6 +1754,82 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return mDisplayRotation.updateOrientation(orientation, forceUpdate);
}
+ @Nullable
+ private ActivityRecord getLastOrientationSourceApp() {
+ final WindowContainer<?> orientationSrc = getLastOrientationSource();
+ return orientationSrc != null ? orientationSrc.asActivityRecord() : null;
+ }
+
+ /**
+ * This is called when the display rotation is changed. If the current top activity which
+ * decides the display orientation is not opaque, all non-top visible activities with
+ * different fixed orientations will still keep their original appearances.
+ */
+ void applyFixedRotationForNonTopVisibleActivityIfNeeded() {
+ if (!mWmService.mFlags.mRespectNonTopVisibleFixedOrientation) {
+ return;
+ }
+ final ActivityRecord orientationSrcApp = getLastOrientationSourceApp();
+ if (orientationSrcApp == null || orientationSrcApp.fillsParent()) {
+ return;
+ }
+ final int topOrientation = orientationSrcApp.getRequestedOrientation();
+ if (topOrientation == SCREEN_ORIENTATION_UNSPECIFIED) {
+ return;
+ }
+ forAllActivities(ar -> {
+ if (!ar.isVisibleRequested()) {
+ return true;
+ }
+ applyFixedRotationForNonTopVisibleActivityIfNeeded(ar, topOrientation);
+ return false;
+ }, true /* traverseTopToBottom */);
+ }
+
+ /**
+ * This is called when a non-top activity becomes visible. Such when moving a task which
+ * contains 2 activities with different fixed orientations, and if the top one is translucent,
+ * then the bottom one will apply the fixed rotation transform for its orientation.
+ */
+ void applyFixedRotationForNonTopVisibleActivityIfNeeded(@NonNull ActivityRecord ar) {
+ if (!mWmService.mFlags.mRespectNonTopVisibleFixedOrientation) {
+ return;
+ }
+ final ActivityRecord orientationSrcApp = getLastOrientationSourceApp();
+ if (orientationSrcApp != null) {
+ applyFixedRotationForNonTopVisibleActivityIfNeeded(ar,
+ orientationSrcApp.getRequestedOrientation());
+ }
+ }
+
+ /**
+ * If the given visible activity uses a different fixed orientation than the current top, the
+ * fixed rotation transform will be applied to respect its requested appearance.
+ */
+ private void applyFixedRotationForNonTopVisibleActivityIfNeeded(@NonNull ActivityRecord ar,
+ @ActivityInfo.ScreenOrientation int topOrientation) {
+ final int orientation = ar.getRequestedOrientation();
+ if (orientation == topOrientation || ar.inMultiWindowMode()
+ || ar.getRequestedConfigurationOrientation() == ORIENTATION_UNDEFINED) {
+ return;
+ }
+ final int displayRotation = getRotation();
+ final int rotation = ar.isVisible()
+ ? ar.getWindowConfiguration().getDisplayRotation()
+ : mDisplayRotation.rotationForOrientation(orientation, displayRotation);
+ if (rotation == displayRotation) {
+ return;
+ }
+ startFixedRotationTransform(ar, rotation);
+ final WindowState wallpaperTarget = mWallpaperController.getWallpaperTarget();
+ if (wallpaperTarget != null && wallpaperTarget.mActivityRecord == ar) {
+ final WindowState wp = mWallpaperController.getTopVisibleWallpaper();
+ if (wp != null) {
+ wp.mToken.linkFixedRotationTransform(ar);
+ }
+ }
+ }
+
@Override
boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
// Do not consider children because if they are requested to be synced, they should be
@@ -1870,10 +1898,23 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return false;
}
if (r.hasFixedRotationTransform()) {
+ if (mWmService.mFlags.mRespectNonTopVisibleFixedOrientation
+ && mFixedRotationLaunchingApp == null) {
+ // It could be finishing the previous top translucent activity, and the next fixed
+ // orientation activity becomes the current top.
+ setFixedRotationLaunchingAppUnchecked(r,
+ r.getWindowConfiguration().getDisplayRotation());
+ }
// It has been set and not yet finished.
return true;
}
- if (!r.occludesParent() || r.isReportedDrawn()) {
+ if (mWmService.mFlags.mRespectNonTopVisibleFixedOrientation) {
+ if (r.isReportedDrawn()) {
+ // It is late for a drawn app. Either this is already a stable state or it needs
+ // a rotation animation to handle the change.
+ return false;
+ }
+ } else if (!r.occludesParent() || r.isReportedDrawn()) {
// While entering or leaving a translucent or floating activity (e.g. dialog style),
// there is a visible activity in the background. Then it still needs rotation animation
// to cover the activity configuration change.
@@ -2889,12 +2930,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
}
- if (mDisplayRotationCompatPolicy != null) {
- int compatOrientation = mDisplayRotationCompatPolicy.getOrientation();
- if (compatOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
- mLastOrientationSource = null;
- return compatOrientation;
- }
+ final int compatOrientation = mAppCompatCameraPolicy.getOrientation();
+ if (compatOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
+ mLastOrientationSource = null;
+ return compatOrientation;
}
final int orientation = super.getOrientation();
@@ -3364,17 +3403,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
getPendingTransaction().apply();
mWmService.mWindowPlacerLocked.requestTraversal();
- if (mDisplayRotationCompatPolicy != null) {
- mDisplayRotationCompatPolicy.dispose();
- }
-
- if (mCameraCompatFreeformPolicy != null) {
- mCameraCompatFreeformPolicy.dispose();
- }
-
- if (mCameraStateMonitor != null) {
- mCameraStateMonitor.dispose();
- }
+ mAppCompatCameraPolicy.dispose();
}
/** Returns true if a removal action is still being deferred. */
@@ -4053,12 +4082,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
final Transaction t = mWmService.mTransactionFactory.get();
forAllWindows(w -> {
final WindowStateAnimator wsa = w.mWinAnimator;
- if (wsa.mSurfaceController == null) {
+ if (wsa.mSurfaceControl == null) {
return;
}
if (!mWmService.mSessions.contains(wsa.mSession)) {
Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
- + w + " surface=" + wsa.mSurfaceController
+ + w + " surface=" + wsa.mSurfaceControl
+ " token=" + w.mToken
+ " pid=" + w.mSession.mPid
+ " uid=" + w.mSession.mUid);
@@ -4067,7 +4096,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mTmpWindow = w;
} else if (w.mActivityRecord != null && !w.mActivityRecord.isClientVisible()) {
Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
- + w + " surface=" + wsa.mSurfaceController
+ + w + " surface=" + wsa.mSurfaceControl
+ " token=" + w.mActivityRecord);
ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE LEAK DESTROY: %s", w);
wsa.destroySurface(t);
@@ -6983,7 +7012,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// In most cases this is a no-op if the activity doesn't have fixed rotation.
// Otherwise it could be from finishing recents animation while the display has
// different orientation.
- r.finishFixedRotationTransform();
+ if (!mWmService.mFlags.mRespectNonTopVisibleFixedOrientation) {
+ r.finishFixedRotationTransform();
+ } else if (!r.isVisible()) {
+ r.finishFixedRotationTransform();
+ }
return;
}
if (mFixedRotationLaunchingApp.hasFixedRotationTransform(r)) {
@@ -6998,7 +7031,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// E.g. activity A transferred starting window to B, only A will receive transition
// finished event. A doesn't have fixed rotation but B is the rotated launching app.
final Task task = r.getTask();
- if (task == null || task != mFixedRotationLaunchingApp.getTask()) {
+ if (task != mFixedRotationLaunchingApp.getTask()
+ // When closing a translucent task A (r.fillsParent() is false) to a
+ // visible task B, because only A has visibility change, there is only A's
+ // transition callback. Then it still needs to update orientation for B.
+ && (!mWmService.mFlags.mRespectNonTopVisibleFixedOrientation
+ || r.fillsParent())) {
// Different tasks won't be in one activity transition animation.
return;
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index b36fbd34866c..80362a44a33f 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -782,7 +782,6 @@ public class DisplayPolicy {
}
private void onDisplaySwitchFinished() {
- mDisplayContent.mWallpaperController.onDisplaySwitchFinished();
mDisplayContent.mDisplayUpdater.onDisplaySwitching(false);
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index f3ccc3b5aef8..d2976b01acbb 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -627,6 +627,7 @@ public class DisplayRotation {
mRotation = rotation;
+ mDisplayContent.applyFixedRotationForNonTopVisibleActivityIfNeeded();
mDisplayContent.setLayoutNeeded();
mDisplayContent.mWaitingForConfig = true;
@@ -2294,10 +2295,8 @@ public class DisplayRotation {
mInHalfFoldTransition = false;
mDeviceState = DeviceStateController.DeviceState.UNKNOWN;
}
- mDisplayRotationCompatPolicySummary = dc.mDisplayRotationCompatPolicy == null
- ? null
- : dc.mDisplayRotationCompatPolicy
- .getSummaryForDisplayRotationHistoryRecord();
+ mDisplayRotationCompatPolicySummary = dc.mAppCompatCameraPolicy
+ .getSummaryForDisplayRotationHistoryRecord();
mRotationReversionSlots =
dr.mDisplayContent.getRotationReversionController().getSlotsCopy();
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
index 3d71e95f4802..1a0124a1d4de 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
@@ -299,8 +299,7 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp
// Checking whether an activity in fullscreen rather than the task as this camera
// compat treatment doesn't cover activity embedding.
if (cameraActivity.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
- cameraActivity.mAppCompatController
- .getAppCompatCameraPolicy().recomputeConfigurationForCameraCompatIfNeeded();
+ recomputeConfigurationForCameraCompatIfNeeded(cameraActivity);
mDisplayContent.updateOrientation();
return true;
}
@@ -343,12 +342,19 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp
}
@Override
- public boolean onCameraClosed(@NonNull ActivityRecord cameraActivity,
- @NonNull String cameraId) {
+ public boolean onCameraClosed(@NonNull String cameraId) {
+ // Top activity in the same task as the camera activity, or `null` if the task is
+ // closed.
+ final ActivityRecord topActivity = mDisplayContent.topRunningActivity(
+ /* considerKeyguardState= */ true);
+ if (topActivity == null) {
+ return true;
+ }
+
synchronized (this) {
// TODO(b/336474959): Once refresh is implemented in `CameraCompatFreeformPolicy`,
// consider checking this in CameraStateMonitor before notifying the listeners (this).
- if (isActivityForCameraIdRefreshing(cameraId)) {
+ if (isActivityForCameraIdRefreshing(topActivity, cameraId)) {
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Display id=%d is notified that camera is closed but activity is"
+ " still refreshing. Rescheduling an update.",
@@ -356,31 +362,37 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp
return false;
}
}
+
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Display id=%d is notified that Camera is closed, updating rotation.",
mDisplayContent.mDisplayId);
- final ActivityRecord topActivity = mDisplayContent.topRunningActivity(
- /* considerKeyguardState= */ true);
- if (topActivity == null
- // Checking whether an activity in fullscreen rather than the task as this
- // camera compat treatment doesn't cover activity embedding.
- || topActivity.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
+ // Checking whether an activity in fullscreen rather than the task as this camera compat
+ // treatment doesn't cover activity embedding.
+ // TODO(b/350495350): Consider checking whether this activity is the camera activity, or
+ // whether the top activity has the same task as the one which opened camera.
+ if (topActivity.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
return true;
}
- topActivity.mAppCompatController
- .getAppCompatCameraPolicy().recomputeConfigurationForCameraCompatIfNeeded();
+ recomputeConfigurationForCameraCompatIfNeeded(topActivity);
mDisplayContent.updateOrientation();
return true;
}
// TODO(b/336474959): Do we need cameraId here?
- private boolean isActivityForCameraIdRefreshing(@NonNull String cameraId) {
- final ActivityRecord topActivity = mDisplayContent.topRunningActivity(
- /* considerKeyguardState= */ true);
- if (!isTreatmentEnabledForActivity(topActivity)
- || !mCameraStateMonitor.isCameraWithIdRunningForActivity(topActivity, cameraId)) {
+ private boolean isActivityForCameraIdRefreshing(@NonNull ActivityRecord activity,
+ @NonNull String cameraId) {
+ if (!isTreatmentEnabledForActivity(activity)
+ || !mCameraStateMonitor.isCameraWithIdRunningForActivity(activity, cameraId)) {
return false;
}
- return mActivityRefresher.isActivityRefreshing(topActivity);
+ return mActivityRefresher.isActivityRefreshing(activity);
+ }
+
+ private void recomputeConfigurationForCameraCompatIfNeeded(
+ @NonNull ActivityRecord activityRecord) {
+ if (activityRecord.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldRecomputeConfigurationForCameraCompat()) {
+ activityRecord.recomputeConfiguration();
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotationReversionController.java b/services/core/java/com/android/server/wm/DisplayRotationReversionController.java
index f94b8c41b24a..b955738e37b2 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationReversionController.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationReversionController.java
@@ -61,7 +61,7 @@ final class DisplayRotationReversionController {
}
boolean isRotationReversionEnabled() {
- return mDisplayContent.mDisplayRotationCompatPolicy != null
+ return mDisplayContent.mAppCompatCameraPolicy.hasDisplayRotationCompatPolicy()
|| mDisplayContent.getDisplayRotation().mFoldController != null
|| mDisplayContent.getIgnoreOrientationRequest();
}
diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java
index 30f2d0d64d13..6abef8b9a048 100644
--- a/services/core/java/com/android/server/wm/DragDropController.java
+++ b/services/core/java/com/android/server/wm/DragDropController.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.content.ClipDescription.EXTRA_HIDE_DRAG_SOURCE_TASK_ID;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.View.DRAG_FLAG_GLOBAL;
import static android.view.View.DRAG_FLAG_GLOBAL_SAME_APPLICATION;
@@ -217,6 +218,11 @@ class DragDropController {
mDragState.mToken = dragToken;
mDragState.mDisplayContent = displayContent;
mDragState.mData = data;
+ mDragState.mCallingTaskIdToHide = shouldMoveCallingTaskToBack(callingWin,
+ flags);
+ if (DEBUG_DRAG) {
+ Slog.d(TAG_WM, "Calling task to hide=" + mDragState.mCallingTaskIdToHide);
+ }
if ((flags & View.DRAG_FLAG_ACCESSIBILITY_ACTION) == 0) {
final Display display = displayContent.getDisplay();
@@ -364,6 +370,23 @@ class DragDropController {
}
/**
+ * If the calling window's task should be hidden for the duration of the drag, this returns the
+ * task id of the task (or -1 otherwise).
+ */
+ private int shouldMoveCallingTaskToBack(WindowState callingWin, int flags) {
+ if ((flags & View.DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START) == 0) {
+ // Not requested by the app
+ return -1;
+ }
+ final ActivityRecord callingActivity = callingWin.getActivityRecord();
+ if (callingActivity == null || callingActivity.getTask() == null) {
+ // Not an activity
+ return -1;
+ }
+ return callingActivity.getTask().mTaskId;
+ }
+
+ /**
* Notifies the unhandled drag listener if needed.
* @return whether the listener was notified and subsequent drag completion should be deferred
* until the listener calls back
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 4be5bad644f7..ba74f5076bc0 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.content.ClipDescription.EXTRA_HIDE_DRAG_SOURCE_TASK_ID;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
@@ -48,6 +49,7 @@ import android.graphics.Rect;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
@@ -117,6 +119,8 @@ class DragState {
InputInterceptor mInputInterceptor;
ArrayList<WindowState> mNotifiedWindows;
boolean mDragInProgress;
+ // Set to non -1 value if a valid app requests DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START
+ int mCallingTaskIdToHide;
/**
* Whether if animation is completed. Needs to be volatile to update from the animation thread
* without having a WM lock.
@@ -320,12 +324,12 @@ class DragState {
}
}
final boolean targetInterceptsGlobalDrag = targetInterceptsGlobalDrag(touchedWin);
- return obtainDragEvent(DragEvent.ACTION_DROP, x, y, mData,
+ return obtainDragEvent(DragEvent.ACTION_DROP, x, y, mDataDescription, mData,
/* includeDragSurface= */ targetInterceptsGlobalDrag,
/* includeDragFlags= */ targetInterceptsGlobalDrag,
dragAndDropPermissions);
} else {
- return obtainDragEvent(DragEvent.ACTION_DROP, x, y, mData,
+ return obtainDragEvent(DragEvent.ACTION_DROP, x, y, mDataDescription, mData,
/* includeDragSurface= */ includePrivateInfo,
/* includeDragFlags= */ includePrivateInfo,
null /* dragAndDropPermissions */);
@@ -527,11 +531,24 @@ class DragState {
Slog.d(TAG_WM, "Sending DRAG_STARTED to new window " + newWin);
}
// Only allow the extras to be dispatched to a global-intercepting drag target
- ClipData data = interceptsGlobalDrag ? mData.copyForTransferWithActivityInfo() : null;
+ ClipData data = null;
+ if (interceptsGlobalDrag) {
+ data = mData.copyForTransferWithActivityInfo();
+ PersistableBundle extras = data.getDescription().getExtras() != null
+ ? data.getDescription().getExtras()
+ : new PersistableBundle();
+ extras.putInt(EXTRA_HIDE_DRAG_SOURCE_TASK_ID, mCallingTaskIdToHide);
+ // Note that setting extras always copies the bundle
+ data.getDescription().setExtras(extras);
+ if (DEBUG_DRAG) {
+ Slog.d(TAG_WM, "Adding EXTRA_HIDE_DRAG_SOURCE_TASK_ID=" + mCallingTaskIdToHide);
+ }
+ }
+ ClipDescription description = data != null ? data.getDescription() : mDataDescription;
DragEvent event = obtainDragEvent(DragEvent.ACTION_DRAG_STARTED,
newWin.translateToWindowX(touchX), newWin.translateToWindowY(touchY),
- data, false /* includeDragSurface */, true /* includeDragFlags */,
- null /* dragAndDropPermission */);
+ description, data, false /* includeDragSurface */,
+ true /* includeDragFlags */, null /* dragAndDropPermission */);
try {
newWin.mClient.dispatchDragEvent(event);
// track each window that we've notified that the drag is starting
@@ -700,37 +717,51 @@ class DragState {
return mDragInProgress;
}
- private DragEvent obtainDragEvent(int action, float x, float y, ClipData data,
- boolean includeDragSurface, boolean includeDragFlags,
+ private DragEvent obtainDragEvent(int action, float x, float y, ClipDescription description,
+ ClipData data, boolean includeDragSurface, boolean includeDragFlags,
IDragAndDropPermissions dragAndDropPermissions) {
return DragEvent.obtain(action, x, y, mThumbOffsetX, mThumbOffsetY,
includeDragFlags ? mFlags : 0,
- null /* localState */, mDataDescription, data,
+ null /* localState */, description, data,
includeDragSurface ? mSurfaceControl : null,
dragAndDropPermissions, false /* result */);
}
private ValueAnimator createReturnAnimationLocked() {
- final ValueAnimator animator = ValueAnimator.ofPropertyValuesHolder(
- PropertyValuesHolder.ofFloat(
- ANIMATED_PROPERTY_X, mCurrentX - mThumbOffsetX,
- mOriginalX - mThumbOffsetX),
- PropertyValuesHolder.ofFloat(
- ANIMATED_PROPERTY_Y, mCurrentY - mThumbOffsetY,
- mOriginalY - mThumbOffsetY),
- PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale,
- mAnimatedScale),
- PropertyValuesHolder.ofFloat(
- ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, mOriginalAlpha / 2));
-
- final float translateX = mOriginalX - mCurrentX;
- final float translateY = mOriginalY - mCurrentY;
- // Adjust the duration to the travel distance.
- final double travelDistance = Math.sqrt(translateX * translateX + translateY * translateY);
- final double displayDiagonal =
- Math.sqrt(mDisplaySize.x * mDisplaySize.x + mDisplaySize.y * mDisplaySize.y);
- final long duration = MIN_ANIMATION_DURATION_MS + (long) (travelDistance / displayDiagonal
- * (MAX_ANIMATION_DURATION_MS - MIN_ANIMATION_DURATION_MS));
+ final ValueAnimator animator;
+ final long duration;
+ if (mCallingTaskIdToHide != -1) {
+ animator = ValueAnimator.ofPropertyValuesHolder(
+ PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_X, mCurrentX, mCurrentX),
+ PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_Y, mCurrentY, mCurrentY),
+ PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale,
+ mAnimatedScale),
+ PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, 0f));
+ duration = MIN_ANIMATION_DURATION_MS;
+ } else {
+ animator = ValueAnimator.ofPropertyValuesHolder(
+ PropertyValuesHolder.ofFloat(
+ ANIMATED_PROPERTY_X, mCurrentX - mThumbOffsetX,
+ mOriginalX - mThumbOffsetX),
+ PropertyValuesHolder.ofFloat(
+ ANIMATED_PROPERTY_Y, mCurrentY - mThumbOffsetY,
+ mOriginalY - mThumbOffsetY),
+ PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale,
+ mAnimatedScale),
+ PropertyValuesHolder.ofFloat(
+ ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, mOriginalAlpha / 2));
+
+ final float translateX = mOriginalX - mCurrentX;
+ final float translateY = mOriginalY - mCurrentY;
+ // Adjust the duration to the travel distance.
+ final double travelDistance = Math.sqrt(
+ translateX * translateX + translateY * translateY);
+ final double displayDiagonal =
+ Math.sqrt(mDisplaySize.x * mDisplaySize.x + mDisplaySize.y * mDisplaySize.y);
+ duration = MIN_ANIMATION_DURATION_MS + (long) (travelDistance / displayDiagonal
+ * (MAX_ANIMATION_DURATION_MS - MIN_ANIMATION_DURATION_MS));
+ }
+
final AnimationListener listener = new AnimationListener();
animator.setDuration(duration);
animator.setInterpolator(mCubicEaseOutInterpolator);
@@ -742,13 +773,24 @@ class DragState {
}
private ValueAnimator createCancelAnimationLocked() {
- final ValueAnimator animator = ValueAnimator.ofPropertyValuesHolder(
- PropertyValuesHolder.ofFloat(
- ANIMATED_PROPERTY_X, mCurrentX - mThumbOffsetX, mCurrentX),
- PropertyValuesHolder.ofFloat(
- ANIMATED_PROPERTY_Y, mCurrentY - mThumbOffsetY, mCurrentY),
- PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale, 0),
- PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, 0));
+ final ValueAnimator animator;
+ if (mCallingTaskIdToHide != -1) {
+ animator = ValueAnimator.ofPropertyValuesHolder(
+ PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_X, mCurrentX, mCurrentX),
+ PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_Y, mCurrentY, mCurrentY),
+ PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale,
+ mAnimatedScale),
+ PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, 0f));
+ } else {
+ animator = ValueAnimator.ofPropertyValuesHolder(
+ PropertyValuesHolder.ofFloat(
+ ANIMATED_PROPERTY_X, mCurrentX - mThumbOffsetX, mCurrentX),
+ PropertyValuesHolder.ofFloat(
+ ANIMATED_PROPERTY_Y, mCurrentY - mThumbOffsetY, mCurrentY),
+ PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale, 0),
+ PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, 0));
+ }
+
final AnimationListener listener = new AnimationListener();
animator.setDuration(MIN_ANIMATION_DURATION_MS);
animator.setInterpolator(mCubicEaseOutInterpolator);
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index f40eb24fd5eb..3123018e9e88 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -174,6 +174,9 @@ class EnsureActivitiesVisibleHelper {
// First: if this is not the current activity being started, make
// sure it matches the current configuration.
if (r != mStarting && mNotifyClients) {
+ if (!isTop) {
+ r.mDisplayContent.applyFixedRotationForNonTopVisibleActivityIfNeeded(r);
+ }
r.ensureActivityConfiguration(true /* ignoreVisibility */);
}
diff --git a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
index bf99ccdf1b0a..d79c11cecdc0 100644
--- a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
+++ b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
@@ -408,9 +408,8 @@ public class ImmersiveModeConfirmation {
final boolean intersectsTopCutout = topDisplayCutout.intersects(
width - (windowWidth / 2), 0,
width + (windowWidth / 2), topDisplayCutout.bottom);
- if (mClingWindow != null &&
- (windowWidth < 0 || (width > 0 && intersectsTopCutout))) {
- final View iconView = mClingWindow.findViewById(R.id.immersive_cling_icon);
+ if (windowWidth < 0 || (width > 0 && intersectsTopCutout)) {
+ final View iconView = findViewById(R.id.immersive_cling_icon);
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)
iconView.getLayoutParams();
lp.topMargin = topDisplayCutout.bottom;
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 74dbd15d1399..b496a65ba4a6 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -623,7 +623,7 @@ final class InputMonitor {
// occlusion detection depending on the type or if it's a trusted overlay.
populateOverlayInputInfo(inputWindowHandle, w);
setInputWindowInfoIfNeeded(mInputTransaction,
- w.mWinAnimator.mSurfaceController.mSurfaceControl, inputWindowHandle);
+ w.mWinAnimator.mSurfaceControl, inputWindowHandle);
return;
}
// Skip this window because it cannot possibly receive input.
@@ -687,7 +687,7 @@ final class InputMonitor {
if (w.mWinAnimator.hasSurface()) {
populateInputWindowHandle(inputWindowHandle, w);
setInputWindowInfoIfNeeded(mInputTransaction,
- w.mWinAnimator.mSurfaceController.mSurfaceControl, inputWindowHandle);
+ w.mWinAnimator.mSurfaceControl, inputWindowHandle);
}
}
}
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index b5af8065726d..0161ae5b5473 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -19,7 +19,6 @@ package com.android.server.wm;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import android.annotation.DimenRes;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -29,11 +28,11 @@ import android.provider.DeviceConfig;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wm.utils.DimenPxIntSupplier;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.function.Function;
-import java.util.function.IntSupplier;
/** Reads letterbox configs from resources and controls their overrides at runtime. */
final class LetterboxConfiguration {
@@ -308,34 +307,6 @@ final class LetterboxConfiguration {
// Flags dynamically updated with {@link android.provider.DeviceConfig}.
@NonNull private final SynchedDeviceConfig mDeviceConfig;
- // Cached version of IntSupplier customised to evaluate new dimen in pixels
- // when density changes
- private static class DimenPxIntSupplier implements IntSupplier {
-
- @NonNull
- private final Context mContext;
-
- private final int mResourceId;
-
- private float mLastDensity = Float.MIN_VALUE;
- private int mValue = 0;
-
- private DimenPxIntSupplier(@NonNull Context context, @DimenRes int resourceId) {
- mContext = context;
- mResourceId = resourceId;
- }
-
- @Override
- public int getAsInt() {
- final float newDensity = mContext.getResources().getDisplayMetrics().density;
- if (newDensity != mLastDensity) {
- mLastDensity = newDensity;
- mValue = mContext.getResources().getDimensionPixelSize(mResourceId);
- }
- return mValue;
- }
- }
-
LetterboxConfiguration(@NonNull final Context systemUiContext) {
this(systemUiContext, new LetterboxConfigurationPersister(
() -> readLetterboxHorizontalReachabilityPositionFromConfig(
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index e924fb60f56f..235d6cd09d35 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -17,15 +17,6 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_4_3;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_APP_DEFAULT;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_DISPLAY_SIZE;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -44,7 +35,6 @@ import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHA
import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__LEFT_TO_CENTER;
import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__RIGHT_TO_CENTER;
import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__TOP_TO_CENTER;
-import static com.android.server.wm.ActivityRecord.computeAspectRatio;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
@@ -54,23 +44,18 @@ import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT;
-import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_POSITION_MULTIPLIER_CENTER;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
-import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
import static com.android.server.wm.LetterboxConfiguration.letterboxBackgroundTypeToString;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager.TaskDescription;
-import android.content.pm.PackageManager;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
-import android.os.RemoteException;
import android.util.Slog;
import android.view.InsetsSource;
import android.view.InsetsState;
@@ -80,7 +65,6 @@ import android.view.SurfaceControl.Transaction;
import android.view.WindowInsets;
import android.view.WindowManager;
-import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.LetterboxDetails;
import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
@@ -103,11 +87,6 @@ final class LetterboxUiController {
private boolean mShowWallpaperForLetterboxBackground;
- // TODO(b/315140179): Make mUserAspectRatio final
- // The min aspect ratio override set by user
- @PackageManager.UserMinAspectRatio
- private int mUserAspectRatio = USER_MIN_ASPECT_RATIO_UNSET;
-
@Nullable
private Letterbox mLetterbox;
@@ -154,22 +133,6 @@ final class LetterboxUiController {
}
/**
- * Whether we should apply the min aspect ratio per-app override. When this override is applied
- * the min aspect ratio given in the app's manifest will be overridden to the largest enabled
- * aspect ratio treatment unless the app's manifest value is higher. The treatment will also
- * apply if no value is provided in the manifest.
- *
- * <p>This method returns {@code true} when the following conditions are met:
- * <ul>
- * <li>Opt-out component property isn't enabled
- * <li>Per-app override is enabled
- * </ul>
- */
- boolean shouldOverrideMinAspectRatio() {
- return getAppCompatOverrides().shouldOverrideMinAspectRatio();
- }
-
- /**
* Whether we should apply the force resize per-app override. When this override is applied it
* forces the packages it is applied to to be resizable. It won't change whether the app can be
* put into multi-windowing mode, but allow the app to resize without going into size-compat
@@ -230,10 +193,6 @@ final class LetterboxUiController {
return getAppCompatOverrides().shouldUseDisplayLandscapeNaturalOrientation();
}
- private boolean isCompatChangeEnabled(long overrideChangeId) {
- return mActivityRecord.info.isChangeEnabled(overrideChangeId);
- }
-
boolean hasWallpaperBackgroundForLetterbox() {
return mShowWallpaperForLetterboxBackground;
}
@@ -395,7 +354,7 @@ final class LetterboxUiController {
// be a TaskFragment, and its windowing mode is always MULTI_WINDOW, even if the task is
// actually fullscreen. If display is still in transition e.g. unfolding, don't return true
// for HALF_FOLDED state or app will flicker.
- private boolean isDisplayFullScreenAndInPosture(boolean isTabletop) {
+ boolean isDisplayFullScreenAndInPosture(boolean isTabletop) {
Task task = mActivityRecord.getTask();
return mActivityRecord.mDisplayContent != null && task != null
&& mActivityRecord.mDisplayContent.getDisplayRotation().isDeviceInPosture(
@@ -444,44 +403,14 @@ final class LetterboxUiController {
}
float getFixedOrientationLetterboxAspectRatio(@NonNull Configuration parentConfiguration) {
- return shouldUseSplitScreenAspectRatio(parentConfiguration)
- ? getSplitScreenAspectRatio()
- : mActivityRecord.shouldCreateCompatDisplayInsets()
- ? getDefaultMinAspectRatioForUnresizableApps()
- : getDefaultMinAspectRatio();
+ return mActivityRecord.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .getFixedOrientationLetterboxAspectRatio(parentConfiguration);
}
boolean isLetterboxEducationEnabled() {
return mLetterboxConfiguration.getIsEducationEnabled();
}
- private boolean shouldUseSplitScreenAspectRatio(@NonNull Configuration parentConfiguration) {
- final boolean isBookMode = isDisplayFullScreenAndInPosture(/* isTabletop */ false);
- final boolean isNotCenteredHorizontally = getHorizontalPositionMultiplier(
- parentConfiguration) != LETTERBOX_POSITION_MULTIPLIER_CENTER;
- final boolean isTabletopMode = isDisplayFullScreenAndInPosture(/* isTabletop */ true);
- final boolean isLandscape = isFixedOrientationLandscape(
- mActivityRecord.getOverrideOrientation());
-
- // Don't resize to split screen size when in book mode if letterbox position is centered
- return (isBookMode && isNotCenteredHorizontally || isTabletopMode && isLandscape)
- || mActivityRecord.mAppCompatController.getAppCompatCameraOverrides()
- .isCameraCompatSplitScreenAspectRatioAllowed()
- && getAppCompatOverrides().isCameraCompatTreatmentActive();
- }
-
- private float getDefaultMinAspectRatioForUnresizableApps() {
- if (!mLetterboxConfiguration.getIsSplitScreenAspectRatioForUnresizableAppsEnabled()
- || mActivityRecord.getDisplayArea() == null) {
- return mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
- > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
- ? mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
- : getDefaultMinAspectRatio();
- }
-
- return getSplitScreenAspectRatio();
- }
-
/**
* @return {@value true} if the resulting app is letterboxed in a way defined as thin.
*/
@@ -543,123 +472,9 @@ final class LetterboxUiController {
return !isHorizontalThinLetterboxed();
}
- float getSplitScreenAspectRatio() {
- // Getting the same aspect ratio that apps get in split screen.
- final DisplayArea displayArea = mActivityRecord.getDisplayArea();
- if (displayArea == null) {
- return getDefaultMinAspectRatioForUnresizableApps();
- }
- int dividerWindowWidth =
- getResources().getDimensionPixelSize(R.dimen.docked_stack_divider_thickness);
- int dividerInsets =
- getResources().getDimensionPixelSize(R.dimen.docked_stack_divider_insets);
- int dividerSize = dividerWindowWidth - dividerInsets * 2;
- final Rect bounds = new Rect(displayArea.getWindowConfiguration().getAppBounds());
- if (bounds.width() >= bounds.height()) {
- bounds.inset(/* dx */ dividerSize / 2, /* dy */ 0);
- bounds.right = bounds.centerX();
- } else {
- bounds.inset(/* dx */ 0, /* dy */ dividerSize / 2);
- bounds.bottom = bounds.centerY();
- }
- return computeAspectRatio(bounds);
- }
-
- /**
- * Whether we should enable users to resize the current app.
- */
- boolean shouldEnableUserAspectRatioSettings() {
- return getAppCompatOverrides().shouldEnableUserAspectRatioSettings();
- }
-
- /**
- * Whether we should apply the user aspect ratio override to the min aspect ratio for the
- * current app.
- */
- boolean shouldApplyUserMinAspectRatioOverride() {
- if (!shouldEnableUserAspectRatioSettings()) {
- return false;
- }
-
- mUserAspectRatio = getUserMinAspectRatioOverrideCode();
-
- return mUserAspectRatio != USER_MIN_ASPECT_RATIO_UNSET
- && mUserAspectRatio != USER_MIN_ASPECT_RATIO_APP_DEFAULT
- && mUserAspectRatio != USER_MIN_ASPECT_RATIO_FULLSCREEN;
- }
-
- boolean shouldApplyUserFullscreenOverride() {
- if (isUserFullscreenOverrideEnabled()) {
- mUserAspectRatio = getUserMinAspectRatioOverrideCode();
-
- return mUserAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN;
- }
-
- return false;
- }
-
- boolean isUserFullscreenOverrideEnabled() {
- return getAppCompatOverrides().isUserFullscreenOverrideEnabled();
- }
-
- boolean isSystemOverrideToFullscreenEnabled() {
- return getAppCompatOverrides().isSystemOverrideToFullscreenEnabled(mUserAspectRatio);
- }
-
- boolean hasFullscreenOverride() {
- // `mUserAspectRatio` is always initialized first in `shouldApplyUserFullscreenOverride()`.
- return shouldApplyUserFullscreenOverride() || isSystemOverrideToFullscreenEnabled();
- }
-
- float getUserMinAspectRatio() {
- switch (mUserAspectRatio) {
- case USER_MIN_ASPECT_RATIO_DISPLAY_SIZE:
- return getDisplaySizeMinAspectRatio();
- case USER_MIN_ASPECT_RATIO_SPLIT_SCREEN:
- return getSplitScreenAspectRatio();
- case USER_MIN_ASPECT_RATIO_16_9:
- return 16 / 9f;
- case USER_MIN_ASPECT_RATIO_4_3:
- return 4 / 3f;
- case USER_MIN_ASPECT_RATIO_3_2:
- return 3 / 2f;
- default:
- throw new AssertionError("Unexpected user min aspect ratio override: "
- + mUserAspectRatio);
- }
- }
-
- @VisibleForTesting
- int getUserMinAspectRatioOverrideCode() {
- try {
- return mActivityRecord.mAtmService.getPackageManager()
- .getUserMinAspectRatio(mActivityRecord.packageName, mActivityRecord.mUserId);
- } catch (RemoteException e) {
- Slog.w(TAG, "Exception thrown retrieving aspect ratio user override " + this, e);
- }
- return mUserAspectRatio;
- }
-
- private float getDisplaySizeMinAspectRatio() {
- final DisplayArea displayArea = mActivityRecord.getDisplayArea();
- if (displayArea == null) {
- return mActivityRecord.info.getMinAspectRatio();
- }
- final Rect bounds = new Rect(displayArea.getWindowConfiguration().getAppBounds());
- return computeAspectRatio(bounds);
- }
-
- private float getDefaultMinAspectRatio() {
- if (mActivityRecord.getDisplayArea() == null
- || !mLetterboxConfiguration
- .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox()) {
- return mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
- }
- return getDisplaySizeMinAspectRatio();
- }
-
- Resources getResources() {
- return mActivityRecord.mWmService.mContext.getResources();
+ boolean shouldOverrideMinAspectRatio() {
+ return mActivityRecord.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldOverrideMinAspectRatio();
}
@LetterboxConfiguration.LetterboxVerticalReachabilityPosition
@@ -1082,7 +897,7 @@ final class LetterboxUiController {
pw.println(prefix + " letterboxReason=" + getLetterboxReasonString(mainWin));
pw.println(prefix + " activityAspectRatio="
- + mActivityRecord.computeAspectRatio(mActivityRecord.getBounds()));
+ + AppCompatUtils.computeAspectRatio(mActivityRecord.getBounds()));
boolean shouldShowLetterboxUi = shouldShowLetterboxUi(mainWin);
pw.println(prefix + "shouldShowLetterboxUi=" + shouldShowLetterboxUi);
@@ -1141,13 +956,15 @@ final class LetterboxUiController {
if (mActivityRecord.inSizeCompatMode()) {
return "SIZE_COMPAT_MODE";
}
- if (mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio()) {
+ if (mActivityRecord.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()) {
return "FIXED_ORIENTATION";
}
if (mainWin.isLetterboxedForDisplayCutout()) {
return "DISPLAY_CUTOUT";
}
- if (mActivityRecord.isLetterboxedForAspectRatioOnly()) {
+ if (mActivityRecord.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForAspectRatioOnly()) {
return "ASPECT_RATIO";
}
return "UNKNOWN_REASON";
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 6f2528085d74..7aede8b4a068 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -61,7 +61,6 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Environment;
import android.os.IBinder;
@@ -76,7 +75,6 @@ import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.InsetsState;
import android.view.MotionEvent;
-import android.view.WindowInsets;
import android.view.WindowManagerPolicyConstants.PointerEventListener;
import com.android.internal.annotations.VisibleForTesting;
@@ -1536,6 +1534,11 @@ class RecentTasks {
return true;
}
+ // The task is marked as non-trimmable. Don't trim the task.
+ if (!task.mIsTrimmableFromRecents) {
+ return false;
+ }
+
// Ignore tasks from different displays
// TODO (b/115289124): No Recents on non-default displays.
if (!task.isOnHomeDisplay()) {
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index a8edaebd24a6..f8665c70c61d 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -44,8 +44,8 @@ import android.view.SurfaceControl.Transaction;
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.LogLevel;
import com.android.internal.protolog.ProtoLog;
+import com.android.internal.protolog.common.LogLevel;
import com.android.internal.util.FastPrintWriter;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
@@ -53,7 +53,6 @@ import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
-import java.util.function.Consumer;
/**
* Helper class to run app animations in a remote process.
@@ -349,10 +348,6 @@ class RemoteAnimationController implements DeathRecipient {
} finally {
mIsFinishing = false;
}
- // Reset input for all activities when the remote animation is finished.
- final Consumer<ActivityRecord> updateActivities =
- activity -> activity.setDropInputForAnimation(false);
- mDisplayContent.forAllActivities(updateActivities);
}
setRunningRemoteAnimation(false);
ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "Finishing remote animation");
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index d1f1cab43b8a..f2ccbc4e1aeb 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -667,7 +667,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
boolean secure) {
- final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
+ final SurfaceControl surfaceControl = winAnimator.mSurfaceControl;
boolean leakedSurface = false;
boolean killedApps = false;
EventLogTags.writeWmNoSurfaceMemory(winAnimator.mWin.toString(),
@@ -692,7 +692,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return;
}
final WindowStateAnimator wsa = w.mWinAnimator;
- if (wsa.mSurfaceController != null) {
+ if (wsa.mSurfaceControl != null) {
pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
}
}, false /* traverseTopToBottom */);
@@ -717,7 +717,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// app to request another one.
Slog.w(TAG_WM,
"Looks like we have reclaimed some memory, clearing surface for retry.");
- if (surfaceController != null) {
+ if (surfaceControl != null) {
ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
"SURFACE RECOVER DESTROY: %s", winAnimator.mWin);
SurfaceControl.Transaction t = mWmService.mTransactionFactory.get();
@@ -2847,10 +2847,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
SleepToken createSleepToken(String tag, int displayId) {
- return createSleepToken(tag, displayId, false /* isSwappingDisplay */);
- }
-
- SleepToken createSleepToken(String tag, int displayId, boolean isSwappingDisplay) {
final DisplayContent display = getDisplayContent(displayId);
if (display == null) {
throw new IllegalArgumentException("Invalid display: " + displayId);
@@ -2859,16 +2855,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
final int tokenKey = makeSleepTokenKey(tag, displayId);
SleepToken token = mSleepTokens.get(tokenKey);
if (token == null) {
- token = new SleepToken(tag, displayId, isSwappingDisplay);
+ token = new SleepToken(tag, displayId);
mSleepTokens.put(tokenKey, token);
display.mAllSleepTokens.add(token);
ProtoLog.d(WM_DEBUG_STATES, "Create sleep token: tag=%s, displayId=%d", tag, displayId);
} else {
throw new RuntimeException("Create the same sleep token twice: " + token);
}
- if (isSwappingDisplay) {
- display.mWallpaperController.onDisplaySwitchStarted();
- }
return token;
}
@@ -3802,34 +3795,18 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
private final String mTag;
private final long mAcquireTime;
private final int mDisplayId;
- private final boolean mIsSwappingDisplay;
final int mHashKey;
- // The display could remain in sleep after the physical display swapped, adding a 1
- // seconds display swap timeout to prevent activities staying in PAUSED state.
- // Otherwise, the sleep token should be removed once display turns back on after swapped.
- private static final long DISPLAY_SWAP_TIMEOUT = 1000;
-
- SleepToken(String tag, int displayId, boolean isSwappingDisplay) {
+ SleepToken(String tag, int displayId) {
mTag = tag;
mDisplayId = displayId;
mAcquireTime = SystemClock.uptimeMillis();
- mIsSwappingDisplay = isSwappingDisplay;
mHashKey = makeSleepTokenKey(mTag, mDisplayId);
}
- public boolean isDisplaySwapping() {
- long now = SystemClock.uptimeMillis();
- if (now - mAcquireTime > DISPLAY_SWAP_TIMEOUT) {
- return false;
- }
- return mIsSwappingDisplay;
- }
-
@Override
public String toString() {
return "{\"" + mTag + "\", display " + mDisplayId
- + (mIsSwappingDisplay ? " is swapping " : "")
+ ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
}
diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java
index b452131188c6..8c7b6375a72f 100644
--- a/services/core/java/com/android/server/wm/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java
@@ -442,7 +442,10 @@ public class SafeActivityOptions {
return taskDisplayArea;
}
- private boolean isAssistant(ActivityTaskManagerService atmService, int callingUid) {
+ /**
+ * Returns whether the given UID caller is the assistant.
+ */
+ public static boolean isAssistant(ActivityTaskManagerService atmService, int callingUid) {
if (atmService.mActiveVoiceInteractionServiceComponent == null) {
return false;
}
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 3eb321804520..db0374e52b1a 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -324,7 +324,7 @@ class ScreenRotationAnimation {
if (!w.mToken.mRoundedCornerOverlay || !w.isVisible() || !w.mWinAnimator.hasSurface()) {
return;
}
- t.setSkipScreenshot(w.mWinAnimator.mSurfaceController.mSurfaceControl, skipScreenshot);
+ t.setSkipScreenshot(w.mWinAnimator.mSurfaceControl, skipScreenshot);
}, false);
if (!skipScreenshot) {
// Use sync apply to apply the change immediately, so that the next
@@ -815,10 +815,8 @@ class ScreenRotationAnimation {
if (mDisplayContent.getRotationAnimation() == ScreenRotationAnimation.this) {
// It also invokes kill().
mDisplayContent.setRotationAnimation(null);
- if (mDisplayContent.mDisplayRotationCompatPolicy != null) {
- mDisplayContent.mDisplayRotationCompatPolicy
- .onScreenRotationAnimationFinished();
- }
+ mDisplayContent.mAppCompatCameraPolicy
+ .onScreenRotationAnimationFinished();
} else {
kill();
}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 9addce6d5f08..c26684f60731 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -109,8 +109,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
private final String mStringName;
SurfaceSession mSurfaceSession;
private final ArrayList<WindowState> mAddedWindows = new ArrayList<>();
- /** Set of visible alert/app-overlay window surfaces connected to this session. */
- private final ArraySet<WindowSurfaceController> mAlertWindowSurfaces = new ArraySet<>();
+ /** Set of visible alert/app-overlay windows connected to this session. */
+ private final ArraySet<WindowState> mAlertWindows = new ArraySet<>();
private final DragDropController mDragDropController;
final boolean mCanAddInternalSystemWindow;
boolean mCanForceShowingInsets;
@@ -324,19 +324,19 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
}
@Override
- public boolean performHapticFeedback(int effectId, boolean always, boolean fromIme) {
+ public boolean performHapticFeedback(int effectId, int flags, int privFlags) {
final long ident = Binder.clearCallingIdentity();
try {
- return mService.mPolicy.performHapticFeedback(mUid, mPackageName,
- effectId, always, null, fromIme);
+ return mService.mPolicy.performHapticFeedback(mUid, mPackageName, effectId, null, flags,
+ privFlags);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
@Override
- public void performHapticFeedbackAsync(int effectId, boolean always, boolean fromIme) {
- performHapticFeedback(effectId, always, fromIme);
+ public void performHapticFeedbackAsync(int effectId, int flags, int privFlags) {
+ performHapticFeedback(effectId, flags, privFlags);
}
/* Drag/drop */
@@ -349,7 +349,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
final int callingPid = Binder.getCallingPid();
// Validate and resolve ClipDescription data before clearing the calling identity
validateAndResolveDragMimeTypeExtras(data, callingUid, callingPid, mPackageName);
- validateDragFlags(flags);
+ validateDragFlags(flags, callingUid);
final long ident = Binder.clearCallingIdentity();
try {
return mDragDropController.performDrag(mPid, mUid, window, flags, surface, touchSource,
@@ -375,12 +375,17 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
* Validates the given drag flags.
*/
@VisibleForTesting
- void validateDragFlags(int flags) {
+ void validateDragFlags(int flags, int callingUid) {
if ((flags & View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION) != 0) {
if (!mCanStartTasksFromRecents) {
throw new SecurityException("Requires START_TASKS_FROM_RECENTS permission");
}
}
+ if ((flags & View.DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START) != 0) {
+ if (!SafeActivityOptions.isAssistant(mService.mAtmService, callingUid)) {
+ throw new SecurityException("Caller is not the assistant");
+ }
+ }
}
/**
@@ -764,9 +769,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
return !mAddedWindows.isEmpty();
}
- void onWindowSurfaceVisibilityChanged(WindowSurfaceController surfaceController,
- boolean visible, int type) {
-
+ void onWindowSurfaceVisibilityChanged(WindowState window, boolean visible) {
+ final int type = window.mAttrs.type;
if (!isSystemAlertWindowType(type)) {
return;
}
@@ -777,7 +781,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
final boolean noSystemOverlayPermission =
!mCanAddInternalSystemWindow && !mCanCreateSystemApplicationOverlay;
if (visible) {
- changed = mAlertWindowSurfaces.add(surfaceController);
+ changed = mAlertWindows.add(window);
if (type == TYPE_APPLICATION_OVERLAY) {
MetricsLoggerWrapper.logAppOverlayEnter(mUid, mPackageName, changed, type,
false /* set false to only log for TYPE_APPLICATION_OVERLAY */);
@@ -786,7 +790,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
true /* only log for non-TYPE_APPLICATION_OVERLAY */);
}
} else {
- changed = mAlertWindowSurfaces.remove(surfaceController);
+ changed = mAlertWindows.remove(window);
if (type == TYPE_APPLICATION_OVERLAY) {
MetricsLoggerWrapper.logAppOverlayExit(mUid, mPackageName, changed, type,
false /* set false to only log for TYPE_APPLICATION_OVERLAY */);
@@ -797,9 +801,9 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
}
if (changed && noSystemOverlayPermission) {
- if (mAlertWindowSurfaces.isEmpty()) {
+ if (mAlertWindows.isEmpty()) {
cancelAlertWindowNotification();
- } else if (mAlertWindowNotification == null) {
+ } else if (mAlertWindowNotification == null && !isSatellitePointingUiPackage()) {
mAlertWindowNotification = new AlertWindowNotification(mService, mPackageName);
if (mShowingAlertWindowNotificationAllowed) {
mAlertWindowNotification.post();
@@ -810,10 +814,20 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
if (changed && mPid != WindowManagerService.MY_PID) {
// Notify activity manager that the process contains overlay/alert windows, so it can
// adjust the importance score for the process.
- setHasOverlayUi(!mAlertWindowSurfaces.isEmpty());
+ setHasOverlayUi(!mAlertWindows.isEmpty());
}
}
+ // TODO b/349195999 - short term solution to not show the satellite pointing ui notification.
+ private boolean isSatellitePointingUiPackage() {
+ if (mPackageName == null || !mPackageName.equals(mService.mContext.getString(
+ com.android.internal.R.string.config_pointing_ui_package))) {
+ return false;
+ }
+ return ActivityTaskManagerService.checkPermission(
+ android.Manifest.permission.SATELLITE_COMMUNICATION, mPid, mUid) == PERMISSION_GRANTED;
+ }
+
void setShowingAlertWindowNotificationAllowed(boolean allowed) {
mShowingAlertWindowNotificationAllowed = allowed;
if (mAlertWindowNotification != null) {
@@ -844,7 +858,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
}
mSurfaceSession = null;
mAddedWindows.clear();
- mAlertWindowSurfaces.clear();
+ mAlertWindows.clear();
setHasOverlayUi(false);
cancelAlertWindowNotification();
}
@@ -865,10 +879,13 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("numWindow="); pw.print(mAddedWindows.size());
pw.print(" mCanAddInternalSystemWindow="); pw.print(mCanAddInternalSystemWindow);
- pw.print(" mAlertWindowSurfaces="); pw.print(mAlertWindowSurfaces);
+ pw.print(" mAlertWindows="); pw.print(mAlertWindows);
pw.print(" mClientDead="); pw.print(mClientDead);
pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
pw.print(prefix); pw.print("mPackageName="); pw.println(mPackageName);
+ if (isSatellitePointingUiPackage()) {
+ pw.print(prefix); pw.println("mIsSatellitePointingUiPackage=true");
+ }
}
@Override
@@ -878,9 +895,9 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
/** @return {@code true} if there is an alert window surface on the given display. */
boolean hasAlertWindowSurfaces(DisplayContent displayContent) {
- for (int i = mAlertWindowSurfaces.size() - 1; i >= 0; i--) {
- final WindowSurfaceController surfaceController = mAlertWindowSurfaces.valueAt(i);
- if (surfaceController.mAnimator.mWin.getDisplayContent() == displayContent) {
+ for (int i = mAlertWindows.size() - 1; i >= 0; i--) {
+ final WindowState window = mAlertWindows.valueAt(i);
+ if (window.mDisplayContent == displayContent) {
return true;
}
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index f0b0e915da29..74f8a0683811 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -404,8 +404,6 @@ class Task extends TaskFragment {
String mCallingPackage;
String mCallingFeatureId;
- private static final Rect sTmpBounds = new Rect();
-
// Last non-fullscreen bounds the task was launched in or resized to.
// The information is persisted and used to determine the appropriate root task to launch the
// task into on restore.
@@ -497,6 +495,12 @@ class Task extends TaskFragment {
*/
boolean mReparentLeafTaskIfRelaunch;
+ /**
+ * Set to affect whether recents should be able to trim this task or not. It's set to true by
+ * default.
+ */
+ boolean mIsTrimmableFromRecents;
+
private final AnimatingActivityRegistry mAnimatingActivityRegistry =
new AnimatingActivityRegistry();
@@ -668,6 +672,7 @@ class Task extends TaskFragment {
mLaunchCookie = _launchCookie;
mDeferTaskAppear = _deferTaskAppear;
mRemoveWithTaskOrganizer = _removeWithTaskOrganizer;
+ mIsTrimmableFromRecents = true;
EventLogTags.writeWmTaskCreated(mTaskId);
}
@@ -811,42 +816,30 @@ class Task extends TaskFragment {
}
}
- /** Convenience method to reparent a task to the top or bottom position of the root task. */
- boolean reparent(Task preferredRootTask, boolean toTop,
- @ReparentMoveRootTaskMode int moveRootTaskMode, boolean animate, boolean deferResume,
- String reason) {
- return reparent(preferredRootTask, toTop ? MAX_VALUE : 0, moveRootTaskMode, animate,
- deferResume, true /* schedulePictureInPictureModeChange */, reason);
- }
-
/**
* Reparents the task into a preferred root task, creating it if necessary.
*
* @param preferredRootTask the target root task to move this task
- * @param position the position to place this task in the new root task
+ * @param toTop top or bottom position to place this task in the target task
* @param animate whether or not we should wait for the new window created as a part of the
* reparenting to be drawn and animated in
* @param moveRootTaskMode whether or not to move the root task to the front always, only if
* it was previously focused & in front, or never
* @param deferResume whether or not to update the visibility of other tasks and root tasks
* that may have changed as a result of this reparenting
- * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
- * change. Callers may set this to false if they are explicitly scheduling PiP mode
- * changes themselves, like during the PiP animation
* @param reason the caller of this reparenting
* @return whether the task was reparented
*/
// TODO: Inspect all call sites and change to just changing windowing mode of the root task vs.
// re-parenting the task. Can only be done when we are no longer using static root task Ids.
- boolean reparent(Task preferredRootTask, int position,
+ boolean reparent(Task preferredRootTask, boolean toTop,
@ReparentMoveRootTaskMode int moveRootTaskMode, boolean animate, boolean deferResume,
- boolean schedulePictureInPictureModeChange, String reason) {
+ String reason) {
final ActivityTaskSupervisor supervisor = mTaskSupervisor;
final RootWindowContainer root = mRootWindowContainer;
- final WindowManagerService windowManager = mAtmService.mWindowManager;
final Task sourceRootTask = getRootTask();
final Task toRootTask = supervisor.getReparentTargetRootTask(this, preferredRootTask,
- position == MAX_VALUE);
+ toTop);
if (toRootTask == sourceRootTask) {
return false;
}
@@ -857,7 +850,6 @@ class Task extends TaskFragment {
final ActivityRecord topActivity = getTopNonFinishingActivity();
mAtmService.deferWindowLayout();
- boolean kept = true;
try {
final ActivityRecord r = topRunningActivityLocked();
final boolean wasFocused = r != null && root.isTopDisplayFocusedRootTask(sourceRootTask)
@@ -873,12 +865,7 @@ class Task extends TaskFragment {
|| (moveRootTaskMode == REPARENT_KEEP_ROOT_TASK_AT_FRONT
&& (wasFocused || wasFront));
- reparent(toRootTask, position, moveRootTaskToFront, reason);
-
- if (schedulePictureInPictureModeChange) {
- // Notify of picture-in-picture mode changes
- supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceRootTask);
- }
+ reparent(toRootTask, toTop ? MAX_VALUE : 0, moveRootTaskToFront, reason);
// If the task had focus before (or we're requested to move focus), move focus to the
// new root task by moving the root task to the front.
@@ -2864,69 +2851,6 @@ class Task extends TaskFragment {
}
}
- /**
- * Calculate the maximum visible area of this task. If the task has only one app,
- * the result will be visible frame of that app. If the task has more than one apps,
- * we search from top down if the next app got different visible area.
- *
- * This effort is to handle the case where some task (eg. GMail composer) might pop up
- * a dialog that's different in size from the activity below, in which case we should
- * be dimming the entire task area behind the dialog.
- *
- * @param out the union of visible bounds.
- */
- private static void getMaxVisibleBounds(ActivityRecord token, Rect out, boolean[] foundTop) {
- // skip hidden (or about to hide) apps
- if (token.mIsExiting || !token.isClientVisible() || !token.isVisibleRequested()) {
- return;
- }
- final WindowState win = token.findMainWindow();
- if (win == null) {
- return;
- }
- if (!foundTop[0]) {
- foundTop[0] = true;
- out.setEmpty();
- }
-
- final Rect visibleFrame = sTmpBounds;
- final WindowManager.LayoutParams attrs = win.mAttrs;
- visibleFrame.set(win.getFrame());
- visibleFrame.inset(win.getInsetsStateWithVisibilityOverride().calculateVisibleInsets(
- visibleFrame, attrs.type, win.getActivityType(), attrs.softInputMode,
- attrs.flags));
- out.union(visibleFrame);
- }
-
- /** Bounds of the task to be used for dimming, as well as touch related tests. */
- @Override
- void getDimBounds(@NonNull Rect out) {
- if (isRootTask()) {
- getBounds(out);
- return;
- }
-
- final Task rootTask = getRootTask();
- if (inFreeformWindowingMode()) {
- boolean[] foundTop = { false };
- forAllActivities(a -> { getMaxVisibleBounds(a, out, foundTop); });
- if (foundTop[0]) {
- return;
- }
- }
-
- if (!matchParentBounds()) {
- // When minimizing the root docked task when going home, we don't adjust the task bounds
- // so we need to intersect the task bounds with the root task bounds here..
- rootTask.getBounds(mTmpRect);
- mTmpRect.intersect(getBounds());
- out.set(mTmpRect);
- } else {
- out.set(getBounds());
- }
- return;
- }
-
void setDragResizing(boolean dragResizing) {
if (mDragResizing != dragResizing) {
// No need to check if allowed if it's leaving dragResize
@@ -3476,14 +3400,17 @@ class Task extends TaskFragment {
info.isVisibleRequested = isVisibleRequested();
info.isSleeping = shouldSleepActivities();
info.isTopActivityTransparent = top != null && !top.fillsParent();
+ info.isTopActivityStyleFloating = top != null && top.isStyleFloating();
appCompatTaskInfo.topActivityLetterboxVerticalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
appCompatTaskInfo.topActivityLetterboxHorizontalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
appCompatTaskInfo.topActivityLetterboxWidth = TaskInfo.PROPERTY_VALUE_UNSET;
appCompatTaskInfo.topActivityLetterboxHeight = TaskInfo.PROPERTY_VALUE_UNSET;
appCompatTaskInfo.isUserFullscreenOverrideEnabled = top != null
- && top.mLetterboxUiController.shouldApplyUserFullscreenOverride();
+ && top.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldApplyUserFullscreenOverride();
appCompatTaskInfo.isSystemFullscreenOverrideEnabled = top != null
- && top.mLetterboxUiController.isSystemOverrideToFullscreenEnabled();
+ && top.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .isSystemOverrideToFullscreenEnabled();
appCompatTaskInfo.isFromLetterboxDoubleTap = top != null
&& top.mLetterboxUiController.isFromDoubleTap();
if (top != null) {
@@ -3517,7 +3444,8 @@ class Task extends TaskFragment {
}
appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton = top != null
&& !appCompatTaskInfo.topActivityInSizeCompat
- && top.mLetterboxUiController.shouldEnableUserAspectRatioSettings()
+ && top.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldEnableUserAspectRatioSettings()
&& !info.isTopActivityTransparent;
appCompatTaskInfo.topActivityBoundsLetterboxed = top != null && top.areBoundsLetterboxed();
appCompatTaskInfo.cameraCompatTaskInfo.freeformCameraCompatMode = top == null
@@ -3920,6 +3848,7 @@ class Task extends TaskFragment {
pw.print(" isResizeable="); pw.println(isResizeable());
pw.print(prefix); pw.print("lastActiveTime="); pw.print(lastActiveTime);
pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
+ pw.print(prefix); pw.println(" isTrimmable=" + mIsTrimmableFromRecents);
}
@Override
@@ -6154,11 +6083,6 @@ class Task extends TaskFragment {
return setBoundsUnchecked(!inMultiWindowMode() ? null : bounds);
}
- @Override
- public void getBounds(Rect bounds) {
- bounds.set(getBounds());
- }
-
/**
* Put a Task in this root task. Used for adding only.
* When task is added to top of the root task, the entire branch of the hierarchy (including
@@ -6365,6 +6289,10 @@ class Task extends TaskFragment {
}
}
+ void setTrimmableFromRecents(boolean isTrimmable) {
+ mIsTrimmableFromRecents = isTrimmable;
+ }
+
/**
* Return true if the activityInfo has the same requiredDisplayCategory as this task.
*/
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index b6b6cf2dc430..561ff7db5b9d 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -46,7 +46,6 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
-import android.view.RemoteAnimationDefinition;
import android.view.WindowManager;
import android.window.ITaskFragmentOrganizer;
import android.window.ITaskFragmentOrganizerController;
@@ -58,8 +57,8 @@ import android.window.TaskFragmentTransaction;
import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.ProtoLogGroup;
import com.android.internal.protolog.ProtoLog;
+import com.android.internal.protolog.ProtoLogGroup;
import com.android.window.flags.Flags;
import java.lang.annotation.Retention;
@@ -146,13 +145,6 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
private final boolean mIsSystemOrganizer;
/**
- * {@link RemoteAnimationDefinition} for embedded activities transition animation that is
- * organized by this organizer.
- */
- @Nullable
- private RemoteAnimationDefinition mRemoteAnimationDefinition;
-
- /**
* Map from {@link TaskFragmentTransaction#getTransactionToken()} to the
* {@link Transition#getSyncId()} that has been deferred. {@link TransitionController} will
* wait until the organizer finished handling the {@link TaskFragmentTransaction}.
@@ -533,50 +525,6 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
@Override
- public void registerRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer,
- @NonNull RemoteAnimationDefinition definition) {
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- synchronized (mGlobalLock) {
- ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
- "Register remote animations for organizer=%s uid=%d pid=%d",
- organizer.asBinder(), uid, pid);
- final TaskFragmentOrganizerState organizerState =
- mTaskFragmentOrganizerState.get(organizer.asBinder());
- if (organizerState == null) {
- throw new IllegalStateException("The organizer hasn't been registered.");
- }
- if (organizerState.mRemoteAnimationDefinition != null) {
- throw new IllegalStateException(
- "The organizer has already registered remote animations="
- + organizerState.mRemoteAnimationDefinition);
- }
-
- definition.setCallingPidUid(pid, uid);
- organizerState.mRemoteAnimationDefinition = definition;
- }
- }
-
- @Override
- public void unregisterRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer) {
- final int pid = Binder.getCallingPid();
- final long uid = Binder.getCallingUid();
- synchronized (mGlobalLock) {
- ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
- "Unregister remote animations for organizer=%s uid=%d pid=%d",
- organizer.asBinder(), uid, pid);
- final TaskFragmentOrganizerState organizerState =
- mTaskFragmentOrganizerState.get(organizer.asBinder());
- if (organizerState == null) {
- Slog.e(TAG, "The organizer hasn't been registered.");
- return;
- }
-
- organizerState.mRemoteAnimationDefinition = null;
- }
- }
-
- @Override
public void onTransactionHandled(@NonNull IBinder transactionToken,
@NonNull WindowContainerTransaction wct,
@WindowManager.TransitionType int transitionType, boolean shouldApplyIndependently) {
@@ -617,25 +565,6 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
}
- /**
- * Gets the {@link RemoteAnimationDefinition} set on the given organizer if exists. Returns
- * {@code null} if it doesn't.
- */
- @Nullable
- public RemoteAnimationDefinition getRemoteAnimationDefinition(
- @NonNull ITaskFragmentOrganizer organizer) {
- synchronized (mGlobalLock) {
- final TaskFragmentOrganizerState organizerState =
- mTaskFragmentOrganizerState.get(organizer.asBinder());
- if (organizerState == null) {
- Slog.e(TAG, "TaskFragmentOrganizer has been unregistered or died when trying"
- + " to play animation on its organized windows.");
- return null;
- }
- return organizerState.mRemoteAnimationDefinition;
- }
- }
-
int getTaskFragmentOrganizerUid(@NonNull ITaskFragmentOrganizer organizer) {
final TaskFragmentOrganizerState state = validateAndGetState(organizer);
return state.mOrganizerUid;
@@ -1240,16 +1169,6 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
}
- @Override
- public boolean isActivityEmbedded(IBinder activityToken) {
- synchronized (mGlobalLock) {
- final ActivityRecord activity = ActivityRecord.forTokenLocked(activityToken);
- return activity != null
- ? activity.isEmbeddedInHostContainer()
- : false;
- }
- }
-
@VisibleForTesting
@NonNull
IApplicationThread getAppThread(int pid, int uid) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 35a77022737f..f6a68d58ea27 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.ActivityOptions.ANIM_CUSTOM;
import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
@@ -105,8 +106,8 @@ import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
import com.android.internal.policy.TransitionAnimation;
-import com.android.internal.protolog.ProtoLogGroup;
import com.android.internal.protolog.ProtoLog;
+import com.android.internal.protolog.ProtoLogGroup;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
@@ -1443,11 +1444,11 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
asyncRotationController.onTransitionFinished();
}
dc.onTransitionFinished();
- if (hasParticipatedDisplay && dc.mDisplayRotationCompatPolicy != null) {
+ if (hasParticipatedDisplay) {
final ChangeInfo changeInfo = mChanges.get(dc);
if (changeInfo != null
&& changeInfo.mRotation != dc.getWindowConfiguration().getRotation()) {
- dc.mDisplayRotationCompatPolicy.onScreenRotationAnimationFinished();
+ dc.mAppCompatCameraPolicy.onScreenRotationAnimationFinished();
}
}
if (mTransientLaunches != null) {
@@ -1694,7 +1695,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
// ActivityRecord#canShowWindows() may reject to show its window. The visibility also
// needs to be updated for STATE_ABORT.
commitVisibleActivities(transaction);
- commitVisibleWallpapers();
+ commitVisibleWallpapers(transaction);
if (mTransactionCompletedListeners != null) {
for (int i = 0; i < mTransactionCompletedListeners.size(); i++) {
@@ -1897,7 +1898,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
}
}
- private void overrideAnimationOptionsToInfoIfNecessary(@NonNull TransitionInfo info) {
+ @VisibleForTesting
+ void overrideAnimationOptionsToInfoIfNecessary(@NonNull TransitionInfo info) {
if (mOverrideOptions == null) {
return;
}
@@ -1914,12 +1916,28 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
changes.get(i).setAnimationOptions(mOverrideOptions);
// TODO(b/295805497): Extract mBackgroundColor from AnimationOptions.
changes.get(i).setBackgroundColor(mOverrideOptions.getBackgroundColor());
+ } else if (shouldApplyAnimOptionsToEmbeddedTf(container.asTaskFragment())) {
+ // We only override AnimationOptions because backgroundColor should be from
+ // TaskFragmentAnimationParams.
+ changes.get(i).setAnimationOptions(mOverrideOptions);
}
}
}
updateActivityTargetForCrossProfileAnimation(info);
}
+ private boolean shouldApplyAnimOptionsToEmbeddedTf(@Nullable TaskFragment taskFragment) {
+ if (taskFragment == null || !taskFragment.isEmbedded()) {
+ return false;
+ }
+ if (taskFragment.getAnimationParams().hasOverrideAnimation()) {
+ // Always respect animation overrides from TaskFragmentAnimationParams.
+ return false;
+ }
+ // ActivityEmbedding animation adapter only support custom animation
+ return mOverrideOptions != null && mOverrideOptions.getType() == ANIM_CUSTOM;
+ }
+
/**
* Updates activity open target if {@link #mOverrideOptions} is
* {@link ANIM_OPEN_CROSS_PROFILE_APPS}.
@@ -1929,8 +1947,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
return;
}
for (int i = 0; i < mTargets.size(); ++i) {
- final ActivityRecord activity = mTargets.get(i).mContainer
- .asActivityRecord();
+ final ActivityRecord activity = mTargets.get(i).mContainer.asActivityRecord();
final TransitionInfo.Change change = info.getChanges().get(i);
if (activity == null || change.getMode() != TRANSIT_OPEN) {
continue;
@@ -2126,15 +2143,38 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
}
/**
+
+ * Wallpaper will set itself as target if it wants to keep itself visible without a target.
+ */
+ private static boolean wallpaperIsOwnTarget(WallpaperWindowToken wallpaper) {
+ final WindowState target =
+ wallpaper.getDisplayContent().mWallpaperController.getWallpaperTarget();
+ return target != null && target.isDescendantOf(wallpaper);
+ }
+
+ /**
* Reset waitingToshow for all wallpapers, and commit the visibility of the visible ones
*/
- private void commitVisibleWallpapers() {
+ private void commitVisibleWallpapers(SurfaceControl.Transaction t) {
boolean showWallpaper = shouldWallpaperBeVisible();
for (int i = mParticipants.size() - 1; i >= 0; --i) {
final WallpaperWindowToken wallpaper = mParticipants.valueAt(i).asWallpaperToken();
if (wallpaper != null) {
- if (!wallpaper.isVisible() && wallpaper.isVisibleRequested()) {
+ if (!wallpaper.isVisible() && (wallpaper.isVisibleRequested()
+ || (Flags.ensureWallpaperInTransitions() && showWallpaper))) {
wallpaper.commitVisibility(showWallpaper);
+ } else if (Flags.ensureWallpaperInTransitions() && wallpaper.isVisible()
+ && !showWallpaper && !wallpaper.getDisplayContent().isKeyguardLocked()
+ && !wallpaperIsOwnTarget(wallpaper)) {
+ wallpaper.setVisibleRequested(false);
+ }
+ if (showWallpaper && Flags.ensureWallpaperInTransitions()
+ && wallpaper.isVisibleRequested()
+ && getLeashSurface(wallpaper, t) != wallpaper.getSurfaceControl()) {
+ // If on a rotation leash, we need to explicitly show the wallpaper surface
+ // because shell only gets the leash and we don't allow non-transition logic
+ // to touch the surfaces until the transition is over.
+ t.show(wallpaper.getSurfaceControl());
}
}
}
@@ -2548,11 +2588,10 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
if (wc.asWindowState() != null) continue;
final ChangeInfo changeInfo = changes.get(wc);
- // Reject no-ops, unless wallpaper
- if (!changeInfo.hasChanged()
- && (!Flags.ensureWallpaperInTransitions() || wc.asWallpaperToken() == null)) {
+ // Reject no-ops
+ if (!changeInfo.hasChanged()) {
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
- " Rejecting as no-op: %s", wc);
+ " Rejecting as no-op: %s vis: %b", wc, wc.isVisibleRequested());
continue;
}
targets.add(changeInfo);
@@ -2749,12 +2788,19 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
return out;
}
+ // Get the animation theme from the top-most application window
+ // when Flags.customAnimationsBehindTranslucent() is false.
final AnimationOptions animOptionsForActivityTransition =
calculateAnimationOptionsForActivityTransition(type, sortedTargets);
+
if (!Flags.moveAnimationOptionsToChange() && animOptionsForActivityTransition != null) {
out.setAnimationOptions(animOptionsForActivityTransition);
}
+ // Store the animation options of the topmost non-translucent change
+ // (Used when Flags.customAnimationsBehindTranslucent() is true)
+ AnimationOptions activityAboveAnimationOptions = null;
+
final ArraySet<WindowContainer> occludedAtEndContainers = new ArraySet<>();
// Convert all the resolved ChangeInfos into TransactionInfo.Change objects in order.
final int count = sortedTargets.size();
@@ -2837,6 +2883,13 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
// Use parent rotation because shell doesn't know the surface is rotated.
endRotation = parent.getWindowConfiguration().getRotation();
}
+ } else if (isWallpaper(target) && Flags.ensureWallpaperInTransitions()
+ && target.getRelativeDisplayRotation() != 0
+ && !target.mTransitionController.useShellTransitionsRotation()) {
+ // If the wallpaper is "fixed-rotated", shell is unaware of this, so use the
+ // "as-if-not-rotating" bounds and rotation
+ change.setEndAbsBounds(parent.getBounds());
+ endRotation = parent.getWindowConfiguration().getRotation();
} else {
change.setEndAbsBounds(bounds);
}
@@ -2866,9 +2919,26 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
change.setBackgroundColor(ColorUtils.setAlphaComponent(backgroundColor, 255));
}
- AnimationOptions animOptions = null;
+ // Calculate the animation options for this change
if (Flags.moveAnimationOptionsToChange()) {
- if (activityRecord != null && animOptionsForActivityTransition != null) {
+ AnimationOptions animOptions = null;
+ if (Flags.customAnimationsBehindTranslucent() && activityRecord != null) {
+ if (activityAboveAnimationOptions != null) {
+ // Inherit the options from one of the changes on top of this
+ animOptions = activityAboveAnimationOptions;
+ } else {
+ // Create the options based on this change's custom animations and layout
+ // parameters
+ animOptions = getOptions(activityRecord /* customAnimActivity */,
+ activityRecord /* animLpActivity */);
+ if (!change.hasFlags(FLAG_TRANSLUCENT)) {
+ // If this change is not translucent, its options are going to be
+ // inherited by the changes below
+ activityAboveAnimationOptions = animOptions;
+ }
+ }
+ } else if (activityRecord != null && animOptionsForActivityTransition != null) {
+ // Use the same options from the top activity for all the activities
animOptions = animOptionsForActivityTransition;
} else if (Flags.activityEmbeddingOverlayPresentationFlag()
&& isEmbeddedTaskFragment) {
@@ -2916,25 +2986,42 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
@Nullable
private static AnimationOptions calculateAnimationOptionsForActivityTransition(
@TransitionType int type, @NonNull ArrayList<ChangeInfo> sortedTargets) {
- TransitionInfo.AnimationOptions animOptions = null;
-
- // Check if the top-most app is an activity (ie. activity->activity). If so, make sure
- // to honor its custom transition options.
WindowContainer<?> topApp = null;
for (int i = 0; i < sortedTargets.size(); i++) {
- if (isWallpaper(sortedTargets.get(i).mContainer)) continue;
- topApp = sortedTargets.get(i).mContainer;
- break;
+ if (!isWallpaper(sortedTargets.get(i).mContainer)) {
+ topApp = sortedTargets.get(i).mContainer;
+ break;
+ }
}
- if (topApp.asActivityRecord() != null) {
- final ActivityRecord topActivity = topApp.asActivityRecord();
- animOptions = addCustomActivityTransition(topActivity, true/* open */,
- null /* animOptions */);
- animOptions = addCustomActivityTransition(topActivity, false/* open */,
+ ActivityRecord animLpActivity = findAnimLayoutParamsActivityRecord(type, sortedTargets);
+ return getOptions(topApp.asActivityRecord() /* customAnimActivity */,
+ animLpActivity /* animLpActivity */);
+ }
+
+ /**
+ * Updates and returns animOptions with the layout parameters of animLpActivity
+ * @param customAnimActivity the activity that drives the custom animation options
+ * @param animLpActivity the activity that drives the animation options with its layout
+ * parameters
+ * @return the options extracted from the provided activities
+ */
+ @Nullable
+ private static AnimationOptions getOptions(@Nullable ActivityRecord customAnimActivity,
+ @Nullable ActivityRecord animLpActivity) {
+ AnimationOptions animOptions = null;
+ // Custom
+ if (customAnimActivity != null) {
+ animOptions = addCustomActivityTransition(customAnimActivity, true /* open */,
+ animOptions);
+ animOptions = addCustomActivityTransition(customAnimActivity, false /* open */,
animOptions);
}
- final WindowManager.LayoutParams animLp =
- getLayoutParamsForAnimationsStyle(type, sortedTargets);
+
+ // Layout parameters
+ final WindowState mainWindow = animLpActivity != null
+ ? animLpActivity.findMainWindow() : null;
+ final WindowManager.LayoutParams animLp = mainWindow != null ? mainWindow.mAttrs : null;
+
if (animLp != null && animLp.type != TYPE_APPLICATION_STARTING
&& animLp.windowAnimations != 0) {
// Don't send animation options if no windowAnimations have been set or if the we
@@ -3072,10 +3159,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
return ancestor;
}
- private static WindowManager.LayoutParams getLayoutParamsForAnimationsStyle(int type,
- ArrayList<ChangeInfo> sortedTargets) {
- // Find the layout params of the top-most application window that is part of the
- // transition, which is what will control the animation theme.
+ @Nullable
+ private static ActivityRecord findAnimLayoutParamsActivityRecord(
+ @TransitionType int transit, @NonNull List<ChangeInfo> sortedTargets) {
final ArraySet<Integer> activityTypes = new ArraySet<>();
final int targetCount = sortedTargets.size();
for (int i = 0; i < targetCount; ++i) {
@@ -3095,16 +3181,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
// activity through the layout parameter animation style.
return null;
}
- final ActivityRecord animLpActivity =
- findAnimLayoutParamsActivityRecord(sortedTargets, type, activityTypes);
- final WindowState mainWindow = animLpActivity != null
- ? animLpActivity.findMainWindow() : null;
- return mainWindow != null ? mainWindow.mAttrs : null;
- }
- private static ActivityRecord findAnimLayoutParamsActivityRecord(
- List<ChangeInfo> sortedTargets,
- @TransitionType int transit, ArraySet<Integer> activityTypes) {
// Remote animations always win, but fullscreen windows override non-fullscreen windows.
ActivityRecord result = lookForTopWindowWithFilter(sortedTargets,
w -> w.getRemoteAnimationDefinition() != null
diff --git a/services/core/java/com/android/server/wm/TransparentPolicy.java b/services/core/java/com/android/server/wm/TransparentPolicy.java
index 3044abdffa8f..cdb14ab1dc0a 100644
--- a/services/core/java/com/android/server/wm/TransparentPolicy.java
+++ b/services/core/java/com/android/server/wm/TransparentPolicy.java
@@ -162,10 +162,6 @@ class TransparentPolicy {
mTransparentPolicyState.clearInheritedCompatDisplayInsets();
}
- TransparentPolicyState getTransparentPolicyState() {
- return mTransparentPolicyState;
- }
-
/**
* In case of translucent activities, it consumes the {@link ActivityRecord} of the first opaque
* activity beneath using the given consumer and returns {@code true}.
@@ -176,7 +172,7 @@ class TransparentPolicy {
@NonNull
Optional<ActivityRecord> getFirstOpaqueActivity() {
- return isRunning() ? Optional.of(mTransparentPolicyState.mFirstOpaqueActivity)
+ return isRunning() ? Optional.ofNullable(mTransparentPolicyState.mFirstOpaqueActivity)
: Optional.empty();
}
@@ -216,10 +212,6 @@ class TransparentPolicy {
SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
}
- private void inheritConfiguration(ActivityRecord firstOpaque) {
- mTransparentPolicyState.inheritFromOpaque(firstOpaque);
- }
-
/**
* Encapsulate the state for the current translucent activity when the transparent policy
* has started.
diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
index c0713966d8de..3947d02c86c9 100644
--- a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
+++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
@@ -153,6 +153,10 @@ class UnknownAppVisibilityController {
mUnknownApps.put(activity, UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE);
mDisplayContent.notifyKeyguardFlagsChanged();
notifyVisibilitiesUpdated();
+ } else if (state == UNKNOWN_STATE_WAITING_RESUME
+ && !activity.isState(ActivityRecord.State.RESUMED)) {
+ Slog.d(TAG, "UAVC: skip waiting for non-resumed relayouted " + activity);
+ mUnknownApps.remove(activity);
}
}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 3b5a6058e803..26526707267b 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import static android.app.WallpaperManager.COMMAND_DISPLAY_SWITCH;
import static android.app.WallpaperManager.COMMAND_FREEZE;
import static android.app.WallpaperManager.COMMAND_UNFREEZE;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -119,11 +118,6 @@ class WallpaperController {
private boolean mShouldOffsetWallpaperCenter;
- /**
- * Whether the wallpaper has been notified about a physical display switch event is started.
- */
- private volatile boolean mIsWallpaperNotifiedOnDisplaySwitch;
-
private final ToBooleanFunction<WindowState> mFindWallpaperTargetFunction = w -> {
final boolean useShellTransition = w.mTransitionController.isShellTransitionsEnabled();
if (!useShellTransition) {
@@ -1094,52 +1088,6 @@ class WallpaperController {
}
/**
- * Notifies the wallpaper that the display turns off when switching physical device. If the
- * wallpaper is currently visible, its client visibility will be preserved until the display is
- * confirmed to be off or on.
- */
- void onDisplaySwitchStarted() {
- mIsWallpaperNotifiedOnDisplaySwitch = notifyDisplaySwitch(true /* start */);
- }
-
- /**
- * Called when the screen has finished turning on or the device goes to sleep. This is no-op if
- * the operation is not part of a display switch.
- */
- void onDisplaySwitchFinished() {
- // The method can be called outside WM lock (turned on), so only acquire lock if needed.
- // This is to optimize the common cases that regular devices don't have display switch.
- if (mIsWallpaperNotifiedOnDisplaySwitch) {
- synchronized (mService.mGlobalLock) {
- mIsWallpaperNotifiedOnDisplaySwitch = false;
- notifyDisplaySwitch(false /* start */);
- }
- }
- }
-
- private boolean notifyDisplaySwitch(boolean start) {
- boolean notified = false;
- for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
- final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
- for (int i = token.getChildCount() - 1; i >= 0; i--) {
- final WindowState w = token.getChildAt(i);
- if (start && !w.mWinAnimator.getShown()) {
- continue;
- }
- try {
- w.mClient.dispatchWallpaperCommand(COMMAND_DISPLAY_SWITCH, 0 /* x */, 0 /* y */,
- start ? 1 : 0 /* use z as start or finish */,
- null /* bundle */, false /* sync */);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to dispatch COMMAND_DISPLAY_SWITCH " + e);
- }
- notified = true;
- }
- }
- return notified;
- }
-
- /**
* Each window can request a zoom, example:
* - User is in overview, zoomed out.
* - User also pulls down the shade.
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 325ef0d184df..eb1a80b74b76 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -117,6 +117,7 @@ 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;
@@ -179,7 +180,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// List of children for this window container. List is in z-order as the children appear on
// screen with the top-most window container at the tail of the list.
- protected final WindowList<E> mChildren = new WindowList<E>();
+ protected final ArrayList<E> mChildren = new ArrayList<E>();
// The specified orientation for this window container.
// Shouldn't be accessed directly since subclasses can override getOverrideOrientation.
@@ -237,12 +238,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
/** Total number of elements in this subtree, including our own hierarchy element. */
private int mTreeWeight = 1;
- /**
- * Indicates whether we are animating and have committed the transaction to reparent our
- * surface to the animation leash
- */
- private boolean mCommittedReparentToAnimationLeash;
-
private int mSyncTransactionCommitCallbackDepth = 0;
/** Interface for {@link #isAnimating} to check which cases for the container is animating. */
@@ -464,6 +459,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
source.setFrame(provider.getArbitraryRectangle())
.updateSideHint(getBounds())
.setBoundingRects(provider.getBoundingRects());
+ if (Flags.enableCaptionCompatInsetForceConsumption()) {
+ source.setFlags(provider.getFlags());
+ }
mLocalInsetsSources.put(id, source);
mDisplayContent.getInsetsStateController().updateAboveInsetsState(true);
}
@@ -861,7 +859,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
mSurfaceFreezer.unfreeze(getSyncTransaction());
}
while (!mChildren.isEmpty()) {
- final E child = mChildren.peekLast();
+ final E child = mChildren.getLast();
child.removeImmediately();
// Need to do this after calling remove on the child because the child might try to
// remove/detach itself from its parent which will cause an exception if we remove
@@ -985,7 +983,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
switch (position) {
case POSITION_TOP:
- if (mChildren.peekLast() != child) {
+ if (getTopChild() != child) {
mChildren.remove(child);
mChildren.add(child);
onChildPositionChanged(child);
@@ -996,7 +994,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
break;
case POSITION_BOTTOM:
- if (mChildren.peekFirst() != child) {
+ if (getBottomChild() != child) {
mChildren.remove(child);
mChildren.addFirst(child);
onChildPositionChanged(child);
@@ -1451,7 +1449,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
/** Returns the top child container. */
E getTopChild() {
- return mChildren.peekLast();
+ final int n = mChildren.size();
+ return n == 0 ? null : mChildren.get(n - 1);
+ }
+
+ E getBottomChild() {
+ final int n = mChildren.size();
+ return n == 0 ? null : mChildren.get(0);
}
/**
@@ -2556,7 +2560,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
if (mParent != null && mParent == other.mParent) {
- final WindowList<WindowContainer> list = mParent.mChildren;
+ final ArrayList<WindowContainer> list = mParent.mChildren;
return list.indexOf(this) > list.indexOf(other) ? 1 : -1;
}
@@ -2579,8 +2583,12 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// Containers don't belong to the same hierarchy???
if (commonAncestor == null) {
- throw new IllegalArgumentException("No in the same hierarchy this="
- + thisParentChain + " other=" + otherParentChain);
+ final int thisZ = getPrefixOrderIndex();
+ final int otherZ = other.getPrefixOrderIndex();
+ Slog.w(TAG, "Compare not in the same hierarchy this="
+ + thisParentChain + " thisZ=" + thisZ + " other="
+ + otherParentChain + " otherZ=" + otherZ);
+ return Integer.compare(thisZ, otherZ);
}
// Children are always considered greater than their parents, so if one of the containers
@@ -2593,7 +2601,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// The position of the first non-common ancestor in the common ancestor list determines
// which is greater the which.
- final WindowList<WindowContainer> list = commonAncestor.mChildren;
+ final ArrayList<WindowContainer> list = commonAncestor.mChildren;
return list.indexOf(thisParentChain.peekLast()) > list.indexOf(otherParentChain.peekLast())
? 1 : -1;
} finally {
@@ -2871,23 +2879,12 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
void prepareSurfaces() {
- // If a leash has been set when the transaction was committed, then the leash reparent has
- // been committed.
- mCommittedReparentToAnimationLeash = mSurfaceAnimator.hasLeash();
for (int i = 0; i < mChildren.size(); i++) {
mChildren.get(i).prepareSurfaces();
}
}
/**
- * @return true if the reparent to animation leash transaction has been committed, false
- * otherwise.
- */
- boolean hasCommittedReparentToAnimationLeash() {
- return mCommittedReparentToAnimationLeash;
- }
-
- /**
* Trigger a call to prepareSurfaces from the animation thread, such that pending transactions
* will be applied.
*/
diff --git a/services/core/java/com/android/server/wm/WindowList.java b/services/core/java/com/android/server/wm/WindowList.java
deleted file mode 100644
index 1e888f5823a1..000000000000
--- a/services/core/java/com/android/server/wm/WindowList.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.wm;
-
-import java.util.ArrayList;
-
-/**
- * An {@link ArrayList} with extended functionality to be used as the children data structure in
- * {@link WindowContainer}.
- */
-class WindowList<E> extends ArrayList<E> {
-
- public void addFirst(E e) {
- add(0, e);
- }
-
- E peekLast() {
- return size() > 0 ? get(size() - 1) : null;
- }
-
- E peekFirst() {
- return size() > 0 ? get(0) : null;
- }
-}
diff --git a/services/core/java/com/android/server/wm/WindowManagerFlags.java b/services/core/java/com/android/server/wm/WindowManagerFlags.java
index 294733e85fbd..f3e6a184ce45 100644
--- a/services/core/java/com/android/server/wm/WindowManagerFlags.java
+++ b/services/core/java/com/android/server/wm/WindowManagerFlags.java
@@ -50,5 +50,8 @@ class WindowManagerFlags {
final boolean mInsetsDecoupledConfiguration = Flags.insetsDecoupledConfiguration();
+ final boolean mRespectNonTopVisibleFixedOrientation =
+ Flags.respectNonTopVisibleFixedOrientation();
+
/* End Available Flags */
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index a42cb09f5500..2ea1cf88447a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -44,6 +44,7 @@ import android.view.IWindow;
import android.view.InputChannel;
import android.view.MagnificationSpec;
import android.view.RemoteAnimationTarget;
+import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
import android.view.WindowInfo;
@@ -817,6 +818,16 @@ public abstract class WindowManagerInternal {
public abstract Context getTopFocusedDisplayUiContext();
/**
+ * Sets the rotation of a non-default display.
+ *
+ * @param displayId The id of the display
+ * @param rotation The new rotation value.
+ * @param caller The requester of the rotation change, used for bookkeeping.
+ */
+ public abstract void setNonDefaultDisplayRotation(int displayId, @Surface.Rotation int rotation,
+ @NonNull String caller);
+
+ /**
* Sets whether the relevant display content can host the relevant home activity and wallpaper.
*
* @param displayUniqueId The unique ID of the display. Note that the display may not yet be
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 57b8040ef0ac..ebbf6e346e91 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -283,6 +283,7 @@ import android.view.InsetsFrameProvider;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
import android.view.MagnificationSpec;
import android.view.RemoteAnimationAdapter;
import android.view.ScrollCaptureResponse;
@@ -334,8 +335,8 @@ import com.android.internal.policy.IKeyguardLockedStateListener;
import com.android.internal.policy.IShortcutService;
import com.android.internal.policy.KeyInterceptionInfo;
import com.android.internal.protolog.LegacyProtoLogImpl;
-import com.android.internal.protolog.ProtoLogGroup;
import com.android.internal.protolog.ProtoLog;
+import com.android.internal.protolog.ProtoLogGroup;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FrameworkStatsLog;
@@ -732,6 +733,13 @@ public class WindowManagerService extends IWindowManager.Stub
final DisplayWindowListenerController mDisplayNotificationController;
final TaskSystemBarsListenerController mTaskSystemBarsListenerController;
+ /** Amount of time (in milliseconds) to delay the pointer down outside focus handling */
+ private static final int POINTER_DOWN_OUTSIDE_FOCUS_TIMEOUT_MS = 50;
+
+ /** A runnable to handle pointer down outside focus event. */
+ @Nullable
+ private Runnable mPointerDownOutsideFocusRunnable;
+
boolean mDisplayFrozen = false;
long mDisplayFreezeTime = 0;
int mLastDisplayFreezeDuration = 0;
@@ -2562,7 +2570,7 @@ public class WindowManagerService extends IWindowManager.Stub
// surface, let the client use that, but don't create new surface at this
// point.
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface");
- winAnimator.mSurfaceController.getSurfaceControl(outSurfaceControl);
+ winAnimator.getSurfaceControl(outSurfaceControl);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
} else {
if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);
@@ -2758,15 +2766,15 @@ public class WindowManagerService extends IWindowManager.Stub
result |= RELAYOUT_RES_SURFACE_CHANGED;
}
- WindowSurfaceController surfaceController;
+ SurfaceControl surfaceControl;
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
- surfaceController = winAnimator.createSurfaceLocked();
+ surfaceControl = winAnimator.createSurfaceLocked();
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
- if (surfaceController != null) {
- surfaceController.getSurfaceControl(outSurfaceControl);
+ if (surfaceControl != null) {
+ winAnimator.getSurfaceControl(outSurfaceControl);
ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);
} else {
@@ -5896,7 +5904,8 @@ public class WindowManagerService extends IWindowManager.Stub
case ON_POINTER_DOWN_OUTSIDE_FOCUS: {
synchronized (mGlobalLock) {
final IBinder touchedToken = (IBinder) msg.obj;
- onPointerDownOutsideFocusLocked(getInputTargetFromToken(touchedToken));
+ onPointerDownOutsideFocusLocked(getInputTargetFromToken(touchedToken),
+ true /* fromHandler */);
}
break;
}
@@ -6764,11 +6773,11 @@ public class WindowManagerService extends IWindowManager.Stub
if (windowState == null) {
return false;
}
- WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController;
- if (surfaceController == null) {
+ final SurfaceControl surfaceControl = windowState.mWinAnimator.mSurfaceControl;
+ if (surfaceControl == null) {
return false;
}
- return surfaceController.clearWindowContentFrameStats();
+ return surfaceControl.clearContentFrameStats();
}
}
@@ -6783,15 +6792,15 @@ public class WindowManagerService extends IWindowManager.Stub
if (windowState == null) {
return null;
}
- WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController;
- if (surfaceController == null) {
+ final SurfaceControl surfaceControl = windowState.mWinAnimator.mSurfaceControl;
+ if (surfaceControl == null) {
return null;
}
if (mTempWindowRenderStats == null) {
mTempWindowRenderStats = new WindowContentFrameStats();
}
WindowContentFrameStats stats = mTempWindowRenderStats;
- if (!surfaceController.getWindowContentFrameStats(stats)) {
+ if (!surfaceControl.getContentFrameStats(stats)) {
return null;
}
return stats;
@@ -7432,6 +7441,16 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ return mPolicy.getApplicationLaunchKeyboardShortcuts(deviceId);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
enforceRegisterWindowManagerListenersPermission("requestAppKeyboardShortcuts");
@@ -7922,7 +7941,8 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mGlobalLock) {
final InputTarget inputTarget =
WindowManagerService.this.getInputTargetFromWindowTokenLocked(windowToken);
- WindowManagerService.this.onPointerDownOutsideFocusLocked(inputTarget);
+ WindowManagerService.this.onPointerDownOutsideFocusLocked(inputTarget,
+ false /* fromHandler */);
}
}
@@ -8362,6 +8382,26 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void setNonDefaultDisplayRotation(int displayId, @Surface.Rotation int rotation,
+ @NonNull String caller) {
+ if (displayId == Display.DEFAULT_DISPLAY || displayId == Display.INVALID_DISPLAY) {
+ Slog.w(TAG, "Cannot set rotation for display with id: " + displayId);
+ return;
+ }
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ Slog.w(TAG, "Cannot set rotation for display " + displayId
+ + " due to missing DisplayContent");
+ return;
+ }
+ displayContent.getDisplayRotation().setUserRotation(
+ displayContent.getDisplayRotation().getUserRotationMode(), rotation,
+ caller);
+ }
+ }
+
+ @Override
public void setHomeSupportedOnDisplay(String displayUniqueId, int displayType,
boolean supported) {
final long origId = Binder.clearCallingIdentity();
@@ -8977,39 +9017,78 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- private void onPointerDownOutsideFocusLocked(InputTarget t) {
+ void clearPointerDownOutsideFocusRunnable() {
+ if (mPointerDownOutsideFocusRunnable == null) return;
+
+ mH.removeCallbacks(mPointerDownOutsideFocusRunnable);
+ mPointerDownOutsideFocusRunnable = null;
+ }
+
+ private void onPointerDownOutsideFocusLocked(InputTarget t, boolean fromHandler) {
if (t == null || !t.receiveFocusFromTapOutside()) {
// If the window that received the input event cannot receive keys, don't move the
// display it's on to the top since that window won't be able to get focus anyway.
return;
}
- if (mRecentsAnimationController != null
- && mRecentsAnimationController.getTargetAppMainWindow() == t) {
- // If there is an active recents animation and touched window is the target, then ignore
- // the touch. The target already handles touches using its own input monitor and we
- // don't want to trigger any lifecycle changes from focusing another window.
- // TODO(b/186770026): We should remove this once we support multiple resumed activities
- // while in overview
- return;
- }
+ clearPointerDownOutsideFocusRunnable();
+
+ // For embedded activity that is showing side-by-side with another activity, delay
+ // handling the touch-outside event to prevent focus rapid changes back-n-forth.
+ // Otherwise, handle the touch-outside event directly.
final WindowState w = t.getWindowState();
- if (w != null) {
- final Task task = w.getTask();
- if (task != null && w.mTransitionController.isTransientHide(task)) {
- // Don't disturb transient animation by accident touch.
+ final ActivityRecord activity = w != null ? w.getActivityRecord() : null;
+ if (activity != null && activity.isEmbedded()
+ && activity.getTaskFragment().getAdjacentTaskFragment() != null) {
+ mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
+ mH.postDelayed(mPointerDownOutsideFocusRunnable, POINTER_DOWN_OUTSIDE_FOCUS_TIMEOUT_MS);
+ } else if (!fromHandler) {
+ // Still post the runnable to handler thread in case there is already a runnable
+ // in execution, but still waiting to hold the wm lock.
+ mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
+ mH.post(mPointerDownOutsideFocusRunnable);
+ } else {
+ handlePointerDownOutsideFocus(t);
+ }
+ }
+
+ private void handlePointerDownOutsideFocus(InputTarget t) {
+ synchronized (mGlobalLock) {
+ if (mPointerDownOutsideFocusRunnable != null
+ && mH.hasCallbacks(mPointerDownOutsideFocusRunnable)) {
+ // Skip if there's another pending pointer-down-outside-focus event.
+ return;
+ }
+ clearPointerDownOutsideFocusRunnable();
+
+ if (mRecentsAnimationController != null
+ && mRecentsAnimationController.getTargetAppMainWindow() == t) {
+ // If there is an active recents animation and touched window is the target,
+ // then ignore the touch. The target already handles touches using its own
+ // input monitor and we don't want to trigger any lifecycle changes from
+ // focusing another window.
+ // TODO(b/186770026): We should remove this once we support multiple resumed
+ // activities while in overview
return;
}
- }
- ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "onPointerDownOutsideFocusLocked called on %s",
- t);
- if (mFocusedInputTarget != t && mFocusedInputTarget != null) {
- mFocusedInputTarget.handleTapOutsideFocusOutsideSelf();
+ final WindowState w = t.getWindowState();
+ if (w != null) {
+ final Task task = w.getTask();
+ if (task != null && w.mTransitionController.isTransientHide(task)) {
+ // Don't disturb transient animation by accident touch.
+ return;
+ }
+ }
+
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "onPointerDownOutsideFocusLocked called on %s", t);
+ if (mFocusedInputTarget != t && mFocusedInputTarget != null) {
+ mFocusedInputTarget.handleTapOutsideFocusOutsideSelf();
+ }
+ // Trigger Activity#onUserLeaveHint() if the order change of task pauses any activities.
+ mAtmService.mTaskSupervisor.mUserLeaving = true;
+ t.handleTapOutsideFocusInsideSelf();
+ mAtmService.mTaskSupervisor.mUserLeaving = false;
}
- // Trigger Activity#onUserLeaveHint() if the order change of task pauses any activities.
- mAtmService.mTaskSupervisor.mUserLeaving = true;
- t.handleTapOutsideFocusInsideSelf();
- mAtmService.mTaskSupervisor.mUserLeaving = false;
}
@VisibleForTesting
@@ -9231,7 +9310,8 @@ public class WindowManagerService extends IWindowManager.Stub
isTrustedOverlay);
final int sanitizedLpFlags =
- (flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE))
+ (flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE
+ | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH))
| LayoutParams.FLAG_NOT_TOUCH_MODAL;
h.layoutParamsType = type;
h.layoutParamsFlags = sanitizedLpFlags;
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index de584573fcaf..bc32b91f2c57 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -62,6 +62,7 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH;
@@ -123,8 +124,8 @@ import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.ProtoLogGroup;
import com.android.internal.protolog.ProtoLog;
+import com.android.internal.protolog.ProtoLogGroup;
import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.android.server.pm.LauncherAppsService.LauncherAppsServiceInternal;
@@ -617,7 +618,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
if (transition.isCollecting()) {
deferTransitionReady = true;
transition.deferTransitionReady();
- } else if (Flags.alwaysDeferTransitionWhenApplyWct()) {
+ } else {
Slog.w(TAG, "Transition is not collecting when applyTransaction."
+ " transition=" + transition + " state=" + transition.getState());
transition = null;
@@ -878,15 +879,20 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
final int childWindowingMode = c.getActivityWindowingMode();
if (!ActivityTaskManagerService.isPip2ExperimentEnabled()
- && tr.getWindowingMode() == WINDOWING_MODE_PINNED
- && (childWindowingMode == WINDOWING_MODE_PINNED
- || childWindowingMode == WINDOWING_MODE_UNDEFINED)) {
- // If setActivityWindowingMode requested to match its pinned task's windowing mode,
- // remove any inconsistency checking timeout callbacks for PiP.
- Slog.d(TAG, "Task and activity windowing modes match, so remove any timeout "
- + "abort PiP callbacks scheduled if needed; task_win_mode="
- + tr.getWindowingMode() + ", activity_win_mode=" + childWindowingMode);
- mService.mRootWindowContainer.removeAllMaybeAbortPipEnterRunnable();
+ && tr.getWindowingMode() == WINDOWING_MODE_PINNED) {
+ if (childWindowingMode == WINDOWING_MODE_PINNED
+ || childWindowingMode == WINDOWING_MODE_UNDEFINED) {
+ // If setActivityWindowingMode requested to match its pinned task's windowing mode,
+ // remove any inconsistency checking timeout callbacks for PiP.
+ Slog.d(TAG, "Task and activity windowing modes match, so remove any timeout "
+ + "abort PiP callbacks scheduled if needed; task_win_mode="
+ + tr.getWindowingMode() + ", activity_win_mode=" + childWindowingMode);
+ mService.mRootWindowContainer.removeAllMaybeAbortPipEnterRunnable();
+ } else if (shouldApplyLifecycleEffectOnPipChange()) {
+ // This is leaving PiP: task is pinned mode and activity changes to non-pip mode.
+ // Then the activity can be resumed because it becomes focusable.
+ effects |= TRANSACT_EFFECTS_LIFECYCLE;
+ }
}
if (childWindowingMode > -1) {
tr.forAllActivities(a -> { a.setWindowingMode(childWindowingMode); });
@@ -911,6 +917,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
if (canEnterPip) {
canEnterPip = mService.mActivityClientController
.requestPictureInPictureMode(activity);
+ if (canEnterPip && shouldApplyLifecycleEffectOnPipChange()) {
+ effects |= TRANSACT_EFFECTS_LIFECYCLE;
+ }
}
if (!canEnterPip) {
// Restore the flag to its previous state when the activity cannot enter PIP.
@@ -922,6 +931,14 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
return effects;
}
+ // TODO(b/333452456): For testing on local easier. Remove after the use case is gone.
+ @VisibleForTesting
+ static boolean shouldApplyLifecycleEffectOnPipChange() {
+ return android.os.SystemProperties.getBoolean(
+ "persist.wm.debug.apply_lifecycle_on_pip_change", false)
+ || com.android.window.flags.Flags.applyLifecycleOnPipChange();
+ }
+
private int applyDisplayAreaChanges(DisplayArea displayArea,
WindowContainerTransaction.Change c) {
final int[] effects = new int[1];
@@ -1355,6 +1372,17 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
task.setReparentLeafTaskIfRelaunch(hop.isReparentLeafTaskIfRelaunch());
break;
}
+ case HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE: {
+ final WindowContainer container = WindowContainer.fromBinder(hop.getContainer());
+ final Task task = container != null ? container.asTask() : null;
+ if (task == null || !task.isAttached()) {
+ Slog.e(TAG, "Attempt to operate on unknown or detached container: "
+ + container);
+ break;
+ }
+ task.setTrimmableFromRecents(hop.isTrimmableFromRecents());
+ break;
+ }
}
return effects;
}
@@ -1580,7 +1608,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
case OP_TYPE_REORDER_TO_BOTTOM_OF_TASK: {
final Task task = taskFragment.getTask();
if (task != null) {
- if (task.mChildren.peekFirst() != taskFragment) {
+ if (task.getBottomChild() != taskFragment) {
task.mChildren.remove(taskFragment);
task.mChildren.add(0, taskFragment);
if (!taskFragment.hasChild()) {
@@ -1596,7 +1624,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
case OP_TYPE_REORDER_TO_TOP_OF_TASK: {
final Task task = taskFragment.getTask();
if (task != null) {
- if (task.mChildren.peekLast() != taskFragment) {
+ if (task.getTopChild() != taskFragment) {
task.mChildren.remove(taskFragment);
task.mChildren.add(taskFragment);
if (!taskFragment.hasChild()) {
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 60d3e787cac4..bbd9c0a820ef 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -1655,6 +1655,22 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
// Otherwise if other places send wpc.getConfiguration() to client, the configuration may
// be ignored due to the seq is older.
resolvedConfig.seq = newParentConfig.seq;
+
+ if (mConfigActivityRecord != null) {
+ // Let the activity decide whether to apply the size override.
+ return;
+ }
+ final DisplayContent displayContent = mAtm.mWindowManager != null
+ ? mAtm.mWindowManager.getDefaultDisplayContentLocked()
+ : null;
+ applySizeOverrideIfNeeded(
+ displayContent,
+ mInfo,
+ newParentConfig,
+ resolvedConfig,
+ false /* optOutEdgeToEdge */,
+ false /* hasFixedRotationTransform */,
+ false /* hasCompatDisplayInsets */);
}
void dispatchConfiguration(@NonNull Configuration config) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index fec1175785ea..9ebb89dfe9b6 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -28,6 +28,7 @@ import static android.graphics.GraphicsProtos.dumpPointProto;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import static android.os.PowerManager.DRAW_WAKE_LOCK;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.util.SequenceUtils.getNextSeq;
import static android.view.SurfaceControl.Transaction;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
@@ -96,8 +97,8 @@ import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_MULTIPLIER;
import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET;
-import static android.util.SequenceUtils.getNextSeq;
+import static com.android.input.flags.Flags.removeInputChannelFromWindowstate;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ANIM;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
@@ -249,8 +250,8 @@ import android.window.OnBackInvokedCallbackInfo;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.KeyInterceptionInfo;
-import com.android.internal.protolog.common.LogLevel;
import com.android.internal.protolog.ProtoLog;
+import com.android.internal.protolog.common.LogLevel;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.policy.WindowManagerPolicy;
@@ -633,6 +634,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// Input channel and input window handle used by the input dispatcher.
final InputWindowHandleWrapper mInputWindowHandle;
+ /**
+ * Only populated if flag REMOVE_INPUT_CHANNEL_FROM_WINDOWSTATE is disabled.
+ */
InputChannel mInputChannel;
/**
@@ -1101,7 +1105,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mPolicy = mWmService.mPolicy;
mContext = mWmService.mContext;
mForceSeamlesslyRotate = token.mRoundedCornerOverlay;
- mLastReportedActivityWindowInfo = Flags.activityWindowInfoFlag() && mActivityRecord != null
+ mLastReportedActivityWindowInfo = mActivityRecord != null
? new ActivityWindowInfo()
: null;
mInputWindowHandle = new InputWindowHandleWrapper(new InputWindowHandle(
@@ -1497,7 +1501,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (isDrawn()) {
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Orientation not waiting for draw in %s, surfaceController %s", this,
- winAnimator.mSurfaceController);
+ winAnimator.mSurfaceControl);
setOrientationChanging(false);
mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
- mWmService.mDisplayFreezeTime);
@@ -1877,6 +1881,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
* Input Manager uses when discarding windows from input consideration.
*/
boolean isPotentialDragTarget(boolean targetInterceptsGlobalDrag) {
+ if (removeInputChannelFromWindowstate()) {
+ return (targetInterceptsGlobalDrag || isVisibleNow()) && !mRemoved
+ && mInputChannelToken != null && mInputWindowHandle != null;
+ }
return (targetInterceptsGlobalDrag || isVisibleNow()) && !mRemoved
&& mInputChannel != null && mInputWindowHandle != null;
}
@@ -1976,8 +1984,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
*/
boolean isReadyForDisplay() {
final boolean parentAndClientVisible = !isParentWindowHidden()
- && mViewVisibility == View.VISIBLE && mToken.isVisible();
- return mHasSurface && isVisibleByPolicy() && !mDestroying
+ && mViewVisibility == View.VISIBLE;
+ return mHasSurface && isVisibleByPolicy() && !mDestroying && mToken.isVisible()
&& (parentAndClientVisible || isAnimating(TRANSITION | PARENTS));
}
@@ -2417,7 +2425,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
ProtoLog.v(WM_DEBUG_FOCUS, "Remove client=%x, surfaceController=%s Callers=%s",
System.identityHashCode(mClient.asBinder()),
- mWinAnimator.mSurfaceController,
+ mWinAnimator.mSurfaceControl,
Debug.getCallers(5));
final DisplayContent displayContent = getDisplayContent();
@@ -2428,10 +2436,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mOnBackInvokedCallbackInfo = null;
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
- "Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b "
+ "Remove %s: mSurfaceControl=%s mAnimatingExit=%b mRemoveOnExit=%b "
+ "mHasSurface=%b surfaceShowing=%b animating=%b app-animation=%b "
+ "mDisplayFrozen=%b callers=%s",
- this, mWinAnimator.mSurfaceController, mAnimatingExit, mRemoveOnExit,
+ this, mWinAnimator.mSurfaceControl, mAnimatingExit, mRemoveOnExit,
mHasSurface, mWinAnimator.getShown(),
isAnimating(TRANSITION | PARENTS),
mActivityRecord != null && mActivityRecord.isAnimating(PARENTS | TRANSITION),
@@ -2608,7 +2616,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
+ isVisibleRequestedOrAdding() + " isVisible: " + (isVisible()
&& mActivityRecord != null && mActivityRecord.isVisible()));
if (!isVisibleRequestedOrAdding()) {
- Slog.i(TAG_WM, " mSurfaceController=" + mWinAnimator.mSurfaceController
+ Slog.i(TAG_WM, " mSurfaceControl=" + mWinAnimator.mSurfaceControl
+ " relayoutCalled=" + mRelayoutCalled
+ " viewVis=" + mViewVisibility
+ " policyVis=" + isVisibleByPolicy()
@@ -2626,6 +2634,19 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
void openInputChannel(@NonNull InputChannel outInputChannel) {
+ if (mInputChannelToken != null) {
+ throw new IllegalStateException("Window already has an input channel token.");
+ }
+ if (removeInputChannelFromWindowstate()) {
+ String name = getName();
+ InputChannel channel = mWmService.mInputManager.createInputChannel(name);
+ mInputChannelToken = channel.getToken();
+ mInputWindowHandle.setToken(mInputChannelToken);
+ mWmService.mInputToWindowMap.put(mInputChannelToken, this);
+ channel.copyTo(outInputChannel);
+ channel.dispose();
+ return;
+ }
if (mInputChannel != null) {
throw new IllegalStateException("Window already has an input channel.");
}
@@ -2657,9 +2678,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mInputChannelToken = null;
}
- if (mInputChannel != null) {
- mInputChannel.dispose();
- mInputChannel = null;
+ if (!removeInputChannelFromWindowstate()) {
+ if (mInputChannel != null) {
+ mInputChannel.dispose();
+ mInputChannel = null;
+ }
}
mInputWindowHandle.setToken(null);
}
@@ -4434,7 +4457,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowState c = mChildren.get(i);
- if (c.mWinAnimator.mSurfaceController != null) {
+ if (c.mWinAnimator.mSurfaceControl != null) {
c.performShowLocked();
// It hadn't been shown, which means layout not performed on it, so now we
// want to make sure to do a layout. If called from within the transaction
@@ -4891,7 +4914,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
Slog.v(TAG, "Win " + this + ": isDrawn=" + isDrawn()
+ ", animating=" + isAnimating(TRANSITION | PARENTS));
if (!isDrawn()) {
- Slog.v(TAG, "Not displayed: s=" + mWinAnimator.mSurfaceController
+ Slog.v(TAG, "Not displayed: s=" + mWinAnimator.mSurfaceControl
+ " pv=" + isVisibleByPolicy()
+ " mDrawState=" + mWinAnimator.mDrawState
+ " ph=" + isParentWindowHidden()
@@ -5512,13 +5535,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// been defined and so we can use static layers and leave it that way.
if (w.mAttrs.type == TYPE_APPLICATION_MEDIA) {
if (mWinAnimator.hasSurface()) {
- w.assignRelativeLayer(t, mWinAnimator.mSurfaceController.mSurfaceControl, -2);
+ w.assignRelativeLayer(t, mWinAnimator.mSurfaceControl, -2);
} else {
w.assignLayer(t, -2);
}
} else if (w.mAttrs.type == TYPE_APPLICATION_MEDIA_OVERLAY) {
if (mWinAnimator.hasSurface()) {
- w.assignRelativeLayer(t, mWinAnimator.mSurfaceController.mSurfaceControl, -1);
+ w.assignRelativeLayer(t, mWinAnimator.mSurfaceControl, -1);
} else {
w.assignLayer(t, -1);
}
@@ -5694,7 +5717,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
SurfaceControl getClientViewRootSurface() {
- return mWinAnimator.getSurfaceControl();
+ return mWinAnimator.mSurfaceControl;
}
/** Drops a buffer for this window's view-root from a transaction */
@@ -6094,11 +6117,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
getPendingTransaction().setSecure(mSurfaceControl, isSecure);
} else {
- if (mWinAnimator.mSurfaceController == null
- || mWinAnimator.mSurfaceController.mSurfaceControl == null) {
+ if (mWinAnimator.mSurfaceControl == null) {
return;
}
- getPendingTransaction().setSecure(mWinAnimator.mSurfaceController.mSurfaceControl,
+ getPendingTransaction().setSecure(mWinAnimator.mSurfaceControl,
isSecure);
}
if (mDisplayContent != null) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 397a6357fb66..24a2a626fe50 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -16,6 +16,10 @@
package com.android.server.wm;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.view.SurfaceControl.METADATA_OWNER_PID;
+import static android.view.SurfaceControl.METADATA_OWNER_UID;
+import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -44,6 +48,7 @@ import static com.android.server.wm.WindowManagerService.logWithStack;
import static com.android.server.wm.WindowStateAnimatorProto.DRAW_STATE;
import static com.android.server.wm.WindowStateAnimatorProto.SURFACE;
import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT;
+import static com.android.server.wm.WindowSurfaceControllerProto.SHOWN;
import static com.android.window.flags.Flags.secureWindowState;
import static com.android.window.flags.Flags.setScPropertiesInClient;
@@ -52,6 +57,7 @@ import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Debug;
import android.os.Trace;
+import android.util.EventLog;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.Surface.OutOfResourcesException;
@@ -95,12 +101,13 @@ class WindowStateAnimator {
final Session mSession;
final WindowManagerPolicy mPolicy;
final Context mContext;
- final boolean mIsWallpaper;
private final WallpaperController mWallpaperControllerLocked;
boolean mAnimationIsEntrance;
- WindowSurfaceController mSurfaceController;
+ SurfaceControl mSurfaceControl;
+ private boolean mSurfaceShown;
+ private String mTitle;
float mShownAlpha = 0;
float mAlpha = 0;
@@ -164,7 +171,6 @@ class WindowStateAnimator {
mWin = win;
mSession = win.mSession;
mAttrType = win.mAttrs.type;
- mIsWallpaper = win.mIsWallpaper;
mWallpaperControllerLocked = win.getDisplayContent().mWallpaperController;
}
@@ -198,16 +204,32 @@ class WindowStateAnimator {
}
void hide(SurfaceControl.Transaction transaction, String reason) {
- if (!mLastHidden) {
- //dump();
- mLastHidden = true;
+ if (mLastHidden) {
+ return;
+ }
+ mLastHidden = true;
+ if (mSurfaceControl == null || !mSurfaceShown) {
+ return;
+ }
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE HIDE ( %s ): %s", reason, mTitle);
- if (mSurfaceController != null) {
- mSurfaceController.hide(transaction, reason);
- }
+ setShown(false);
+ transaction.hide(mSurfaceControl);
+ if (mWin.mIsWallpaper) {
+ final DisplayContent dc = mWin.getDisplayContent();
+ EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE,
+ dc.mDisplayId, 0 /* request hidden */,
+ String.valueOf(dc.mWallpaperController.getWallpaperTarget()));
}
}
+ private void setShown(boolean surfaceShown) {
+ mSurfaceShown = surfaceShown;
+ mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mWin, surfaceShown);
+ mWin.onSurfaceShownChanged(surfaceShown);
+ mSession.onWindowSurfaceVisibilityChanged(mWin, mSurfaceShown);
+ }
+
boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) {
final boolean startingWindow =
mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -221,7 +243,7 @@ class WindowStateAnimator {
if (mDrawState == DRAW_PENDING) {
ProtoLog.v(WM_DEBUG_DRAW,
"finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", mWin,
- mSurfaceController);
+ mSurfaceControl);
if (startingWindow) {
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Draw state now committed in %s", mWin);
}
@@ -248,7 +270,7 @@ class WindowStateAnimator {
return false;
}
ProtoLog.i(WM_DEBUG_ANIM, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW %s",
- mSurfaceController);
+ mSurfaceControl);
mDrawState = READY_TO_SHOW;
boolean result = false;
final ActivityRecord activity = mWin.mActivityRecord;
@@ -271,11 +293,11 @@ class WindowStateAnimator {
}
}
- WindowSurfaceController createSurfaceLocked() {
+ SurfaceControl createSurfaceLocked() {
final WindowState w = mWin;
- if (mSurfaceController != null) {
- return mSurfaceController;
+ if (mSurfaceControl != null) {
+ return mSurfaceControl;
}
w.setHasSurface(false);
@@ -312,10 +334,22 @@ class WindowStateAnimator {
final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
- mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format,
- flags, this, attrs.type);
+ mTitle = attrs.getTitle().toString();
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
+ mSurfaceControl = mWin.makeSurface()
+ .setParent(mWin.mSurfaceControl)
+ .setName(mTitle)
+ .setFormat(format)
+ .setFlags(flags)
+ .setMetadata(METADATA_WINDOW_TYPE, attrs.type)
+ .setMetadata(METADATA_OWNER_UID, mSession.mUid)
+ .setMetadata(METADATA_OWNER_PID, mSession.mPid)
+ .setCallsite("WindowSurfaceController")
+ .setBLASTLayer().build();
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+
if (!setScPropertiesInClient()) {
- mSurfaceController.setColorSpaceAgnostic(w.getPendingTransaction(),
+ setColorSpaceAgnosticLocked(
(attrs.privateFlags & LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);
}
@@ -326,7 +360,7 @@ class WindowStateAnimator {
ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
" CREATE SURFACE %s IN SESSION %s: pid=%d format=%d flags=0x%x / %s",
- mSurfaceController, mSession.mSurfaceSession, mSession.mPid, attrs.format,
+ mSurfaceControl, mSession.mSurfaceSession, mSession.mPid, attrs.format,
flags, this);
} catch (OutOfResourcesException e) {
Slog.w(TAG, "OutOfResourcesException creating surface");
@@ -340,7 +374,7 @@ class WindowStateAnimator {
}
if (DEBUG) {
- Slog.v(TAG, "Got surface: " + mSurfaceController
+ Slog.v(TAG, "Got surface: " + mSurfaceControl
+ ", set left=" + w.getFrame().left + " top=" + w.getFrame().top);
}
@@ -353,15 +387,19 @@ class WindowStateAnimator {
mLastHidden = true;
if (DEBUG) Slog.v(TAG, "Created surface " + this);
- return mSurfaceController;
+ return mSurfaceControl;
}
boolean hasSurface() {
- return mSurfaceController != null && mSurfaceController.hasSurface();
+ return mSurfaceControl != null;
+ }
+
+ void getSurfaceControl(SurfaceControl outSurfaceControl) {
+ outSurfaceControl.copyFrom(mSurfaceControl, "WindowStateAnimator.getSurfaceControl");
}
void destroySurfaceLocked(SurfaceControl.Transaction t) {
- if (mSurfaceController == null) {
+ if (mSurfaceControl == null) {
return;
}
@@ -370,7 +408,7 @@ class WindowStateAnimator {
try {
if (DEBUG_VISIBILITY) {
logWithStack(TAG, "Window " + this + " destroying surface "
- + mSurfaceController + ", session " + mSession);
+ + mSurfaceControl + ", session " + mSession);
}
ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY: %s. %s",
mWin, new RuntimeException().fillInStackTrace());
@@ -384,23 +422,13 @@ class WindowStateAnimator {
}
} catch (RuntimeException e) {
Slog.w(TAG, "Exception thrown when destroying Window " + this
- + " surface " + mSurfaceController + " session " + mSession + ": "
+ + " surface " + mSurfaceControl + " session " + mSession + ": "
+ e.toString());
}
-
- // Whether the surface was preserved (and copied to mPendingDestroySurface) or not, it
- // needs to be cleared to match the WindowState.mHasSurface state. It is also necessary
- // so it can be recreated successfully in mPendingDestroySurface case.
- mWin.setHasSurface(false);
- if (mSurfaceController != null) {
- mSurfaceController.setShown(false);
- }
- mSurfaceController = null;
- mDrawState = NO_SURFACE;
}
void computeShownFrameLocked() {
- if (mIsWallpaper && mService.mRoot.mWallpaperActionPending) {
+ if (mWin.mIsWallpaper && mService.mRoot.mWallpaperActionPending) {
return;
} else if (mWin.isDragResizeChanged()) {
// This window is awaiting a relayout because user just started (or ended)
@@ -454,14 +482,13 @@ class WindowStateAnimator {
mLastAlpha = mShownAlpha;
ProtoLog.i(WM_SHOW_TRANSACTIONS,
"SURFACE controller=%s alpha=%f HScale=%f, VScale=%f: %s",
- mSurfaceController, mShownAlpha, w.mHScale, w.mVScale, w);
+ mSurfaceControl, mShownAlpha, w.mHScale, w.mVScale, w);
- boolean prepared =
- mSurfaceController.prepareToShowInTransaction(t, mShownAlpha);
+ t.setAlpha(mSurfaceControl, mShownAlpha);
- if (prepared && mDrawState == HAS_DRAWN) {
+ if (mDrawState == HAS_DRAWN) {
if (mLastHidden) {
- mSurfaceController.showRobustly(t);
+ showRobustly(t);
mLastHidden = false;
final DisplayContent displayContent = w.getDisplayContent();
if (!displayContent.getLastHasContent()) {
@@ -494,18 +521,38 @@ class WindowStateAnimator {
}
}
+ private void showRobustly(SurfaceControl.Transaction t) {
+ if (mSurfaceShown) {
+ return;
+ }
+
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SHOW (performLayout): %s", mTitle);
+ if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this + " during relayout");
+ setShown(true);
+ t.show(mSurfaceControl);
+ if (mWin.mIsWallpaper) {
+ final DisplayContent dc = mWin.mDisplayContent;
+ EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE,
+ dc.mDisplayId, 1 /* request shown */,
+ String.valueOf(dc.mWallpaperController.getWallpaperTarget()));
+ }
+ }
+
void setOpaqueLocked(boolean isOpaque) {
- if (mSurfaceController == null) {
+ if (mSurfaceControl == null) {
return;
}
- mSurfaceController.setOpaque(isOpaque);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isOpaque=%b: %s", isOpaque, mTitle);
+ mWin.getPendingTransaction().setOpaque(mSurfaceControl, isOpaque);
+ mService.scheduleAnimationLocked();
}
void setColorSpaceAgnosticLocked(boolean agnostic) {
- if (mSurfaceController == null) {
+ if (mSurfaceControl == null) {
return;
}
- mSurfaceController.setColorSpaceAgnostic(mWin.getPendingTransaction(), agnostic);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isColorSpaceAgnostic=%b: %s", agnostic, mTitle);
+ mWin.getPendingTransaction().setColorSpaceAgnostic(mSurfaceControl, agnostic);
}
void applyEnterAnimationLocked() {
@@ -521,7 +568,7 @@ class WindowStateAnimator {
// should be controlled by ActivityRecord in general. Wallpaper is also excluded because
// WallpaperController should handle it. Also skip play enter animation for the window
// below starting window.
- if (mAttrType != TYPE_BASE_APPLICATION && !mIsWallpaper
+ if (mAttrType != TYPE_BASE_APPLICATION && !mWin.mIsWallpaper
&& !(mWin.mActivityRecord != null && mWin.mActivityRecord.hasStartingWindow())) {
applyAnimationLocked(transit, true);
}
@@ -614,8 +661,10 @@ class WindowStateAnimator {
void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- if (mSurfaceController != null) {
- mSurfaceController.dumpDebug(proto, SURFACE);
+ if (mSurfaceControl != null) {
+ final long dumpToken = proto.start(SURFACE);
+ proto.write(SHOWN, mSurfaceShown);
+ proto.end(dumpToken);
}
proto.write(DRAW_STATE, mDrawState);
mSystemDecorRect.dumpDebug(proto, SYSTEM_DECOR_RECT);
@@ -626,8 +675,11 @@ class WindowStateAnimator {
if (mAnimationIsEntrance) {
pw.print(prefix); pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
}
- if (mSurfaceController != null) {
- mSurfaceController.dump(pw, prefix, dumpAll);
+ if (mSurfaceControl != null) {
+ if (dumpAll) {
+ pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
+ }
+ pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
}
if (dumpAll) {
pw.print(prefix); pw.print("mDrawState="); pw.print(drawStateToString());
@@ -659,31 +711,24 @@ class WindowStateAnimator {
}
boolean getShown() {
- if (mSurfaceController != null) {
- return mSurfaceController.getShown();
- }
- return false;
+ return mSurfaceControl != null && mSurfaceShown;
}
void destroySurface(SurfaceControl.Transaction t) {
- try {
- if (mSurfaceController != null) {
- mSurfaceController.destroy(t);
- }
- } catch (RuntimeException e) {
- Slog.w(TAG, "Exception thrown when destroying surface " + this
- + " surface " + mSurfaceController + " session " + mSession + ": " + e);
- } finally {
- mWin.setHasSurface(false);
- mSurfaceController = null;
- mDrawState = NO_SURFACE;
+ if (mSurfaceControl == null) {
+ return;
}
- }
-
- SurfaceControl getSurfaceControl() {
- if (!hasSurface()) {
- return null;
+ ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
+ "Destroying surface %s called by %s", this, Debug.getCallers(8));
+ if (mWin.mIsWallpaper && !mWin.mWindowRemovalAllowed && !mWin.mRemoveOnExit) {
+ // The wallpaper surface should have the same lifetime as its window.
+ Slog.e(TAG, "Unexpected removing wallpaper surface of " + mWin
+ + " by " + Debug.getCallers(8));
}
- return mSurfaceController.mSurfaceControl;
+ t.remove(mSurfaceControl);
+ setShown(false);
+ mSurfaceControl = null;
+ mWin.setHasSurface(false);
+ mDrawState = NO_SURFACE;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
deleted file mode 100644
index d9766e0dfa61..000000000000
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.view.SurfaceControl.METADATA_OWNER_PID;
-import static android.view.SurfaceControl.METADATA_OWNER_UID;
-import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
-
-import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
-import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
-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.WindowSurfaceControllerProto.SHOWN;
-
-import android.os.Debug;
-import android.os.Trace;
-import android.util.EventLog;
-import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
-import android.view.SurfaceControl;
-import android.view.WindowContentFrameStats;
-
-import com.android.internal.protolog.ProtoLog;
-
-import java.io.PrintWriter;
-
-class WindowSurfaceController {
- static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfaceController" : TAG_WM;
-
- final WindowStateAnimator mAnimator;
-
- SurfaceControl mSurfaceControl;
-
- // Should only be set from within setShown().
- private boolean mSurfaceShown = false;
-
- private final String title;
-
- private final WindowManagerService mService;
-
- private final int mWindowType;
- private final Session mWindowSession;
-
-
- WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator,
- int windowType) {
- mAnimator = animator;
-
- title = name;
-
- mService = animator.mService;
- final WindowState win = animator.mWin;
- mWindowType = windowType;
- mWindowSession = win.mSession;
-
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
- mSurfaceControl = win.makeSurface()
- .setParent(win.getSurfaceControl())
- .setName(name)
- .setFormat(format)
- .setFlags(flags)
- .setMetadata(METADATA_WINDOW_TYPE, windowType)
- .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid)
- .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
- .setCallsite("WindowSurfaceController")
- .setBLASTLayer().build();
-
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- }
-
- void hide(SurfaceControl.Transaction transaction, String reason) {
- ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE HIDE ( %s ): %s", reason, title);
-
- if (mSurfaceShown) {
- hideSurface(transaction);
- }
- }
-
- private void hideSurface(SurfaceControl.Transaction transaction) {
- if (mSurfaceControl == null) {
- return;
- }
- setShown(false);
- try {
- transaction.hide(mSurfaceControl);
- if (mAnimator.mIsWallpaper) {
- final DisplayContent dc = mAnimator.mWin.getDisplayContent();
- EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE,
- dc.mDisplayId, 0 /* request hidden */,
- String.valueOf(dc.mWallpaperController.getWallpaperTarget()));
- }
- } catch (RuntimeException e) {
- Slog.w(TAG, "Exception hiding surface in " + this);
- }
- }
-
- void destroy(SurfaceControl.Transaction t) {
- ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
- "Destroying surface %s called by %s", this, Debug.getCallers(8));
- try {
- if (mSurfaceControl != null) {
- if (mAnimator.mIsWallpaper && !mAnimator.mWin.mWindowRemovalAllowed
- && !mAnimator.mWin.mRemoveOnExit) {
- // The wallpaper surface should have the same lifetime as its window.
- Slog.e(TAG, "Unexpected removing wallpaper surface of " + mAnimator.mWin
- + " by " + Debug.getCallers(8));
- }
- t.remove(mSurfaceControl);
- }
- } catch (RuntimeException e) {
- Slog.w(TAG, "Error destroying surface in: " + this, e);
- } finally {
- setShown(false);
- mSurfaceControl = null;
- }
- }
-
- boolean prepareToShowInTransaction(SurfaceControl.Transaction t, float alpha) {
- if (mSurfaceControl == null) {
- return false;
- }
-
- t.setAlpha(mSurfaceControl, alpha);
- return true;
- }
-
- void setOpaque(boolean isOpaque) {
- ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isOpaque=%b: %s", isOpaque, title);
-
- if (mSurfaceControl == null) {
- return;
- }
-
- mAnimator.mWin.getPendingTransaction().setOpaque(mSurfaceControl, isOpaque);
- mService.scheduleAnimationLocked();
- }
-
- void setColorSpaceAgnostic(SurfaceControl.Transaction t, boolean agnostic) {
- ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isColorSpaceAgnostic=%b: %s", agnostic, title);
-
- if (mSurfaceControl == null) {
- return;
- }
- t.setColorSpaceAgnostic(mSurfaceControl, agnostic);
- }
-
- void showRobustly(SurfaceControl.Transaction t) {
- ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SHOW (performLayout): %s", title);
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
- + " during relayout");
-
- if (mSurfaceShown) {
- return;
- }
-
- setShown(true);
- t.show(mSurfaceControl);
- if (mAnimator.mIsWallpaper) {
- final DisplayContent dc = mAnimator.mWin.getDisplayContent();
- EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE,
- dc.mDisplayId, 1 /* request shown */,
- String.valueOf(dc.mWallpaperController.getWallpaperTarget()));
- }
- }
-
- boolean clearWindowContentFrameStats() {
- if (mSurfaceControl == null) {
- return false;
- }
- return mSurfaceControl.clearContentFrameStats();
- }
-
- boolean getWindowContentFrameStats(WindowContentFrameStats outStats) {
- if (mSurfaceControl == null) {
- return false;
- }
- return mSurfaceControl.getContentFrameStats(outStats);
- }
-
- boolean hasSurface() {
- return mSurfaceControl != null;
- }
-
- void getSurfaceControl(SurfaceControl outSurfaceControl) {
- outSurfaceControl.copyFrom(mSurfaceControl, "WindowSurfaceController.getSurfaceControl");
- }
-
- boolean getShown() {
- return mSurfaceShown;
- }
-
- void setShown(boolean surfaceShown) {
- mSurfaceShown = surfaceShown;
-
- mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mAnimator.mWin, surfaceShown);
-
- mAnimator.mWin.onSurfaceShownChanged(surfaceShown);
-
- if (mWindowSession != null) {
- mWindowSession.onWindowSurfaceVisibilityChanged(this, mSurfaceShown, mWindowType);
- }
- }
-
- void dumpDebug(ProtoOutputStream proto, long fieldId) {
- final long token = proto.start(fieldId);
- proto.write(SHOWN, mSurfaceShown);
- proto.end(token);
- }
-
- public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
- if (dumpAll) {
- pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
- }
- pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
- }
-
- @Override
- public String toString() {
- return mSurfaceControl.toString();
- }
-}
diff --git a/services/core/java/com/android/server/wm/WindowTracing.java b/services/core/java/com/android/server/wm/WindowTracing.java
index ba5323ee1f8f..21f7eca5627a 100644
--- a/services/core/java/com/android/server/wm/WindowTracing.java
+++ b/services/core/java/com/android/server/wm/WindowTracing.java
@@ -18,89 +18,52 @@ package com.android.server.wm;
import static android.os.Build.IS_USER;
-import static com.android.server.wm.WindowManagerTraceFileProto.ENTRY;
-import static com.android.server.wm.WindowManagerTraceFileProto.MAGIC_NUMBER;
-import static com.android.server.wm.WindowManagerTraceFileProto.MAGIC_NUMBER_H;
-import static com.android.server.wm.WindowManagerTraceFileProto.MAGIC_NUMBER_L;
-import static com.android.server.wm.WindowManagerTraceFileProto.REAL_TO_ELAPSED_TIME_OFFSET_NANOS;
import static com.android.server.wm.WindowManagerTraceProto.ELAPSED_REALTIME_NANOS;
import static com.android.server.wm.WindowManagerTraceProto.WHERE;
import static com.android.server.wm.WindowManagerTraceProto.WINDOW_MANAGER_SERVICE;
import android.annotation.Nullable;
import android.os.ShellCommand;
-import android.os.SystemClock;
import android.os.Trace;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
import android.view.Choreographer;
import com.android.internal.protolog.LegacyProtoLogImpl;
-import com.android.internal.protolog.common.IProtoLog;
import com.android.internal.protolog.ProtoLog;
-import com.android.internal.util.TraceBuffer;
-import java.io.File;
-import java.io.IOException;
import java.io.PrintWriter;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
- * A class that allows window manager to dump its state continuously to a trace file, such that a
+ * A class that allows window manager to dump its state continuously, such that a
* time series of window manager state can be analyzed after the fact.
*/
-class WindowTracing {
-
- /**
- * Maximum buffer size, currently defined as 5 MB
- * Size was experimentally defined to fit between 100 to 150 elements.
- */
- private static final int BUFFER_CAPACITY_CRITICAL = 5120 * 1024; // 5 MB
- private static final int BUFFER_CAPACITY_TRIM = 10240 * 1024; // 10 MB
- private static final int BUFFER_CAPACITY_ALL = 20480 * 1024; // 20 MB
- static final String WINSCOPE_EXT = ".winscope";
- private static final String TRACE_FILENAME = "/data/misc/wmtrace/wm_trace" + WINSCOPE_EXT;
- private static final String TAG = "WindowTracing";
- private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;
+abstract class WindowTracing {
+ protected static final String TAG = "WindowTracing";
+ protected static final String WHERE_START_TRACING = "trace.enable";
+ protected static final String WHERE_ON_FRAME = "onFrame";
private final WindowManagerService mService;
private final Choreographer mChoreographer;
private final WindowManagerGlobalLock mGlobalLock;
- private final Object mEnabledLock = new Object();
- private final File mTraceFile;
- private final TraceBuffer mBuffer;
private final Choreographer.FrameCallback mFrameCallback = (frameTimeNanos) ->
- log("onFrame" /* where */);
+ log(WHERE_ON_FRAME);
- private @WindowTraceLogLevel int mLogLevel = WindowTraceLogLevel.TRIM;
- private boolean mLogOnFrame = false;
- private boolean mEnabled;
- private volatile boolean mEnabledLockFree;
- private boolean mScheduled;
+ private AtomicBoolean mScheduled = new AtomicBoolean(false);
- private final IProtoLog mProtoLog;
static WindowTracing createDefaultAndStartLooper(WindowManagerService service,
Choreographer choreographer) {
- File file = new File(TRACE_FILENAME);
- return new WindowTracing(file, service, choreographer, BUFFER_CAPACITY_TRIM);
+ return new WindowTracingLegacy(service, choreographer);
}
- private WindowTracing(File file, WindowManagerService service, Choreographer choreographer,
- int bufferCapacity) {
- this(file, service, choreographer, service.mGlobalLock, bufferCapacity);
- }
-
- WindowTracing(File file, WindowManagerService service, Choreographer choreographer,
- WindowManagerGlobalLock globalLock, int bufferCapacity) {
+ protected WindowTracing(WindowManagerService service, Choreographer choreographer,
+ WindowManagerGlobalLock globalLock) {
mChoreographer = choreographer;
mService = service;
mGlobalLock = globalLock;
- mTraceFile = file;
- mBuffer = new TraceBuffer(bufferCapacity);
- setLogLevel(WindowTraceLogLevel.TRIM, null /* pw */);
- mProtoLog = ProtoLog.getSingleInstance();
}
void startTrace(@Nullable PrintWriter pw) {
@@ -108,44 +71,29 @@ class WindowTracing {
logAndPrintln(pw, "Error: Tracing is not supported on user builds.");
return;
}
- synchronized (mEnabledLock) {
- if (!android.tracing.Flags.perfettoProtologTracing()) {
- ((LegacyProtoLogImpl) ProtoLog.getSingleInstance()).startProtoLog(pw);
- }
- logAndPrintln(pw, "Start tracing to " + mTraceFile + ".");
- mBuffer.resetBuffer();
- mEnabled = mEnabledLockFree = true;
+ if (!android.tracing.Flags.perfettoProtologTracing()) {
+ ((LegacyProtoLogImpl) ProtoLog.getSingleInstance()).startProtoLog(pw);
}
- log("trace.enable");
+ startTraceInternal(pw);
}
- /**
- * Stops the trace and write the current buffer to disk
- * @param pw Print writer
- */
void stopTrace(@Nullable PrintWriter pw) {
if (IS_USER) {
logAndPrintln(pw, "Error: Tracing is not supported on user builds.");
return;
}
- synchronized (mEnabledLock) {
- logAndPrintln(pw, "Stop tracing to " + mTraceFile + ". Waiting for traces to flush.");
- mEnabled = mEnabledLockFree = false;
-
- if (mEnabled) {
- logAndPrintln(pw, "ERROR: tracing was re-enabled while waiting for flush.");
- throw new IllegalStateException("tracing enabled while waiting for flush.");
- }
- writeTraceToFileLocked();
- logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
- }
if (!android.tracing.Flags.perfettoProtologTracing()) {
((LegacyProtoLogImpl) ProtoLog.getSingleInstance()).stopProtoLog(pw, true);
}
+ stopTraceInternal(pw);
}
/**
- * Stops the trace and write the current buffer to disk then restart, if it's already running.
+ * If legacy tracing is enabled (either WM or ProtoLog):
+ * 1. Stop tracing
+ * 2. Write trace to disk (to be picked by dumpstate)
+ * 3. Restart tracing
+ *
* @param pw Print writer
*/
void saveForBugreport(@Nullable PrintWriter pw) {
@@ -153,143 +101,24 @@ class WindowTracing {
logAndPrintln(pw, "Error: Tracing is not supported on user builds.");
return;
}
- synchronized (mEnabledLock) {
- if (!mEnabled) {
- return;
- }
- mEnabled = mEnabledLockFree = false;
- logAndPrintln(pw, "Stop tracing to " + mTraceFile + ". Waiting for traces to flush.");
- writeTraceToFileLocked();
- logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
- if (!android.tracing.Flags.perfettoProtologTracing()) {
- ((LegacyProtoLogImpl) mProtoLog).stopProtoLog(pw, true);
- }
- logAndPrintln(pw, "Start tracing to " + mTraceFile + ".");
- mBuffer.resetBuffer();
- mEnabled = mEnabledLockFree = true;
- if (!android.tracing.Flags.perfettoProtologTracing()) {
- ((LegacyProtoLogImpl) mProtoLog).startProtoLog(pw);
- }
- }
- }
-
- private void setLogLevel(@WindowTraceLogLevel int logLevel, PrintWriter pw) {
- logAndPrintln(pw, "Setting window tracing log level to " + logLevel);
- mLogLevel = logLevel;
-
- switch (logLevel) {
- case WindowTraceLogLevel.ALL: {
- setBufferCapacity(BUFFER_CAPACITY_ALL, pw);
- break;
- }
- case WindowTraceLogLevel.TRIM: {
- setBufferCapacity(BUFFER_CAPACITY_TRIM, pw);
- break;
- }
- case WindowTraceLogLevel.CRITICAL: {
- setBufferCapacity(BUFFER_CAPACITY_CRITICAL, pw);
- break;
- }
- }
- }
-
- private void setLogFrequency(boolean onFrame, PrintWriter pw) {
- logAndPrintln(pw, "Setting window tracing log frequency to "
- + ((onFrame) ? "frame" : "transaction"));
- mLogOnFrame = onFrame;
- }
-
- private void setBufferCapacity(int capacity, PrintWriter pw) {
- logAndPrintln(pw, "Setting window tracing buffer capacity to " + capacity + "bytes");
- mBuffer.setCapacity(capacity);
- }
-
- boolean isEnabled() {
- return mEnabledLockFree;
- }
-
- int onShellCommand(ShellCommand shell) {
- PrintWriter pw = shell.getOutPrintWriter();
- String cmd = shell.getNextArgRequired();
- switch (cmd) {
- case "start":
- startTrace(pw);
- return 0;
- case "stop":
- stopTrace(pw);
- return 0;
- case "save-for-bugreport":
- saveForBugreport(pw);
- return 0;
- case "status":
- logAndPrintln(pw, getStatus());
- return 0;
- case "frame":
- setLogFrequency(true /* onFrame */, pw);
- mBuffer.resetBuffer();
- return 0;
- case "transaction":
- setLogFrequency(false /* onFrame */, pw);
- mBuffer.resetBuffer();
- return 0;
- case "level":
- String logLevelStr = shell.getNextArgRequired().toLowerCase();
- switch (logLevelStr) {
- case "all": {
- setLogLevel(WindowTraceLogLevel.ALL, pw);
- break;
- }
- case "trim": {
- setLogLevel(WindowTraceLogLevel.TRIM, pw);
- break;
- }
- case "critical": {
- setLogLevel(WindowTraceLogLevel.CRITICAL, pw);
- break;
- }
- default: {
- setLogLevel(WindowTraceLogLevel.TRIM, pw);
- break;
- }
- }
- mBuffer.resetBuffer();
- return 0;
- case "size":
- setBufferCapacity(Integer.parseInt(shell.getNextArgRequired()) * 1024, pw);
- mBuffer.resetBuffer();
- return 0;
- default:
- pw.println("Unknown command: " + cmd);
- pw.println("Window manager trace options:");
- pw.println(" start: Start logging");
- pw.println(" stop: Stop logging");
- pw.println(" save-for-bugreport: Save logging data to file if it's running.");
- pw.println(" frame: Log trace once per frame");
- pw.println(" transaction: Log each transaction");
- pw.println(" size: Set the maximum log size (in KB)");
- pw.println(" status: Print trace status");
- pw.println(" level [lvl]: Set the log level between");
- pw.println(" lvl may be one of:");
- pw.println(" critical: Only visible windows with reduced information");
- pw.println(" trim: All windows with reduced");
- pw.println(" all: All window and information");
- return -1;
+ if (!android.tracing.Flags.perfettoProtologTracing()
+ && ProtoLog.getSingleInstance().isProtoEnabled()) {
+ ((LegacyProtoLogImpl) ProtoLog.getSingleInstance()).stopProtoLog(pw, true);
+ ((LegacyProtoLogImpl) ProtoLog.getSingleInstance()).startProtoLog(pw);
}
+ saveForBugreportInternal(pw);
}
- String getStatus() {
- return "Status: "
- + ((isEnabled()) ? "Enabled" : "Disabled")
- + "\n"
- + "Log level: "
- + mLogLevel
- + "\n"
- + mBuffer.getStatus();
- }
+ abstract void setLogLevel(@WindowTraceLogLevel int logLevel, PrintWriter pw);
+ abstract void setLogFrequency(boolean onFrame, PrintWriter pw);
+ abstract void setBufferCapacity(int capacity, PrintWriter pw);
+ abstract boolean isEnabled();
+ abstract int onShellCommand(ShellCommand shell);
+ abstract String getStatus();
/**
* If tracing is enabled, log the current state or schedule the next frame to be logged,
- * according to {@link #mLogOnFrame}.
+ * according to the configuration in the derived tracing class.
*
* @param where Logging point descriptor
*/
@@ -298,59 +127,63 @@ class WindowTracing {
return;
}
- if (mLogOnFrame) {
- schedule();
- } else {
+ if (shouldLogOnTransaction()) {
log(where);
}
+
+ if (shouldLogOnFrame()) {
+ schedule();
+ }
}
/**
* Schedule the log to trace the next frame
*/
private void schedule() {
- if (mScheduled) {
+ if (!mScheduled.compareAndSet(false, true)) {
return;
}
- mScheduled = true;
mChoreographer.postFrameCallback(mFrameCallback);
}
/**
- * Write the current frame to the buffer
+ * Write the current frame to proto
*
+ * @param os Proto stream buffer
+ * @param logLevel Log level
* @param where Logging point descriptor
+ * @param elapsedRealtimeNanos Timestamp
*/
- private void log(String where) {
+ protected void dumpToProto(ProtoOutputStream os, @WindowTraceLogLevel int logLevel,
+ String where, long elapsedRealtimeNanos) {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "traceStateLocked");
try {
- ProtoOutputStream os = new ProtoOutputStream();
- long tokenOuter = os.start(ENTRY);
- os.write(ELAPSED_REALTIME_NANOS, SystemClock.elapsedRealtimeNanos());
+ os.write(ELAPSED_REALTIME_NANOS, elapsedRealtimeNanos);
os.write(WHERE, where);
- long tokenInner = os.start(WINDOW_MANAGER_SERVICE);
+ long token = os.start(WINDOW_MANAGER_SERVICE);
synchronized (mGlobalLock) {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "dumpDebugLocked");
try {
- mService.dumpDebugLocked(os, mLogLevel);
+ mService.dumpDebugLocked(os, logLevel);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
}
- os.end(tokenInner);
- os.end(tokenOuter);
- mBuffer.add(os);
- mScheduled = false;
+ os.end(token);
} catch (Exception e) {
Log.wtf(TAG, "Exception while tracing state", e);
} finally {
+ boolean isOnFrameLogEvent = where == WHERE_ON_FRAME;
+ if (isOnFrameLogEvent) {
+ mScheduled.set(false);
+ }
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
}
- private void logAndPrintln(@Nullable PrintWriter pw, String msg) {
+ protected void logAndPrintln(@Nullable PrintWriter pw, String msg) {
Log.i(TAG, msg);
if (pw != null) {
pw.println(msg);
@@ -358,24 +191,10 @@ class WindowTracing {
}
}
- /**
- * Writes the trace buffer to disk. This method has no internal synchronization and should be
- * externally synchronized
- */
- private void writeTraceToFileLocked() {
- try {
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "writeTraceToFileLocked");
- ProtoOutputStream proto = new ProtoOutputStream();
- proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
- long timeOffsetNs =
- TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis())
- - SystemClock.elapsedRealtimeNanos();
- proto.write(REAL_TO_ELAPSED_TIME_OFFSET_NANOS, timeOffsetNs);
- mBuffer.writeTraceToFile(mTraceFile, proto);
- } catch (IOException e) {
- Log.e(TAG, "Unable to write buffer to file", e);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
- }
- }
+ protected abstract void startTraceInternal(@Nullable PrintWriter pw);
+ protected abstract void stopTraceInternal(@Nullable PrintWriter pw);
+ protected abstract void saveForBugreportInternal(@Nullable PrintWriter pw);
+ protected abstract void log(String where);
+ protected abstract boolean shouldLogOnFrame();
+ protected abstract boolean shouldLogOnTransaction();
}
diff --git a/services/core/java/com/android/server/wm/WindowTracingLegacy.java b/services/core/java/com/android/server/wm/WindowTracingLegacy.java
new file mode 100644
index 000000000000..7a36707fd95a
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowTracingLegacy.java
@@ -0,0 +1,276 @@
+/*
+ * 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.wm;
+
+import static com.android.server.wm.WindowManagerTraceFileProto.ENTRY;
+import static com.android.server.wm.WindowManagerTraceFileProto.MAGIC_NUMBER;
+import static com.android.server.wm.WindowManagerTraceFileProto.MAGIC_NUMBER_H;
+import static com.android.server.wm.WindowManagerTraceFileProto.MAGIC_NUMBER_L;
+import static com.android.server.wm.WindowManagerTraceFileProto.REAL_TO_ELAPSED_TIME_OFFSET_NANOS;
+
+import android.annotation.Nullable;
+import android.os.ShellCommand;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.util.Log;
+import android.util.proto.ProtoOutputStream;
+import android.view.Choreographer;
+
+import com.android.internal.util.TraceBuffer;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.concurrent.TimeUnit;
+
+class WindowTracingLegacy extends WindowTracing {
+
+ /**
+ * Maximum buffer size, currently defined as 5 MB
+ * Size was experimentally defined to fit between 100 to 150 elements.
+ */
+ private static final int BUFFER_CAPACITY_CRITICAL = 5120 * 1024; // 5 MB
+ private static final int BUFFER_CAPACITY_TRIM = 10240 * 1024; // 10 MB
+ private static final int BUFFER_CAPACITY_ALL = 20480 * 1024; // 20 MB
+ static final String WINSCOPE_EXT = ".winscope";
+ private static final String TRACE_FILENAME = "/data/misc/wmtrace/wm_trace" + WINSCOPE_EXT;
+ private static final String TAG = "WindowTracing";
+ private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;
+
+ private final Object mEnabledLock = new Object();
+ private final File mTraceFile;
+ private final TraceBuffer mBuffer;
+
+ private boolean mEnabled;
+ private volatile boolean mEnabledLockFree;
+
+ protected @WindowTraceLogLevel int mLogLevel = WindowTraceLogLevel.TRIM;
+ protected boolean mLogOnFrame = false;
+
+ WindowTracingLegacy(WindowManagerService service, Choreographer choreographer) {
+ this(new File(TRACE_FILENAME), service, choreographer,
+ service.mGlobalLock, BUFFER_CAPACITY_TRIM);
+ }
+
+ WindowTracingLegacy(File traceFile, WindowManagerService service, Choreographer choreographer,
+ WindowManagerGlobalLock globalLock, int bufferSize) {
+ super(service, choreographer, globalLock);
+ mTraceFile = traceFile;
+ mBuffer = new TraceBuffer(bufferSize);
+ }
+
+ @Override
+ void setLogLevel(@WindowTraceLogLevel int logLevel, PrintWriter pw) {
+ logAndPrintln(pw, "Setting window tracing log level to " + logLevel);
+ mLogLevel = logLevel;
+
+ switch (logLevel) {
+ case WindowTraceLogLevel.ALL: {
+ setBufferCapacity(BUFFER_CAPACITY_ALL, pw);
+ break;
+ }
+ case WindowTraceLogLevel.TRIM: {
+ setBufferCapacity(BUFFER_CAPACITY_TRIM, pw);
+ break;
+ }
+ case WindowTraceLogLevel.CRITICAL: {
+ setBufferCapacity(BUFFER_CAPACITY_CRITICAL, pw);
+ break;
+ }
+ }
+ }
+
+ @Override
+ void setLogFrequency(boolean onFrame, PrintWriter pw) {
+ logAndPrintln(pw, "Setting window tracing log frequency to "
+ + ((onFrame) ? "frame" : "transaction"));
+ mLogOnFrame = onFrame;
+ }
+
+ @Override
+ void setBufferCapacity(int capacity, PrintWriter pw) {
+ logAndPrintln(pw, "Setting window tracing buffer capacity to " + capacity + "bytes");
+ mBuffer.setCapacity(capacity);
+ }
+
+ @Override
+ boolean isEnabled() {
+ return mEnabledLockFree;
+ }
+
+ @Override
+ int onShellCommand(ShellCommand shell) {
+ PrintWriter pw = shell.getOutPrintWriter();
+ String cmd = shell.getNextArgRequired();
+ switch (cmd) {
+ case "start":
+ startTrace(pw);
+ return 0;
+ case "stop":
+ stopTrace(pw);
+ return 0;
+ case "save-for-bugreport":
+ saveForBugreport(pw);
+ return 0;
+ case "status":
+ logAndPrintln(pw, getStatus());
+ return 0;
+ case "frame":
+ setLogFrequency(true /* onFrame */, pw);
+ mBuffer.resetBuffer();
+ return 0;
+ case "transaction":
+ setLogFrequency(false /* onFrame */, pw);
+ mBuffer.resetBuffer();
+ return 0;
+ case "level":
+ String logLevelStr = shell.getNextArgRequired().toLowerCase();
+ switch (logLevelStr) {
+ case "all": {
+ setLogLevel(WindowTraceLogLevel.ALL, pw);
+ break;
+ }
+ case "trim": {
+ setLogLevel(WindowTraceLogLevel.TRIM, pw);
+ break;
+ }
+ case "critical": {
+ setLogLevel(WindowTraceLogLevel.CRITICAL, pw);
+ break;
+ }
+ default: {
+ setLogLevel(WindowTraceLogLevel.TRIM, pw);
+ break;
+ }
+ }
+ mBuffer.resetBuffer();
+ return 0;
+ case "size":
+ setBufferCapacity(Integer.parseInt(shell.getNextArgRequired()) * 1024, pw);
+ mBuffer.resetBuffer();
+ return 0;
+ default:
+ pw.println("Unknown command: " + cmd);
+ pw.println("Window manager trace options:");
+ pw.println(" start: Start logging");
+ pw.println(" stop: Stop logging");
+ pw.println(" save-for-bugreport: Save logging data to file if it's running.");
+ pw.println(" frame: Log trace once per frame");
+ pw.println(" transaction: Log each transaction");
+ pw.println(" size: Set the maximum log size (in KB)");
+ pw.println(" status: Print trace status");
+ pw.println(" level [lvl]: Set the log level between");
+ pw.println(" lvl may be one of:");
+ pw.println(" critical: Only visible windows with reduced information");
+ pw.println(" trim: All windows with reduced");
+ pw.println(" all: All window and information");
+ return -1;
+ }
+ }
+
+ @Override
+ String getStatus() {
+ return "Status: "
+ + ((isEnabled()) ? "Enabled" : "Disabled")
+ + "\n"
+ + "Log level: "
+ + mLogLevel
+ + "\n"
+ + mBuffer.getStatus();
+ }
+
+ @Override
+ protected void startTraceInternal(@Nullable PrintWriter pw) {
+ synchronized (mEnabledLock) {
+ logAndPrintln(pw, "Start tracing to " + mTraceFile + ".");
+ mBuffer.resetBuffer();
+ mEnabled = mEnabledLockFree = true;
+ }
+ log(WHERE_START_TRACING);
+ }
+
+ @Override
+ protected void stopTraceInternal(@Nullable PrintWriter pw) {
+ synchronized (mEnabledLock) {
+ logAndPrintln(pw, "Stop tracing to " + mTraceFile + ". Waiting for traces to flush.");
+ mEnabled = mEnabledLockFree = false;
+
+ if (mEnabled) {
+ logAndPrintln(pw, "ERROR: tracing was re-enabled while waiting for flush.");
+ throw new IllegalStateException("tracing enabled while waiting for flush.");
+ }
+ writeTraceToFileLocked();
+ logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
+ }
+ }
+
+ @Override
+ protected void saveForBugreportInternal(@Nullable PrintWriter pw) {
+ synchronized (mEnabledLock) {
+ if (!mEnabled) {
+ return;
+ }
+ mEnabled = mEnabledLockFree = false;
+ logAndPrintln(pw, "Stop tracing to " + mTraceFile + ". Waiting for traces to flush.");
+ writeTraceToFileLocked();
+ logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
+ logAndPrintln(pw, "Start tracing to " + mTraceFile + ".");
+ mBuffer.resetBuffer();
+ mEnabled = mEnabledLockFree = true;
+ }
+ }
+
+ @Override
+ protected void log(String where) {
+ try {
+ ProtoOutputStream os = new ProtoOutputStream();
+ long token = os.start(ENTRY);
+ dumpToProto(os, mLogLevel, where, SystemClock.elapsedRealtimeNanos());
+ os.end(token);
+ mBuffer.add(os);
+ } catch (Exception e) {
+ Log.wtf(TAG, "Exception while tracing state", e);
+ }
+ }
+
+ @Override
+ protected boolean shouldLogOnFrame() {
+ return mLogOnFrame;
+ }
+
+ @Override
+ protected boolean shouldLogOnTransaction() {
+ return !mLogOnFrame;
+ }
+
+ private void writeTraceToFileLocked() {
+ try {
+ Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "writeTraceToFileLocked");
+ ProtoOutputStream proto = new ProtoOutputStream();
+ proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
+ long timeOffsetNs =
+ TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis())
+ - SystemClock.elapsedRealtimeNanos();
+ proto.write(REAL_TO_ELAPSED_TIME_OFFSET_NANOS, timeOffsetNs);
+ mBuffer.writeTraceToFile(mTraceFile, proto);
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to write buffer to file", e);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/utils/DimenPxIntSupplier.java b/services/core/java/com/android/server/wm/utils/DimenPxIntSupplier.java
new file mode 100644
index 000000000000..5e4934500154
--- /dev/null
+++ b/services/core/java/com/android/server/wm/utils/DimenPxIntSupplier.java
@@ -0,0 +1,54 @@
+/*
+ * 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.wm.utils;
+
+import android.annotation.DimenRes;
+import android.annotation.NonNull;
+import android.content.Context;
+
+import java.util.function.IntSupplier;
+
+/**
+ * Cached version of IntSupplier customised to evaluate new dimen in pixels
+ * when density changes.
+ * @hide
+ */
+public class DimenPxIntSupplier implements IntSupplier {
+
+ @NonNull
+ private final Context mContext;
+
+ private final int mResourceId;
+
+ private float mLastDensity = Float.MIN_VALUE;
+ private int mValue = 0;
+
+ public DimenPxIntSupplier(@NonNull Context context, @DimenRes int resourceId) {
+ mContext = context;
+ mResourceId = resourceId;
+ }
+
+ @Override
+ public int getAsInt() {
+ final float newDensity = mContext.getResources().getDisplayMetrics().density;
+ if (newDensity != mLastDensity) {
+ mLastDensity = newDensity;
+ mValue = mContext.getResources().getDimensionPixelSize(mResourceId);
+ }
+ return mValue;
+ }
+}
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 7a710dc51004..3cd5f7683ac8 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -193,7 +193,7 @@ cc_defaults {
"android.hardware.thermal-V2-ndk",
"android.hardware.tv.input@1.0",
"android.hardware.tv.input-V2-ndk",
- "android.hardware.vibrator-V2-cpp",
+ "android.hardware.vibrator-V2-ndk",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
@@ -210,6 +210,7 @@ cc_defaults {
"android.system.suspend-V1-ndk",
"server_configurable_flags",
"service.incremental",
+ "android.companion.virtualdevice.flags-aconfig-cc",
],
static_libs: [
diff --git a/services/core/jni/com_android_server_companion_virtual_InputController.cpp b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
index 5c4db24767f9..9ec5ae5a8e51 100644
--- a/services/core/jni/com_android_server_companion_virtual_InputController.cpp
+++ b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
@@ -19,6 +19,7 @@
#include <android-base/unique_fd.h>
#include <android/input.h>
#include <android/keycodes.h>
+#include <android_companion_virtualdevice_flags.h>
#include <errno.h>
#include <fcntl.h>
#include <input/Input.h>
@@ -37,6 +38,8 @@ using android::base::unique_fd;
namespace android {
+namespace vd_flags = android::companion::virtualdevice::flags;
+
static constexpr jlong INVALID_PTR = 0;
enum class DeviceType {
@@ -88,6 +91,10 @@ static unique_fd openUinput(const char* readableName, jint vendorId, jint produc
ioctl(fd, UI_SET_RELBIT, REL_Y);
ioctl(fd, UI_SET_RELBIT, REL_WHEEL);
ioctl(fd, UI_SET_RELBIT, REL_HWHEEL);
+ if (vd_flags::high_resolution_scroll()) {
+ ioctl(fd, UI_SET_RELBIT, REL_WHEEL_HI_RES);
+ ioctl(fd, UI_SET_RELBIT, REL_HWHEEL_HI_RES);
+ }
break;
case DeviceType::TOUCHSCREEN:
ioctl(fd, UI_SET_EVBIT, EV_ABS);
@@ -118,6 +125,9 @@ static unique_fd openUinput(const char* readableName, jint vendorId, jint produc
case DeviceType::ROTARY_ENCODER:
ioctl(fd, UI_SET_EVBIT, EV_REL);
ioctl(fd, UI_SET_RELBIT, REL_WHEEL);
+ if (vd_flags::high_resolution_scroll()) {
+ ioctl(fd, UI_SET_RELBIT, REL_WHEEL_HI_RES);
+ }
break;
default:
ALOGE("Invalid input device type %d", static_cast<int32_t>(deviceType));
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 1f0c827083ac..5719810abc5a 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -314,6 +314,7 @@ public:
void getReaderConfiguration(InputReaderConfiguration* outConfig) override;
void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override;
+ void notifyConfigurationChanged(nsecs_t when) override;
std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
const InputDeviceIdentifier& identifier,
const std::optional<KeyboardLayoutInfo> keyboardLayoutInfo) override;
@@ -331,7 +332,6 @@ public:
void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
uint32_t policyFlags) override;
- void notifyConfigurationChanged(nsecs_t when) override;
// ANR-related callbacks -- start
void notifyNoFocusedWindowAnr(const std::shared_ptr<InputApplicationHandle>& handle) override;
void notifyWindowUnresponsive(const sp<IBinder>& token, std::optional<gui::Pid> pid,
@@ -382,6 +382,7 @@ public:
PointerControllerInterface::ControllerType type) override;
void notifyPointerDisplayIdChanged(ui::LogicalDisplayId displayId,
const FloatPoint& position) override;
+ void notifyMouseCursorFadedOnTyping() override;
/* --- InputFilterPolicyInterface implementation --- */
void notifyStickyModifierStateChanged(uint32_t modifierState,
@@ -788,6 +789,10 @@ void NativeInputManager::notifyPointerDisplayIdChanged(ui::LogicalDisplayId poin
InputReaderConfiguration::Change::DISPLAY_INFO);
}
+void NativeInputManager::notifyMouseCursorFadedOnTyping() {
+ mInputManager->getReader().notifyMouseCursorFadedOnTyping();
+}
+
void NativeInputManager::notifyStickyModifierStateChanged(uint32_t modifierState,
uint32_t lockedModifierState) {
JNIEnv* env = jniEnv();
@@ -1847,10 +1852,6 @@ static void handleInputChannelDisposed(JNIEnv* env, jobject /* inputChannelObj *
const std::shared_ptr<InputChannel>& inputChannel,
void* data) {
NativeInputManager* im = static_cast<NativeInputManager*>(data);
-
- ALOGW("Input channel object '%s' was disposed without first being removed with "
- "the input manager!",
- inputChannel->getName().c_str());
im->removeInputChannel(inputChannel->getConnectionToken());
}
diff --git a/services/core/jni/com_android_server_vibrator_VibratorController.cpp b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
index 4be21d872383..2804a10c317f 100644
--- a/services/core/jni/com_android_server_vibrator_VibratorController.cpp
+++ b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
@@ -16,24 +16,21 @@
#define LOG_TAG "VibratorController"
+#include <aidl/android/hardware/vibrator/IVibrator.h>
#include <android/hardware/vibrator/1.3/IVibrator.h>
-#include <android/hardware/vibrator/IVibrator.h>
-
#include <nativehelper/JNIHelp.h>
-#include "android_runtime/AndroidRuntime.h"
-#include "core_jni_helpers.h"
-#include "jni.h"
-
#include <utils/Log.h>
#include <utils/misc.h>
-
#include <vibratorservice/VibratorHalController.h>
+#include "android_runtime/AndroidRuntime.h"
#include "com_android_server_vibrator_VibratorManagerService.h"
+#include "core_jni_helpers.h"
+#include "jni.h"
namespace V1_0 = android::hardware::vibrator::V1_0;
namespace V1_3 = android::hardware::vibrator::V1_3;
-namespace aidl = android::hardware::vibrator;
+namespace Aidl = aidl::android::hardware::vibrator;
namespace android {
@@ -67,29 +64,29 @@ static struct {
} sRampClassInfo;
static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) ==
- static_cast<uint8_t>(aidl::EffectStrength::LIGHT));
+ static_cast<uint8_t>(Aidl::EffectStrength::LIGHT));
static_assert(static_cast<uint8_t>(V1_0::EffectStrength::MEDIUM) ==
- static_cast<uint8_t>(aidl::EffectStrength::MEDIUM));
+ static_cast<uint8_t>(Aidl::EffectStrength::MEDIUM));
static_assert(static_cast<uint8_t>(V1_0::EffectStrength::STRONG) ==
- static_cast<uint8_t>(aidl::EffectStrength::STRONG));
+ static_cast<uint8_t>(Aidl::EffectStrength::STRONG));
static_assert(static_cast<uint8_t>(V1_3::Effect::CLICK) ==
- static_cast<uint8_t>(aidl::Effect::CLICK));
+ static_cast<uint8_t>(Aidl::Effect::CLICK));
static_assert(static_cast<uint8_t>(V1_3::Effect::DOUBLE_CLICK) ==
- static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK));
-static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) == static_cast<uint8_t>(aidl::Effect::TICK));
-static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) == static_cast<uint8_t>(aidl::Effect::THUD));
-static_assert(static_cast<uint8_t>(V1_3::Effect::POP) == static_cast<uint8_t>(aidl::Effect::POP));
+ static_cast<uint8_t>(Aidl::Effect::DOUBLE_CLICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) == static_cast<uint8_t>(Aidl::Effect::TICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) == static_cast<uint8_t>(Aidl::Effect::THUD));
+static_assert(static_cast<uint8_t>(V1_3::Effect::POP) == static_cast<uint8_t>(Aidl::Effect::POP));
static_assert(static_cast<uint8_t>(V1_3::Effect::HEAVY_CLICK) ==
- static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK));
+ static_cast<uint8_t>(Aidl::Effect::HEAVY_CLICK));
static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_1) ==
- static_cast<uint8_t>(aidl::Effect::RINGTONE_1));
+ static_cast<uint8_t>(Aidl::Effect::RINGTONE_1));
static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_2) ==
- static_cast<uint8_t>(aidl::Effect::RINGTONE_2));
+ static_cast<uint8_t>(Aidl::Effect::RINGTONE_2));
static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) ==
- static_cast<uint8_t>(aidl::Effect::RINGTONE_15));
+ static_cast<uint8_t>(Aidl::Effect::RINGTONE_15));
static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) ==
- static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK));
+ static_cast<uint8_t>(Aidl::Effect::TEXTURE_TICK));
static std::shared_ptr<vibrator::HalController> findVibrator(int32_t vibratorId) {
vibrator::ManagerHalController* manager =
@@ -155,15 +152,15 @@ private:
std::atomic<int64_t> mCallbackId;
};
-static aidl::BrakingPwle brakingPwle(aidl::Braking braking, int32_t duration) {
- aidl::BrakingPwle pwle;
+static Aidl::BrakingPwle brakingPwle(Aidl::Braking braking, int32_t duration) {
+ Aidl::BrakingPwle pwle;
pwle.braking = braking;
pwle.duration = duration;
return pwle;
}
-static aidl::ActivePwle activePwleFromJavaPrimitive(JNIEnv* env, jobject ramp) {
- aidl::ActivePwle pwle;
+static Aidl::ActivePwle activePwleFromJavaPrimitive(JNIEnv* env, jobject ramp) {
+ Aidl::ActivePwle pwle;
pwle.startAmplitude =
static_cast<float>(env->GetFloatField(ramp, sRampClassInfo.startAmplitude));
pwle.endAmplitude = static_cast<float>(env->GetFloatField(ramp, sRampClassInfo.endAmplitude));
@@ -175,20 +172,20 @@ static aidl::ActivePwle activePwleFromJavaPrimitive(JNIEnv* env, jobject ramp) {
}
/* Return true if braking is not NONE and the active PWLE starts and ends with zero amplitude. */
-static bool shouldBeReplacedWithBraking(aidl::ActivePwle activePwle, aidl::Braking braking) {
- return (braking != aidl::Braking::NONE) && (activePwle.startAmplitude == 0) &&
+static bool shouldBeReplacedWithBraking(Aidl::ActivePwle activePwle, Aidl::Braking braking) {
+ return (braking != Aidl::Braking::NONE) && (activePwle.startAmplitude == 0) &&
(activePwle.endAmplitude == 0);
}
/* Return true if braking is not NONE and the active PWLE only ends with zero amplitude. */
-static bool shouldAddLastBraking(aidl::ActivePwle lastActivePwle, aidl::Braking braking) {
- return (braking != aidl::Braking::NONE) && (lastActivePwle.startAmplitude > 0) &&
+static bool shouldAddLastBraking(Aidl::ActivePwle lastActivePwle, Aidl::Braking braking) {
+ return (braking != Aidl::Braking::NONE) && (lastActivePwle.startAmplitude > 0) &&
(lastActivePwle.endAmplitude == 0);
}
-static aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primitive) {
- aidl::CompositeEffect effect;
- effect.primitive = static_cast<aidl::CompositePrimitive>(
+static Aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primitive) {
+ Aidl::CompositeEffect effect;
+ effect.primitive = static_cast<Aidl::CompositePrimitive>(
env->GetIntField(primitive, sPrimitiveClassInfo.id));
effect.scale = static_cast<float>(env->GetFloatField(primitive, sPrimitiveClassInfo.scale));
effect.delayMs = static_cast<int32_t>(env->GetIntField(primitive, sPrimitiveClassInfo.delay));
@@ -282,8 +279,8 @@ static jlong vibratorPerformEffect(JNIEnv* env, jclass /* clazz */, jlong ptr, j
ALOGE("vibratorPerformEffect failed because native wrapper was not initialized");
return -1;
}
- aidl::Effect effectType = static_cast<aidl::Effect>(effect);
- aidl::EffectStrength effectStrength = static_cast<aidl::EffectStrength>(strength);
+ Aidl::Effect effectType = static_cast<Aidl::Effect>(effect);
+ Aidl::EffectStrength effectStrength = static_cast<Aidl::EffectStrength>(strength);
auto callback = wrapper->createCallback(vibrationId);
auto performEffectFn = [effectType, effectStrength, &callback](vibrator::HalWrapper* hal) {
return hal->performEffect(effectType, effectStrength, callback);
@@ -300,7 +297,7 @@ static jlong vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlon
return -1;
}
size_t size = env->GetArrayLength(composition);
- std::vector<aidl::CompositeEffect> effects;
+ std::vector<Aidl::CompositeEffect> effects;
for (size_t i = 0; i < size; i++) {
jobject element = env->GetObjectArrayElement(composition, i);
effects.push_back(effectFromJavaPrimitive(env, element));
@@ -321,13 +318,13 @@ static jlong vibratorPerformPwleEffect(JNIEnv* env, jclass /* clazz */, jlong pt
ALOGE("vibratorPerformPwleEffect failed because native wrapper was not initialized");
return -1;
}
- aidl::Braking braking = static_cast<aidl::Braking>(brakingId);
+ Aidl::Braking braking = static_cast<Aidl::Braking>(brakingId);
size_t size = env->GetArrayLength(waveform);
- std::vector<aidl::PrimitivePwle> primitives;
+ std::vector<Aidl::PrimitivePwle> primitives;
std::chrono::milliseconds totalDuration(0);
for (size_t i = 0; i < size; i++) {
jobject element = env->GetObjectArrayElement(waveform, i);
- aidl::ActivePwle activePwle = activePwleFromJavaPrimitive(env, element);
+ Aidl::ActivePwle activePwle = activePwleFromJavaPrimitive(env, element);
if ((i > 0) && shouldBeReplacedWithBraking(activePwle, braking)) {
primitives.push_back(brakingPwle(braking, activePwle.duration));
} else {
@@ -356,8 +353,8 @@ static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong ptr, j
return;
}
auto alwaysOnEnableFn = [id, effect, strength](vibrator::HalWrapper* hal) {
- return hal->alwaysOnEnable(static_cast<int32_t>(id), static_cast<aidl::Effect>(effect),
- static_cast<aidl::EffectStrength>(strength));
+ return hal->alwaysOnEnable(static_cast<int32_t>(id), static_cast<Aidl::Effect>(effect),
+ static_cast<Aidl::EffectStrength>(strength));
};
wrapper->halCall<void>(alwaysOnEnableFn, "alwaysOnEnable");
}
@@ -389,7 +386,7 @@ static jboolean vibratorGetInfo(JNIEnv* env, jclass /* clazz */, jlong ptr,
static_cast<jlong>(info.capabilities.value()));
}
if (info.supportedEffects.isOk()) {
- std::vector<aidl::Effect> effects = info.supportedEffects.value();
+ std::vector<Aidl::Effect> effects = info.supportedEffects.value();
jintArray supportedEffects = env->NewIntArray(effects.size());
env->SetIntArrayRegion(supportedEffects, 0, effects.size(),
reinterpret_cast<jint*>(effects.data()));
@@ -397,7 +394,7 @@ static jboolean vibratorGetInfo(JNIEnv* env, jclass /* clazz */, jlong ptr,
sVibratorInfoBuilderClassInfo.setSupportedEffects, supportedEffects);
}
if (info.supportedBraking.isOk()) {
- std::vector<aidl::Braking> braking = info.supportedBraking.value();
+ std::vector<Aidl::Braking> braking = info.supportedBraking.value();
jintArray supportedBraking = env->NewIntArray(braking.size());
env->SetIntArrayRegion(supportedBraking, 0, braking.size(),
reinterpret_cast<jint*>(braking.data()));
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index eeb8b9b0b469..4231149336ec 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -179,6 +179,19 @@
<xs:element name="supportsVrr" type="xs:boolean" minOccurs="0">
<xs:annotation name="final"/>
</xs:element>
+ <!-- Table that translates doze brightness sensor values to brightness values in
+ the float scale [0, 1]; -1 means the current brightness should be kept.
+ The following formula should be used for conversion between nits and the float
+ scale: float = (nits - minNits) / (maxNits - minNits). minNits and maxNits are
+ defined in screenBrightnessMap. -->
+ <xs:element type="float-array" name="dozeBrightnessSensorValueToBrightness">
+ <xs:annotation name="final"/>
+ </xs:element>
+ <!-- The default screen brightness in the scale [0, 1] to use while the device is
+ dozing. -->
+ <xs:element type="nonNegativeDecimal" name="defaultDozeBrightness">
+ <xs:annotation name="final"/>
+ </xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
@@ -315,6 +328,42 @@
<xs:element name="screenBrightnessRampDecrease" type="nonNegativeDecimal">
<xs:annotation name="final"/>
</xs:element>
+
+ <!-- The minimum HDR layer % at which hdr boost will be applied with transition point cap.
+ Should be lower or equal to minimumHdrPercentOfScreenForHbm. -->
+ <xs:element name="minimumHdrPercentOfScreenForNbm" type="nonNegativeDecimal"
+ minOccurs="0" maxOccurs="1">
+ <xs:annotation name="nullable"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <!-- The minimum HDR layer size at which hdr boost will be applied. -->
+ <xs:element name="minimumHdrPercentOfScreenForHbm" type="nonNegativeDecimal"
+ minOccurs="0" maxOccurs="1">
+ <xs:annotation name="nullable"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <!-- If hdr boost is allowed in low power mode. -->
+ <xs:element name="allowInLowPowerMode" type="xs:boolean" minOccurs="0" maxOccurs="1">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <!-- sdrNits, hdrRatio This LUT specifies how to boost HDR brightness at given SDR brightness (nits). -->
+ <!-- sdr brightness to hdr boost ratio map
+ Format: first = sdrNits, second = hdrRatio. E.g. :
+ <sdrHdrRatioMap>
+ <point>
+ <first>2.0</first> // sdrNits
+ <second>4.0</second> // hdrRatio
+ </point>
+ ....
+ </sdrHdrRatioMap>
+ -->
+ <xs:element type="nonNegativeFloatToFloatMap" name="sdrHdrRatioMap" minOccurs="0" maxOccurs="1">
+ <xs:annotation name="nullable"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+
+
</xs:complexType>
<!-- Maps to PowerManager.THERMAL_STATUS_* values. -->
@@ -823,6 +872,12 @@
</xs:sequence>
</xs:complexType>
+ <xs:complexType name="float-array">
+ <xs:sequence>
+ <xs:element name="item" type="nonNegativeDecimal" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
<xs:complexType name="usiVersion">
<xs:element name="majorVersion" type="xs:nonNegativeInteger"
minOccurs="1" maxOccurs="1">
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 757b23a2df7e..cec2787ca51f 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -125,9 +125,11 @@ package com.android.server.display.config {
method public final java.math.BigInteger getAmbientLightHorizonLong();
method public final java.math.BigInteger getAmbientLightHorizonShort();
method public com.android.server.display.config.AutoBrightness getAutoBrightness();
+ method public final java.math.BigDecimal getDefaultDozeBrightness();
method @Nullable public final com.android.server.display.config.DensityMapping getDensityMapping();
method @NonNull public final com.android.server.display.config.Thresholds getDisplayBrightnessChangeThresholds();
method public final com.android.server.display.config.Thresholds getDisplayBrightnessChangeThresholdsIdle();
+ method public final com.android.server.display.config.FloatArray getDozeBrightnessSensorValueToBrightness();
method public final com.android.server.display.config.EvenDimmerMode getEvenDimmer();
method @Nullable public final com.android.server.display.config.HdrBrightnessConfig getHdrBrightnessConfig();
method public com.android.server.display.config.HighBrightnessMode getHighBrightnessMode();
@@ -163,9 +165,11 @@ package com.android.server.display.config {
method public final void setAmbientLightHorizonLong(java.math.BigInteger);
method public final void setAmbientLightHorizonShort(java.math.BigInteger);
method public void setAutoBrightness(com.android.server.display.config.AutoBrightness);
+ method public final void setDefaultDozeBrightness(java.math.BigDecimal);
method public final void setDensityMapping(@Nullable com.android.server.display.config.DensityMapping);
method public final void setDisplayBrightnessChangeThresholds(@NonNull com.android.server.display.config.Thresholds);
method public final void setDisplayBrightnessChangeThresholdsIdle(com.android.server.display.config.Thresholds);
+ method public final void setDozeBrightnessSensorValueToBrightness(com.android.server.display.config.FloatArray);
method public final void setEvenDimmer(com.android.server.display.config.EvenDimmerMode);
method public final void setHdrBrightnessConfig(@Nullable com.android.server.display.config.HdrBrightnessConfig);
method public void setHighBrightnessMode(com.android.server.display.config.HighBrightnessMode);
@@ -214,6 +218,11 @@ package com.android.server.display.config {
method public void setTransitionPoint(java.math.BigDecimal);
}
+ public class FloatArray {
+ ctor public FloatArray();
+ method public java.util.List<java.math.BigDecimal> getItem();
+ }
+
public class HbmTiming {
ctor public HbmTiming();
method @NonNull public final java.math.BigInteger getTimeMaxSecs_all();
@@ -226,16 +235,24 @@ package com.android.server.display.config {
public class HdrBrightnessConfig {
ctor public HdrBrightnessConfig();
+ method @NonNull public final boolean getAllowInLowPowerMode();
method public final java.math.BigInteger getBrightnessDecreaseDebounceMillis();
method public final java.math.BigInteger getBrightnessIncreaseDebounceMillis();
method @NonNull public final com.android.server.display.config.NonNegativeFloatToFloatMap getBrightnessMap();
+ method @Nullable public final java.math.BigDecimal getMinimumHdrPercentOfScreenForHbm();
+ method @Nullable public final java.math.BigDecimal getMinimumHdrPercentOfScreenForNbm();
method public final java.math.BigDecimal getScreenBrightnessRampDecrease();
method public final java.math.BigDecimal getScreenBrightnessRampIncrease();
+ method @Nullable public final com.android.server.display.config.NonNegativeFloatToFloatMap getSdrHdrRatioMap();
+ method public final void setAllowInLowPowerMode(@NonNull boolean);
method public final void setBrightnessDecreaseDebounceMillis(java.math.BigInteger);
method public final void setBrightnessIncreaseDebounceMillis(java.math.BigInteger);
method public final void setBrightnessMap(@NonNull com.android.server.display.config.NonNegativeFloatToFloatMap);
+ method public final void setMinimumHdrPercentOfScreenForHbm(@Nullable java.math.BigDecimal);
+ method public final void setMinimumHdrPercentOfScreenForNbm(@Nullable java.math.BigDecimal);
method public final void setScreenBrightnessRampDecrease(java.math.BigDecimal);
method public final void setScreenBrightnessRampIncrease(java.math.BigDecimal);
+ method public final void setSdrHdrRatioMap(@Nullable com.android.server.display.config.NonNegativeFloatToFloatMap);
}
public class HighBrightnessMode {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e122fe039c45..032d6b56af1b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1131,9 +1131,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
@Override
- public void onUserUnlocked(@NonNull TargetUser user) {
- if (user.isPreCreated()) return;
- mService.handleOnUserUnlocked(user.getUserIdentifier());
+ public void onUserSwitching(@NonNull TargetUser from, @NonNull TargetUser to) {
+ if (to.isPreCreated()) return;
+ mService.handleOnUserSwitching(from.getUserIdentifier(), to.getUserIdentifier());
}
}
@@ -3831,8 +3831,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
mDevicePolicyEngine.handleUnlockUser(userId);
}
- void handleOnUserUnlocked(int userId) {
- showNewUserDisclaimerIfNecessary(userId);
+ void handleOnUserSwitching(int fromUserId, int toUserId) {
+ showNewUserDisclaimerIfNecessary(toUserId);
}
void handleStopUser(int userId) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 215cf2c5c85c..db4b171152a7 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -381,6 +381,9 @@ public final class SystemServer implements Dumpable {
+ "OnDevicePersonalizationSystemService$Lifecycle";
private static final String UPDATABLE_DEVICE_CONFIG_SERVICE_CLASS =
"com.android.server.deviceconfig.DeviceConfigInit$Lifecycle";
+ private static final String CRASHRECOVERY_MODULE_LIFECYCLE_CLASS =
+ "com.android.server.crashrecovery.CrashRecoveryModule$Lifecycle";
+
/*
* Implementation class names and jar locations for services in
@@ -1196,15 +1199,18 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(RecoverySystemService.Lifecycle.class);
t.traceEnd();
- // Initialize RescueParty.
- RescueParty.registerHealthObserver(mSystemContext);
- if (!Flags.recoverabilityDetection()) {
- // Now that we have the bare essentials of the OS up and running, take
- // note that we just booted, which might send out a rescue party if
- // we're stuck in a runtime restart loop.
- PackageWatchdog.getInstance(mSystemContext).noteBoot();
+ if (!Flags.refactorCrashrecovery()) {
+ // Initialize RescueParty.
+ RescueParty.registerHealthObserver(mSystemContext);
+ if (!Flags.recoverabilityDetection()) {
+ // Now that we have the bare essentials of the OS up and running, take
+ // note that we just booted, which might send out a rescue party if
+ // we're stuck in a runtime restart loop.
+ PackageWatchdog.getInstance(mSystemContext).noteBoot();
+ }
}
+
// Manages LEDs and display backlight so we need it to bring up the display.
t.traceBegin("StartLightsService");
mSystemServiceManager.startService(LightsService.class);
@@ -2134,14 +2140,20 @@ public final class SystemServer implements Dumpable {
}
t.traceEnd();
- t.traceBegin("StartVpnManagerService");
- try {
- vpnManager = VpnManagerService.create(context);
- ServiceManager.addService(Context.VPN_MANAGEMENT_SERVICE, vpnManager);
- } catch (Throwable e) {
- reportWtf("starting VPN Manager Service", e);
+ if (!isWatch || !android.server.Flags.allowRemovingVpnService()) {
+ t.traceBegin("StartVpnManagerService");
+ try {
+ vpnManager = VpnManagerService.create(context);
+ ServiceManager.addService(Context.VPN_MANAGEMENT_SERVICE, vpnManager);
+ } catch (Throwable e) {
+ reportWtf("starting VPN Manager Service", e);
+ }
+ t.traceEnd();
+ } else {
+ // VPN management currently does not work in Wear, so skip starting the
+ // VPN manager SystemService.
+ Slog.i(TAG, "Not starting VpnManagerService");
}
- t.traceEnd();
t.traceBegin("StartVcnManagementService");
try {
@@ -2439,11 +2451,11 @@ public final class SystemServer implements Dumpable {
t.traceEnd();
}
- t.traceBegin("CertBlacklister");
+ t.traceBegin("CertBlocklister");
try {
- CertBlacklister blacklister = new CertBlacklister(context);
+ CertBlocklister blocklister = new CertBlocklister(context);
} catch (Throwable e) {
- reportWtf("starting CertBlacklister", e);
+ reportWtf("starting CertBlocklister", e);
}
t.traceEnd();
@@ -2925,12 +2937,18 @@ public final class SystemServer implements Dumpable {
mPackageManagerService.systemReady();
t.traceEnd();
- if (Flags.recoverabilityDetection()) {
- // Now that we have the essential services needed for mitigations, register the boot
- // with package watchdog.
- // Note that we just booted, which might send out a rescue party if we're stuck in a
- // runtime restart loop.
- PackageWatchdog.getInstance(mSystemContext).noteBoot();
+ if (Flags.refactorCrashrecovery()) {
+ t.traceBegin("StartCrashRecoveryModule");
+ mSystemServiceManager.startService(CRASHRECOVERY_MODULE_LIFECYCLE_CLASS);
+ t.traceEnd();
+ } else {
+ if (Flags.recoverabilityDetection()) {
+ // Now that we have the essential services needed for mitigations, register the boot
+ // with package watchdog.
+ // Note that we just booted, which might send out a rescue party if we're stuck in a
+ // runtime restart loop.
+ PackageWatchdog.getInstance(mSystemContext).noteBoot();
+ }
}
t.traceBegin("MakeDisplayManagerServiceReady");
diff --git a/services/java/com/android/server/flags.aconfig b/services/java/com/android/server/flags.aconfig
index e8aa68cf1a63..29f387117073 100644
--- a/services/java/com/android/server/flags.aconfig
+++ b/services/java/com/android/server/flags.aconfig
@@ -21,4 +21,11 @@ flag {
namespace: "wear_frameworks"
description: "Remove WearableSensingManagerService on Wear"
bug: "340929916"
+}
+
+flag {
+ name: "allow_removing_vpn_service"
+ namespace: "wear_frameworks"
+ description: "Allow removing VpnManagerService"
+ bug: "340928692"
} \ No newline at end of file
diff --git a/services/manifest_services.xml b/services/manifest_services.xml
index 8ff1a7dfa37b..114fe324f016 100644
--- a/services/manifest_services.xml
+++ b/services/manifest_services.xml
@@ -4,9 +4,4 @@
<version>2</version>
<fqname>IAltitudeService/default</fqname>
</hal>
- <hal format="aidl">
- <name>android.frameworks.vibrator</name>
- <version>1</version>
- <fqname>IVibratorControlService/default</fqname>
- </hal>
</manifest>
diff --git a/services/manifest_services_android.frameworks.vibrator.xml b/services/manifest_services_android.frameworks.vibrator.xml
new file mode 100644
index 000000000000..c287643e8697
--- /dev/null
+++ b/services/manifest_services_android.frameworks.vibrator.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="framework">
+ <hal format="aidl">
+ <name>android.frameworks.vibrator</name>
+ <version>1</version>
+ <fqname>IVibratorControlService/default</fqname>
+ </hal>
+</manifest>
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 3d40f6445834..927146db0a24 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -21,6 +21,7 @@ java_library_static {
":services.net-sources",
],
static_libs: [
+ "modules-utils-build_system",
"netd-client",
"networkstack-client",
"net-utils-services-common",
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
index 78dbc60dbae0..0b7438cd1b17 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
@@ -2687,7 +2687,7 @@ class PermissionService(private val service: AccessCheckingService) :
runtimePermissionChangedUidDevices.getOrPut(uid) { mutableSetOf() } += deviceId
}
- if (permission.hasGids && !wasPermissionGranted && isPermissionGranted) {
+ if (permission.hasGids && (wasPermissionGranted != isPermissionGranted)) {
gidsChangedUids += uid
}
}
diff --git a/services/permission/java/com/android/server/permission/access/util/AtomicFileExtensions.kt b/services/permission/java/com/android/server/permission/access/util/AtomicFileExtensions.kt
index 6b20ef1d5519..996daf5a5f68 100644
--- a/services/permission/java/com/android/server/permission/access/util/AtomicFileExtensions.kt
+++ b/services/permission/java/com/android/server/permission/access/util/AtomicFileExtensions.kt
@@ -47,9 +47,8 @@ inline fun AtomicFile.readWithReserveCopy(block: (FileInputStream) -> Unit) {
/** Write to actual file and reserve file. */
@Throws(IOException::class)
inline fun AtomicFile.writeWithReserveCopy(block: (FileOutputStream) -> Unit) {
- val reserveFile = File(baseFile.parentFile, baseFile.name + ".reservecopy")
- reserveFile.delete()
writeInlined(block)
+ val reserveFile = File(baseFile.parentFile, baseFile.name + ".reservecopy")
try {
FileInputStream(baseFile).use { inputStream ->
FileOutputStream(reserveFile).use { outputStream ->
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 977a8a05d6f3..3ed6ad78343b 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -287,7 +287,7 @@ public final class ProfcollectForwardingService extends SystemService {
if (randomNum < traceFrequency) {
BackgroundThread.get().getThreadHandler().post(() -> {
try {
- mIProfcollect.trace_once("applaunch");
+ mIProfcollect.trace_system("applaunch");
} catch (RemoteException e) {
Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage());
}
@@ -327,7 +327,7 @@ public final class ProfcollectForwardingService extends SystemService {
// Dex2oat could take a while before it starts. Add a short delay before start tracing.
BackgroundThread.get().getThreadHandler().postDelayed(() -> {
try {
- mIProfcollect.trace_once("dex2oat");
+ mIProfcollect.trace_system("dex2oat");
} catch (RemoteException e) {
Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage());
}
@@ -398,14 +398,17 @@ public final class ProfcollectForwardingService extends SystemService {
if (randomNum >= traceFrequency) {
return;
}
- // Wait for 1s before starting tracing.
+ // For a small percentage a traces, we collect the initialization behavior.
+ boolean traceInitialization = ThreadLocalRandom.current().nextInt(10) < 1;
+ int traceDelay = traceInitialization ? 0 : 1000;
+ String traceTag = traceInitialization ? "camera_init" : "camera";
BackgroundThread.get().getThreadHandler().postDelayed(() -> {
try {
- mIProfcollect.trace_once("camera");
+ mIProfcollect.trace_process(traceTag, "android.hardware.camera.provider");
} catch (RemoteException e) {
Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage());
}
- }, 1000);
+ }, traceDelay);
}
}, null);
}
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
index 2029b71034eb..ce68b863d836 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
@@ -21,6 +21,7 @@ import static android.view.WindowInsets.Type.captionBar;
import static com.android.compatibility.common.util.SystemUtil.eventually;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -33,18 +34,20 @@ import android.content.res.Configuration;
import android.graphics.Insets;
import android.os.RemoteException;
import android.provider.Settings;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
import android.util.Log;
import android.view.WindowManagerGlobal;
+import android.view.WindowManagerPolicyConstants;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
+import androidx.annotation.NonNull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
import com.android.apps.inputmethod.simpleime.ims.InputMethodServiceWrapper;
import com.android.apps.inputmethod.simpleime.testing.TestActivity;
@@ -66,6 +69,10 @@ public class InputMethodServiceTest {
private static final String TAG = "SimpleIMSTest";
private static final String INPUT_METHOD_SERVICE_NAME = ".SimpleInputMethodService";
private static final String EDIT_TEXT_DESC = "Input box";
+ private static final String INPUT_METHOD_NAV_BACK_ID =
+ "android:id/input_method_nav_back";
+ private static final String INPUT_METHOD_NAV_IME_SWITCHER_ID =
+ "android:id/input_method_nav_ime_switcher";
private static final long TIMEOUT_IN_SECONDS = 3;
private static final String ENABLE_SHOW_IME_WITH_HARD_KEYBOARD_CMD =
"settings put secure " + Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD + " 1";
@@ -99,6 +106,12 @@ public class InputMethodServiceTest {
InputMethodServiceWrapper.getInputMethodServiceWrapperForTesting();
assertThat(mInputMethodService).isNotNull();
+ // The activity gets focus.
+ assertThat(mActivity.hasWindowFocus()).isTrue();
+ assertThat(mInputMethodService.getCurrentInputEditorInfo()).isNotNull();
+ assertThat(mInputMethodService.getCurrentInputEditorInfo().packageName)
+ .isEqualTo(mTargetPackageName);
+
// The editor won't bring up keyboard by default.
assertThat(mInputMethodService.getCurrentInputStarted()).isTrue();
assertThat(mInputMethodService.getCurrentInputViewStarted()).isFalse();
@@ -691,6 +704,151 @@ public class InputMethodServiceTest {
assertThat(mInputMethodService.isImeNavigationBarShownForTesting()).isFalse();
}
+ /**
+ * Verifies that clicking on the IME navigation bar back button hides the IME.
+ */
+ @Test
+ public void testBackButtonClick() throws Exception {
+ boolean hasNavigationBar = WindowManagerGlobal.getWindowManagerService()
+ .hasNavigationBar(mInputMethodService.getDisplayId());
+ assumeTrue("Must have a navigation bar", hasNavigationBar);
+ assumeTrue("Must be in gesture navigation mode", isGestureNavEnabled());
+
+ setShowImeWithHardKeyboard(true /* enabled */);
+
+ verifyInputViewStatusOnMainSync(
+ () -> {
+ // Ensure the IME navigation bar and the IME switch button are drawn.
+ mInputMethodService.getInputMethodInternal().onNavButtonFlagsChanged(
+ InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR
+ | InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN
+ );
+ assertThat(mActivity.showImeWithWindowInsetsController()).isTrue();
+ },
+ true /* expected */,
+ true /* inputViewStarted */);
+ assertThat(mInputMethodService.isInputViewShown()).isTrue();
+
+ final var backButtonUiObject = getUiObjectById(INPUT_METHOD_NAV_BACK_ID);
+ backButtonUiObject.click();
+ mInstrumentation.waitForIdleSync();
+
+ assertThat(mInputMethodService.isInputViewShown()).isFalse();
+ }
+
+ /**
+ * Verifies that long clicking on the IME navigation bar back button hides the IME.
+ */
+ @Test
+ public void testBackButtonLongClick() throws Exception {
+ boolean hasNavigationBar = WindowManagerGlobal.getWindowManagerService()
+ .hasNavigationBar(mInputMethodService.getDisplayId());
+ assumeTrue("Must have a navigation bar", hasNavigationBar);
+ assumeTrue("Must be in gesture navigation mode", isGestureNavEnabled());
+
+ setShowImeWithHardKeyboard(true /* enabled */);
+
+ verifyInputViewStatusOnMainSync(
+ () -> {
+ // Ensure the IME navigation bar and the IME switch button are drawn.
+ mInputMethodService.getInputMethodInternal().onNavButtonFlagsChanged(
+ InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR
+ | InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN
+ );
+ assertThat(mActivity.showImeWithWindowInsetsController()).isTrue();
+ },
+ true /* expected */,
+ true /* inputViewStarted */);
+ assertThat(mInputMethodService.isInputViewShown()).isTrue();
+
+ final var backButtonUiObject = getUiObjectById(INPUT_METHOD_NAV_BACK_ID);
+ backButtonUiObject.longClick();
+ mInstrumentation.waitForIdleSync();
+
+ assertThat(mInputMethodService.isInputViewShown()).isFalse();
+ }
+
+ /**
+ * Verifies that clicking on the IME switch button shows the Input Method Switcher Menu.
+ */
+ @Test
+ public void testImeSwitchButtonClick() throws Exception {
+ boolean hasNavigationBar = WindowManagerGlobal.getWindowManagerService()
+ .hasNavigationBar(mInputMethodService.getDisplayId());
+ assumeTrue("Must have a navigation bar", hasNavigationBar);
+ assumeTrue("Must be in gesture navigation mode", isGestureNavEnabled());
+
+ setShowImeWithHardKeyboard(true /* enabled */);
+
+ verifyInputViewStatusOnMainSync(
+ () -> {
+ // Ensure the IME navigation bar and the IME switch button are drawn.
+ mInputMethodService.getInputMethodInternal().onNavButtonFlagsChanged(
+ InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR
+ | InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN
+ );
+ assertThat(mActivity.showImeWithWindowInsetsController()).isTrue();
+ },
+ true /* expected */,
+ true /* inputViewStarted */);
+ assertThat(mInputMethodService.isInputViewShown()).isTrue();
+
+ final var imm = mContext.getSystemService(InputMethodManager.class);
+
+ final var imeSwitchButtonUiObject = getUiObjectById(INPUT_METHOD_NAV_IME_SWITCHER_ID);
+ imeSwitchButtonUiObject.click();
+ mInstrumentation.waitForIdleSync();
+
+ assertWithMessage("Input Method Switcher Menu is shown")
+ .that(isInputMethodPickerShown(imm))
+ .isTrue();
+
+ assertThat(mInputMethodService.isInputViewShown()).isTrue();
+
+ // Hide the Picker menu before finishing.
+ mUiDevice.pressBack();
+ }
+
+ /**
+ * Verifies that long clicking on the IME switch button shows the Input Method Switcher Menu.
+ */
+ @Test
+ public void testImeSwitchButtonLongClick() throws Exception {
+ boolean hasNavigationBar = WindowManagerGlobal.getWindowManagerService()
+ .hasNavigationBar(mInputMethodService.getDisplayId());
+ assumeTrue("Must have a navigation bar", hasNavigationBar);
+ assumeTrue("Must be in gesture navigation mode", isGestureNavEnabled());
+
+ setShowImeWithHardKeyboard(true /* enabled */);
+
+ verifyInputViewStatusOnMainSync(
+ () -> {
+ // Ensure the IME navigation bar and the IME switch button are drawn.
+ mInputMethodService.getInputMethodInternal().onNavButtonFlagsChanged(
+ InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR
+ | InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN
+ );
+ assertThat(mActivity.showImeWithWindowInsetsController()).isTrue();
+ },
+ true /* expected */,
+ true /* inputViewStarted */);
+ assertThat(mInputMethodService.isInputViewShown()).isTrue();
+
+ final var imm = mContext.getSystemService(InputMethodManager.class);
+
+ final var imeSwitchButtonUiObject = getUiObjectById(INPUT_METHOD_NAV_IME_SWITCHER_ID);
+ imeSwitchButtonUiObject.longClick();
+ mInstrumentation.waitForIdleSync();
+
+ assertWithMessage("Input Method Switcher Menu is shown")
+ .that(isInputMethodPickerShown(imm))
+ .isTrue();
+ assertThat(mInputMethodService.isInputViewShown()).isTrue();
+
+ // Hide the Picker menu before finishing.
+ mUiDevice.pressBack();
+ }
+
private void verifyInputViewStatus(
Runnable runnable, boolean expected, boolean inputViewStarted)
throws InterruptedException {
@@ -838,6 +996,32 @@ public class InputMethodServiceTest {
return SystemUtil.runShellCommandOrThrow(cmd);
}
+ /**
+ * Checks if the Input Method Switcher Menu is shown. This runs by adopting the Shell's
+ * permission to ensure we have TEST_INPUT_METHOD permission.
+ */
+ private static boolean isInputMethodPickerShown(@NonNull InputMethodManager imm) {
+ return SystemUtil.runWithShellPermissionIdentity(imm::isInputMethodPickerShown);
+ }
+
+ @NonNull
+ private UiObject2 getUiObjectById(@NonNull String id) {
+ final var uiObject = mUiDevice.wait(
+ Until.findObject(By.res(id)),
+ TimeUnit.SECONDS.toMillis(TIMEOUT_IN_SECONDS));
+ assertThat(uiObject).isNotNull();
+ return uiObject;
+ }
+
+ /**
+ * Returns {@code true} if the navigation mode is gesture nav, and {@code false} otherwise.
+ */
+ private boolean isGestureNavEnabled() {
+ return mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_navBarInteractionMode)
+ == WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+ }
+
private void clickOnEditorText() {
// Find the editText and click it.
UiObject2 editTextUiObject =
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java
index 70903cbc2b94..4d28b3c854ff 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java
@@ -140,7 +140,8 @@ public class InputMethodBindingControllerTest extends InputMethodManagerServiceT
final InputMethodInfo info;
synchronized (ImfLock.class) {
mBindingController.setSelectedMethodId(TEST_IME_ID);
- info = mInputMethodManagerService.queryInputMethodForCurrentUserLocked(TEST_IME_ID);
+ info = InputMethodSettingsRepository.get(mCallingUserId).getMethodMap()
+ .get(TEST_IME_ID);
}
assertThat(info).isNotNull();
assertThat(info.getId()).isEqualTo(TEST_IME_ID);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
index 80eab112d814..c2a069d17446 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
@@ -25,6 +25,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.notNull;
@@ -35,17 +36,22 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityManagerInternal;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.res.Configuration;
import android.hardware.input.IInputManager;
import android.hardware.input.InputManagerGlobal;
import android.os.Binder;
+import android.os.Handler;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.util.ArraySet;
import android.view.InputChannel;
import android.view.inputmethod.EditorInfo;
import android.window.ImeOnBackInvokedDispatcher;
@@ -62,7 +68,6 @@ import com.android.internal.inputmethod.InputBindResult;
import com.android.internal.view.IInputMethodManager;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
-import com.android.server.SystemServerInitThreadPool;
import com.android.server.SystemService;
import com.android.server.input.InputManagerInternal;
import com.android.server.pm.UserManagerInternal;
@@ -131,6 +136,14 @@ public class InputMethodManagerServiceTestBase {
protected boolean mIsLargeScreen;
private InputManagerGlobal.TestSession mInputManagerGlobalSession;
+ private final ArraySet<Class<?>> mRegisteredLocalServices = new ArraySet<>();
+
+ protected <T> void addLocalServiceMock(Class<T> type, T service) {
+ mRegisteredLocalServices.add(type);
+ LocalServices.removeServiceForTest(type);
+ LocalServices.addService(type, service);
+ }
+
@BeforeClass
public static void setupClass() {
// Make sure DeviceConfig's lazy-initialized ContentProvider gets
@@ -145,9 +158,9 @@ public class InputMethodManagerServiceTestBase {
mockitoSession()
.initMocks(this)
.strictness(Strictness.LENIENT)
- .spyStatic(LocalServices.class)
+ .spyStatic(InputMethodUtils.class)
.mockStatic(ServiceManager.class)
- .mockStatic(SystemServerInitThreadPool.class)
+ .spyStatic(AdditionalSubtypeMapRepository.class)
.startMocking();
mContext = spy(InstrumentationRegistry.getInstrumentation().getContext());
@@ -160,18 +173,13 @@ public class InputMethodManagerServiceTestBase {
mEditorInfo.packageName = TEST_EDITOR_PKG_NAME;
// Injecting and mocking local services.
- doReturn(mMockWindowManagerInternal)
- .when(() -> LocalServices.getService(WindowManagerInternal.class));
- doReturn(mMockActivityManagerInternal)
- .when(() -> LocalServices.getService(ActivityManagerInternal.class));
- doReturn(mMockPackageManagerInternal)
- .when(() -> LocalServices.getService(PackageManagerInternal.class));
- doReturn(mMockInputManagerInternal)
- .when(() -> LocalServices.getService(InputManagerInternal.class));
- doReturn(mMockUserManagerInternal)
- .when(() -> LocalServices.getService(UserManagerInternal.class));
- doReturn(mMockImeTargetVisibilityPolicy)
- .when(() -> LocalServices.getService(ImeTargetVisibilityPolicy.class));
+ addLocalServiceMock(WindowManagerInternal.class, mMockWindowManagerInternal);
+ addLocalServiceMock(ActivityManagerInternal.class, mMockActivityManagerInternal);
+ addLocalServiceMock(PackageManagerInternal.class, mMockPackageManagerInternal);
+ addLocalServiceMock(InputManagerInternal.class, mMockInputManagerInternal);
+ addLocalServiceMock(UserManagerInternal.class, mMockUserManagerInternal);
+ addLocalServiceMock(ImeTargetVisibilityPolicy.class, mMockImeTargetVisibilityPolicy);
+
doReturn(mMockIInputMethodManager)
.when(() -> ServiceManager.getServiceOrThrow(Context.INPUT_METHOD_SERVICE));
doReturn(mMockIPlatformCompat)
@@ -182,6 +190,9 @@ public class InputMethodManagerServiceTestBase {
doNothing().when(mContext).enforceCallingPermission(anyString(), anyString());
doNothing().when(mContext).sendBroadcastAsUser(any(), any());
doReturn(null).when(mContext).registerReceiver(any(), any());
+ doReturn(null).when(mContext).registerReceiver(
+ any(BroadcastReceiver.class),
+ any(IntentFilter.class), anyString(), any(Handler.class));
doReturn(null)
.when(mContext)
.registerReceiverAsUser(any(), any(), any(), anyString(), any(), anyInt());
@@ -218,23 +229,32 @@ public class InputMethodManagerServiceTestBase {
.thenReturn(TEST_IME_TARGET_INFO);
when(mMockInputMethodClient.asBinder()).thenReturn(mMockInputMethodBinder);
- // Used by lazy initializing draw IMS nav bar at InputMethodManagerService#systemRunning(),
- // which is ok to be mocked out for now.
- doReturn(null).when(() -> SystemServerInitThreadPool.submit(any(), anyString()));
+ // This changes the real IME component state. Not appropriate to do in tests.
+ doNothing().when(() -> InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
+ any(PackageManager.class), anyList()));
+
+ // The background writer thread in AdditionalSubtypeMapRepository should be stubbed out.
+ doNothing().when(AdditionalSubtypeMapRepository::startWriterThread);
mServiceThread =
new ServiceThread(
"immstest1",
Process.THREAD_PRIORITY_FOREGROUND,
true /* allowIo */);
+ mServiceThread.start();
mIoThread =
new ServiceThread(
"immstest2",
Process.THREAD_PRIORITY_FOREGROUND,
true /* allowIo */);
+ mIoThread.start();
+
+ final var ioHandler = spy(Handler.createAsync(mIoThread.getLooper()));
+ doReturn(true).when(ioHandler).post(any());
+
mInputMethodManagerService = new InputMethodManagerService(mContext,
- InputMethodManagerService.shouldEnableExperimentalConcurrentMultiUserMode(mContext),
- mServiceThread, mIoThread,
+ InputMethodManagerService.shouldEnableConcurrentMultiUserMode(mContext),
+ mServiceThread.getLooper(), ioHandler,
unusedUserId -> mMockInputMethodBindingController);
spyOn(mInputMethodManagerService);
@@ -246,16 +266,9 @@ public class InputMethodManagerServiceTestBase {
// Public local InputMethodManagerService.
LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
lifecycle.onStart();
- try {
- // After this boot phase, services can broadcast Intents.
- lifecycle.onBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
- } catch (SecurityException e) {
- // Security exception to permission denial is expected in test, mocking out to ensure
- // InputMethodManagerService as system ready state.
- if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
- throw e;
- }
- }
+
+ // After this boot phase, services can broadcast Intents.
+ lifecycle.onBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
// Call InputMethodManagerService#addClient() as a preparation to start interacting with it.
mInputMethodManagerService.addClient(mMockInputMethodClient, mMockRemoteInputConnection, 0);
@@ -283,7 +296,7 @@ public class InputMethodManagerServiceTestBase {
if (mInputManagerGlobalSession != null) {
mInputManagerGlobalSession.close();
}
- LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
+ mRegisteredLocalServices.forEach(LocalServices::removeServiceForTest);
}
protected void verifyShowSoftInput(boolean setVisible, boolean showSoftInput)
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceWindowGainedFocusTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceWindowGainedFocusTest.java
index 9f46d0ba7df6..ffc4df8f2069 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceWindowGainedFocusTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceWindowGainedFocusTest.java
@@ -50,7 +50,6 @@ import com.android.internal.inputmethod.InputBindResult;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputReason;
-import com.android.server.LocalServices;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.wm.WindowManagerInternal;
@@ -270,8 +269,7 @@ public class InputMethodManagerServiceWindowGainedFocusTest
@Test
public void startInputOrWindowGainedFocus_localeHintsOverride() throws RemoteException {
- doReturn(mMockVdmInternal).when(
- () -> LocalServices.getService(VirtualDeviceManagerInternal.class));
+ addLocalServiceMock(VirtualDeviceManagerInternal.class, mMockVdmInternal);
LocaleList overrideLocale = LocaleList.forLanguageTags("zh-CN");
doReturn(overrideLocale).when(mMockVdmInternal).getPreferredLocaleListForUid(anyInt());
mockHasImeFocusAndRestoreImeVisibility(false /* restoreImeVisibility */);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
index e81cf9df6660..dc0373239547 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
@@ -16,15 +16,26 @@
package com.android.server.inputmethod;
+import static com.android.server.inputmethod.InputMethodSubtypeSwitchingController.MODE_AUTO;
+import static com.android.server.inputmethod.InputMethodSubtypeSwitchingController.MODE_RECENT;
+import static com.android.server.inputmethod.InputMethodSubtypeSwitchingController.MODE_STATIC;
+import static com.android.server.inputmethod.InputMethodSubtypeSwitchingController.SwitchMode;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.view.inputmethod.Flags;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
@@ -35,6 +46,7 @@ import androidx.annotation.Nullable;
import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ControllerImpl;
import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
+import org.junit.Rule;
import org.junit.Test;
import java.util.ArrayList;
@@ -51,6 +63,9 @@ public final class InputMethodSubtypeSwitchingControllerTest {
private static final String SYSTEM_LOCALE = "en_US";
private static final int NOT_A_SUBTYPE_ID = InputMethodUtils.NOT_A_SUBTYPE_ID;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
@NonNull
private static InputMethodSubtype createTestSubtype(@NonNull String locale) {
return new InputMethodSubtypeBuilder()
@@ -170,7 +185,7 @@ public final class InputMethodSubtypeSwitchingControllerTest {
subtype = createTestSubtype(currentItem.mSubtypeName.toString());
}
final ImeSubtypeListItem nextIme = controller.getNextInputMethod(onlyCurrentIme,
- currentItem.mImi, subtype);
+ currentItem.mImi, subtype, MODE_STATIC, true /* forward */);
assertEquals(nextItem, nextIme);
}
@@ -185,15 +200,16 @@ public final class InputMethodSubtypeSwitchingControllerTest {
}
}
- private void onUserAction(@NonNull ControllerImpl controller,
+ private boolean onUserAction(@NonNull ControllerImpl controller,
@NonNull ImeSubtypeListItem subtypeListItem) {
InputMethodSubtype subtype = null;
if (subtypeListItem.mSubtypeName != null) {
subtype = createTestSubtype(subtypeListItem.mSubtypeName.toString());
}
- controller.onUserActionLocked(subtypeListItem.mImi, subtype);
+ return controller.onUserActionLocked(subtypeListItem.mImi, subtype);
}
+ @RequiresFlagsDisabled(Flags.FLAG_IME_SWITCHER_REVAMP)
@Test
public void testControllerImpl() {
final List<ImeSubtypeListItem> disabledItems = createDisabledImeSubtypes();
@@ -213,7 +229,7 @@ public final class InputMethodSubtypeSwitchingControllerTest {
final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(7);
final ControllerImpl controller = ControllerImpl.createFrom(
- null /* currentInstance */, enabledItems);
+ null /* currentInstance */, enabledItems, new ArrayList<>());
// switching-aware loop
assertRotationOrder(controller, false /* onlyCurrentIme */,
@@ -257,6 +273,7 @@ public final class InputMethodSubtypeSwitchingControllerTest {
disabledSubtypeUnawareIme, null);
}
+ @RequiresFlagsDisabled(Flags.FLAG_IME_SWITCHER_REVAMP)
@Test
public void testControllerImplWithUserAction() {
final List<ImeSubtypeListItem> enabledItems = createEnabledImeSubtypes();
@@ -270,7 +287,7 @@ public final class InputMethodSubtypeSwitchingControllerTest {
final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(7);
final ControllerImpl controller = ControllerImpl.createFrom(
- null /* currentInstance */, enabledItems);
+ null /* currentInstance */, enabledItems, new ArrayList<>());
// === switching-aware loop ===
assertRotationOrder(controller, false /* onlyCurrentIme */,
@@ -320,7 +337,7 @@ public final class InputMethodSubtypeSwitchingControllerTest {
// Rotation order should be preserved when created with the same subtype list.
final List<ImeSubtypeListItem> sameEnabledItems = createEnabledImeSubtypes();
final ControllerImpl newController = ControllerImpl.createFrom(controller,
- sameEnabledItems);
+ sameEnabledItems, new ArrayList<>());
assertRotationOrder(newController, false /* onlyCurrentIme */,
subtypeAwareIme, latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
assertRotationOrder(newController, false /* onlyCurrentIme */,
@@ -332,7 +349,7 @@ public final class InputMethodSubtypeSwitchingControllerTest {
latinIme_en_us, latinIme_fr, subtypeAwareIme, switchingUnawareLatinIme_en_uk,
switchUnawareJapaneseIme_ja_jp, subtypeUnawareIme);
final ControllerImpl anotherController = ControllerImpl.createFrom(controller,
- differentEnabledItems);
+ differentEnabledItems, new ArrayList<>());
assertRotationOrder(anotherController, false /* onlyCurrentIme */,
latinIme_en_us, latinIme_fr, subtypeAwareIme);
assertRotationOrder(anotherController, false /* onlyCurrentIme */,
@@ -370,6 +387,7 @@ public final class InputMethodSubtypeSwitchingControllerTest {
assertFalse(item_en_us_allcaps.mIsSystemLanguage);
}
+ @RequiresFlagsDisabled(Flags.FLAG_IME_SWITCHER_REVAMP)
@SuppressWarnings("SelfComparison")
@Test
public void testImeSubtypeListComparator() {
@@ -471,4 +489,739 @@ public final class InputMethodSubtypeSwitchingControllerTest {
assertNotEquals(ime2, ime1);
}
}
+
+ /** Verifies the static mode. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testModeStatic() {
+ final var items = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(items, "LatinIme", "LatinIme",
+ List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */);
+ addTestImeSubtypeListItems(items, "SimpleIme", "SimpleIme",
+ null, true /* supportsSwitchingToNextInputMethod */);
+
+ final var english = items.get(0);
+ final var french = items.get(1);
+ final var italian = items.get(2);
+ final var simple = items.get(3);
+ final var latinIme = List.of(english, french, italian);
+ final var simpleIme = List.of(simple);
+
+ final var hardwareItems = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(hardwareItems, "HardwareLatinIme", "HardwareLatinIme",
+ List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */);
+ addTestImeSubtypeListItems(hardwareItems, "HardwareSimpleIme", "HardwareSimpleIme",
+ null, true /* supportsSwitchingToNextInputMethod */);
+
+ final var hardwareEnglish = hardwareItems.get(0);
+ final var hardwareFrench = hardwareItems.get(1);
+ final var hardwareItalian = hardwareItems.get(2);
+ final var hardwareSimple = hardwareItems.get(3);
+ final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian);
+ final var hardwareSimpleIme = List.of(hardwareSimple);
+
+ final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
+ hardwareItems);
+
+ final int mode = MODE_STATIC;
+
+ // Static mode matches the given items order.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ items, List.of(latinIme, simpleIme));
+
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ // Set french IME as most recent.
+ assertTrue("Recency updated for french IME", onUserAction(controller, french));
+
+ // Static mode is not influenced by recency updates on non-hardware item.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ items, List.of(latinIme, simpleIme));
+
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ assertTrue("Recency updated for french hardware IME",
+ onUserAction(controller, hardwareFrench));
+
+ // Static mode is not influenced by recency updates on hardware item.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ items, List.of(latinIme, simpleIme));
+
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+ }
+
+ /** Verifies the recency mode. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testModeRecent() {
+ final var items = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(items, "LatinIme", "LatinIme",
+ List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */);
+ addTestImeSubtypeListItems(items, "SimpleIme", "SimpleIme",
+ null, true /* supportsSwitchingToNextInputMethod */);
+
+ final var english = items.get(0);
+ final var french = items.get(1);
+ final var italian = items.get(2);
+ final var simple = items.get(3);
+ final var latinIme = List.of(english, french, italian);
+ final var simpleIme = List.of(simple);
+
+ final var hardwareItems = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(hardwareItems, "HardwareLatinIme", "HardwareLatinIme",
+ List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */);
+ addTestImeSubtypeListItems(hardwareItems, "HardwareSimpleIme", "HardwareSimpleIme",
+ null, true /* supportsSwitchingToNextInputMethod */);
+
+ final var hardwareEnglish = hardwareItems.get(0);
+ final var hardwareFrench = hardwareItems.get(1);
+ final var hardwareItalian = hardwareItems.get(2);
+ final var hardwareSimple = hardwareItems.get(3);
+ final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian);
+ final var hardwareSimpleIme = List.of(hardwareSimple);
+
+ final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
+ hardwareItems);
+
+ final int mode = MODE_RECENT;
+
+ // Recency order is initialized to static order.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ items, List.of(latinIme, simpleIme));
+
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ assertTrue("Recency updated for french IME", onUserAction(controller, french));
+ final var recencyItems = List.of(french, english, italian, simple);
+ final var recencyLatinIme = List.of(french, english, italian);
+ final var recencySimpleIme = List.of(simple);
+
+ // The order of non-hardware items is updated.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ recencyItems, List.of(recencyLatinIme, recencySimpleIme));
+
+ // The order of hardware items remains unchanged for an action on a non-hardware item.
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ assertFalse("Recency not updated again for same IME", onUserAction(controller, french));
+
+ // The order of non-hardware items remains unchanged.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ recencyItems, List.of(recencyLatinIme, recencySimpleIme));
+
+ // The order of hardware items remains unchanged.
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ assertTrue("Recency updated for french hardware IME",
+ onUserAction(controller, hardwareFrench));
+
+ final var recencyHardwareItems =
+ List.of(hardwareFrench, hardwareEnglish, hardwareItalian, hardwareSimple);
+ final var recencyHardwareLatinIme =
+ List.of(hardwareFrench, hardwareEnglish, hardwareItalian);
+ final var recencyHardwareSimpleIme = List.of(hardwareSimple);
+
+ // The order of non-hardware items is unchanged.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ recencyItems, List.of(recencyLatinIme, recencySimpleIme));
+
+ // The order of hardware items is updated.
+ assertNextOrder(controller, true /* forHardware */, mode,
+ recencyHardwareItems, List.of(recencyHardwareLatinIme, recencyHardwareSimpleIme));
+ }
+
+ /** Verifies the auto mode. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testModeAuto() {
+ final var items = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(items, "LatinIme", "LatinIme",
+ List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */);
+ addTestImeSubtypeListItems(items, "SimpleIme", "SimpleIme",
+ null, true /* supportsSwitchingToNextInputMethod */);
+
+ final var english = items.get(0);
+ final var french = items.get(1);
+ final var italian = items.get(2);
+ final var simple = items.get(3);
+ final var latinIme = List.of(english, french, italian);
+ final var simpleIme = List.of(simple);
+
+ final var hardwareItems = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(hardwareItems, "HardwareLatinIme", "HardwareLatinIme",
+ List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */);
+ addTestImeSubtypeListItems(hardwareItems, "HardwareSimpleIme", "HardwareSimpleIme",
+ null, true /* supportsSwitchingToNextInputMethod */);
+
+ final var hardwareEnglish = hardwareItems.get(0);
+ final var hardwareFrench = hardwareItems.get(1);
+ final var hardwareItalian = hardwareItems.get(2);
+ final var hardwareSimple = hardwareItems.get(3);
+ final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian);
+ final var hardwareSimpleIme = List.of(hardwareSimple);
+
+ final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
+ hardwareItems);
+
+ final int mode = MODE_AUTO;
+
+ // Auto mode resolves to static order initially.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ items, List.of(latinIme, simpleIme));
+
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ // User action on french IME.
+ assertTrue("Recency updated for french IME", onUserAction(controller, french));
+
+ final var recencyItems = List.of(french, english, italian, simple);
+ final var recencyLatinIme = List.of(french, english, italian);
+ final var recencySimpleIme = List.of(simple);
+
+ // Auto mode resolves to recency order for the first forward after user action, and to
+ // static order for the backwards direction.
+ assertNextOrder(controller, false /* forHardware */, mode, true /* forward */,
+ recencyItems, List.of(recencyLatinIme, recencySimpleIme));
+ assertNextOrder(controller, false /* forHardware */, mode, false /* forward */,
+ items.reversed(), List.of(latinIme.reversed(), simpleIme.reversed()));
+
+ // Auto mode resolves to recency order for the first forward after user action,
+ // but the recency was not updated for hardware items, so it's equivalent to static order.
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ // Change IME, reset user action having happened.
+ controller.onInputMethodSubtypeChanged();
+
+ // Auto mode resolves to static order as there was no user action since changing IMEs.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ items, List.of(latinIme, simpleIme));
+
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ // User action on french IME again.
+ assertFalse("Recency not updated again for same IME", onUserAction(controller, french));
+
+ // Auto mode still resolves to static order, as a user action on the currently most
+ // recent IME has no effect.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ items, List.of(latinIme, simpleIme));
+
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ // User action on hardware french IME.
+ assertTrue("Recency updated for french hardware IME",
+ onUserAction(controller, hardwareFrench));
+
+ final var recencyHardware =
+ List.of(hardwareFrench, hardwareEnglish, hardwareItalian, hardwareSimple);
+ final var recencyHardwareLatin =
+ List.of(hardwareFrench, hardwareEnglish, hardwareItalian);
+ final var recencyHardwareSimple = List.of(hardwareSimple);
+
+ // Auto mode resolves to recency order for the first forward direction after a user action
+ // on a hardware IME, and to static order for the backwards direction.
+ assertNextOrder(controller, false /* forHardware */, mode, true /* forward */,
+ recencyItems, List.of(recencyLatinIme, recencySimpleIme));
+ assertNextOrder(controller, false /* forHardware */, mode, false /* forward */,
+ items.reversed(), List.of(latinIme.reversed(), simpleIme.reversed()));
+
+ assertNextOrder(controller, true /* forHardware */, mode, true /* forward */,
+ recencyHardware, List.of(recencyHardwareLatin, recencyHardwareSimple));
+
+ assertNextOrder(controller, true /* forHardware */, mode, false /* forward */,
+ hardwareItems.reversed(),
+ List.of(hardwareLatinIme.reversed(), hardwareSimpleIme.reversed()));
+ }
+
+ /**
+ * Verifies that the recency order is preserved only when updating with an equal list of items.
+ */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testUpdateList() {
+ final var items = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(items, "LatinIme", "LatinIme",
+ List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */);
+ addTestImeSubtypeListItems(items, "SimpleIme", "SimpleIme",
+ null, true /* supportsSwitchingToNextInputMethod */);
+
+ final var english = items.get(0);
+ final var french = items.get(1);
+ final var italian = items.get(2);
+ final var simple = items.get(3);
+
+ final var latinIme = List.of(english, french, italian);
+ final var simpleIme = List.of(simple);
+
+ final var hardwareItems = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(hardwareItems, "HardwareLatinIme", "HardwareLatinIme",
+ List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */);
+ addTestImeSubtypeListItems(hardwareItems, "HardwareSimpleIme", "HardwareSimpleIme",
+ null, true /* supportsSwitchingToNextInputMethod */);
+
+ final var hardwareEnglish = hardwareItems.get(0);
+ final var hardwareFrench = hardwareItems.get(1);
+ final var hardwareItalian = hardwareItems.get(2);
+ final var hardwareSimple = hardwareItems.get(3);
+
+ final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian);
+ final var hardwareSimpleIme = List.of(hardwareSimple);
+
+ final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
+ hardwareItems);
+
+ final int mode = MODE_RECENT;
+
+ // Recency order is initialized to static order.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ items, List.of(latinIme, simpleIme));
+
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ // User action on french IME.
+ assertTrue("Recency updated for french IME", onUserAction(controller, french));
+
+ final var equalItems = new ArrayList<>(items);
+ final var otherItems = new ArrayList<>(items);
+ otherItems.remove(simple);
+
+ final var equalController = ControllerImpl.createFrom(controller, equalItems,
+ hardwareItems);
+ final var otherController = ControllerImpl.createFrom(controller, otherItems,
+ hardwareItems);
+
+ final var recencyItems = List.of(french, english, italian, simple);
+ final var recencyLatinIme = List.of(french, english, italian);
+ final var recencySimpleIme = List.of(simple);
+
+ assertNextOrder(controller, false /* forHardware */, mode,
+ recencyItems, List.of(recencyLatinIme, recencySimpleIme));
+
+ // The order of equal non-hardware items is unchanged.
+ assertNextOrder(equalController, false /* forHardware */, mode,
+ recencyItems, List.of(recencyLatinIme, recencySimpleIme));
+
+ // The order of other hardware items is reset.
+ assertNextOrder(otherController, false /* forHardware */, mode,
+ latinIme, List.of(latinIme));
+
+ // The order of hardware remains unchanged.
+ assertNextOrder(controller, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ assertNextOrder(equalController, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ assertNextOrder(otherController, true /* forHardware */, mode,
+ hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+
+ assertTrue("Recency updated for french hardware IME",
+ onUserAction(controller, hardwareFrench));
+
+ final var equalHardwareItems = new ArrayList<>(hardwareItems);
+ final var otherHardwareItems = new ArrayList<>(hardwareItems);
+ otherHardwareItems.remove(hardwareSimple);
+
+ final var equalHardwareController = ControllerImpl.createFrom(controller, items,
+ equalHardwareItems);
+ final var otherHardwareController = ControllerImpl.createFrom(controller, items,
+ otherHardwareItems);
+
+ final var recencyHardwareItems =
+ List.of(hardwareFrench, hardwareEnglish, hardwareItalian, hardwareSimple);
+ final var recencyHardwareLatinIme =
+ List.of(hardwareFrench, hardwareEnglish, hardwareItalian);
+ final var recencyHardwareSimpleIme = List.of(hardwareSimple);
+
+ // The order of non-hardware items remains unchanged.
+ assertNextOrder(controller, false /* forHardware */, mode,
+ recencyItems, List.of(recencyLatinIme, recencySimpleIme));
+
+ assertNextOrder(equalHardwareController, false /* forHardware */, mode,
+ recencyItems, List.of(recencyLatinIme, recencySimpleIme));
+
+ assertNextOrder(otherHardwareController, false /* forHardware */, mode,
+ recencyItems, List.of(recencyLatinIme, recencySimpleIme));
+
+ assertNextOrder(controller, true /* forHardware */, mode,
+ recencyHardwareItems, List.of(recencyHardwareLatinIme, recencyHardwareSimpleIme));
+
+ // The order of equal hardware items is unchanged.
+ assertNextOrder(equalHardwareController, true /* forHardware */, mode,
+ recencyHardwareItems, List.of(recencyHardwareLatinIme, recencyHardwareSimpleIme));
+
+ // The order of other hardware items is reset.
+ assertNextOrder(otherHardwareController, true /* forHardware */, mode,
+ hardwareLatinIme, List.of(hardwareLatinIme));
+ }
+
+ /** Verifies that switch aware and switch unaware IMEs are combined together. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testSwitchAwareAndUnawareCombined() {
+ final var items = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(items, "switchAware", "switchAware",
+ null, true /* supportsSwitchingToNextInputMethod*/);
+ addTestImeSubtypeListItems(items, "switchUnaware", "switchUnaware",
+ null, false /* supportsSwitchingToNextInputMethod*/);
+
+ final var hardwareItems = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(hardwareItems, "hardwareSwitchAware", "hardwareSwitchAware",
+ null, true /* supportsSwitchingToNextInputMethod*/);
+ addTestImeSubtypeListItems(hardwareItems, "hardwareSwitchUnaware", "hardwareSwitchUnaware",
+ null, false /* supportsSwitchingToNextInputMethod*/);
+
+ final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
+ hardwareItems);
+
+ for (int mode = MODE_STATIC; mode <= MODE_AUTO; mode++) {
+ assertNextOrder(controller, false /* forHardware */, false /* onlyCurrentIme */,
+ mode, true /* forward */, items);
+ assertNextOrder(controller, false /* forHardware */, false /* onlyCurrentIme */,
+ mode, false /* forward */, items.reversed());
+
+ assertNextOrder(controller, true /* forHardware */, false /* onlyCurrentIme */,
+ mode, true /* forward */, hardwareItems);
+ assertNextOrder(controller, true /* forHardware */, false /* onlyCurrentIme */,
+ mode, false /* forward */, hardwareItems.reversed());
+ }
+ }
+
+ /** Verifies that an empty controller can't take any actions. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testEmptyList() {
+ final var items = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(items, "LatinIme", "LatinIme",
+ List.of("en", "fr"), true /* supportsSwitchingToNextInputMethod */);
+
+ final var hardwareItems = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(hardwareItems, "HardwareIme", "HardwareIme",
+ List.of("en", "fr"), true /* supportsSwitchingToNextInputMethod */);
+
+ final var controller = ControllerImpl.createFrom(null /* currentInstance */, List.of(),
+ List.of());
+
+ assertNoAction(controller, false /* forHardware */, items);
+ assertNoAction(controller, true /* forHardware */, hardwareItems);
+ }
+
+ /** Verifies that a controller with a single item can't take any actions. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testSingleItemList() {
+ final var items = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(items, "LatinIme", "LatinIme",
+ List.of("en", "fr"), true /* supportsSwitchingToNextInputMethod */);
+
+ final var hardwareItems = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(hardwareItems, "HardwareIme", "HardwareIme",
+ List.of("en", "fr"), true /* supportsSwitchingToNextInputMethod */);
+
+ final var controller = ControllerImpl.createFrom(null /* currentInstance */,
+ List.of(items.get(0)), List.of(hardwareItems.get(0)));
+
+ assertNoAction(controller, false /* forHardware */, items);
+ assertNoAction(controller, true /* forHardware */, hardwareItems);
+ }
+
+ /** Verifies that a controller can't take any actions for unknown items. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testUnknownItems() {
+ final var items = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(items, "LatinIme", "LatinIme",
+ List.of("en", "fr"), true /* supportsSwitchingToNextInputMethod */);
+ final var unknownItems = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(unknownItems, "UnknownIme", "UnknownIme",
+ List.of("en", "fr"), true /* supportsSwitchingToNextInputMethod */);
+
+ final var hardwareItems = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(hardwareItems, "HardwareIme", "HardwareIme",
+ List.of("en", "fr"), true /* supportsSwitchingToNextInputMethod */);
+ final var unknownHardwareItems = new ArrayList<ImeSubtypeListItem>();
+ addTestImeSubtypeListItems(unknownHardwareItems, "HardwareUnknownIme", "HardwareUnknownIme",
+ List.of("en", "fr"), true /* supportsSwitchingToNextInputMethod */);
+
+ final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
+ hardwareItems);
+
+ assertNoAction(controller, false /* forHardware */, unknownItems);
+ assertNoAction(controller, true /* forHardware */, unknownHardwareItems);
+ }
+
+ /** Verifies that the IME name does influence the comparison order. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testCompareImeName() {
+ final var component = new ComponentName("com.example.ime", "Ime");
+ final var imeX = createTestItem(component, "ImeX", "A", "en_US", 0);
+ final var imeY = createTestItem(component, "ImeY", "A", "en_US", 0);
+
+ assertTrue("Smaller IME name should be smaller.", imeX.compareTo(imeY) < 0);
+ assertTrue("Larger IME name should be larger.", imeY.compareTo(imeX) > 0);
+ }
+
+ /** Verifies that the IME ID does influence the comparison order. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testCompareImeId() {
+ final var component1 = new ComponentName("com.example.ime1", "Ime");
+ final var component2 = new ComponentName("com.example.ime2", "Ime");
+ final var ime1 = createTestItem(component1, "Ime", "A", "en_US", 0);
+ final var ime2 = createTestItem(component2, "Ime", "A", "en_US", 0);
+
+ assertTrue("Smaller IME ID should be smaller.", ime1.compareTo(ime2) < 0);
+ assertTrue("Larger IME ID should be larger.", ime2.compareTo(ime1) > 0);
+ }
+
+ /** Verifies that comparison on self returns an equal order. */
+ @SuppressWarnings("SelfComparison")
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testCompareSelf() {
+ final var component = new ComponentName("com.example.ime", "Ime");
+ final var item = createTestItem(component, "Ime", "A", "en_US", 0);
+
+ assertEquals("Item should have the same order to itself.", 0, item.compareTo(item));
+ }
+
+ /** Verifies that comparison on an equivalent item returns an equal order. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testCompareEquivalent() {
+ final var component = new ComponentName("com.example.ime", "Ime");
+ final var item = createTestItem(component, "Ime", "A", "en_US", 0);
+ final var equivalent = createTestItem(component, "Ime", "A", "en_US", 0);
+
+ assertEquals("Equivalent items should have the same order.", 0, item.compareTo(equivalent));
+ }
+
+ /**
+ * Verifies that the system locale and system language do not the influence comparison order.
+ */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testCompareSystemLocaleSystemLanguage() {
+ final var component = new ComponentName("com.example.ime", "Ime");
+ final var japanese = createTestItem(component, "Ime", "A", "ja_JP", 0);
+ final var systemLanguage = createTestItem(component, "Ime", "A", "en_GB", 0);
+ final var systemLocale = createTestItem(component, "Ime", "A", "en_US", 0);
+
+ assertFalse(japanese.mIsSystemLanguage);
+ assertFalse(japanese.mIsSystemLocale);
+ assertTrue(systemLanguage.mIsSystemLanguage);
+ assertFalse(systemLanguage.mIsSystemLocale);
+ assertTrue(systemLocale.mIsSystemLanguage);
+ assertTrue(systemLocale.mIsSystemLocale);
+
+ assertEquals("System language shouldn't influence comparison over non-system language.",
+ 0, japanese.compareTo(systemLanguage));
+ assertEquals("System locale shouldn't influence comparison over non-system locale.",
+ 0, japanese.compareTo(systemLocale));
+ assertEquals("System locale shouldn't influence comparison over system language.",
+ 0, systemLanguage.compareTo(systemLocale));
+ }
+
+ /** Verifies that the subtype name does not influence the comparison order. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testCompareSubtypeName() {
+ final var component = new ComponentName("com.example.ime", "Ime");
+ final var subtypeA = createTestItem(component, "Ime", "A", "en_US", 0);
+ final var subtypeB = createTestItem(component, "Ime", "B", "en_US", 0);
+
+ assertEquals("Subtype name shouldn't influence comparison.",
+ 0, subtypeA.compareTo(subtypeB));
+ }
+
+ /** Verifies that the subtype index does not influence the comparison order. */
+ @RequiresFlagsEnabled(Flags.FLAG_IME_SWITCHER_REVAMP)
+ @Test
+ public void testCompareSubtypeIndex() {
+ final var component = new ComponentName("com.example.ime", "Ime");
+ final var subtype0 = createTestItem(component, "Ime1", "A", "en_US", 0);
+ final var subtype1 = createTestItem(component, "Ime1", "A", "en_US", 1);
+
+ assertEquals("Subtype index shouldn't influence comparison.",
+ 0, subtype0.compareTo(subtype1));
+ }
+
+ /**
+ * Verifies that the controller's next item order matches the given one, and cycles back at
+ * the end, both across all IMEs, and also per each IME. If a single item is given, verifies
+ * that no next item is returned.
+ *
+ * @param controller the controller to use for finding the next items.
+ * @param forHardware whether to find the next hardware item, or software item.
+ * @param mode the switching mode.
+ * @param forward whether to search forwards or backwards in the list.
+ * @param allItems the list of items across all IMEs.
+ * @param perImeItems the list of lists of items per IME.
+ */
+ private static void assertNextOrder(@NonNull ControllerImpl controller, boolean forHardware,
+ @SwitchMode int mode, boolean forward, @NonNull List<ImeSubtypeListItem> allItems,
+ @NonNull List<List<ImeSubtypeListItem>> perImeItems) {
+ assertNextOrder(controller, forHardware, false /* onlyCurrentIme */, mode,
+ forward, allItems);
+
+ for (var imeItems : perImeItems) {
+ assertNextOrder(controller, forHardware, true /* onlyCurrentIme */, mode,
+ forward, imeItems);
+ }
+ }
+
+ /**
+ * Verifies that the controller's next item order matches the given one, and cycles back at
+ * the end, both across all IMEs, and also per each IME. This checks the forward direction
+ * with the given items, and the backwards order with the items reversed. If a single item is
+ * given, verifies that no next item is returned.
+ *
+ * @param controller the controller to use for finding the next items.
+ * @param forHardware whether to find the next hardware item, or software item.
+ * @param mode the switching mode.
+ * @param allItems the list of items across all IMEs.
+ * @param perImeItems the list of lists of items per IME.
+ */
+ private static void assertNextOrder(@NonNull ControllerImpl controller, boolean forHardware,
+ @SwitchMode int mode, @NonNull List<ImeSubtypeListItem> allItems,
+ @NonNull List<List<ImeSubtypeListItem>> perImeItems) {
+ assertNextOrder(controller, forHardware, false /* onlyCurrentIme */, mode,
+ true /* forward */, allItems);
+ assertNextOrder(controller, forHardware, false /* onlyCurrentIme */, mode,
+ false /* forward */, allItems.reversed());
+
+ for (var imeItems : perImeItems) {
+ assertNextOrder(controller, forHardware, true /* onlyCurrentIme */, mode,
+ true /* forward */, imeItems);
+ assertNextOrder(controller, forHardware, true /* onlyCurrentIme */, mode,
+ false /* forward */, imeItems.reversed());
+ }
+ }
+
+ /**
+ * Verifies that the controller's next item order (starting from the first one in {@code items}
+ * matches the given on, and cycles back at the end. If a single item is given, verifies that
+ * no next item is returned.
+ *
+ * @param controller the controller to use for finding the next items.
+ * @param forHardware whether to find the next hardware item, or software item.
+ * @param onlyCurrentIme whether to consider only subtypes of the current input method.
+ * @param mode the switching mode.
+ * @param forward whether to search forwards or backwards in the list.
+ * @param items the list of items to verify, in the expected order.
+ */
+ private static void assertNextOrder(@NonNull ControllerImpl controller,
+ boolean forHardware, boolean onlyCurrentIme, @SwitchMode int mode, boolean forward,
+ @NonNull List<ImeSubtypeListItem> items) {
+ final int numItems = items.size();
+ if (numItems == 0) {
+ return;
+ } else if (numItems == 1) {
+ // Single item controllers should never return a next item.
+ assertNextItem(controller, forHardware, onlyCurrentIme, mode, forward, items.get(0),
+ null /* expectedNext*/);
+ return;
+ }
+
+ var item = items.get(0);
+
+ final var expectedNextItems = new ArrayList<>(items);
+ // Add first item in the last position of expected order, to ensure the order is cyclic.
+ expectedNextItems.add(item);
+
+ final var nextItems = new ArrayList<>();
+ // Add first item in the first position of actual order, to ensure the order is cyclic.
+ nextItems.add(item);
+
+ // Compute the nextItems starting from the first given item, and compare the order.
+ for (int i = 0; i < numItems; i++) {
+ item = getNextItem(controller, forHardware, onlyCurrentIme, mode, forward, item);
+ assertNotNull("Next item shouldn't be null.", item);
+ nextItems.add(item);
+ }
+
+ assertEquals("Rotation order doesn't match.", expectedNextItems, nextItems);
+ }
+
+ /**
+ * Verifies that the controller gets the expected next value from the given item.
+ *
+ * @param controller the controller to sue for finding the next value.
+ * @param forHardware whether to find the next hardware item, or software item.
+ * @param onlyCurrentIme whether to consider only subtypes of the current input method.
+ * @param mode the switching mode.
+ * @param forward whether to search forwards or backwards in the list.
+ * @param item the item to find the next value from.
+ * @param expectedNext the expected next value.
+ */
+ private static void assertNextItem(@NonNull ControllerImpl controller,
+ boolean forHardware, boolean onlyCurrentIme, @SwitchMode int mode, boolean forward,
+ @NonNull ImeSubtypeListItem item, @Nullable ImeSubtypeListItem expectedNext) {
+ final var nextItem = getNextItem(controller, forHardware, onlyCurrentIme, mode, forward,
+ item);
+ assertEquals("Next item doesn't match.", expectedNext, nextItem);
+ }
+
+ /**
+ * Gets the next value from the given item.
+ *
+ * @param controller the controller to use for finding the next value.
+ * @param forHardware whether to find the next hardware item, or software item.
+ * @param onlyCurrentIme whether to consider only subtypes of the current input method.
+ * @param mode the switching mode.
+ * @param forward whether to search forwards or backwards in the list.
+ * @param item the item to find the next value from.
+ * @return the next item found, otherwise {@code null}.
+ */
+ @Nullable
+ private static ImeSubtypeListItem getNextItem(@NonNull ControllerImpl controller,
+ boolean forHardware, boolean onlyCurrentIme, @SwitchMode int mode, boolean forward,
+ @NonNull ImeSubtypeListItem item) {
+ final var subtype = item.mSubtypeName != null
+ ? createTestSubtype(item.mSubtypeName.toString()) : null;
+ return forHardware
+ ? controller.getNextInputMethodForHardware(
+ onlyCurrentIme, item.mImi, subtype, mode, forward)
+ : controller.getNextInputMethod(
+ onlyCurrentIme, item.mImi, subtype, mode, forward);
+ }
+
+ /**
+ * Verifies that no next items can be found, and the recency cannot be updated for the
+ * given items.
+ *
+ * @param controller the controller to verify the items on.
+ * @param forHardware whether to try finding the next hardware item, or software item.
+ * @param items the list of items to verify.
+ */
+ private void assertNoAction(@NonNull ControllerImpl controller, boolean forHardware,
+ @NonNull List<ImeSubtypeListItem> items) {
+ for (var item : items) {
+ for (int mode = MODE_STATIC; mode <= MODE_AUTO; mode++) {
+ assertNextItem(controller, forHardware, false /* onlyCurrentIme */, mode,
+ false /* forward */, item, null /* expectedNext */);
+ assertNextItem(controller, forHardware, false /* onlyCurrentIme */, mode,
+ true /* forward */, item, null /* expectedNext */);
+ assertNextItem(controller, forHardware, true /* onlyCurrentIme */, mode,
+ false /* forward */, item, null /* expectedNext */);
+ assertNextItem(controller, forHardware, true /* onlyCurrentIme */, mode,
+ true /* forward */, item, null /* expectedNext */);
+ }
+
+ assertFalse("User action shouldn't have updated the recency.",
+ onUserAction(controller, item));
+ }
+ }
}
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
index e2f3eec1a20b..d59f28b4cad2 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
@@ -18,23 +18,12 @@ package com.android.server.inputmethod;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.pm.UserInfo;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Looper;
import android.platform.test.ravenwood.RavenwoodRule;
-import com.android.server.pm.UserManagerInternal;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -52,13 +41,8 @@ public final class UserDataRepositoryTest {
.setProvideMainThread(true).build();
@Mock
- private UserManagerInternal mMockUserManagerInternal;
-
- @Mock
private InputMethodManagerService mMockInputMethodManagerService;
- private Handler mHandler;
-
private IntFunction<InputMethodBindingController> mBindingControllerFactory;
@Before
@@ -66,7 +50,6 @@ public final class UserDataRepositoryTest {
MockitoAnnotations.initMocks(this);
SecureSettingsWrapper.startTestMode();
- mHandler = new Handler(Looper.getMainLooper());
mBindingControllerFactory = new IntFunction<InputMethodBindingController>() {
@Override
@@ -81,54 +64,20 @@ public final class UserDataRepositoryTest {
SecureSettingsWrapper.endTestMode();
}
- @Test
- public void testUserDataRepository_addsNewUserInfoOnUserCreatedEvent() {
- // Create UserDataRepository and capture the user lifecycle listener
- final var captor = ArgumentCaptor.forClass(UserManagerInternal.UserLifecycleListener.class);
- final var bindingControllerFactorySpy = spy(mBindingControllerFactory);
- final var repository = new UserDataRepository(mHandler,
- mMockUserManagerInternal, bindingControllerFactorySpy);
-
- verify(mMockUserManagerInternal, times(1)).addUserLifecycleListener(captor.capture());
- final var listener = captor.getValue();
-
- // Assert that UserDataRepository is empty and then call onUserCreated
- assertThat(collectUserData(repository)).isEmpty();
- final var userInfo = new UserInfo();
- userInfo.id = ANY_USER_ID;
- listener.onUserCreated(userInfo, /* unused token */ new Object());
- waitForIdle();
-
- // Assert UserDataRepository contains the expected UserData
- final var allUserData = collectUserData(repository);
- assertThat(allUserData).hasSize(1);
- assertThat(allUserData.get(0).mUserId).isEqualTo(ANY_USER_ID);
-
- // Assert UserDataRepository called the InputMethodBindingController creator function.
- verify(bindingControllerFactorySpy).apply(ANY_USER_ID);
- assertThat(allUserData.get(0).mBindingController.getUserId()).isEqualTo(ANY_USER_ID);
- }
-
+ // TODO(b/352615651): Move this to end-to-end test.
@Test
public void testUserDataRepository_removesUserInfoOnUserRemovedEvent() {
- // Create UserDataRepository and capture the user lifecycle listener
- final var captor = ArgumentCaptor.forClass(UserManagerInternal.UserLifecycleListener.class);
- final var repository = new UserDataRepository(mHandler,
- mMockUserManagerInternal,
+ // Create UserDataRepository
+ final var repository = new UserDataRepository(
userId -> new InputMethodBindingController(userId, mMockInputMethodManagerService));
- verify(mMockUserManagerInternal, times(1)).addUserLifecycleListener(captor.capture());
- final var listener = captor.getValue();
-
// Add one UserData ...
- final var userInfo = new UserInfo();
- userInfo.id = ANY_USER_ID;
- listener.onUserCreated(userInfo, /* unused token */ new Object());
- waitForIdle();
+ final var userData = repository.getOrCreate(ANY_USER_ID);
+ assertThat(userData.mUserId).isEqualTo(ANY_USER_ID);
+
// ... and then call onUserRemoved
assertThat(collectUserData(repository)).hasSize(1);
- listener.onUserRemoved(userInfo);
- waitForIdle();
+ repository.remove(ANY_USER_ID);
// Assert UserDataRepository is now empty
assertThat(collectUserData(repository)).isEmpty();
@@ -136,13 +85,10 @@ public final class UserDataRepositoryTest {
@Test
public void testGetOrCreate() {
- final var repository = new UserDataRepository(mHandler,
- mMockUserManagerInternal, mBindingControllerFactory);
+ final var repository = new UserDataRepository(mBindingControllerFactory);
- synchronized (ImfLock.class) {
- final var userData = repository.getOrCreate(ANY_USER_ID);
- assertThat(userData.mUserId).isEqualTo(ANY_USER_ID);
- }
+ final var userData = repository.getOrCreate(ANY_USER_ID);
+ assertThat(userData.mUserId).isEqualTo(ANY_USER_ID);
final var allUserData = collectUserData(repository);
assertThat(allUserData).hasSize(1);
@@ -152,17 +98,10 @@ public final class UserDataRepositoryTest {
assertThat(allUserData.get(0).mBindingController.getUserId()).isEqualTo(ANY_USER_ID);
}
- private List<UserDataRepository.UserData> collectUserData(UserDataRepository repository) {
- final var collected = new ArrayList<UserDataRepository.UserData>();
- synchronized (ImfLock.class) {
- repository.forAllUserData(userData -> collected.add(userData));
- }
+ private List<UserData> collectUserData(UserDataRepository repository) {
+ final var collected = new ArrayList<UserData>();
+ repository.forAllUserData(userData -> collected.add(userData));
return collected;
}
- private void waitForIdle() {
- final var done = new ConditionVariable();
- mHandler.post(done::open);
- done.block();
- }
}
diff --git a/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/src/com/android/apps/inputmethod/simpleime/ims/InputMethodServiceWrapper.java b/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/src/com/android/apps/inputmethod/simpleime/ims/InputMethodServiceWrapper.java
index b706a654e3a8..67212b60f1b8 100644
--- a/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/src/com/android/apps/inputmethod/simpleime/ims/InputMethodServiceWrapper.java
+++ b/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/src/com/android/apps/inputmethod/simpleime/ims/InputMethodServiceWrapper.java
@@ -53,13 +53,14 @@ public class InputMethodServiceWrapper extends InputMethodService {
@Override
public void onStartInput(EditorInfo info, boolean restarting) {
- Log.i(TAG, "onStartInput() editor=" + info + ", restarting=" + restarting);
+ Log.i(TAG, "onStartInput() editor=" + dumpEditorInfo(info) + ", restarting=" + restarting);
super.onStartInput(info, restarting);
}
@Override
public void onStartInputView(EditorInfo info, boolean restarting) {
- Log.i(TAG, "onStartInputView() editor=" + info + ", restarting=" + restarting);
+ Log.i(TAG, "onStartInputView() editor=" + dumpEditorInfo(info)
+ + ", restarting=" + restarting);
super.onStartInputView(info, restarting);
mInputViewStarted = true;
if (mCountDownLatchForTesting != null) {
@@ -99,4 +100,14 @@ public class InputMethodServiceWrapper extends InputMethodService {
mCountDownLatchForTesting.countDown();
}
}
+
+ private String dumpEditorInfo(EditorInfo info) {
+ var sb = new StringBuilder();
+ sb.append("EditorInfo{packageName=").append(info.packageName);
+ sb.append(" fieldId=").append(info.fieldId);
+ sb.append(" hintText=").append(info.hintText);
+ sb.append(" privateImeOptions=").append(info.privateImeOptions);
+ sb.append("}");
+ return sb.toString();
+ }
}
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
index 89b4aea216f9..dec463444faa 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -1027,6 +1027,96 @@ public class PackageManagerSettingsTests {
}
@Test
+ public void testWriteReadDebuggable() {
+ Settings settings = makeSettings();
+ PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1);
+ packageSetting.setAppId(Process.FIRST_APPLICATION_UID);
+ packageSetting.setPkg(PackageImpl.forTesting(PACKAGE_NAME_1).hideAsParsed()
+ .setUid(packageSetting.getAppId())
+ .hideAsFinal());
+
+ packageSetting.setDebuggable(true);
+ settings.mPackages.put(PACKAGE_NAME_1, packageSetting);
+
+ settings.writeLPr(computer, /* sync= */ true);
+ settings.mPackages.clear();
+
+ assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
+ assertThat(settings.getPackageLPr(PACKAGE_NAME_1).isDebuggable(), is(true));
+ }
+
+ @Test
+ public void testWriteReadBaseRevisionCode() {
+ Settings settings = makeSettings();
+ PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1);
+ packageSetting.setAppId(Process.FIRST_APPLICATION_UID);
+ packageSetting.setPkg(PackageImpl.forTesting(PACKAGE_NAME_1).hideAsParsed()
+ .setUid(packageSetting.getAppId())
+ .hideAsFinal());
+
+ final int revisionCode = 311;
+ packageSetting.setBaseRevisionCode(revisionCode);
+ settings.mPackages.put(PACKAGE_NAME_1, packageSetting);
+
+ settings.writeLPr(computer, /* sync= */ true);
+ settings.mPackages.clear();
+
+ assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
+ assertThat(settings.getPackageLPr(PACKAGE_NAME_1).getBaseRevisionCode(), is(revisionCode));
+ }
+
+ @Test
+ public void testHasPkg_writeReadSplitVersions() {
+ Settings settings = makeSettings();
+ PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1);
+ packageSetting.setAppId(Process.FIRST_APPLICATION_UID);
+ packageSetting.setPkg(PackageImpl.forTesting(PACKAGE_NAME_1).hideAsParsed()
+ .setUid(packageSetting.getAppId())
+ .hideAsFinal());
+
+ final String splitOne = "one";
+ final String splitTwo = "two";
+ final int revisionOne = 311;
+ final int revisionTwo = 330;
+ packageSetting.setSplitNames(new String[] { splitOne, splitTwo});
+ packageSetting.setSplitRevisionCodes(new int[] { revisionOne, revisionTwo});
+ settings.mPackages.put(PACKAGE_NAME_1, packageSetting);
+
+ settings.writeLPr(computer, /* sync= */ true);
+ settings.mPackages.clear();
+
+ assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
+ PackageSetting resultSetting = settings.getPackageLPr(PACKAGE_NAME_1);
+ assertThat(resultSetting.getSplitNames().length, is(0));
+ assertThat(resultSetting.getSplitRevisionCodes().length, is(0));
+ }
+
+ @Test
+ public void testNoPkg_writeReadSplitVersions() {
+ Settings settings = makeSettings();
+ PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1);
+ packageSetting.setAppId(Process.FIRST_APPLICATION_UID);
+
+ final String splitOne = "one";
+ final String splitTwo = "two";
+ final int revisionOne = 311;
+ final int revisionTwo = 330;
+ packageSetting.setSplitNames(new String[] { splitOne, splitTwo});
+ packageSetting.setSplitRevisionCodes(new int[] { revisionOne, revisionTwo});
+ settings.mPackages.put(PACKAGE_NAME_1, packageSetting);
+
+ settings.writeLPr(computer, /* sync= */ true);
+ settings.mPackages.clear();
+
+ assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
+ PackageSetting resultSetting = settings.getPackageLPr(PACKAGE_NAME_1);
+ assertThat(resultSetting.getSplitNames()[0], is(splitOne));
+ assertThat(resultSetting.getSplitNames()[1], is(splitTwo));
+ assertThat(resultSetting.getSplitRevisionCodes()[0], is(revisionOne));
+ assertThat(resultSetting.getSplitRevisionCodes()[1], is(revisionTwo));
+ }
+
+ @Test
public void testWriteReadArchiveState() {
Settings settings = makeSettings();
PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java
index bba4c8d64c86..f690b1bbfccf 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java
@@ -44,7 +44,7 @@ public class DisplayBrightnessStateTest {
@Test
public void validateAllDisplayBrightnessStateFieldsAreSetAsExpected() {
float brightness = 0.3f;
- float sdrBrightness = 0.2f;
+ float hdrBrightness = 0.4f;
boolean shouldUseAutoBrightness = true;
boolean shouldUpdateScreenBrightnessSetting = true;
int brightnessAdjustmentFlag = 2;
@@ -53,7 +53,7 @@ public class DisplayBrightnessStateTest {
brightnessReason.setModifier(BrightnessReason.MODIFIER_DIMMED);
DisplayBrightnessState displayBrightnessState = mDisplayBrightnessStateBuilder
.setBrightness(brightness)
- .setSdrBrightness(sdrBrightness)
+ .setHdrBrightness(hdrBrightness)
.setBrightnessReason(brightnessReason)
.setShouldUseAutoBrightness(shouldUseAutoBrightness)
.setShouldUpdateScreenBrightnessSetting(shouldUpdateScreenBrightnessSetting)
@@ -62,7 +62,7 @@ public class DisplayBrightnessStateTest {
.build();
assertEquals(displayBrightnessState.getBrightness(), brightness, FLOAT_DELTA);
- assertEquals(displayBrightnessState.getSdrBrightness(), sdrBrightness, FLOAT_DELTA);
+ assertEquals(displayBrightnessState.getHdrBrightness(), hdrBrightness, FLOAT_DELTA);
assertEquals(displayBrightnessState.getBrightnessReason(), brightnessReason);
assertEquals(displayBrightnessState.getShouldUseAutoBrightness(), shouldUseAutoBrightness);
assertEquals(shouldUpdateScreenBrightnessSetting,
@@ -78,7 +78,7 @@ public class DisplayBrightnessStateTest {
DisplayBrightnessState state1 = new DisplayBrightnessState.Builder()
.setBrightnessReason(reason)
.setBrightness(0.26f)
- .setSdrBrightness(0.23f)
+ .setHdrBrightness(0.29f)
.setShouldUseAutoBrightness(false)
.setShouldUpdateScreenBrightnessSetting(true)
.build();
@@ -91,8 +91,8 @@ public class DisplayBrightnessStateTest {
sb.append("DisplayBrightnessState:")
.append("\n brightness:")
.append(displayBrightnessState.getBrightness())
- .append("\n sdrBrightness:")
- .append(displayBrightnessState.getSdrBrightness())
+ .append("\n hdrBrightness:")
+ .append(displayBrightnessState.getHdrBrightness())
.append("\n brightnessReason:")
.append(displayBrightnessState.getBrightnessReason())
.append("\n shouldUseAutoBrightness:")
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 9a25b1acfaae..d4506831d9c2 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -54,6 +54,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.server.display.config.HdrBrightnessData;
+import com.android.server.display.config.HighBrightnessModeData;
import com.android.server.display.config.HysteresisLevels;
import com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholdPoint;
import com.android.server.display.config.RefreshRateData;
@@ -436,7 +437,7 @@ public final class DisplayDeviceConfigTest {
public void testHighBrightnessModeDataFromDisplayConfig() throws IOException {
setupDisplayDeviceConfigFromDisplayConfigFile();
- DisplayDeviceConfig.HighBrightnessModeData hbmData =
+ HighBrightnessModeData hbmData =
mDisplayDeviceConfig.getHighBrightnessModeData();
assertNotNull(hbmData);
assertEquals(BRIGHTNESS[1], hbmData.transitionPoint, ZERO_DELTA);
@@ -671,14 +672,14 @@ public final class DisplayDeviceConfigTest {
HdrBrightnessData data = mDisplayDeviceConfig.getHdrBrightnessData();
assertNotNull(data);
- assertEquals(2, data.mMaxBrightnessLimits.size());
- assertEquals(13000, data.mBrightnessDecreaseDebounceMillis);
- assertEquals(0.1f, data.mScreenBrightnessRampDecrease, SMALL_DELTA);
- assertEquals(1000, data.mBrightnessIncreaseDebounceMillis);
- assertEquals(0.11f, data.mScreenBrightnessRampIncrease, SMALL_DELTA);
-
- assertEquals(0.3f, data.mMaxBrightnessLimits.get(500f), SMALL_DELTA);
- assertEquals(0.6f, data.mMaxBrightnessLimits.get(1200f), SMALL_DELTA);
+ assertEquals(2, data.maxBrightnessLimits.size());
+ assertEquals(13000, data.brightnessDecreaseDebounceMillis);
+ assertEquals(0.1f, data.screenBrightnessRampDecrease, SMALL_DELTA);
+ assertEquals(1000, data.brightnessIncreaseDebounceMillis);
+ assertEquals(0.11f, data.screenBrightnessRampIncrease, SMALL_DELTA);
+
+ assertEquals(0.3f, data.maxBrightnessLimits.get(500f), SMALL_DELTA);
+ assertEquals(0.6f, data.maxBrightnessLimits.get(1200f), SMALL_DELTA);
}
private void verifyConfigValuesFromConfigResource() {
@@ -964,6 +965,51 @@ public final class DisplayDeviceConfigTest {
assertThat(supportedModeData.vsyncRate).isEqualTo(240);
}
+ @Test
+ public void testDozeBrightness_Ddc() throws IOException {
+ when(mFlags.isDozeBrightnessFloatEnabled()).thenReturn(true);
+ setupDisplayDeviceConfigFromDisplayConfigFile();
+
+ assertArrayEquals(new float[]{ -1, 0.1f, 0.2f, 0.3f, 0.4f },
+ mDisplayDeviceConfig.getDozeBrightnessSensorValueToBrightness(), SMALL_DELTA);
+ assertEquals(0.25f, mDisplayDeviceConfig.getDefaultDozeBrightness(), SMALL_DELTA);
+ }
+
+ @Test
+ public void testDefaultDozeBrightness_FallBackToConfigXmlFloat() throws IOException {
+ setupDisplayDeviceConfigFromConfigResourceFile();
+ when(mFlags.isDozeBrightnessFloatEnabled()).thenReturn(true);
+ when(mResources.getFloat(com.android.internal.R.dimen.config_screenBrightnessDozeFloat))
+ .thenReturn(0.31f);
+ when(mResources.getInteger(com.android.internal.R.integer.config_screenBrightnessDoze))
+ .thenReturn(90);
+
+ // Empty display config file
+ setupDisplayDeviceConfigFromDisplayConfigFile(
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<displayConfiguration />\n");
+
+ assertEquals(0.31f, mDisplayDeviceConfig.getDefaultDozeBrightness(), ZERO_DELTA);
+ }
+
+ @Test
+ public void testDefaultDozeBrightness_FallBackToConfigXmlInt() throws IOException {
+ setupDisplayDeviceConfigFromConfigResourceFile();
+ when(mFlags.isDozeBrightnessFloatEnabled()).thenReturn(true);
+ when(mResources.getFloat(com.android.internal.R.dimen.config_screenBrightnessDozeFloat))
+ .thenReturn(DisplayDeviceConfig.INVALID_BRIGHTNESS_IN_CONFIG);
+ when(mResources.getInteger(com.android.internal.R.integer.config_screenBrightnessDoze))
+ .thenReturn(90);
+
+ // Empty display config file
+ setupDisplayDeviceConfigFromDisplayConfigFile(
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<displayConfiguration />\n");
+
+ assertEquals(brightnessIntToFloat(90),
+ mDisplayDeviceConfig.getDefaultDozeBrightness(), ZERO_DELTA);
+ }
+
private String getValidLuxThrottling() {
return "<luxThrottling>\n"
+ " <brightnessLimitMap>\n"
@@ -1707,6 +1753,16 @@ public final class DisplayDeviceConfigTest {
+ "</point>"
+ "</luxThresholds>"
+ "</idleScreenRefreshRateTimeout>"
+ + "<dozeBrightnessSensorValueToBrightness>\n"
+ + "<item>-1</item>\n"
+ + "<item>0.1</item>\n"
+ + "<item>0.2</item>\n"
+ + "<item>0.3</item>\n"
+ + "<item>0.4</item>\n"
+ + "</dozeBrightnessSensorValueToBrightness>\n"
+ + "<defaultDozeBrightness>"
+ + "0.25"
+ + "</defaultDozeBrightness>\n"
+ "</displayConfiguration>\n";
}
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 211ab03813b3..d2686372f550 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -2584,18 +2584,19 @@ public class DisplayManagerServiceTest {
LogicalDisplay display =
logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true);
+ displayManager.setDisplayState(display.getDisplayIdLocked(), Display.STATE_ON);
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_ON);
- assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(), false))
- .isTrue();
+ assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(),
+ Display.STATE_OFF)).isTrue();
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_OFF);
- assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(), true))
- .isTrue();
+ assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(),
+ Display.STATE_UNKNOWN)).isTrue();
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_ON);
@@ -2621,8 +2622,10 @@ public class DisplayManagerServiceTest {
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_ON);
- assertThrows(SecurityException.class, () -> bs.requestDisplayPower(displayId, true));
- assertThrows(SecurityException.class, () -> bs.requestDisplayPower(displayId, false));
+ assertThrows(SecurityException.class,
+ () -> bs.requestDisplayPower(displayId, Display.STATE_UNKNOWN));
+ assertThrows(SecurityException.class,
+ () -> bs.requestDisplayPower(displayId, Display.STATE_OFF));
}
@Test
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index d070aaa93b01..624c8971d36f 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -83,6 +83,7 @@ import com.android.server.display.brightness.BrightnessReason;
import com.android.server.display.brightness.clamper.BrightnessClamperController;
import com.android.server.display.brightness.clamper.HdrClamper;
import com.android.server.display.color.ColorDisplayService;
+import com.android.server.display.config.HighBrightnessModeData;
import com.android.server.display.config.HysteresisLevels;
import com.android.server.display.config.SensorData;
import com.android.server.display.feature.DisplayManagerFlags;
@@ -116,6 +117,7 @@ public final class DisplayPowerControllerTest {
private static final String SECOND_FOLLOWER_UNIQUE_DISPLAY_ID = "unique_id_789";
private static final float PROX_SENSOR_MAX_RANGE = 5;
private static final float DOZE_SCALE_FACTOR = 0.34f;
+ private static final float DEFAULT_DOZE_BRIGHTNESS = 0.121f;
private static final float BRIGHTNESS_RAMP_RATE_MINIMUM = 0.0f;
private static final float BRIGHTNESS_RAMP_RATE_FAST_DECREASE = 0.3f;
@@ -1942,7 +1944,7 @@ public final class DisplayPowerControllerTest {
}
@Test
- public void testDozeManualBrightness() {
+ public void testDozeManualBrightness_DpcRefactorDisabled() {
when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
Settings.System.putInt(mContext.getContentResolver(),
@@ -1972,6 +1974,45 @@ public final class DisplayPowerControllerTest {
/* ignoreAnimationLimits= */ anyBoolean());
assertEquals(brightness * DOZE_SCALE_FACTOR, mHolder.dpc.getDozeBrightnessForOffload(),
/* delta= */ 0);
+ // This brightness shouldn't be stored in the setting
+ verify(mHolder.brightnessSetting, never()).setBrightness(brightness * DOZE_SCALE_FACTOR);
+ }
+
+ @Test
+ public void testDozeManualBrightness_DpcRefactorEnabled() {
+ when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
+ when(mDisplayManagerFlagsMock.isRefactorDisplayPowerControllerEnabled()).thenReturn(true);
+ mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
+ mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+ float brightness = 0.277f;
+ when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
+ when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+ when(mHolder.hbmController.getCurrentBrightnessMax())
+ .thenReturn(PowerManager.BRIGHTNESS_MAX);
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_DOZE;
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState, initialize
+
+ ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+ ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+ verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+ BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
+ listener.onBrightnessChanged(brightness);
+ advanceTime(1); // Send messages, run updatePowerState
+
+ verify(mHolder.animator).animateTo(eq(brightness * DOZE_SCALE_FACTOR),
+ /* linearSecondTarget= */ anyFloat(), /* rate= */ anyFloat(),
+ /* ignoreAnimationLimits= */ anyBoolean());
+ assertEquals(brightness * DOZE_SCALE_FACTOR, mHolder.dpc.getDozeBrightnessForOffload(),
+ /* delta= */ 0);
+ // This brightness shouldn't be stored in the setting
+ verify(mHolder.brightnessSetting, never()).setBrightness(brightness * DOZE_SCALE_FACTOR);
}
@Test
@@ -2011,9 +2052,6 @@ public final class DisplayPowerControllerTest {
@Test
public void testDefaultDozeBrightness() {
- float brightness = 0.121f;
- when(mPowerManagerMock.getBrightnessConstraint(
- PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE)).thenReturn(brightness);
mContext.getOrCreateTestableResources().addOverride(
com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, false);
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
@@ -2029,15 +2067,25 @@ public final class DisplayPowerControllerTest {
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1); // Run updatePowerState
- verify(mHolder.animator).animateTo(eq(brightness), /* linearSecondTarget= */ anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
+ verify(mHolder.animator).animateTo(eq(DEFAULT_DOZE_BRIGHTNESS),
+ /* linearSecondTarget= */ anyFloat(), eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE),
+ eq(false));
+
+ // The display device changes and the default doze brightness changes
+ setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+ mHolder.config, /* isEnabled= */ true);
+ when(mHolder.config.getDefaultDozeBrightness()).thenReturn(DEFAULT_DOZE_BRIGHTNESS / 2);
+ mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
+
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.animator).animateTo(eq(DEFAULT_DOZE_BRIGHTNESS / 2),
+ /* linearSecondTarget= */ anyFloat(), eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE),
+ eq(false));
}
@Test
public void testDefaultDozeBrightness_ShouldNotBeUsedIfAutoBrightnessAllowedInDoze() {
- float brightness = 0.121f;
- when(mPowerManagerMock.getBrightnessConstraint(
- PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE)).thenReturn(brightness);
mContext.getOrCreateTestableResources().addOverride(
com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, true);
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
@@ -2053,7 +2101,7 @@ public final class DisplayPowerControllerTest {
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1); // Run updatePowerState
- verify(mHolder.animator, never()).animateTo(eq(brightness),
+ verify(mHolder.animator, never()).animateTo(eq(DEFAULT_DOZE_BRIGHTNESS),
/* linearSecondTarget= */ anyFloat(), /* rate= */ anyFloat(),
/* ignoreAnimationLimits= */ anyBoolean());
}
@@ -2111,6 +2159,8 @@ public final class DisplayPowerControllerTest {
new SensorData(Sensor.STRING_TYPE_LIGHT, null));
when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
.thenReturn(new int[0]);
+ when(displayDeviceConfigMock.getDefaultDozeBrightness())
+ .thenReturn(DEFAULT_DOZE_BRIGHTNESS);
when(displayDeviceConfigMock.getBrightnessRampFastDecrease())
.thenReturn(BRIGHTNESS_RAMP_RATE_FAST_DECREASE);
@@ -2386,7 +2436,7 @@ public final class DisplayPowerControllerTest {
@Override
HighBrightnessModeController getHighBrightnessModeController(Handler handler, int width,
int height, IBinder displayToken, String displayUniqueId, float brightnessMin,
- float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData,
+ float brightnessMax, HighBrightnessModeData hbmData,
HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg,
Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata,
Context context) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java
index 8e01a11cb23f..cde87b9b89b2 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java
@@ -23,7 +23,6 @@ import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLI
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE;
-import static com.android.server.display.DisplayDeviceConfig.HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT;
import static com.android.server.display.HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID;
import static org.junit.Assert.assertEquals;
@@ -56,8 +55,8 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule;
-import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData;
import com.android.server.display.HighBrightnessModeController.Injector;
+import com.android.server.display.config.HighBrightnessModeData;
import com.android.server.testutils.OffsettableClock;
import org.junit.Before;
@@ -77,6 +76,7 @@ public class HighBrightnessModeControllerTest {
private static final long TIME_ALLOWED_IN_WINDOW_MILLIS = 12 * 1000;
private static final long TIME_MINIMUM_AVAILABLE_TO_ENABLE_MILLIS = 5 * 1000;
private static final boolean ALLOW_IN_LOW_POWER_MODE = false;
+ private static final float HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT = 0.5f;
private static final float DEFAULT_MIN = 0.01f;
private static final float DEFAULT_MAX = 0.80f;
@@ -103,7 +103,8 @@ public class HighBrightnessModeControllerTest {
private static final HighBrightnessModeData DEFAULT_HBM_DATA =
new HighBrightnessModeData(MINIMUM_LUX, TRANSITION_POINT, TIME_WINDOW_MILLIS,
TIME_ALLOWED_IN_WINDOW_MILLIS, TIME_MINIMUM_AVAILABLE_TO_ENABLE_MILLIS,
- ALLOW_IN_LOW_POWER_MODE, HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT);
+ ALLOW_IN_LOW_POWER_MODE, HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT,
+ null, null, true);
@Before
public void setUp() {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeMetadataMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeMetadataMapperTest.java
index 7e7ccf733876..7132bc1687ca 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeMetadataMapperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeMetadataMapperTest.java
@@ -22,6 +22,8 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
+import com.android.server.display.config.HighBrightnessModeData;
+
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -39,7 +41,7 @@ public class HighBrightnessModeMetadataMapperTest {
private DisplayDeviceConfig mDdcMock;
@Mock
- private DisplayDeviceConfig.HighBrightnessModeData mHbmDataMock;
+ private HighBrightnessModeData mHbmDataMock;
private HighBrightnessModeMetadataMapper mHighBrightnessModeMetadataMapper;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
index 6d138c5b6b29..1729ad5ff19f 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -16,7 +16,7 @@
package com.android.server.display;
-import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
+import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.DEFAULT_DISPLAY_GROUP;
import static android.view.Display.FLAG_REAR;
@@ -62,9 +62,11 @@ 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.PropertyInvalidatedCache;
import android.content.Context;
import android.content.res.Resources;
+import android.hardware.devicestate.DeviceState;
import android.os.Handler;
import android.os.IPowerManager;
import android.os.IThermalService;
@@ -103,7 +105,9 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -111,9 +115,12 @@ public class LogicalDisplayMapperTest {
private static int sUniqueTestDisplayId = 0;
private static final int TIMEOUT_STATE_TRANSITION_MILLIS = 500;
private static final int FOLD_SETTLE_DELAY = 1000;
- private static final int DEVICE_STATE_CLOSED = 0;
- private static final int DEVICE_STATE_HALF_OPEN = 1;
- private static final int DEVICE_STATE_OPEN = 2;
+ private static final DeviceState DEVICE_STATE_CLOSED = createDeviceState(0, "Zero",
+ Set.of(DeviceState.PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP), Collections.emptySet());
+ private static final DeviceState DEVICE_STATE_HALF_OPEN = createDeviceState(1, "One",
+ Set.of(DeviceState.PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE), Collections.emptySet());
+ private static final DeviceState DEVICE_STATE_OPEN = createDeviceState(2, "Two",
+ Set.of(DeviceState.PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE), Collections.emptySet());
private static final int FLAG_GO_TO_SLEEP_ON_FOLD = 0;
private static final int FLAG_GO_TO_SLEEP_FLAG_SOFT_SLEEP = 2;
private static int sNextNonDefaultDisplayId = DEFAULT_DISPLAY + 1;
@@ -703,8 +710,7 @@ public class LogicalDisplayMapperTest {
/* isInteractive= */true,
/* isBootCompleted= */true));
assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED,
- INVALID_DEVICE_STATE_IDENTIFIER,
- /* isInteractive= */true,
+ INVALID_DEVICE_STATE /* currentState */, /* isInteractive= */true,
/* isBootCompleted= */true));
}
@@ -932,7 +938,7 @@ public class LogicalDisplayMapperTest {
// We can only have one default display
assertEquals(DEFAULT_DISPLAY, id(display1));
- mLogicalDisplayMapper.setDeviceStateLocked(0);
+ mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_CLOSED);
advanceTime(1000);
// The new state is not applied until the boot is completed
assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked());
@@ -953,7 +959,7 @@ public class LogicalDisplayMapperTest {
assertEquals("concurrent", mLogicalDisplayMapper.getDisplayLocked(device2)
.getDisplayInfoLocked().thermalBrightnessThrottlingDataId);
- mLogicalDisplayMapper.setDeviceStateLocked(1);
+ mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_HALF_OPEN);
advanceTime(1000);
assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked());
assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked());
@@ -966,7 +972,7 @@ public class LogicalDisplayMapperTest {
mLogicalDisplayMapper.getDisplayLocked(device2)
.getDisplayInfoLocked().thermalBrightnessThrottlingDataId);
- mLogicalDisplayMapper.setDeviceStateLocked(2);
+ mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_OPEN);
advanceTime(1000);
assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked());
assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked());
@@ -1043,7 +1049,7 @@ public class LogicalDisplayMapperTest {
// 3) Send DISPLAY_DEVICE_EVENT_CHANGE to inform the mapper of the new display state
// 4) Dispatch handler events.
mLogicalDisplayMapper.onBootCompleted();
- mLogicalDisplayMapper.setDeviceStateLocked(0);
+ mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_CLOSED);
mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED);
advanceTime(1000);
final int[] allDisplayIds = mLogicalDisplayMapper.getDisplayIdsLocked(
@@ -1073,7 +1079,7 @@ public class LogicalDisplayMapperTest {
/* includeDisabled= */ false));
// Now do it again to go back to state 1
- mLogicalDisplayMapper.setDeviceStateLocked(1);
+ mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_HALF_OPEN);
mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED);
advanceTime(1000);
final int[] threeDisplaysEnabled = mLogicalDisplayMapper.getDisplayIdsLocked(
@@ -1127,7 +1133,7 @@ public class LogicalDisplayMapperTest {
// We can only have one default display
assertEquals(DEFAULT_DISPLAY, id(display1));
- mLogicalDisplayMapper.setDeviceStateLocked(0);
+ mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_CLOSED);
advanceTime(1000);
mLogicalDisplayMapper.onBootCompleted();
advanceTime(1000);
@@ -1180,13 +1186,15 @@ public class LogicalDisplayMapperTest {
Layout layout = new Layout();
createDefaultDisplay(layout, outer);
createNonDefaultDisplay(layout, inner, /* enabled= */ false, /* group= */ null);
- when(mDeviceStateToLayoutMapSpy.get(DEVICE_STATE_CLOSED)).thenReturn(layout);
+ when(mDeviceStateToLayoutMapSpy.get(DEVICE_STATE_CLOSED.getIdentifier())).thenReturn(
+ layout);
layout = new Layout();
createNonDefaultDisplay(layout, outer, /* enabled= */ false, /* group= */ null);
createDefaultDisplay(layout, inner);
- when(mDeviceStateToLayoutMapSpy.get(DEVICE_STATE_HALF_OPEN)).thenReturn(layout);
- when(mDeviceStateToLayoutMapSpy.get(DEVICE_STATE_OPEN)).thenReturn(layout);
+ when(mDeviceStateToLayoutMapSpy.get(DEVICE_STATE_HALF_OPEN.getIdentifier())).thenReturn(
+ layout);
+ when(mDeviceStateToLayoutMapSpy.get(DEVICE_STATE_OPEN.getIdentifier())).thenReturn(layout);
when(mDeviceStateToLayoutMapSpy.size()).thenReturn(4);
add(outer);
@@ -1317,6 +1325,15 @@ public class LogicalDisplayMapperTest {
assertNotEquals(DEFAULT_DISPLAY, id(displayRemoved));
}
+ private static DeviceState createDeviceState(int identifier, @NonNull String name,
+ @NonNull Set<@DeviceState.SystemDeviceStateProperties Integer> systemProperties,
+ @NonNull Set<@DeviceState.PhysicalDeviceStateProperties Integer> physicalProperties) {
+ DeviceState.Configuration deviceStateConfiguration = new DeviceState.Configuration.Builder(
+ identifier, name).setSystemProperties(systemProperties).setPhysicalProperties(
+ physicalProperties).build();
+ return new DeviceState(deviceStateConfiguration);
+ }
+
private final static class FoldableDisplayDevices {
final TestDisplayDevice mOuter;
final TestDisplayDevice mInner;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
index c785ea6b1865..721285636d7a 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
@@ -34,6 +34,7 @@ import android.os.PowerManager;
import androidx.test.filters.SmallTest;
import com.android.server.display.AutomaticBrightnessController;
+import com.android.server.display.config.DisplayDeviceConfigTestUtilsKt;
import com.android.server.display.config.HdrBrightnessData;
import com.android.server.testutils.OffsettableClock;
import com.android.server.testutils.TestHandler;
@@ -54,13 +55,14 @@ public class HdrClamperTest {
private static final float FLOAT_TOLERANCE = 0.0001f;
private static final long SEND_TIME_TOLERANCE = 100;
- private static final HdrBrightnessData TEST_HDR_DATA = new HdrBrightnessData(
- Map.of(500f, 0.6f),
- /* brightnessIncreaseDebounceMillis= */ 1000,
- /* screenBrightnessRampIncrease= */ 0.02f,
- /* brightnessDecreaseDebounceMillis= */ 3000,
- /* screenBrightnessRampDecrease= */0.04f
- );
+ private static final HdrBrightnessData TEST_HDR_DATA = DisplayDeviceConfigTestUtilsKt
+ .createHdrBrightnessData(
+ Map.of(500f, 0.6f),
+ /* brightnessIncreaseDebounceMillis= */ 1000,
+ /* screenBrightnessRampIncrease= */ 0.02f,
+ /* brightnessDecreaseDebounceMillis= */ 3000,
+ /* screenBrightnessRampDecrease= */0.04f
+ );
private static final int WIDTH = 600;
private static final int HEIGHT = 800;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategyTest.java
index 4d5ff55cc805..bb24c0f7b18e 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategyTest.java
@@ -110,7 +110,6 @@ public class AutoBrightnessFallbackStrategyTest {
new DisplayBrightnessState.Builder()
.setBrightness(fallbackBrightness)
.setBrightnessReason(brightnessReason)
- .setSdrBrightness(fallbackBrightness)
.setDisplayBrightnessStrategyName(mAutoBrightnessFallbackStrategy.getName())
.build();
DisplayBrightnessState updatedDisplayBrightnessState =
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
index e16377e57321..93ff9e11d52f 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
@@ -559,7 +559,6 @@ public class AutomaticBrightnessStrategyTest {
mock(DisplayManagerInternal.DisplayPowerRequest.class);
DisplayBrightnessState expectedDisplayBrightnessState = new DisplayBrightnessState.Builder()
.setBrightness(brightness)
- .setSdrBrightness(brightness)
.setBrightnessReason(brightnessReason)
.setDisplayBrightnessStrategyName(mAutomaticBrightnessStrategy.getName())
.setIsSlowChange(false)
@@ -608,7 +607,6 @@ public class AutomaticBrightnessStrategyTest {
DisplayBrightnessState expectedDisplayBrightnessState = new DisplayBrightnessState.Builder()
.setBrightness(brightness)
- .setSdrBrightness(brightness)
.setBrightnessReason(brightnessReason)
.setDisplayBrightnessStrategyName(mAutomaticBrightnessStrategy.getName())
.setIsSlowChange(false)
@@ -648,7 +646,6 @@ public class AutomaticBrightnessStrategyTest {
DisplayBrightnessState expectedDisplayBrightnessState = new DisplayBrightnessState.Builder()
.setBrightness(brightness)
- .setSdrBrightness(brightness)
.setBrightnessReason(brightnessReason)
.setDisplayBrightnessStrategyName(mAutomaticBrightnessStrategy.getName())
.setIsSlowChange(true)
@@ -688,7 +685,6 @@ public class AutomaticBrightnessStrategyTest {
DisplayBrightnessState expectedDisplayBrightnessState = new DisplayBrightnessState.Builder()
.setBrightness(brightness)
- .setSdrBrightness(brightness)
.setBrightnessReason(brightnessReason)
.setDisplayBrightnessStrategyName(mAutomaticBrightnessStrategy.getName())
.setIsSlowChange(false)
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/BoostBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/BoostBrightnessStrategyTest.java
index 353432539587..275bb3efee8e 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/BoostBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/BoostBrightnessStrategyTest.java
@@ -55,7 +55,6 @@ public class BoostBrightnessStrategyTest {
new DisplayBrightnessState.Builder()
.setBrightness(PowerManager.BRIGHTNESS_MAX)
.setBrightnessReason(brightnessReason)
- .setSdrBrightness(PowerManager.BRIGHTNESS_MAX)
.setDisplayBrightnessStrategyName(mBoostBrightnessStrategy.getName())
.build();
DisplayBrightnessState updatedDisplayBrightnessState =
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/DozeBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/DozeBrightnessStrategyTest.java
index bd6d8be45fcb..23e447c25245 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/DozeBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/DozeBrightnessStrategyTest.java
@@ -52,7 +52,6 @@ public class DozeBrightnessStrategyTest {
new DisplayBrightnessState.Builder()
.setBrightness(dozeScreenBrightness)
.setBrightnessReason(brightnessReason)
- .setSdrBrightness(dozeScreenBrightness)
.setDisplayBrightnessStrategyName(mDozeBrightnessModeStrategy.getName())
.build();
DisplayBrightnessState updatedDisplayBrightnessState =
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FallbackBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FallbackBrightnessStrategyTest.java
index 4cae35d11853..c4a579092d38 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FallbackBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FallbackBrightnessStrategyTest.java
@@ -54,7 +54,6 @@ public class FallbackBrightnessStrategyTest {
new DisplayBrightnessState.Builder()
.setBrightness(currentBrightness)
.setBrightnessReason(brightnessReason)
- .setSdrBrightness(currentBrightness)
.setDisplayBrightnessStrategyName(mFallbackBrightnessStrategy.getName())
.setShouldUpdateScreenBrightnessSetting(true)
.setIsUserInitiatedChange(true)
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FollowerBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FollowerBrightnessStrategyTest.java
index fdaf8f6a7808..c01f96e800de 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FollowerBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FollowerBrightnessStrategyTest.java
@@ -55,7 +55,6 @@ public class FollowerBrightnessStrategyTest {
new DisplayBrightnessState.Builder()
.setBrightness(brightnessToFollow)
.setBrightnessReason(brightnessReason)
- .setSdrBrightness(brightnessToFollow)
.setDisplayBrightnessStrategyName(mFollowerBrightnessStrategy.getName())
.setIsSlowChange(slowChange)
.build();
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OffloadBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OffloadBrightnessStrategyTest.java
index e3c276025e51..9fb2afa26ed2 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OffloadBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OffloadBrightnessStrategyTest.java
@@ -66,7 +66,6 @@ public class OffloadBrightnessStrategyTest {
new DisplayBrightnessState.Builder()
.setBrightness(brightness)
.setBrightnessReason(brightnessReason)
- .setSdrBrightness(brightness)
.setDisplayBrightnessStrategyName(mOffloadBrightnessStrategy.getName())
.setShouldUpdateScreenBrightnessSetting(true)
.build();
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OverrideBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OverrideBrightnessStrategyTest.java
index ebe407b2445b..e8b4c06b9c89 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OverrideBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OverrideBrightnessStrategyTest.java
@@ -55,7 +55,6 @@ public class OverrideBrightnessStrategyTest {
new DisplayBrightnessState.Builder()
.setBrightness(overrideBrightness)
.setBrightnessReason(brightnessReason)
- .setSdrBrightness(overrideBrightness)
.setDisplayBrightnessStrategyName(mOverrideBrightnessStrategy.getName())
.build();
DisplayBrightnessState updatedDisplayBrightnessState =
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategyTest.java
index 4bad5696861f..38709ece7007 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategyTest.java
@@ -51,7 +51,6 @@ public final class ScreenOffBrightnessStrategyTest {
DisplayBrightnessState expectedDisplayBrightnessState =
new DisplayBrightnessState.Builder()
.setBrightness(PowerManager.BRIGHTNESS_OFF_FLOAT)
- .setSdrBrightness(PowerManager.BRIGHTNESS_OFF_FLOAT)
.setBrightnessReason(brightnessReason)
.setDisplayBrightnessStrategyName(mScreenOffBrightnessModeStrategy
.getName())
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java
index 5410a20e9d75..f523b6af426b 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java
@@ -55,7 +55,6 @@ public class TemporaryBrightnessStrategyTest {
new DisplayBrightnessState.Builder()
.setBrightness(temporaryBrightness)
.setBrightnessReason(brightnessReason)
- .setSdrBrightness(temporaryBrightness)
.setDisplayBrightnessStrategyName(mTemporaryBrightnessStrategy.getName())
.build();
DisplayBrightnessState updatedDisplayBrightnessState =
diff --git a/services/tests/displayservicetests/src/com/android/server/display/config/DisplayDeviceConfigTestUtils.kt b/services/tests/displayservicetests/src/com/android/server/display/config/DisplayDeviceConfigTestUtils.kt
new file mode 100644
index 000000000000..3b3d6f74da50
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/config/DisplayDeviceConfigTestUtils.kt
@@ -0,0 +1,173 @@
+/*
+ * 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.display.config
+
+import android.util.Spline
+import android.util.Xml
+import com.android.server.display.config.HighBrightnessModeData.HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.OutputStreamWriter
+import org.xmlpull.v1.XmlSerializer
+
+fun createRefreshRateData(
+ defaultRefreshRate: Int = 60,
+ defaultPeakRefreshRate: Int = 60,
+ defaultRefreshRateInHbmHdr: Int = 60,
+ defaultRefreshRateInHbmSunlight: Int = 60,
+ lowPowerSupportedModes: List<SupportedModeData> = emptyList(),
+ lowLightBlockingZoneSupportedModes: List<SupportedModeData> = emptyList()
+): RefreshRateData {
+ return RefreshRateData(
+ defaultRefreshRate, defaultPeakRefreshRate,
+ defaultRefreshRateInHbmHdr, defaultRefreshRateInHbmSunlight,
+ lowPowerSupportedModes, lowLightBlockingZoneSupportedModes
+ )
+}
+
+@JvmOverloads
+fun createHdrBrightnessData(
+ maxBrightnessLimits: Map<Float, Float> = mapOf(Pair(500f, 0.6f)),
+ brightnessIncreaseDebounceMillis: Long = 1000,
+ screenBrightnessRampIncrease: Float = 0.02f,
+ brightnessDecreaseDebounceMillis: Long = 3000,
+ screenBrightnessRampDecrease: Float = 0.04f,
+ minimumHdrPercentOfScreenForNbm: Float = HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT,
+ minimumHdrPercentOfScreenForHbm: Float = HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT,
+ allowInLowPowerMode: Boolean = false,
+ sdrToHdrRatioSpline: Spline? = null
+): HdrBrightnessData {
+ return HdrBrightnessData(
+ maxBrightnessLimits,
+ brightnessIncreaseDebounceMillis,
+ screenBrightnessRampIncrease,
+ brightnessDecreaseDebounceMillis,
+ screenBrightnessRampDecrease,
+ minimumHdrPercentOfScreenForNbm,
+ minimumHdrPercentOfScreenForHbm,
+ allowInLowPowerMode,
+ sdrToHdrRatioSpline
+ )
+}
+
+fun XmlSerializer.highBrightnessMode(
+ enabled: String = "true",
+ transitionPoint: String = "0.67",
+ minimumLux: String = "2500",
+ timeWindowSecs: String = "200",
+ timeMaxSecs: String = "30",
+ timeMinSecs: String = "3",
+ refreshRateRange: Pair<String, String>? = null,
+ allowInLowPowerMode: String? = null,
+ minimumHdrPercentOfScreen: String? = null,
+ sdrHdrRatioMap: List<Pair<String, String>>? = null,
+) {
+ element("highBrightnessMode") {
+ attribute("", "enabled", enabled)
+ element("transitionPoint", transitionPoint)
+ element("minimumLux", minimumLux)
+ element("timing") {
+ element("timeWindowSecs", timeWindowSecs)
+ element("timeMaxSecs", timeMaxSecs)
+ element("timeMinSecs", timeMinSecs)
+ }
+ pair("refreshRate", "minimum", "maximum", refreshRateRange)
+ element("allowInLowPowerMode", allowInLowPowerMode)
+ element("minimumHdrPercentOfScreen", minimumHdrPercentOfScreen)
+ map("sdrHdrRatioMap", "point", "sdrNits", "hdrRatio", sdrHdrRatioMap)
+ }
+}
+
+fun XmlSerializer.hdrBrightnessConfig(
+ brightnessMap: List<Pair<String, String>> = listOf(Pair("500", "0.6")),
+ brightnessIncreaseDebounceMillis: String = "1000",
+ screenBrightnessRampIncrease: String = "0.02",
+ brightnessDecreaseDebounceMillis: String = "3000",
+ screenBrightnessRampDecrease: String = "0.04",
+ minimumHdrPercentOfScreenForNbm: String? = null,
+ minimumHdrPercentOfScreenForHbm: String? = null,
+ allowInLowPowerMode: String? = null,
+ sdrHdrRatioMap: List<Pair<String, String>>? = null,
+) {
+ element("hdrBrightnessConfig") {
+ map("brightnessMap", "point", "first", "second", brightnessMap)
+ element("brightnessIncreaseDebounceMillis", brightnessIncreaseDebounceMillis)
+ element("screenBrightnessRampIncrease", screenBrightnessRampIncrease)
+ element("brightnessDecreaseDebounceMillis", brightnessDecreaseDebounceMillis)
+ element("screenBrightnessRampDecrease", screenBrightnessRampDecrease)
+ element("minimumHdrPercentOfScreenForNbm", minimumHdrPercentOfScreenForNbm)
+ element("minimumHdrPercentOfScreenForHbm", minimumHdrPercentOfScreenForHbm)
+ element("allowInLowPowerMode", allowInLowPowerMode)
+ map("sdrHdrRatioMap", "point", "first", "second", sdrHdrRatioMap)
+ }
+}
+
+fun createDisplayConfiguration(content: XmlSerializer.() -> Unit = { }): DisplayConfiguration {
+ val byteArrayOutputStream = ByteArrayOutputStream()
+ val xmlSerializer = Xml.newSerializer()
+ OutputStreamWriter(byteArrayOutputStream).use { writer ->
+ xmlSerializer.setOutput(writer)
+ xmlSerializer.startDocument("UTF-8", true)
+ xmlSerializer.startTag("", "displayConfiguration")
+ xmlSerializer.content()
+ xmlSerializer.endTag("", "displayConfiguration")
+ xmlSerializer.endDocument()
+ }
+ return XmlParser.read(ByteArrayInputStream(byteArrayOutputStream.toByteArray()))
+}
+
+private fun XmlSerializer.map(
+ rootName: String,
+ nodeName: String,
+ keyName: String,
+ valueName: String,
+ map: List<Pair<String, String>>?
+) {
+ map?.let { m ->
+ element(rootName) {
+ m.forEach { e -> pair(nodeName, keyName, valueName, e) }
+ }
+ }
+}
+
+private fun XmlSerializer.pair(
+ nodeName: String,
+ keyName: String,
+ valueName: String,
+ pair: Pair<String, String>?
+) {
+ pair?.let {
+ element(nodeName) {
+ element(keyName, pair.first)
+ element(valueName, pair.second)
+ }
+ }
+}
+
+private fun XmlSerializer.element(name: String, content: String?) {
+ if (content != null) {
+ startTag("", name)
+ text(content)
+ endTag("", name)
+ }
+}
+
+private fun XmlSerializer.element(name: String, content: XmlSerializer.() -> Unit) {
+ startTag("", name)
+ content()
+ endTag("", name)
+} \ No newline at end of file
diff --git a/services/tests/displayservicetests/src/com/android/server/display/config/HdrBrightnessDataTest.kt b/services/tests/displayservicetests/src/com/android/server/display/config/HdrBrightnessDataTest.kt
new file mode 100644
index 000000000000..19c6924dfa5b
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/config/HdrBrightnessDataTest.kt
@@ -0,0 +1,158 @@
+/*
+ * 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.display.config
+
+import android.util.Spline.createSpline
+import androidx.test.filters.SmallTest
+import com.android.server.display.DisplayBrightnessState
+import com.android.server.display.config.HighBrightnessModeData.HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+@SmallTest
+class HdrBrightnessDataTest {
+
+ @Test
+ fun `test HdrBrightnessData default configuration`() {
+ val displayConfiguration = createDisplayConfiguration {
+ hdrBrightnessConfig(
+ brightnessDecreaseDebounceMillis = "3000",
+ screenBrightnessRampDecrease = "0.05",
+ brightnessIncreaseDebounceMillis = "2000",
+ screenBrightnessRampIncrease = "0.03",
+ brightnessMap = listOf(Pair("500", "0.6"), Pair("600", "0.7")),
+ minimumHdrPercentOfScreenForNbm = null,
+ minimumHdrPercentOfScreenForHbm = null,
+ allowInLowPowerMode = null,
+ sdrHdrRatioMap = null,
+ )
+ }
+
+ val hdrBrightnessData = HdrBrightnessData.loadConfig(displayConfiguration)
+ assertThat(hdrBrightnessData).isNotNull()
+
+ assertThat(hdrBrightnessData!!.brightnessDecreaseDebounceMillis).isEqualTo(3000)
+ assertThat(hdrBrightnessData.screenBrightnessRampDecrease).isEqualTo(0.05f)
+ assertThat(hdrBrightnessData.brightnessIncreaseDebounceMillis).isEqualTo(2000)
+ assertThat(hdrBrightnessData.screenBrightnessRampIncrease).isEqualTo(0.03f)
+
+ assertThat(hdrBrightnessData.maxBrightnessLimits).hasSize(2)
+ assertThat(hdrBrightnessData.maxBrightnessLimits).containsEntry(500f, 0.6f)
+ assertThat(hdrBrightnessData.maxBrightnessLimits).containsEntry(600f, 0.7f)
+
+ assertThat(hdrBrightnessData.minimumHdrPercentOfScreenForNbm).isEqualTo(
+ HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT
+ )
+ assertThat(hdrBrightnessData.minimumHdrPercentOfScreenForHbm).isEqualTo(
+ HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT
+ )
+ assertThat(hdrBrightnessData.allowInLowPowerMode).isFalse()
+ assertThat(hdrBrightnessData.sdrToHdrRatioSpline).isNull()
+ }
+
+ @Test
+ fun `test HdrBrightnessData fallback configuration`() {
+ val displayConfiguration = createDisplayConfiguration {
+ hdrBrightnessConfig(
+ minimumHdrPercentOfScreenForNbm = null,
+ minimumHdrPercentOfScreenForHbm = null,
+ allowInLowPowerMode = null,
+ sdrHdrRatioMap = null,
+ )
+ highBrightnessMode(
+ minimumHdrPercentOfScreen = "0.2",
+ sdrHdrRatioMap = listOf(Pair("2.0", "4.0"), Pair("5.0", "8.0"))
+ )
+ }
+
+ val hdrBrightnessData = HdrBrightnessData.loadConfig(displayConfiguration)
+ assertThat(hdrBrightnessData).isNotNull()
+
+ assertThat(hdrBrightnessData!!.minimumHdrPercentOfScreenForNbm).isEqualTo(0.2f)
+ assertThat(hdrBrightnessData.minimumHdrPercentOfScreenForHbm).isEqualTo(0.2f)
+ assertThat(hdrBrightnessData.allowInLowPowerMode).isFalse()
+
+ val expectedSpline = createSpline(floatArrayOf(2.0f, 5.0f), floatArrayOf(4.0f, 8.0f))
+ assertThat(hdrBrightnessData.sdrToHdrRatioSpline.toString())
+ .isEqualTo(expectedSpline.toString())
+ }
+
+ @Test
+ fun `test HdrBrightnessData fallback configuration no hdrBrightnessConfig`() {
+ val displayConfiguration = createDisplayConfiguration {
+ highBrightnessMode(
+ minimumHdrPercentOfScreen = "0.2",
+ sdrHdrRatioMap = listOf(Pair("2.0", "4.0"), Pair("5.0", "8.0"))
+ )
+ }
+
+ val hdrBrightnessData = HdrBrightnessData.loadConfig(displayConfiguration)
+ assertThat(hdrBrightnessData).isNotNull()
+
+ assertThat(hdrBrightnessData!!.brightnessDecreaseDebounceMillis).isEqualTo(0)
+ assertThat(hdrBrightnessData.screenBrightnessRampDecrease)
+ .isEqualTo(DisplayBrightnessState.CUSTOM_ANIMATION_RATE_NOT_SET)
+ assertThat(hdrBrightnessData.brightnessIncreaseDebounceMillis).isEqualTo(0)
+ assertThat(hdrBrightnessData.screenBrightnessRampIncrease)
+ .isEqualTo(DisplayBrightnessState.CUSTOM_ANIMATION_RATE_NOT_SET)
+
+ assertThat(hdrBrightnessData.maxBrightnessLimits).hasSize(0)
+
+ assertThat(hdrBrightnessData.minimumHdrPercentOfScreenForNbm).isEqualTo(0.2f)
+ assertThat(hdrBrightnessData.minimumHdrPercentOfScreenForHbm).isEqualTo(0.2f)
+ assertThat(hdrBrightnessData.allowInLowPowerMode).isFalse()
+
+ val expectedSpline = createSpline(floatArrayOf(2.0f, 5.0f), floatArrayOf(4.0f, 8.0f))
+ assertThat(hdrBrightnessData.sdrToHdrRatioSpline.toString())
+ .isEqualTo(expectedSpline.toString())
+ }
+
+ @Test
+ fun `test HdrBrightnessData configuration no configuration`() {
+ val displayConfiguration = createDisplayConfiguration()
+
+ val hdrBrightnessData = HdrBrightnessData.loadConfig(displayConfiguration)
+ assertThat(hdrBrightnessData).isNull()
+ }
+
+ @Test
+ fun `test HdrBrightnessData real configuration`() {
+ val displayConfiguration = createDisplayConfiguration {
+ hdrBrightnessConfig(
+ minimumHdrPercentOfScreenForNbm = "0.3",
+ minimumHdrPercentOfScreenForHbm = "0.6",
+ allowInLowPowerMode = "true",
+ sdrHdrRatioMap = listOf(Pair("3.0", "5.0"), Pair("6.0", "8.0"))
+ )
+ highBrightnessMode(
+ minimumHdrPercentOfScreen = "0.2",
+ sdrHdrRatioMap = listOf(Pair("2.0", "4.0"), Pair("5.0", "8.0"))
+ )
+ }
+
+ val hdrBrightnessData = HdrBrightnessData.loadConfig(displayConfiguration)
+ assertThat(hdrBrightnessData).isNotNull()
+
+ assertThat(hdrBrightnessData!!.minimumHdrPercentOfScreenForNbm).isEqualTo(0.3f)
+ assertThat(hdrBrightnessData.minimumHdrPercentOfScreenForHbm).isEqualTo(0.6f)
+ assertThat(hdrBrightnessData.allowInLowPowerMode).isTrue()
+
+ val expectedSpline = createSpline(floatArrayOf(3.0f, 6.0f), floatArrayOf(5.0f, 8.0f))
+ assertThat(hdrBrightnessData.sdrToHdrRatioSpline.toString())
+ .isEqualTo(expectedSpline.toString())
+ }
+} \ No newline at end of file
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt b/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt
index 95702aa1bce1..3c77ec925078 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt
@@ -25,6 +25,7 @@ import androidx.test.filters.SmallTest
import com.android.server.display.DisplayDeviceConfig
import com.android.server.display.config.RefreshRateData
import com.android.server.display.config.SupportedModeData
+import com.android.server.display.config.createRefreshRateData
import com.android.server.display.feature.DisplayManagerFlags
import com.android.server.display.mode.DisplayModeDirector.DisplayDeviceConfigProvider
import com.android.server.testutils.TestHandler
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/SettingsObserverTest.kt b/services/tests/displayservicetests/src/com/android/server/display/mode/SettingsObserverTest.kt
index e431c8c3555c..4fc574a77571 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/SettingsObserverTest.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/SettingsObserverTest.kt
@@ -29,6 +29,7 @@ import com.android.internal.util.test.FakeSettingsProvider
import com.android.server.display.DisplayDeviceConfig
import com.android.server.display.config.RefreshRateData
import com.android.server.display.config.SupportedModeData
+import com.android.server.display.config.createRefreshRateData
import com.android.server.display.feature.DisplayManagerFlags
import com.android.server.display.mode.DisplayModeDirector.DisplayDeviceConfigProvider
import com.android.server.display.mode.SupportedRefreshRatesVote.RefreshRates
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/TestUtils.kt b/services/tests/displayservicetests/src/com/android/server/display/mode/TestUtils.kt
index 5b07166d63e4..0b34fce18a1b 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/TestUtils.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/TestUtils.kt
@@ -16,9 +16,6 @@
package com.android.server.display.mode
-import com.android.server.display.config.RefreshRateData
-import com.android.server.display.config.SupportedModeData
-
internal fun createVotesSummary(
isDisplayResolutionRangeVotingEnabled: Boolean = true,
supportedModesVoteEnabled: Boolean = true,
@@ -29,15 +26,3 @@ internal fun createVotesSummary(
loggingEnabled, supportsFrameRateOverride)
}
-fun createRefreshRateData(
- defaultRefreshRate: Int = 60,
- defaultPeakRefreshRate: Int = 60,
- defaultRefreshRateInHbmHdr: Int = 60,
- defaultRefreshRateInHbmSunlight: Int = 60,
- lowPowerSupportedModes: List<SupportedModeData> = emptyList(),
- lowLightBlockingZoneSupportedModes: List<SupportedModeData> = emptyList()
-): RefreshRateData {
- return RefreshRateData(defaultRefreshRate, defaultPeakRefreshRate,
- defaultRefreshRateInHbmHdr, defaultRefreshRateInHbmSunlight,
- lowPowerSupportedModes, lowLightBlockingZoneSupportedModes)
-}
diff --git a/services/tests/dreamservicetests/AndroidManifest.xml b/services/tests/dreamservicetests/AndroidManifest.xml
index 6092ef6f9427..449521b05135 100644
--- a/services/tests/dreamservicetests/AndroidManifest.xml
+++ b/services/tests/dreamservicetests/AndroidManifest.xml
@@ -53,6 +53,35 @@
android:name="android.service.dream"
android:resource="@xml/test_dream_metadata_invalid" />
</service>
+
+ <service
+ android:name="com.android.server.dreams.TestDreamServiceWithNonexistentSettings"
+ android:exported="false"
+ android:label="Test Dream" >
+ <intent-filter>
+ <action android:name="android.service.dreams.DreamService" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data
+ android:name="android.service.dream"
+ android:resource="@xml/test_dream_metadata_nonexistent_settings" />
+ </service>
+
+ <service
+ android:name="com.android.server.dreams.TestDreamServiceNoPackageNonexistentSettings"
+ android:exported="false"
+ android:label="Test Dream" >
+ <intent-filter>
+ <action android:name="android.service.dreams.DreamService" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data
+ android:name="android.service.dream"
+ android:resource="@xml/test_dream_metadata_nopackage_nonexistent_settings" />
+ </service>
+
+ <activity android:name=".TestDreamSettingsActivity">
+ </activity>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml
new file mode 100644
index 000000000000..f91f0586ec6c
--- /dev/null
+++ b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml
@@ -0,0 +1,20 @@
+<!--
+ ~ 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.
+ -->
+
+<!-- The settings activity does not exist, which is invalid. -->
+<dream xmlns:android="http://schemas.android.com/apk/res/android"
+ android:settingsActivity="com.android.frameworks.dreamservicetests/.TestDreamSettingsActivityNonexistent"
+ android:showClockAndComplications="false"/>
diff --git a/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml
new file mode 100644
index 000000000000..24032c9efcea
--- /dev/null
+++ b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml
@@ -0,0 +1,20 @@
+<!--
+ ~ 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.
+ -->
+
+<!-- The settings activity's ComponentName is invalid. -->
+<dream xmlns:android="http://schemas.android.com/apk/res/android"
+ android:settingsActivity="com.android.frameworks.dreamservicetests.TestDreamSettingsActivityNonexistentNoPackage"
+ android:showClockAndComplications="false"/>
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
index b98af6bc7dd0..b4e1abff3bf7 100644
--- a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
@@ -91,6 +91,28 @@ public class DreamServiceTest {
}
@Test
+ public void testMetadataParsing_nonexistentSettingsActivity()
+ throws PackageManager.NameNotFoundException {
+ final String testDreamClassName =
+ "com.android.server.dreams.TestDreamServiceWithNonexistentSettings";
+ final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName);
+
+ assertThat(metadata.settingsActivity).isNull();
+ assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_DEFAULT);
+ }
+
+ @Test
+ public void testMetadataParsing_noPackage_nonexistentSettingsActivity()
+ throws PackageManager.NameNotFoundException {
+ final String testDreamClassName =
+ "com.android.server.dreams.TestDreamServiceNoPackageNonexistentSettings";
+ final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName);
+
+ assertThat(metadata.settingsActivity).isNull();
+ assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_DEFAULT);
+ }
+
+ @Test
public void testMetadataParsing_exceptionReading() {
final PackageManager packageManager = Mockito.mock(PackageManager.class);
final ServiceInfo serviceInfo = Mockito.mock(ServiceInfo.class);
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java
new file mode 100644
index 000000000000..bb8db8a9b655
--- /dev/null
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java
@@ -0,0 +1,20 @@
+/*
+ * 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.dreams;
+
+public class TestDreamSettingsActivity {
+}
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp
index 4149e44a2ee9..5b2c0c651058 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -53,6 +53,7 @@ android_test {
"mockingservicestests-utils-mockito",
"mockito-target-extended-minus-junit4",
"platform-compat-test-rules",
+ "platform-parametric-runner-lib",
"platform-test-annotations",
"PlatformProperties",
"service-blobstore",
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index 337789950a32..f2acbc31b008 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -27,7 +27,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.RescueParty.DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN;
import static com.android.server.RescueParty.LEVEL_FACTORY_RESET;
-import static com.android.server.RescueParty.RESCUE_LEVEL_FACTORY_RESET;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -36,7 +35,6 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
import android.content.ContentResolver;
import android.content.Context;
@@ -47,6 +45,9 @@ import android.crashrecovery.flags.Flags;
import android.os.RecoverySystem;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.DeviceConfig;
import android.provider.Settings;
@@ -61,6 +62,9 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
@@ -77,10 +81,14 @@ import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+
/**
* Test RescueParty.
*/
+@RunWith(Parameterized.class)
public class RescuePartyTest {
+ @Rule
+ public SetFlagsRule mSetFlagsRule;
private static final long CURRENT_NETWORK_TIME_MILLIS = 0L;
private static final String FAKE_NATIVE_NAMESPACE1 = "native1";
private static final String FAKE_NATIVE_NAMESPACE2 = "native2";
@@ -103,9 +111,6 @@ public class RescuePartyTest {
private static final String PROP_DISABLE_FACTORY_RESET_FLAG =
"persist.device_config.configuration.disable_rescue_party_factory_reset";
- @Rule
- public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
private MockitoSession mSession;
private HashMap<String, String> mSystemSettingsMap;
private HashMap<String, String> mCrashRecoveryPropertiesMap;
@@ -129,6 +134,17 @@ public class RescuePartyTest {
@Captor
private ArgumentCaptor<List<String>> mPackageListCaptor;
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getFlags() {
+ return FlagsParameterization.allCombinationsOf(
+ Flags.FLAG_RECOVERABILITY_DETECTION,
+ Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS);
+ }
+
+ public RescuePartyTest(FlagsParameterization flags) {
+ mSetFlagsRule = new SetFlagsRule(flags);
+ }
+
@Before
public void setUp() throws Exception {
mSession =
@@ -234,10 +250,10 @@ public class RescuePartyTest {
}
@Test
- public void testBootLoopDetectionWithExecutionForAllRescueLevels() {
+ @DisableFlags({Flags.FLAG_RECOVERABILITY_DETECTION,
+ Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS})
+ public void testBootLoop() {
// this is old test where the flag needs to be disabled
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
-
RescueParty.onSettingsProviderPublished(mMockContext);
verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
any(Executor.class),
@@ -264,10 +280,22 @@ public class RescuePartyTest {
noteBoot(5);
assertTrue(RescueParty.isFactoryResetPropertySet());
}
+ @Test
+ @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testBootLoopNoFlags() {
+ // this is old test where the flag needs to be disabled
+ noteBoot(1);
+ assertTrue(RescueParty.isRebootPropertySet());
+
+ setCrashRecoveryPropAttemptingReboot(false);
+ noteBoot(2);
+ assertTrue(RescueParty.isFactoryResetPropertySet());
+ }
@Test
- public void testBootLoopDetectionWithExecutionForAllRescueLevelsRecoverabilityDetection() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
+ @EnableFlags(Flags.FLAG_RECOVERABILITY_DETECTION)
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testBootLoopRecoverability() {
RescueParty.onSettingsProviderPublished(mMockContext);
verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
any(Executor.class),
@@ -281,12 +309,14 @@ public class RescuePartyTest {
final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
+
noteBoot(1);
noteBoot(2);
assertTrue(RescueParty.isRebootPropertySet());
noteBoot(3);
+
verifyOnlySettingsReset(Settings.RESET_MODE_UNTRUSTED_DEFAULTS);
noteBoot(4);
@@ -301,10 +331,10 @@ public class RescuePartyTest {
}
@Test
- public void testPersistentAppCrashDetectionWithExecutionForAllRescueLevels() {
+ @DisableFlags({Flags.FLAG_RECOVERABILITY_DETECTION,
+ Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS})
+ public void testPersistentAppCrash() {
// this is old test where the flag needs to be disabled
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
-
noteAppCrash(1, true);
noteAppCrash(2, true);
noteAppCrash(3, true);
@@ -318,8 +348,21 @@ public class RescuePartyTest {
}
@Test
- public void testPersistentAppCrashDetectionWithExecutionForAllRescueLevelsRecoverability() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
+ @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testPersistentAppCrashNoFlags() {
+ // this is old test where the flag needs to be disabled
+ noteAppCrash(1, true);
+ assertTrue(RescueParty.isRebootPropertySet());
+
+ setCrashRecoveryPropAttemptingReboot(false);
+ noteAppCrash(2, true);
+ assertTrue(RescueParty.isFactoryResetPropertySet());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_RECOVERABILITY_DETECTION)
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testPersistentAppCrashRecoverability() {
RescueParty.onSettingsProviderPublished(mMockContext);
verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
any(Executor.class),
@@ -357,10 +400,10 @@ public class RescuePartyTest {
}
@Test
- public void testNonPersistentAppDoesntDoAnything() {
+ @DisableFlags({Flags.FLAG_RECOVERABILITY_DETECTION,
+ Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS})
+ public void testNonPersistentApp() {
// this is old test where the flag needs to be disabled
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
-
noteAppCrash(1, false);
noteAppCrash(2, false);
noteAppCrash(3, false);
@@ -371,8 +414,9 @@ public class RescuePartyTest {
}
@Test
+ @EnableFlags(Flags.FLAG_RECOVERABILITY_DETECTION)
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testNonPersistentAppOnlyPerformsFlagResetsRecoverabilityDetection() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
RescueParty.onSettingsProviderPublished(mMockContext);
verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
any(Executor.class),
@@ -408,60 +452,6 @@ public class RescuePartyTest {
}
@Test
- public void testNonPersistentAppCrashDetectionWithScopedResets() {
- // this is old test where the flag needs to be disabled
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
-
- RescueParty.onSettingsProviderPublished(mMockContext);
- verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
- any(Executor.class),
- mMonitorCallbackCaptor.capture()));
-
- // Record DeviceConfig accesses
- RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
- DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue();
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE2);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE3);
-
- // Fake DeviceConfig value changes
- monitorCallback.onNamespaceUpdate(NAMESPACE1);
- verify(mMockPackageWatchdog).startObservingHealth(observer,
- Arrays.asList(CALLING_PACKAGE1), RescueParty.DEFAULT_OBSERVING_DURATION_MS);
- monitorCallback.onNamespaceUpdate(NAMESPACE2);
- verify(mMockPackageWatchdog, times(2)).startObservingHealth(eq(observer),
- mPackageListCaptor.capture(),
- eq(RescueParty.DEFAULT_OBSERVING_DURATION_MS));
- monitorCallback.onNamespaceUpdate(NAMESPACE3);
- verify(mMockPackageWatchdog).startObservingHealth(observer,
- Arrays.asList(CALLING_PACKAGE2), RescueParty.DEFAULT_OBSERVING_DURATION_MS);
- assertTrue(mPackageListCaptor.getValue().containsAll(
- Arrays.asList(CALLING_PACKAGE1, CALLING_PACKAGE2)));
- // Perform and verify scoped resets
- final String[] expectedResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
- final String[] expectedAllResetNamespaces =
- new String[]{NAMESPACE1, NAMESPACE2, NAMESPACE3};
- HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>();
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
-
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2);
-
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3);
-
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 4);
- assertFalse(RescueParty.isRebootPropertySet());
-
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 5);
- assertFalse(RescueParty.isFactoryResetPropertySet());
- }
-
- @Test
public void testIsRecoveryTriggeredReboot() {
for (int i = 0; i < LEVEL_FACTORY_RESET; i++) {
noteBoot(i + 1);
@@ -474,19 +464,6 @@ public class RescuePartyTest {
}
@Test
- public void testIsRecoveryTriggeredRebootRecoverabilityDetection() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- for (int i = 0; i < RESCUE_LEVEL_FACTORY_RESET; i++) {
- noteBoot(i + 1);
- }
- assertFalse(RescueParty.isFactoryResetPropertySet());
- setCrashRecoveryPropAttemptingReboot(false);
- noteBoot(RESCUE_LEVEL_FACTORY_RESET + 1);
- assertTrue(RescueParty.isRecoveryTriggeredReboot());
- assertTrue(RescueParty.isFactoryResetPropertySet());
- }
-
- @Test
public void testIsRecoveryTriggeredRebootOnlyAfterRebootCompleted() {
for (int i = 0; i < LEVEL_FACTORY_RESET; i++) {
noteBoot(i + 1);
@@ -505,25 +482,6 @@ public class RescuePartyTest {
}
@Test
- public void testIsRecoveryTriggeredRebootOnlyAfterRebootCompletedRecoverabilityDetection() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- for (int i = 0; i < RESCUE_LEVEL_FACTORY_RESET; i++) {
- noteBoot(i + 1);
- }
- int mitigationCount = RESCUE_LEVEL_FACTORY_RESET + 1;
- assertFalse(RescueParty.isFactoryResetPropertySet());
- noteBoot(mitigationCount++);
- assertFalse(RescueParty.isFactoryResetPropertySet());
- noteBoot(mitigationCount++);
- assertFalse(RescueParty.isFactoryResetPropertySet());
- noteBoot(mitigationCount++);
- setCrashRecoveryPropAttemptingReboot(false);
- noteBoot(mitigationCount + 1);
- assertTrue(RescueParty.isRecoveryTriggeredReboot());
- assertTrue(RescueParty.isFactoryResetPropertySet());
- }
-
- @Test
public void testThrottlingOnBootFailures() {
setCrashRecoveryPropAttemptingReboot(false);
long now = System.currentTimeMillis();
@@ -537,20 +495,6 @@ public class RescuePartyTest {
}
@Test
- public void testThrottlingOnBootFailuresRecoverabilityDetection() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- setCrashRecoveryPropAttemptingReboot(false);
- long now = System.currentTimeMillis();
- long beforeTimeout = now - TimeUnit.MINUTES.toMillis(
- DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN - 1);
- setCrashRecoveryPropLastFactoryReset(beforeTimeout);
- for (int i = 1; i <= RESCUE_LEVEL_FACTORY_RESET; i++) {
- noteBoot(i);
- }
- assertFalse(RescueParty.isRecoveryTriggeredReboot());
- }
-
- @Test
public void testThrottlingOnAppCrash() {
setCrashRecoveryPropAttemptingReboot(false);
long now = System.currentTimeMillis();
@@ -564,20 +508,6 @@ public class RescuePartyTest {
}
@Test
- public void testThrottlingOnAppCrashRecoverabilityDetection() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- setCrashRecoveryPropAttemptingReboot(false);
- long now = System.currentTimeMillis();
- long beforeTimeout = now - TimeUnit.MINUTES.toMillis(
- DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN - 1);
- setCrashRecoveryPropLastFactoryReset(beforeTimeout);
- for (int i = 0; i <= RESCUE_LEVEL_FACTORY_RESET; i++) {
- noteAppCrash(i + 1, true);
- }
- assertFalse(RescueParty.isRecoveryTriggeredReboot());
- }
-
- @Test
public void testNotThrottlingAfterTimeoutOnBootFailures() {
setCrashRecoveryPropAttemptingReboot(false);
long now = System.currentTimeMillis();
@@ -591,20 +521,6 @@ public class RescuePartyTest {
}
@Test
- public void testNotThrottlingAfterTimeoutOnBootFailuresRecoverabilityDetection() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- setCrashRecoveryPropAttemptingReboot(false);
- long now = System.currentTimeMillis();
- long afterTimeout = now - TimeUnit.MINUTES.toMillis(
- DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN + 1);
- setCrashRecoveryPropLastFactoryReset(afterTimeout);
- for (int i = 1; i <= RESCUE_LEVEL_FACTORY_RESET; i++) {
- noteBoot(i);
- }
- assertTrue(RescueParty.isRecoveryTriggeredReboot());
- }
-
- @Test
public void testNotThrottlingAfterTimeoutOnAppCrash() {
setCrashRecoveryPropAttemptingReboot(false);
long now = System.currentTimeMillis();
@@ -618,20 +534,7 @@ public class RescuePartyTest {
}
@Test
- public void testNotThrottlingAfterTimeoutOnAppCrashRecoverabilityDetection() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- setCrashRecoveryPropAttemptingReboot(false);
- long now = System.currentTimeMillis();
- long afterTimeout = now - TimeUnit.MINUTES.toMillis(
- DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN + 1);
- setCrashRecoveryPropLastFactoryReset(afterTimeout);
- for (int i = 0; i <= RESCUE_LEVEL_FACTORY_RESET; i++) {
- noteAppCrash(i + 1, true);
- }
- assertTrue(RescueParty.isRecoveryTriggeredReboot());
- }
-
- @Test
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testNativeRescuePartyResets() {
doReturn(true).when(() -> SettingsToPropertiesMapper.isNativeFlagsResetPerformed());
doReturn(FAKE_RESET_NATIVE_NAMESPACES).when(
@@ -647,7 +550,6 @@ public class RescuePartyTest {
@Test
public void testExplicitlyEnablingAndDisablingRescue() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false));
SystemProperties.set(PROP_DISABLE_RESCUE, Boolean.toString(true));
assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
@@ -660,7 +562,6 @@ public class RescuePartyTest {
@Test
public void testDisablingRescueByDeviceConfigFlag() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false));
SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(true));
@@ -686,24 +587,10 @@ public class RescuePartyTest {
}
@Test
- public void testDisablingFactoryResetByDeviceConfigFlagRecoverabilityDetection() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
- SystemProperties.set(PROP_DISABLE_FACTORY_RESET_FLAG, Boolean.toString(true));
-
- for (int i = 0; i < RESCUE_LEVEL_FACTORY_RESET; i++) {
- noteBoot(i + 1);
- }
- assertFalse(RescueParty.isFactoryResetPropertySet());
-
- // Restore the property value initialized in SetUp()
- SystemProperties.set(PROP_DISABLE_FACTORY_RESET_FLAG, "");
- }
-
- @Test
+ @DisableFlags({Flags.FLAG_RECOVERABILITY_DETECTION,
+ Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS})
public void testHealthCheckLevels() {
// this is old test where the flag needs to be disabled
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
-
RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
// Ensure that no action is taken for cases where the failure reason is unknown
@@ -729,8 +616,9 @@ public class RescuePartyTest {
}
@Test
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ @EnableFlags(Flags.FLAG_RECOVERABILITY_DETECTION)
public void testHealthCheckLevelsRecoverabilityDetection() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
// Ensure that no action is taken for cases where the failure reason is unknown
@@ -767,11 +655,31 @@ public class RescuePartyTest {
PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 7),
PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
}
+ @Test
+ @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testHealthCheckLevelsNoFlags() {
+ // this is old test where the flag needs to be disabled
+ RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
+
+ // Ensure that no action is taken for cases where the failure reason is unknown
+ assertEquals(observer.onHealthCheckFailed(null, PackageWatchdog.FAILURE_REASON_UNKNOWN, 1),
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_0);
+
+ // Ensure the correct user impact is returned for each mitigation count.
+ assertEquals(observer.onHealthCheckFailed(null,
+ PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1),
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_50);
+ assertEquals(observer.onHealthCheckFailed(null,
+ PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2),
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_100);
+ }
@Test
+ @DisableFlags({Flags.FLAG_RECOVERABILITY_DETECTION,
+ Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS})
public void testBootLoopLevels() {
// this is old test where the flag needs to be disabled
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
+
RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
@@ -784,8 +692,9 @@ public class RescuePartyTest {
}
@Test
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ @EnableFlags(Flags.FLAG_RECOVERABILITY_DETECTION)
public void testBootLoopLevelsRecoverabilityDetection() {
- mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
assertEquals(observer.onBootLoop(1), PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
@@ -797,6 +706,16 @@ public class RescuePartyTest {
}
@Test
+ @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testBootLoopLevelsNoFlags() {
+ RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
+
+ assertEquals(observer.onBootLoop(1), PackageHealthObserverImpact.USER_IMPACT_LEVEL_50);
+ assertEquals(observer.onBootLoop(2), PackageHealthObserverImpact.USER_IMPACT_LEVEL_100);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testResetDeviceConfigForPackagesOnlyRuntimeMap() {
RescueParty.onSettingsProviderPublished(mMockContext);
verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
@@ -827,6 +746,7 @@ public class RescuePartyTest {
}
@Test
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testResetDeviceConfigForPackagesOnlyPresetMap() {
RescueParty.onSettingsProviderPublished(mMockContext);
verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
@@ -835,7 +755,7 @@ public class RescuePartyTest {
String presetMapping = NAMESPACE1 + ":" + CALLING_PACKAGE1 + ","
+ NAMESPACE2 + ":" + CALLING_PACKAGE2 + ","
- + NAMESPACE3 + ":" + CALLING_PACKAGE1;
+ + NAMESPACE3 + ":" + CALLING_PACKAGE1;
doReturn(presetMapping).when(() -> DeviceConfig.getString(
eq(RescueParty.NAMESPACE_CONFIGURATION),
eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG),
@@ -848,6 +768,7 @@ public class RescuePartyTest {
}
@Test
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testResetDeviceConfigForPackagesBothMaps() {
RescueParty.onSettingsProviderPublished(mMockContext);
verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
@@ -884,6 +805,7 @@ public class RescuePartyTest {
}
@Test
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testResetDeviceConfigNoExceptionWhenFlagMalformed() {
RescueParty.onSettingsProviderPublished(mMockContext);
verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 419bcb8650a7..e610a32cb549 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -527,7 +527,7 @@ public class ActivityManagerServiceTest {
final ProcessRecord appRec = new ProcessRecord(mAms, info, info.processName, uid);
final ProcessStatsService tracker = mAms.mProcessStats;
- final IApplicationThread appThread = mock(IApplicationThread.class);
+ final ApplicationThreadDeferred appThread = mock(ApplicationThreadDeferred.class);
doReturn(mock(IBinder.class)).when(appThread).asBinder();
appRec.makeActive(appThread, tracker);
mAms.mProcessList.addProcessNameLocked(appRec);
@@ -701,7 +701,8 @@ public class ActivityManagerServiceTest {
final var wpc = fifoProc.getWindowProcessController();
spyOn(wpc);
doReturn(true).when(wpc).useFifoUiScheduling();
- fifoProc.makeActive(fifoProc.getThread(), mAms.mProcessStats);
+ fifoProc.makeActive(new ApplicationThreadDeferred(fifoProc.getThread()),
+ mAms.mProcessStats);
assertTrue(fifoProc.useFifoUiScheduling());
assertTrue(mAms.mSpecifiedFifoProcesses.contains(fifoProc));
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationThreadDeferredTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationThreadDeferredTest.java
new file mode 100644
index 000000000000..8f8c1ac51907
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationThreadDeferredTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.am;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.IApplicationThread;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+
+/**
+ * Tests to verify that the ApplicationThreadDeferred properly defers binder calls to paused
+ * processes.
+ */
+@SmallTest
+public class ApplicationThreadDeferredTest {
+ private static final String TAG = "ApplicationThreadDeferredTest";
+
+ private void callDeferredApis(IApplicationThread thread) throws Exception {
+ thread.clearDnsCache();
+ thread.updateHttpProxy();
+ thread.updateTimeZone();
+ thread.scheduleLowMemory();
+ }
+
+ // Verify that the special APIs have been called count times.
+ private void verifyDeferredApis(IApplicationThread thread, int count) throws Exception {
+ verify(thread, times(count)).clearDnsCache();
+ verify(thread, times(count)).updateHttpProxy();
+ verify(thread, times(count)).updateTimeZone();
+ verify(thread, times(count)).scheduleLowMemory();
+ }
+
+ // Test the baseline behavior of IApplicationThread. If this test fails, all other tests are
+ // suspect.
+ @Test
+ public void testBaseline() throws Exception {
+ IApplicationThread thread = mock(IApplicationThread.class);
+ callDeferredApis(thread);
+ verifyDeferredApis(thread, 1);
+ }
+
+ // Test the baseline behavior of IApplicationThreadDeferred. If this test fails, all other
+ // tests are suspect.
+ @Test
+ public void testBaselineDeferred() throws Exception {
+ IApplicationThread thread = mock(ApplicationThreadDeferred.class);
+ callDeferredApis(thread);
+ verifyDeferredApis(thread, 1);
+ }
+
+ // Verify that a deferred thread behaves like a regular thread when it is not paused.
+ @Test
+ public void testDeferredUnpaused() throws Exception {
+ IApplicationThread base = mock(IApplicationThread.class);
+ ApplicationThreadDeferred thread = new ApplicationThreadDeferred(base, true);
+ callDeferredApis(thread);
+ verifyDeferredApis(base, 1);
+ }
+
+ // Verify that a paused deferred thread thread does not deliver any calls to its parent. Then
+ // unpause the thread and verify that the collapsed calls are forwarded.
+ @Test
+ public void testDeferredPaused() throws Exception {
+ IApplicationThread base = mock(IApplicationThread.class);
+ ApplicationThreadDeferred thread = new ApplicationThreadDeferred(base, true);
+ thread.onProcessPaused();
+ callDeferredApis(thread);
+ callDeferredApis(thread);
+ verifyDeferredApis(base, 0);
+ thread.onProcessUnpaused();
+ verifyDeferredApis(base, 1);
+ }
+
+ // TODO: [b/302724778] Remove manual JNI load
+ static {
+ System.loadLibrary("mockingservicestestjni");
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java b/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java
index 80f7a066985b..93066d8d113a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java
@@ -189,7 +189,7 @@ public class AsyncProcessStartTest {
private ProcessRecord makeActiveProcessRecord(ApplicationInfo ai, boolean wedge)
throws Exception {
- final IApplicationThread thread = mock(IApplicationThread.class);
+ final ApplicationThreadDeferred thread = mock(ApplicationThreadDeferred.class);
final IBinder threadBinder = new Binder();
doReturn(threadBinder).when(thread).asBinder();
doAnswer((invocation) -> {
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index 13ba1e5e705c..3aaf2e5c61a6 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -325,13 +325,13 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest {
ProcessRecord.updateProcessRecordNodes(r);
mActiveProcesses.add(r);
- final IApplicationThread thread;
+ final ApplicationThreadDeferred thread;
if (dead) {
- thread = mock(IApplicationThread.class, (invocation) -> {
+ thread = mock(ApplicationThreadDeferred.class, (invocation) -> {
throw new DeadObjectException();
});
} else {
- thread = mock(IApplicationThread.class);
+ thread = mock(ApplicationThreadDeferred.class);
}
final IBinder threadBinder = new Binder();
doReturn(threadBinder).when(thread).asBinder();
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java
index 240ddf51ffdc..0796f419e385 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java
@@ -760,7 +760,7 @@ public class CacheOomRankerTest {
ProcessStatsService processStatsService = new ProcessStatsService(
mock(ActivityManagerService.class), new File(Environment.getDataSystemCeDirectory(),
"procstats"));
- app.makeActive(mock(IApplicationThread.class), processStatsService);
+ app.makeActive(mock(ApplicationThreadDeferred.class), processStatsService);
return app;
}
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 6366f24a27e1..1dbd5320cac6 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -3209,7 +3209,7 @@ public class MockingOomAdjusterTests {
final ProcessReceiverRecord receivers = app.mReceivers;
final ProcessProfileRecord profile = app.mProfile;
final ProcessProviderRecord providers = app.mProviders;
- app.makeActive(mock(IApplicationThread.class), mService.mProcessStats);
+ app.makeActive(mock(ApplicationThreadDeferred.class), mService.mProcessStats);
app.setLastActivityTime(mLastActivityTime);
app.setKilledByAm(mKilledByAm);
app.setIsolatedEntryPoint(mIsolatedEntryPoint);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ProcessObserverTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ProcessObserverTest.java
index 89c67d5e32b7..3572d2315a9d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ProcessObserverTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ProcessObserverTest.java
@@ -193,7 +193,7 @@ public class ProcessObserverTest {
private ProcessRecord makeActiveProcessRecord(ApplicationInfo ai)
throws Exception {
- final IApplicationThread thread = mock(IApplicationThread.class);
+ final ApplicationThreadDeferred thread = mock(ApplicationThreadDeferred.class);
final IBinder threadBinder = new Binder();
doReturn(threadBinder).when(thread).asBinder();
doAnswer((invocation) -> {
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java
index 5f126774835d..1ff4a27cb787 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java
@@ -529,7 +529,7 @@ public final class ServiceBindingOomAdjPolicyTest {
@SuppressWarnings("GuardedBy")
private ProcessRecord addProcessRecord(int pid, int uid, int procState, int adj, int cap,
String packageName) {
- final IApplicationThread appThread = mock(IApplicationThread.class);
+ final ApplicationThreadDeferred appThread = mock(ApplicationThreadDeferred.class);
final IBinder threadBinder = mock(IBinder.class);
final ProcessRecord app = makeProcessRecord(pid, uid, uid, null, 0,
procState, adj, cap, 0L, 0L, packageName, packageName, mAms);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ServiceTimeoutTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ServiceTimeoutTest.java
index 7ec27be0bfc3..3c4363651557 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ServiceTimeoutTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ServiceTimeoutTest.java
@@ -145,7 +145,7 @@ public final class ServiceTimeoutTest {
name, // processName
name, // packageName
mAms);
- app.makeActive(mock(IApplicationThread.class), mAms.mProcessStats);
+ app.makeActive(mock(ApplicationThreadDeferred.class), mAms.mProcessStats);
mProcessList.updateLruProcessLocked(app, false, null);
final long now = SystemClock.uptimeMillis();
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
index 396f4da75172..bf7e3a0bd0a6 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
@@ -525,7 +525,7 @@ public class TarBackupReaderTest {
@Test
public void
- chooseRestorePolicy_flagOnNotRestoreAnyVersionVToURestoreAndInAllowlist_returnsIgnore()
+ chooseRestorePolicy_flagOnNotRestoreAnyVersionVToURestoreAndInAllowlist_returnsAccept()
throws Exception {
mSetFlagsRule.enableFlags(
@@ -540,7 +540,8 @@ public class TarBackupReaderTest {
FileMetadata info = new FileMetadata();
info.version = Build.VERSION_CODES.UPSIDE_DOWN_CAKE + 1;
- PackageInfo packageInfo = createNonRestoreAnyVersionUPackage();
+ PackageInfo packageInfo = createNonRestoreAnyVersionPackage(
+ Build.VERSION_CODES.UPSIDE_DOWN_CAKE);
PackageManagerStub.sPackageInfo = packageInfo;
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
@@ -559,7 +560,7 @@ public class TarBackupReaderTest {
@Test
public void
- chooseRestorePolicy_flagOffNotRestoreAnyVersionVToURestoreAndInAllowlist_returnsAccept()
+ chooseRestorePolicy_flagOffNotRestoreAnyVersionVToURestoreAndInAllowlist_returnsIgnore()
throws Exception {
mSetFlagsRule.disableFlags(
@@ -574,7 +575,8 @@ public class TarBackupReaderTest {
FileMetadata info = new FileMetadata();
info.version = Build.VERSION_CODES.UPSIDE_DOWN_CAKE + 1;
- PackageInfo packageInfo = createNonRestoreAnyVersionUPackage();
+ PackageInfo packageInfo = createNonRestoreAnyVersionPackage(
+ Build.VERSION_CODES.UPSIDE_DOWN_CAKE);
PackageManagerStub.sPackageInfo = packageInfo;
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
@@ -608,7 +610,8 @@ public class TarBackupReaderTest {
FileMetadata info = new FileMetadata();
info.version = Build.VERSION_CODES.UPSIDE_DOWN_CAKE + 1;
- PackageInfo packageInfo = createNonRestoreAnyVersionUPackage();
+ PackageInfo packageInfo = createNonRestoreAnyVersionPackage(
+ Build.VERSION_CODES.UPSIDE_DOWN_CAKE);
PackageManagerStub.sPackageInfo = packageInfo;
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
@@ -716,6 +719,36 @@ public class TarBackupReaderTest {
LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER);
}
+ @Test
+ public void
+ chooseRestorePolicy_allowlistNotSetNotRestoreAnyVersionVersionMismatch_returnsIgnore()
+ throws Exception {
+ mSetFlagsRule.disableFlags(
+ Flags.FLAG_ENABLE_V_TO_U_RESTORE_FOR_SYSTEM_COMPONENTS_IN_ALLOWLIST);
+
+ TarBackupReader tarBackupReader = createTarBackupReader();
+
+ Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+ FileMetadata info = new FileMetadata();
+ info.version = Build.VERSION_CODES.UPSIDE_DOWN_CAKE + 2;
+
+ PackageInfo packageInfo = createNonRestoreAnyVersionPackage(
+ Build.VERSION_CODES.UPSIDE_DOWN_CAKE + 1);
+ PackageManagerStub.sPackageInfo = packageInfo;
+
+ doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
+ packageInfo.packageName);
+ RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+ false /* allowApks */, info, signatures, mMockPackageManagerInternal,
+ mUserId, mContext);
+
+ assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+ assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+ LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER);
+ }
+
private TarBackupReader createTarBackupReader() throws Exception {
InputStream inputStream = mContext.getResources().openRawResource(
R.raw.backup_telephony_no_password);
@@ -726,7 +759,7 @@ public class TarBackupReaderTest {
return tarBackupReader;
}
- private PackageInfo createNonRestoreAnyVersionUPackage(){
+ private PackageInfo createNonRestoreAnyVersionPackage(int versionCode) {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
packageInfo.applicationInfo = new ApplicationInfo();
@@ -740,7 +773,7 @@ public class TarBackupReaderTest {
SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
null,
null));
- packageInfo.versionCode = Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
+ packageInfo.versionCode = versionCode;
return packageInfo;
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp
new file mode 100644
index 000000000000..127d3e8a4136
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp
@@ -0,0 +1,58 @@
+// 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 {
+ // 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"],
+ default_team: "trendy_team_mainline_modularization",
+}
+
+android_test {
+ name: "CrashRecoveryModuleTests",
+
+ srcs: [
+ "*.java",
+ ],
+
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.runner",
+ "mockito-target-extended-minus-junit4",
+ "services.core",
+ "truth",
+ "flag-junit",
+ ],
+
+ libs: [
+ "android.test.mock",
+ "android.test.base",
+ "android.test.runner",
+ ],
+
+ jni_libs: [
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
+ ],
+
+ certificate: "platform",
+ platform_apis: true,
+ test_suites: [
+ "device-tests",
+ "automotive-tests",
+ ],
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/AndroidManifest.xml b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/AndroidManifest.xml
new file mode 100644
index 000000000000..067f116d003c
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.crashrecovery">
+
+ <uses-sdk android:targetSdkVersion="35" />
+
+ <application android:testOnly="true"
+ android:debuggable="true">
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.server.crashrecovery"
+ android:label="Frameworks crashrecovery module test" />
+</manifest>
diff --git a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/AndroidTest.xml b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/AndroidTest.xml
new file mode 100644
index 000000000000..7b06ebec654d
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+<configuration description="Runs Crashrecovery Module Tests.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-instrumentation" />
+
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="install-arg" value="-t" />
+ <option name="test-file-name" value="CrashRecoveryModuleTests.apk" />
+ </target_preparer>
+
+ <option name="test-tag" value="CrashRecoveryModuleTests" />
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.server.crashrecovery" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration>
diff --git a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/CrashRecoveryModuleTest.java b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/CrashRecoveryModuleTest.java
new file mode 100644
index 000000000000..d0b7cc7b70e6
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/CrashRecoveryModuleTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.crashrecovery;
+
+import static com.android.server.SystemService.PHASE_ACTIVITY_MANAGER_READY;
+import static com.android.server.SystemService.PHASE_THIRD_PARTY_APPS_CAN_START;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.runner.AndroidJUnit4;
+
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.server.PackageWatchdog;
+import com.android.server.RescueParty;
+import com.android.server.crashrecovery.CrashRecoveryModule.Lifecycle;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+/**
+ * Test CrashRecoveryModule.
+ */
+@RunWith(AndroidJUnit4.class)
+public class CrashRecoveryModuleTest {
+
+ @Rule
+ public SetFlagsRule mSetFlagsRule;
+
+ private MockitoSession mSession;
+ private Lifecycle mLifecycle;
+
+ @Mock PackageWatchdog mPackageWatchdog;
+
+ @Before
+ public void setup() {
+ Context context = ApplicationProvider.getApplicationContext();
+ mSession = ExtendedMockito.mockitoSession()
+ .initMocks(this)
+ .strictness(Strictness.LENIENT)
+ .mockStatic(PackageWatchdog.class)
+ .mockStatic(RescueParty.class)
+ .startMocking();
+ when(PackageWatchdog.getInstance(context)).thenReturn(mPackageWatchdog);
+ ExtendedMockito.doNothing().when(() -> RescueParty.registerHealthObserver(context));
+ mLifecycle = new Lifecycle(context);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mSession.finishMocking();
+ }
+
+ @Test
+ public void testLifecycleServiceStart() {
+ mLifecycle.onStart();
+ doNothing().when(mPackageWatchdog).registerShutdownBroadcastReceiver();
+
+ verify(mPackageWatchdog, times(1)).noteBoot();
+ verify(mPackageWatchdog, times(1)).registerShutdownBroadcastReceiver();
+ ExtendedMockito.verify(() -> RescueParty.registerHealthObserver(any()),
+ Mockito.times(1));
+ }
+
+ @Test
+ public void testLifecycleServiceOnBootPhase() {
+ doNothing().when(mPackageWatchdog).onPackagesReady();
+
+ mLifecycle.onBootPhase(PHASE_ACTIVITY_MANAGER_READY);
+ verify(mPackageWatchdog, never()).onPackagesReady();
+
+ mLifecycle.onBootPhase(PHASE_THIRD_PARTY_APPS_CAN_START);
+ verify(mPackageWatchdog, times(1)).onPackagesReady();
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/OWNERS b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/OWNERS
new file mode 100644
index 000000000000..8337fd2453df
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/crashrecovery/OWNERS \ No newline at end of file
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 79f1574105ba..37d87c4e5d97 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -683,15 +683,14 @@ public final class UserManagerServiceTest {
UserInfo privateProfileUser =
mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME,
USER_TYPE_PROFILE_PRIVATE, 0, mainUser, null);
- Mockito.doNothing().when(mSpiedUms).scheduleMessageToAutoLockPrivateSpace(
- eq(privateProfileUser.getUserHandle().getIdentifier()), any(),
- anyLong());
+ Mockito.doNothing().when(mSpiedUms).scheduleAlarmToAutoLockPrivateSpace(
+ eq(privateProfileUser.getUserHandle().getIdentifier()), anyLong());
- mSpiedUms.maybeScheduleMessageToAutoLockPrivateSpace();
+ mSpiedUms.maybeScheduleAlarmToAutoLockPrivateSpace();
- Mockito.verify(mSpiedUms).scheduleMessageToAutoLockPrivateSpace(
- eq(privateProfileUser.getUserHandle().getIdentifier()), any(), anyLong());
+ Mockito.verify(mSpiedUms).scheduleAlarmToAutoLockPrivateSpace(
+ eq(privateProfileUser.getUserHandle().getIdentifier()), anyLong());
}
@Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
index 7aec42b7eceb..1a398c5f1ec3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
@@ -16,6 +16,8 @@
package com.android.server.trust;
+import static android.security.Flags.FLAG_SHOULD_TRUST_MANAGER_LISTEN_FOR_PRIMARY_AUTH;
+import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth;
import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
@@ -43,6 +45,7 @@ import static java.util.Collections.singleton;
import android.Manifest;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManager;
@@ -72,6 +75,8 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
+import android.platform.test.flag.junit.FlagsParameterization;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.security.KeyStoreAuthorization;
import android.service.trust.GrantTrustResult;
@@ -90,6 +95,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.StrongAuthFlags;
import com.android.internal.widget.LockSettingsInternal;
+import com.android.internal.widget.LockSettingsStateListener;
import com.android.modules.utils.testing.ExtendedMockitoRule;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -100,6 +106,7 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
@@ -111,7 +118,16 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
public class TrustManagerServiceTest {
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getParams() {
+ return FlagsParameterization.allCombinationsOf(
+ FLAG_SHOULD_TRUST_MANAGER_LISTEN_FOR_PRIMARY_AUTH);
+ }
@Rule
public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
@@ -121,6 +137,9 @@ public class TrustManagerServiceTest {
.build();
@Rule
+ public final SetFlagsRule mSetFlagsRule;
+
+ @Rule
public final MockContext mMockContext = new MockContext(
ApplicationProvider.getApplicationContext());
@@ -142,6 +161,7 @@ public class TrustManagerServiceTest {
private final Map<ComponentName, ITrustAgentService.Stub> mMockTrustAgents = new HashMap<>();
private @Mock ActivityManager mActivityManager;
+ private @Mock ActivityManagerInternal mActivityManagerInternal;
private @Mock AlarmManager mAlarmManager;
private @Mock BiometricManager mBiometricManager;
private @Mock DevicePolicyManager mDevicePolicyManager;
@@ -158,6 +178,11 @@ public class TrustManagerServiceTest {
private HandlerThread mHandlerThread;
private TrustManagerService mService;
private ITrustManager mTrustManager;
+ private ActivityManagerInternal mPreviousActivityManagerInternal;
+
+ public TrustManagerServiceTest(FlagsParameterization flags) {
+ mSetFlagsRule = new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT, flags);
+ }
@Before
public void setUp() throws Exception {
@@ -210,6 +235,11 @@ public class TrustManagerServiceTest {
mMockContext.setMockPackageManager(mPackageManager);
mMockContext.addMockSystemService(UserManager.class, mUserManager);
doReturn(mWindowManager).when(() -> WindowManagerGlobal.getWindowManagerService());
+ mPreviousActivityManagerInternal = LocalServices.getService(
+ ActivityManagerInternal.class);
+ LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+ LocalServices.addService(ActivityManagerInternal.class,
+ mActivityManagerInternal);
LocalServices.addService(SystemServiceManager.class, mock(SystemServiceManager.class));
grantPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE);
@@ -257,7 +287,14 @@ public class TrustManagerServiceTest {
@After
public void tearDown() {
LocalServices.removeServiceForTest(SystemServiceManager.class);
- mHandlerThread.quit();
+ LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+ if (mPreviousActivityManagerInternal != null) {
+ LocalServices.addService(ActivityManagerInternal.class,
+ mPreviousActivityManagerInternal);
+ }
+ if (mHandlerThread != null) {
+ mHandlerThread.quit();
+ }
}
@Test
@@ -579,11 +616,27 @@ public class TrustManagerServiceTest {
}
private void attemptSuccessfulUnlock(int userId) throws RemoteException {
- mTrustManager.reportUnlockAttempt(/* successful= */ true, userId);
+ if (shouldTrustManagerListenForPrimaryAuth()) {
+ ArgumentCaptor<LockSettingsStateListener> captor =
+ ArgumentCaptor.forClass(LockSettingsStateListener.class);
+ verify(mLockSettingsInternal).registerLockSettingsStateListener(captor.capture());
+ LockSettingsStateListener listener = captor.getValue();
+ listener.onAuthenticationSucceeded(userId);
+ } else {
+ mTrustManager.reportUnlockAttempt(/* successful= */ true, userId);
+ }
}
private void attemptFailedUnlock(int userId) throws RemoteException {
- mTrustManager.reportUnlockAttempt(/* successful= */ false, userId);
+ if (shouldTrustManagerListenForPrimaryAuth()) {
+ ArgumentCaptor<LockSettingsStateListener> captor =
+ ArgumentCaptor.forClass(LockSettingsStateListener.class);
+ verify(mLockSettingsInternal).registerLockSettingsStateListener(captor.capture());
+ LockSettingsStateListener listener = captor.getValue();
+ listener.onAuthenticationFailed(userId);
+ } else {
+ mTrustManager.reportUnlockAttempt(/* successful= */ false, userId);
+ }
}
private void grantRenewableTrust(ITrustAgentServiceCallback callback) throws RemoteException {
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
index 362607b91763..b13fc530399b 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
@@ -355,7 +355,7 @@ public class WifiPowerStatsCollectorTest {
assertThat(stats.getNumBytesRx()).isEqualTo(13321);
assertThat(stats.getNumPacketsTx()).isEqualTo(263);
assertThat(stats.getNumBytesTx()).isEqualTo(7234);
- assertThat(stats.getScanTimeMillis()).isEqualTo(2200);
+ assertThat(stats.getScanTimeMillis()).isEqualTo(200);
assertThat(stats.getRxTimeMillis()).isEqualTo(6000);
assertThat(stats.getTxTimeMillis()).isEqualTo(1000);
assertThat(stats.getIdleTimeMillis()).isEqualTo(300);
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 753db125ffe3..b9e99dd2e1e4 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -36,6 +36,8 @@ android_test {
"-Werror",
],
static_libs: [
+ "a11ychecker-protos-java-proto-lite",
+ "aatf",
"cts-input-lib",
"frameworks-base-testutils",
"services.accessibility",
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
index ca3055196e6d..62fa95149067 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
@@ -152,6 +152,7 @@ public class AccessibilityUserStateTest {
@Test
public void onSwitchToAnotherUser_userStateClearedNonDefaultValues() {
+ String componentNameString = COMPONENT_NAME.flattenToString();
mUserState.getBoundServicesLocked().add(mMockConnection);
mUserState.getBindingServicesLocked().add(COMPONENT_NAME);
mUserState.setLastSentClientStateLocked(
@@ -162,10 +163,13 @@ public class AccessibilityUserStateTest {
mUserState.setInteractiveUiTimeoutLocked(30);
mUserState.mEnabledServices.add(COMPONENT_NAME);
mUserState.mTouchExplorationGrantedServices.add(COMPONENT_NAME);
- mUserState.updateShortcutTargetsLocked(Set.of(COMPONENT_NAME.flattenToString()), HARDWARE);
- mUserState.updateShortcutTargetsLocked(Set.of(COMPONENT_NAME.flattenToString()), SOFTWARE);
- mUserState.updateShortcutTargetsLocked(Set.of(COMPONENT_NAME.flattenToString()), GESTURE);
- mUserState.setTargetAssignedToAccessibilityButton(COMPONENT_NAME.flattenToString());
+ mUserState.updateShortcutTargetsLocked(Set.of(componentNameString), HARDWARE);
+ mUserState.updateShortcutTargetsLocked(Set.of(componentNameString), SOFTWARE);
+ mUserState.updateShortcutTargetsLocked(Set.of(componentNameString), GESTURE);
+ mUserState.updateShortcutTargetsLocked(Set.of(componentNameString), QUICK_SETTINGS);
+ mUserState.updateA11yTilesInQsPanelLocked(
+ Set.of(AccessibilityShortcutController.COLOR_INVERSION_TILE_COMPONENT_NAME));
+ mUserState.setTargetAssignedToAccessibilityButton(componentNameString);
mUserState.setTouchExplorationEnabledLocked(true);
mUserState.setMagnificationSingleFingerTripleTapEnabledLocked(true);
mUserState.setMagnificationTwoFingerTripleTapEnabledLocked(true);
@@ -189,6 +193,8 @@ public class AccessibilityUserStateTest {
assertTrue(mUserState.getShortcutTargetsLocked(HARDWARE).isEmpty());
assertTrue(mUserState.getShortcutTargetsLocked(SOFTWARE).isEmpty());
assertTrue(mUserState.getShortcutTargetsLocked(GESTURE).isEmpty());
+ assertTrue(mUserState.getShortcutTargetsLocked(QUICK_SETTINGS).isEmpty());
+ assertTrue(mUserState.getA11yQsTilesInQsPanel().isEmpty());
assertNull(mUserState.getTargetAssignedToAccessibilityButton());
assertFalse(mUserState.isTouchExplorationEnabledLocked());
assertFalse(mUserState.isMagnificationSingleFingerTripleTapEnabledLocked());
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MouseKeysInterceptorTest.kt b/services/tests/servicestests/src/com/android/server/accessibility/MouseKeysInterceptorTest.kt
new file mode 100644
index 000000000000..0def51691efa
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MouseKeysInterceptorTest.kt
@@ -0,0 +1,295 @@
+/*
+ * Copyright 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.accessibility
+
+import android.util.MathUtils.sqrt
+
+import android.companion.virtual.VirtualDeviceManager
+import android.companion.virtual.VirtualDeviceParams
+import android.content.Context
+import android.hardware.input.IInputManager
+import android.hardware.input.InputManager
+import android.hardware.input.InputManagerGlobal
+import android.hardware.input.VirtualMouse
+import android.hardware.input.VirtualMouseButtonEvent
+import android.hardware.input.VirtualMouseConfig
+import android.hardware.input.VirtualMouseRelativeEvent
+import android.hardware.input.VirtualMouseScrollEvent
+import android.os.RemoteException
+import android.os.test.TestLooper
+import android.platform.test.annotations.Presubmit
+import android.view.KeyEvent
+import androidx.test.core.app.ApplicationProvider
+import com.android.server.companion.virtual.VirtualDeviceManagerInternal
+import com.android.server.LocalServices
+import com.android.server.testutils.OffsettableClock
+import junit.framework.Assert.assertEquals
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.mockito.ArgumentCaptor
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import java.util.concurrent.TimeUnit
+import java.util.LinkedList
+import java.util.Queue
+import android.util.ArraySet
+
+/**
+ * Tests for {@link MouseKeysInterceptor}
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:MouseKeysInterceptorTest
+ */
+@Presubmit
+class MouseKeysInterceptorTest {
+ companion object {
+ const val DISPLAY_ID = 1
+ const val DEVICE_ID = 123
+ const val MOUSE_POINTER_MOVEMENT_STEP = 1.8f
+ // This delay is required for key events to be sent and handled correctly.
+ // The handler only performs a move/scroll event if it receives the key event
+ // at INTERVAL_MILLIS (which happens in practice). Hence, we need this delay in the tests.
+ const val KEYBOARD_POST_EVENT_DELAY_MILLIS = 20L
+ }
+
+ private lateinit var mouseKeysInterceptor: MouseKeysInterceptor
+ private val clock = OffsettableClock()
+ private val testLooper = TestLooper { clock.now() }
+ private val nextInterceptor = TrackingInterceptor()
+
+ @Mock
+ private lateinit var mockAms: AccessibilityManagerService
+
+ @Mock
+ private lateinit var iInputManager: IInputManager
+ private lateinit var testSession: InputManagerGlobal.TestSession
+ private lateinit var mockInputManager: InputManager
+
+ @Mock
+ private lateinit var mockVirtualDeviceManagerInternal: VirtualDeviceManagerInternal
+ @Mock
+ private lateinit var mockVirtualDevice: VirtualDeviceManager.VirtualDevice
+ @Mock
+ private lateinit var mockVirtualMouse: VirtualMouse
+
+ @Mock
+ private lateinit var mockTraceManager: AccessibilityTraceManager
+
+ @Before
+ @Throws(RemoteException::class)
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ val context = ApplicationProvider.getApplicationContext<Context>()
+ testSession = InputManagerGlobal.createTestSession(iInputManager)
+ mockInputManager = InputManager(context)
+
+ Mockito.`when`(mockVirtualDeviceManagerInternal.getDeviceIdsForUid(Mockito.anyInt()))
+ .thenReturn(ArraySet(setOf(DEVICE_ID)))
+ LocalServices.removeServiceForTest(VirtualDeviceManagerInternal::class.java)
+ LocalServices.addService<VirtualDeviceManagerInternal>(
+ VirtualDeviceManagerInternal::class.java, mockVirtualDeviceManagerInternal
+ )
+
+ Mockito.`when`(mockVirtualDeviceManagerInternal.createVirtualDevice(
+ Mockito.any(VirtualDeviceParams::class.java)
+ )).thenReturn(mockVirtualDevice)
+ Mockito.`when`(mockVirtualDevice.createVirtualMouse(
+ Mockito.any(VirtualMouseConfig::class.java)
+ )).thenReturn(mockVirtualMouse)
+
+ Mockito.`when`(iInputManager.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID))
+ Mockito.`when`(mockAms.traceManager).thenReturn(mockTraceManager)
+
+ mouseKeysInterceptor = MouseKeysInterceptor(mockAms, testLooper.looper, DISPLAY_ID)
+ // VirtualMouse is created on a separate thread.
+ // Wait for VirtualMouse to be created before running tests
+ TimeUnit.MILLISECONDS.sleep(20L)
+ mouseKeysInterceptor.next = nextInterceptor
+ }
+
+ @After
+ fun tearDown() {
+ testLooper.dispatchAll()
+ if (this::testSession.isInitialized) {
+ testSession.close()
+ }
+ }
+
+ @Test
+ fun whenNonMouseKeyEventArrives_eventIsPassedToNextInterceptor() {
+ val downTime = clock.now()
+ val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_Q, 0, 0, DEVICE_ID, 0)
+ mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+ testLooper.dispatchAll()
+
+ assertEquals(1, nextInterceptor.events.size)
+ assertEquals(downEvent, nextInterceptor.events.poll())
+ }
+
+ @Test
+ fun whenMouseDirectionalKeyIsPressed_relativeEventIsSent() {
+ // There should be some delay between the downTime of the key event and calling onKeyEvent
+ val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
+ val keyCode = MouseKeysInterceptor.MouseKeyEvent.DIAGONAL_DOWN_LEFT_MOVE.keyCodeValue
+ val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ keyCode, 0, 0, DEVICE_ID, 0)
+
+ mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+ testLooper.dispatchAll()
+
+ // Verify the sendRelativeEvent method is called once and capture the arguments
+ verifyRelativeEvents(arrayOf(-MOUSE_POINTER_MOVEMENT_STEP / sqrt(2.0f)),
+ arrayOf(MOUSE_POINTER_MOVEMENT_STEP / sqrt(2.0f)))
+ }
+
+ @Test
+ fun whenClickKeyIsPressed_buttonEventIsSent() {
+ // There should be some delay between the downTime of the key event and calling onKeyEvent
+ val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
+ val keyCode = MouseKeysInterceptor.MouseKeyEvent.LEFT_CLICK.keyCodeValue
+ val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ keyCode, 0, 0, DEVICE_ID, 0)
+ mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+ testLooper.dispatchAll()
+
+ val actions = arrayOf<Int>(
+ VirtualMouseButtonEvent.ACTION_BUTTON_PRESS,
+ VirtualMouseButtonEvent.ACTION_BUTTON_RELEASE)
+ val buttons = arrayOf<Int>(
+ VirtualMouseButtonEvent.BUTTON_PRIMARY,
+ VirtualMouseButtonEvent.BUTTON_PRIMARY)
+ // Verify the sendButtonEvent method is called twice and capture the arguments
+ verifyButtonEvents(actions, buttons)
+ }
+
+ @Test
+ fun whenHoldKeyIsPressed_buttonEventIsSent() {
+ val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
+ val keyCode = MouseKeysInterceptor.MouseKeyEvent.HOLD.keyCodeValue
+ val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ keyCode, 0, 0, DEVICE_ID, 0)
+ mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+ testLooper.dispatchAll()
+
+ // Verify the sendButtonEvent method is called once and capture the arguments
+ verifyButtonEvents(
+ arrayOf<Int>( VirtualMouseButtonEvent.ACTION_BUTTON_PRESS),
+ arrayOf<Int>( VirtualMouseButtonEvent.BUTTON_PRIMARY)
+ )
+ }
+
+ @Test
+ fun whenReleaseKeyIsPressed_buttonEventIsSent() {
+ val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
+ val keyCode = MouseKeysInterceptor.MouseKeyEvent.RELEASE.keyCodeValue
+ val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ keyCode, 0, 0, DEVICE_ID, 0)
+ mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+ testLooper.dispatchAll()
+
+ // Verify the sendButtonEvent method is called once and capture the arguments
+ verifyButtonEvents(
+ arrayOf<Int>( VirtualMouseButtonEvent.ACTION_BUTTON_RELEASE),
+ arrayOf<Int>( VirtualMouseButtonEvent.BUTTON_PRIMARY)
+ )
+ }
+
+ @Test
+ fun whenScrollToggleOn_ScrollUpKeyIsPressed_scrollEventIsSent() {
+ // There should be some delay between the downTime of the key event and calling onKeyEvent
+ val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
+ val keyCodeScrollToggle = MouseKeysInterceptor.MouseKeyEvent.SCROLL_TOGGLE.keyCodeValue
+ val keyCodeScroll = MouseKeysInterceptor.MouseKeyEvent.UP_MOVE_OR_SCROLL.keyCodeValue
+
+ val scrollToggleDownEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ keyCodeScrollToggle, 0, 0, DEVICE_ID, 0)
+ val scrollDownEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ keyCodeScroll, 0, 0, DEVICE_ID, 0)
+
+ mouseKeysInterceptor.onKeyEvent(scrollToggleDownEvent, 0)
+ mouseKeysInterceptor.onKeyEvent(scrollDownEvent, 0)
+ testLooper.dispatchAll()
+
+ // Verify the sendScrollEvent method is called once and capture the arguments
+ verifyScrollEvents(arrayOf<Float>(0f), arrayOf<Float>(1.0f))
+ }
+
+ @Test
+ fun whenScrollToggleOff_DirectionalUpKeyIsPressed_RelativeEventIsSent() {
+ // There should be some delay between the downTime of the key event and calling onKeyEvent
+ val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
+ val keyCode = MouseKeysInterceptor.MouseKeyEvent.UP_MOVE_OR_SCROLL.keyCodeValue
+ val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ keyCode, 0, 0, DEVICE_ID, 0)
+
+ mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+ testLooper.dispatchAll()
+
+ // Verify the sendRelativeEvent method is called once and capture the arguments
+ verifyRelativeEvents(arrayOf<Float>(0f), arrayOf<Float>(-MOUSE_POINTER_MOVEMENT_STEP))
+ }
+
+ private fun verifyRelativeEvents(expectedX: Array<Float>, expectedY: Array<Float>) {
+ assertEquals(expectedX.size, expectedY.size)
+ val captor = ArgumentCaptor.forClass(VirtualMouseRelativeEvent::class.java)
+ Mockito.verify(mockVirtualMouse, Mockito.times(expectedX.size))
+ .sendRelativeEvent(captor.capture())
+
+ for (i in expectedX.indices) {
+ val captorEvent = captor.allValues[i]
+ assertEquals(expectedX[i], captorEvent.relativeX)
+ assertEquals(expectedY[i], captorEvent.relativeY)
+ }
+ }
+
+ private fun verifyButtonEvents(actions: Array<Int>, buttons: Array<Int>) {
+ assertEquals(actions.size, buttons.size)
+ val captor = ArgumentCaptor.forClass(VirtualMouseButtonEvent::class.java)
+ Mockito.verify(mockVirtualMouse, Mockito.times(actions.size))
+ .sendButtonEvent(captor.capture())
+
+ for (i in actions.indices) {
+ val captorEvent = captor.allValues[i]
+ assertEquals(actions[i], captorEvent.action)
+ assertEquals(buttons[i], captorEvent.buttonCode)
+ }
+ }
+
+ private fun verifyScrollEvents(xAxisMovements: Array<Float>, yAxisMovements: Array<Float>) {
+ assertEquals(xAxisMovements.size, yAxisMovements.size)
+ val captor = ArgumentCaptor.forClass(VirtualMouseScrollEvent::class.java)
+ Mockito.verify(mockVirtualMouse, Mockito.times(xAxisMovements.size))
+ .sendScrollEvent(captor.capture())
+
+ for (i in xAxisMovements.indices) {
+ val captorEvent = captor.allValues[i]
+ assertEquals(xAxisMovements[i], captorEvent.xAxisMovement)
+ assertEquals(yAxisMovements[i], captorEvent.yAxisMovement)
+ }
+ }
+
+ private class TrackingInterceptor : BaseEventStreamTransformation() {
+ val events: Queue<KeyEvent> = LinkedList()
+
+ override fun onKeyEvent(event: KeyEvent, policyFlags: Int) {
+ events.add(event)
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/AccessibilityCheckerUtilsTest.java b/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/AccessibilityCheckerUtilsTest.java
new file mode 100644
index 000000000000..90d427596ab2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/AccessibilityCheckerUtilsTest.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 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.accessibility.a11ychecker;
+
+import static com.android.server.accessibility.a11ychecker.TestUtils.TEST_A11Y_SERVICE_CLASS_NAME;
+import static com.android.server.accessibility.a11ychecker.TestUtils.TEST_A11Y_SERVICE_SOURCE_PACKAGE_NAME;
+import static com.android.server.accessibility.a11ychecker.TestUtils.TEST_A11Y_SERVICE_SOURCE_VERSION_CODE;
+import static com.android.server.accessibility.a11ychecker.TestUtils.TEST_ACTIVITY_NAME;
+import static com.android.server.accessibility.a11ychecker.TestUtils.TEST_APP_PACKAGE_NAME;
+import static com.android.server.accessibility.a11ychecker.TestUtils.TEST_APP_VERSION_CODE;
+import static com.android.server.accessibility.a11ychecker.TestUtils.TEST_WINDOW_TITLE;
+import static com.android.server.accessibility.a11ychecker.TestUtils.getMockPackageManagerWithInstalledApps;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckPreset;
+import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult;
+import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheck;
+import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheckResult;
+import com.google.android.apps.common.testing.accessibility.framework.checks.ClassNameCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.ClickableSpanCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.SpeakableTextPresentCheck;
+import com.google.android.apps.common.testing.accessibility.framework.checks.TouchTargetSizeCheck;
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityCheckerUtilsTest {
+
+ PackageManager mMockPackageManager;
+
+ @Before
+ public void setUp() throws PackageManager.NameNotFoundException {
+ mMockPackageManager = getMockPackageManagerWithInstalledApps();
+ }
+
+ @Test
+ public void processResults_happyPath_setsAllFields() {
+ AccessibilityNodeInfo mockNodeInfo =
+ new MockAccessibilityNodeInfoBuilder()
+ .setViewIdResourceName("TargetNode")
+ .build();
+ AccessibilityHierarchyCheckResult result1 =
+ new AccessibilityHierarchyCheckResult(
+ SpeakableTextPresentCheck.class,
+ AccessibilityCheckResult.AccessibilityCheckResultType.WARNING, null, 1,
+ null);
+ AccessibilityHierarchyCheckResult result2 =
+ new AccessibilityHierarchyCheckResult(
+ TouchTargetSizeCheck.class,
+ AccessibilityCheckResult.AccessibilityCheckResultType.ERROR, null, 2, null);
+ AccessibilityHierarchyCheckResult result3 =
+ new AccessibilityHierarchyCheckResult(
+ ClassNameCheck.class,
+ AccessibilityCheckResult.AccessibilityCheckResultType.INFO, null, 5, null);
+ AccessibilityHierarchyCheckResult result4 =
+ new AccessibilityHierarchyCheckResult(
+ ClickableSpanCheck.class,
+ AccessibilityCheckResult.AccessibilityCheckResultType.NOT_RUN, null, 5,
+ null);
+
+ Set<A11yCheckerProto.AccessibilityCheckResultReported> atoms =
+ AccessibilityCheckerUtils.processResults(
+ mockNodeInfo,
+ List.of(result1, result2, result3, result4),
+ null,
+ mMockPackageManager,
+ new ComponentName(TEST_A11Y_SERVICE_SOURCE_PACKAGE_NAME,
+ TEST_A11Y_SERVICE_CLASS_NAME));
+
+ assertThat(atoms).containsExactly(
+ createAtom(A11yCheckerProto.AccessibilityCheckClass.SPEAKABLE_TEXT_PRESENT_CHECK,
+ A11yCheckerProto.AccessibilityCheckResultType.WARNING, 1),
+ createAtom(A11yCheckerProto.AccessibilityCheckClass.TOUCH_TARGET_SIZE_CHECK,
+ A11yCheckerProto.AccessibilityCheckResultType.ERROR, 2)
+ );
+ }
+
+ @Test
+ public void processResults_packageNameNotFound_returnsEmptySet()
+ throws PackageManager.NameNotFoundException {
+ when(mMockPackageManager.getPackageInfo("com.uninstalled.app", 0))
+ .thenThrow(PackageManager.NameNotFoundException.class);
+ AccessibilityNodeInfo mockNodeInfo =
+ new MockAccessibilityNodeInfoBuilder()
+ .setPackageName("com.uninstalled.app")
+ .setViewIdResourceName("TargetNode")
+ .build();
+ AccessibilityHierarchyCheckResult result1 =
+ new AccessibilityHierarchyCheckResult(
+ TouchTargetSizeCheck.class,
+ AccessibilityCheckResult.AccessibilityCheckResultType.WARNING, null, 1,
+ null);
+ AccessibilityHierarchyCheckResult result2 =
+ new AccessibilityHierarchyCheckResult(
+ TouchTargetSizeCheck.class,
+ AccessibilityCheckResult.AccessibilityCheckResultType.ERROR, null, 2, null);
+
+ Set<A11yCheckerProto.AccessibilityCheckResultReported> atoms =
+ AccessibilityCheckerUtils.processResults(
+ mockNodeInfo,
+ List.of(result1, result2),
+ null,
+ mMockPackageManager,
+ new ComponentName(TEST_A11Y_SERVICE_SOURCE_PACKAGE_NAME,
+ TEST_A11Y_SERVICE_CLASS_NAME));
+
+ assertThat(atoms).isEmpty();
+ }
+
+ @Test
+ public void getActivityName_hasWindowStateChangedEvent_returnsActivityName() {
+ AccessibilityEvent accessibilityEvent =
+ AccessibilityEvent.obtain(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ accessibilityEvent.setPackageName(TEST_APP_PACKAGE_NAME);
+ accessibilityEvent.setClassName(TEST_ACTIVITY_NAME);
+
+ assertThat(AccessibilityCheckerUtils.getActivityName(mMockPackageManager,
+ accessibilityEvent)).isEqualTo("MainActivity");
+ }
+
+ // Makes sure the AccessibilityHierarchyCheck class to enum mapping is up to date with the
+ // latest prod preset.
+ @Test
+ public void checkClassToEnumMap_hasAllLatestPreset() {
+ ImmutableSet<AccessibilityHierarchyCheck> checkPreset =
+ AccessibilityCheckPreset.getAccessibilityHierarchyChecksForPreset(
+ AccessibilityCheckPreset.LATEST);
+ Set<Class<? extends AccessibilityHierarchyCheck>> latestCheckClasses =
+ checkPreset.stream().map(AccessibilityHierarchyCheck::getClass).collect(
+ Collectors.toUnmodifiableSet());
+
+ assertThat(AccessibilityCheckerUtils.CHECK_CLASS_TO_ENUM_MAP.keySet())
+ .containsExactlyElementsIn(latestCheckClasses);
+ }
+
+
+ private static A11yCheckerProto.AccessibilityCheckResultReported createAtom(
+ A11yCheckerProto.AccessibilityCheckClass checkClass,
+ A11yCheckerProto.AccessibilityCheckResultType resultType,
+ int resultId) {
+ return A11yCheckerProto.AccessibilityCheckResultReported.newBuilder()
+ .setPackageName(TEST_APP_PACKAGE_NAME)
+ .setAppVersionCode(TEST_APP_VERSION_CODE)
+ .setUiElementPath(TEST_APP_PACKAGE_NAME + ":TargetNode")
+ .setWindowTitle(TEST_WINDOW_TITLE)
+ .setActivityName("")
+ .setSourceComponentName(new ComponentName(TEST_A11Y_SERVICE_SOURCE_PACKAGE_NAME,
+ TEST_A11Y_SERVICE_CLASS_NAME).flattenToString())
+ .setSourceVersionCode(TEST_A11Y_SERVICE_SOURCE_VERSION_CODE)
+ .setResultCheckClass(checkClass)
+ .setResultType(resultType)
+ .setResultId(resultId)
+ .build();
+ }
+
+}
diff --git a/core/tests/coretests/src/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilderTest.java b/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/AccessibilityNodePathBuilderTest.java
index 438277b272cb..a53f42ece21f 100644
--- a/core/tests/coretests/src/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilderTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/AccessibilityNodePathBuilderTest.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.view.accessibility.a11ychecker;
+package com.android.server.accessibility.a11ychecker;
-import static android.view.accessibility.a11ychecker.MockAccessibilityNodeInfoBuilder.PACKAGE_NAME;
+import static com.android.server.accessibility.a11ychecker.TestUtils.TEST_APP_PACKAGE_NAME;
import static com.google.common.truth.Truth.assertThat;
@@ -36,7 +36,7 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class AccessibilityNodePathBuilderTest {
- public static final String RESOURCE_ID_PREFIX = PACKAGE_NAME + ":id/";
+ public static final String RESOURCE_ID_PREFIX = TEST_APP_PACKAGE_NAME + ":id/";
@Test
public void createNodePath_pathWithResourceNames() {
@@ -55,11 +55,11 @@ public class AccessibilityNodePathBuilderTest {
.build();
assertThat(AccessibilityNodePathBuilder.createNodePath(child))
- .isEqualTo(PACKAGE_NAME + ":root_node/parent_node[1]/child_node[1]");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":root_node/parent_node[1]/child_node[1]");
assertThat(AccessibilityNodePathBuilder.createNodePath(parent))
- .isEqualTo(PACKAGE_NAME + ":root_node/parent_node[1]");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":root_node/parent_node[1]");
assertThat(AccessibilityNodePathBuilder.createNodePath(root))
- .isEqualTo(PACKAGE_NAME + ":root_node");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":root_node");
}
@Test
@@ -81,11 +81,11 @@ public class AccessibilityNodePathBuilderTest {
.build();
assertThat(AccessibilityNodePathBuilder.createNodePath(child))
- .isEqualTo(PACKAGE_NAME + ":FrameLayout/RecyclerView[1]/TextView[1]");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":FrameLayout/RecyclerView[1]/TextView[1]");
assertThat(AccessibilityNodePathBuilder.createNodePath(parent))
- .isEqualTo(PACKAGE_NAME + ":FrameLayout/RecyclerView[1]");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":FrameLayout/RecyclerView[1]");
assertThat(AccessibilityNodePathBuilder.createNodePath(root))
- .isEqualTo(PACKAGE_NAME + ":FrameLayout");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":FrameLayout");
}
@Test
@@ -105,11 +105,11 @@ public class AccessibilityNodePathBuilderTest {
.build();
assertThat(AccessibilityNodePathBuilder.createNodePath(child1))
- .isEqualTo(PACKAGE_NAME + ":FrameLayout/child1[1]");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":FrameLayout/child1[1]");
assertThat(AccessibilityNodePathBuilder.createNodePath(child2))
- .isEqualTo(PACKAGE_NAME + ":FrameLayout/TextView[2]");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":FrameLayout/TextView[2]");
assertThat(AccessibilityNodePathBuilder.createNodePath(parent))
- .isEqualTo(PACKAGE_NAME + ":FrameLayout");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":FrameLayout");
}
@Test
@@ -133,13 +133,13 @@ public class AccessibilityNodePathBuilderTest {
.build();
assertThat(AccessibilityNodePathBuilder.createNodePath(child1))
- .isEqualTo(PACKAGE_NAME + ":parentId/childId[1]");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":parentId/childId[1]");
assertThat(AccessibilityNodePathBuilder.createNodePath(child2))
- .isEqualTo(PACKAGE_NAME + ":parentId/child/Id/With/Slash[2]");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":parentId/child/Id/With/Slash[2]");
assertThat(AccessibilityNodePathBuilder.createNodePath(child3))
- .isEqualTo(PACKAGE_NAME + ":parentId/childIdWithoutPrefix[3]");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":parentId/childIdWithoutPrefix[3]");
assertThat(AccessibilityNodePathBuilder.createNodePath(parent))
- .isEqualTo(PACKAGE_NAME + ":parentId");
+ .isEqualTo(TEST_APP_PACKAGE_NAME + ":parentId");
}
}
diff --git a/core/tests/coretests/src/android/view/accessibility/a11ychecker/MockAccessibilityNodeInfoBuilder.java b/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/MockAccessibilityNodeInfoBuilder.java
index e363f0c81720..7cd3535e72ba 100644
--- a/core/tests/coretests/src/android/view/accessibility/a11ychecker/MockAccessibilityNodeInfoBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/MockAccessibilityNodeInfoBuilder.java
@@ -14,21 +14,33 @@
* limitations under the License.
*/
-package android.view.accessibility.a11ychecker;
+package com.android.server.accessibility.a11ychecker;
+
+import static com.android.server.accessibility.a11ychecker.TestUtils.TEST_APP_PACKAGE_NAME;
+import static com.android.server.accessibility.a11ychecker.TestUtils.TEST_WINDOW_TITLE;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
import java.util.List;
final class MockAccessibilityNodeInfoBuilder {
- static final String PACKAGE_NAME = "com.example.app";
private final AccessibilityNodeInfo mMockNodeInfo = mock(AccessibilityNodeInfo.class);
MockAccessibilityNodeInfoBuilder() {
- when(mMockNodeInfo.getPackageName()).thenReturn(PACKAGE_NAME);
+ setPackageName(TEST_APP_PACKAGE_NAME);
+
+ AccessibilityWindowInfo windowInfo = new AccessibilityWindowInfo();
+ windowInfo.setTitle(TEST_WINDOW_TITLE);
+ when(mMockNodeInfo.getWindow()).thenReturn(windowInfo);
+ }
+
+ MockAccessibilityNodeInfoBuilder setPackageName(String packageName) {
+ when(mMockNodeInfo.getPackageName()).thenReturn(packageName);
+ return this;
}
MockAccessibilityNodeInfoBuilder setClassName(String className) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/OWNERS b/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/OWNERS
new file mode 100644
index 000000000000..7bdc0297907c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/OWNERS
@@ -0,0 +1 @@
+include /services/accessibility/java/com/android/server/accessibility/a11ychecker/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/TestUtils.java b/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/TestUtils.java
new file mode 100644
index 000000000000..a04bbee05730
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/a11ychecker/TestUtils.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 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.accessibility.a11ychecker;
+
+import static org.mockito.Mockito.when;
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+
+import org.mockito.Mockito;
+
+public class TestUtils {
+ static final String TEST_APP_PACKAGE_NAME = "com.example.app";
+ static final int TEST_APP_VERSION_CODE = 12321;
+ static final String TEST_ACTIVITY_NAME = "com.example.app.MainActivity";
+ static final String TEST_A11Y_SERVICE_SOURCE_PACKAGE_NAME = "com.assistive.app";
+ static final String TEST_A11Y_SERVICE_CLASS_NAME = "MyA11yService";
+ static final int TEST_A11Y_SERVICE_SOURCE_VERSION_CODE = 333555;
+ static final String TEST_WINDOW_TITLE = "Example window";
+
+ static PackageManager getMockPackageManagerWithInstalledApps()
+ throws PackageManager.NameNotFoundException {
+ PackageManager mockPackageManager = Mockito.mock(PackageManager.class);
+ ActivityInfo testActivityInfo = getTestActivityInfo();
+ ComponentName testActivityComponentName = new ComponentName(TEST_APP_PACKAGE_NAME,
+ TEST_ACTIVITY_NAME);
+
+ when(mockPackageManager.getActivityInfo(testActivityComponentName, 0))
+ .thenReturn(testActivityInfo);
+ when(mockPackageManager.getPackageInfo(TEST_APP_PACKAGE_NAME, 0))
+ .thenReturn(createPackageInfo(TEST_APP_PACKAGE_NAME, TEST_APP_VERSION_CODE,
+ testActivityInfo));
+ when(mockPackageManager.getPackageInfo(TEST_A11Y_SERVICE_SOURCE_PACKAGE_NAME, 0))
+ .thenReturn(createPackageInfo(TEST_A11Y_SERVICE_SOURCE_PACKAGE_NAME,
+ TEST_A11Y_SERVICE_SOURCE_VERSION_CODE, null));
+ return mockPackageManager;
+ }
+
+ static ActivityInfo getTestActivityInfo() {
+ ActivityInfo activityInfo = new ActivityInfo();
+ activityInfo.packageName = TEST_APP_PACKAGE_NAME;
+ activityInfo.name = TEST_ACTIVITY_NAME;
+ return activityInfo;
+ }
+
+ static PackageInfo createPackageInfo(String packageName, int versionCode,
+ @Nullable ActivityInfo activityInfo) {
+ PackageInfo packageInfo = new PackageInfo();
+ packageInfo.packageName = packageName;
+ packageInfo.setLongVersionCode(versionCode);
+ if (activityInfo != null) {
+ packageInfo.activities = new ActivityInfo[]{activityInfo};
+ }
+ return packageInfo;
+
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java
index f6da41166403..ffc78110d496 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java
@@ -28,7 +28,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
import android.hardware.biometrics.BiometricConstants;
import android.os.Handler;
@@ -88,16 +87,14 @@ public class BiometricSchedulerOperationTest {
private Handler mHandler;
private BiometricSchedulerOperation mInterruptableOperation;
private BiometricSchedulerOperation mNonInterruptableOperation;
- private boolean mIsDebuggable;
@Before
public void setUp() {
mHandler = new Handler(TestableLooper.get(this).getLooper());
- mIsDebuggable = false;
mInterruptableOperation = new BiometricSchedulerOperation(mInterruptableClientMonitor,
- mClientCallback, () -> mIsDebuggable);
+ mClientCallback);
mNonInterruptableOperation = new BiometricSchedulerOperation(mNonInterruptableClientMonitor,
- mClientCallback, () -> mIsDebuggable);
+ mClientCallback);
when(mInterruptableClientMonitor.isInterruptable()).thenReturn(true);
when(mNonInterruptableClientMonitor.isInterruptable()).thenReturn(false);
@@ -143,32 +140,13 @@ public class BiometricSchedulerOperationTest {
}
@Test
- public void testSecondStartWithCookieCrashesWhenDebuggable() {
+ public void testSecondStartWithCookieFails() {
final int cookie = 5;
- mIsDebuggable = true;
when(mInterruptableClientMonitor.getCookie()).thenReturn(cookie);
when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
- final boolean started = mInterruptableOperation.startWithCookie(mOnStartCallback, cookie);
- assertThat(started).isTrue();
-
- assertThrows(IllegalStateException.class,
- () -> mInterruptableOperation.startWithCookie(mOnStartCallback, cookie));
- }
-
- @Test
- public void testSecondStartWithCookieFailsNicelyWhenNotDebuggable() {
- final int cookie = 5;
- mIsDebuggable = false;
- when(mInterruptableClientMonitor.getCookie()).thenReturn(cookie);
- when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
-
- final boolean started = mInterruptableOperation.startWithCookie(mOnStartCallback, cookie);
- assertThat(started).isTrue();
-
- final boolean startedAgain = mInterruptableOperation.startWithCookie(mOnStartCallback,
- cookie);
- assertThat(startedAgain).isFalse();
+ assertThat(mInterruptableOperation.startWithCookie(mOnStartCallback, cookie)).isTrue();
+ assertThat(mInterruptableOperation.startWithCookie(mOnStartCallback, cookie)).isFalse();
}
@Test
@@ -217,56 +195,23 @@ public class BiometricSchedulerOperationTest {
}
@Test
- public void secondStartCrashesWhenDebuggable() {
- mIsDebuggable = true;
+ public void secondStartFails() {
when(mInterruptableClientMonitor.getCookie()).thenReturn(0);
when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
- final boolean started = mInterruptableOperation.start(mOnStartCallback);
- assertThat(started).isTrue();
-
- assertThrows(IllegalStateException.class, () -> mInterruptableOperation.start(
- mOnStartCallback));
- }
-
- @Test
- public void secondStartFailsNicelyWhenNotDebuggable() {
- mIsDebuggable = false;
- when(mInterruptableClientMonitor.getCookie()).thenReturn(0);
- when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
-
- final boolean started = mInterruptableOperation.start(mOnStartCallback);
- assertThat(started).isTrue();
-
- final boolean startedAgain = mInterruptableOperation.start(mOnStartCallback);
- assertThat(startedAgain).isFalse();
+ assertThat(mInterruptableOperation.start(mOnStartCallback)).isTrue();
+ assertThat(mInterruptableOperation.start(mOnStartCallback)).isFalse();
}
@Test
public void doesNotStartWithCookie() {
- // This class only throws exceptions when debuggable.
- mIsDebuggable = true;
when(mInterruptableClientMonitor.getCookie()).thenReturn(9);
- assertThrows(IllegalStateException.class,
- () -> mInterruptableOperation.start(mock(ClientMonitorCallback.class)));
- }
- @Test
- public void cannotRestart() {
- // This class only throws exceptions when debuggable.
- mIsDebuggable = true;
- when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
-
- mInterruptableOperation.start(mOnStartCallback);
-
- assertThrows(IllegalStateException.class,
- () -> mInterruptableOperation.start(mock(ClientMonitorCallback.class)));
+ assertThat(mInterruptableOperation.start(mock(ClientMonitorCallback.class))).isFalse();
}
@Test
- public void abortsNotRunning() {
- // This class only throws exceptions when debuggable.
- mIsDebuggable = true;
+ public void abortSuccessfulIfOperationNotRunning() {
when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
mInterruptableOperation.abort();
@@ -274,28 +219,17 @@ public class BiometricSchedulerOperationTest {
assertThat(mInterruptableOperation.isFinished()).isTrue();
verify(mInterruptableClientMonitor).unableToStart();
verify(mInterruptableClientMonitor).destroy();
- assertThrows(IllegalStateException.class,
- () -> mInterruptableOperation.start(mock(ClientMonitorCallback.class)));
+ assertThat(mInterruptableOperation.start(mock(ClientMonitorCallback.class))).isFalse();
}
@Test
- public void abortCrashesWhenDebuggableIfOperationIsRunning() {
- mIsDebuggable = true;
+ public void abortFailsIfOperationIsRunning() {
when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
mInterruptableOperation.start(mOnStartCallback);
-
- assertThrows(IllegalStateException.class, () -> mInterruptableOperation.abort());
- }
-
- @Test
- public void abortFailsNicelyWhenNotDebuggableIfOperationIsRunning() {
- mIsDebuggable = false;
- when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
-
- mInterruptableOperation.start(mOnStartCallback);
-
mInterruptableOperation.abort();
+
+ assertThat(mInterruptableOperation.isFinished()).isFalse();
}
@Test
@@ -344,21 +278,7 @@ public class BiometricSchedulerOperationTest {
}
@Test
- public void cancelCrashesWhenDebuggableIfOperationIsFinished() {
- mIsDebuggable = true;
- when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
-
- mInterruptableOperation.abort();
- assertThat(mInterruptableOperation.isFinished()).isTrue();
-
- final ClientMonitorCallback cancelCb = mock(ClientMonitorCallback.class);
- assertThrows(IllegalStateException.class, () -> mInterruptableOperation.cancel(mHandler,
- cancelCb));
- }
-
- @Test
- public void cancelFailsNicelyWhenNotDebuggableIfOperationIsFinished() {
- mIsDebuggable = false;
+ public void cancelFailsIfOperationIsFinished() {
when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
mInterruptableOperation.abort();
@@ -366,6 +286,9 @@ public class BiometricSchedulerOperationTest {
final ClientMonitorCallback cancelCb = mock(ClientMonitorCallback.class);
mInterruptableOperation.cancel(mHandler, cancelCb);
+
+ verify(mInterruptableClientMonitor, never()).cancel();
+ verify(mInterruptableClientMonitor, never()).cancelWithoutStarting(any());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
index ecd799f44552..6ec888cd2e45 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
@@ -406,8 +406,6 @@ public class FingerprintAuthenticationClientTest {
mContextInjector.getValue().accept(opContext);
verify(mHal).onContextChanged(same(opContext));
- verify(mHal, times(2)).setIgnoreDisplayTouches(
- opContext.operationState.getFingerprintOperationState().isHardwareIgnoringTouches);
client.stopHalOperation();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 21364b861ed8..87b52e6194ce 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -2068,7 +2068,6 @@ public class HdmiCecLocalDeviceTvTest {
assertThat(mPowerManager.isInteractive()).isTrue();
}
-
@Test
public void handleStandby_fromNonActiveSource_previousActiveSourceNotSet_Standby() {
HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
@@ -2091,6 +2090,35 @@ public class HdmiCecLocalDeviceTvTest {
.isFalse();
}
+ @Test
+ public void handleReportPhysicalAddress_DeviceDiscoveryActionInProgress_noNewDeviceAction() {
+ mHdmiControlService.getHdmiCecNetwork().clearDeviceList();
+ mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mNativeWrapper.clearResultMessages();
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage reportPhysicalAddressFromPlayback1 =
+ HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
+ ADDR_PLAYBACK_1, 0x1000, HdmiDeviceInfo.DEVICE_PLAYBACK);
+ HdmiCecMessage reportPhysicalAddressFromPlayback2 =
+ HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
+ ADDR_PLAYBACK_2, 0x2000, HdmiDeviceInfo.DEVICE_PLAYBACK);
+ HdmiCecMessage giveOsdName = HdmiCecMessageBuilder.buildGiveOsdNameCommand(
+ ADDR_TV, ADDR_PLAYBACK_2);
+ // Skip state waiting for <Report Physical Address> for DeviceDiscoveryAction s.t. message
+ // can be dispatched to local device TV.
+ mNativeWrapper.onCecMessage(reportPhysicalAddressFromPlayback1);
+ mNativeWrapper.clearResultMessages();
+ mTestLooper.dispatchAll();
+
+ mNativeWrapper.onCecMessage(reportPhysicalAddressFromPlayback2);
+ mTestLooper.dispatchAll();
+
+ // NewDeviceAction did not start and <Give OSD Name> was not sent.
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveOsdName);
+ }
+
protected static class MockTvDevice extends HdmiCecLocalDeviceTv {
MockTvDevice(HdmiControlService service) {
super(service);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java
index 10f4308cbcfb..599a3b86e1af 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java
@@ -396,7 +396,7 @@ public class HdmiCecNetworkTest {
}
@Test
- public void cecDevices_tracking_updatesPhysicalAddress() {
+ public void cecDevices_tracking_updatesPhysicalAddress_add() {
int logicalAddress = Constants.ADDR_PLAYBACK_1;
int initialPhysicalAddress = 0x1000;
int updatedPhysicalAddress = 0x2000;
@@ -415,11 +415,12 @@ public class HdmiCecNetworkTest {
assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo(updatedPhysicalAddress);
assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(type);
- // ADD for physical address first detected
- // UPDATE for updating device with new physical address
+ // Handle case where PA is changed: Update CEC device information by calling
+ // addCecDevice().
assertThat(mDeviceEventListenerStatuses).containsExactly(
HdmiControlManager.DEVICE_EVENT_ADD_DEVICE,
- HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE);
+ HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE,
+ HdmiControlManager.DEVICE_EVENT_ADD_DEVICE);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEventLoggerTest.java b/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEventLoggerTest.java
index 8863d2796acf..41cb6fd99d9b 100644
--- a/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEventLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEventLoggerTest.java
@@ -18,11 +18,15 @@ package com.android.server.location.contexthub;
import static com.google.common.truth.Truth.assertThat;
+import android.chre.flags.Flags;
import android.hardware.location.NanoAppMessage;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -33,6 +37,8 @@ import java.util.Arrays;
public class ContextHubEventLoggerTest {
private static final ContextHubEventLogger sInstance = ContextHubEventLogger.getInstance();
+ @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Test
public void testLogNanoappLoad() {
ContextHubEventLogger.NanoappLoadEvent[] events =
@@ -46,10 +52,10 @@ public class ContextHubEventLoggerTest {
sInstance.clear();
sInstance.logNanoappLoad(-1, 42, -34, 100, false);
sInstance.logNanoappLoad(0, 123, 321, 001, true);
- String sInstanceDump = sInstance.toString();
+ String instanceDump = sInstance.toString();
for (String eventString: eventStrings) {
assertThat(eventString.length() > 0).isTrue();
- assertThat(sInstanceDump.contains(eventString)).isTrue();
+ assertThat(instanceDump.contains(eventString)).isTrue();
}
}
@@ -66,10 +72,10 @@ public class ContextHubEventLoggerTest {
sInstance.clear();
sInstance.logNanoappUnload(-1, 47, false);
sInstance.logNanoappUnload(1, 0xFFFFFFFF, true);
- String sInstanceDump = sInstance.toString();
+ String instanceDump = sInstance.toString();
for (String eventString: eventStrings) {
assertThat(eventString.length() > 0).isTrue();
- assertThat(sInstanceDump.contains(eventString)).isTrue();
+ assertThat(instanceDump.contains(eventString)).isTrue();
}
}
@@ -90,10 +96,10 @@ public class ContextHubEventLoggerTest {
sInstance.clear();
sInstance.logMessageFromNanoapp(-123, message1, false);
sInstance.logMessageFromNanoapp(321, message2, true);
- String sInstanceDump = sInstance.toString();
+ String instanceDump = sInstance.toString();
for (String eventString: eventStrings) {
assertThat(eventString.length() > 0).isTrue();
- assertThat(sInstanceDump.contains(eventString)).isTrue();
+ assertThat(instanceDump.contains(eventString)).isTrue();
}
}
@@ -114,10 +120,54 @@ public class ContextHubEventLoggerTest {
sInstance.clear();
sInstance.logMessageToNanoapp(888, message1, true);
sInstance.logMessageToNanoapp(999, message2, false);
- String sInstanceDump = sInstance.toString();
+ String instanceDump = sInstance.toString();
+ for (String eventString: eventStrings) {
+ assertThat(eventString.length() > 0).isTrue();
+ assertThat(instanceDump.contains(eventString)).isTrue();
+ }
+ }
+
+ @Test
+ @EnableFlags({Flags.FLAG_RELIABLE_MESSAGE,
+ Flags.FLAG_RELIABLE_MESSAGE_IMPLEMENTATION})
+ public void testLogReliableMessageToNanoappStatus() {
+ NanoAppMessage message1 = NanoAppMessage.createMessageToNanoApp(1, 0,
+ new byte[] {0x00, 0x11, 0x22, 0x33});
+ NanoAppMessage message2 = NanoAppMessage.createMessageToNanoApp(0, 1,
+ new byte[] {(byte) 0xDE, (byte) 0xAD, (byte) 0xBE, (byte) 0xEF});
+ message1.setIsReliable(true);
+ message2.setIsReliable(true);
+ message1.setMessageSequenceNumber(0);
+ message2.setMessageSequenceNumber(1);
+
+ ContextHubEventLogger.NanoappMessageEvent[] events =
+ new ContextHubEventLogger.NanoappMessageEvent[] {
+ new ContextHubEventLogger.NanoappMessageEvent(23, 888, message1, true),
+ new ContextHubEventLogger.NanoappMessageEvent(34, 999, message2, false)
+ };
+ String[] eventStrings = generateEventDumpStrings(events);
+
+ // log events and test sInstance.toString() contains event details
+ sInstance.clear();
+ sInstance.logMessageToNanoapp(888, message1, true);
+ sInstance.logMessageToNanoapp(999, message2, false);
+ String instanceDump = sInstance.toString();
+ for (String eventString: eventStrings) {
+ assertThat(eventString.length() > 0).isTrue();
+ assertThat(instanceDump.contains(eventString)).isTrue();
+ }
+
+ // set the error codes for the events and verify
+ sInstance.logReliableMessageToNanoappStatus(0, (byte) 0x02);
+ sInstance.logReliableMessageToNanoappStatus(1, (byte) 0x03);
+ events[0].setErrorCode((byte) 0x02);
+ events[1].setErrorCode((byte) 0x03);
+ eventStrings = generateEventDumpStrings(events);
+
+ instanceDump = sInstance.toString();
for (String eventString: eventStrings) {
assertThat(eventString.length() > 0).isTrue();
- assertThat(sInstanceDump.contains(eventString)).isTrue();
+ assertThat(instanceDump.contains(eventString)).isTrue();
}
}
@@ -134,10 +184,10 @@ public class ContextHubEventLoggerTest {
sInstance.clear();
sInstance.logContextHubRestart(1);
sInstance.logContextHubRestart(2);
- String sInstanceDump = sInstance.toString();
+ String instanceDump = sInstance.toString();
for (String eventString: eventStrings) {
assertThat(eventString.length() > 0).isTrue();
- assertThat(sInstanceDump.contains(eventString)).isTrue();
+ assertThat(instanceDump.contains(eventString)).isTrue();
}
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockscreenRepairModeTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockscreenRepairModeTest.java
index 70150c507460..4396c679ec24 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockscreenRepairModeTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockscreenRepairModeTest.java
@@ -19,6 +19,8 @@ package com.android.server.locksettings;
import static com.android.internal.widget.LockPatternUtils.USER_REPAIR_MODE;
import static com.android.internal.widget.LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
@@ -199,6 +201,27 @@ public class LockscreenRepairModeTest extends BaseLockSettingsServiceTests {
.getResponseCode());
}
+ @Test
+ public void writeRepairModeCredential_noLock() {
+ assertThat(mService.writeRepairModeCredential(PRIMARY_USER_ID)).isFalse();
+ }
+
+ @Test
+ public void writeRepairModeCredential_hasLock() {
+ mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
+ assertThat(mService.writeRepairModeCredential(PRIMARY_USER_ID)).isTrue();
+ }
+
+ @Test
+ public void writeRepairModeCredential_verifyRepairModeUser() {
+ mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
+ mService.writeRepairModeCredential(PRIMARY_USER_ID);
+ setRepairModeActive(true);
+
+ var response = mService.verifyCredential(newPin("1234"), USER_REPAIR_MODE, 0);
+ assertThat(response.isMatched()).isTrue();
+ }
+
private void setRepairModeActive(boolean active) {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.REPAIR_MODE_ACTIVE, active ? 1 : 0);
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index e64397d4223b..316b5faf2a68 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -17,6 +17,7 @@
package com.android.server.media.projection;
+import static android.Manifest.permission.RECORD_SENSITIVE_CONTENT;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
import static android.media.projection.MediaProjectionManager.TYPE_MIRRORING;
@@ -50,6 +51,7 @@ import static org.testng.Assert.assertThrows;
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions.LaunchCookie;
+import android.app.KeyguardManager;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
@@ -66,7 +68,9 @@ import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.test.TestLooper;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.view.ContentRecordingSession;
import android.view.ContentRecordingSession.RecordContent;
@@ -81,6 +85,7 @@ import com.android.server.wm.WindowManagerInternal;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -151,6 +156,9 @@ public class MediaProjectionManagerServiceTest {
private ContentRecordingSession mWaitingDisplaySession =
createDisplaySession(DEFAULT_DISPLAY);
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Mock
private ActivityManagerInternal mAmInternal;
@Mock
@@ -158,6 +166,8 @@ public class MediaProjectionManagerServiceTest {
@Mock
private PackageManager mPackageManager;
@Mock
+ private KeyguardManager mKeyguardManager;
+ @Mock
private IMediaProjectionWatcherCallback mWatcherCallback;
@Mock
private MediaProjectionMetricsLogger mMediaProjectionMetricsLogger;
@@ -177,6 +187,7 @@ public class MediaProjectionManagerServiceTest {
mContext = spy(new ContextWrapper(
InstrumentationRegistry.getInstrumentation().getTargetContext()));
doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(mKeyguardManager).when(mContext).getSystemService(eq(Context.KEYGUARD_SERVICE));
mClock = new OffsettableClock.Stopped();
mWaitingDisplaySession.setWaitingForConsent(true);
@@ -246,6 +257,39 @@ public class MediaProjectionManagerServiceTest {
assertThat(stoppedCallback2).isFalse();
}
+ @EnableFlags(android.companion.virtualdevice.flags
+ .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS)
+ @Test
+ public void testCreateProjection_keyguardLocked() throws Exception {
+ MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+
+ doReturn(true).when(mKeyguardManager).isKeyguardLocked();
+ doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager)
+ .checkPermission(RECORD_SENSITIVE_CONTENT, projection.packageName);
+ projection.start(mIMediaProjectionCallback);
+ projection.notifyVirtualDisplayCreated(10);
+
+ assertThat(mService.getActiveProjectionInfo()).isNull();
+ assertThat(mIMediaProjectionCallback.mLatch.await(5, TimeUnit.SECONDS)).isTrue();
+ }
+
+ @EnableFlags(android.companion.virtualdevice.flags
+ .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS)
+ @Test
+ public void testCreateProjection_keyguardLocked_packageAllowlisted()
+ throws NameNotFoundException {
+ MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+
+ doReturn(true).when(mKeyguardManager).isKeyguardLocked();
+ doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager)
+ .checkPermission(RECORD_SENSITIVE_CONTENT, projection.packageName);
+ projection.start(mIMediaProjectionCallback);
+ projection.notifyVirtualDisplayCreated(10);
+
+ // The projection was started because it was allowed to capture the keyguard.
+ assertThat(mService.getActiveProjectionInfo()).isNotNull();
+ }
+
@Test
public void testCreateProjection_attemptReuse_noPriorProjectionGrant()
throws NameNotFoundException {
@@ -317,6 +361,48 @@ public class MediaProjectionManagerServiceTest {
assertThat(secondProjection).isNotEqualTo(projection);
}
+ @EnableFlags(android.companion.virtualdevice.flags
+ .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS)
+ @Test
+ public void testKeyguardLocked_stopsActiveProjection() throws Exception {
+ MediaProjectionManagerService service =
+ new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
+ MediaProjectionManagerService.MediaProjection projection =
+ startProjectionPreconditions(service);
+ projection.start(mIMediaProjectionCallback);
+
+ assertThat(service.getActiveProjectionInfo()).isNotNull();
+
+ doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager)
+ .checkPermission(RECORD_SENSITIVE_CONTENT, projection.packageName);
+ service.onKeyguardLockedStateChanged(true);
+
+ verify(mMediaProjectionMetricsLogger).logStopped(UID, TARGET_UID_UNKNOWN);
+ assertThat(service.getActiveProjectionInfo()).isNull();
+ assertThat(mIMediaProjectionCallback.mLatch.await(5, TimeUnit.SECONDS)).isTrue();
+ }
+
+ @EnableFlags(android.companion.virtualdevice.flags
+ .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS)
+ @Test
+ public void testKeyguardLocked_packageAllowlisted_doesNotStopActiveProjection()
+ throws NameNotFoundException {
+ MediaProjectionManagerService service =
+ new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
+ MediaProjectionManagerService.MediaProjection projection =
+ startProjectionPreconditions(service);
+ projection.start(mIMediaProjectionCallback);
+
+ assertThat(service.getActiveProjectionInfo()).isNotNull();
+
+ doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission(
+ RECORD_SENSITIVE_CONTENT, projection.packageName);
+ service.onKeyguardLockedStateChanged(true);
+
+ verifyZeroInteractions(mMediaProjectionMetricsLogger);
+ assertThat(service.getActiveProjectionInfo()).isNotNull();
+ }
+
@Test
public void stop_noActiveProjections_doesNotLog() throws Exception {
MediaProjectionManagerService service =
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 02d3b59fbf87..d714db99f18f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -1060,6 +1060,23 @@ public final class UserManagerTest {
assertThrows(SecurityException.class, userProps::getAlwaysVisible);
}
+ /**
+ * Test that UserManager.getUserProperties throws the IllegalArgumentException for unsupported
+ * arguments such as UserHandle.NULL, UserHandle.CURRENT or UserHandle.ALL.
+ **/
+ @MediumTest
+ @Test
+ public void testThrowUserPropertiesForUnsupportedUserHandles() throws Exception {
+ assertThrows(IllegalArgumentException.class, () ->
+ mUserManager.getUserProperties(UserHandle.of(UserHandle.USER_NULL)));
+ assertThrows(IllegalArgumentException.class, () ->
+ mUserManager.getUserProperties(UserHandle.CURRENT));
+ assertThrows(IllegalArgumentException.class, () ->
+ mUserManager.getUserProperties(UserHandle.CURRENT_OR_SELF));
+ assertThrows(IllegalArgumentException.class, () ->
+ mUserManager.getUserProperties(UserHandle.ALL));
+ }
+
// Make sure only max managed profiles can be created
@MediumTest
@Test
@@ -1845,6 +1862,25 @@ public final class UserManagerTest {
assertThat(profilesExcludingHidden).asList().doesNotContain(profile.id);
}
+ /**
+ * Test that UserManager.isQuietModeEnabled return false for unsupported
+ * arguments such as UserHandle.NULL, UserHandle.CURRENT or UserHandle.ALL.
+ **/
+ @MediumTest
+ @Test
+ public void testQuietModeEnabledForUnsupportedUserHandles() throws Exception {
+ assumeManagedUsersSupported();
+ final int mainUserId = mUserManager.getMainUser().getIdentifier();
+ UserInfo userInfo = createProfileForUser("Profile",
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
+ mUserManager.requestQuietModeEnabled(true, userInfo.getUserHandle());
+ assertThat(mUserManager.isQuietModeEnabled(userInfo.getUserHandle())).isTrue();
+ assertThat(mUserManager.isQuietModeEnabled(UserHandle.of(UserHandle.USER_NULL))).isFalse();
+ assertThat(mUserManager.isQuietModeEnabled(UserHandle.CURRENT)).isFalse();
+ assertThat(mUserManager.isQuietModeEnabled(UserHandle.CURRENT_OR_SELF)).isFalse();
+ assertThat(mUserManager.isQuietModeEnabled(UserHandle.ALL)).isFalse();
+ }
+
private String generateLongString() {
String partialString = "Test Name Test Name Test Name Test Name Test Name Test Name Test "
+ "Name Test Name Test Name Test Name "; //String of length 100
diff --git a/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java b/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java
index 698f094c8796..6b32be0b2dfd 100644
--- a/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java
@@ -16,9 +16,14 @@
package com.android.server.power;
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DIM;
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_OFF;
import static android.os.PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON;
import static android.os.PowerManager.GO_TO_SLEEP_REASON_TIMEOUT;
import static android.os.PowerManager.WAKE_REASON_POWER_BUTTON;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.DEFAULT_DISPLAY_GROUP;
import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN;
import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_TOUCH;
@@ -27,6 +32,10 @@ import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCO
import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION;
import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_TIMEOUT_SUCCESS;
import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT;
+import static com.android.server.power.WakefulnessSessionObserver.POLICY_REASON_BRIGHT_INITIATED_REVERT;
+import static com.android.server.power.WakefulnessSessionObserver.POLICY_REASON_BRIGHT_UNDIM;
+import static com.android.server.power.WakefulnessSessionObserver.POLICY_REASON_OFF_POWER_BUTTON;
+import static com.android.server.power.WakefulnessSessionObserver.POLICY_REASON_OFF_TIMEOUT;
import static com.google.common.truth.Truth.assertThat;
@@ -40,18 +49,24 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Resources;
+import android.hardware.display.DisplayManagerInternal;
+import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.UserHandle;
import android.provider.Settings;
import android.test.mock.MockContentResolver;
+import android.view.DisplayAddress;
+import android.view.DisplayInfo;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.R;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.testutils.OffsettableClock;
+import com.android.server.testutils.TestHandler;
import org.junit.After;
import org.junit.Before;
@@ -65,25 +80,18 @@ import org.mockito.MockitoAnnotations;
public class WakefulnessSessionObserverTest {
private static final int DEFAULT_SCREEN_OFF_TIMEOUT_MS = 30000;
private static final int OVERRIDE_SCREEN_OFF_TIMEOUT_MS = 15000;
+ private static final int DISPLAY_PORT = 0xFF;
+ private static final long DISPLAY_MODEL = 0xEEEEEEEEL;
private WakefulnessSessionObserver mWakefulnessSessionObserver;
private Context mContext;
private OffsettableClock mTestClock;
@Mock
private WakefulnessSessionObserver.WakefulnessSessionFrameworkStatsLogger
mWakefulnessSessionFrameworkStatsLogger;
- private WakefulnessSessionObserver.Injector mInjector =
- new WakefulnessSessionObserver.Injector() {
- @Override
- WakefulnessSessionObserver.WakefulnessSessionFrameworkStatsLogger
- getWakefulnessSessionFrameworkStatsLogger() {
- return mWakefulnessSessionFrameworkStatsLogger;
- }
- @Override
- WakefulnessSessionObserver.Clock getClock() {
- return mTestClock::now;
- }
- };
+ @Mock
+ private DisplayManagerInternal mDisplayManagerInternal;
+ private TestHandler mHandler;
@Before
public void setUp() {
mTestClock = new OffsettableClock.Stopped();
@@ -95,7 +103,7 @@ public class WakefulnessSessionObserverTest {
final Resources res = spy(mContext.getResources());
doReturn(OVERRIDE_SCREEN_OFF_TIMEOUT_MS).when(res).getInteger(
- com.android.internal.R.integer.config_screenTimeoutOverride);
+ R.integer.config_screenTimeoutOverride);
when(mContext.getResources()).thenReturn(res);
FakeSettingsProvider.clearSettingsProvider();
MockContentResolver mockContentResolver = new MockContentResolver();
@@ -104,7 +112,32 @@ public class WakefulnessSessionObserverTest {
Settings.System.putIntForUser(mockContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
DEFAULT_SCREEN_OFF_TIMEOUT_MS, UserHandle.USER_CURRENT);
- mWakefulnessSessionObserver = new WakefulnessSessionObserver(mContext, mInjector);
+ final DisplayInfo info = new DisplayInfo();
+ info.address = DisplayAddress.fromPortAndModel(DISPLAY_PORT, DISPLAY_MODEL);
+ mHandler = new TestHandler(null);
+ mWakefulnessSessionObserver = new WakefulnessSessionObserver(
+ mContext, new WakefulnessSessionObserver.Injector() {
+ @Override
+ WakefulnessSessionObserver.WakefulnessSessionFrameworkStatsLogger
+ getWakefulnessSessionFrameworkStatsLogger() {
+ return mWakefulnessSessionFrameworkStatsLogger;
+ }
+ @Override
+ WakefulnessSessionObserver.Clock getClock() {
+ return mTestClock::now;
+ }
+ @Override
+ Handler getHandler() {
+ return mHandler;
+ }
+ @Override
+ DisplayManagerInternal getDisplayManagerInternal() {
+ when(mDisplayManagerInternal.getDisplayInfo(DEFAULT_DISPLAY))
+ .thenReturn(info);
+ return mDisplayManagerInternal;
+ }
+ }
+ );
}
@After
@@ -317,6 +350,167 @@ public class WakefulnessSessionObserverTest {
DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default timeout ms
}
+ @Test
+ public void testOnScreenPolicyUpdate_OffByTimeout() {
+ int userActivity = PowerManager.USER_ACTIVITY_EVENT_ATTENTION;
+ long userActivityTimestamp = mTestClock.now();
+ mWakefulnessSessionObserver.notifyUserActivity(
+ userActivityTimestamp, DEFAULT_DISPLAY_GROUP, userActivity);
+ mWakefulnessSessionObserver.onScreenPolicyUpdate(
+ mTestClock.now(), DEFAULT_DISPLAY_GROUP, POLICY_DIM);
+ mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+ DEFAULT_DISPLAY_GROUP, PowerManagerInternal.WAKEFULNESS_AWAKE,
+ WAKE_REASON_POWER_BUTTON, mTestClock.now());
+ int advancedTime = 5;
+ advanceTime(advancedTime);
+ mWakefulnessSessionObserver.onScreenPolicyUpdate(mTestClock.now(), DEFAULT_DISPLAY_GROUP,
+ POLICY_OFF);
+ mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+ DEFAULT_DISPLAY_GROUP, PowerManagerInternal.WAKEFULNESS_ASLEEP,
+ GO_TO_SLEEP_REASON_TIMEOUT, mTestClock.now());
+
+ verify(mWakefulnessSessionFrameworkStatsLogger)
+ .logDimEvent(
+ DISPLAY_PORT, // physical display port id
+ POLICY_REASON_OFF_TIMEOUT, // policy reason
+ userActivity, // last user activity event
+ advancedTime, // last user activity timestamp
+ advancedTime, // dim duration ms
+ DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default Timeout Ms
+ }
+
+ @Test
+ public void testOnScreenPolicyUpdate_NoLogging_NotDefaultDisplayGroup() {
+ int powerGroupId = 1;
+ int userActivity = PowerManager.USER_ACTIVITY_EVENT_ATTENTION;
+ long userActivityTimestamp = mTestClock.now();
+ int advancedTime = 5;
+ mWakefulnessSessionObserver.notifyUserActivity(
+ userActivityTimestamp, powerGroupId, userActivity);
+ mWakefulnessSessionObserver.onScreenPolicyUpdate(
+ mTestClock.now(), powerGroupId, POLICY_DIM);
+ advanceTime(advancedTime);
+ mWakefulnessSessionObserver.onScreenPolicyUpdate(mTestClock.now(), powerGroupId,
+ POLICY_OFF);
+
+ verify(mWakefulnessSessionFrameworkStatsLogger, never())
+ .logDimEvent(
+ DISPLAY_PORT, // physical display port id
+ POLICY_REASON_OFF_TIMEOUT, // policy reason
+ userActivity, // last user activity event
+ advancedTime, // last user activity timestamp
+ advancedTime, // dim duration ms
+ DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default Timeout Ms
+ }
+
+ @Test
+ public void testOnScreenPolicyUpdate_OffByPowerButton() {
+ // ----- initialize start -----
+ mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+ DEFAULT_DISPLAY_GROUP, PowerManagerInternal.WAKEFULNESS_AWAKE,
+ WAKE_REASON_POWER_BUTTON, mTestClock.now());
+
+ int userActivity = PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY;
+ long userActivityTimestamp = mTestClock.now();
+ mWakefulnessSessionObserver.notifyUserActivity(
+ userActivityTimestamp, DEFAULT_DISPLAY_GROUP, userActivity);
+ mWakefulnessSessionObserver.onScreenPolicyUpdate(
+ mTestClock.now(), DEFAULT_DISPLAY_GROUP, POLICY_DIM);
+ // ----- initialize end -----
+
+ int dimDuration = 500;
+ advanceTime(dimDuration);
+ int userActivityDuration = dimDuration;
+ mWakefulnessSessionObserver.notifyUserActivity(
+ mTestClock.now(), DEFAULT_DISPLAY_GROUP, PowerManager.USER_ACTIVITY_EVENT_BUTTON);
+ mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+ DEFAULT_DISPLAY_GROUP, PowerManagerInternal.WAKEFULNESS_ASLEEP,
+ GO_TO_SLEEP_REASON_POWER_BUTTON, mTestClock.now());
+
+ verify(mWakefulnessSessionFrameworkStatsLogger)
+ .logDimEvent(
+ DISPLAY_PORT, // physical display port id
+ POLICY_REASON_OFF_POWER_BUTTON, // policy reason
+ userActivity, // last user activity event
+ userActivityDuration, // last user activity timestamp
+ dimDuration, // dim duration ms
+ DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default Timeout Ms
+ assertThat(mHandler.getPendingMessages()).isEmpty();
+ }
+
+ @Test
+ public void testOnScreenPolicyUpdate_Undim() {
+ // ----- initialize start -----
+ int userActivity = PowerManager.USER_ACTIVITY_EVENT_TOUCH;
+ long userActivityTimestamp = mTestClock.now();
+ mWakefulnessSessionObserver.notifyUserActivity(
+ userActivityTimestamp, DEFAULT_DISPLAY_GROUP, userActivity);
+ mWakefulnessSessionObserver.onScreenPolicyUpdate(
+ mTestClock.now(), DEFAULT_DISPLAY_GROUP, POLICY_DIM);
+ mWakefulnessSessionObserver.mPowerGroups.get(DEFAULT_DISPLAY_GROUP).mIsInteractive = true;
+ // ----- initialize end -----
+
+ int dimDurationMs = 5;
+ advanceTime(dimDurationMs);
+ mWakefulnessSessionObserver.onScreenPolicyUpdate(
+ mTestClock.now(), DEFAULT_DISPLAY_GROUP, POLICY_BRIGHT);
+
+ int expectedLastUserActivityTimeMs = (int) (mTestClock.now() - userActivityTimestamp);
+
+ mHandler.flush();
+ verify(mWakefulnessSessionFrameworkStatsLogger)
+ .logDimEvent(
+ DISPLAY_PORT, // physical display port id
+ POLICY_REASON_BRIGHT_UNDIM, // policy reason
+ userActivity, // last user activity event
+ expectedLastUserActivityTimeMs, // last user activity timestamp
+ dimDurationMs, // dim duration ms
+ DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default Timeout Ms
+ }
+
+ @Test
+ public void testOnScreenPolicyUpdate_BrightInitiatedRevert() {
+ // ----- initialize start -----
+ mWakefulnessSessionObserver.onScreenPolicyUpdate(
+ mTestClock.now(), DEFAULT_DISPLAY_GROUP, POLICY_DIM);
+ int dimDurationMs = 500;
+ advanceTime(dimDurationMs);
+ int userActivity = PowerManager.USER_ACTIVITY_EVENT_BUTTON;
+ long userActivityTimestamp = mTestClock.now();
+ mWakefulnessSessionObserver.notifyUserActivity(
+ userActivityTimestamp, DEFAULT_DISPLAY_GROUP, userActivity);
+ int userActivityTime = 5;
+ advanceTime(userActivityTime);
+ dimDurationMs += userActivityTime;
+ mWakefulnessSessionObserver.onScreenPolicyUpdate(
+ mTestClock.now(), DEFAULT_DISPLAY_GROUP, POLICY_OFF);
+ mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+ DEFAULT_DISPLAY_GROUP, PowerManagerInternal.WAKEFULNESS_ASLEEP,
+ GO_TO_SLEEP_REASON_POWER_BUTTON, mTestClock.now());
+
+ mWakefulnessSessionObserver.mPowerGroups.get(DEFAULT_DISPLAY_GROUP)
+ .mPastDimDurationMs = dimDurationMs;
+ // ----- initialize end -----
+
+ int advancedTime = 5;
+ advanceTime(advancedTime); // shorter than 5000 ms
+ userActivityTime += advancedTime;
+ mWakefulnessSessionObserver.onScreenPolicyUpdate(mTestClock.now(), DEFAULT_DISPLAY_GROUP,
+ POLICY_BRIGHT);
+ mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+ DEFAULT_DISPLAY_GROUP, PowerManagerInternal.WAKEFULNESS_AWAKE,
+ WAKE_REASON_POWER_BUTTON, mTestClock.now());
+
+ verify(mWakefulnessSessionFrameworkStatsLogger)
+ .logDimEvent(
+ DISPLAY_PORT, // physical display port id
+ POLICY_REASON_BRIGHT_INITIATED_REVERT, // policy reason
+ userActivity, // last user activity event
+ userActivityTime, // last user activity timestamp
+ dimDurationMs, // dim duration ms
+ DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default Timeout Ms
+ }
+
private void advanceTime(long timeMs) {
mTestClock.fastForward(timeMs);
}
diff --git a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java
index bf478162c46e..1decd36be394 100644
--- a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java
@@ -151,7 +151,6 @@ public class HintManagerServiceTest {
private HintManagerService mService;
private ChannelConfig mConfig;
- private ApplicationInfo mApplicationInfo;
private static Answer<Long> fakeCreateWithConfig(Long ptr, Long sessionId) {
return new Answer<Long>() {
@@ -168,12 +167,12 @@ public class HintManagerServiceTest {
mConfig = new ChannelConfig();
mConfig.readFlagBitmask = 1;
mConfig.writeFlagBitmask = 2;
- mApplicationInfo = new ApplicationInfo();
- mApplicationInfo.category = ApplicationInfo.CATEGORY_GAME;
+ ApplicationInfo applicationInfo = new ApplicationInfo();
+ applicationInfo.category = ApplicationInfo.CATEGORY_GAME;
when(mContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getNameForUid(anyInt())).thenReturn(TEST_APP_NAME);
when(mMockPackageManager.getApplicationInfo(eq(TEST_APP_NAME), anyInt()))
- .thenReturn(mApplicationInfo);
+ .thenReturn(applicationInfo);
when(mNativeWrapperMock.halGetHintSessionPreferredRate())
.thenReturn(DEFAULT_HINT_PREFERRED_RATE);
when(mNativeWrapperMock.halCreateHintSession(eq(TGID), eq(UID), eq(SESSION_TIDS_A),
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 8a7d276dbecd..225c1dc752c1 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -20,13 +20,23 @@ import static android.app.Notification.FLAG_AUTO_CANCEL;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_CAN_COLORIZE;
import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
+import static android.app.Notification.FLAG_GROUP_SUMMARY;
import static android.app.Notification.FLAG_NO_CLEAR;
import static android.app.Notification.FLAG_ONGOING_EVENT;
+import static android.app.Notification.GROUP_ALERT_ALL;
+import static android.app.Notification.GROUP_ALERT_CHILDREN;
+import static android.app.Notification.GROUP_ALERT_SUMMARY;
import static android.app.Notification.VISIBILITY_PRIVATE;
import static android.app.Notification.VISIBILITY_PUBLIC;
import static android.app.Notification.VISIBILITY_SECRET;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
+import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
+import static com.android.server.notification.GroupHelper.AGGREGATE_GROUP_KEY;
+import static com.android.server.notification.GroupHelper.AUTOGROUP_KEY;
import static com.android.server.notification.GroupHelper.BASE_FLAGS;
import static com.google.common.truth.Truth.assertThat;
@@ -41,6 +51,7 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -49,6 +60,7 @@ import static org.mockito.Mockito.when;
import android.annotation.SuppressLint;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.AdaptiveIconDrawable;
@@ -66,6 +78,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.server.UiServiceTestCase;
+import com.android.server.notification.GroupHelper.CachedSummary;
import com.android.server.notification.GroupHelper.NotificationAttributes;
import org.junit.Before;
@@ -90,11 +103,15 @@ public class GroupHelperTest extends UiServiceTestCase {
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
private final int DEFAULT_VISIBILITY = VISIBILITY_PRIVATE;
+ private final int DEFAULT_GROUP_ALERT = GROUP_ALERT_CHILDREN;
+
+ private final String TEST_CHANNEL_ID = "TEST_CHANNEL_ID";
private @Mock GroupHelper.Callback mCallback;
private @Mock PackageManager mPackageManager;
private final static int AUTOGROUP_AT_COUNT = 7;
+ private final static int AUTOGROUP_SINGLETONS_AT_COUNT = 2;
private GroupHelper mGroupHelper;
private @Mock Icon mSmallIcon;
@@ -113,7 +130,7 @@ public class GroupHelperTest extends UiServiceTestCase {
MockitoAnnotations.initMocks(this);
mGroupHelper = new GroupHelper(getContext(), mPackageManager, AUTOGROUP_AT_COUNT,
- mCallback);
+ AUTOGROUP_SINGLETONS_AT_COUNT, mCallback);
NotificationRecord r = mock(NotificationRecord.class);
StatusBarNotification sbn = getSbn("package", 0, "0", UserHandle.SYSTEM);
@@ -124,7 +141,7 @@ public class GroupHelperTest extends UiServiceTestCase {
private StatusBarNotification getSbn(String pkg, int id, String tag,
UserHandle user, String groupKey, Icon smallIcon, int iconColor) {
- Notification.Builder nb = new Notification.Builder(getContext(), "test_channel_id")
+ Notification.Builder nb = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
.setContentTitle("A")
.setWhen(1205)
.setSmallIcon(smallIcon)
@@ -146,15 +163,54 @@ public class GroupHelperTest extends UiServiceTestCase {
return getSbn(pkg, id, tag, user, null);
}
+ private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+ UserHandle user) {
+ return getNotificationRecord(pkg, id, tag, user, null, false);
+ }
+
+ private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+ UserHandle user, String groupKey, boolean isSummary) {
+ return getNotificationRecord(pkg, id, tag, user, groupKey, isSummary, IMPORTANCE_DEFAULT);
+ }
+
+ private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+ UserHandle user, String groupKey, boolean isSummary, int importance) {
+ return getNotificationRecord(pkg, id, tag, user, groupKey, isSummary,
+ new NotificationChannel(TEST_CHANNEL_ID, TEST_CHANNEL_ID, importance));
+ }
+
+ private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+ UserHandle user, String groupKey, boolean isSummary, NotificationChannel channel) {
+ StatusBarNotification sbn = getSbn(pkg, id, tag, user, groupKey);
+ if (isSummary) {
+ sbn.getNotification().flags |= FLAG_GROUP_SUMMARY;
+ }
+ return new NotificationRecord(getContext(), sbn, channel);
+ }
+
+ private NotificationRecord getNotificationRecord(StatusBarNotification sbn) {
+ return new NotificationRecord(getContext(), sbn,
+ new NotificationChannel(TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT));
+ }
+
private NotificationAttributes getNotificationAttributes(int flags) {
- return new NotificationAttributes(flags, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY);
+ return new NotificationAttributes(flags, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY,
+ DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+ }
+
+ private String getExpectedAutogroupKey(final NotificationRecord record) {
+ if (android.service.notification.Flags.notificationForceGrouping()) {
+ return GroupHelper.getFullAggregateGroupKey(record);
+ } else {
+ return AUTOGROUP_KEY;
+ }
}
@Test
public void testGetAutogroupSummaryFlags_noChildren() {
ArrayMap<String, NotificationAttributes> children = new ArrayMap<>();
- assertEquals(BASE_FLAGS, mGroupHelper.getAutogroupSummaryFlags(children));
+ assertEquals(BASE_FLAGS, GroupHelper.getAutogroupSummaryFlags(children));
}
@Test
@@ -165,7 +221,7 @@ public class GroupHelperTest extends UiServiceTestCase {
children.put("c", getNotificationAttributes(FLAG_BUBBLE));
assertEquals(FLAG_ONGOING_EVENT | BASE_FLAGS,
- mGroupHelper.getAutogroupSummaryFlags(children));
+ GroupHelper.getAutogroupSummaryFlags(children));
}
@Test
@@ -176,7 +232,7 @@ public class GroupHelperTest extends UiServiceTestCase {
children.put("c", getNotificationAttributes(FLAG_BUBBLE));
assertEquals(FLAG_NO_CLEAR | FLAG_ONGOING_EVENT | BASE_FLAGS,
- mGroupHelper.getAutogroupSummaryFlags(children));
+ GroupHelper.getAutogroupSummaryFlags(children));
}
@Test
@@ -187,7 +243,7 @@ public class GroupHelperTest extends UiServiceTestCase {
children.put("c", getNotificationAttributes(FLAG_BUBBLE));
assertEquals(FLAG_ONGOING_EVENT | BASE_FLAGS,
- mGroupHelper.getAutogroupSummaryFlags(children));
+ GroupHelper.getAutogroupSummaryFlags(children));
}
@Test
@@ -199,7 +255,7 @@ public class GroupHelperTest extends UiServiceTestCase {
children.put("d", getNotificationAttributes(FLAG_ONGOING_EVENT));
assertEquals(FLAG_ONGOING_EVENT | BASE_FLAGS,
- mGroupHelper.getAutogroupSummaryFlags(children));
+ GroupHelper.getAutogroupSummaryFlags(children));
}
@Test
@@ -210,7 +266,7 @@ public class GroupHelperTest extends UiServiceTestCase {
children.put("c", getNotificationAttributes(FLAG_BUBBLE));
assertEquals(BASE_FLAGS,
- mGroupHelper.getAutogroupSummaryFlags(children));
+ GroupHelper.getAutogroupSummaryFlags(children));
}
@Test
@@ -222,7 +278,7 @@ public class GroupHelperTest extends UiServiceTestCase {
children.put("d", getNotificationAttributes(FLAG_AUTO_CANCEL | FLAG_FOREGROUND_SERVICE));
assertEquals(FLAG_AUTO_CANCEL | BASE_FLAGS,
- mGroupHelper.getAutogroupSummaryFlags(children));
+ GroupHelper.getAutogroupSummaryFlags(children));
}
@Test
@@ -235,15 +291,16 @@ public class GroupHelperTest extends UiServiceTestCase {
FLAG_AUTO_CANCEL | FLAG_FOREGROUND_SERVICE | FLAG_ONGOING_EVENT));
assertEquals(FLAG_AUTO_CANCEL| FLAG_ONGOING_EVENT | BASE_FLAGS,
- mGroupHelper.getAutogroupSummaryFlags(children));
+ GroupHelper.getAutogroupSummaryFlags(children));
}
@Test
public void testNoGroup_postingUnderLimit() {
final String pkg = "package";
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
- mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
- false);
+ mGroupHelper.onNotificationPosted(
+ getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+ false);
}
verifyZeroInteractions(mCallback);
}
@@ -253,11 +310,12 @@ public class GroupHelperTest extends UiServiceTestCase {
final String pkg = "package";
final String pkg2 = "package2";
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
- mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
- false);
+ mGroupHelper.onNotificationPosted(
+ getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+ false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
+ getNotificationRecord(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
verifyZeroInteractions(mCallback);
}
@@ -265,11 +323,12 @@ public class GroupHelperTest extends UiServiceTestCase {
public void testNoGroup_multiUser() {
final String pkg = "package";
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
- mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
- false);
+ mGroupHelper.onNotificationPosted(
+ getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+ false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.of(7)), false);
+ getNotificationRecord(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.of(7)), false);
verifyZeroInteractions(mCallback);
}
@@ -278,10 +337,11 @@ public class GroupHelperTest extends UiServiceTestCase {
final String pkg = "package";
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationPosted(
- getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
+ getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"), false);
+ getNotificationRecord(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a", false),
+ false);
verifyZeroInteractions(mCallback);
}
@@ -289,185 +349,241 @@ public class GroupHelperTest extends UiServiceTestCase {
@DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAddSummary_alwaysAutogroup() {
final String pkg = "package";
+ final String autogroupKey = getExpectedAutogroupKey(
+ getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
mGroupHelper.onNotificationPosted(
- getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
+ getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
}
verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+ anyInt(), eq(pkg), anyString(), eq(autogroupKey),
+ anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(autogroupKey),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAddSummary() {
final String pkg = "package";
+ final String autogroupKey = getExpectedAutogroupKey(
+ getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
assertThat(mGroupHelper.onNotificationPosted(
- getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false)).isFalse();
+ getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+ false)).isFalse();
}
assertThat(mGroupHelper.onNotificationPosted(
- getSbn(pkg, AUTOGROUP_AT_COUNT - 1, String.valueOf(AUTOGROUP_AT_COUNT - 1),
+ getNotificationRecord(pkg, AUTOGROUP_AT_COUNT - 1, String.valueOf(AUTOGROUP_AT_COUNT - 1),
UserHandle.SYSTEM), false)).isTrue();
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(autogroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAddSummary_oneChildOngoing_summaryOngoing_alwaysAutogroup() {
final String pkg = "package";
+ final String autogroupKey = getExpectedAutogroupKey(
+ getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
if (i == 0) {
- sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+ r.getNotification().flags |= FLAG_ONGOING_EVENT;
}
- mGroupHelper.onNotificationPosted(sbn, false);
+ mGroupHelper.onNotificationPosted(r, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(autogroupKey), anyInt(),
eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAddSummary_oneChildOngoing_summaryOngoing() {
final String pkg = "package";
+ final String autogroupKey = getExpectedAutogroupKey(
+ getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
if (i == 0) {
- sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+ r.getNotification().flags |= FLAG_ONGOING_EVENT;
}
- mGroupHelper.onNotificationPosted(sbn, false);
+ mGroupHelper.onNotificationPosted(r, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(autogroupKey), anyInt(),
eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAddSummary_oneChildAutoCancel_summaryNotAutoCancel_alwaysAutogroup() {
final String pkg = "package";
+ final String autogroupKey = getExpectedAutogroupKey(
+ getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
if (i == 0) {
- sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
}
- mGroupHelper.onNotificationPosted(sbn, false);
+ mGroupHelper.onNotificationPosted(r, false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(autogroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAddSummary_oneChildAutoCancel_summaryNotAutoCancel() {
final String pkg = "package";
+ final String autogroupKey = getExpectedAutogroupKey(
+ getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
if (i == 0) {
- sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
}
- mGroupHelper.onNotificationPosted(sbn, false);
+ mGroupHelper.onNotificationPosted(r, false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(autogroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(),
+ eq(autogroupKey), anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAddSummary_allChildrenAutoCancel_summaryAutoCancel_alwaysAutogroup() {
final String pkg = "package";
+ final String autogroupKey = getExpectedAutogroupKey(
+ getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
- mGroupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
+ mGroupHelper.onNotificationPosted(r, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(autogroupKey), anyInt(),
eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(autogroupKey),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAddSummary_allChildrenAutoCancel_summaryAutoCancel() {
final String pkg = "package";
+ final String autogroupKey = getExpectedAutogroupKey(
+ getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
- mGroupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
+ mGroupHelper.onNotificationPosted(r, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(autogroupKey), anyInt(),
eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(),
+ eq(autogroupKey), anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAddSummary_summaryAutoCancelNoClear_alwaysAutogroup() {
final String pkg = "package";
+ final String autogroupKey = getExpectedAutogroupKey(
+ getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
if (i == 0) {
- sbn.getNotification().flags |= FLAG_NO_CLEAR;
+ r.getNotification().flags |= FLAG_NO_CLEAR;
}
- mGroupHelper.onNotificationPosted(sbn, false);
+ mGroupHelper.onNotificationPosted(r, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(autogroupKey), anyInt(),
eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL | FLAG_NO_CLEAR)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(autogroupKey),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAddSummary_summaryAutoCancelNoClear() {
final String pkg = "package";
+ final String autogroupKey = getExpectedAutogroupKey(
+ getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
if (i == 0) {
- sbn.getNotification().flags |= FLAG_NO_CLEAR;
+ r.getNotification().flags |= FLAG_NO_CLEAR;
}
- mGroupHelper.onNotificationPosted(sbn, false);
+ mGroupHelper.onNotificationPosted(r, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(autogroupKey), anyInt(),
eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL | FLAG_NO_CLEAR)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(),
+ eq(autogroupKey), anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@@ -475,15 +591,16 @@ public class GroupHelperTest extends UiServiceTestCase {
final String pkg = "package";
// Post AUTOGROUP_AT_COUNT ongoing notifications
- ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
- notifications.add(sbn);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ r.getNotification().flags |= FLAG_ONGOING_EVENT;
+ notifications.add(r);
}
- for (StatusBarNotification sbn: notifications) {
- mGroupHelper.onNotificationPosted(sbn, false);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
}
// One notification is no longer ongoing
@@ -491,7 +608,7 @@ public class GroupHelperTest extends UiServiceTestCase {
mGroupHelper.onNotificationPosted(notifications.get(0), true);
// Summary should keep FLAG_ONGOING_EVENT if any child has it
- verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+ verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
}
@@ -500,24 +617,25 @@ public class GroupHelperTest extends UiServiceTestCase {
final String pkg = "package";
// Post AUTOGROUP_AT_COUNT ongoing notifications
- ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
if (i == 0) {
- sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+ r.getNotification().flags |= FLAG_ONGOING_EVENT;
}
- notifications.add(sbn);
+ notifications.add(r);
}
- for (StatusBarNotification sbn: notifications) {
- mGroupHelper.onNotificationPosted(sbn, false);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
}
// remove ongoing
mGroupHelper.onNotificationRemoved(notifications.get(0));
// Summary is no longer ongoing
- verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+ verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
eq(getNotificationAttributes(BASE_FLAGS)));
}
@@ -526,14 +644,15 @@ public class GroupHelperTest extends UiServiceTestCase {
final String pkg = "package";
// Post AUTOGROUP_AT_COUNT ongoing notifications
- ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- notifications.add(sbn);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ notifications.add(r);
}
- for (StatusBarNotification sbn: notifications) {
- mGroupHelper.onNotificationPosted(sbn, false);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
}
// update to ongoing
@@ -541,7 +660,7 @@ public class GroupHelperTest extends UiServiceTestCase {
mGroupHelper.onNotificationPosted(notifications.get(0), true);
// Summary is now ongoing
- verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+ verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
}
@@ -550,23 +669,25 @@ public class GroupHelperTest extends UiServiceTestCase {
final String pkg = "package";
// Post AUTOGROUP_AT_COUNT ongoing notifications
- ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- notifications.add(sbn);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ notifications.add(r);
}
- for (StatusBarNotification sbn: notifications) {
- mGroupHelper.onNotificationPosted(sbn, false);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
}
// add ongoing
- StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT + 1, null, UserHandle.SYSTEM);
- sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
- mGroupHelper.onNotificationPosted(sbn, true);
+ NotificationRecord r = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT + 1, null,
+ UserHandle.SYSTEM);
+ r.getNotification().flags |= FLAG_ONGOING_EVENT;
+ mGroupHelper.onNotificationPosted(r, true);
// Summary is now ongoing
- verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+ verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
}
@@ -575,51 +696,84 @@ public class GroupHelperTest extends UiServiceTestCase {
final String pkg = "package";
// Post AUTOGROUP_AT_COUNT ongoing notifications
- ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
if (i == 0) {
- sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+ r.getNotification().flags |= FLAG_ONGOING_EVENT;
}
- notifications.add(sbn);
+ notifications.add(r);
}
- for (StatusBarNotification sbn: notifications) {
- mGroupHelper.onNotificationPosted(sbn, false);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
}
// app group the ongoing child
- StatusBarNotification sbn = getSbn(pkg, 0, "0", UserHandle.SYSTEM, "app group now");
- mGroupHelper.onNotificationPosted(sbn, true);
+ NotificationRecord r = getNotificationRecord(pkg, 0, "0", UserHandle.SYSTEM,
+ "app group now", false);
+ mGroupHelper.onNotificationPosted(r, true);
// Summary is no longer ongoing
- verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+ verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
eq(getNotificationAttributes(BASE_FLAGS)));
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testAutoGrouped_singleOngoing_removeNonOngoingChild() {
final String pkg = "package";
// Post AUTOGROUP_AT_COUNT ongoing notifications
- ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
if (i == 0) {
- sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+ r.getNotification().flags |= FLAG_ONGOING_EVENT;
}
- notifications.add(sbn);
+ notifications.add(r);
}
- for (StatusBarNotification sbn: notifications) {
- mGroupHelper.onNotificationPosted(sbn, false);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
}
// remove ongoing
mGroupHelper.onNotificationRemoved(notifications.get(1));
// Summary is still ongoing
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testAutoGrouped_singleOngoing_removeNonOngoingChild_forceGrouping() {
+ final String pkg = "package";
+
+ // Post AUTOGROUP_AT_COUNT ongoing notifications
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ if (i == 0) {
+ r.getNotification().flags |= FLAG_ONGOING_EVENT;
+ }
+ notifications.add(r);
+ }
+
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
+ }
+
+ // remove ongoing
+ mGroupHelper.onNotificationRemoved(notifications.get(1));
+
+ // Summary is still ongoing
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@@ -627,15 +781,16 @@ public class GroupHelperTest extends UiServiceTestCase {
final String pkg = "package";
// Post AUTOGROUP_AT_COUNT ongoing notifications
- ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
- notifications.add(sbn);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
+ notifications.add(r);
}
- for (StatusBarNotification sbn: notifications) {
- mGroupHelper.onNotificationPosted(sbn, false);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
}
// One notification is no longer autocancelable
@@ -643,7 +798,7 @@ public class GroupHelperTest extends UiServiceTestCase {
mGroupHelper.onNotificationPosted(notifications.get(0), true);
// Summary should no longer be autocancelable
- verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+ verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
eq(getNotificationAttributes(BASE_FLAGS)));
}
@@ -652,17 +807,18 @@ public class GroupHelperTest extends UiServiceTestCase {
final String pkg = "package";
// Post AUTOGROUP_AT_COUNT ongoing notifications
- ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
if (i != 0) {
- sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
}
- notifications.add(sbn);
+ notifications.add(r);
}
- for (StatusBarNotification sbn: notifications) {
- mGroupHelper.onNotificationPosted(sbn, false);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
}
// Missing notification is now autocancelable
@@ -670,254 +826,327 @@ public class GroupHelperTest extends UiServiceTestCase {
mGroupHelper.onNotificationPosted(notifications.get(0), true);
// Summary should now autocancelable
- verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+ verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL)));
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testAutoGrouped_allAutoCancel_updateChildAppGrouped() {
final String pkg = "package";
// Post AUTOGROUP_AT_COUNT ongoing notifications
- ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
+ notifications.add(r);
+ }
+
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
+ }
+
+ // One notification is now grouped by app
+ NotificationRecord r = getNotificationRecord(pkg, 0, "0", UserHandle.SYSTEM,
+ "app group now", false);
+ mGroupHelper.onNotificationPosted(r, true);
+
+ // Summary should be still be autocancelable
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testAutoGrouped_allAutoCancel_updateChildAppGrouped_forceGrouping() {
+ final String pkg = "package";
+
+ // Post AUTOGROUP_AT_COUNT ongoing notifications
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
- notifications.add(sbn);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
+ notifications.add(r);
}
- for (StatusBarNotification sbn: notifications) {
- mGroupHelper.onNotificationPosted(sbn, false);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
}
// One notification is now grouped by app
- StatusBarNotification sbn = getSbn(pkg, 0, "0", UserHandle.SYSTEM, "app group now");
- mGroupHelper.onNotificationPosted(sbn, true);
+ NotificationRecord r = getNotificationRecord(pkg, 0, "0", UserHandle.SYSTEM,
+ "app group now", false);
+ mGroupHelper.onNotificationPosted(r, true);
// Summary should be still be autocancelable
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testAutoGrouped_allAutoCancel_removeChild() {
final String pkg = "package";
// Post AUTOGROUP_AT_COUNT ongoing notifications
- ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
- notifications.add(sbn);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
+ notifications.add(r);
}
- for (StatusBarNotification sbn: notifications) {
- mGroupHelper.onNotificationPosted(sbn, false);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
}
mGroupHelper.onNotificationRemoved(notifications.get(0));
// Summary should still be autocancelable
- verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testAutoGrouped_allAutoCancel_removeChild_forceGrouping() {
+ final String pkg = "package";
+
+ // Post AUTOGROUP_AT_COUNT ongoing notifications
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ r.getNotification().flags |= FLAG_AUTO_CANCEL;
+ notifications.add(r);
+ }
+
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
+ }
+
+ mGroupHelper.onNotificationRemoved(notifications.get(0));
+
+ // Summary should still be autocancelable
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
}
@Test
@DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testDropToZeroRemoveGroup_disableFlag() {
final String pkg = "package";
- List<StatusBarNotification> posted = new ArrayList<>();
+ ArrayList<NotificationRecord> posted = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- posted.add(sbn);
- mGroupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ posted.add(r);
+ mGroupHelper.onNotificationPosted(r, false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), anyString(),
+ anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationRemoved(posted.remove(0));
}
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
mGroupHelper.onNotificationRemoved(posted.remove(0));
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
}
@Test
@EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testDropToZeroRemoveGroup() {
final String pkg = "package";
- List<StatusBarNotification> posted = new ArrayList<>();
+ ArrayList<NotificationRecord> posted = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- posted.add(sbn);
- mGroupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ posted.add(r);
+ mGroupHelper.onNotificationPosted(r, false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), anyString(),
+ anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationRemoved(posted.remove(0));
}
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
mGroupHelper.onNotificationRemoved(posted.remove(0));
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
}
@Test
@DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAppStartsGrouping_disableFlag() {
final String pkg = "package";
- List<StatusBarNotification> posted = new ArrayList<>();
+ ArrayList<NotificationRecord> posted = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- posted.add(sbn);
- mGroupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ posted.add(r);
+ mGroupHelper.onNotificationPosted(r, false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- final StatusBarNotification sbn =
- getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
- sbn.setOverrideGroupKey("autogrouped");
- mGroupHelper.onNotificationPosted(sbn, true);
- verify(mCallback, times(1)).removeAutoGroup(sbn.getKey());
+ final NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "app group", false);
+ r.getSbn().setOverrideGroupKey("autogrouped");
+ mGroupHelper.onNotificationPosted(r, true);
+ verify(mCallback, times(1)).removeAutoGroup(r.getKey());
if (i < AUTOGROUP_AT_COUNT - 1) {
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(),
+ anyString());
}
}
- verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
}
@Test
@EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testAppStartsGrouping() {
final String pkg = "package";
- List<StatusBarNotification> posted = new ArrayList<>();
+ ArrayList<NotificationRecord> posted = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- posted.add(sbn);
- mGroupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ posted.add(r);
+ mGroupHelper.onNotificationPosted(r, false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- final StatusBarNotification sbn =
- getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
- sbn.setOverrideGroupKey("autogrouped");
- mGroupHelper.onNotificationPosted(sbn, true);
- verify(mCallback, times(1)).removeAutoGroup(sbn.getKey());
+ final NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "app group", false);
+ r.getSbn().setOverrideGroupKey("autogrouped");
+ mGroupHelper.onNotificationPosted(r, true);
+ verify(mCallback, times(1)).removeAutoGroup(r.getKey());
if (i < AUTOGROUP_AT_COUNT - 1) {
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(),
+ anyString());
}
}
- verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
}
@Test
@DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled_alwaysGroup() {
final String pkg = "package";
- List<StatusBarNotification> posted = new ArrayList<>();
+ ArrayList<NotificationRecord> posted = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- posted.add(sbn);
- mGroupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ posted.add(r);
+ mGroupHelper.onNotificationPosted(r, false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
for (int i = posted.size() - 2; i >= 0; i--) {
mGroupHelper.onNotificationRemoved(posted.remove(i));
}
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
- // only one child remains
- assertEquals(1, mGroupHelper.getNotGroupedByAppCount(UserHandle.USER_SYSTEM, pkg));
-
// Add new notification; it should be autogrouped even though the total count is
// < AUTOGROUP_AT_COUNT
- final StatusBarNotification sbn = getSbn(pkg, 5, String.valueOf(5), UserHandle.SYSTEM);
- posted.add(sbn);
- assertThat(mGroupHelper.onNotificationPosted(sbn, true)).isFalse();
- verify(mCallback, times(1)).addAutoGroup(sbn.getKey(), true);
+ final NotificationRecord r = getNotificationRecord(pkg, 5, String.valueOf(5),
+ UserHandle.SYSTEM);
+ final String autogroupKey = getExpectedAutogroupKey(r);
+ posted.add(r);
+ assertThat(mGroupHelper.onNotificationPosted(r, true)).isFalse();
+ verify(mCallback, times(1)).addAutoGroup(r.getKey(), autogroupKey, true);
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(), any());
+ verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+ anyString(), anyInt(), any());
}
@Test
@EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled() {
final String pkg = "package";
- List<StatusBarNotification> posted = new ArrayList<>();
+ ArrayList<NotificationRecord> posted = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
- posted.add(sbn);
- mGroupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM);
+ posted.add(r);
+ mGroupHelper.onNotificationPosted(r, false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
for (int i = posted.size() - 2; i >= 0; i--) {
mGroupHelper.onNotificationRemoved(posted.remove(i));
}
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
- // only one child remains
- assertEquals(1, mGroupHelper.getNotGroupedByAppCount(UserHandle.USER_SYSTEM, pkg));
-
// Add new notification; it should be autogrouped even though the total count is
// < AUTOGROUP_AT_COUNT
- final StatusBarNotification sbn = getSbn(pkg, 5, String.valueOf(5), UserHandle.SYSTEM);
- posted.add(sbn);
- assertThat(mGroupHelper.onNotificationPosted(sbn, true)).isTrue();
+ final NotificationRecord r = getNotificationRecord(pkg, 5, String.valueOf(5),
+ UserHandle.SYSTEM);
+ posted.add(r);
+ assertThat(mGroupHelper.onNotificationPosted(r, true)).isTrue();
// addAutoGroup not called on sbn, because the autogrouping is expected to be done
// synchronously.
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
eq(getNotificationAttributes(BASE_FLAGS)));
- verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(), any());
+ verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+ anyString(), anyInt(), any());
}
@Test
@@ -929,29 +1158,32 @@ public class GroupHelperTest extends UiServiceTestCase {
when(icon.sameAs(icon)).thenReturn(true);
final int iconColor = Color.BLUE;
final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
- DEFAULT_VISIBILITY);
+ DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
// Add notifications with same icon and color
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
- icon, iconColor);
- mGroupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(
+ getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null, icon, iconColor));
+ mGroupHelper.onNotificationPosted(r, false);
}
// Check that the summary would have the same icon and color
verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(attr));
- verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+ anyInt(), eq(pkg), anyString(), anyString(), anyInt(), eq(attr));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
// After auto-grouping, add new notification with the same color
- StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
- String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
- mGroupHelper.onNotificationPosted(sbn, true);
+ NotificationRecord r = getNotificationRecord(
+ getSbn(pkg, AUTOGROUP_AT_COUNT, String.valueOf(AUTOGROUP_AT_COUNT),
+ UserHandle.SYSTEM,null, icon, iconColor));
+ mGroupHelper.onNotificationPosted(r, true);
// Check that the summary was updated
//NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor);
- verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(attr));
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ eq(attr));
}
@Test
@@ -963,29 +1195,31 @@ public class GroupHelperTest extends UiServiceTestCase {
when(icon.sameAs(icon)).thenReturn(true);
final int iconColor = Color.BLUE;
final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
- DEFAULT_VISIBILITY);
+ DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
// Add notifications with same icon and color
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
- icon, iconColor);
- mGroupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(
+ getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null, icon, iconColor));
+ mGroupHelper.onNotificationPosted(r, false);
}
// Check that the summary would have the same icon and color
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(attr));
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ anyString(), anyInt(), eq(attr));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
// After auto-grouping, add new notification with the same color
- StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
- String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
- mGroupHelper.onNotificationPosted(sbn, true);
+ NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+ String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor));
+ mGroupHelper.onNotificationPosted(r, true);
// Check that the summary was updated
//NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor);
- verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(attr));
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ eq(attr));
}
@Test
@@ -1004,33 +1238,37 @@ public class GroupHelperTest extends UiServiceTestCase {
doReturn(monochromeIcon).when(groupHelper).getMonochromeAppIcon(eq(pkg));
final NotificationAttributes initialAttr = new NotificationAttributes(BASE_FLAGS,
- initialIcon, initialIconColor, DEFAULT_VISIBILITY);
+ initialIcon, initialIconColor, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+ TEST_CHANNEL_ID);
// Add notifications with same icon and color
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
- initialIcon, initialIconColor);
- groupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(
+ getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+ initialIcon, initialIconColor));
+ groupHelper.onNotificationPosted(r, false);
}
// Check that the summary would have the same icon and color
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(initialAttr));
- verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ anyString(), anyInt(), eq(initialAttr));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
// After auto-grouping, add new notification with a different color
final Icon newIcon = mock(Icon.class);
final int newIconColor = Color.YELLOW;
- StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
+ NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, newIcon,
- newIconColor);
- groupHelper.onNotificationPosted(sbn, true);
+ newIconColor));
+ groupHelper.onNotificationPosted(r, true);
// Summary should be updated to the default color and the icon to the monochrome icon
NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, monochromeIcon,
- COLOR_DEFAULT, DEFAULT_VISIBILITY);
- verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+ COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ eq(newAttr));
}
@Test
@@ -1049,33 +1287,37 @@ public class GroupHelperTest extends UiServiceTestCase {
doReturn(monochromeIcon).when(groupHelper).getMonochromeAppIcon(eq(pkg));
final NotificationAttributes initialAttr = new NotificationAttributes(BASE_FLAGS,
- initialIcon, initialIconColor, DEFAULT_VISIBILITY);
+ initialIcon, initialIconColor, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+ TEST_CHANNEL_ID);
// Add notifications with same icon and color
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
- initialIcon, initialIconColor);
- groupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(
+ getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+ initialIcon, initialIconColor));
+ groupHelper.onNotificationPosted(r, false);
}
// Check that the summary would have the same icon and color
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(initialAttr));
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ anyString(), anyInt(), eq(initialAttr));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
// After auto-grouping, add new notification with a different color
final Icon newIcon = mock(Icon.class);
final int newIconColor = Color.YELLOW;
- StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
- String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, newIcon,
- newIconColor);
- groupHelper.onNotificationPosted(sbn, true);
+ NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+ String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, newIcon,
+ newIconColor));
+ groupHelper.onNotificationPosted(r, true);
// Summary should be updated to the default color and the icon to the monochrome icon
NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, monochromeIcon,
- COLOR_DEFAULT, DEFAULT_VISIBILITY);
- verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+ COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ eq(newAttr));
}
@Test
@@ -1087,32 +1329,35 @@ public class GroupHelperTest extends UiServiceTestCase {
when(icon.sameAs(icon)).thenReturn(true);
final int iconColor = Color.BLUE;
final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
- VISIBILITY_PRIVATE);
+ VISIBILITY_PRIVATE, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
// Add notifications with same icon and color and default visibility (private)
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
- icon, iconColor);
- mGroupHelper.onNotificationPosted(sbn, false);
+ NotificationRecord r = getNotificationRecord(
+ getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+ icon, iconColor));
+ mGroupHelper.onNotificationPosted(r, false);
}
// Check that the summary has private visibility
verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(attr));
+ anyInt(), eq(pkg), anyString(), anyString(), anyInt(), eq(attr));
- verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
// After auto-grouping, add new notification with public visibility
- StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
- String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
- sbn.getNotification().visibility = VISIBILITY_PUBLIC;
- mGroupHelper.onNotificationPosted(sbn, true);
+ NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+ String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor));
+ r.getNotification().visibility = VISIBILITY_PUBLIC;
+ mGroupHelper.onNotificationPosted(r, true);
// Check that the summary visibility was updated
NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
- VISIBILITY_PUBLIC);
- verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+ VISIBILITY_PUBLIC, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ eq(newAttr));
}
@Test
@@ -1124,71 +1369,116 @@ public class GroupHelperTest extends UiServiceTestCase {
when(icon.sameAs(icon)).thenReturn(true);
final int iconColor = Color.BLUE;
final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
- VISIBILITY_PRIVATE);
+ VISIBILITY_PRIVATE, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
// Add notifications with same icon and color and default visibility (private)
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
- icon, iconColor);
- assertThat(mGroupHelper.onNotificationPosted(sbn, false)).isFalse();
+ NotificationRecord r = getNotificationRecord(
+ getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+ icon, iconColor));
+ assertThat(mGroupHelper.onNotificationPosted(r, false)).isFalse();
}
// The last notification added will reach the autogroup threshold.
- StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT - 1,
- String.valueOf(AUTOGROUP_AT_COUNT - 1), UserHandle.SYSTEM, null, icon, iconColor);
- assertThat(mGroupHelper.onNotificationPosted(sbn, false)).isTrue();
+ NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT - 1,
+ String.valueOf(AUTOGROUP_AT_COUNT - 1), UserHandle.SYSTEM, null, icon, iconColor));
+ assertThat(mGroupHelper.onNotificationPosted(r, false)).isTrue();
// Check that the summary has private visibility
- verify(mCallback, times(1)).addAutoGroupSummary(
- anyInt(), eq(pkg), anyString(), eq(attr));
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), anyString(),
+ anyInt(), eq(attr));
// The last sbn is expected to be added to autogroup synchronously.
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+ anyBoolean());
verify(mCallback, never()).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
// After auto-grouping, add new notification with public visibility
- sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
- String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
- sbn.getNotification().visibility = VISIBILITY_PUBLIC;
- assertThat(mGroupHelper.onNotificationPosted(sbn, true)).isTrue();
+ r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+ String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor));
+ r.getNotification().visibility = VISIBILITY_PUBLIC;
+ assertThat(mGroupHelper.onNotificationPosted(r, true)).isTrue();
// Check that the summary visibility was updated
NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
- VISIBILITY_PUBLIC);
- verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+ VISIBILITY_PUBLIC, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ eq(newAttr));
}
@Test
@EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
+ @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testAutoGrouped_diffIcon_diffColor_removeChild_updateTo_sameIcon_sameColor() {
final String pkg = "package";
final Icon initialIcon = mock(Icon.class);
when(initialIcon.sameAs(initialIcon)).thenReturn(true);
final int initialIconColor = Color.BLUE;
final NotificationAttributes initialAttr = new NotificationAttributes(
- GroupHelper.FLAG_INVALID, initialIcon, initialIconColor, DEFAULT_VISIBILITY);
+ GroupHelper.FLAG_INVALID, initialIcon, initialIconColor, DEFAULT_VISIBILITY,
+ DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
// Add AUTOGROUP_AT_COUNT-1 notifications with same icon and color
- ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
- StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
- initialIcon, initialIconColor);
- notifications.add(sbn);
+ NotificationRecord r = getNotificationRecord(
+ getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+ initialIcon, initialIconColor));
+ notifications.add(r);
}
// And an additional notification with different icon and color
final int lastIdx = AUTOGROUP_AT_COUNT - 1;
- StatusBarNotification newSbn = getSbn(pkg, lastIdx,
+ NotificationRecord newRec = getNotificationRecord(getSbn(pkg, lastIdx,
String.valueOf(lastIdx), UserHandle.SYSTEM, null, mock(Icon.class),
- Color.YELLOW);
- notifications.add(newSbn);
- for (StatusBarNotification sbn: notifications) {
- mGroupHelper.onNotificationPosted(sbn, false);
+ Color.YELLOW));
+ notifications.add(newRec);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
}
// Remove last notification (the only one with different icon and color)
mGroupHelper.onNotificationRemoved(notifications.get(lastIdx));
// Summary should be updated to the common icon and color
- verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(initialAttr));
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ eq(initialAttr));
+ }
+
+ @Test
+ @EnableFlags({Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE,
+ FLAG_NOTIFICATION_FORCE_GROUPING})
+ public void testAutoGrouped_diffIcon_diffColor_removeChild_updateTo_sameIcon_sameColor_forceGrouping() {
+ final String pkg = "package";
+ final Icon initialIcon = mock(Icon.class);
+ when(initialIcon.sameAs(initialIcon)).thenReturn(true);
+ final int initialIconColor = Color.BLUE;
+ final NotificationAttributes initialAttr = new NotificationAttributes(
+ BASE_FLAGS, initialIcon, initialIconColor, DEFAULT_VISIBILITY,
+ DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+
+ // Add AUTOGROUP_AT_COUNT-1 notifications with same icon and color
+ ArrayList<NotificationRecord> notifications = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+ NotificationRecord r = getNotificationRecord(
+ getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+ initialIcon, initialIconColor));
+ notifications.add(r);
+ }
+ // And an additional notification with different icon and color
+ final int lastIdx = AUTOGROUP_AT_COUNT - 1;
+ NotificationRecord newRec = getNotificationRecord(getSbn(pkg, lastIdx,
+ String.valueOf(lastIdx), UserHandle.SYSTEM, null, mock(Icon.class),
+ Color.YELLOW));
+ notifications.add(newRec);
+ for (NotificationRecord r: notifications) {
+ mGroupHelper.onNotificationPosted(r, false);
+ }
+
+ // Remove last notification (the only one with different icon and color)
+ mGroupHelper.onNotificationRemoved(notifications.get(lastIdx));
+
+ // Summary should be updated to the common icon and color
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ eq(initialAttr));
}
@Test
@@ -1202,7 +1492,7 @@ public class GroupHelperTest extends UiServiceTestCase {
List<NotificationAttributes> childrenAttr = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
childrenAttr.add(new NotificationAttributes(0, icon, COLOR_DEFAULT,
- DEFAULT_VISIBILITY));
+ DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
}
//Check that the generated summary icon is the same as the child notifications'
@@ -1223,7 +1513,7 @@ public class GroupHelperTest extends UiServiceTestCase {
List<NotificationAttributes> childrenAttr = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), COLOR_DEFAULT,
- DEFAULT_VISIBILITY));
+ DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
}
// Check that the generated summary icon is the monochrome icon
@@ -1240,7 +1530,7 @@ public class GroupHelperTest extends UiServiceTestCase {
List<NotificationAttributes> childrenAttr = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
- DEFAULT_VISIBILITY));
+ DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
}
// Check that the generated summary icon color is the same as the child notifications'
@@ -1257,7 +1547,7 @@ public class GroupHelperTest extends UiServiceTestCase {
List<NotificationAttributes> childrenAttr = new ArrayList<>();
for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), i,
- DEFAULT_VISIBILITY));
+ DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
}
// Check that the generated summary icon color is the default color
@@ -1274,10 +1564,10 @@ public class GroupHelperTest extends UiServiceTestCase {
// Create notifications with private and public visibility
List<NotificationAttributes> childrenAttr = new ArrayList<>();
childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
- VISIBILITY_PUBLIC));
+ VISIBILITY_PUBLIC, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
- VISIBILITY_PRIVATE));
+ VISIBILITY_PRIVATE, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
}
// Check that the generated summary visibility is public
@@ -1301,7 +1591,7 @@ public class GroupHelperTest extends UiServiceTestCase {
visibility = VISIBILITY_SECRET;
}
childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
- visibility));
+ visibility, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
}
// Check that the generated summary visibility is private
@@ -1311,6 +1601,90 @@ public class GroupHelperTest extends UiServiceTestCase {
}
@Test
+ public void testAutobundledSummaryAlertBehavior_oneChildAlertChildren() {
+ final String pkg = "package";
+ final int iconColor = Color.BLUE;
+ // Create notifications with GROUP_ALERT_SUMMARY + one with GROUP_ALERT_CHILDREN
+ List<NotificationAttributes> childrenAttr = new ArrayList<>();
+ childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+ VISIBILITY_PUBLIC, GROUP_ALERT_CHILDREN, TEST_CHANNEL_ID));
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+ childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+ VISIBILITY_PRIVATE, GROUP_ALERT_SUMMARY, TEST_CHANNEL_ID));
+ }
+ // Check that the generated summary alert behavior is GROUP_ALERT_CHILDREN
+ int groupAlertBehavior = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+ childrenAttr).groupAlertBehavior;
+ assertThat(groupAlertBehavior).isEqualTo(GROUP_ALERT_CHILDREN);
+ }
+
+ @Test
+ public void testAutobundledSummaryAlertBehavior_oneChildAlertAll() {
+ final String pkg = "package";
+ final int iconColor = Color.BLUE;
+ // Create notifications with GROUP_ALERT_SUMMARY + one with GROUP_ALERT_ALL
+ List<NotificationAttributes> childrenAttr = new ArrayList<>();
+ childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+ VISIBILITY_PUBLIC, GROUP_ALERT_ALL, TEST_CHANNEL_ID));
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+ childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+ VISIBILITY_PRIVATE, GROUP_ALERT_SUMMARY, TEST_CHANNEL_ID));
+ }
+ // Check that the generated summary alert behavior is GROUP_ALERT_CHILDREN
+ int groupAlertBehavior = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+ childrenAttr).groupAlertBehavior;
+ assertThat(groupAlertBehavior).isEqualTo(GROUP_ALERT_CHILDREN);
+ }
+
+ @Test
+ public void testAutobundledSummaryAlertBehavior_allChildAlertSummary() {
+ final String pkg = "package";
+ final int iconColor = Color.BLUE;
+ // Create notifications with GROUP_ALERT_SUMMARY
+ List<NotificationAttributes> childrenAttr = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+ VISIBILITY_PRIVATE, GROUP_ALERT_SUMMARY, TEST_CHANNEL_ID));
+ }
+
+ // Check that the generated summary alert behavior is GROUP_ALERT_SUMMARY
+ int groupAlertBehavior = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+ childrenAttr).groupAlertBehavior;
+ assertThat(groupAlertBehavior).isEqualTo(GROUP_ALERT_SUMMARY);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
+ public void testAutobundledSummaryChannelId() {
+ final String pkg = "package";
+ final int iconColor = Color.BLUE;
+ final String expectedChannelId = TEST_CHANNEL_ID + "0";
+ // Create notifications with different channelIds
+ List<NotificationAttributes> childrenAttr = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+ DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID+i));
+ }
+
+ // Check that the generated summary channelId is the first child in the list
+ String summaryChannelId = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+ childrenAttr).channelId;
+ assertThat(summaryChannelId).isEqualTo(expectedChannelId);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
+ public void testAutobundledSummaryChannelId_noChildren() {
+ final String pkg = "package";
+ // No child notifications
+ List<NotificationAttributes> childrenAttr = new ArrayList<>();
+ // Check that the generated summary channelId is null
+ String summaryChannelId = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+ childrenAttr).channelId;
+ assertThat(summaryChannelId).isNull();
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
public void testMonochromeAppIcon_adaptiveIconExists() throws Exception {
final String pkg = "testPackage";
@@ -1333,4 +1707,855 @@ public class GroupHelperTest extends UiServiceTestCase {
assertThat(mGroupHelper.getMonochromeAppIcon(pkg).getResId())
.isEqualTo(fallbackIconResId);
}
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testGetAggregateGroupKey() {
+ final String fullAggregateGroupKey = GroupHelper.getFullAggregateGroupKey("pkg",
+ "groupKey", 1234);
+ assertThat(fullAggregateGroupKey).isEqualTo("1234|pkg|g:groupKey");
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testNoGroup_postingUnderLimit_forcedGrouping() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verifyZeroInteractions(mCallback);
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testNoGroup_AutobundledAlready_forcedGrouping() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, null, true);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verifyZeroInteractions(mCallback);
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testNoGroup_isCanceled_forcedGrouping() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp" + i, true);
+ r.isCanceled = true;
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verifyZeroInteractions(mCallback);
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testNoGroup_isAggregated_forcedGrouping() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ String aggregateGroupKey = AGGREGATE_GROUP_KEY + "AlertingSection";
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, aggregateGroupKey, true);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verifyZeroInteractions(mCallback);
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testNoGroup_multiPackage_forcedGrouping() {
+ final String pkg = "package";
+ final String pkg2 = "package2";
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ NotificationRecord r = getNotificationRecord(pkg2, AUTOGROUP_AT_COUNT,
+ String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, "testGrp", true);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ verifyZeroInteractions(mCallback);
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testNoGroup_multiUser_forcedGrouping() {
+ final String pkg = "package";
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ NotificationRecord r = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT,
+ String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.of(7), "testGrp", true);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ verifyZeroInteractions(mCallback);
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testNoGroup_summaryWithChildren_forcedGrouping() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ // Next posted summary has 1 child => no forced grouping
+ NotificationRecord summary = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT,
+ String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, "testGrp", true);
+ notificationList.add(summary);
+ NotificationRecord child = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT + 1,
+ String.valueOf(AUTOGROUP_AT_COUNT + 1), UserHandle.SYSTEM, "testGrp", false);
+ notificationList.add(child);
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ verifyZeroInteractions(mCallback);
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testNoGroup_groupWithSummary_forcedGrouping() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ // Next posted notification has summary => no forced grouping
+ NotificationRecord summary = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT,
+ String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, "testGrp", true);
+ notificationList.add(summary);
+ NotificationRecord child = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT + 1,
+ String.valueOf(AUTOGROUP_AT_COUNT + 1), UserHandle.SYSTEM, "testGrp", false);
+ notificationList.add(child);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+ verifyZeroInteractions(mCallback);
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testAddAggregateSummary_summaryNoChildren() {
+ final String pkg = "package";
+ final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ // Post group summaries without children => force autogroup
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testAddAggregateSummary_childrenNoSummary() {
+ final String pkg = "package";
+ final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ // Post group notifications without summaries => force autogroup
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testAddAggregateSummary_multipleSections() {
+ final String pkg = "package";
+ final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ // Post notifications with different importance values => force group into separate sections
+ NotificationRecord r;
+ for (int i = 0; i < 2 * AUTOGROUP_AT_COUNT; i++) {
+ if (i % 2 == 0) {
+ r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+ "testGrp " + i, true, IMPORTANCE_DEFAULT);
+ } else {
+ r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+ "testGrp " + i, false, IMPORTANCE_LOW);
+ }
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_alerting), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_silent), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_alerting), eq(true));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_silent), eq(true));
+
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ }
+
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
+ public void testAddAggregateSummary_mixUngroupedAndAbusive_alwaysAutogroup() {
+ final String pkg = "package";
+ final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ // Post ungrouped notifications => create autogroup
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ mGroupHelper.onNotificationPosted(
+ getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
+ }
+ verify(mCallback, times(1)).addAutoGroupSummary(
+ anyInt(), eq(pkg), anyString(), eq(expectedGroupKey),
+ anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(expectedGroupKey),
+ anyBoolean());
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+
+ reset(mCallback);
+
+ // Post group notifications without summaries => add to autogroup
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final int id = AUTOGROUP_AT_COUNT;
+ NotificationRecord r = getNotificationRecord(pkg, id, String.valueOf(id),
+ UserHandle.SYSTEM, "testGrp " + id, false);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+
+ // Check that the new notification was added
+ verify(mCallback, times(1)).addAutoGroup(eq(r.getKey()),
+ eq(expectedGroupKey), eq(true));
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey), any());
+ verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+ anyString(), anyInt(), any());
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
+ public void testUpdateAggregateSummary_postUngroupedAfterForcedGrouping_alwaysAutogroup() {
+ final String pkg = "package";
+ final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ // Post group notifications without summaries => force autogroup
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+
+ reset(mCallback);
+
+ // Post ungrouped notification => update autogroup
+ final int id = AUTOGROUP_AT_COUNT;
+ NotificationRecord r = getNotificationRecord(pkg, id, String.valueOf(id),
+ UserHandle.SYSTEM);
+ mGroupHelper.onNotificationPosted(r, true);
+
+ verify(mCallback, times(1)).addAutoGroup(eq(r.getKey()),
+ eq(expectedGroupKey), eq(true));
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+ anyString(), anyInt(), any());
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST})
+ public void testUpdateAggregateSummary_postUngroupedAfterForcedGrouping() {
+ final String pkg = "package";
+ final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ // Post group notifications without summaries => force autogroup
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+
+ reset(mCallback);
+
+ // Post ungrouped notification => update autogroup
+ final int id = AUTOGROUP_AT_COUNT;
+ NotificationRecord r = getNotificationRecord(pkg, id, String.valueOf(id),
+ UserHandle.SYSTEM);
+ mGroupHelper.onNotificationPosted(r, true);
+
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean());
+ verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+ anyString(), anyInt(), any());
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testUpdateAggregateSummary_postAfterForcedGrouping() {
+ final String pkg = "package";
+ final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ // Post group notifications w/o summaries and summaries w/o children => force autogrouping
+ NotificationRecord r;
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ if (i % 2 == 0) {
+ r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+ "testGrp " + i, true);
+ } else {
+ r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+ "testGrp " + i, false);
+ }
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+
+ // Post another notification after forced grouping
+ final Icon icon = mock(Icon.class);
+ when(icon.sameAs(icon)).thenReturn(true);
+ final int iconColor = Color.BLUE;
+ r = getNotificationRecord(
+ getSbn(pkg, AUTOGROUP_AT_COUNT, String.valueOf(AUTOGROUP_AT_COUNT),
+ UserHandle.SYSTEM, "testGrp " + AUTOGROUP_AT_COUNT, icon, iconColor));
+
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT + 1)).addAutoGroup(anyString(),
+ eq(expectedGroupKey), eq(true));
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey), any());
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testRemoveAggregateSummary_removeAllNotifications() {
+ final String pkg = "package";
+ final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ // Post group notifications without summaries => force autogroup
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ Mockito.reset(mCallback);
+
+ // Remove all posted notifications
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false);
+ r.setOverrideGroupKey(expectedGroupKey);
+ mGroupHelper.onNotificationRemoved(r, notificationList);
+ }
+ // Check that the autogroup summary is removed
+ verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey));
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testMoveAggregateGroups_updateChannel() {
+ final String pkg = "package";
+ final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ final NotificationChannel channel = new NotificationChannel(TEST_CHANNEL_ID,
+ TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ // Post group notifications without summaries => force autogroup
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false, channel);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_alerting), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_alerting), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ Mockito.reset(mCallback);
+
+ // Update the channel importance for all posted notifications
+ final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+ channel.setImportance(IMPORTANCE_LOW);
+ for (NotificationRecord r: notificationList) {
+ r.updateNotificationChannel(channel);
+ }
+ mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel,
+ notificationList);
+
+ // Check that all notifications are moved to the silent section group
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_silent), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_silent), eq(false));
+
+ // Check that the alerting section group is removed
+ verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey_alerting));
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testMoveAggregateGroups_updateChannel_multipleChannels() {
+ final String pkg = "package";
+ final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ final NotificationChannel channel1 = new NotificationChannel("TEST_CHANNEL_ID1",
+ "TEST_CHANNEL_ID1", IMPORTANCE_DEFAULT);
+ final NotificationChannel channel2 = new NotificationChannel("TEST_CHANNEL_ID2",
+ "TEST_CHANNEL_ID2", IMPORTANCE_DEFAULT);
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ // Post notifications with different channels that autogroup within the same section
+ NotificationRecord r;
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ if (i % 2 == 0) {
+ r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false, channel1);
+ } else {
+ r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false, channel2);
+ }
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ NotificationAttributes expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
+ mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+ "TEST_CHANNEL_ID1");
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_alerting), anyInt(), eq(expectedSummaryAttr));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_alerting), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ Mockito.reset(mCallback);
+
+ // Update channel1's importance
+ final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+ channel1.setImportance(IMPORTANCE_LOW);
+ for (NotificationRecord record: notificationList) {
+ if (record.getChannel().getId().equals(channel1.getId())) {
+ record.updateNotificationChannel(channel1);
+ }
+ }
+ mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel1,
+ notificationList);
+
+ // Check that channel1's notifications are moved to the silent section group
+ expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
+ mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+ "TEST_CHANNEL_ID1");
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_silent), anyInt(), eq(expectedSummaryAttr));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT/2 + 1)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_silent), eq(false));
+
+ // Check that the alerting section group is not removed, only updated
+ expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
+ mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+ "TEST_CHANNEL_ID2");
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey_alerting));
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey_alerting), eq(expectedSummaryAttr));
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testMoveAggregateGroups_updateChannel_groupsUngrouped() {
+ final String pkg = "package";
+ final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+
+ // Post too few group notifications without summaries => do not autogroup
+ final NotificationChannel lowPrioChannel = new NotificationChannel("TEST_CHANNEL_LOW_ID",
+ "TEST_CHANNEL_LOW_ID", IMPORTANCE_LOW);
+ final int numUngrouped = AUTOGROUP_AT_COUNT - 1;
+ int startIdx = 42;
+ for (int i = startIdx; i < startIdx + numUngrouped; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false, lowPrioChannel);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean());
+ verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+ anyString(), anyInt(), any());
+
+ reset(mCallback);
+
+ final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ final NotificationChannel channel = new NotificationChannel(TEST_CHANNEL_ID,
+ TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
+
+ // Post group notifications without summaries => force autogroup
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false, channel);
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_alerting), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_alerting), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ Mockito.reset(mCallback);
+
+ // Update the channel importance for all posted notifications
+ final int numSilentGroupNotifications = AUTOGROUP_AT_COUNT + numUngrouped;
+ channel.setImportance(IMPORTANCE_LOW);
+ for (NotificationRecord r: notificationList) {
+ r.updateNotificationChannel(channel);
+ }
+ mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel,
+ notificationList);
+
+ // Check that all notifications are moved to the silent section group
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_silent), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(numSilentGroupNotifications)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_silent), eq(false));
+
+ // Check that the alerting section group is removed
+ verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey_alerting));
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+ public void testNoGroup_singletonGroup_underLimit() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ // Post singleton groups, under forced group limit
+ for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT - 1; i++) {
+ NotificationRecord summary = getNotificationRecord(pkg, i,
+ String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+ notificationList.add(summary);
+ NotificationRecord child = getNotificationRecord(pkg, i + 42,
+ String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+ notificationList.add(child);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ }
+ verifyZeroInteractions(mCallback);
+ }
+
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ @DisableFlags(Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS)
+ public void testAddAggregateSummary_singletonGroup_disableFlag() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ // Post singleton groups, above forced group limit
+ for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+ NotificationRecord summary = getNotificationRecord(pkg, i,
+ String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+ notificationList.add(summary);
+ NotificationRecord child = getNotificationRecord(pkg, i + 42,
+ String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+ notificationList.add(child);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ }
+ // FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS is disabled => don't force group
+ verifyZeroInteractions(mCallback);
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+ public void testAddAggregateSummary_singletonGroups() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ // Post singleton groups, above forced group limit
+ for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+ NotificationRecord summary = getNotificationRecord(pkg, i,
+ String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+ notificationList.add(summary);
+ NotificationRecord child = getNotificationRecord(pkg, i + 42,
+ String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+ notificationList.add(child);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+ summary.isCanceled = true; // simulate removing the app summary
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+
+ }
+ // Check that notifications are forced grouped
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+
+ // Check that summaries are canceled
+ verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).removeAppProvidedSummary(anyString());
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+ public void testCancelCachedSummary_singletonGroups() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ final int id = 0;
+ // Post singleton groups, above forced group limit
+ for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+ NotificationRecord summary = getNotificationRecord(pkg, i,
+ String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+ notificationList.add(summary);
+ NotificationRecord child = getNotificationRecord(pkg, i + 42,
+ String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+ notificationList.add(child);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+ summary.isCanceled = true; // simulate removing the app summary
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ }
+ Mockito.reset(mCallback);
+
+ // App cancels the summary of an aggregated group
+ mGroupHelper.maybeCancelGroupChildrenForCanceledSummary(pkg, String.valueOf(id), id,
+ UserHandle.SYSTEM.getIdentifier(), REASON_APP_CANCEL);
+
+ verify(mCallback, times(1)).removeNotificationFromCanceledGroup(
+ eq(UserHandle.SYSTEM.getIdentifier()), eq(pkg), eq("testGrp " + id),
+ eq(REASON_APP_CANCEL));
+ CachedSummary cachedSummary = mGroupHelper.findCanceledSummary(pkg, String.valueOf(id), id,
+ UserHandle.SYSTEM.getIdentifier());
+ assertThat(cachedSummary).isNull();
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+ public void testRemoveCachedSummary_singletonGroups_removeChildren() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ final int id = 0;
+ NotificationRecord childToRemove = null;
+ // Post singleton groups, above forced group limit
+ for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+ NotificationRecord summary = getNotificationRecord(pkg, i,
+ String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+ notificationList.add(summary);
+ NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+ UserHandle.SYSTEM, "testGrp " + i, false);
+ if (i == id) {
+ childToRemove = child;
+ }
+ notificationList.add(child);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+ summary.isCanceled = true; // simulate removing the app summary
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ }
+ // override group key for child notifications
+ List<NotificationRecord> notificationListAfterGrouping = new ArrayList<>(
+ notificationList.stream().filter(r -> {
+ if (r.getSbn().getNotification().isGroupChild()) {
+ r.setOverrideGroupKey(expectedGroupKey);
+ return true;
+ } else {
+ return false;
+ }
+ }).toList());
+ summaryByGroup.clear();
+ Mockito.reset(mCallback);
+
+ //Cancel child 0 => remove cached summary
+ childToRemove.isCanceled = true;
+ notificationListAfterGrouping.remove(childToRemove);
+ mGroupHelper.onNotificationRemoved(childToRemove, notificationListAfterGrouping);
+ CachedSummary cachedSummary = mGroupHelper.findCanceledSummary(pkg, String.valueOf(id), id,
+ UserHandle.SYSTEM.getIdentifier());
+ assertThat(cachedSummary).isNull();
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testGroupSectioners() {
+ final NotificationRecord notification_alerting = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, IMPORTANCE_DEFAULT);
+ assertThat(GroupHelper.getSection(notification_alerting).mName).isEqualTo("AlertingSection");
+
+ final NotificationRecord notification_silent = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, IMPORTANCE_LOW);
+ assertThat(GroupHelper.getSection(notification_silent).mName).isEqualTo("SilentSection");
+
+ NotificationRecord notification_conversation = mock(NotificationRecord.class);
+ when(notification_conversation.isConversation()).thenReturn(true);
+ assertThat(GroupHelper.getSection(notification_conversation)).isNull();
+
+ NotificationRecord notification_call = spy(getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, IMPORTANCE_LOW));
+ Notification n = mock(Notification.class);
+ StatusBarNotification sbn = spy(getSbn("package", 0, "0", UserHandle.SYSTEM));
+ when(notification_call.isConversation()).thenReturn(false);
+ when(notification_call.getNotification()).thenReturn(n);
+ when(notification_call.getSbn()).thenReturn(sbn);
+ when(sbn.getNotification()).thenReturn(n);
+ when(n.isStyle(Notification.CallStyle.class)).thenReturn(true);
+ assertThat(GroupHelper.getSection(notification_call)).isNull();
+
+ NotificationRecord notification_colorFg = spy(getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, IMPORTANCE_LOW));
+ sbn = spy(getSbn("package", 0, "0", UserHandle.SYSTEM));
+ n = mock(Notification.class);
+ when(notification_colorFg.isConversation()).thenReturn(false);
+ when(notification_colorFg.getNotification()).thenReturn(n);
+ when(notification_colorFg.getSbn()).thenReturn(sbn);
+ when(sbn.getNotification()).thenReturn(n);
+ when(n.isForegroundService()).thenReturn(true);
+ when(n.isColorized()).thenReturn(true);
+ when(n.isStyle(Notification.CallStyle.class)).thenReturn(false);
+ assertThat(GroupHelper.getSection(notification_colorFg)).isNull();
+ }
+
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java
index 3da80314e6d4..e06d939a34f7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java
@@ -84,6 +84,8 @@ import android.os.UserManager;
import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.os.Vibrator;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.service.notification.NotificationListenerService;
@@ -221,10 +223,16 @@ public class NotificationAttentionHelperTest extends UiServiceTestCase {
Settings.System.putInt(getContext().getContentResolver(),
Settings.System.NOTIFICATION_LIGHT_PULSE, 1);
+ // Enable notification cooldown independent of device Settings
+ Settings.System.putInt(getContext().getContentResolver(),
+ Settings.System.NOTIFICATION_COOLDOWN_ENABLED, 1);
+
Resources resources = spy(getContext().getResources());
when(resources.getBoolean(R.bool.config_useAttentionLight)).thenReturn(true);
when(resources.getBoolean(
com.android.internal.R.bool.config_intrusiveNotificationLed)).thenReturn(true);
+ when(resources.getBoolean(R.bool.config_enableNotificationAccessibilityEvents))
+ .thenReturn(true);
when(getContext().getResources()).thenReturn(resources);
// TODO (b/291907312): remove feature flag
@@ -1221,6 +1229,44 @@ public class NotificationAttentionHelperTest extends UiServiceTestCase {
}
@Test
+ @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+ public void testSilentNotification_flagSilent() throws Exception {
+ final Notification n = new Builder(getContext(), "test")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .setSilent(true)
+ .build();
+ StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+ mPid, n, mUser, null, System.currentTimeMillis());
+ NotificationRecord r = new NotificationRecord(getContext(), sbn,
+ new NotificationChannel("test", "test", IMPORTANCE_HIGH));
+
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ verifyNeverBeep();
+ assertFalse(r.isInterruptive());
+ assertEquals(-1, r.getLastAudiblyAlertedMs());
+ assertTrue(mAttentionHelper.shouldMuteNotificationLocked(r, DEFAULT_SIGNALS));
+ }
+
+ @Test
+ @DisableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+ public void testSilentNotification_groupKeySilent() throws Exception {
+ final Notification n = new Builder(getContext(), "test")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .setSilent(true)
+ .build();
+ StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+ mPid, n, mUser, null, System.currentTimeMillis());
+ NotificationRecord r = new NotificationRecord(getContext(), sbn,
+ new NotificationChannel("test", "test", IMPORTANCE_HIGH));
+
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ verifyNeverBeep();
+ assertFalse(r.isInterruptive());
+ assertEquals(-1, r.getLastAudiblyAlertedMs());
+ assertTrue(mAttentionHelper.shouldMuteNotificationLocked(r, DEFAULT_SIGNALS));
+ }
+
+ @Test
public void testHonorAlertOnlyOnceForBuzz() throws Exception {
NotificationRecord r = getBuzzyNotification();
NotificationRecord s = getBuzzyOnceNotification();
@@ -2790,6 +2836,34 @@ public class NotificationAttentionHelperTest extends UiServiceTestCase {
assertThat(r.getRankingTimeMs()).isEqualTo(r.getSbn().getPostTime());
}
+ @Test
+ public void testAccessibilityEventsEnabledInConfig() throws Exception {
+ Resources resources = spy(getContext().getResources());
+ when(resources.getBoolean(R.bool.config_enableNotificationAccessibilityEvents))
+ .thenReturn(true);
+ when(getContext().getResources()).thenReturn(resources);
+ initAttentionHelper(mTestFlagResolver);
+ NotificationRecord r = getBeepyNotification();
+
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+ verify(mAccessibilityService).sendAccessibilityEvent(any(), anyInt());
+ }
+
+ @Test
+ public void testAccessibilityEventsDisabledInConfig() throws Exception {
+ Resources resources = spy(getContext().getResources());
+ when(resources.getBoolean(R.bool.config_enableNotificationAccessibilityEvents))
+ .thenReturn(false);
+ when(getContext().getResources()).thenReturn(resources);
+ initAttentionHelper(mTestFlagResolver);
+ NotificationRecord r = getBeepyNotification();
+
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+ verify(mAccessibilityService, never()).sendAccessibilityEvent(any(), anyInt());
+ }
+
static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> {
private final int mRepeatIndex;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index c48d745b1dc0..c1f5a01a8c47 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -39,8 +39,10 @@ import static android.app.Notification.FLAG_NO_DISMISS;
import static android.app.Notification.FLAG_ONGOING_EVENT;
import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
import static android.app.Notification.FLAG_USER_INITIATED_JOB;
+import static android.app.Notification.GROUP_ALERT_CHILDREN;
import static android.app.Notification.VISIBILITY_PRIVATE;
import static android.app.NotificationChannel.NEWS_ID;
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE;
import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
@@ -87,7 +89,6 @@ import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
import static android.os.UserManager.USER_TYPE_PROFILE_PRIVATE;
-import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
import static android.service.notification.Adjustment.KEY_CONTEXTUAL_ACTIONS;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
@@ -98,11 +99,13 @@ import static android.service.notification.Adjustment.TYPE_NEWS;
import static android.service.notification.Condition.SOURCE_CONTEXT;
import static android.service.notification.Condition.SOURCE_USER_ACTION;
import static android.service.notification.Condition.STATE_TRUE;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING;
import static android.service.notification.Flags.FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
+import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_LOCKDOWN;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
@@ -117,6 +120,7 @@ import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
import static com.android.server.notification.Flags.FLAG_ALL_NOTIFS_NEED_TTL;
import static com.android.server.notification.Flags.FLAG_REJECT_OLD_NOTIFICATIONS;
+import static com.android.server.notification.GroupHelper.AUTOGROUP_KEY;
import static com.android.server.notification.NotificationManagerService.BITMAP_DURATION;
import static com.android.server.notification.NotificationManagerService.DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
import static com.android.server.notification.NotificationManagerService.NOTIFICATION_TTL;
@@ -369,6 +373,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
private static final int TOAST_DURATION = 2_000;
private static final int SECONDARY_DISPLAY_ID = 42;
private static final int TEST_PROFILE_USERHANDLE = 12;
+ private static final long DELAY_FORCE_REGROUP_TIME = 3000;
private static final String ACTION_NOTIFICATION_TIMEOUT =
NotificationManagerService.class.getSimpleName() + ".TIMEOUT";
@@ -832,13 +837,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Pretend the shortcut exists
List<ShortcutInfo> shortcutInfos = new ArrayList<>();
- ShortcutInfo info = mock(ShortcutInfo.class);
- when(info.getPackage()).thenReturn(mPkg);
- when(info.getId()).thenReturn(VALID_CONVO_SHORTCUT_ID);
- when(info.getUserId()).thenReturn(USER_SYSTEM);
- when(info.isLongLived()).thenReturn(true);
- when(info.isEnabled()).thenReturn(true);
- shortcutInfos.add(info);
+ shortcutInfos.add(createMockConvoShortcut());
when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos);
when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
anyString(), anyInt(), any())).thenReturn(true);
@@ -2487,43 +2486,372 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testAutobundledSummary_notificationAdded() {
NotificationRecord summary =
- generateNotificationRecord(mTestNotificationChannel, 0, "pkg", true);
+ generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
mService.addNotification(summary);
mService.mSummaryByGroupKey.put("pkg", summary);
mService.mAutobundledSummaries.put(0, new ArrayMap<>());
mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey());
- mService.updateAutobundledSummaryLocked(0, "pkg",
+ mService.updateAutobundledSummaryLocked(0, "pkg", AUTOGROUP_KEY,
+ new NotificationAttributes(GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT,
+ mock(Icon.class), 0,
+ VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
+ waitForIdle();
+
+ assertTrue(summary.getSbn().isOngoing());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testAutobundledSummary_notificationAdded_forcedGrouping() {
+ NotificationRecord summary =
+ generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
+ summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
+ mService.addNotification(summary);
+ mService.mSummaryByGroupKey.put("pkg", summary);
+ mService.mAutobundledSummaries.put(0, new ArrayMap<>());
+ mService.mAutobundledSummaries.get(0).put(summary.getGroupKey(), summary.getKey());
+
+ mService.updateAutobundledSummaryLocked(0, "pkg", summary.getGroupKey(),
new NotificationAttributes(GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT,
- mock(Icon.class), 0, VISIBILITY_PRIVATE), false);
+ mock(Icon.class), 0,
+ VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
waitForIdle();
assertTrue(summary.getSbn().isOngoing());
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testAutobundledSummary_notificationRemoved() {
NotificationRecord summary =
- generateNotificationRecord(mTestNotificationChannel, 0, "pkg", true);
+ generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
summary.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
mService.addNotification(summary);
mService.mAutobundledSummaries.put(0, new ArrayMap<>());
mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey());
- mService.mSummaryByGroupKey.put("pkg", summary);
+ mService.mSummaryByGroupKey.put(summary.getGroupKey(), summary);
+
+ mService.updateAutobundledSummaryLocked(0, "pkg", AUTOGROUP_KEY,
+ new NotificationAttributes(GroupHelper.BASE_FLAGS,
+ mock(Icon.class), 0,
+ VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
+ waitForIdle();
+
+ assertFalse(summary.getSbn().isOngoing());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testAutobundledSummary_notificationRemoved_forceGrouping() {
+ NotificationRecord summary =
+ generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
+ summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
+ summary.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+ mService.addNotification(summary);
+ mService.mAutobundledSummaries.put(0, new ArrayMap<>());
+ mService.mAutobundledSummaries.get(0).put(summary.getGroupKey(), summary.getKey());
- mService.updateAutobundledSummaryLocked(0, "pkg",
+ mService.updateAutobundledSummaryLocked(0, "pkg", summary.getGroupKey(),
new NotificationAttributes(GroupHelper.BASE_FLAGS,
- mock(Icon.class), 0, VISIBILITY_PRIVATE), false);
+ mock(Icon.class), 0,
+ VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
waitForIdle();
assertFalse(summary.getSbn().isOngoing());
}
@Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testAggregatedSummary_updateSummaryAttributes() {
+ final String aggregateGroupName = "Aggregate_Test";
+ final String newChannelId = "newChannelId";
+ final NotificationChannel newChannel = new NotificationChannel(
+ newChannelId, newChannelId, IMPORTANCE_DEFAULT);
+ mService.setPreferencesHelper(mPreferencesHelper);
+ final NotificationRecord summary =
+ generateNotificationRecord(mTestNotificationChannel, 0, aggregateGroupName, true);
+ final String groupKey = summary.getGroupKey();
+ summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
+ mService.addNotification(summary);
+ mService.mAutobundledSummaries.put(0, new ArrayMap<>());
+ mService.mAutobundledSummaries.get(0).put(groupKey, summary.getKey());
+ when(mPreferencesHelper.getNotificationChannel(eq("pkg"), anyInt(),
+ eq(newChannelId), anyBoolean())).thenReturn(newChannel);
+
+ mService.updateAutobundledSummaryLocked(0, "pkg", groupKey,
+ new NotificationAttributes(GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT,
+ mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, newChannelId),
+ false);
+ waitForIdle();
+
+ assertTrue(summary.getSbn().isOngoing());
+ assertThat(summary.getNotification().getGroupAlertBehavior()).isEqualTo(
+ GROUP_ALERT_CHILDREN);
+
+ assertThat(summary.getChannel().getId()).isEqualTo(newChannelId);
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testAddAggregateNotification_notifyPostedLocked() throws Exception {
+ final String originalGroupName = "originalGroup";
+ final NotificationRecord r =
+ generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, false);
+ mService.addNotification(r);
+ mService.addAutogroupKeyLocked(r.getKey(), "grpKey", true);
+
+ assertThat(r.getSbn().getOverrideGroupKey()).isEqualTo("grpKey");
+ verify(mRankingHandler, times(1)).requestSort();
+ verify(mListeners, times(1)).notifyPostedLocked(eq(r), eq(r));
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testAddAggregateSummaryNotification_convertSummary() throws Exception {
+ final String originalGroupName = "originalGroup";
+ final NotificationRecord r =
+ generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, true);
+ final String groupKey = r.getGroupKey();
+ mService.addNotification(r);
+ assertThat(mService.mSummaryByGroupKey.containsKey(groupKey)).isTrue();
+ boolean isConverted = mService.convertSummaryToNotificationLocked(r.getKey());
+
+ assertThat(isConverted).isTrue();
+ assertThat(r.getSbn().isGroup()).isTrue();
+ assertThat(r.getNotification().isGroupSummary()).isFalse();
+ assertThat(mService.mSummaryByGroupKey.containsKey(groupKey)).isFalse();
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+ public void testAggregateGroups_RemoveAppSummary() throws Exception {
+ final String originalGroupName = "originalGroup";
+ final NotificationRecord r =
+ generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, true);
+ mService.addNotification(r);
+ mService.removeAppSummaryLocked(r.getKey());
+
+ assertThat(r.isCanceled).isTrue();
+ waitForIdle();
+ verify(mWorkerHandler, times(1)).scheduleCancelNotification(any(), eq(0));
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testUngroupingAggregateSummary() throws Exception {
+ final String originalGroupName = "originalGroup";
+ final String aggregateGroupName = "Aggregate_Test";
+ final int summaryId = Integer.MAX_VALUE;
+ // Add 2 group notifications without a summary
+ NotificationRecord nr0 =
+ generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, false);
+ NotificationRecord nr1 =
+ generateNotificationRecord(mTestNotificationChannel, 1, originalGroupName, false);
+ mService.addNotification(nr0);
+ mService.addNotification(nr1);
+ mService.mSummaryByGroupKey.remove(nr0.getGroupKey());
+
+ // GroupHelper is a mock, so make the calls it would make
+ // Add aggregate group summary
+ NotificationAttributes attr = new NotificationAttributes(GroupHelper.BASE_FLAGS,
+ mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN,
+ nr0.getChannel().getId());
+ NotificationRecord aggregateSummary = mService.createAutoGroupSummary(nr0.getUserId(),
+ nr0.getSbn().getPackageName(), nr0.getKey(), aggregateGroupName, summaryId, attr);
+ mService.addNotification(aggregateSummary);
+ nr0.setOverrideGroupKey(aggregateGroupName);
+ nr1.setOverrideGroupKey(aggregateGroupName);
+ final String fullAggregateGroupKey = nr0.getGroupKey();
+
+ // Check that the aggregate group summary was created
+ assertThat(aggregateSummary.getNotification().getGroup()).isEqualTo(aggregateGroupName);
+ assertThat(aggregateSummary.getNotification().getChannelId()).isEqualTo(
+ nr0.getChannel().getId());
+ assertThat(mService.mSummaryByGroupKey.containsKey(fullAggregateGroupKey)).isTrue();
+
+ // Cancel both children
+ mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0.getSbn().getTag(),
+ nr0.getSbn().getId(), nr0.getSbn().getUserId());
+ mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr1.getSbn().getTag(),
+ nr1.getSbn().getId(), nr1.getSbn().getUserId());
+ waitForIdle();
+
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr0), any());
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr1), any());
+
+ // GroupHelper would send 'remove summary' event
+ mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName(),
+ fullAggregateGroupKey);
+ waitForIdle();
+
+ // Make sure the summary was removed and not re-posted
+ assertThat(mService.getNotificationRecordCount()).isEqualTo(0);
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+ public void testCancelGroupChildrenForCanceledSummary_singletonGroup() throws Exception {
+ final String originalGroupName = "originalGroup";
+ final String aggregateGroupName = "Aggregate_Test";
+ final int summaryId = Integer.MAX_VALUE;
+ // Add a "singleton group"
+ NotificationRecord nr0 =
+ generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, false);
+ NotificationRecord nr1 =
+ generateNotificationRecord(mTestNotificationChannel, 1, originalGroupName, false);
+ final NotificationRecord summary =
+ generateNotificationRecord(mTestNotificationChannel, 2, originalGroupName, true);
+ final String originalGroupKey = summary.getGroupKey();
+ mService.addNotification(nr0);
+ mService.addNotification(nr1);
+ mService.addNotification(summary);
+
+ // GroupHelper is a mock, so make the calls it would make
+ // Remove the app's summary notification
+ mService.removeAppSummaryLocked(summary.getKey());
+ waitForIdle();
+
+ // Add aggregate group summary
+ NotificationAttributes attr = new NotificationAttributes(GroupHelper.BASE_FLAGS,
+ mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN,
+ nr0.getChannel().getId());
+ NotificationRecord aggregateSummary = mService.createAutoGroupSummary(nr0.getUserId(),
+ nr0.getSbn().getPackageName(), nr0.getKey(), aggregateGroupName, summaryId, attr);
+ mService.addNotification(aggregateSummary);
+
+ nr0.setOverrideGroupKey(aggregateGroupName);
+ nr1.setOverrideGroupKey(aggregateGroupName);
+ final String fullAggregateGroupKey = nr0.getGroupKey();
+
+ assertThat(aggregateSummary.getNotification().getGroup()).isEqualTo(aggregateGroupName);
+ assertThat(aggregateSummary.getNotification().getChannelId()).isEqualTo(
+ nr0.getChannel().getId());
+ assertThat(mService.mSummaryByGroupKey.containsKey(fullAggregateGroupKey)).isTrue();
+ assertThat(mService.mSummaryByGroupKey.containsKey(originalGroupKey)).isFalse();
+
+ // Cancel the original app summary (is already removed)
+ mBinderService.cancelNotificationWithTag(summary.getSbn().getPackageName(),
+ summary.getSbn().getPackageName(), summary.getSbn().getTag(),
+ summary.getSbn().getId(), summary.getSbn().getUserId());
+ waitForIdle();
+
+ // Check if NMS.CancelNotificationRunnable calls maybeCancelGroupChildrenForCanceledSummary
+ verify(mGroupHelper, times(1)).maybeCancelGroupChildrenForCanceledSummary(
+ eq(summary.getSbn().getPackageName()), eq(summary.getSbn().getTag()),
+ eq(summary.getSbn().getId()), eq(summary.getSbn().getUserId()),
+ eq(REASON_APP_CANCEL));
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testUpdateChannel_notifyGroupHelper() throws Exception {
+ mService.setPreferencesHelper(mPreferencesHelper);
+ mTestNotificationChannel.setLightColor(Color.CYAN);
+ when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
+ eq(mTestNotificationChannel.getId()), anyBoolean()))
+ .thenReturn(mTestNotificationChannel);
+
+ mBinderService.updateNotificationChannelForPackage(mPkg, mUid, mTestNotificationChannel);
+ mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+ waitForIdle();
+
+ verify(mGroupHelper, times(1)).onChannelUpdated(eq(Process.myUserHandle().getIdentifier()),
+ eq(mPkg), eq(mTestNotificationChannel), any());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testSnoozeRunnable_snoozeAggregateGroupChild_summaryNotSnoozed() throws Exception {
+ final String aggregateGroupName = "Aggregate_Test";
+
+ // build autogroup summary notification
+ Notification.Builder nb = new Notification.Builder(mContext,
+ mTestNotificationChannel.getId())
+ .setContentTitle("foo")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .setGroup(aggregateGroupName)
+ .setGroupSummary(true)
+ .setFlag(Notification.FLAG_AUTOGROUP_SUMMARY, true);
+ StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
+ "tag" + System.currentTimeMillis(), mUid, 0, nb.build(),
+ UserHandle.getUserHandleForUid(mUid), null, 0);
+ final NotificationRecord summary = new NotificationRecord(mContext, sbn,
+ mTestNotificationChannel);
+
+ final NotificationRecord child = generateNotificationRecord(
+ mTestNotificationChannel, 2, aggregateGroupName, false);
+ mService.addNotification(summary);
+ mService.addNotification(child);
+ when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
+
+ // snooze child only
+ NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
+ mService.new SnoozeNotificationRunnable(
+ child.getKey(), 100, null);
+ snoozeNotificationRunnable.run();
+
+ // only child should be snoozed
+ verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
+
+ // both group summary and child should be cancelled
+ assertNull(mService.getNotificationRecord(summary.getKey()));
+ assertNull(mService.getNotificationRecord(child.getKey()));
+
+ assertEquals(4, mNotificationRecordLogger.numCalls());
+ assertEquals(NotificationRecordLogger.NotificationEvent.NOTIFICATION_SNOOZED,
+ mNotificationRecordLogger.event(0));
+ assertEquals(
+ NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_SNOOZED,
+ mNotificationRecordLogger.event(1));
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testOnlyForceGroupIfNeeded_newNotification_notAutogrouped() {
+ NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
+ when(mGroupHelper.onNotificationPosted(any(), anyBoolean())).thenReturn(false);
+ mService.addEnqueuedNotification(r);
+ NotificationManagerService.PostNotificationRunnable runnable =
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+ r.getUid(), mPostNotificationTrackerFactory.newTracker(null));
+ runnable.run();
+ waitForIdle();
+
+ mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+ waitForIdle();
+
+ verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
+ verify(mGroupHelper, times(1)).onNotificationPostedWithDelay(eq(r), any(), any());
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testOnlyForceGroupIfNeeded_newNotification_wasAutogrouped() {
+ NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
+ when(mGroupHelper.onNotificationPosted(any(), anyBoolean())).thenReturn(true);
+ mService.addEnqueuedNotification(r);
+ NotificationManagerService.PostNotificationRunnable runnable =
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+ r.getUid(), mPostNotificationTrackerFactory.newTracker(null));
+ runnable.run();
+ waitForIdle();
+
+ mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+ waitForIdle();
+
+ verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
+ verify(mGroupHelper, never()).onNotificationPostedWithDelay(eq(r), any(), any());
+ }
+
+ @Test
public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
when(mAmi.applyForegroundServiceNotification(
any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY);
@@ -3653,9 +3981,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
when(mPermissionHelper.isPermissionFixed(mPkg, temp.getUserId())).thenReturn(true);
+ NotificationAttributes attr = new NotificationAttributes(GroupHelper.BASE_FLAGS,
+ mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
+
NotificationRecord r = mService.createAutoGroupSummary(temp.getUserId(),
- temp.getSbn().getPackageName(), temp.getKey(), 0, mock(Icon.class), 0,
- VISIBILITY_PRIVATE);
+ temp.getSbn().getPackageName(), temp.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr);
assertThat(r.isImportanceFixed()).isTrue();
}
@@ -4796,6 +5126,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testSnoozeRunnable_snoozeAutoGroupChild_summaryNotSnoozed() throws Exception {
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 1, GroupHelper.AUTOGROUP_KEY, true);
@@ -5659,7 +5990,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testAddAutogroup_requestsSort() throws Exception {
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
mService.addNotification(r);
- mService.addAutogroupKeyLocked(r.getKey(), true);
+ mService.addAutogroupKeyLocked(r.getKey(), "grpKey", true);
verify(mRankingHandler, times(1)).requestSort();
}
@@ -5679,7 +6010,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
r.setOverrideGroupKey("TEST");
mService.addNotification(r);
- mService.addAutogroupKeyLocked(r.getKey(), true);
+ mService.addAutogroupKeyLocked(r.getKey(), "grpName", true);
verify(mRankingHandler, never()).requestSort();
}
@@ -5689,7 +6020,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testAutogroupSuppressSort_noSort() throws Exception {
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
mService.addNotification(r);
- mService.addAutogroupKeyLocked(r.getKey(), false);
+ mService.addAutogroupKeyLocked(r.getKey(), "grpName", false);
verify(mRankingHandler, never()).requestSort();
}
@@ -10771,8 +11102,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
BUBBLE_PREFERENCE_ALL /* app */,
true /* channel */);
- ArgumentCaptor<LauncherApps.Callback> launcherAppsCallback =
- ArgumentCaptor.forClass(LauncherApps.Callback.class);
+ ArgumentCaptor<LauncherApps.ShortcutChangeCallback> shortcutChangeCallback =
+ ArgumentCaptor.forClass(LauncherApps.ShortcutChangeCallback.class);
// Messaging notification with shortcut info
Notification.BubbleMetadata metadata =
@@ -10793,7 +11124,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Verify:
// Make sure we register the callback for shortcut changes
- verify(mLauncherApps, times(1)).registerCallback(launcherAppsCallback.capture(), any());
+ verify(mShortcutServiceInternal, times(1)).addShortcutChangeCallback(
+ shortcutChangeCallback.capture());
// yes allowed, yes messaging w/shortcut, yes bubble
Notification notif = mService.getNotificationRecord(nr.getSbn().getKey()).getNotification();
@@ -10806,14 +11138,17 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Test: Remove the shortcut
when(mLauncherApps.getShortcuts(any(), any())).thenReturn(null);
- launcherAppsCallback.getValue().onShortcutsChanged(mPkg, emptyList(),
+ ArrayList<ShortcutInfo> removedShortcuts = new ArrayList<>();
+ removedShortcuts.add(createMockConvoShortcut());
+ shortcutChangeCallback.getValue().onShortcutsRemoved(mPkg, removedShortcuts,
UserHandle.getUserHandleForUid(mUid));
waitForIdle();
// Verify:
// Make sure callback is unregistered
- verify(mLauncherApps, times(1)).unregisterCallback(launcherAppsCallback.getValue());
+ verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(
+ shortcutChangeCallback.getValue());
// We're no longer a bubble
NotificationRecord notif2 = mService.getNotificationRecord(
@@ -10831,8 +11166,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
BUBBLE_PREFERENCE_ALL /* app */,
true /* channel */);
- ArgumentCaptor<LauncherApps.Callback> launcherAppsCallback =
- ArgumentCaptor.forClass(LauncherApps.Callback.class);
+ ArgumentCaptor<LauncherApps.ShortcutChangeCallback> shortcutChangeCallback =
+ ArgumentCaptor.forClass(LauncherApps.ShortcutChangeCallback.class);
// Messaging notification with shortcut info
Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder(
@@ -10866,7 +11201,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Verify:
// Make sure we register the callback for shortcut changes
- verify(mLauncherApps, times(1)).registerCallback(launcherAppsCallback.capture(), any());
+ verify(mShortcutServiceInternal, times(1)).addShortcutChangeCallback(
+ shortcutChangeCallback.capture());
// yes allowed, yes messaging w/shortcut, yes bubble
Notification notif = mService.getNotificationRecord(nr.getSbn().getKey()).getNotification();
@@ -10885,7 +11221,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Verify:
// Make sure callback is unregistered
- verify(mLauncherApps, times(1)).unregisterCallback(launcherAppsCallback.getValue());
+ verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(
+ shortcutChangeCallback.getValue());
}
@Test
@@ -12688,6 +13025,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testUngroupingOngoingAutoSummary() throws Exception {
NotificationRecord nr0 =
generateNotificationRecord(mTestNotificationChannel, 0);
@@ -12701,10 +13039,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// grouphelper is a mock here, so make the calls it would make
// add summary
+ NotificationAttributes attr = new NotificationAttributes(
+ GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT, mock(Icon.class), 0,
+ VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
mService.addNotification(
mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
- nr1.getKey(), GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT, mock(Icon.class), 0,
- VISIBILITY_PRIVATE));
+ nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
// cancel both children
mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0.getSbn().getTag(),
@@ -12714,7 +13054,46 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
waitForIdle();
// group helper would send 'remove summary' event
- mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName());
+ mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName(),
+ AUTOGROUP_KEY);
+ waitForIdle();
+
+ // make sure the summary was removed and not re-posted
+ assertThat(mService.getNotificationRecordCount()).isEqualTo(0);
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testUngroupingOngoingAutoSummary_forceGrouping() throws Exception {
+ NotificationRecord nr0 =
+ generateNotificationRecord(mTestNotificationChannel, 0);
+ NotificationRecord nr1 =
+ generateNotificationRecord(mTestNotificationChannel, 0);
+ nr1.getSbn().getNotification().flags |= FLAG_ONGOING_EVENT;
+
+ mService.addNotification(nr0);
+ mService.addNotification(nr1);
+
+ // grouphelper is a mock here, so make the calls it would make
+
+ // add summary
+ NotificationAttributes attr = new NotificationAttributes(
+ GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT, mock(Icon.class), 0,
+ VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
+ mService.addNotification(
+ mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
+ nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
+
+ // cancel both children
+ mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0.getSbn().getTag(),
+ nr0.getSbn().getId(), nr0.getSbn().getUserId());
+ mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr1.getSbn().getTag(),
+ nr1.getSbn().getId(), nr1.getSbn().getUserId());
+ waitForIdle();
+
+ // group helper would send 'remove summary' event
+ mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName(),
+ AUTOGROUP_KEY);
waitForIdle();
// make sure the summary was removed and not re-posted
@@ -12722,6 +13101,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testUngroupingAutoSummary_differentUsers() throws Exception {
NotificationRecord nr0 =
generateNotificationRecord(mTestNotificationChannel, 0, USER_SYSTEM);
@@ -12729,11 +13109,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
generateNotificationRecord(mTestNotificationChannel, 1, USER_SYSTEM);
// add notifications + summary for USER_SYSTEM
+ NotificationAttributes attr = new NotificationAttributes(
+ GroupHelper.BASE_FLAGS, mock(Icon.class), 0,
+ VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
mService.addNotification(nr0);
mService.addNotification(nr1);
mService.addNotification(
mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
- nr1.getKey(), GroupHelper.BASE_FLAGS, mock(Icon.class), 0, VISIBILITY_PRIVATE));
+ nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
// add notifications + summary for USER_ALL
NotificationRecord nr0_all =
@@ -12746,7 +13129,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.addNotification(
mService.createAutoGroupSummary(nr0_all.getUserId(),
nr0_all.getSbn().getPackageName(),
- nr0_all.getKey(), GroupHelper.BASE_FLAGS, mock(Icon.class), 0, VISIBILITY_PRIVATE));
+ nr0_all.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
// cancel both children for USER_ALL
mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0_all.getSbn().getTag(),
@@ -12757,7 +13140,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// group helper would send 'remove summary' event
mService.clearAutogroupSummaryLocked(UserHandle.USER_ALL,
- nr0_all.getSbn().getPackageName());
+ nr0_all.getSbn().getPackageName(), AUTOGROUP_KEY);
waitForIdle();
// make sure the right summary was removed
@@ -12770,6 +13153,58 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void testUngroupingAutoSummary_differentUsers_forceGrouping() throws Exception {
+ NotificationRecord nr0 =
+ generateNotificationRecord(mTestNotificationChannel, 0, USER_SYSTEM);
+ NotificationRecord nr1 =
+ generateNotificationRecord(mTestNotificationChannel, 1, USER_SYSTEM);
+
+ // add notifications + summary for USER_SYSTEM
+ NotificationAttributes attr = new NotificationAttributes(
+ GroupHelper.BASE_FLAGS, mock(Icon.class), 0,
+ VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
+ mService.addNotification(nr0);
+ mService.addNotification(nr1);
+ mService.addNotification(
+ mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
+ nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
+
+ // add notifications + summary for USER_ALL
+ NotificationRecord nr0_all =
+ generateNotificationRecord(mTestNotificationChannel, 2, UserHandle.USER_ALL);
+ NotificationRecord nr1_all =
+ generateNotificationRecord(mTestNotificationChannel, 3, UserHandle.USER_ALL);
+
+ mService.addNotification(nr0_all);
+ mService.addNotification(nr1_all);
+ mService.addNotification(
+ mService.createAutoGroupSummary(nr0_all.getUserId(),
+ nr0_all.getSbn().getPackageName(),
+ nr0_all.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
+
+ // cancel both children for USER_ALL
+ mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0_all.getSbn().getTag(),
+ nr0_all.getSbn().getId(), UserHandle.USER_ALL);
+ mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr1_all.getSbn().getTag(),
+ nr1_all.getSbn().getId(), UserHandle.USER_ALL);
+ waitForIdle();
+
+ // group helper would send 'remove summary' event
+ mService.clearAutogroupSummaryLocked(UserHandle.USER_ALL,
+ nr0_all.getSbn().getPackageName(), AUTOGROUP_KEY);
+ waitForIdle();
+
+ // make sure the right summary was removed
+ assertThat(mService.getNotificationCount(nr0_all.getSbn().getPackageName(),
+ UserHandle.USER_ALL, 0, null)).isEqualTo(0);
+
+ // the USER_SYSTEM notifications + summary were not removed
+ assertThat(mService.getNotificationCount(nr0.getSbn().getPackageName(),
+ USER_SYSTEM, 0, null)).isEqualTo(3);
+ }
+
+ @Test
public void testStrongAuthTracker_isInLockDownMode() {
mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
@@ -15827,4 +16262,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID);
}
+
+ private ShortcutInfo createMockConvoShortcut() {
+ ShortcutInfo info = mock(ShortcutInfo.class);
+ when(info.getPackage()).thenReturn(mPkg);
+ when(info.getId()).thenReturn(VALID_CONVO_SHORTCUT_ID);
+ when(info.getUserId()).thenReturn(USER_SYSTEM);
+ when(info.isLongLived()).thenReturn(true);
+ when(info.isEnabled()).thenReturn(true);
+ return info;
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index ff4bc2158502..559c32413d70 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -120,6 +120,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionManager;
+import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
@@ -187,6 +188,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;
@SmallTest
@@ -488,6 +490,34 @@ public class PreferencesHelperTest extends UiServiceTestCase {
when(mPm.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid);
}
+ private static void testThreadSafety(Runnable operationToTest, int nThreads,
+ int nRunsPerThread) throws Exception {
+ final CountDownLatch startLatch = new CountDownLatch(1);
+ final CountDownLatch doneLatch = new CountDownLatch(nThreads);
+
+ for (int i = 0; i < nThreads; i++) {
+ Runnable threadRunnable = () -> {
+ try {
+ startLatch.await();
+ for (int j = 0; j < nRunsPerThread; j++) {
+ operationToTest.run();
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } finally {
+ doneLatch.countDown();
+ }
+ };
+ new Thread(threadRunnable, "Test Thread #" + i).start();
+ }
+
+ // Ready set go
+ startLatch.countDown();
+
+ // Wait for all test threads to be done.
+ doneLatch.await();
+ }
+
@Test
public void testWriteXml_onlyBackupsTargetUser() throws Exception {
// Setup package notifications.
@@ -2127,6 +2157,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_CLASSIFICATION)
public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
@@ -2907,6 +2938,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_CLASSIFICATION)
public void testOnlyHasDefaultChannel() throws Exception {
assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O));
@@ -3317,9 +3349,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
assertEquals(3, actual.size());
for (NotificationChannelGroup group : actual) {
if (group.getId() == null) {
- assertEquals(
- notificationClassification() ? 6 : 2,
- group.getChannels().size()); // misc channel too
+ assertEquals(2, group.getChannels().size());
assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
|| channel3.getId().equals(group.getChannels().get(1).getId()));
} else if (group.getId().equals(ncg.getId())) {
@@ -6192,6 +6222,36 @@ public class PreferencesHelperTest extends UiServiceTestCase {
.isEqualTo(IMPORTANCE_LOW);
}
+
+ @Test
+ public void testRestoredWithoutUid_threadSafety() throws Exception {
+ when(mPm.getPackageUidAsUser(anyString(), anyInt())).thenReturn(UNKNOWN_UID);
+ when(mPm.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())).thenThrow(
+ new PackageManager.NameNotFoundException());
+ when(mClock.millis()).thenReturn(System.currentTimeMillis());
+ testThreadSafety(() -> {
+ String id = "id";
+ String xml = "<ranking version=\"1\">\n"
+ + "<package name=\"" + Thread.currentThread()+ "\" show_badge=\"true\">\n"
+ + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
+ + "show_badge=\"true\" />\n"
+ + "</package>\n"
+ + "<package name=\"" + PKG_P + "\" show_badge=\"true\">\n"
+ + "</package>\n"
+ + "</ranking>\n";
+
+ try {
+ loadByteArrayXml(xml.getBytes(), true, USER_SYSTEM);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ // trigger a removal from the list
+ mXmlHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_P},
+ new int[]{UNKNOWN_UID});
+ }, 20, 50);
+ }
+
private static NotificationChannel cloneChannel(NotificationChannel original) {
Parcel parcel = Parcel.obtain();
try {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
index a4fb16dc1adc..f008cb671e78 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
@@ -22,17 +22,22 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.PendingIntent;
import android.app.Person;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps.ShortcutQuery;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutQueryWrapper;
import android.content.pm.ShortcutServiceInternal;
+import android.graphics.drawable.Icon;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.notification.StatusBarNotification;
@@ -50,11 +55,9 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
@SmallTest
@@ -64,7 +67,6 @@ public class ShortcutHelperTest extends UiServiceTestCase {
private static final String SHORTCUT_ID = "shortcut";
private static final String PKG = "pkg";
- private static final String KEY = "key";
private static final Person PERSON = mock(Person.class);
@Mock
@@ -75,19 +77,11 @@ public class ShortcutHelperTest extends UiServiceTestCase {
UserManager mUserManager;
@Mock
ShortcutServiceInternal mShortcutServiceInternal;
- @Mock
- NotificationRecord mNr;
- @Mock
- Notification mNotif;
- @Mock
- StatusBarNotification mSbn;
- @Mock
- Notification.BubbleMetadata mBubbleMetadata;
- @Mock
- ShortcutInfo mShortcutInfo;
@Captor private ArgumentCaptor<ShortcutQuery> mShortcutQueryCaptor;
+ NotificationRecord mNr;
+
ShortcutHelper mShortcutHelper;
@Before
@@ -96,137 +90,186 @@ public class ShortcutHelperTest extends UiServiceTestCase {
mShortcutHelper = new ShortcutHelper(
mLauncherApps, mShortcutListener, mShortcutServiceInternal, mUserManager);
- when(mSbn.getPackageName()).thenReturn(PKG);
- when(mShortcutInfo.getId()).thenReturn(SHORTCUT_ID);
- when(mNotif.getBubbleMetadata()).thenReturn(mBubbleMetadata);
- when(mBubbleMetadata.getShortcutId()).thenReturn(SHORTCUT_ID);
when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true);
- setUpMockNotificationRecord(mNr, KEY);
+ mNr = setUpNotificationRecord(SHORTCUT_ID, PKG, UserHandle.of(UserHandle.USER_SYSTEM));
}
- private void setUpMockNotificationRecord(NotificationRecord mockRecord, String key) {
- when(mockRecord.getKey()).thenReturn(key);
- when(mockRecord.getSbn()).thenReturn(mSbn);
- when(mockRecord.getNotification()).thenReturn(mNotif);
- when(mockRecord.getShortcutInfo()).thenReturn(mShortcutInfo);
+ private NotificationRecord setUpNotificationRecord(String shortcutId,
+ String pkg,
+ UserHandle user) {
+ ShortcutInfo shortcutInfo = mock(ShortcutInfo.class);
+ when(shortcutInfo.getId()).thenReturn(shortcutId);
+ when(shortcutInfo.getUserHandle()).thenReturn(user);
+ when(shortcutInfo.isLongLived()).thenReturn(true);
+
+ Notification notification = new Notification.Builder(getContext())
+ .setContentTitle("title")
+ .setShortcutId(shortcutId)
+ .setBubbleMetadata(new Notification.BubbleMetadata.Builder(shortcutId).build())
+ .build();
+
+ StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, 0, null,
+ 1000, 2000, notification, user, null, System.currentTimeMillis());
+ NotificationRecord record = new NotificationRecord(mContext, sbn,
+ mock(NotificationChannel.class));
+ record.setShortcutInfo(shortcutInfo);
+ return record;
}
- private LauncherApps.Callback addShortcutBubbleAndVerifyListener() {
- mShortcutHelper.maybeListenForShortcutChangesForBubbles(mNr,
- false /* removed */,
- null /* handler */);
+ private LauncherApps.ShortcutChangeCallback addShortcutBubbleAndVerifyListener(
+ NotificationRecord record) {
+ mShortcutHelper.maybeListenForShortcutChangesForBubbles(record, false /* removed */);
- ArgumentCaptor<LauncherApps.Callback> launcherAppsCallback =
- ArgumentCaptor.forClass(LauncherApps.Callback.class);
+ ArgumentCaptor<LauncherApps.ShortcutChangeCallback> launcherAppsCallback =
+ ArgumentCaptor.forClass(LauncherApps.ShortcutChangeCallback.class);
- verify(mLauncherApps, times(1)).registerCallback(
- launcherAppsCallback.capture(), any());
+ verify(mShortcutServiceInternal, times(1)).addShortcutChangeCallback(
+ launcherAppsCallback.capture());
return launcherAppsCallback.getValue();
}
@Test
public void testBubbleAdded_listenedAdded() {
- addShortcutBubbleAndVerifyListener();
+ addShortcutBubbleAndVerifyListener(mNr);
}
@Test
+ public void testListenerNotifiedOnShortcutRemoved() {
+ LauncherApps.ShortcutChangeCallback callback = addShortcutBubbleAndVerifyListener(mNr);
+
+ List<ShortcutInfo> removedShortcuts = new ArrayList<>();
+ removedShortcuts.add(mNr.getShortcutInfo());
+
+ callback.onShortcutsRemoved(PKG, removedShortcuts, mNr.getUser());
+ verify(mShortcutListener).onShortcutRemoved(mNr.getKey());
+ }
+
+ @Test
+ public void testListenerNotNotified_notMatchingPackage() {
+ LauncherApps.ShortcutChangeCallback callback = addShortcutBubbleAndVerifyListener(mNr);
+
+ List<ShortcutInfo> removedShortcuts = new ArrayList<>();
+ removedShortcuts.add(mNr.getShortcutInfo());
+
+ callback.onShortcutsRemoved("differentPackage", removedShortcuts, mNr.getUser());
+ verify(mShortcutListener, never()).onShortcutRemoved(anyString());
+ }
+
+ @Test
+ public void testListenerNotNotified_notMatchingUser() {
+ LauncherApps.ShortcutChangeCallback callback = addShortcutBubbleAndVerifyListener(mNr);
+
+ List<ShortcutInfo> removedShortcuts = new ArrayList<>();
+ removedShortcuts.add(mNr.getShortcutInfo());
+
+ callback.onShortcutsRemoved(PKG, removedShortcuts, UserHandle.of(10));
+ verify(mShortcutListener, never()).onShortcutRemoved(anyString());
+ }
+
+ @Test
+ public void testListenerNotifiedDifferentUser() {
+ LauncherApps.ShortcutChangeCallback callback = addShortcutBubbleAndVerifyListener(mNr);
+ NotificationRecord diffUserRecord = setUpNotificationRecord(SHORTCUT_ID, PKG,
+ UserHandle.of(10));
+ mShortcutHelper.maybeListenForShortcutChangesForBubbles(diffUserRecord,
+ false /* removed */);
+
+ List<ShortcutInfo> removedShortcuts = new ArrayList<>();
+ removedShortcuts.add(mNr.getShortcutInfo());
+
+ callback.onShortcutsRemoved(PKG, removedShortcuts, mNr.getUser());
+ verify(mShortcutListener).onShortcutRemoved(mNr.getKey());
+
+ reset(mShortcutListener);
+ removedShortcuts.clear();
+ removedShortcuts.add(diffUserRecord.getShortcutInfo());
+
+ callback.onShortcutsRemoved(PKG, removedShortcuts, diffUserRecord.getUser());
+ verify(mShortcutListener).onShortcutRemoved(diffUserRecord.getKey());
+ }
+
+
+ @Test
public void testBubbleRemoved_listenerRemoved() {
// First set it up to listen
- addShortcutBubbleAndVerifyListener();
+ addShortcutBubbleAndVerifyListener(mNr);
// Then remove the notif
mShortcutHelper.maybeListenForShortcutChangesForBubbles(mNr,
- true /* removed */,
- null /* handler */);
+ true /* removed */);
- verify(mLauncherApps, times(1)).unregisterCallback(any());
+ verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(any());
}
@Test
public void testBubbleNoLongerHasBubbleMetadata_listenerRemoved() {
// First set it up to listen
- addShortcutBubbleAndVerifyListener();
+ addShortcutBubbleAndVerifyListener(mNr);
// Then make it not a bubble
- when(mNotif.getBubbleMetadata()).thenReturn(null);
+ mNr.getNotification().setBubbleMetadata(null);
mShortcutHelper.maybeListenForShortcutChangesForBubbles(mNr,
- false /* removed */,
- null /* handler */);
+ false /* removed */);
- verify(mLauncherApps, times(1)).unregisterCallback(any());
+ verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(any());
}
@Test
public void testBubbleNoLongerHasShortcutId_listenerRemoved() {
// First set it up to listen
- addShortcutBubbleAndVerifyListener();
+ addShortcutBubbleAndVerifyListener(mNr);
// Clear out shortcutId
- when(mBubbleMetadata.getShortcutId()).thenReturn(null);
+ mNr.getNotification().setBubbleMetadata(new Notification.BubbleMetadata.Builder(
+ mock(PendingIntent.class), mock(Icon.class)).build());
mShortcutHelper.maybeListenForShortcutChangesForBubbles(mNr,
- false /* removed */,
- null /* handler */);
+ false /* removed */);
- verify(mLauncherApps, times(1)).unregisterCallback(any());
+ verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(any());
}
@Test
public void testNotifNoLongerHasShortcut_listenerRemoved() {
// First set it up to listen
- addShortcutBubbleAndVerifyListener();
-
- NotificationRecord validMock1 = Mockito.mock(NotificationRecord.class);
- setUpMockNotificationRecord(validMock1, "KEY1");
-
- NotificationRecord validMock2 = Mockito.mock(NotificationRecord.class);
- setUpMockNotificationRecord(validMock2, "KEY2");
+ addShortcutBubbleAndVerifyListener(mNr);
- NotificationRecord validMock3 = Mockito.mock(NotificationRecord.class);
- setUpMockNotificationRecord(validMock3, "KEY3");
+ NotificationRecord record1 = setUpNotificationRecord(SHORTCUT_ID, PKG,
+ UserHandle.of(UserHandle.USER_SYSTEM));
+ NotificationRecord record2 = setUpNotificationRecord(SHORTCUT_ID, PKG,
+ UserHandle.of(UserHandle.USER_SYSTEM));
+ NotificationRecord record3 = setUpNotificationRecord(SHORTCUT_ID, PKG,
+ UserHandle.of(UserHandle.USER_SYSTEM));
- mShortcutHelper.maybeListenForShortcutChangesForBubbles(validMock1,
- false /* removed */,
- null /* handler */);
+ mShortcutHelper.maybeListenForShortcutChangesForBubbles(record1,
+ false /* removed */);
- mShortcutHelper.maybeListenForShortcutChangesForBubbles(validMock2,
- false /* removed */,
- null /* handler */);
+ mShortcutHelper.maybeListenForShortcutChangesForBubbles(record2,
+ false /* removed */);
- mShortcutHelper.maybeListenForShortcutChangesForBubbles(validMock3,
- false /* removed */,
- null /* handler */);
+ mShortcutHelper.maybeListenForShortcutChangesForBubbles(record3,
+ false /* removed */);
- // Clear out shortcutId of the bubble in the middle, to double check that we don't hit a
+ // Clear out shortcutId of the bubble in the middle, to double-check that we don't hit a
// concurrent modification exception (removing the last bubble would sidestep that check).
- when(validMock2.getShortcutInfo()).thenReturn(null);
- mShortcutHelper.maybeListenForShortcutChangesForBubbles(validMock2,
- false /* removed */,
- null /* handler */);
+ record2.setShortcutInfo(null);
+ mShortcutHelper.maybeListenForShortcutChangesForBubbles(record2,
+ false /* removed */);
- verify(mLauncherApps, times(1)).unregisterCallback(any());
+ verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(any());
}
@Test
public void testOnShortcutsChanged_listenerRemoved() {
// First set it up to listen
- LauncherApps.Callback callback = addShortcutBubbleAndVerifyListener();
+ LauncherApps.ShortcutChangeCallback callback = addShortcutBubbleAndVerifyListener(mNr);
// App shortcuts are removed:
- callback.onShortcutsChanged(PKG, Collections.emptyList(), mock(UserHandle.class));
+ List<ShortcutInfo> removedShortcuts = new ArrayList<>();
+ removedShortcuts.add(mNr.getShortcutInfo());
+ callback.onShortcutsRemoved(PKG, removedShortcuts, mNr.getUser());
- verify(mLauncherApps, times(1)).unregisterCallback(any());
- }
-
- @Test
- public void testListenerNotifiedOnShortcutRemoved() {
- LauncherApps.Callback callback = addShortcutBubbleAndVerifyListener();
-
- List<ShortcutInfo> shortcutInfos = new ArrayList<>();
- when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos);
-
- callback.onShortcutsChanged(PKG, shortcutInfos, mock(UserHandle.class));
- verify(mShortcutListener).onShortcutRemoved(mNr.getKey());
+ verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(any());
}
@Test
@@ -321,7 +364,6 @@ public class ShortcutHelperTest extends UiServiceTestCase {
.isSameInstanceAs(si);
}
-
@Test
public void testGetValidShortcutInfo_isValidButUserLocked() {
ShortcutInfo si = mock(ShortcutInfo.class);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/TimeToLiveHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/TimeToLiveHelperTest.java
index 8b46c8c409d4..ad6c233789e9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/TimeToLiveHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/TimeToLiveHelperTest.java
@@ -29,6 +29,8 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.content.Intent;
+import android.net.Uri;
import android.os.SystemClock;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
@@ -36,6 +38,7 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.UiServiceTestCase;
+import com.android.server.pm.PackageManagerService;
import org.junit.After;
import org.junit.Before;
@@ -125,6 +128,50 @@ public class TimeToLiveHelperTest extends UiServiceTestCase {
}
@Test
+ public void testTimeoutExpires_notifAlreadyCanceled() {
+ NotificationRecord r = getRecord("testTimeoutExpires", 1);
+
+ mHelper.scheduleTimeoutLocked(r, 1);
+ mHelper.cancelScheduledTimeoutLocked(r);
+
+ Intent intent = new Intent("com.android.server.notification.TimeToLiveHelper")
+ .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
+ .setData(new Uri.Builder()
+ .scheme("timeout")
+ .appendPath(r.getKey())
+ .build())
+ .putExtra(EXTRA_KEY, r.getKey())
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+
+ mHelper.mNotificationTimeoutReceiver.onReceive(mContext, intent);
+
+ assertThat(mHelper.mKeys).isEmpty();
+ }
+
+ @Test
+ public void testTimeoutExpires_laterNotifAlreadyCanceled() {
+ NotificationRecord r = getRecord("testTimeoutExpires", 1);
+ NotificationRecord r2 = getRecord("testTimeoutExpires", 2);
+
+ mHelper.scheduleTimeoutLocked(r, 1);
+ mHelper.scheduleTimeoutLocked(r2, 2);
+ mHelper.cancelScheduledTimeoutLocked(r2);
+
+ Intent intent = new Intent("com.android.server.notification.TimeToLiveHelper")
+ .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
+ .setData(new Uri.Builder()
+ .scheme("timeout")
+ .appendPath(r2.getKey())
+ .build())
+ .putExtra(EXTRA_KEY, r2.getKey())
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+
+ mHelper.mNotificationTimeoutReceiver.onReceive(mContext, intent);
+
+ assertThat(mHelper.mKeys).isEmpty();
+ }
+
+ @Test
public void testTimeout_earlierEntryAddedSecond() {
NotificationRecord later = getRecord("testTimeoutSecond", 2);
mHelper.scheduleTimeoutLocked(later, 1);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index f5ab95c1ab4c..f7340abcaeca 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -18,8 +18,10 @@ package com.android.server.notification;
import static android.app.AutomaticZenRule.TYPE_BEDTIME;
import static android.app.Flags.FLAG_MODES_UI;
+import static android.app.Flags.modesUi;
import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
import static android.provider.Settings.Global.ZEN_MODE_OFF;
+import static android.service.notification.Condition.SOURCE_UNKNOWN;
import static android.service.notification.Condition.SOURCE_USER_ACTION;
import static android.service.notification.Condition.STATE_FALSE;
import static android.service.notification.Condition.STATE_TRUE;
@@ -36,10 +38,18 @@ import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import android.app.AutomaticZenRule;
import android.app.Flags;
import android.app.NotificationManager.Policy;
import android.content.ComponentName;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Parcel;
import android.platform.test.annotations.DisableFlags;
@@ -66,6 +76,8 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.xmlpull.v1.XmlPullParserException;
import java.io.BufferedInputStream;
@@ -102,6 +114,9 @@ public class ZenModeConfigTest extends UiServiceTestCase {
private final boolean ENABLED = true;
private final int CREATION_TIME = 123;
+ @Mock
+ PackageManager mPm;
+
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(
SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);
@@ -119,6 +134,8 @@ public class ZenModeConfigTest extends UiServiceTestCase {
@Before
public final void setUp() {
mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API);
+ MockitoAnnotations.initMocks(this);
+ mContext.setMockPackageManager(mPm);
}
@Test
@@ -967,6 +984,85 @@ public class ZenModeConfigTest extends UiServiceTestCase {
assertThat(fromXml.zenPolicy).isEqualTo(config.getZenPolicy());
}
+ @Test
+ public void testGetDescription_off() {
+ ZenModeConfig config = new ZenModeConfig();
+ if (!modesUi()) {
+ config.manualRule = new ZenModeConfig.ZenRule();
+ }
+ config.manualRule.pkg = "android";
+ assertThat(ZenModeConfig.getDescription(mContext, true, config, false)).isNull();
+ }
+
+ @Test
+ public void testGetDescription_on_manual_endTime() {
+ ZenModeConfig config = new ZenModeConfig();
+ if (!modesUi()) {
+ config.manualRule = new ZenModeConfig.ZenRule();
+ }
+ config.manualRule.conditionId = ZenModeConfig.toCountdownConditionId(
+ System.currentTimeMillis() + 10000, false);
+ config.manualRule.pkg = "android";
+ config.manualRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ config.manualRule.condition = new Condition(Uri.EMPTY, "", STATE_TRUE, SOURCE_UNKNOWN);
+ assertThat(ZenModeConfig.getDescription(mContext, true, config, false))
+ .startsWith("Until");
+ }
+
+ @Test
+ public void getSoundSummary_on_manual_noEnd() {
+ ZenModeConfig config = new ZenModeConfig();
+ if (!modesUi()) {
+ config.manualRule = new ZenModeConfig.ZenRule();
+ }
+ config.manualRule.conditionId = Uri.EMPTY;
+ config.manualRule.pkg = "android";
+ config.manualRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ config.manualRule.condition = new Condition(Uri.EMPTY, "", STATE_TRUE, SOURCE_UNKNOWN);
+ assertThat(ZenModeConfig.getDescription(mContext, true, config, false)).isNull();
+ }
+
+ @Test
+ public void getSoundSummary_on_manual_enabler() throws Exception {
+ ApplicationInfo ai = mock(ApplicationInfo.class);
+ when(ai.loadLabel(any())).thenReturn("app name");
+ when(mPm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
+
+ ZenModeConfig config = new ZenModeConfig();
+ if (!modesUi()) {
+ config.manualRule = new ZenModeConfig.ZenRule();
+ }
+ config.manualRule.conditionId = Uri.EMPTY;
+ config.manualRule.pkg = "android";
+ config.manualRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ config.manualRule.enabler = "app";
+ config.manualRule.condition = new Condition(Uri.EMPTY, "", STATE_TRUE, SOURCE_UNKNOWN);
+ assertThat(ZenModeConfig.getDescription(mContext, true, config, false))
+ .isEqualTo("app name");
+ }
+
+ @Test
+ public void testGetDescription_on_automatic() {
+ ZenModeConfig config = new ZenModeConfig();
+ ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
+ rule.configurationActivity = new ComponentName("a", "a");
+ rule.component = new ComponentName("b", "b");
+ rule.conditionId = new Uri.Builder().scheme("hello").build();
+ rule.condition = new Condition(rule.conditionId, "", Condition.STATE_TRUE);
+ rule.enabled = true;
+ rule.creationTime = 123;
+ rule.id = "id";
+ rule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ rule.modified = true;
+ rule.name = "name";
+ rule.snoozing = false;
+ rule.pkg = "b";
+ config.automaticRules.put("key", rule);
+
+ assertThat(ZenModeConfig.getDescription(mContext, true, config, false))
+ .isEqualTo("name");
+ }
+
private ZenModeConfig getMutedRingerConfig() {
ZenModeConfig config = new ZenModeConfig();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java
index ff1308c4f6db..1c8cb8f90f1e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java
@@ -137,4 +137,9 @@ public class ZenModeEventLoggerFake extends ZenModeEventLogger {
checkInRange(i);
return mChanges.get(i).getActiveRuleTypes();
}
+
+ public int getChangeOrigin(int i) throws IllegalArgumentException {
+ checkInRange(i);
+ return mChanges.get(i).getChangeOrigin();
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 7bb633e6e1e0..4bbbc2b28dad 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -818,7 +818,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// 1. Current ringer is normal
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
// Set zen to priority-only with all notification sounds muted (so ringer will be muted)
- Policy totalSilence = new Policy(0,0,0);
+ Policy totalSilence = new Policy(0, 0, 0);
mZenModeHelper.setNotificationPolicy(totalSilence, UPDATE_ORIGIN_APP, 1);
mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
@@ -873,7 +873,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// even when ringer is muted (since all ringer sounds cannot bypass DND),
// system stream is still affected by ringer mode
- mZenModeHelper.setNotificationPolicy(new Policy(0,0,0), UPDATE_ORIGIN_APP, 1);
+ mZenModeHelper.setNotificationPolicy(new Policy(0, 0, 0), UPDATE_ORIGIN_APP, 1);
mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, Uri.EMPTY,
UPDATE_ORIGIN_APP, "test", "caller", 1);
ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerNotMuted =
@@ -1065,9 +1065,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
@Test
public void testParcelConfig() {
mZenModeHelper.setNotificationPolicy(new Policy(PRIORITY_CATEGORY_EVENTS
- | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_REPEAT_CALLERS
- | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_STARRED,
- PRIORITY_SENDERS_STARRED, 0, CONVERSATION_SENDERS_ANYONE), UPDATE_ORIGIN_UNKNOWN,
+ | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_REPEAT_CALLERS
+ | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_STARRED,
+ PRIORITY_SENDERS_STARRED, 0, CONVERSATION_SENDERS_ANYONE),
+ UPDATE_ORIGIN_UNKNOWN,
1);
mZenModeHelper.setManualZenRuleDeviceEffects(new ZenDeviceEffects.Builder()
.setShouldDimWallpaper(true)
@@ -1085,13 +1086,14 @@ public class ZenModeHelperTest extends UiServiceTestCase {
@Test
public void testWriteXml() throws Exception {
mZenModeHelper.setNotificationPolicy(new Policy(PRIORITY_CATEGORY_EVENTS
- | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_REPEAT_CALLERS
- | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_STARRED,
- PRIORITY_SENDERS_STARRED, SUPPRESSED_EFFECT_BADGE, CONVERSATION_SENDERS_ANYONE),
+ | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_REPEAT_CALLERS
+ | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_STARRED,
+ PRIORITY_SENDERS_STARRED, SUPPRESSED_EFFECT_BADGE,
+ CONVERSATION_SENDERS_ANYONE),
UPDATE_ORIGIN_UNKNOWN, 1);
mZenModeHelper.setManualZenRuleDeviceEffects(new ZenDeviceEffects.Builder()
- .setShouldDimWallpaper(true)
- .setShouldDisplayGrayscale(true)
+ .setShouldDimWallpaper(true)
+ .setShouldDisplayGrayscale(true)
.build(), UPDATE_ORIGIN_UNKNOWN, "test", 1);
mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, Uri.EMPTY,
UPDATE_ORIGIN_UNKNOWN, "test", "me", 1);
@@ -2210,7 +2212,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
customDefaultRule.name = "Schedule Default Rule";
customDefaultRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
ScheduleInfo scheduleInfo = new ScheduleInfo();
- scheduleInfo.days = new int[] { Calendar.SUNDAY };
+ scheduleInfo.days = new int[]{Calendar.SUNDAY};
scheduleInfo.startHour = 18;
scheduleInfo.endHour = 19;
customDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(scheduleInfo);
@@ -3027,7 +3029,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// Turn zen mode on (to important_interruptions)
// Need to additionally call the looper in order to finish the post-apply-config process
mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
- Flags.modesApi() ? UPDATE_ORIGIN_USER: UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null,
+ Flags.modesApi() ? UPDATE_ORIGIN_USER : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null,
Process.SYSTEM_UID);
// Now turn zen mode off, but via a different package UID -- this should get registered as
@@ -3060,6 +3062,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertTrue(mZenModeEventLogger.getIsUserAction(0));
assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(0));
checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
+ // change origin should be populated only under modes_ui
+ assertThat(mZenModeEventLogger.getChangeOrigin(0)).isEqualTo(
+ (Flags.modesApi() && Flags.modesUi()) ? UPDATE_ORIGIN_USER : 0);
// and from turning zen mode off:
// - event ID: DND_TURNED_OFF
@@ -3082,6 +3087,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
} else {
checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
}
+ assertThat(mZenModeEventLogger.getChangeOrigin(1)).isEqualTo(
+ Flags.modesUi() ? UPDATE_ORIGIN_APP : 0);
}
@Test
@@ -3098,17 +3105,21 @@ public class ZenModeHelperTest extends UiServiceTestCase {
null,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
- UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
+ UPDATE_ORIGIN_APP, "test", CUSTOM_PKG_UID);
// Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE
+ // Note that pre-modes_ui, this event serves as a test that automatic changes to an app's
+ // that look like they're coming from the system are attributed to the app, but when
+ // modes_ui is true, we opt to trust the provided change origin.
mZenModeHelper.setAutomaticZenRuleState(id,
new Condition(zenRule.getConditionId(), "", STATE_TRUE),
- UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
+ Flags.modesUi() ? UPDATE_ORIGIN_APP : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+ CUSTOM_PKG_UID);
// Event 2: "User" turns off the automatic rule (sets it to not enabled)
zenRule.setEnabled(false);
mZenModeHelper.updateAutomaticZenRule(id, zenRule,
- Flags.modesApi() ? UPDATE_ORIGIN_USER: UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
+ Flags.modesApi() ? UPDATE_ORIGIN_USER : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
Process.SYSTEM_UID);
AutomaticZenRule systemRule = new AutomaticZenRule("systemRule",
@@ -3118,7 +3129,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
null,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
String systemId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), systemRule,
- Flags.modesApi() ? UPDATE_ORIGIN_USER: UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test",
+ Flags.modesApi() ? UPDATE_ORIGIN_USER : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test",
Process.SYSTEM_UID);
// Event 3: turn on the system rule
@@ -3128,7 +3139,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// Event 4: "User" deletes the rule
mZenModeHelper.removeAutomaticZenRule(systemId,
- Flags.modesApi() ? UPDATE_ORIGIN_USER: UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
+ Flags.modesApi() ? UPDATE_ORIGIN_USER : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
Process.SYSTEM_UID);
// In total, this represents 4 events
assertEquals(4, mZenModeEventLogger.numLoggedChanges());
@@ -3151,9 +3162,13 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertFalse(mZenModeEventLogger.getIsUserAction(0));
assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
checkDndProtoMatchesDefaultZenConfig(mZenModeEventLogger.getPolicyProto(0));
+ assertThat(mZenModeEventLogger.getChangeOrigin(0)).isEqualTo(
+ Flags.modesUi() ? UPDATE_ORIGIN_APP : 0);
// When the automatic rule is disabled, this should turn off zen mode and also count as a
// user action. We don't care what the consolidated policy is when DND turns off.
+ // When modes_ui is true, this event should look like a user action attributed to the
+ // specific app.
assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
mZenModeEventLogger.getEventId(1));
assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getPrevZenMode(1));
@@ -3161,12 +3176,15 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(1));
assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
assertTrue(mZenModeEventLogger.getIsUserAction(1));
- assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
+ assertThat(mZenModeEventLogger.getPackageUid(1)).isEqualTo(
+ Flags.modesUi() ? CUSTOM_PKG_UID : Process.SYSTEM_UID);
if (Flags.modesApi()) {
assertThat(mZenModeEventLogger.getPolicyProto(1)).isNull();
} else {
checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
}
+ assertThat(mZenModeEventLogger.getChangeOrigin(1)).isEqualTo(
+ Flags.modesUi() ? UPDATE_ORIGIN_USER : 0);
// When the system rule is enabled, this counts as an automatic action that comes from the
// system and turns on DND
@@ -3176,6 +3194,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertEquals(1, mZenModeEventLogger.getNumRulesActive(2));
assertFalse(mZenModeEventLogger.getIsUserAction(2));
assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
+ assertThat(mZenModeEventLogger.getChangeOrigin(2)).isEqualTo(
+ Flags.modesUi() ? UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI : 0);
// When the system rule is deleted, we consider this a user action that turns DND off
// (again)
@@ -3185,6 +3205,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertEquals(0, mZenModeEventLogger.getNumRulesActive(3));
assertTrue(mZenModeEventLogger.getIsUserAction(3));
assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(3));
+ assertThat(mZenModeEventLogger.getChangeOrigin(3)).isEqualTo(
+ Flags.modesUi() ? UPDATE_ORIGIN_USER : 0);
}
@Test
@@ -3238,6 +3260,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
assertTrue(mZenModeEventLogger.getIsUserAction(0));
assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
+ assertThat(mZenModeEventLogger.getChangeOrigin(0)).isEqualTo(
+ Flags.modesUi() ? UPDATE_ORIGIN_USER : 0);
// Automatic rule turned off automatically by app:
// - event ID: DND_TURNED_OFF
@@ -3249,6 +3273,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
assertFalse(mZenModeEventLogger.getIsUserAction(1));
assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1));
+ assertThat(mZenModeEventLogger.getChangeOrigin(1)).isEqualTo(
+ Flags.modesUi() ? UPDATE_ORIGIN_APP : 0);
// Automatic rule turned on automatically by app:
// - event ID: DND_TURNED_ON
@@ -3261,6 +3287,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertEquals(1, mZenModeEventLogger.getNumRulesActive(2));
assertFalse(mZenModeEventLogger.getIsUserAction(2));
assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(2));
+ assertThat(mZenModeEventLogger.getChangeOrigin(2)).isEqualTo(
+ Flags.modesUi() ? UPDATE_ORIGIN_APP : 0);
// Automatic rule turned off automatically by the user:
// - event ID: DND_TURNED_ON
@@ -3272,6 +3300,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertEquals(0, mZenModeEventLogger.getNumRulesActive(3));
assertTrue(mZenModeEventLogger.getIsUserAction(3));
assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(3));
+ assertThat(mZenModeEventLogger.getChangeOrigin(3)).isEqualTo(
+ Flags.modesUi() ? UPDATE_ORIGIN_USER : 0);
}
@Test
@@ -3335,7 +3365,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
AutomaticZenRule zenRule = new AutomaticZenRule("name",
null,
- new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
+ new ComponentName("android", "ScheduleConditionProvider"),
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
null,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
@@ -3345,7 +3375,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// Rule 2, same as rule 1
AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
null,
- new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
+ new ComponentName("android", "ScheduleConditionProvider"),
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
null,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
@@ -3395,7 +3425,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
assertFalse(mZenModeEventLogger.getIsUserAction(0));
- assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
+ assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(0));
checkDndProtoMatchesDefaultZenConfig(mZenModeEventLogger.getPolicyProto(0));
// Event 2: rule 2 turns on. This should not change anything about the policy, so the only
@@ -3404,7 +3434,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
mZenModeEventLogger.getEventId(1));
assertEquals(2, mZenModeEventLogger.getNumRulesActive(1));
assertFalse(mZenModeEventLogger.getIsUserAction(1));
- assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1));
+ assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
checkDndProtoMatchesDefaultZenConfig(mZenModeEventLogger.getPolicyProto(1));
// Event 3: rule 3 turns on. This should trigger a policy change, and be classified as such,
@@ -3482,9 +3512,11 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// Turn on rule 1; call looks like it's from the system. Because setting a condition is
// typically an automatic (non-user-initiated) action, expect the calling UID to be
// re-evaluated to the one associated with CUSTOM_PKG_NAME.
+ // When modes_ui is true: we expect the change origin to be the source of truth.
mZenModeHelper.setAutomaticZenRuleState(id,
new Condition(zenRule.getConditionId(), "", STATE_TRUE),
- UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
+ Flags.modesUi() ? UPDATE_ORIGIN_APP : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+ Process.SYSTEM_UID);
// Second: turn on rule 2. This is a system-owned rule and the UID should not be modified
// (nor even looked up; the mock PackageManager won't handle "android" as input).
@@ -3493,7 +3525,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
// Disable rule 1. Because this looks like a user action, the UID should not be modified
- // from the system-provided one.
+ // from the system-provided one unless modes_ui is true.
zenRule.setEnabled(false);
mZenModeHelper.updateAutomaticZenRule(id, zenRule,
UPDATE_ORIGIN_USER, "", Process.SYSTEM_UID);
@@ -3504,6 +3536,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// Change rule 2's condition, but from some other UID. Since it doesn't look like it's from
// the system, we keep the UID info.
+ // Note that this probably shouldn't be able to occur in real scenarios.
mZenModeHelper.setAutomaticZenRuleState(id2,
new Condition(zenRule2.getConditionId(), "", STATE_FALSE),
UPDATE_ORIGIN_APP, 12345);
@@ -3528,11 +3561,13 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
// Third event: disable rule 1. This looks like a user action so UID should be left alone.
+ // When modes_ui is true, we assign log this user action with the app that owns the rule.
assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
mZenModeEventLogger.getEventId(2));
assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2));
assertTrue(mZenModeEventLogger.getIsUserAction(2));
- assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
+ assertThat(mZenModeEventLogger.getPackageUid(2)).isEqualTo(
+ Flags.modesUi() ? CUSTOM_PKG_UID : Process.SYSTEM_UID);
// Fourth event: turns on manual mode. Doesn't change effective policy so this is just a
// change in active rules. Confirm that the package UID is left unchanged.
@@ -6202,7 +6237,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
public void setManualZenRuleDeviceEffects_noPreexistingMode() {
ZenDeviceEffects effects = new ZenDeviceEffects.Builder()
.setShouldDimWallpaper(true)
- .build();
+ .build();
mZenModeHelper.setManualZenRuleDeviceEffects(effects, UPDATE_ORIGIN_USER, "settings", 1000);
assertThat(mZenModeHelper.getConfig().manualRule).isNotNull();
@@ -6339,21 +6374,21 @@ public class ZenModeHelperTest extends UiServiceTestCase {
private static final Correspondence<ZenRule, ZenRule> IGNORE_METADATA =
Correspondence.transforming(zr -> {
- Parcel p = Parcel.obtain();
- try {
- zr.writeToParcel(p, 0);
- p.setDataPosition(0);
- ZenRule copy = new ZenRule(p);
- copy.creationTime = 0;
- copy.userModifiedFields = 0;
- copy.zenPolicyUserModifiedFields = 0;
- copy.zenDeviceEffectsUserModifiedFields = 0;
- return copy;
- } finally {
- p.recycle();
- }
- },
- "Ignoring timestamp and userModifiedFields");
+ Parcel p = Parcel.obtain();
+ try {
+ zr.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ ZenRule copy = new ZenRule(p);
+ copy.creationTime = 0;
+ copy.userModifiedFields = 0;
+ copy.zenPolicyUserModifiedFields = 0;
+ copy.zenDeviceEffectsUserModifiedFields = 0;
+ return copy;
+ } finally {
+ p.recycle();
+ }
+ },
+ "Ignoring timestamp and userModifiedFields");
private ZenRule expectedImplicitRule(String ownerPkg, int zenMode, ZenPolicy policy,
@Nullable Boolean conditionActive) {
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java
index 633a3c985b7f..901c0361092f 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java
@@ -54,6 +54,7 @@ import android.os.vibrator.Flags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.AtomicFile;
import android.util.SparseArray;
+import android.view.HapticFeedbackConstants;
import androidx.test.InstrumentationRegistry;
@@ -292,7 +293,7 @@ public class HapticFeedbackVibrationProviderTest {
for (int effectId : BIOMETRIC_FEEDBACK_CONSTANTS) {
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
- effectId, /* bypassVibrationIntensitySetting= */ false, /* fromIme= */ false);
+ effectId, /* flags */ 0, /* privFlags */ 0);
assertThat(attrs.getUsage()).isEqualTo(VibrationAttributes.USAGE_COMMUNICATION_REQUEST);
}
}
@@ -302,8 +303,7 @@ public class HapticFeedbackVibrationProviderTest {
HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
- SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ false,
- false /* fromIme*/);
+ SAFE_MODE_ENABLED, /* flags */ 0, /* privFlags */ 0);
assertThat(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)).isFalse();
}
@@ -313,7 +313,8 @@ public class HapticFeedbackVibrationProviderTest {
HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
- SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ true, false /* fromIme*/);
+ SAFE_MODE_ENABLED,
+ /* flags */ HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING, /* privFlags */ 0);
assertThat(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)).isTrue();
}
@@ -325,7 +326,7 @@ public class HapticFeedbackVibrationProviderTest {
for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
- effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/);
+ effectId, /* flags */ 0, /* privFlags */ 0);
assertWithMessage("Expected FLAG_BYPASS_INTERRUPTION_POLICY for effect " + effectId)
.that(attrs.isFlagSet(FLAG_BYPASS_INTERRUPTION_POLICY)).isTrue();
}
@@ -338,7 +339,7 @@ public class HapticFeedbackVibrationProviderTest {
for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
- effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/);
+ effectId, /* flags */ 0, /* privFlags */ 0);
assertWithMessage("Expected no FLAG_BYPASS_INTERRUPTION_POLICY for effect " + effectId)
.that(attrs.isFlagSet(FLAG_BYPASS_INTERRUPTION_POLICY)).isFalse();
}
@@ -351,7 +352,8 @@ public class HapticFeedbackVibrationProviderTest {
for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
- effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/);
+ effectId, /* flags */ 0,
+ HapticFeedbackConstants.PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS);
assertWithMessage("Expected USAGE_TOUCH for effect " + effectId)
.that(attrs.getUsage()).isEqualTo(USAGE_TOUCH);
assertWithMessage("Expected no CATEGORY_KEYBOARD for effect " + effectId)
@@ -366,7 +368,7 @@ public class HapticFeedbackVibrationProviderTest {
for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
- effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/);
+ effectId, /* flags */ 0, /* privFlags */ 0);
assertWithMessage("Expected USAGE_TOUCH for effect " + effectId)
.that(attrs.getUsage()).isEqualTo(USAGE_TOUCH);
assertWithMessage("Expected CATEGORY_KEYBOARD for effect " + effectId)
@@ -381,7 +383,8 @@ public class HapticFeedbackVibrationProviderTest {
for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
- effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/);
+ effectId, /* flags */ 0,
+ HapticFeedbackConstants.PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS);
assertWithMessage("Expected USAGE_TOUCH for effect " + effectId)
.that(attrs.getUsage()).isEqualTo(USAGE_TOUCH);
assertWithMessage("Expected CATEGORY_KEYBOARD for effect " + effectId)
@@ -398,7 +401,8 @@ public class HapticFeedbackVibrationProviderTest {
for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
- effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/);
+ effectId, /* flags */ 0,
+ HapticFeedbackConstants.PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS);
assertWithMessage("Expected no FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE for effect "
+ effectId)
.that(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)).isFalse();
@@ -414,7 +418,7 @@ public class HapticFeedbackVibrationProviderTest {
for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
- effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/);
+ effectId, /* flags */ 0, /* privFlags */ 0);
assertWithMessage("Expected no FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE for effect "
+ effectId)
.that(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)).isFalse();
@@ -430,7 +434,8 @@ public class HapticFeedbackVibrationProviderTest {
for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
- effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/);
+ effectId, /* flags */ 0,
+ HapticFeedbackConstants.PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS);
assertWithMessage("Expected FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE for effect "
+ effectId)
.that(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)).isTrue();
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
index 88a94830e98a..60d8964267f1 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -605,7 +605,7 @@ public class VibrationSettingsTest {
public void shouldIgnoreVibration_withKeyboardSettingsOff_shouldIgnoreKeyboardVibration() {
setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_MEDIUM);
setUserSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED, 0 /* OFF*/);
- setHasFixedKeyboardAmplitudeIntensity(true);
+ setKeyboardVibrationSettingsSupported(true);
// Keyboard touch ignored.
assertVibrationIgnoredForAttributes(
@@ -630,7 +630,7 @@ public class VibrationSettingsTest {
public void shouldIgnoreVibration_withKeyboardSettingsOn_shouldNotIgnoreKeyboardVibration() {
setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF);
setUserSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED, 1 /* ON */);
- setHasFixedKeyboardAmplitudeIntensity(true);
+ setKeyboardVibrationSettingsSupported(true);
// General touch ignored.
assertVibrationIgnoredForUsage(USAGE_TOUCH, Vibration.Status.IGNORED_FOR_SETTINGS);
@@ -645,10 +645,10 @@ public class VibrationSettingsTest {
@Test
@RequiresFlagsEnabled(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED)
- public void shouldIgnoreVibration_noFixedKeyboardAmplitude_ignoresKeyboardTouchVibration() {
+ public void shouldIgnoreVibration_notSupportKeyboardVibration_ignoresKeyboardTouchVibration() {
setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF);
setUserSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED, 1 /* ON */);
- setHasFixedKeyboardAmplitudeIntensity(false);
+ setKeyboardVibrationSettingsSupported(false);
// General touch ignored.
assertVibrationIgnoredForUsage(USAGE_TOUCH, Vibration.Status.IGNORED_FOR_SETTINGS);
@@ -974,8 +974,8 @@ public class VibrationSettingsTest {
when(mVibrationConfigMock.ignoreVibrationsOnWirelessCharger()).thenReturn(ignore);
}
- private void setHasFixedKeyboardAmplitudeIntensity(boolean hasFixedAmplitude) {
- when(mVibrationConfigMock.hasFixedKeyboardAmplitude()).thenReturn(hasFixedAmplitude);
+ private void setKeyboardVibrationSettingsSupported(boolean supported) {
+ when(mVibrationConfigMock.isKeyboardVibrationSettingsSupported()).thenReturn(supported);
}
private void deleteUserSetting(String settingName) {
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index 18752847910b..ef944dbba3ca 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -2661,9 +2661,10 @@ public class VibratorManagerServiceTest {
private HalVibration performHapticFeedbackAndWaitUntilFinished(VibratorManagerService service,
int constant, boolean always) throws InterruptedException {
- HalVibration vib =
- service.performHapticFeedbackInternal(UID, Context.DEVICE_ID_DEFAULT, PACKAGE_NAME,
- constant, always, "some reason", service, false /* fromIme */);
+ HalVibration vib = service.performHapticFeedbackInternal(UID, Context.DEVICE_ID_DEFAULT,
+ PACKAGE_NAME, constant, "some reason", service,
+ always ? HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING : 0 /* flags */,
+ 0 /* privFlags */);
if (vib != null) {
vib.waitForEnd();
}
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 777f6189fdea..6e6b70d319ab 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -52,6 +52,7 @@
<uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS"/>
<uses-permission android:name="android.permission.MANAGE_DEFAULT_APPLICATIONS"/>
<uses-permission android:name="android.permission.DUMP"/>
+ <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) -->
<application android:debuggable="true"
diff --git a/services/tests/wmtests/res/xml/bookmarks.xml b/services/tests/wmtests/res/xml/bookmarks.xml
new file mode 100644
index 000000000000..88419e9c441b
--- /dev/null
+++ b/services/tests/wmtests/res/xml/bookmarks.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<bookmarks>
+ <bookmark
+ role="android.app.role.BROWSER"
+ shortcut="b" />
+ <bookmark
+ category="android.intent.category.APP_CONTACTS"
+ shortcut="c" />
+ <bookmark
+ category="android.intent.category.APP_EMAIL"
+ shortcut="e" />
+ <bookmark
+ category="android.intent.category.APP_CALENDAR"
+ shortcut="k" />
+ <bookmark
+ category="android.intent.category.APP_MAPS"
+ shortcut="m" />
+ <bookmark
+ category="android.intent.category.APP_MUSIC"
+ shortcut="p" />
+ <bookmark
+ role="android.app.role.SMS"
+ shortcut="s" />
+ <bookmark
+ category="android.intent.category.APP_CALCULATOR"
+ shortcut="u" />
+</bookmarks>
diff --git a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java
new file mode 100644
index 000000000000..8c375d413950
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java
@@ -0,0 +1,167 @@
+/*
+ * 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.policy;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyObject;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
+import android.view.KeyboardShortcutInfo;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.R;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+
+/**
+ * Test class for {@link ModifierShortcutManager}.
+ *
+ * Build/Install/Run:
+ * atest ModifierShortcutManagerTests
+ */
+
+@SmallTest
+public class ModifierShortcutManagerTests {
+ private ModifierShortcutManager mModifierShortcutManager;
+ private Handler mHandler;
+ private Context mContext;
+ private Resources mResources;
+
+ @Before
+ public void setUp() {
+ mHandler = new Handler(Looper.getMainLooper());
+ mContext = spy(getInstrumentation().getTargetContext());
+ mResources = spy(mContext.getResources());
+
+ XmlResourceParser testBookmarks = mResources.getXml(
+ com.android.frameworks.wmtests.R.xml.bookmarks);
+
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mResources.getXml(R.xml.bookmarks)).thenReturn(testBookmarks);
+
+ mModifierShortcutManager = new ModifierShortcutManager(mContext, mHandler);
+ }
+
+ @Test
+ public void test_getApplicationLaunchKeyboardShortcuts() {
+ KeyboardShortcutGroup group =
+ mModifierShortcutManager.getApplicationLaunchKeyboardShortcuts(-1);
+ assertEquals(8, group.getItems().size());
+ }
+
+ @Test
+ public void test_shortcutInfoFromIntent_appIntent() {
+ Intent mockIntent = mock(Intent.class);
+ ActivityInfo mockActivityInfo = mock(ActivityInfo.class);
+ when(mockActivityInfo.loadLabel(anyObject())).thenReturn("label");
+ mockActivityInfo.packageName = "android";
+ when(mockActivityInfo.getIconResource()).thenReturn(R.drawable.sym_def_app_icon);
+ when(mockIntent.resolveActivityInfo(anyObject(), anyInt())).thenReturn(mockActivityInfo);
+
+ KeyboardShortcutInfo info = mModifierShortcutManager.shortcutInfoFromIntent(
+ 'a', mockIntent, true);
+
+ assertEquals("label", info.getLabel().toString());
+ assertEquals('a', info.getBaseCharacter());
+ assertEquals(R.drawable.sym_def_app_icon, info.getIcon().getResId());
+ assertEquals(KeyEvent.META_META_ON | KeyEvent.META_SHIFT_ON, info.getModifiers());
+
+ }
+
+ @Test
+ public void test_shortcutInfoFromIntent_resolverIntent() {
+ Intent mockIntent = mock(Intent.class);
+ Intent mockSelector = mock(Intent.class);
+ ActivityInfo mockActivityInfo = mock(ActivityInfo.class);
+ mockActivityInfo.name = com.android.internal.app.ResolverActivity.class.getName();
+ when(mockIntent.resolveActivityInfo(anyObject(), anyInt())).thenReturn(mockActivityInfo);
+ when(mockIntent.getSelector()).thenReturn(mockSelector);
+ when(mockSelector.getCategories()).thenReturn(
+ Collections.singleton(Intent.CATEGORY_APP_BROWSER));
+
+ KeyboardShortcutInfo info = mModifierShortcutManager.shortcutInfoFromIntent(
+ 'a', mockIntent, false);
+
+ assertEquals(mContext.getString(R.string.keyboard_shortcut_group_applications_browser),
+ info.getLabel().toString());
+ assertEquals('a', info.getBaseCharacter());
+ assertEquals(R.drawable.sym_def_app_icon, info.getIcon().getResId());
+ assertEquals(KeyEvent.META_META_ON, info.getModifiers());
+
+ // validate that an unknown category that we can't present a label to the user for
+ // returns null shortcut info.
+ when(mockSelector.getCategories()).thenReturn(
+ Collections.singleton("not_a_category"));
+ assertEquals(null, mModifierShortcutManager.shortcutInfoFromIntent(
+ 'a', mockIntent, false));
+ }
+
+ @Test
+ public void test_getIntentCategoryLabel() {
+ assertEquals(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_browser),
+ ModifierShortcutManager.getIntentCategoryLabel(
+ mContext, Intent.CATEGORY_APP_BROWSER));
+ assertEquals(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_contacts),
+ ModifierShortcutManager.getIntentCategoryLabel(
+ mContext, Intent.CATEGORY_APP_CONTACTS));
+ assertEquals(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_email),
+ ModifierShortcutManager.getIntentCategoryLabel(
+ mContext, Intent.CATEGORY_APP_EMAIL));
+ assertEquals(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_calendar),
+ ModifierShortcutManager.getIntentCategoryLabel(
+ mContext, Intent.CATEGORY_APP_CALENDAR));
+ assertEquals(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_maps),
+ ModifierShortcutManager.getIntentCategoryLabel(
+ mContext, Intent.CATEGORY_APP_MAPS));
+ assertEquals(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_music),
+ ModifierShortcutManager.getIntentCategoryLabel(
+ mContext, Intent.CATEGORY_APP_MUSIC));
+ assertEquals(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_sms),
+ ModifierShortcutManager.getIntentCategoryLabel(
+ mContext, Intent.CATEGORY_APP_MESSAGING));
+ assertEquals(
+ mContext.getString(R.string.keyboard_shortcut_group_applications_calculator),
+ ModifierShortcutManager.getIntentCategoryLabel(
+ mContext, Intent.CATEGORY_APP_CALCULATOR));
+ assertEquals(null, ModifierShortcutManager.getIntentCategoryLabel(mContext, "foo"));
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
index 0ed02dd0f429..526c351a656c 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
@@ -65,7 +65,8 @@ public class ModifierShortcutTests extends ShortcutKeyTestBase {
private static final SparseArray<String> INTENT_SHORTCUTS = new SparseArray<>();
private static final SparseArray<String> ROLE_SHORTCUTS = new SparseArray<>();
static {
- // These shortcuts should align with those defined in bookmarks.xml
+ // These shortcuts should align with those defined in
+ // services/tests/wmtests/res/xml/bookmarks.xml
INTENT_SHORTCUTS.append(KEYCODE_U, Intent.CATEGORY_APP_CALCULATOR);
INTENT_SHORTCUTS.append(KEYCODE_C, Intent.CATEGORY_APP_CONTACTS);
INTENT_SHORTCUTS.append(KEYCODE_E, Intent.CATEGORY_APP_EMAIL);
@@ -96,6 +97,7 @@ public class ModifierShortcutTests extends ShortcutKeyTestBase {
mPhoneWindowManager.assertLaunchCategory(category);
}
+ mPhoneWindowManager.overrideRoleManager();
for (int i = 0; i < ROLE_SHORTCUTS.size(); i++) {
final int keyCode = ROLE_SHORTCUTS.keyAt(i);
final String role = ROLE_SHORTCUTS.valueAt(i);
diff --git a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
index 248091371ff1..07934ea90b7e 100644
--- a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
@@ -131,8 +131,6 @@ public class PhoneWindowManagerTests {
@Test
public void testScreenTurnedOff() {
- mSetFlagsRule.enableFlags(com.android.window.flags.Flags
- .FLAG_SKIP_SLEEPING_WHEN_SWITCHING_DISPLAY);
doNothing().when(mPhoneWindowManager).updateSettings(any());
doNothing().when(mPhoneWindowManager).initializeHdmiState();
final boolean[] isScreenTurnedOff = { false };
@@ -159,14 +157,15 @@ public class PhoneWindowManagerTests {
// Skip sleep-token for non-sleep-screen-off.
clearInvocations(tokenAcquirer);
mPhoneWindowManager.screenTurnedOff(DEFAULT_DISPLAY, true /* isSwappingDisplay */);
- verify(tokenAcquirer, never()).acquire(anyInt(), anyBoolean());
+ verify(tokenAcquirer, never()).acquire(anyInt());
assertThat(isScreenTurnedOff[0]).isTrue();
// Apply sleep-token for sleep-screen-off.
+ isScreenTurnedOff[0] = false;
mPhoneWindowManager.startedGoingToSleep(DEFAULT_DISPLAY, 0 /* reason */);
assertThat(mPhoneWindowManager.mIsGoingToSleepDefaultDisplay).isTrue();
mPhoneWindowManager.screenTurnedOff(DEFAULT_DISPLAY, true /* isSwappingDisplay */);
- verify(tokenAcquirer).acquire(eq(DEFAULT_DISPLAY), eq(true));
+ verify(tokenAcquirer).acquire(eq(DEFAULT_DISPLAY));
mPhoneWindowManager.finishedGoingToSleep(DEFAULT_DISPLAY, 0 /* reason */);
assertThat(mPhoneWindowManager.mIsGoingToSleepDefaultDisplay).isFalse();
@@ -176,11 +175,11 @@ public class PhoneWindowManagerTests {
isScreenTurnedOff[0] = false;
clearInvocations(tokenAcquirer);
mPhoneWindowManager.screenTurnedOff(DEFAULT_DISPLAY, true /* isSwappingDisplay */);
- verify(tokenAcquirer, never()).acquire(anyInt(), anyBoolean());
+ verify(tokenAcquirer, never()).acquire(anyInt());
assertThat(displayPolicy.isScreenOnEarly()).isFalse();
assertThat(displayPolicy.isScreenOnFully()).isFalse();
mPhoneWindowManager.startedGoingToSleep(DEFAULT_DISPLAY, 0 /* reason */);
- verify(tokenAcquirer).acquire(eq(DEFAULT_DISPLAY), eq(false));
+ verify(tokenAcquirer).acquire(eq(DEFAULT_DISPLAY));
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
index dff4984adb80..f5c8fb803fd8 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
@@ -49,6 +49,7 @@ import static java.util.Collections.unmodifiableMap;
import android.content.Context;
import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.ArrayMap;
import android.view.InputDevice;
@@ -102,6 +103,9 @@ class ShortcutKeyTestBase {
doReturn(mResources).when(mContext).getResources();
doReturn(mSettingsProviderRule.mockContentResolver(mContext))
.when(mContext).getContentResolver();
+ XmlResourceParser testBookmarks = mResources.getXml(
+ com.android.frameworks.wmtests.R.xml.bookmarks);
+ doReturn(testBookmarks).when(mResources).getXml(com.android.internal.R.xml.bookmarks);
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index fdb57d1e29d1..2b7e7ab1b9ae 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -568,6 +568,12 @@ class TestPhoneWindowManager {
doReturn(isShowing).when(mKeyguardServiceDelegate).isShowing();
}
+ void overrideRoleManager() {
+ doReturn(mContext).when(mContext).createContextAsUser(any(), anyInt());
+ doReturn(mRoleManager).when(mContext).getSystemService(eq(RoleManager.class));
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ }
+
void setupAssistForLaunch() {
doNothing().when(mPhoneWindowManager).sendCloseSystemWindows();
doReturn(true).when(mPhoneWindowManager).isUserSetupComplete();
@@ -709,7 +715,7 @@ class TestPhoneWindowManager {
throw new AssertionError("failed to assert " + category, t);
}
// Reset verifier for next call.
- Mockito.reset(mContext);
+ Mockito.clearInvocations(mContext);
}
void assertLaunchRole(String role) {
@@ -719,10 +725,10 @@ class TestPhoneWindowManager {
verify(mContext).startActivityAsUser(intentCaptor.capture(), any());
switch (role) {
case RoleManager.ROLE_BROWSER:
- Assert.assertEquals(intentCaptor.getValue(), mBrowserIntent);
+ Assert.assertEquals(mBrowserIntent, intentCaptor.getValue());
break;
case RoleManager.ROLE_SMS:
- Assert.assertEquals(intentCaptor.getValue(), mSmsIntent);
+ Assert.assertEquals(mSmsIntent, intentCaptor.getValue());
break;
default:
throw new AssertionError("Role " + role + " not supported in tests.");
@@ -731,7 +737,7 @@ class TestPhoneWindowManager {
throw new AssertionError("failed to assert " + role, t);
}
// Reset verifier for next call.
- Mockito.reset(mContext);
+ Mockito.clearInvocations(mContext);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index ef3df6cdc523..b4505fad1b20 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -116,7 +116,6 @@ import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.when;
import android.app.ActivityOptions;
import android.app.AppOpsManager;
@@ -685,7 +684,8 @@ public class ActivityRecordTests extends WindowTestsBase {
// Asserts fixed orientation request is not ignored, and the orientation is changed.
assertNotEquals(activityCurOrientation, activity.getConfiguration().orientation);
- assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(activity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
}
@Test
@@ -718,7 +718,8 @@ public class ActivityRecordTests extends WindowTestsBase {
// Relaunching the app should still respect the orientation request.
assertEquals(ORIENTATION_PORTRAIT, activity.getConfiguration().orientation);
- assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(activity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
}
@Test
@@ -2482,10 +2483,10 @@ public class ActivityRecordTests extends WindowTestsBase {
assertTrue(activity.mChildren.contains(win4));
// The starting window should be on-top of all other windows.
- assertEquals(startingWin, activity.mChildren.peekLast());
+ assertEquals(startingWin, activity.getTopChild());
// The base application window should be below all other windows.
- assertEquals(baseWin, activity.mChildren.peekFirst());
+ assertEquals(baseWin, activity.getBottomChild());
activity.removeImmediately();
}
@@ -3508,23 +3509,6 @@ public class ActivityRecordTests extends WindowTestsBase {
}
@Test
- public void testIsCameraActive() {
- final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- final DisplayRotationCompatPolicy displayRotationCompatPolicy = mock(
- DisplayRotationCompatPolicy.class);
- when(mDisplayContent.getDisplayRotationCompatPolicy()).thenReturn(
- displayRotationCompatPolicy);
-
- when(displayRotationCompatPolicy.isCameraActive(any(ActivityRecord.class),
- anyBoolean())).thenReturn(false);
- assertFalse(app.mActivityRecord.isCameraActive());
-
- when(displayRotationCompatPolicy.isCameraActive(any(ActivityRecord.class),
- anyBoolean())).thenReturn(true);
- assertTrue(app.mActivityRecord.isCameraActive());
- }
-
- @Test
public void testUpdateCameraCompatStateFromUser_clickedOnDismiss() throws RemoteException {
final ActivityRecord activity = createActivityWithTask();
// Mock a flag being enabled.
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 467050e9932c..867f01fd4699 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
@@ -69,6 +69,7 @@ class AppCompatActivityRobot {
private final int mDisplayWidth;
private final int mDisplayHeight;
+ private DisplayContent mDisplayContent;
AppCompatActivityRobot(@NonNull WindowManagerService wm,
@NonNull ActivityTaskManagerService atm, @NonNull ActivityTaskSupervisor supervisor,
@@ -79,6 +80,7 @@ class AppCompatActivityRobot {
mDisplayHeight = displayHeight;
mActivityStack = new TestComponentStack<>();
mTaskStack = new TestComponentStack<>();
+ createNewDisplay();
}
AppCompatActivityRobot(@NonNull WindowManagerService wm,
@@ -87,13 +89,19 @@ class AppCompatActivityRobot {
}
void createActivityWithComponent() {
- createActivityWithComponentInNewTask(/* inNewTask */ mTaskStack.isEmpty());
+ createActivityWithComponentInNewTask(/* inNewTask */ mTaskStack.isEmpty(),
+ /* inNewDisplay */ false);
}
void createActivityWithComponentInNewTask() {
- createActivityWithComponentInNewTask(/* inNewTask */ true);
+ createActivityWithComponentInNewTask(/* inNewTask */ true, /* inNewDisplay */ false);
}
+ void createActivityWithComponentInNewTaskAndDisplay() {
+ createActivityWithComponentInNewTask(/* inNewTask */ true, /* inNewDisplay */ true);
+ }
+
+
void configureTopActivity(float minAspect, float maxAspect, int screenOrientation,
boolean isUnresizable) {
prepareLimitedBounds(mActivityStack.top(), minAspect, maxAspect, screenOrientation,
@@ -110,12 +118,22 @@ class AppCompatActivityRobot {
/* isUnresizable */ true);
}
+ void activateCameraInPolicy(boolean isCameraActive) {
+ doReturn(isCameraActive).when(mDisplayContent.mAppCompatCameraPolicy)
+ .isCameraActive(any(ActivityRecord.class), anyBoolean());
+ }
+
@NonNull
ActivityRecord top() {
return mActivityStack.top();
}
@NonNull
+ DisplayContent displayContent() {
+ return mDisplayContent;
+ }
+
+ @NonNull
ActivityRecord getFromTop(int fromTop) {
return mActivityStack.getFromTop(fromTop);
}
@@ -125,12 +143,12 @@ class AppCompatActivityRobot {
}
void setLetterboxedForFixedOrientationAndAspectRatio(boolean enabled) {
- doReturn(enabled).when(mActivityStack.top())
- .isLetterboxedForFixedOrientationAndAspectRatio();
+ doReturn(enabled).when(mActivityStack.top().mAppCompatController
+ .getAppCompatAspectRatioPolicy()).isLetterboxedForFixedOrientationAndAspectRatio();
}
void enableTreatmentForTopActivity(boolean enabled) {
- doReturn(enabled).when(getTopDisplayRotationCompatPolicy())
+ doReturn(enabled).when(mDisplayContent.mAppCompatCameraPolicy)
.isTreatmentEnabledForActivity(eq(mActivityStack.top()));
}
@@ -145,8 +163,8 @@ class AppCompatActivityRobot {
}
void setShouldApplyUserMinAspectRatioOverride(boolean enabled) {
- doReturn(enabled).when(mActivityStack.top()
- .mLetterboxUiController).shouldApplyUserMinAspectRatioOverride();
+ doReturn(enabled).when(mActivityStack.top().mAppCompatController
+ .getAppCompatAspectRatioOverrides()).shouldApplyUserMinAspectRatioOverride();
}
void setShouldCreateCompatDisplayInsets(boolean enabled) {
@@ -154,17 +172,18 @@ class AppCompatActivityRobot {
}
void setShouldApplyUserFullscreenOverride(boolean enabled) {
- doReturn(enabled).when(mActivityStack.top()
- .mLetterboxUiController).shouldApplyUserFullscreenOverride();
+ doReturn(enabled).when(mActivityStack.top().mAppCompatController
+ .getAppCompatAspectRatioOverrides()).shouldApplyUserFullscreenOverride();
}
void setGetUserMinAspectRatioOverrideCode(@PackageManager.UserMinAspectRatio int orientation) {
doReturn(orientation).when(mActivityStack.top()
- .mLetterboxUiController).getUserMinAspectRatioOverrideCode();
+ .mAppCompatController.getAppCompatAspectRatioOverrides())
+ .getUserMinAspectRatioOverrideCode();
}
void setIgnoreOrientationRequest(boolean enabled) {
- mActivityStack.top().mDisplayContent.setIgnoreOrientationRequest(enabled);
+ mDisplayContent.setIgnoreOrientationRequest(enabled);
}
void setTopActivityAsEmbedded(boolean embedded) {
@@ -179,20 +198,22 @@ class AppCompatActivityRobot {
mActivityStack.applyTo(/* fromTop */ fromTop, ActivityRecord::removeImmediately);
}
+ void createNewDisplay() {
+ mDisplayContent = new TestDisplayContent.Builder(mAtm, mDisplayWidth, mDisplayHeight)
+ .build();
+ spyOnAppCompatCameraPolicy();
+ }
+
void createNewTask() {
- final DisplayContent displayContent = new TestDisplayContent
- .Builder(mAtm, mDisplayWidth, mDisplayHeight).build();
final Task newTask = new WindowTestsBase.TaskBuilder(mSupervisor)
- .setDisplay(displayContent).build();
+ .setDisplay(mDisplayContent).build();
mTaskStack.push(newTask);
}
void createNewTaskWithBaseActivity() {
- final DisplayContent displayContent = new TestDisplayContent
- .Builder(mAtm, mDisplayWidth, mDisplayHeight).build();
final Task newTask = new WindowTestsBase.TaskBuilder(mSupervisor)
.setCreateActivity(true)
- .setDisplay(displayContent).build();
+ .setDisplay(mDisplayContent).build();
mTaskStack.push(newTask);
pushActivity(newTask.getTopNonFinishingActivity());
}
@@ -319,7 +340,10 @@ class AppCompatActivityRobot {
pushActivity(newActivity);
}
- private void createActivityWithComponentInNewTask(boolean inNewTask) {
+ private void createActivityWithComponentInNewTask(boolean inNewTask, boolean inNewDisplay) {
+ if (inNewDisplay) {
+ createNewDisplay();
+ }
if (inNewTask) {
createNewTask();
}
@@ -369,7 +393,8 @@ class AppCompatActivityRobot {
}
private DisplayRotationCompatPolicy getTopDisplayRotationCompatPolicy() {
- return mActivityStack.top().mDisplayContent.mDisplayRotationCompatPolicy;
+ return mActivityStack.top().mDisplayContent
+ .mAppCompatCameraPolicy.mDisplayRotationCompatPolicy;
}
// We add the activity to the stack and spyOn() on its properties.
@@ -377,10 +402,18 @@ class AppCompatActivityRobot {
mActivityStack.push(activity);
spyOn(activity);
spyOn(activity.mAppCompatController.getTransparentPolicy());
- if (activity.mDisplayContent != null
- && activity.mDisplayContent.mDisplayRotationCompatPolicy != null) {
- spyOn(activity.mDisplayContent.mDisplayRotationCompatPolicy);
- }
+ spyOn(activity.mAppCompatController.getAppCompatAspectRatioOverrides());
+ spyOn(activity.mAppCompatController.getAppCompatAspectRatioPolicy());
spyOn(activity.mLetterboxUiController);
}
+
+ private void spyOnAppCompatCameraPolicy() {
+ spyOn(mDisplayContent.mAppCompatCameraPolicy);
+ if (mDisplayContent.mAppCompatCameraPolicy.hasDisplayRotationCompatPolicy()) {
+ spyOn(mDisplayContent.mAppCompatCameraPolicy.mDisplayRotationCompatPolicy);
+ }
+ if (mDisplayContent.mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy()) {
+ spyOn(mDisplayContent.mAppCompatCameraPolicy.mCameraCompatFreeformPolicy);
+ }
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
index 9263b4f17920..2d94b34c52f1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
@@ -26,7 +26,6 @@ import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTA
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.window.flags.Flags.FLAG_CAMERA_COMPAT_FOR_FREEFORM;
@@ -264,14 +263,29 @@ public class AppCompatCameraOverridesTest extends WindowTestsBase {
public void testShouldRecomputeConfigurationForCameraCompat() {
runTestScenario((robot) -> {
robot.conf().enableCameraCompatSplitScreenAspectRatio(true);
- robot.activity().createActivityWithComponentInNewTask();
- robot.activateCamera(true);
- robot.activity().setShouldCreateCompatDisplayInsets(false);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponentInNewTask();
+ a.activateCameraInPolicy(true);
+ a.setShouldCreateCompatDisplayInsets(false);
+ });
robot.checkShouldApplyFreeformTreatmentForCameraCompat(true);
});
}
+ @Test
+ public void testIsCameraActive() {
+ runTestScenario((robot) -> {
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.activateCameraInPolicy(/* isCameraActive */ false);
+ robot.checkIsCameraActive(/* active */ false);
+ a.activateCameraInPolicy(/* isCameraActive */ true);
+ robot.checkIsCameraActive(/* active */ true);
+ });
+ });
+ }
+
/**
* Runs a test scenario providing a Robot.
*/
@@ -289,10 +303,6 @@ public class AppCompatCameraOverridesTest extends WindowTestsBase {
super(wm, atm, supervisor);
}
- void activateCamera(boolean isCameraActive) {
- doReturn(isCameraActive).when(activity().top()).isCameraActive();
- }
-
void checkShouldRefreshActivityForCameraCompat(boolean expected) {
Assert.assertEquals(getAppCompatCameraOverrides()
.shouldRefreshActivityForCameraCompat(), expected);
@@ -313,6 +323,10 @@ public class AppCompatCameraOverridesTest extends WindowTestsBase {
.shouldApplyFreeformTreatmentForCameraCompat(), expected);
}
+ void checkIsCameraActive(boolean active) {
+ Assert.assertEquals(getAppCompatCameraOverrides().isCameraActive(), active);
+ }
+
private AppCompatCameraOverrides getAppCompatCameraOverrides() {
return activity().top().mAppCompatController.getAppCompatCameraOverrides();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java
index 411631301fff..006b37002e23 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java
@@ -16,23 +16,20 @@
package com.android.server.wm;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
-import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
-
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_CAMERA_COMPAT_FOR_FREEFORM;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
+import static org.mockito.ArgumentMatchers.any;
import android.compat.testing.PlatformCompatChangeRule;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import androidx.annotation.NonNull;
-import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
-import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
-
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
@@ -54,96 +51,128 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase {
public TestRule compatChangeRule = new PlatformCompatChangeRule();
@Test
- @DisableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
- public void testRecomputeConfigurationForCameraCompatIfNeeded_allDisabledNoRecompute() {
+ public void testDisplayRotationCompatPolicy_presentWhenEnabled() {
runTestScenario((robot) -> {
- robot.activity().createActivityWithComponent();
- robot.conf().enableCameraCompatSplitScreenAspectRatio(false);
- robot.activateCamera(/* isCameraActive */ false);
-
- robot.recomputeConfigurationForCameraCompatIfNeeded();
- robot.checkRecomputeConfigurationInvoked(/* invoked */ false);
-
+ robot.conf().enableCameraCompatTreatmentAtBuildTime(true);
+ robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+ robot.checkTopActivityHasDisplayRotationCompatPolicy(true);
});
}
@Test
- @EnableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
- public void testRecomputeConfigurationForCameraCompatIfNeeded_cameraEnabledRecompute() {
+ public void testDisplayRotationCompatPolicy_notPresentWhenDisabled() {
runTestScenario((robot) -> {
- robot.activity().createActivityWithComponent();
- robot.conf().enableCameraCompatSplitScreenAspectRatio(false);
- robot.activateCamera(/* isCameraActive */ false);
-
- robot.recomputeConfigurationForCameraCompatIfNeeded();
- robot.checkRecomputeConfigurationInvoked(/* invoked */ true);
+ robot.conf().enableCameraCompatTreatmentAtBuildTime(false);
+ robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+ robot.checkTopActivityHasDisplayRotationCompatPolicy(false);
});
}
@Test
- @DisableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
- public void testRecomputeConfigurationForCameraSplitScreenCompatIfNeeded_recompute() {
+ @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+ public void testCameraCompatFreeformPolicy_presentWhenEnabledAndDW() {
runTestScenario((robot) -> {
- robot.activity().createActivityWithComponent();
- robot.conf().enableCameraCompatSplitScreenAspectRatio(true);
- robot.activateCamera(/* isCameraActive */ false);
+ robot.allowEnterDesktopMode(true);
+ robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+ robot.checkTopActivityHasCameraCompatFreeformPolicy(true);
+ });
+ }
- robot.recomputeConfigurationForCameraCompatIfNeeded();
- robot.checkRecomputeConfigurationInvoked(/* invoked */ true);
+ @Test
+ @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+ public void testCameraCompatFreeformPolicy_notPresentWhenNoDW() {
+ runTestScenario((robot) -> {
+ robot.allowEnterDesktopMode(false);
+ robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+ robot.checkTopActivityHasCameraCompatFreeformPolicy(false);
});
}
@Test
- @DisableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
- @EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
- public void testRecomputeConfigurationForCameraSplitScreenCompatIfNeededWithCamera_recompute() {
+ @DisableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+ public void testCameraCompatFreeformPolicy_notPresentWhenNoFlag() {
runTestScenario((robot) -> {
- robot.activity().createActivityWithComponent();
- robot.conf().enableCameraCompatSplitScreenAspectRatio(false);
- robot.activateCamera(/* isCameraActive */ true);
+ robot.allowEnterDesktopMode(true);
+ robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+ robot.checkTopActivityHasCameraCompatFreeformPolicy(false);
+ });
+ }
- robot.recomputeConfigurationForCameraCompatIfNeeded();
- robot.checkRecomputeConfigurationInvoked(/* invoked */ true);
+ @Test
+ @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+ public void testCameraCompatFreeformPolicy_notPresentWhenNoFlagAndNoDW() {
+ runTestScenario((robot) -> {
+ robot.allowEnterDesktopMode(false);
+ robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+ robot.checkTopActivityHasCameraCompatFreeformPolicy(false);
});
}
- void runTestScenario(@NonNull Consumer<CameraPolicyRobotTest> consumer) {
+ /**
+ * Runs a test scenario providing a Robot.
+ */
+ void runTestScenario(@NonNull Consumer<DisplayRotationPolicyRobotTest> consumer) {
spyOn(mWm.mLetterboxConfiguration);
- final CameraPolicyRobotTest robot = new CameraPolicyRobotTest(mWm, mAtm, mSupervisor);
+ final DisplayRotationPolicyRobotTest robot =
+ new DisplayRotationPolicyRobotTest(mWm, mAtm, mSupervisor);
consumer.accept(robot);
}
- private static class CameraPolicyRobotTest extends AppCompatRobotBase {
+ @Test
+ public void testIsCameraCompatTreatmentActive_whenTreatmentForTopActivityIsEnabled() {
+ runTestScenario((robot) -> {
+ robot.applyOnActivity((a)-> {
+ a.createActivityWithComponent();
+ a.enableTreatmentForTopActivity(/* enabled */ true);
+ });
- private final WindowManagerService mWm;
+ robot.checkIsCameraCompatTreatmentActiveForTopActivity(/* active */ true);
+ });
+ }
- CameraPolicyRobotTest(@NonNull WindowManagerService wm,
+ @Test
+ public void testIsCameraCompatTreatmentNotActive_whenTreatmentForTopActivityIsDisabled() {
+ runTestScenario((robot) -> {
+ robot.applyOnActivity((a)-> {
+ a.createActivityWithComponent();
+ a.enableTreatmentForTopActivity(/* enabled */ false);
+ });
+
+ robot.checkIsCameraCompatTreatmentActiveForTopActivity(/* active */ false);
+ });
+ }
+
+ private static class DisplayRotationPolicyRobotTest extends AppCompatRobotBase {
+
+ DisplayRotationPolicyRobotTest(@NonNull WindowManagerService wm,
@NonNull ActivityTaskManagerService atm,
@NonNull ActivityTaskSupervisor supervisor) {
super(wm, atm, supervisor);
- mWm = wm;
- spyOn(mWm);
}
- void activateCamera(boolean isCameraActive) {
- doReturn(isCameraActive).when(activity().top()).isCameraActive();
+ void checkTopActivityHasDisplayRotationCompatPolicy(boolean exists) {
+ Assert.assertEquals(exists, activity().top().mDisplayContent
+ .mAppCompatCameraPolicy.hasDisplayRotationCompatPolicy());
}
- void recomputeConfigurationForCameraCompatIfNeeded() {
- getAppCompatCameraPolicy().recomputeConfigurationForCameraCompatIfNeeded();
+ void checkTopActivityHasCameraCompatFreeformPolicy(boolean exists) {
+ Assert.assertEquals(exists, activity().top().mDisplayContent
+ .mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy());
}
- void checkRecomputeConfigurationInvoked(boolean invoked) {
- if (invoked) {
- verify(activity().top()).recomputeConfiguration();
- } else {
- verify(activity().top(), never()).recomputeConfiguration();
- }
+ void checkIsCameraCompatTreatmentActiveForTopActivity(boolean active) {
+ Assert.assertEquals(getTopAppCompatCameraPolicy()
+ .isTreatmentEnabledForActivity(activity().top()), active);
}
- private AppCompatCameraPolicy getAppCompatCameraPolicy() {
- return activity().top().mAppCompatController.getAppCompatCameraPolicy();
+ // TODO(b/350460645): Create Desktop Windowing Robot to reuse common functionalities.
+ void allowEnterDesktopMode(boolean isAllowed) {
+ doReturn(isAllowed).when(() ->
+ DesktopModeLaunchParamsModifier.canEnterDesktopMode(any()));
}
- }
+ private AppCompatCameraPolicy getTopAppCompatCameraPolicy() {
+ return activity().top().mDisplayContent.mAppCompatCameraPolicy;
+ }
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java
index 1720b64f558b..35c2ee0b83a1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java
@@ -15,12 +15,8 @@
*/
package com.android.server.wm;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
-import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
-import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.AppCompatOrientationOverrides.OrientationOverridesState.MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP;
@@ -31,7 +27,6 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.compat.testing.PlatformCompatChangeRule;
-import android.content.res.Configuration;
import android.platform.test.annotations.Presubmit;
import androidx.annotation.NonNull;
@@ -62,82 +57,6 @@ public class AppCompatOrientationOverridesTest extends WindowTestsBase {
public TestRule compatChangeRule = new PlatformCompatChangeRule();
@Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
- public void testShouldIgnoreRequestedOrientation_activityRelaunching_returnsTrue() {
- runTestScenario((robot) -> {
- robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
- robot.activity().createActivityWithComponent();
- robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
-
- robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
- /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
- public void testShouldIgnoreRequestedOrientation_cameraCompatTreatment_returnsTrue() {
- runTestScenario((robot) -> {
- robot.applyOnConf((c) -> {
- c.enableCameraCompatTreatment(true);
- c.enableCameraCompatTreatmentAtBuildTime(true);
- c.enablePolicyForIgnoringRequestedOrientation(true);
- });
- robot.applyOnActivity((a) -> {
- a.createActivityWithComponentInNewTask();
- a.enableTreatmentForTopActivity(true);
- });
- robot.prepareRelaunchingAfterRequestedOrientationChanged(false);
-
- robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
- /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
- @Test
- public void testShouldIgnoreRequestedOrientation_overrideDisabled_returnsFalse() {
- runTestScenario((robot) -> {
- robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
-
- robot.activity().createActivityWithComponent();
- robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
-
- robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
- /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
- @Test
- public void testShouldIgnoreRequestedOrientation_propertyIsTrue_returnsTrue() {
- runTestScenario((robot) -> {
- robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
- robot.prop().enable(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
-
- robot.activity().createActivityWithComponent();
- robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
-
- robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
- /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
- public void testShouldIgnoreRequestedOrientation_propertyIsFalseAndOverride_returnsFalse()
- throws Exception {
- runTestScenario((robot) -> {
- robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
- robot.prop().disable(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
-
- robot.activity().createActivityWithComponent();
- robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
-
- robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
- /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
- @Test
public void testShouldIgnoreOrientationRequestLoop_overrideDisabled_returnsFalse() {
runTestScenario((robot) -> {
robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
@@ -239,21 +158,6 @@ public class AppCompatOrientationOverridesTest extends WindowTestsBase {
});
}
- @Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
- public void testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse() {
- runTestScenario((robot) -> {
- robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
- robot.applyOnActivity((a) -> {
- a.createActivityWithComponent();
- a.setLetterboxedForFixedOrientationAndAspectRatio(false);
- });
-
- robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
- /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
/**
* Runs a test scenario providing a Robot.
*/
@@ -276,10 +180,6 @@ public class AppCompatOrientationOverridesTest extends WindowTestsBase {
mTestCurrentTimeMillisSupplier = new CurrentTimeMillisSupplierFake();
}
- void prepareRelaunchingAfterRequestedOrientationChanged(boolean enabled) {
- getTopOrientationOverrides().setRelaunchingAfterRequestedOrientationChanged(enabled);
- }
-
// Useful to reduce timeout during tests
void prepareMockedTime() {
getTopOrientationOverrides().mOrientationOverridesState.mCurrentTimeMillisSupplier =
@@ -290,12 +190,6 @@ public class AppCompatOrientationOverridesTest extends WindowTestsBase {
mTestCurrentTimeMillisSupplier.delay(SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS);
}
- void checkShouldIgnoreRequestedOrientation(boolean expected,
- @Configuration.Orientation int requestedOrientation) {
- assertEquals(expected, getTopOrientationOverrides()
- .shouldIgnoreRequestedOrientation(requestedOrientation));
- }
-
void checkExpectedLoopCount(int expectedCount) {
assertEquals(expectedCount, getTopOrientationOverrides()
.getSetOrientationRequestCounter());
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java
index 9885a2d37b07..aa520e9cc599 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java
@@ -18,6 +18,8 @@ package com.android.server.wm;
import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION;
import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION_TO_USER;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
import static android.content.pm.ActivityInfo.OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE;
import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR;
@@ -33,13 +35,16 @@ import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import android.compat.testing.PlatformCompatChangeRule;
import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
import android.platform.test.annotations.Presubmit;
import androidx.annotation.NonNull;
@@ -266,7 +271,7 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase {
c.enableCameraCompatTreatmentAtBuildTime(true);
});
robot.applyOnActivity((a) -> {
- a.createActivityWithComponentInNewTask();
+ a.createActivityWithComponentInNewTaskAndDisplay();
a.setTopActivityEligibleForOrientationOverride(false);
});
@@ -285,7 +290,7 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase {
c.enableCameraCompatTreatmentAtBuildTime(true);
});
robot.applyOnActivity((a) -> {
- a.createActivityWithComponentInNewTask();
+ a.createActivityWithComponentInNewTaskAndDisplay();
a.setTopActivityEligibleForOrientationOverride(true);
});
@@ -315,7 +320,7 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase {
c.enableCameraCompatTreatmentAtBuildTime(true);
});
robot.applyOnActivity((a) -> {
- a.createActivityWithComponentInNewTask();
+ a.createActivityWithComponentInNewTaskAndDisplay();
a.setTopActivityCameraActive(false);
});
@@ -398,6 +403,97 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase {
});
}
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+ public void testShouldIgnoreRequestedOrientation_activityRelaunching_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.activity().createActivityWithComponent();
+ robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+ public void testShouldIgnoreRequestedOrientation_cameraCompatTreatment_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.applyOnConf((c) -> {
+ c.enableCameraCompatTreatment(true);
+ c.enableCameraCompatTreatmentAtBuildTime(true);
+ c.enablePolicyForIgnoringRequestedOrientation(true);
+ });
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponentInNewTask();
+ a.enableTreatmentForTopActivity(true);
+ });
+ robot.prepareRelaunchingAfterRequestedOrientationChanged(false);
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
+ @Test
+ public void testShouldIgnoreRequestedOrientation_overrideDisabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+
+ robot.activity().createActivityWithComponent();
+ robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
+ @Test
+ public void testShouldIgnoreRequestedOrientation_propertyIsTrue_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.prop().enable(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
+
+ robot.activity().createActivityWithComponent();
+ robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+ public void testShouldIgnoreRequestedOrientation_propertyIsFalseAndOverride_returnsFalse()
+ throws Exception {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.prop().disable(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
+
+ robot.activity().createActivityWithComponent();
+ robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+ public void testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+ });
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
/**
* Runs a test scenario with an existing activity providing a Robot.
@@ -440,6 +536,10 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase {
}
}
+ void prepareRelaunchingAfterRequestedOrientationChanged(boolean enabled) {
+ getTopOrientationOverrides().setRelaunchingAfterRequestedOrientationChanged(enabled);
+ }
+
int overrideOrientationIfNeeded(@ActivityInfo.ScreenOrientation int candidate) {
return activity().top().mAppCompatController.getOrientationPolicy()
.overrideOrientationIfNeeded(candidate);
@@ -451,12 +551,27 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase {
void checkOverrideOrientation(@ActivityInfo.ScreenOrientation int candidate,
@ActivityInfo.ScreenOrientation int expected) {
- Assert.assertEquals(expected, overrideOrientationIfNeeded(candidate));
+ assertEquals(expected, overrideOrientationIfNeeded(candidate));
}
void checkOverrideOrientationIsNot(@ActivityInfo.ScreenOrientation int candidate,
@ActivityInfo.ScreenOrientation int notExpected) {
Assert.assertNotEquals(notExpected, overrideOrientationIfNeeded(candidate));
}
+
+ void checkShouldIgnoreRequestedOrientation(boolean expected,
+ @Configuration.Orientation int requestedOrientation) {
+ assertEquals(expected, getTopAppCompatOrientationPolicy()
+ .shouldIgnoreRequestedOrientation(requestedOrientation));
+ }
+
+ private AppCompatOrientationOverrides getTopOrientationOverrides() {
+ return activity().top().mAppCompatController.getAppCompatOverrides()
+ .getAppCompatOrientationOverrides();
+ }
+
+ private AppCompatOrientationPolicy getTopAppCompatOrientationPolicy() {
+ return activity().top().mAppCompatController.getOrientationPolicy();
+ }
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 0c1fbf3cb3d7..af4394acce67 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -25,15 +25,11 @@ import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
-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_DREAM_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
-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_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
@@ -41,7 +37,6 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
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.wm.WindowContainer.POSITION_BOTTOM;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -51,14 +46,11 @@ import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.annotation.Nullable;
-import android.graphics.Rect;
-import android.gui.DropInputMode;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -841,353 +833,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
}
@Test
- public void testOverrideTaskFragmentAdapter_overrideWithEmbeddedActivity() {
- final Task task = createTask(mDisplayContent);
- final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
- final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
-
- // Create a TaskFragment with embedded activity.
- final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
- final ActivityRecord activity = taskFragment.getTopMostActivity();
- prepareActivityForAppTransition(activity);
- spyOn(mDisplayContent.mAppTransition);
-
- // Prepare and start transition.
- prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
- mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
-
- // Animation run by the remote handler.
- assertTrue(remoteAnimationRunner.isAnimationStarted());
- }
-
- @Test
- public void testOverrideTaskFragmentAdapter_noOverrideWithOnlyTaskFragmentFillingTask() {
- final Task task = createTask(mDisplayContent);
- final ActivityRecord closingActivity = createActivityRecord(task);
- final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
- final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
-
- // Create a TaskFragment with embedded activity.
- final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
-
- // Make sure the TaskFragment is not embedded.
- assertFalse(taskFragment.isEmbeddedWithBoundsOverride());
- final ActivityRecord openingActivity = taskFragment.getTopMostActivity();
- prepareActivityForAppTransition(closingActivity);
- prepareActivityForAppTransition(openingActivity);
- final int uid = 12345;
- closingActivity.info.applicationInfo.uid = uid;
- openingActivity.info.applicationInfo.uid = uid;
- task.effectiveUid = uid;
- spyOn(mDisplayContent.mAppTransition);
-
- // Prepare and start transition.
- prepareAndTriggerAppTransition(openingActivity, closingActivity,
- null /* changingTaskFragment */);
- mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
-
- // Animation is not run by the remote handler because the activity is filling the Task.
- assertFalse(remoteAnimationRunner.isAnimationStarted());
- }
-
- @Test
- public void testOverrideTaskFragmentAdapter_overrideWithTaskFragmentNotFillingTask() {
- final Task task = createTask(mDisplayContent);
- final ActivityRecord closingActivity = createActivityRecord(task);
- final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
- final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
-
- // Create a TaskFragment with embedded activity.
- final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
-
- // Make sure the TaskFragment is embedded.
- taskFragment.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
- final Rect embeddedBounds = new Rect(task.getBounds());
- embeddedBounds.right = embeddedBounds.left + embeddedBounds.width() / 2;
- taskFragment.setBounds(embeddedBounds);
- assertTrue(taskFragment.isEmbeddedWithBoundsOverride());
- final ActivityRecord openingActivity = taskFragment.getTopMostActivity();
- prepareActivityForAppTransition(closingActivity);
- prepareActivityForAppTransition(openingActivity);
- final int uid = 12345;
- closingActivity.info.applicationInfo.uid = uid;
- openingActivity.info.applicationInfo.uid = uid;
- task.effectiveUid = uid;
- spyOn(mDisplayContent.mAppTransition);
-
- // Prepare and start transition.
- prepareAndTriggerAppTransition(openingActivity, closingActivity,
- null /* changingTaskFragment */);
- mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
-
- // Animation run by the remote handler.
- assertTrue(remoteAnimationRunner.isAnimationStarted());
- }
-
- @Test
- public void testOverrideTaskFragmentAdapter_overrideWithNonEmbeddedActivity() {
- final Task task = createTask(mDisplayContent);
- final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
- final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
-
- // Closing non-embedded activity.
- final ActivityRecord closingActivity = createActivityRecord(task);
- prepareActivityForAppTransition(closingActivity);
- // Opening TaskFragment with embedded activity.
- final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
- final ActivityRecord openingActivity = taskFragment.getTopMostActivity();
- prepareActivityForAppTransition(openingActivity);
- task.effectiveUid = openingActivity.getUid();
- spyOn(mDisplayContent.mAppTransition);
-
- // Prepare and start transition.
- prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment);
- mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
-
- // Animation run by the remote handler.
- assertTrue(remoteAnimationRunner.isAnimationStarted());
- }
-
- @Test
- public void testOverrideTaskFragmentAdapter_overrideEmbeddedActivityWithDiffUid() {
- final Task task = createTask(mDisplayContent);
- final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
- final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
-
- // Closing TaskFragment with embedded activity.
- final TaskFragment taskFragment1 = createTaskFragmentWithEmbeddedActivity(task, organizer);
- final ActivityRecord closingActivity = taskFragment1.getTopMostActivity();
- prepareActivityForAppTransition(closingActivity);
- closingActivity.info.applicationInfo.uid = 12345;
- // Opening TaskFragment with embedded activity with different UID.
- final TaskFragment taskFragment2 = createTaskFragmentWithEmbeddedActivity(task, organizer);
- final ActivityRecord openingActivity = taskFragment2.getTopMostActivity();
- prepareActivityForAppTransition(openingActivity);
- openingActivity.info.applicationInfo.uid = 54321;
- spyOn(mDisplayContent.mAppTransition);
-
- // Prepare and start transition.
- prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment1);
- mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
-
- // Animation run by the remote handler.
- assertTrue(remoteAnimationRunner.isAnimationStarted());
- }
-
- @Test
- public void testOverrideTaskFragmentAdapter_noOverrideWithTwoApps() {
- final Task task = createTask(mDisplayContent);
- final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
- final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
-
- // Closing activity in Task1.
- final ActivityRecord closingActivity = createActivityRecord(mDisplayContent);
- prepareActivityForAppTransition(closingActivity);
- // Opening TaskFragment with embedded activity in Task2.
- final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
- final ActivityRecord openingActivity = taskFragment.getTopMostActivity();
- prepareActivityForAppTransition(openingActivity);
- spyOn(mDisplayContent.mAppTransition);
-
- // Prepare and start transition.
- prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment);
- mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
-
- // Animation not run by the remote handler.
- assertFalse(remoteAnimationRunner.isAnimationStarted());
- }
-
- @Test
- public void testOverrideTaskFragmentAdapter_noOverrideNonEmbeddedActivityWithDiffUid() {
- final Task task = createTask(mDisplayContent);
- final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
- final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
-
- // Closing TaskFragment with embedded activity.
- final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
- final ActivityRecord closingActivity = taskFragment.getTopMostActivity();
- prepareActivityForAppTransition(closingActivity);
- closingActivity.info.applicationInfo.uid = 12345;
- task.effectiveUid = closingActivity.getUid();
- // Opening non-embedded activity with different UID.
- final ActivityRecord openingActivity = createActivityRecord(task);
- prepareActivityForAppTransition(openingActivity);
- openingActivity.info.applicationInfo.uid = 54321;
- spyOn(mDisplayContent.mAppTransition);
-
- // Prepare and start transition.
- prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment);
- mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
-
- // Animation should not run by the remote handler when there are non-embedded activities of
- // different UID.
- assertFalse(remoteAnimationRunner.isAnimationStarted());
- }
-
- @Test
- public void testOverrideTaskFragmentAdapter_noOverrideWithWallpaper() {
- final Task task = createTask(mDisplayContent);
- final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
- final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
-
- // Create a TaskFragment with embedded activity.
- final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
- final ActivityRecord activity = taskFragment.getTopMostActivity();
- prepareActivityForAppTransition(activity);
- // Set wallpaper as visible.
- final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
- mock(IBinder.class), true, mDisplayContent, true /* ownerCanManageAppTokens */);
- spyOn(mDisplayContent.mWallpaperController);
- doReturn(true).when(mDisplayContent.mWallpaperController).isWallpaperVisible();
- spyOn(mDisplayContent.mAppTransition);
-
- // Prepare and start transition.
- prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
- mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
-
- // Animation should not run by the remote handler when there is wallpaper in the transition.
- assertFalse(remoteAnimationRunner.isAnimationStarted());
- }
-
- @Test
- public void testOverrideTaskFragmentAdapter_inputProtectedForUntrustedAnimation() {
- final Task task = createTask(mDisplayContent);
- final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
- final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
-
- // Create a TaskFragment with embedded activities, one is trusted embedded, and the other
- // one is untrusted embedded.
- final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
- .setParentTask(task)
- .createActivityCount(2)
- .setOrganizer(organizer)
- .build();
- final ActivityRecord activity0 = taskFragment.getChildAt(0).asActivityRecord();
- final ActivityRecord activity1 = taskFragment.getChildAt(1).asActivityRecord();
- // Also create a non-embedded activity in the Task.
- final ActivityRecord activity2 = new ActivityBuilder(mAtm).build();
- task.addChild(activity2, POSITION_BOTTOM);
- prepareActivityForAppTransition(activity0);
- prepareActivityForAppTransition(activity1);
- prepareActivityForAppTransition(activity2);
- doReturn(false).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity0);
- doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity1);
- spyOn(mDisplayContent.mAppTransition);
-
- // Prepare and start transition.
- prepareAndTriggerAppTransition(activity1, null /* closingActivity */, taskFragment);
- mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
-
- // The animation will be animated remotely by client and all activities are input disabled
- // for untrusted animation.
- assertTrue(remoteAnimationRunner.isAnimationStarted());
- verify(activity0).setDropInputForAnimation(true);
- verify(activity1).setDropInputForAnimation(true);
- verify(activity2).setDropInputForAnimation(true);
- verify(activity0).setDropInputMode(DropInputMode.ALL);
- verify(activity1).setDropInputMode(DropInputMode.ALL);
- verify(activity2).setDropInputMode(DropInputMode.ALL);
-
- // Reset input after animation is finished.
- clearInvocations(activity0);
- clearInvocations(activity1);
- clearInvocations(activity2);
- remoteAnimationRunner.finishAnimation();
-
- verify(activity0).setDropInputForAnimation(false);
- verify(activity1).setDropInputForAnimation(false);
- verify(activity2).setDropInputForAnimation(false);
- verify(activity0).setDropInputMode(DropInputMode.OBSCURED);
- verify(activity1).setDropInputMode(DropInputMode.NONE);
- verify(activity2).setDropInputMode(DropInputMode.NONE);
- }
-
- /**
- * Since we don't have any use case to rely on handling input during animation, disable it even
- * if it is trusted embedding so that it could cover some edge-cases when a previously trusted
- * host starts doing something bad.
- */
- @Test
- public void testOverrideTaskFragmentAdapter_inputProtectedForTrustedAnimation() {
- final Task task = createTask(mDisplayContent);
- final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
- final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
-
- // Create a TaskFragment with only trusted embedded activity
- final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
- .setParentTask(task)
- .createActivityCount(1)
- .setOrganizer(organizer)
- .build();
- final ActivityRecord activity = taskFragment.getChildAt(0).asActivityRecord();
- prepareActivityForAppTransition(activity);
- doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity);
- spyOn(mDisplayContent.mAppTransition);
-
- // Prepare and start transition.
- prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
- mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
-
- // The animation will be animated remotely by client and all activities are input disabled
- // for untrusted animation.
- assertTrue(remoteAnimationRunner.isAnimationStarted());
- verify(activity).setDropInputForAnimation(true);
- verify(activity).setDropInputMode(DropInputMode.ALL);
-
- // Reset input after animation is finished.
- clearInvocations(activity);
- remoteAnimationRunner.finishAnimation();
-
- verify(activity).setDropInputForAnimation(false);
- verify(activity).setDropInputMode(DropInputMode.NONE);
- }
-
- /**
- * We don't need to drop input for fully trusted embedding (system app, and embedding in the
- * same app). This will allow users to do fast tapping.
- */
- @Test
- public void testOverrideTaskFragmentAdapter_noInputProtectedForFullyTrustedAnimation() {
- final Task task = createTask(mDisplayContent);
- final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
- final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
- setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
-
- // Create a TaskFragment with only trusted embedded activity
- final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
- .setParentTask(task)
- .createActivityCount(1)
- .setOrganizer(organizer)
- .build();
- final ActivityRecord activity = taskFragment.getChildAt(0).asActivityRecord();
- prepareActivityForAppTransition(activity);
- final int uid = mAtm.mTaskFragmentOrganizerController.getTaskFragmentOrganizerUid(
- getITaskFragmentOrganizer(organizer));
- doReturn(true).when(task).isFullyTrustedEmbedding(uid);
- spyOn(mDisplayContent.mAppTransition);
-
- // Prepare and start transition.
- prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
- mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
-
- // The animation will be animated remotely by client, but input should not be dropped for
- // fully trusted.
- assertTrue(remoteAnimationRunner.isAnimationStarted());
- verify(activity, never()).setDropInputForAnimation(true);
- verify(activity, never()).setDropInputMode(DropInputMode.ALL);
- }
-
- @Test
public void testTransitionGoodToGoForTaskFragments() {
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final Task task = createTask(mDisplayContent);
@@ -1253,22 +898,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
verify(mDisplayContent.mAppTransition).goodToGo(anyInt(), any());
}
- /** Registers remote animation for the organizer. */
- private void setupTaskFragmentRemoteAnimation(TaskFragmentOrganizer organizer,
- TestRemoteAnimationRunner remoteAnimationRunner) {
- final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
- remoteAnimationRunner, 10, 1);
- final ITaskFragmentOrganizer iOrganizer = getITaskFragmentOrganizer(organizer);
- final RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
- definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, adapter);
- definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, adapter);
- definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, adapter);
- definition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, adapter);
- definition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_CLOSE, adapter);
- registerTaskFragmentOrganizer(iOrganizer);
- mAtm.mTaskFragmentOrganizerController.registerRemoteAnimations(iOrganizer, definition);
- }
-
private static ITaskFragmentOrganizer getITaskFragmentOrganizer(
TaskFragmentOrganizer organizer) {
return ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder());
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java
index a4df03447754..c9c7e92d71cd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java
@@ -18,9 +18,11 @@ package com.android.server.wm;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_DISALLOW;
+import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_BOUND_BY_FOREGROUND;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_FOREGROUND;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_GRACE_PERIOD;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION;
+import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_TOKEN;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW;
import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK;
@@ -30,12 +32,18 @@ import android.app.BackgroundStartPrivileges;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
+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;
import androidx.test.filters.SmallTest;
import com.android.server.wm.BackgroundActivityStartController.BalVerdict;
+import com.android.window.flags.Flags;
+import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -44,6 +52,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
+
/**
* Tests for the {@link BackgroundLaunchProcessController} class.
*
@@ -55,6 +64,10 @@ import java.util.Set;
@RunWith(JUnit4.class)
public class BackgroundLaunchProcessControllerTests {
+
+ @ClassRule public static final SetFlagsRule.ClassRule mClassRule = new SetFlagsRule.ClassRule();
+ @Rule public final SetFlagsRule mSetFlagsRule = mClassRule.createSetFlagsRule();
+
Set<IBinder> mActivityStartAllowed = new HashSet<>();
Set<Integer> mHasActiveVisibleWindow = new HashSet<>();
@@ -113,6 +126,25 @@ public class BackgroundLaunchProcessControllerTests {
}
@Test
+ @DisableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
+ public void testAllowedByTokenNoCallbackOld() {
+ mController = new BackgroundLaunchProcessController(mHasActiveVisibleWindow::contains,
+ null);
+ Binder token = new Binder();
+ mActivityStartAllowed.add(token);
+ mController.addOrUpdateAllowBackgroundStartPrivileges(token,
+ BackgroundStartPrivileges.ALLOW_BAL);
+ BalVerdict balVerdict = mController.areBackgroundActivityStartsAllowed(
+ mPid, mUid, mPackageName,
+ mAppSwitchState, mIsCheckingForFgsStart,
+ mHasActivityInVisibleTask, mHasBackgroundActivityStartPrivileges,
+ mLastStopAppSwitchesTime, mLastActivityLaunchTime,
+ mLastActivityFinishTime);
+ assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_PERMISSION);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
public void testAllowedByTokenNoCallback() {
mController = new BackgroundLaunchProcessController(mHasActiveVisibleWindow::contains,
null);
@@ -126,10 +158,27 @@ public class BackgroundLaunchProcessControllerTests {
mHasActivityInVisibleTask, mHasBackgroundActivityStartPrivileges,
mLastStopAppSwitchesTime, mLastActivityLaunchTime,
mLastActivityFinishTime);
+ assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_TOKEN);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
+ public void testAllowedByTokenOld() {
+ Binder token = new Binder();
+ mActivityStartAllowed.add(token);
+ mController.addOrUpdateAllowBackgroundStartPrivileges(token,
+ BackgroundStartPrivileges.ALLOW_BAL);
+ BalVerdict balVerdict = mController.areBackgroundActivityStartsAllowed(
+ mPid, mUid, mPackageName,
+ mAppSwitchState, mIsCheckingForFgsStart,
+ mHasActivityInVisibleTask, mHasBackgroundActivityStartPrivileges,
+ mLastStopAppSwitchesTime, mLastActivityLaunchTime,
+ mLastActivityFinishTime);
assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_PERMISSION);
}
@Test
+ @EnableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
public void testAllowedByToken() {
Binder token = new Binder();
mActivityStartAllowed.add(token);
@@ -141,11 +190,12 @@ public class BackgroundLaunchProcessControllerTests {
mHasActivityInVisibleTask, mHasBackgroundActivityStartPrivileges,
mLastStopAppSwitchesTime, mLastActivityLaunchTime,
mLastActivityFinishTime);
- assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_PERMISSION);
+ assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_TOKEN);
}
@Test
- public void testBoundByForeground() {
+ @DisableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
+ public void testBoundByForegroundOld() {
mAppSwitchState = APP_SWITCH_ALLOW;
mController.addBoundClientUid(999, "visible.package", Context.BIND_ALLOW_ACTIVITY_STARTS);
mHasActiveVisibleWindow.add(999);
@@ -159,6 +209,21 @@ public class BackgroundLaunchProcessControllerTests {
}
@Test
+ @EnableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
+ public void testBoundByForeground() {
+ mAppSwitchState = APP_SWITCH_ALLOW;
+ mController.addBoundClientUid(999, "visible.package", Context.BIND_ALLOW_ACTIVITY_STARTS);
+ mHasActiveVisibleWindow.add(999);
+ BalVerdict balVerdict = mController.areBackgroundActivityStartsAllowed(
+ mPid, mUid, mPackageName,
+ mAppSwitchState, mIsCheckingForFgsStart,
+ mHasActivityInVisibleTask, mHasBackgroundActivityStartPrivileges,
+ mLastStopAppSwitchesTime, mLastActivityLaunchTime,
+ mLastActivityFinishTime);
+ assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_BOUND_BY_FOREGROUND);
+ }
+
+ @Test
public void testForegroundTask() {
mAppSwitchState = APP_SWITCH_ALLOW;
mHasActivityInVisibleTask = true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
index 564c29f09bc9..11e6d90a5f50 100644
--- a/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
@@ -23,7 +23,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
@@ -176,22 +175,9 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
- mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
- mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
callOnActivityConfigurationChanging(mActivity);
-
- assertInCameraCompatMode();
- assertActivityRefreshRequested(/* refreshRequested */ true);
- }
-
- @Test
- public void testReconnectedToDifferentCamera_activatesCameraCompatModeAndRefresh()
- throws Exception {
- configureActivity(SCREEN_ORIENTATION_PORTRAIT);
-
- mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
- mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_2, TEST_PACKAGE_1);
+ mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
callOnActivityConfigurationChanging(mActivity);
assertInCameraCompatMode();
@@ -199,20 +185,6 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
}
@Test
- public void testCameraDisconnected_deactivatesCameraCompatMode() {
- configureActivityAndDisplay(SCREEN_ORIENTATION_PORTRAIT, ORIENTATION_LANDSCAPE,
- WINDOWING_MODE_FREEFORM);
- // Open camera and test for compat treatment
- mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
- assertInCameraCompatMode();
-
- // Close camera and test for revert
- mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
-
- assertNotInCameraCompatMode();
- }
-
- @Test
public void testCameraOpenedForDifferentPackage_notInCameraCompatMode() {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
diff --git a/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java b/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java
index e468fd8ee495..1c8dc05c6787 100644
--- a/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java
@@ -256,8 +256,7 @@ public final class CameraStateMonitorTests extends WindowTestsBase {
}
@Override
- public boolean onCameraClosed(@NonNull ActivityRecord cameraActivity,
- @NonNull String cameraId) {
+ public boolean onCameraClosed(@NonNull String cameraId) {
mOnCameraClosedCounter++;
boolean returnValue = mOnCameraClosedReturnValue;
// If false, return false only the first time, so it doesn't fall in the infinite retry
diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
index a4bec64bdf97..ad3fba3084fe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
@@ -166,9 +166,9 @@ public class DesktopModeLaunchParamsModifierTests extends
ACTIVITY_TYPE_STANDARD).setDisplay(display).build();
final int desiredWidth =
- (int) (DISPLAY_STABLE_BOUNDS.width() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
+ (int) (DISPLAY_BOUNDS.width() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
final int desiredHeight =
- (int) (DISPLAY_STABLE_BOUNDS.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
+ (int) (DISPLAY_BOUNDS.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().setTask(task).calculate());
assertEquals(desiredWidth, mResult.mBounds.width());
assertEquals(desiredHeight, mResult.mBounds.height());
diff --git a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
index 51255948ed4a..36861fae35da 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
@@ -16,6 +16,15 @@
package com.android.server.wm;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN;
+import static android.hardware.devicestate.feature.flags.Flags.FLAG_DEVICE_STATE_PROPERTY_MIGRATION;
+
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
@@ -24,8 +33,11 @@ import static org.junit.Assert.assertTrue;
import android.content.Context;
import android.content.res.Resources;
+import android.hardware.devicestate.DeviceState;
import android.hardware.devicestate.DeviceStateManager;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
import android.util.Pair;
import androidx.test.filters.SmallTest;
@@ -37,6 +49,8 @@ import com.google.common.util.concurrent.MoreExecutors;
import org.junit.Before;
import org.junit.Test;
+import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -79,39 +93,67 @@ public class DeviceStateControllerTests {
@Test
public void testInitialization() {
initialize(true /* supportFold */, true /* supportHalfFolded */);
- mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
}
@Test
public void testInitializationWithNoFoldSupport() {
initialize(false /* supportFold */, false /* supportHalfFolded */);
- mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
// Note that the folded state is ignored.
assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState);
}
@Test
- public void testWithFoldSupported() {
+ @RequiresFlagsDisabled(FLAG_DEVICE_STATE_PROPERTY_MIGRATION)
+ public void testWithFoldSupported_withOverlayConfigValues() {
initialize(true /* supportFold */, false /* supportHalfFolded */);
- mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
- mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
- mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates.get(0).getIdentifier());
assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState); // Ignored
}
@Test
- public void testWithHalfFoldSupported() {
+ @RequiresFlagsEnabled(FLAG_DEVICE_STATE_PROPERTY_MIGRATION)
+ public void testWithFoldSupported_withDeviceStateManagerPropertyAPI() {
+ initialize(true /* supportFold */, false /* supportHalfFolded */);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
+ assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
+ assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
+ mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates.get(0).getIdentifier());
+ assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState); // Ignored
+ }
+
+ @Test
+ @RequiresFlagsDisabled(FLAG_DEVICE_STATE_PROPERTY_MIGRATION)
+ public void testWithHalfFoldSupported_withOverlayConfigValue() {
+ initialize(true /* supportFold */, true /* supportHalfFolded */);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
+ assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
+ assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
+ mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates.get(0).getIdentifier());
+ assertEquals(DeviceStateController.DeviceState.HALF_FOLDED, mCurrentState);
+ mTarget.onDeviceStateReceivedByDisplayManager(mConcurrentDisplayState.getIdentifier());
+ assertEquals(DeviceStateController.DeviceState.CONCURRENT, mCurrentState);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_DEVICE_STATE_PROPERTY_MIGRATION)
+ public void testWithHalfFoldSupported_withDeviceStateManagerPropertyApi() {
initialize(true /* supportFold */, true /* supportHalfFolded */);
- mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
- mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
- mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates.get(0).getIdentifier());
assertEquals(DeviceStateController.DeviceState.HALF_FOLDED, mCurrentState);
- mTarget.onDeviceStateReceivedByDisplayManager(mConcurrentDisplayState);
+ mTarget.onDeviceStateReceivedByDisplayManager(mConcurrentDisplayState.getIdentifier());
assertEquals(DeviceStateController.DeviceState.CONCURRENT, mCurrentState);
}
@@ -121,16 +163,18 @@ public class DeviceStateControllerTests {
assertEquals(1, mTarget.mDeviceStateCallbacks.size());
assertTrue(mTarget.mDeviceStateCallbacks.containsKey(mDelegate));
- mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
- mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
// The callback should not receive state change when it is unregistered.
mTarget.unregisterDeviceStateCallback(mDelegate);
assertTrue(mTarget.mDeviceStateCallbacks.isEmpty());
- mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
- assertEquals(DeviceStateController.DeviceState.FOLDED /* unchanged */, mCurrentState);
+
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
+ assertEquals(DeviceStateController.DeviceState.FOLDED /* unchanged */,
+ mCurrentState);
}
@Test
@@ -151,16 +195,50 @@ public class DeviceStateControllerTests {
assertEquals(mExecutor, entries.get(0).second);
}
- private final int[] mFoldedStates = {0};
- private final int[] mOpenDeviceStates = {1};
- private final int[] mHalfFoldedStates = {2};
- private final int[] mRearDisplayStates = {3};
- private final int mConcurrentDisplayState = 4;
+ private final List<DeviceState> mFoldedStates = new ArrayList<>(
+ List.of(new DeviceState(new DeviceState.Configuration.Builder(0,
+ "folded").setSystemProperties(new HashSet<>(
+ List.of(PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY)))
+ .setPhysicalProperties(new HashSet<>(
+ List.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED)))
+ .build())));
+ private final List<DeviceState> mOpenDeviceStates = new ArrayList<>(
+ List.of(new DeviceState(new DeviceState.Configuration.Builder(1,
+ "open").setSystemProperties(new HashSet<>(
+ List.of(PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY)))
+ .setPhysicalProperties(new HashSet<>(
+ List.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN)))
+ .build())));
+ private final List<DeviceState> mHalfFoldedStates = new ArrayList<>(
+ List.of(new DeviceState(new DeviceState.Configuration.Builder(2,
+ "half_folded").setSystemProperties(new HashSet<>(
+ List.of(PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY)))
+ .setPhysicalProperties(new HashSet<>(
+ List.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN)))
+ .build())));
+ private final List<DeviceState> mRearDisplayStates = new ArrayList<>(
+ List.of(new DeviceState(new DeviceState.Configuration.Builder(3,
+ "rear_display").setSystemProperties(new HashSet<>(
+ List.of(PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY,
+ PROPERTY_FEATURE_REAR_DISPLAY)))
+ .setPhysicalProperties(new HashSet<>(
+ List.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN)))
+ .build())));
+ private final DeviceState mConcurrentDisplayState = new DeviceState(
+ new DeviceState.Configuration.Builder(4, "concurrent_display")
+ .setSystemProperties(new HashSet<>(List.of(
+ PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY,
+ PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT)))
+ .setPhysicalProperties(new HashSet<>(List.of(
+ PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN)))
+ .build());
private class DeviceStateControllerBuilder {
private boolean mSupportFold = false;
private boolean mSupportHalfFold = false;
+
private Consumer<DeviceStateController.DeviceState> mDelegate;
+ private final List<DeviceState> mDeviceStateList = new ArrayList<>();
DeviceStateControllerBuilder setSupportFold(
boolean supportFold, boolean supportHalfFold) {
@@ -179,13 +257,17 @@ public class DeviceStateControllerTests {
if (enableFold || enableHalfFold) {
when(mMockContext.getResources()
.getIntArray(R.array.config_openDeviceStates))
- .thenReturn(mOpenDeviceStates);
+ .thenReturn(mapDeviceStateListToIdentifierArray(mOpenDeviceStates));
when(mMockContext.getResources()
.getIntArray(R.array.config_rearDisplayDeviceStates))
- .thenReturn(mRearDisplayStates);
+ .thenReturn(mapDeviceStateListToIdentifierArray(mRearDisplayStates));
when(mMockContext.getResources()
.getInteger(R.integer.config_deviceStateConcurrentRearDisplay))
- .thenReturn(mConcurrentDisplayState);
+ .thenReturn(mConcurrentDisplayState.getIdentifier());
+
+ mDeviceStateList.addAll(mOpenDeviceStates);
+ mDeviceStateList.addAll(mRearDisplayStates);
+ mDeviceStateList.add(mConcurrentDisplayState);
} else {
// Match the default value in framework resources
when(mMockContext.getResources()
@@ -196,12 +278,14 @@ public class DeviceStateControllerTests {
if (enableFold) {
when(mMockContext.getResources()
.getIntArray(R.array.config_foldedDeviceStates))
- .thenReturn(mFoldedStates);
+ .thenReturn(mapDeviceStateListToIdentifierArray(mFoldedStates));
+ mDeviceStateList.addAll(mFoldedStates);
}
if (enableHalfFold) {
when(mMockContext.getResources()
.getIntArray(R.array.config_halfFoldedDeviceStates))
- .thenReturn(mHalfFoldedStates);
+ .thenReturn(mapDeviceStateListToIdentifierArray(mHalfFoldedStates));
+ mDeviceStateList.addAll(mHalfFoldedStates);
}
}
@@ -210,11 +294,20 @@ public class DeviceStateControllerTests {
mMockDeviceStateManager = mock(DeviceStateManager.class);
when(mMockContext.getSystemService(DeviceStateManager.class))
.thenReturn(mMockDeviceStateManager);
+ when(mMockDeviceStateManager.getSupportedDeviceStates()).thenReturn(mDeviceStateList);
Resources mockRes = mock(Resources.class);
when(mMockContext.getResources()).thenReturn((mockRes));
mockFold(mSupportFold, mSupportHalfFold);
mTarget = new DeviceStateController(mMockContext, new WindowManagerGlobalLock());
mTarget.registerDeviceStateCallback(mDelegate, mExecutor);
}
+
+ private int[] mapDeviceStateListToIdentifierArray(List<DeviceState> deviceStates) {
+ int[] identifiers = new int[deviceStates.size()];
+ for (int i = 0; i < deviceStates.size(); i++) {
+ identifiers[i] = deviceStates.get(i).getIdentifier();
+ }
+ return identifiers;
+ }
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 695750217cac..65aaf605bdfe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -117,8 +117,8 @@ import android.os.Binder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
-import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.util.ArraySet;
import android.view.Display;
@@ -1871,6 +1871,46 @@ public class DisplayContentTests extends WindowTestsBase {
assertFalse(recentsActivity.hasFixedRotationTransform());
}
+ @EnableFlags(com.android.window.flags.Flags.FLAG_RESPECT_NON_TOP_VISIBLE_FIXED_ORIENTATION)
+ @Test
+ public void testRespectNonTopVisibleFixedOrientation() {
+ spyOn(mWm.mLetterboxConfiguration);
+ doReturn(false).when(mWm.mLetterboxConfiguration).isTranslucentLetterboxingEnabled();
+ makeDisplayPortrait(mDisplayContent);
+ final ActivityRecord nonTopVisible = new ActivityBuilder(mAtm)
+ .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
+ .setCreateTask(true).build();
+ final ActivityRecord translucentTop = new ActivityBuilder(mAtm)
+ .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
+ .setTask(nonTopVisible.getTask()).setVisible(false)
+ .setActivityTheme(android.R.style.Theme_Translucent).build();
+ final TestTransitionPlayer player = registerTestTransitionPlayer();
+ mDisplayContent.requestTransitionAndLegacyPrepare(WindowManager.TRANSIT_OPEN, 0);
+ translucentTop.setVisibility(true);
+ mDisplayContent.updateOrientation();
+ assertEquals("Non-top visible activity must be portrait",
+ Configuration.ORIENTATION_PORTRAIT, nonTopVisible.getConfiguration().orientation);
+ assertEquals("Top translucent activity must be landscape",
+ Configuration.ORIENTATION_LANDSCAPE, translucentTop.getConfiguration().orientation);
+
+ player.start();
+ player.finish();
+ assertEquals("Display must be landscape after the transition is finished",
+ Configuration.ORIENTATION_LANDSCAPE,
+ mDisplayContent.getConfiguration().orientation);
+ assertEquals("Non-top visible activity must still be portrait",
+ Configuration.ORIENTATION_PORTRAIT,
+ nonTopVisible.getConfiguration().orientation);
+
+ translucentTop.finishIfPossible("test", false /* oomAdj */);
+ mDisplayContent.updateOrientation();
+ player.start();
+ player.finish();
+ assertEquals("Display must be portrait after closing the translucent activity",
+ Configuration.ORIENTATION_PORTRAIT,
+ mDisplayContent.getConfiguration().orientation);
+ }
+
@Test
public void testSecondaryInternalDisplayRotationFollowsDefaultDisplay() {
// Skip freezing so the unrelated conditions in updateRotationUnchecked won't disturb.
@@ -2832,7 +2872,7 @@ public class DisplayContentTests extends WindowTestsBase {
doReturn(true).when(() ->
DesktopModeLaunchParamsModifier.canEnterDesktopMode(any()));
- assertNotNull(createNewDisplay().mCameraCompatFreeformPolicy);
+ assertTrue(createNewDisplay().mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy());
}
@DisableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
@@ -2841,14 +2881,14 @@ public class DisplayContentTests extends WindowTestsBase {
doReturn(true).when(() ->
DesktopModeLaunchParamsModifier.canEnterDesktopMode(any()));
- assertNull(createNewDisplay().mCameraCompatFreeformPolicy);
+ assertFalse(createNewDisplay().mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy());
}
@EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
public void desktopWindowingFlagNotEnabled_cameraCompatFreeformPolicyIsNull() {
- assertNull(createNewDisplay().mCameraCompatFreeformPolicy);
+ assertFalse(createNewDisplay().mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy());
}
private void removeRootTaskTests(Runnable runnable) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index e3a85424554d..2e488d8127bb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -1607,6 +1607,7 @@ public class DisplayRotationTests {
.thenReturn(mMockDeviceStateManager);
mDeviceStateController = mock(DeviceStateController.class);
+ mMockDisplayContent.mAppCompatCameraPolicy = mock(AppCompatCameraPolicy.class);
mTarget = new TestDisplayRotation(mMockDisplayContent, mMockDisplayAddress,
mMockDisplayPolicy, mMockDisplayWindowSettings, mMockContext,
mDeviceStateController);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
index 7faf2aacc0bc..8cdb574a967b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
@@ -497,7 +497,8 @@ public class DragDropControllerTests extends WindowTestsBase {
public void testValidateFlags() {
final Session session = getTestSession();
try {
- session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION);
+ session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION,
+ 0 /* callingUid */);
fail("Expected failure without permission");
} catch (SecurityException e) {
// Expected failure
@@ -510,7 +511,8 @@ public class DragDropControllerTests extends WindowTestsBase {
.checkCallingOrSelfPermission(eq(START_TASKS_FROM_RECENTS));
final Session session = createTestSession(mAtm);
try {
- session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION);
+ session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION,
+ 0 /* callingUid */);
// Expected pass
} catch (SecurityException e) {
fail("Expected no failure with permission");
diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
index 83ad7b1b5d92..708d6860abc2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -214,7 +214,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
final Rect activityBounds = new Rect(mFirstActivity.getBounds());
// DAG is portrait (860x1200), so Task and Activity fill DAG.
- assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
assertThat(taskBounds).isEqualTo(dagBounds);
assertThat(activityBounds).isEqualTo(taskBounds);
@@ -238,7 +239,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
new Rect(mFirstActivity.getConfiguration().windowConfiguration.getBounds());
// DAG is landscape (1200x860), no fixed orientation letterbox
- assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
assertThat(mFirstActivity.inSizeCompatMode()).isTrue();
assertThat(newDagBounds.width()).isEqualTo(dagBounds.height());
assertThat(newDagBounds.height()).isEqualTo(dagBounds.width());
@@ -262,11 +264,13 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
- assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
rotateDisplay(mDisplay, ROTATION_90);
- assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
}
@@ -283,7 +287,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
// DAG is portrait (860x1200), and activity is letterboxed for fixed orientation
// (860x[860x860/1200=616]). Task fills DAG.
- assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isTrue();
+ assertThat(mFirstActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isTrue();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
assertThat(taskBounds).isEqualTo(dagBounds);
assertThat(activityBounds.width()).isEqualTo(dagBounds.width());
@@ -300,7 +305,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
- assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
}
@Test
@@ -310,7 +316,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LOCKED);
- assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
}
@Test
@@ -329,7 +336,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
final Rect newActivityBounds = new Rect(mFirstActivity.getBounds());
// DAG is landscape (1200x860), no fixed orientation letterbox
- assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
assertThat(mFirstActivity.inSizeCompatMode()).isTrue();
assertThat(newDagBounds.width()).isEqualTo(dagBounds.height());
assertThat(newDagBounds.height()).isEqualTo(dagBounds.width());
@@ -354,7 +362,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
rotateDisplay(mDisplay, ROTATION_90);
- assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
}
@@ -522,7 +531,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
assertThat(mFirstRoot.getConfiguration().orientation).isEqualTo(ORIENTATION_PORTRAIT);
assertThat(mFirstActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_PORTRAIT);
- assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
// Launch portrait on second DAG
@@ -534,13 +544,15 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_PORTRAIT);
assertThat(mSecondRoot.getConfiguration().orientation).isEqualTo(ORIENTATION_LANDSCAPE);
assertThat(mSecondActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_LANDSCAPE);
- assertThat(mSecondActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mSecondActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
assertThat(mSecondActivity.inSizeCompatMode()).isFalse();
// First activity is letterboxed in portrait as requested.
assertThat(mFirstRoot.getConfiguration().orientation).isEqualTo(ORIENTATION_LANDSCAPE);
assertThat(mFirstActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_PORTRAIT);
- assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isTrue();
+ assertThat(mFirstActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio()).isTrue();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index 74e2d44c35cc..c42367e8ae18 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -293,6 +293,7 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
mainWindow.mInvGlobalScale = 1f;
spyOn(resources);
spyOn(mActivity);
+ spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy());
if (taskbar != null) {
taskbar.setVisible(true);
@@ -301,7 +302,8 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
doReturn(mLetterboxedPortraitTaskBounds).when(mActivity).getBounds();
doReturn(false).when(mActivity).isInLetterboxAnimation();
doReturn(true).when(mActivity).isVisible();
- doReturn(true).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+ doReturn(true).when(mActivity.mAppCompatController
+ .getAppCompatAspectRatioPolicy()).isLetterboxedForFixedOrientationAndAspectRatio();
doReturn(insets).when(mainWindow).getInsetsState();
doReturn(attrs).when(mainWindow).getAttrs();
doReturn(true).when(mainWindow).isDrawn();
@@ -324,10 +326,11 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
/* value */ true);
- mController = new LetterboxUiController(mWm, mActivity);
doReturn(false).when(mLetterboxConfiguration).isUserAppAspectRatioFullscreenEnabled();
+ mActivity = setUpActivityWithComponent();
- assertFalse(mController.shouldApplyUserFullscreenOverride());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldApplyUserFullscreenOverride());
}
@Test
@@ -337,9 +340,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
/* value */ false);
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
- assertFalse(mController.shouldApplyUserFullscreenOverride());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldApplyUserFullscreenOverride());
}
@Test
@@ -348,16 +352,18 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
prepareActivityThatShouldApplyUserFullscreenOverride();
mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ false);
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
- assertFalse(mController.shouldApplyUserFullscreenOverride());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldApplyUserFullscreenOverride());
}
@Test
public void testShouldApplyUserFullscreenOverride_returnsTrue() {
prepareActivityThatShouldApplyUserFullscreenOverride();
- assertTrue(mController.shouldApplyUserFullscreenOverride());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldApplyUserFullscreenOverride());
}
@Test
@@ -369,18 +375,22 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
mActivity = setUpActivityWithComponent();
mController = new LetterboxUiController(mWm, mActivity);
- assertFalse(mController.shouldEnableUserAspectRatioSettings());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldEnableUserAspectRatioSettings());
}
@Test
public void testShouldEnableUserAspectRatioSettings_trueProperty_returnsTrue()
throws Exception {
- prepareActivityThatShouldApplyUserMinAspectRatioOverride();
+
mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ true);
+ mActivity = setUpActivityWithComponent();
+ prepareActivityThatShouldApplyUserMinAspectRatioOverride();
mController = new LetterboxUiController(mWm, mActivity);
- assertTrue(mController.shouldEnableUserAspectRatioSettings());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldEnableUserAspectRatioSettings());
}
@Test
@@ -391,7 +401,8 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
mController = new LetterboxUiController(mWm, mActivity);
- assertFalse(mController.shouldEnableUserAspectRatioSettings());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldEnableUserAspectRatioSettings());
}
@Test
@@ -400,9 +411,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
prepareActivityThatShouldApplyUserMinAspectRatioOverride();
mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ false);
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
- assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldEnableUserAspectRatioSettings());
}
@Test
@@ -411,9 +423,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
doReturn(false).when(mLetterboxConfiguration).isUserAppAspectRatioSettingsEnabled();
mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ true);
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
- assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldApplyUserMinAspectRatioOverride());
}
@Test
@@ -421,30 +434,35 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
prepareActivityThatShouldApplyUserMinAspectRatioOverride();
mDisplayContent.setIgnoreOrientationRequest(false);
- assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldApplyUserMinAspectRatioOverride());
}
@Test
public void testShouldApplyUserMinAspectRatioOverride_returnsTrue() {
prepareActivityThatShouldApplyUserMinAspectRatioOverride();
- assertTrue(mController.shouldApplyUserMinAspectRatioOverride());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldApplyUserMinAspectRatioOverride());
}
@Test
public void testShouldApplyUserMinAspectRatioOverride_noIgnoreOrientation_returnsFalse() {
prepareActivityForShouldApplyUserMinAspectRatioOverride(/* orientationRequest */ false);
- assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldApplyUserMinAspectRatioOverride());
}
private void prepareActivityForShouldApplyUserMinAspectRatioOverride(
boolean orientationRequest) {
- spyOn(mController);
+ spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides());
doReturn(orientationRequest).when(
mLetterboxConfiguration).isUserAppAspectRatioSettingsEnabled();
mDisplayContent.setIgnoreOrientationRequest(true);
- doReturn(USER_MIN_ASPECT_RATIO_3_2).when(mController).getUserMinAspectRatioOverrideCode();
+ doReturn(USER_MIN_ASPECT_RATIO_3_2)
+ .when(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides())
+ .getUserMinAspectRatioOverrideCode();
}
private void prepareActivityThatShouldApplyUserMinAspectRatioOverride() {
@@ -452,10 +470,11 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
}
private void prepareActivityThatShouldApplyUserFullscreenOverride() {
- spyOn(mController);
+ spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides());
doReturn(true).when(mLetterboxConfiguration).isUserAppAspectRatioFullscreenEnabled();
mDisplayContent.setIgnoreOrientationRequest(true);
- doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN).when(mController)
+ doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN)
+ .when(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides())
.getUserMinAspectRatioOverrideCode();
}
@@ -578,9 +597,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
@Test
@EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
public void testshouldOverrideMinAspectRatio_overrideEnabled_returnsTrue() {
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
- assertTrue(mController.shouldOverrideMinAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldOverrideMinAspectRatio());
}
@Test
@@ -588,9 +608,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
public void testshouldOverrideMinAspectRatio_propertyTrue_overrideEnabled_returnsTrue()
throws Exception {
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
- assertTrue(mController.shouldOverrideMinAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldOverrideMinAspectRatio());
}
@Test
@@ -598,17 +619,19 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
public void testshouldOverrideMinAspectRatio_propertyTrue_overrideDisabled_returnsFalse()
throws Exception {
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
- assertFalse(mController.shouldOverrideMinAspectRatio());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldOverrideMinAspectRatio());
}
@Test
@DisableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
public void testshouldOverrideMinAspectRatio_overrideDisabled_returnsFalse() {
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
- assertFalse(mController.shouldOverrideMinAspectRatio());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldOverrideMinAspectRatio());
}
@Test
@@ -618,9 +641,9 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
mActivity = setUpActivityWithComponent();
- mController = new LetterboxUiController(mWm, mActivity);
- assertFalse(mController.shouldOverrideMinAspectRatio());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldOverrideMinAspectRatio());
}
@Test
@@ -628,16 +651,18 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
public void testshouldOverrideMinAspectRatio_propertyFalse_noOverride_returnsFalse()
throws Exception {
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
- assertFalse(mController.shouldOverrideMinAspectRatio());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()
+ .shouldOverrideMinAspectRatio());
}
@Test
@EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
public void shouldOverrideMinAspectRatioForCamera_overrideEnabled_returnsTrue() {
- doReturn(true).when(mActivity).isCameraActive();
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
+ doReturn(true).when(mActivity.mAppCompatController
+ .getAppCompatCameraOverrides()).isCameraActive();
assertTrue(mActivity.mAppCompatController.getAppCompatCameraOverrides()
.shouldOverrideMinAspectRatioForCamera());
@@ -647,9 +672,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
@EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
public void shouldOverrideMinAspectRatioForCamera_propertyTrue_overrideEnabled_returnsTrue()
throws Exception {
- doReturn(true).when(mActivity).isCameraActive();
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
+ doReturn(true).when(mActivity.mAppCompatController
+ .getAppCompatCameraOverrides()).isCameraActive();
assertTrue(mActivity.mAppCompatController.getAppCompatCameraOverrides()
.shouldOverrideMinAspectRatioForCamera());
@@ -659,9 +685,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
@EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
public void shouldOverrideMinAspectRatioForCamera_propertyTrue_overrideEnabled_returnsFalse()
throws Exception {
- doReturn(false).when(mActivity).isCameraActive();
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
+ doReturn(false).when(mActivity.mAppCompatController
+ .getAppCompatCameraOverrides()).isCameraActive();
assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
.shouldOverrideMinAspectRatioForCamera());
@@ -671,9 +698,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
@DisableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
public void shouldOverrideMinAspectRatioForCamera_propertyTrue_overrideDisabled_returnsFalse()
throws Exception {
- doReturn(true).when(mActivity).isCameraActive();
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
+ doReturn(true).when(mActivity.mAppCompatController
+ .getAppCompatCameraOverrides()).isCameraActive();
assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
.shouldOverrideMinAspectRatioForCamera());
@@ -682,8 +710,9 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
@Test
@DisableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
public void shouldOverrideMinAspectRatioForCamera_overrideDisabled_returnsFalse() {
- doReturn(true).when(mActivity).isCameraActive();
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
+ doReturn(true).when(mActivity.mAppCompatController
+ .getAppCompatCameraOverrides()).isCameraActive();
assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
.shouldOverrideMinAspectRatioForCamera());
@@ -694,7 +723,7 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
public void shouldOverrideMinAspectRatioForCamera_propertyFalse_overrideEnabled_returnsFalse()
throws Exception {
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
- mController = new LetterboxUiController(mWm, mActivity);
+ mActivity = setUpActivityWithComponent();
assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
.shouldOverrideMinAspectRatioForCamera());
@@ -705,8 +734,11 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
public void shouldOverrideMinAspectRatioForCamera_propertyFalse_noOverride_returnsFalse()
throws Exception {
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
- doReturn(true).when(mActivity).isCameraActive();
- mController = new LetterboxUiController(mWm, mActivity);
+
+ mActivity = setUpActivityWithComponent();
+
+ doReturn(true).when(mActivity.mAppCompatController
+ .getAppCompatCameraOverrides()).isCameraActive();
assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
.shouldOverrideMinAspectRatioForCamera());
@@ -848,12 +880,14 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
assertEquals(1.5f, mController.getFixedOrientationLetterboxAspectRatio(
mActivity.getParent().getConfiguration()), /* delta */ 0.01);
- spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
- doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
+ spyOn(mDisplayContent.mAppCompatCameraPolicy);
+ doReturn(true).when(mDisplayContent.mAppCompatCameraPolicy)
.isTreatmentEnabledForActivity(eq(mActivity));
- assertEquals(mController.getSplitScreenAspectRatio(),
- mController.getFixedOrientationLetterboxAspectRatio(
+ final AppCompatAspectRatioOverrides aspectRatioOverrides =
+ mActivity.mAppCompatController.getAppCompatAspectRatioOverrides();
+ assertEquals(aspectRatioOverrides.getSplitScreenAspectRatio(),
+ aspectRatioOverrides.getFixedOrientationLetterboxAspectRatio(
mActivity.getParent().getConfiguration()), /* delta */ 0.01);
}
@@ -980,6 +1014,7 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
.setComponent(ComponentName.createRelative(mContext,
com.android.server.wm.LetterboxUiControllerTest.class.getName()))
.build();
+ spyOn(activity.mAppCompatController.getAppCompatCameraOverrides());
return activity;
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java b/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
index 7efbc88833cf..35cff7a7a324 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
@@ -25,11 +25,11 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.protolog.ProtoLogGroup;
import com.android.internal.protolog.ProtoLogImpl;
import com.android.internal.protolog.common.IProtoLog;
import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.ProtoLog;
import org.junit.After;
import org.junit.Ignore;
@@ -53,9 +53,6 @@ public class ProtoLogIntegrationTest {
runWith(mockedProtoLog, this::testProtoLog);
verify(mockedProtoLog).log(eq(LogLevel.ERROR), eq(ProtoLogGroup.TEST_GROUP),
anyInt(), eq(0b0010010111),
- eq(com.android.internal.protolog.ProtoLogGroup.TEST_GROUP.isLogToLogcat()
- ? "Test completed successfully: %b %d %x %f %% %s"
- : null),
eq(new Object[]{true, 1L, 2L, 0.3, "ok"}));
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 6ec1429200e6..33f7035dbf18 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -653,6 +653,34 @@ public class RecentTasksTest extends WindowTestsBase {
}
@Test
+ public void testTrimNonTrimmableTask_isTrimmable_returnsFalse() {
+ Task nonTrimmableTask = createTaskBuilder(".NonTrimmableTask").setFlags(
+ FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS).build();
+ nonTrimmableTask.mIsTrimmableFromRecents = false;
+
+ // Move home to front so the task can satisfy the condition in RecentTasks#isTrimmable.
+ mRootWindowContainer.getDefaultTaskDisplayArea().getRootHomeTask().moveToFront("test");
+
+ assertThat(mRecentTasks.isTrimmable(nonTrimmableTask)).isFalse();
+ }
+
+ @Test
+ public void testTrimNonTrimmableTask_taskNotTrimmed() {
+ Task nonTrimmableTask = createTaskBuilder(".NonTrimmableTask").setFlags(
+ FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS).build();
+ nonTrimmableTask.mIsTrimmableFromRecents = false;
+
+ // Move home to front so the task can satisfy the condition in RecentTasks#isTrimmable.
+ mRootWindowContainer.getDefaultTaskDisplayArea().getRootHomeTask().moveToFront("test");
+
+ mRecentTasks.add(mTasks.get(0));
+ mRecentTasks.add(nonTrimmableTask);
+ mRecentTasks.add(mTasks.get(1));
+
+ triggerTrimAndAssertNoTasksTrimmed();
+ }
+
+ @Test
public void testSessionDuration() {
mRecentTasks.setOnlyTestVisibleRange();
mRecentTasks.setParameters(-1 /* min */, -1 /* max */, 50 /* ms */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index c1be5ca562b1..63e3e5cf865a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -714,7 +714,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
// Simulate when the window is exiting and cleanupAnimation invoked
// (e.g. screen off during RecentsAnimation animating), will expect the window receives
// onExitAnimationDone to destroy the surface when the removal is allowed.
- win1.mWinAnimator.mSurfaceController = mock(WindowSurfaceController.class);
+ win1.mWinAnimator.mSurfaceControl = mock(SurfaceControl.class);
win1.mHasSurface = true;
win1.mAnimatingExit = true;
win1.mRemoveOnExit = true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index 11d9629cf25e..0bf27d11493b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -43,8 +43,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
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.Mockito.mock;
@@ -758,12 +756,9 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
// Simulating win1 has shown IME and being IME layering/input target
mDisplayContent.setImeLayeringTarget(win1);
mDisplayContent.setImeInputTarget(win1);
- mImeWindow.mWinAnimator.mSurfaceController = mock(WindowSurfaceController.class);
mImeWindow.mWinAnimator.hide(mDisplayContent.getPendingTransaction(), "test");
spyOn(mDisplayContent);
- doReturn(true).when(mImeWindow.mWinAnimator.mSurfaceController).hasSurface();
- doReturn(true).when(mImeWindow.mWinAnimator.mSurfaceController)
- .prepareToShowInTransaction(any(), anyFloat());
+ mImeWindow.mWinAnimator.mSurfaceControl = mock(SurfaceControl.class);
makeWindowVisibleAndDrawn(mImeWindow);
assertTrue(mImeWindow.isOnScreen());
assertFalse(mImeWindow.isParentWindowHidden());
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 3078df026d8a..d29505f02fe8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -274,17 +274,28 @@ public class RootWindowContainerTests extends WindowTestsBase {
@Test
public void testAttachApplication() {
- final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setProcessName("testAttach")
+ .setCreateTask(true).build();
+ final ActivityRecord topActivity = new ActivityBuilder(mAtm).setProcessName("testAttach")
+ .setUseProcess(activity.app).setTask(activity.getTask()).build();
activity.detachFromProcess();
- mAtm.startProcessAsync(activity, false /* knownToBeDead */,
+ topActivity.detachFromProcess();
+ mAtm.startProcessAsync(topActivity, false /* knownToBeDead */,
true /* isTop */, "test" /* hostingType */);
+ // Even if the activity is added after topActivity, the start order should still follow
+ // z-order, i.e. the topActivity will be started first.
+ mAtm.startProcessAsync(activity, false /* knownToBeDead */,
+ false /* isTop */, "test" /* hostingType */);
+ assertEquals(2, mAtm.mStartingProcessActivities.size());
+ assertEquals("Top record must be at the tail to start first",
+ topActivity, mAtm.mStartingProcessActivities.get(1));
final WindowProcessController proc = mSystemServicesTestRule.addProcess(
activity.packageName, activity.processName,
6789 /* pid */, activity.info.applicationInfo.uid);
try {
mRootWindowContainer.attachApplication(proc);
- verify(mSupervisor).realStartActivityLocked(eq(activity), eq(proc), anyBoolean(),
- anyBoolean());
+ verify(mSupervisor).realStartActivityLocked(eq(topActivity), eq(proc),
+ anyBoolean(), anyBoolean());
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
@@ -428,7 +439,8 @@ public class RootWindowContainerTests extends WindowTestsBase {
final Rect bounds = new Rect(task.getBounds());
bounds.scale(0.5f);
task.setBounds(bounds);
- assertFalse(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(activity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertThat(task.autoRemoveRecents).isFalse();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 64527cb63e45..ae88b1baa5b8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -64,6 +64,7 @@ import static com.android.server.wm.ActivityRecord.State.PAUSED;
import static com.android.server.wm.ActivityRecord.State.RESTARTING_PROCESS;
import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.ActivityRecord.State.STOPPED;
+import static com.android.server.wm.AppCompatUtils.computeAspectRatio;
import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_POSITION_MULTIPLIER_CENTER;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
@@ -103,6 +104,7 @@ import android.graphics.Rect;
import android.os.Binder;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
@@ -494,7 +496,7 @@ public class SizeCompatTests extends WindowTestsBase {
// Activity is sandboxed; it is in size compat mode since it is not resizable and has a
// max aspect ratio.
assertActivityMaxBoundsSandboxed();
- assertScaled();
+ assertDownScaled();
}
@Test
@@ -514,7 +516,7 @@ public class SizeCompatTests extends WindowTestsBase {
// The bounds should be [100, 0 - 1100, 2500].
assertEquals(origBounds.width(), currentBounds.width());
assertEquals(origBounds.height(), currentBounds.height());
- assertScaled();
+ assertDownScaled();
// The scale is 2000/2500=0.8. The horizontal centered offset is (1000-(1000*0.8))/2=100.
final float scale = (float) display.mBaseDisplayHeight / currentBounds.height();
@@ -554,7 +556,7 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(origBounds.width(), currentBounds.width());
assertEquals(origBounds.height(), currentBounds.height());
assertEquals(offsetX, mActivity.getBounds().left);
- assertScaled();
+ assertDownScaled();
// Activity is sandboxed due to size compat mode.
assertActivityMaxBoundsSandboxed();
@@ -692,7 +694,7 @@ public class SizeCompatTests extends WindowTestsBase {
// The configuration bounds [820, 0 - 1820, 2500] should keep the same.
assertEquals(originalBounds.width(), currentBounds.width());
assertEquals(originalBounds.height(), currentBounds.height());
- assertScaled();
+ assertDownScaled();
// Activity max bounds are sandboxed due to size compat mode on the new display.
assertActivityMaxBoundsSandboxed();
@@ -751,7 +753,7 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(origAppBounds.width(), appBounds.width());
assertEquals(origAppBounds.height(), appBounds.height());
// The activity is 1000x1400 and the display is 2500x1000.
- assertScaled();
+ assertDownScaled();
final float scale = mActivity.getCompatScale();
// The position in configuration should be in app coordinates.
final Rect screenBounds = mActivity.getBounds();
@@ -848,7 +850,7 @@ public class SizeCompatTests extends WindowTestsBase {
// Size compatibility mode is able to handle orientation change so the process shouldn't be
// restarted and the override configuration won't be cleared.
verify(mActivity, never()).restartProcessIfVisible();
- assertScaled();
+ assertDownScaled();
// Activity max bounds are sandboxed due to size compat mode, even if is not visible.
assertActivityMaxBoundsSandboxed();
@@ -1081,10 +1083,11 @@ public class SizeCompatTests extends WindowTestsBase {
// Simulate the user selecting the fullscreen user aspect ratio override
spyOn(activity.mWmService.mLetterboxConfiguration);
- spyOn(activity.mLetterboxUiController);
+ spyOn(activity.mAppCompatController.getAppCompatAspectRatioOverrides());
doReturn(true).when(activity.mWmService.mLetterboxConfiguration)
.isUserAppAspectRatioFullscreenEnabled();
- doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN).when(activity.mLetterboxUiController)
+ doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN)
+ .when(activity.mAppCompatController.getAppCompatAspectRatioOverrides())
.getUserMinAspectRatioOverrideCode();
assertFalse(activity.shouldCreateCompatDisplayInsets());
}
@@ -1102,9 +1105,10 @@ public class SizeCompatTests extends WindowTestsBase {
RESIZE_MODE_UNRESIZEABLE, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// Simulate the user selecting the fullscreen user aspect ratio override
- spyOn(activity.mLetterboxUiController);
- doReturn(true).when(activity.mLetterboxUiController)
- .isSystemOverrideToFullscreenEnabled();
+ spyOn(activity.mAppCompatController.getAppCompatAspectRatioOverrides());
+ doReturn(true).when(
+ activity.mAppCompatController.getAppCompatAspectRatioOverrides())
+ .isSystemOverrideToFullscreenEnabled();
assertFalse(activity.shouldCreateCompatDisplayInsets());
}
@@ -1123,7 +1127,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(activity, /* maxAspect=*/ 1.5f, SCREEN_ORIENTATION_LANDSCAPE);
// Activity max bounds should not be sandboxed, even though it is letterboxed.
- assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(activity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertThat(activity.getConfiguration().windowConfiguration.getMaxBounds())
.isEqualTo(activity.getDisplayArea().getBounds());
}
@@ -1164,7 +1169,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(activity, /* maxAspect=*/ 1.5f, SCREEN_ORIENTATION_LANDSCAPE);
// Activity max bounds should not be sandboxed, even though it is letterboxed.
- assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(activity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertThat(activity.getConfiguration().windowConfiguration.getMaxBounds())
.isEqualTo(activity.getDisplayArea().getBounds());
}
@@ -1187,7 +1193,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(activity, /* maxAspect=*/ 1.5f, SCREEN_ORIENTATION_LANDSCAPE);
// Activity max bounds should not be sandboxed, even though it is letterboxed.
- assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(activity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertThat(activity.getConfiguration().windowConfiguration.getMaxBounds())
.isEqualTo(activity.getDisplayArea().getBounds());
}
@@ -1618,6 +1625,85 @@ public class SizeCompatTests extends WindowTestsBase {
activity.getBounds().width(), 0.5);
}
+
+ /**
+ * Test that a freeform unresizeable activity can be down-scaled to fill its smaller parent
+ * bounds.
+ */
+ @Test
+ public void testCompatScaling_freeformUnresizeableApp_largerThanParent_downScaled() {
+ final int dw = 600;
+ final int dh = 800;
+ final DisplayContent display = new TestDisplayContent.Builder(mAtm, dw, dh)
+ .setWindowingMode(WINDOWING_MODE_FREEFORM)
+ .build();
+ setUpApp(display);
+ prepareUnresizable(mActivity, /* maxAspect */ 0f, SCREEN_ORIENTATION_PORTRAIT);
+ mActivity.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ assertFalse(mActivity.inSizeCompatMode());
+
+ // Resize app to make original app bounds larger than parent bounds.
+ mTask.getWindowConfiguration().setAppBounds(
+ new Rect(0, 0, dw - 300, dh - 400));
+ mActivity.onConfigurationChanged(mTask.getConfiguration());
+ // App should enter size compat mode and be down-scaled to fill new parent bounds.
+ assertDownScaled();
+ }
+
+ /**
+ * Test that when desktop mode is enabled, a freeform unresizeable activity can be up-scaled to
+ * fill its larger parent bounds.
+ */
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ public void testCompatScaling_freeformUnresizeableApp_smallerThanParent_upScaled() {
+ doReturn(true).when(() ->
+ DesktopModeLaunchParamsModifier.canEnterDesktopMode(any()));
+ final int dw = 600;
+ final int dh = 800;
+ final DisplayContent display = new TestDisplayContent.Builder(mAtm, dw, dh)
+ .setWindowingMode(WINDOWING_MODE_FREEFORM)
+ .build();
+ setUpApp(display);
+ prepareUnresizable(mActivity, /* maxAspect */ 0f, SCREEN_ORIENTATION_PORTRAIT);
+ mActivity.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ assertFalse(mActivity.inSizeCompatMode());
+
+ // Resize app to make original app bounds smaller than parent bounds.
+ mTask.getWindowConfiguration().setAppBounds(
+ new Rect(0, 0, dw + 300, dh + 400));
+ mActivity.onConfigurationChanged(mTask.getConfiguration());
+ // App should enter size compat mode and be up-scaled to fill parent bounds.
+ assertUpScaled();
+ }
+
+ /**
+ * Test that when desktop mode is disabled, a freeform unresizeable activity cannot be up-scaled
+ * despite its larger parent bounds.
+ */
+ @Test
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ public void testSizeCompatScaling_freeformUnresizeableApp_smallerThanParent_notScaled() {
+ final int dw = 600;
+ final int dh = 800;
+ final DisplayContent display = new TestDisplayContent.Builder(mAtm, dw, dh)
+ .setWindowingMode(WINDOWING_MODE_FREEFORM)
+ .build();
+ setUpApp(display);
+ prepareUnresizable(mActivity, /* maxAspect */ 0f, SCREEN_ORIENTATION_PORTRAIT);
+ mActivity.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ assertFalse(mActivity.inSizeCompatMode());
+ final Rect originalAppBounds = mActivity.getBounds();
+
+ // Resize app to make original app bounds smaller than parent bounds.
+ mTask.getWindowConfiguration().setAppBounds(
+ new Rect(0, 0, dw + 300, dh + 400));
+ mActivity.onConfigurationChanged(mTask.getConfiguration());
+ // App should enter size compat mode but remain its original size.
+ assertTrue(mActivity.inSizeCompatMode());
+ assertEquals(originalAppBounds, mActivity.getBounds());
+ }
+
@Test
public void testGetLetterboxInnerBounds_noScalingApplied() {
// Set up a display in portrait and ignoring orientation request.
@@ -1636,7 +1722,8 @@ public class SizeCompatTests extends WindowTestsBase {
addWindowToActivity(mActivity);
// App should launch in fullscreen.
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
// Activity inherits max bounds from TaskDisplayArea.
@@ -1650,8 +1737,9 @@ public class SizeCompatTests extends WindowTestsBase {
assertTrue(rotatedDisplayBounds.width() < rotatedDisplayBounds.height());
// App should be in size compat.
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
- assertScaled();
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
+ assertDownScaled();
assertThat(mActivity.inSizeCompatMode()).isTrue();
assertActivityMaxBoundsSandboxed();
@@ -1762,7 +1850,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertTrue(displayBounds.width() > displayBounds.height());
// App should launch in fixed orientation letterbox.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
assertActivityMaxBoundsSandboxed();
@@ -1793,7 +1882,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertTrue(displayBounds.width() > displayBounds.height());
// App should launch in fixed orientation letterbox.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
// Activity bounds should respect minimum aspect ratio for activity.
@@ -1823,7 +1913,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertTrue(displayBounds.width() > displayBounds.height());
// App should launch in fixed orientation letterbox.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
// Activity bounds should respect maximum aspect ratio for activity.
@@ -1853,7 +1944,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertTrue(displayBounds.width() > displayBounds.height());
// App should launch in fixed orientation letterbox.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
// Activity bounds should respect aspect ratio override for fixed orientation letterbox.
@@ -1950,7 +2042,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertTrue(displayBounds.width() > displayBounds.height());
// App should launch in fixed orientation letterbox.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
// Letterbox logic should use config_letterboxDefaultMinAspectRatioForUnresizableApps over
@@ -1976,7 +2069,8 @@ public class SizeCompatTests extends WindowTestsBase {
// App should launch in fixed orientation letterbox.
// Activity bounds should be 700x1400 with the ratio as the display.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFitted();
assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
assertTrue(originalScreenWidthDp < originalScreenHeighthDp);
@@ -1986,7 +2080,7 @@ public class SizeCompatTests extends WindowTestsBase {
// After we rotate, the activity should go in the size-compat mode and report the same
// configuration values.
- assertScaled();
+ assertDownScaled();
assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
assertEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp);
assertEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp);
@@ -2018,7 +2112,8 @@ public class SizeCompatTests extends WindowTestsBase {
// App should launch in fixed orientation letterbox.
// Activity bounds should be 700x1400 with the ratio as the display.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFitted();
assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
assertTrue(originalScreenWidthDp < originalScreenHeighthDp);
@@ -2052,7 +2147,8 @@ public class SizeCompatTests extends WindowTestsBase {
final Rect activityBounds = new Rect(mActivity.getBounds());
// App should launch in fixed orientation letterbox.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
// Checking that there is no size compat mode.
assertFitted();
@@ -2081,9 +2177,10 @@ public class SizeCompatTests extends WindowTestsBase {
.isUserAppAspectRatioFullscreenEnabled();
// Set user aspect ratio override
- spyOn(mActivity.mLetterboxUiController);
- doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN).when(mActivity.mLetterboxUiController)
- .getUserMinAspectRatioOverrideCode();
+ spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides());
+ doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN)
+ .when(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides())
+ .getUserMinAspectRatioOverrideCode();
prepareMinAspectRatio(mActivity, 16 / 9f, SCREEN_ORIENTATION_PORTRAIT);
@@ -2105,9 +2202,10 @@ public class SizeCompatTests extends WindowTestsBase {
.isUserAppAspectRatioFullscreenEnabled();
// Set user aspect ratio override
- spyOn(mActivity.mLetterboxUiController);
- doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN).when(mActivity.mLetterboxUiController)
- .getUserMinAspectRatioOverrideCode();
+ spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides());
+ doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN)
+ .when(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides())
+ .getUserMinAspectRatioOverrideCode();
prepareMinAspectRatio(mActivity, 16 / 9f, SCREEN_ORIENTATION_LANDSCAPE);
@@ -2124,9 +2222,10 @@ public class SizeCompatTests extends WindowTestsBase {
final int displayHeight = 1400;
setUpDisplaySizeWithApp(displayWidth, displayHeight);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
- spyOn(mActivity.mLetterboxUiController);
- doReturn(true).when(mActivity.mLetterboxUiController)
- .isSystemOverrideToFullscreenEnabled();
+ spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides());
+ doReturn(true).when(
+ mActivity.mAppCompatController.getAppCompatAspectRatioOverrides())
+ .isSystemOverrideToFullscreenEnabled();
prepareMinAspectRatio(mActivity, 16 / 9f, SCREEN_ORIENTATION_PORTRAIT);
@@ -2143,9 +2242,10 @@ public class SizeCompatTests extends WindowTestsBase {
final int displayHeight = 1600;
setUpDisplaySizeWithApp(displayWidth, displayHeight);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
- spyOn(mActivity.mLetterboxUiController);
- doReturn(true).when(mActivity.mLetterboxUiController)
- .isSystemOverrideToFullscreenEnabled();
+ spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides());
+ doReturn(true).when(
+ mActivity.mAppCompatController.getAppCompatAspectRatioOverrides())
+ .isSystemOverrideToFullscreenEnabled();
prepareMinAspectRatio(mActivity, 16 / 9f, SCREEN_ORIENTATION_LANDSCAPE);
@@ -2588,7 +2688,8 @@ public class SizeCompatTests extends WindowTestsBase {
final Rect activityBounds = new Rect(mActivity.getBounds());
// App should launch in fixed orientation letterbox.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
// Checking that there is no size compat mode.
assertFitted();
@@ -2632,13 +2733,14 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode());
// App should launch in fixed orientation letterbox.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
// Checking that there is no size compat mode.
assertFitted();
// Check that the display aspect ratio is used by the app.
final float targetMinAspectRatio = 1f * displayHeight / displayWidth;
- assertEquals(targetMinAspectRatio, ActivityRecord
- .computeAspectRatio(mActivity.getBounds()), DELTA_ASPECT_RATIO_TOLERANCE);
+ assertEquals(targetMinAspectRatio, computeAspectRatio(mActivity.getBounds()),
+ DELTA_ASPECT_RATIO_TOLERANCE);
}
@Test
@@ -2667,13 +2769,14 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode());
// App should launch in fixed orientation letterbox.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
// Checking that there is no size compat mode.
assertFitted();
// Check that the display aspect ratio is used by the app.
final float targetMinAspectRatio = 1f * displayWidth / displayHeight;
- assertEquals(targetMinAspectRatio, ActivityRecord
- .computeAspectRatio(mActivity.getBounds()), DELTA_ASPECT_RATIO_TOLERANCE);
+ assertEquals(targetMinAspectRatio, computeAspectRatio(mActivity.getBounds()),
+ DELTA_ASPECT_RATIO_TOLERANCE);
}
@Test
@@ -2693,13 +2796,14 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
// App should launch in fixed orientation letterbox.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
// Checking that there is no size compat mode.
assertFitted();
// Check that the display aspect ratio is used by the app.
final float targetMinAspectRatio = 1f * displayHeight / displayWidth;
- assertEquals(targetMinAspectRatio, ActivityRecord
- .computeAspectRatio(mActivity.getBounds()), DELTA_ASPECT_RATIO_TOLERANCE);
+ assertEquals(targetMinAspectRatio, computeAspectRatio(mActivity.getBounds()),
+ DELTA_ASPECT_RATIO_TOLERANCE);
}
@Test
@@ -2719,13 +2823,14 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
// App should launch in fixed orientation letterbox.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
// Checking that there is no size compat mode.
assertFitted();
// Check that the display aspect ratio is used by the app.
final float targetMinAspectRatio = 1f * displayWidth / displayHeight;
- assertEquals(targetMinAspectRatio, ActivityRecord
- .computeAspectRatio(mActivity.getBounds()), DELTA_ASPECT_RATIO_TOLERANCE);
+ assertEquals(targetMinAspectRatio, computeAspectRatio(mActivity.getBounds()),
+ DELTA_ASPECT_RATIO_TOLERANCE);
}
@Test
@@ -2748,8 +2853,9 @@ public class SizeCompatTests extends WindowTestsBase {
assertTrue(displayBounds.width() < displayBounds.height());
// App should be in size compat.
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
- assertScaled();
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
+ assertDownScaled();
assertEquals(activityBounds.width(), newActivityBounds.width());
assertEquals(activityBounds.height(), newActivityBounds.height());
assertActivityMaxBoundsSandboxed();
@@ -2765,7 +2871,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
// App should launch in fullscreen.
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
// Activity inherits max bounds from TaskDisplayArea.
assertMaxBoundsInheritDisplayAreaBounds();
@@ -2778,8 +2885,9 @@ public class SizeCompatTests extends WindowTestsBase {
assertTrue(rotatedDisplayBounds.width() > rotatedDisplayBounds.height());
// App should be in size compat.
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
- assertScaled();
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
+ assertDownScaled();
assertThat(mActivity.inSizeCompatMode()).isTrue();
assertActivityMaxBoundsSandboxed();
@@ -2799,7 +2907,8 @@ public class SizeCompatTests extends WindowTestsBase {
// Portrait fixed app without max aspect.
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
// Launch another portrait fixed app.
@@ -2821,7 +2930,8 @@ public class SizeCompatTests extends WindowTestsBase {
// Task and display bounds should be equal while activity should be letterboxed and
// has 700x1400 bounds with the ratio as the display.
- assertTrue(newActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(newActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(newActivity.inSizeCompatMode());
// Activity max bounds are sandboxed due to size compat mode.
assertThat(newActivity.getConfiguration().windowConfiguration.getMaxBounds())
@@ -2842,7 +2952,8 @@ public class SizeCompatTests extends WindowTestsBase {
// Portrait fixed app without max aspect.
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
@@ -2863,7 +2974,8 @@ public class SizeCompatTests extends WindowTestsBase {
// Portrait fixed app without max aspect.
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
// Launch another portrait fixed app with max aspect ratio as 1.3.
@@ -2893,7 +3005,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertActivityMaxBoundsSandboxed();
// Activity bounds should be (1400 / 1.3 = 1076)x1400 with the app requested ratio.
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(newActivity.inSizeCompatMode());
assertEquals(displayBounds.height(), newActivityBounds.height());
assertEquals((long) Math.rint(newActivityBounds.height()
@@ -2912,15 +3025,17 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
clearInvocations(mActivity);
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
// Rotate display to portrait.
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
// App should be in size compat.
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
- assertScaled();
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
+ assertDownScaled();
assertThat(mActivity.inSizeCompatMode()).isTrue();
// Activity max bounds are sandboxed due to size compat mode.
assertActivityMaxBoundsSandboxed();
@@ -2930,8 +3045,9 @@ public class SizeCompatTests extends WindowTestsBase {
// App still in size compat, and the bounds don't change.
verify(mActivity, never()).clearSizeCompatMode();
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
- assertScaled();
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
+ assertDownScaled();
assertEquals(activityBounds, mActivity.getBounds());
// Activity max bounds are sandboxed due to size compat.
assertActivityMaxBoundsSandboxed();
@@ -2948,7 +3064,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
// In fixed orientation letterbox
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
assertActivityMaxBoundsSandboxed();
@@ -2956,15 +3073,17 @@ public class SizeCompatTests extends WindowTestsBase {
rotateDisplay(display, ROTATION_90);
// App should be in size compat.
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
- assertScaled();
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
+ assertDownScaled();
assertActivityMaxBoundsSandboxed();
// Rotate display to landscape.
rotateDisplay(display, ROTATION_180);
// In activity letterbox
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
assertActivityMaxBoundsSandboxed();
}
@@ -2982,7 +3101,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_LANDSCAPE);
// In fixed orientation letterbox
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
assertActivityMaxBoundsSandboxed();
@@ -2990,15 +3110,17 @@ public class SizeCompatTests extends WindowTestsBase {
rotateDisplay(display, ROTATION_90);
// App should be in size compat.
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
- assertScaled();
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
+ assertDownScaled();
assertActivityMaxBoundsSandboxed();
// Rotate display to portrait.
rotateDisplay(display, ROTATION_180);
// In fixed orientation letterbox
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
assertActivityMaxBoundsSandboxed();
}
@@ -3182,7 +3304,7 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode());
// Non-resizable activity in size compat mode
- assertScaled();
+ assertDownScaled();
final Rect newBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
assertEquals(originalBounds.width(), newBounds.width());
assertEquals(originalBounds.height(), newBounds.height());
@@ -3195,7 +3317,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(ORIENTATION_PORTRAIT, mTask.getConfiguration().orientation);
assertEquals(ORIENTATION_LANDSCAPE, mActivity.getConfiguration().orientation);
assertFitted();
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertActivityMaxBoundsSandboxed();
// Letterbox should fill the gap between the split screen and the letterboxed activity.
@@ -3221,7 +3344,8 @@ public class SizeCompatTests extends WindowTestsBase {
// Resizable activity is not in size compat mode but in the letterbox for fixed orientation.
assertFitted();
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
}
@Test
@@ -3244,7 +3368,7 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode());
// Non-resizable activity in size compat mode
- assertScaled();
+ assertDownScaled();
final Rect newBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
assertEquals(originalBounds.width(), newBounds.width());
assertEquals(originalBounds.height(), newBounds.height());
@@ -3257,7 +3381,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(ORIENTATION_PORTRAIT, mTask.getConfiguration().orientation);
assertEquals(ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation);
assertFitted();
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertActivityMaxBoundsSandboxed();
// Activity bounds fill split screen.
@@ -3284,7 +3409,7 @@ public class SizeCompatTests extends WindowTestsBase {
organizer.mPrimary.setBounds(0, 0, 1000, 800);
// Non-resizable activity should be in size compat mode.
- assertScaled();
+ assertDownScaled();
assertEquals(mActivity.getBounds(), new Rect(60, 0, 940, 800));
recomputeNaturalConfigurationOfUnresizableActivity();
@@ -3861,7 +3986,7 @@ public class SizeCompatTests extends WindowTestsBase {
// Force activity to scaled down for size compat mode.
resizeDisplay(mTask.mDisplayContent, 700, 1400);
assertTrue(mActivity.inSizeCompatMode());
- assertScaled();
+ assertDownScaled();
assertEquals(sizeCompatScaled, mActivity.getBounds());
}
@@ -3892,7 +4017,8 @@ public class SizeCompatTests extends WindowTestsBase {
// orientation is not respected with insets as insets have been decoupled.
final Rect appBounds = activity.getWindowConfiguration().getAppBounds();
final Rect displayBounds = display.getBounds();
- assertFalse(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(activity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertNotNull(appBounds);
assertEquals(displayBounds.width(), appBounds.width());
assertEquals(displayBounds.height(), appBounds.height());
@@ -3923,7 +4049,8 @@ public class SizeCompatTests extends WindowTestsBase {
final Rect bounds = activity.getBounds();
// Activity should be letterboxed and should have portrait app bounds
- assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(activity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertTrue(bounds.height() > bounds.width());
}
@@ -3957,7 +4084,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertNotNull(activity.getCompatDisplayInsets());
// Activity is not letterboxed for fixed orientation because orientation is respected
// with insets, and should not be in size compat mode
- assertFalse(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(activity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(activity.inSizeCompatMode());
}
@@ -4204,9 +4332,10 @@ public class SizeCompatTests extends WindowTestsBase {
Configuration parentConfig = mActivity.getParent().getConfiguration();
- float actual = mActivity.mLetterboxUiController
- .getFixedOrientationLetterboxAspectRatio(parentConfig);
- float expected = mActivity.mLetterboxUiController.getSplitScreenAspectRatio();
+ final AppCompatAspectRatioOverrides aspectRatioOverrides =
+ mActivity.mAppCompatController.getAppCompatAspectRatioOverrides();
+ float actual = aspectRatioOverrides.getFixedOrientationLetterboxAspectRatio(parentConfig);
+ float expected = aspectRatioOverrides.getSplitScreenAspectRatio();
assertEquals(expected, actual, DELTA_ASPECT_RATIO_TOLERANCE);
}
@@ -4357,7 +4486,7 @@ public class SizeCompatTests extends WindowTestsBase {
resizeDisplay(mTask.mDisplayContent, 1400, 700);
assertTrue(mActivity.inSizeCompatMode());
- assertScaled();
+ assertDownScaled();
assertEquals(sizeCompatScaled, mActivity.getBounds());
}
@@ -4380,7 +4509,8 @@ public class SizeCompatTests extends WindowTestsBase {
verifyLogAppCompatState(mActivity, APP_COMPAT_STATE_CHANGED__STATE__NOT_LETTERBOXED);
prepareUnresizable(mActivity, /* maxAspect= */ 2, SCREEN_ORIENTATION_PORTRAIT);
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
assertTrue(mActivity.areBoundsLetterboxed());
@@ -4396,7 +4526,8 @@ public class SizeCompatTests extends WindowTestsBase {
// ActivityRecord#resolveSizeCompatModeConfiguration because mCompatDisplayInsets aren't
// null but activity doesn't enter size compat mode. Checking that areBoundsLetterboxed()
// still returns true because of the aspect ratio restrictions.
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
assertTrue(mActivity.areBoundsLetterboxed());
verifyLogAppCompatState(mActivity,
@@ -4423,7 +4554,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
assertTrue(mActivity.areBoundsLetterboxed());
verifyLogAppCompatState(mActivity,
@@ -4441,7 +4573,8 @@ public class SizeCompatTests extends WindowTestsBase {
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertTrue(mActivity.inSizeCompatMode());
assertTrue(mActivity.areBoundsLetterboxed());
verifyLogAppCompatState(mActivity,
@@ -4502,7 +4635,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
assertFalse(mActivity.isEligibleForLetterboxEducation());
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
}
@Test
@@ -4560,7 +4694,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
assertTrue(mActivity.isEligibleForLetterboxEducation());
- assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertTrue(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
}
@Test
@@ -4574,7 +4709,8 @@ public class SizeCompatTests extends WindowTestsBase {
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
assertTrue(mActivity.isEligibleForLetterboxEducation());
- assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertTrue(mActivity.inSizeCompatMode());
}
@@ -4616,7 +4752,7 @@ public class SizeCompatTests extends WindowTestsBase {
// Target min aspect ratio must be larger than parent aspect ratio to be applied.
final float targetMinAspectRatio = 3.0f;
- // Create fixed portait activity with min aspect ratio greater than parent aspect ratio.
+ // Create fixed portrait activity with min aspect ratio greater than parent aspect ratio.
final ActivityRecord fixedOrientationActivity = new ActivityBuilder(mAtm)
.setTask(task).setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
.setMinAspectRatio(targetMinAspectRatio).build();
@@ -4630,7 +4766,7 @@ public class SizeCompatTests extends WindowTestsBase {
final Rect minAspectRatioAppBounds = new Rect(minAspectRatioActivity.getConfiguration()
.windowConfiguration.getAppBounds());
- // Create unresizeable fixed portait activity with min aspect ratio greater than parent
+ // Create unresizeable fixed portrait activity with min aspect ratio greater than parent
// aspect ratio.
final ActivityRecord sizeCompatActivity = new ActivityBuilder(mAtm)
.setTask(task).setResizeMode(RESIZE_MODE_UNRESIZEABLE)
@@ -4642,12 +4778,12 @@ public class SizeCompatTests extends WindowTestsBase {
.windowConfiguration.getAppBounds());
// Check that aspect ratio of app bounds is equal to the min aspect ratio.
- assertEquals(targetMinAspectRatio, ActivityRecord
- .computeAspectRatio(fixedOrientationAppBounds), DELTA_ASPECT_RATIO_TOLERANCE);
- assertEquals(targetMinAspectRatio, ActivityRecord
- .computeAspectRatio(minAspectRatioAppBounds), DELTA_ASPECT_RATIO_TOLERANCE);
- assertEquals(targetMinAspectRatio, ActivityRecord
- .computeAspectRatio(sizeCompatAppBounds), DELTA_ASPECT_RATIO_TOLERANCE);
+ assertEquals(targetMinAspectRatio,
+ computeAspectRatio(fixedOrientationAppBounds), DELTA_ASPECT_RATIO_TOLERANCE);
+ assertEquals(targetMinAspectRatio,
+ computeAspectRatio(minAspectRatioAppBounds), DELTA_ASPECT_RATIO_TOLERANCE);
+ assertEquals(targetMinAspectRatio,
+ computeAspectRatio(sizeCompatAppBounds), DELTA_ASPECT_RATIO_TOLERANCE);
}
@Test
@@ -4663,7 +4799,7 @@ public class SizeCompatTests extends WindowTestsBase {
// Activity should enter size compat with old density after display density change.
display.setForcedDensity(newDensity, UserHandle.USER_CURRENT);
- assertScaled();
+ assertDownScaled();
assertEquals(origDensity, mActivity.getConfiguration().densityDpi);
// Activity should exit size compat with new density.
@@ -4902,14 +5038,25 @@ public class SizeCompatTests extends WindowTestsBase {
}
}
- private void assertScaled() {
- assertScaled(mActivity);
+ private void assertUpScaled() {
+ assertScaled(mActivity, /* upScalingExpected */ true);
}
- /** Asserts that the size of activity is larger than its parent so it is scaling. */
- private void assertScaled(ActivityRecord activity) {
+ private void assertDownScaled() {
+ assertScaled(mActivity, /* upScalingExpected */ false);
+ }
+
+ /**
+ * Asserts that the size of an activity differs from its parent and so it is scaling (either up
+ * or down).
+ */
+ private void assertScaled(ActivityRecord activity, boolean upScalingExpected) {
assertTrue(activity.inSizeCompatMode());
- assertNotEquals(1f, activity.getCompatScale(), 0.0001f /* delta */);
+ if (upScalingExpected) {
+ assertTrue(activity.getCompatScale() > 1f);
+ } else {
+ assertTrue(activity.getCompatScale() < 1f);
+ }
}
private void assertFitted() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index c962a3f9ea4d..4220f319b8f2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -442,15 +442,7 @@ public class SystemServicesTestRule implements TestRule {
dc.getDisplayPolicy().release();
// Unregister SensorEventListener (foldable device may register for hinge angle).
dc.getDisplayRotation().onDisplayRemoved();
- if (dc.mDisplayRotationCompatPolicy != null) {
- dc.mDisplayRotationCompatPolicy.dispose();
- }
- if (dc.mCameraCompatFreeformPolicy != null) {
- dc.mCameraCompatFreeformPolicy.dispose();
- }
- if (dc.mCameraStateMonitor != null) {
- dc.mCameraStateMonitor.dispose();
- }
+ dc.mAppCompatCameraPolicy.dispose();
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index a71b81e025d2..d013053a063d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -90,7 +90,6 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
-import android.view.RemoteAnimationDefinition;
import android.view.SurfaceControl;
import android.window.IRemoteTransition;
import android.window.ITaskFragmentOrganizer;
@@ -140,7 +139,6 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
private IBinder mFragmentToken;
private WindowContainerTransaction mTransaction;
private WindowContainerToken mFragmentWindowToken;
- private RemoteAnimationDefinition mDefinition;
private IBinder mErrorToken;
private Rect mTaskFragBounds;
@@ -169,7 +167,6 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mTransaction = new WindowContainerTransaction();
mTransaction.setTaskFragmentOrganizer(mIOrganizer);
mFragmentWindowToken = mTaskFragment.mRemoteToken.toWindowContainerToken();
- mDefinition = new RemoteAnimationDefinition();
mErrorToken = new Binder();
final Rect displayBounds = mDisplayContent.getBounds();
mTaskFragBounds = new Rect(displayBounds.left, displayBounds.top, displayBounds.centerX(),
@@ -579,17 +576,6 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
}
@Test
- public void testRegisterRemoteAnimations() {
- mController.registerRemoteAnimations(mIOrganizer, mDefinition);
-
- assertEquals(mDefinition, mController.getRemoteAnimationDefinition(mIOrganizer));
-
- mController.unregisterRemoteAnimations(mIOrganizer);
-
- assertNull(mController.getRemoteAnimationDefinition(mIOrganizer));
- }
-
- @Test
public void testApplyTransaction_disallowRemoteTransitionForNonSystemOrganizer() {
mTransaction.setRelativeBounds(mFragmentWindowToken, new Rect(0, 0, 100, 100));
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 35b6b70cb611..47d34a6e5f2b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -759,20 +759,24 @@ public class TaskFragmentTest extends WindowTestsBase {
// Assert fixed orientation request is ignored for activity in ActivityEmbedding split.
activity0.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
- assertFalse(activity0.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(activity0.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertEquals(SCREEN_ORIENTATION_UNSET, task.getOrientation());
activity1.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
- assertFalse(activity1.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(activity1.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertEquals(SCREEN_ORIENTATION_UNSET, task.getOrientation());
// Also verify the behavior on device that ignore orientation request.
mDisplayContent.setIgnoreOrientationRequest(true);
task.onConfigurationChanged(task.getParent().getConfiguration());
- assertFalse(activity0.isLetterboxedForFixedOrientationAndAspectRatio());
- assertFalse(activity1.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(activity0.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
+ assertFalse(activity1.mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio());
assertEquals(SCREEN_ORIENTATION_UNSET, task.getOrientation());
tf0.setResumedActivity(activity0, "test");
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 4bc87b1237f0..76690ec1691f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -613,11 +613,12 @@ public class TaskTests extends WindowTestsBase {
final ActivityRecord root = task.getTopNonFinishingActivity();
spyOn(mWm.mLetterboxConfiguration);
spyOn(root);
- spyOn(root.mLetterboxUiController);
+ spyOn(root.mAppCompatController.getAppCompatAspectRatioOverrides());
doReturn(true).when(root).fillsParent();
- doReturn(true).when(root.mLetterboxUiController)
- .shouldEnableUserAspectRatioSettings();
+ doReturn(true).when(
+ root.mAppCompatController.getAppCompatAspectRatioOverrides())
+ .shouldEnableUserAspectRatioSettings();
doReturn(false).when(root).inSizeCompatMode();
doReturn(task).when(root).getOrganizedTask();
@@ -626,12 +627,13 @@ public class TaskTests extends WindowTestsBase {
.appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton);
// When shouldApplyUserMinAspectRatioOverride is disable the button is not enabled
- doReturn(false).when(root.mLetterboxUiController)
- .shouldEnableUserAspectRatioSettings();
+ doReturn(false).when(
+ root.mAppCompatController.getAppCompatAspectRatioOverrides())
+ .shouldEnableUserAspectRatioSettings();
assertFalse(task.getTaskInfo()
.appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton);
- doReturn(true).when(root.mLetterboxUiController)
- .shouldEnableUserAspectRatioSettings();
+ doReturn(true).when(root.mAppCompatController
+ .getAppCompatAspectRatioOverrides()).shouldEnableUserAspectRatioSettings();
// When in size compat mode the button is not enabled
doReturn(true).when(root).inSizeCompatMode();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 00a8842c358e..4b0668f7a056 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -27,6 +27,7 @@ import android.os.PowerManager.GoToSleepReason;
import android.os.PowerManager.WakeReason;
import android.util.proto.ProtoOutputStream;
import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
@@ -35,6 +36,7 @@ import com.android.internal.policy.IShortcutService;
import com.android.server.policy.WindowManagerPolicy;
import java.io.PrintWriter;
+import java.util.Collections;
class TestWindowManagerPolicy implements WindowManagerPolicy {
@@ -268,8 +270,8 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
}
@Override
- public boolean performHapticFeedback(int uid, String packageName, int effectId,
- boolean always, String reason, boolean fromIme) {
+ public boolean performHapticFeedback(int uid, String packageName, int effectId, String reason,
+ int flags, int privFlags) {
return false;
}
@@ -362,4 +364,9 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
public boolean isGlobalKey(int keyCode) {
return false;
}
+
+ @Override
+ public KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId) {
+ return new KeyboardShortcutGroup("", Collections.emptyList());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 95d37ebf4597..7d01b79fe866 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -35,6 +35,7 @@ import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.window.TransitionInfo.FLAG_CONFIG_AT_END;
+import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_OWNER_THUMBNAIL;
import static android.window.TransitionInfo.FLAG_FILLS_TASK;
import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
@@ -77,13 +78,14 @@ import static java.lang.Integer.MAX_VALUE;
import android.app.ActivityManager;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
+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;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.view.SurfaceControl;
@@ -95,6 +97,7 @@ import android.window.ITaskOrganizer;
import android.window.ITransitionPlayer;
import android.window.RemoteTransition;
import android.window.SystemPerformanceHinter;
+import android.window.TaskFragmentAnimationParams;
import android.window.TaskFragmentOrganizer;
import android.window.TransitionInfo;
@@ -104,7 +107,6 @@ import androidx.test.filters.SmallTest;
import com.android.internal.graphics.ColorUtils;
import com.android.window.flags.Flags;
-import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -120,16 +122,15 @@ import java.util.function.Function;
* Build/Install/Run:
* atest WmTests:TransitionTests
*/
-@EnableFlags(Flags.FLAG_MOVE_ANIMATION_OPTIONS_TO_CHANGE)
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
public class TransitionTests extends WindowTestsBase {
final SurfaceControl.Transaction mMockT = mock(SurfaceControl.Transaction.class);
private BLASTSyncEngine mSyncEngine;
+ private Transition mTransition;
+ private TransitionInfo mInfo;
- @Rule
- public SetFlagsRule mRule = new SetFlagsRule();
private Transition createTestTransition(int transitType, TransitionController controller) {
final Transition transition = new Transition(transitType, 0 /* flags */, controller,
controller.mSyncEngine);
@@ -1994,6 +1995,221 @@ public class TransitionTests extends WindowTestsBase {
assertEquals(expectedBackgroundColor, info.getChanges().get(1).getBackgroundColor());
}
+ @DisableFlags(Flags.FLAG_MOVE_ANIMATION_OPTIONS_TO_CHANGE)
+ @Test
+ public void testOverrideAnimationOptionsToInfoIfNecessary_disableAnimOptionsPerChange() {
+ initializeOverrideAnimationOptionsTest();
+ TransitionInfo.AnimationOptions options = TransitionInfo.AnimationOptions
+ .makeCommonAnimOptions("testPackage");
+ mTransition.setOverrideAnimation(options, null /* startCallback */,
+ null /* finishCallback */);
+
+ mTransition.overrideAnimationOptionsToInfoIfNecessary(mInfo);
+
+ assertEquals(options, mInfo.getAnimationOptions());
+ }
+
+ @EnableFlags(Flags.FLAG_MOVE_ANIMATION_OPTIONS_TO_CHANGE)
+ @Test
+ public void testOverrideAnimationOptionsToInfoIfNecessary_nonCustomAnimOptions() {
+ initializeOverrideAnimationOptionsTest();
+ TransitionInfo.AnimationOptions options = TransitionInfo.AnimationOptions
+ .makeCommonAnimOptions("testPackage");
+ mTransition.setOverrideAnimation(options, null /* startCallback */,
+ null /* finishCallback */);
+
+ mTransition.overrideAnimationOptionsToInfoIfNecessary(mInfo);
+
+ final TransitionInfo.Change displayChange = mInfo.getChanges().get(0);
+ final TransitionInfo.Change taskChange = mInfo.getChanges().get(1);
+ final TransitionInfo.Change embeddedTfChange = mInfo.getChanges().get(2);
+ final TransitionInfo.Change activityChange = mInfo.getChanges().get(3);
+
+ assertNull("Display change's AnimationOptions must not be overridden.",
+ displayChange.getAnimationOptions());
+ assertNull("Task change's AnimationOptions must not be overridden.",
+ taskChange.getAnimationOptions());
+ assertNull("Embedded TF change's AnimationOptions must not be overridden.",
+ embeddedTfChange.getAnimationOptions());
+ assertEquals("Activity change's AnimationOptions must be overridden.",
+ options, activityChange.getAnimationOptions());
+ }
+
+ @EnableFlags(Flags.FLAG_MOVE_ANIMATION_OPTIONS_TO_CHANGE)
+ @Test
+ public void testOverrideAnimationOptionsToInfoIfNecessary_crossProfileAnimOptions() {
+ initializeOverrideAnimationOptionsTest();
+ TransitionInfo.AnimationOptions options = TransitionInfo.AnimationOptions
+ .makeCrossProfileAnimOptions();
+ mTransition.setOverrideAnimation(options, null /* startCallback */,
+ null /* finishCallback */);
+
+ final TransitionInfo.Change displayChange = mInfo.getChanges().get(0);
+ final TransitionInfo.Change taskChange = mInfo.getChanges().get(1);
+ final TransitionInfo.Change embeddedTfChange = mInfo.getChanges().get(2);
+ final TransitionInfo.Change activityChange = mInfo.getChanges().get(3);
+ activityChange.setMode(TRANSIT_OPEN);
+
+ mTransition.overrideAnimationOptionsToInfoIfNecessary(mInfo);
+
+ assertNull("Display change's AnimationOptions must not be overridden.",
+ displayChange.getAnimationOptions());
+ assertNull("Task change's AnimationOptions must not be overridden.",
+ taskChange.getAnimationOptions());
+ assertNull("Embedded TF change's AnimationOptions must not be overridden.",
+ embeddedTfChange.getAnimationOptions());
+ assertEquals("Activity change's AnimationOptions must be overridden.",
+ options, activityChange.getAnimationOptions());
+ assertTrue(activityChange.hasFlags(FLAG_CROSS_PROFILE_OWNER_THUMBNAIL));
+ }
+
+ @EnableFlags(Flags.FLAG_MOVE_ANIMATION_OPTIONS_TO_CHANGE)
+ @Test
+ public void testOverrideAnimationOptionsToInfoIfNecessary_customAnimOptions() {
+ initializeOverrideAnimationOptionsTest();
+ TransitionInfo.AnimationOptions options = TransitionInfo.AnimationOptions
+ .makeCustomAnimOptions("testPackage", Resources.ID_NULL,
+ TransitionInfo.AnimationOptions.DEFAULT_ANIMATION_RESOURCES_ID,
+ TransitionInfo.AnimationOptions.DEFAULT_ANIMATION_RESOURCES_ID,
+ Color.GREEN, false /* overrideTaskTransition */);
+ mTransition.setOverrideAnimation(options, null /* startCallback */,
+ null /* finishCallback */);
+
+ mTransition.overrideAnimationOptionsToInfoIfNecessary(mInfo);
+
+ final TransitionInfo.Change displayChange = mInfo.getChanges().get(0);
+ final TransitionInfo.Change taskChange = mInfo.getChanges().get(1);
+ final TransitionInfo.Change embeddedTfChange = mInfo.getChanges().get(2);
+ final TransitionInfo.Change activityChange = mInfo.getChanges().get(3);
+
+ assertNull("Display change's AnimationOptions must not be overridden.",
+ displayChange.getAnimationOptions());
+ assertNull("Task change's AnimationOptions must not be overridden.",
+ taskChange.getAnimationOptions());
+ assertEquals("Embedded TF change's AnimationOptions must be overridden.",
+ options, embeddedTfChange.getAnimationOptions());
+ assertEquals("Embedded TF change's background color must not be overridden.",
+ 0, embeddedTfChange.getBackgroundColor());
+ assertEquals("Activity change's AnimationOptions must be overridden.",
+ options, activityChange.getAnimationOptions());
+ assertEquals("Activity change's background color must be overridden.",
+ options.getBackgroundColor(), activityChange.getBackgroundColor());
+ }
+
+ @EnableFlags(Flags.FLAG_MOVE_ANIMATION_OPTIONS_TO_CHANGE)
+ @Test
+ public void testOverrideAnimationOptionsToInfoIfNecessary_haveTaskFragmentAnimParams() {
+ initializeOverrideAnimationOptionsTest();
+
+ final TaskFragment embeddedTf = mTransition.mTargets.get(2).mContainer.asTaskFragment();
+ embeddedTf.setAnimationParams(new TaskFragmentAnimationParams.Builder()
+ .setAnimationBackgroundColor(Color.RED)
+ .setOpenAnimationResId(0x12345678)
+ .build());
+
+ TransitionInfo.AnimationOptions options = TransitionInfo.AnimationOptions
+ .makeCustomAnimOptions("testPackage", Resources.ID_NULL,
+ TransitionInfo.AnimationOptions.DEFAULT_ANIMATION_RESOURCES_ID,
+ TransitionInfo.AnimationOptions.DEFAULT_ANIMATION_RESOURCES_ID,
+ Color.GREEN, false /* overrideTaskTransition */);
+ mTransition.setOverrideAnimation(options, null /* startCallback */,
+ null /* finishCallback */);
+
+ final TransitionInfo.Change displayChange = mInfo.getChanges().get(0);
+ final TransitionInfo.Change taskChange = mInfo.getChanges().get(1);
+ final TransitionInfo.Change embeddedTfChange = mInfo.getChanges().get(2);
+ final TransitionInfo.Change activityChange = mInfo.getChanges().get(3);
+
+ final int expectedColor = embeddedTf.getAnimationParams().getAnimationBackgroundColor();
+ embeddedTfChange.setBackgroundColor(expectedColor);
+ final TransitionInfo.AnimationOptions expectedOptions = TransitionInfo.AnimationOptions
+ .makeCustomAnimOptions("testPackage", 0x12345678,
+ TransitionInfo.AnimationOptions.DEFAULT_ANIMATION_RESOURCES_ID,
+ TransitionInfo.AnimationOptions.DEFAULT_ANIMATION_RESOURCES_ID,
+ 0, false /* overrideTaskTransition */);
+ embeddedTfChange.setAnimationOptions(expectedOptions);
+
+ mTransition.overrideAnimationOptionsToInfoIfNecessary(mInfo);
+
+ assertNull("Display change's AnimationOptions must not be overridden.",
+ displayChange.getAnimationOptions());
+ assertNull("Task change's AnimationOptions must not be overridden.",
+ taskChange.getAnimationOptions());
+ assertEquals("Embedded TF change's AnimationOptions must be overridden.",
+ expectedOptions, embeddedTfChange.getAnimationOptions());
+ assertEquals("Embedded TF change's background color must not be overridden.",
+ expectedColor, embeddedTfChange.getBackgroundColor());
+ assertEquals("Activity change's AnimationOptions must be overridden.",
+ options, activityChange.getAnimationOptions());
+ assertEquals("Activity change's background color must be overridden.",
+ options.getBackgroundColor(), activityChange.getBackgroundColor());
+ }
+
+ @EnableFlags(Flags.FLAG_MOVE_ANIMATION_OPTIONS_TO_CHANGE)
+ @Test
+ public void testOverrideAnimationOptionsToInfoIfNecessary_customAnimOptionsWithTaskOverride() {
+ initializeOverrideAnimationOptionsTest();
+ TransitionInfo.AnimationOptions options = TransitionInfo.AnimationOptions
+ .makeCustomAnimOptions("testPackage", Resources.ID_NULL,
+ TransitionInfo.AnimationOptions.DEFAULT_ANIMATION_RESOURCES_ID,
+ TransitionInfo.AnimationOptions.DEFAULT_ANIMATION_RESOURCES_ID,
+ Color.GREEN, true /* overrideTaskTransition */);
+ mTransition.setOverrideAnimation(options, null /* startCallback */,
+ null /* finishCallback */);
+
+ mTransition.overrideAnimationOptionsToInfoIfNecessary(mInfo);
+
+ final TransitionInfo.Change displayChange = mInfo.getChanges().get(0);
+ final TransitionInfo.Change taskChange = mInfo.getChanges().get(1);
+ final TransitionInfo.Change embeddedTfChange = mInfo.getChanges().get(2);
+ final TransitionInfo.Change activityChange = mInfo.getChanges().get(3);
+
+ assertNull("Display change's AnimationOptions must not be overridden.",
+ displayChange.getAnimationOptions());
+ assertEquals("Task change's AnimationOptions must be overridden.",
+ options, taskChange.getAnimationOptions());
+ assertEquals("Task change's background color must be overridden.",
+ options.getBackgroundColor(), taskChange.getBackgroundColor());
+ assertEquals("Embedded TF change's AnimationOptions must be overridden.",
+ options, embeddedTfChange.getAnimationOptions());
+ assertEquals("Embedded TF change's background color must be overridden.",
+ 0, embeddedTfChange.getBackgroundColor());
+ assertEquals("Activity change's AnimationOptions must be overridden.",
+ options, activityChange.getAnimationOptions());
+ assertEquals("Activity change's background color must be overridden.",
+ options.getBackgroundColor(), activityChange.getBackgroundColor());
+ }
+
+ private void initializeOverrideAnimationOptionsTest() {
+ mTransition = createTestTransition(TRANSIT_OPEN);
+
+ // Test set AnimationOptions for Activity and Task.
+ final Task task = createTask(mDisplayContent);
+ // Create an embedded TaskFragment.
+ final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+ registerTaskFragmentOrganizer(
+ ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder()));
+ final TaskFragment embeddedTf = createTaskFragmentWithEmbeddedActivity(task, organizer);
+ final ActivityRecord nonEmbeddedActivity = createActivityRecord(task);
+ mWm.mCurrentUserId = nonEmbeddedActivity.mUserId;
+
+ mTransition.mTargets = new ArrayList<>();
+ mTransition.mTargets.add(new Transition.ChangeInfo(mDisplayContent));
+ mTransition.mTargets.add(new Transition.ChangeInfo(task));
+ mTransition.mTargets.add(new Transition.ChangeInfo(embeddedTf));
+ mTransition.mTargets.add(new Transition.ChangeInfo(nonEmbeddedActivity));
+
+ mInfo = new TransitionInfo(TRANSIT_OPEN, 0 /* flags */);
+ mInfo.addChange(new TransitionInfo.Change(mDisplayContent.mRemoteToken
+ .toWindowContainerToken(), mDisplayContent.getAnimationLeash()));
+ mInfo.addChange(new TransitionInfo.Change(task.mRemoteToken.toWindowContainerToken(),
+ task.getAnimationLeash()));
+ mInfo.addChange(new TransitionInfo.Change(embeddedTf.mRemoteToken.toWindowContainerToken(),
+ embeddedTf.getAnimationLeash()));
+ mInfo.addChange(new TransitionInfo.Change(null /* container */,
+ nonEmbeddedActivity.getAnimationLeash()));
+ }
+
@Test
public void testTransitionVisibleChange() {
registerTestTransitionPlayer();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index 9b48cb9d328c..c65b76efd614 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -31,7 +31,6 @@ import static android.view.WindowManager.TRANSIT_OPEN;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.window.flags.Flags.multiCrop;
import static com.google.common.truth.Truth.assertThat;
@@ -551,10 +550,9 @@ public class WallpaperControllerTests extends WindowTestsBase {
}
private static void makeWallpaperWindowShown(WindowState w) {
- final WindowSurfaceController windowSurfaceController = mock(WindowSurfaceController.class);
- w.mWinAnimator.mSurfaceController = windowSurfaceController;
w.mWinAnimator.mLastAlpha = 1;
- when(windowSurfaceController.getShown()).thenReturn(true);
+ spyOn(w.mWinAnimator);
+ doReturn(true).when(w.mWinAnimator).getShown();
}
private WindowState createWallpaperWindow(DisplayContent dc, int width, int height) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index a94b58690775..401964c2f597 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -22,6 +22,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.InsetsSource.FLAG_FORCE_CONSUMING;
import static android.view.WindowInsets.Type.systemOverlays;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -77,6 +78,7 @@ import android.os.Parcel;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
@@ -91,6 +93,8 @@ import android.view.WindowManager;
import androidx.test.filters.SmallTest;
+import com.android.window.flags.Flags;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -801,18 +805,11 @@ public class WindowContainerTests extends WindowTestsBase {
final TestWindowContainer root2 = builder.setLayer(0).build();
+ assertEquals("Roots have the same z-order", 0, root.compareTo(root2));
assertEquals(0, root.compareTo(root));
assertEquals(-1, child1.compareTo(child2));
assertEquals(1, child2.compareTo(child1));
- boolean inTheSameTree = true;
- try {
- root.compareTo(root2);
- } catch (IllegalArgumentException e) {
- inTheSameTree = false;
- }
- assertFalse(inTheSameTree);
-
assertEquals(-1, child1.compareTo(child11));
assertEquals(1, child21.compareTo(root));
assertEquals(1, child21.compareTo(child12));
@@ -960,6 +957,25 @@ public class WindowContainerTests extends WindowTestsBase {
assertTrue(child.handlesOrientationChangeFromDescendant(orientation));
}
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION)
+ public void testAddLocalInsets_addsFlagsFromProvider() {
+ final Task rootTask = createTask(mDisplayContent);
+ final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
+
+ final Binder owner = new Binder();
+ Rect insetsRect = new Rect(0, 200, 1080, 700);
+ final int flags = FLAG_FORCE_CONSUMING;
+ final InsetsFrameProvider provider =
+ new InsetsFrameProvider(owner, 1, WindowInsets.Type.captionBar())
+ .setArbitraryRectangle(insetsRect)
+ .setFlags(flags);
+ task.addLocalInsetsFrameProvider(provider, owner);
+
+ final int sourceFlags = task.mLocalInsetsSources.get(provider.getId()).getFlags();
+ assertEquals(flags, sourceFlags);
+ }
+
private static void addLocalInsets(WindowContainer wc) {
final Binder owner = new Binder();
Rect genericOverlayInsetsRect1 = new Rect(0, 200, 1080, 700);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index fcf7a3fe79c1..89abe2ff0866 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -253,22 +253,18 @@ public class WindowManagerServiceTests extends WindowTestsBase {
final Session session = createTestSession(mAtm, wpc.getPid(), wpc.mUid);
spyOn(session);
assertTrue(session.mCanAddInternalSystemWindow);
- final WindowSurfaceController winSurface = mock(WindowSurfaceController.class);
- session.onWindowSurfaceVisibilityChanged(winSurface, true /* visible */,
- LayoutParams.TYPE_PHONE);
+ final WindowState window = createWindow(null, LayoutParams.TYPE_PHONE, "win");
+ session.onWindowSurfaceVisibilityChanged(window, true /* visible */);
verify(session).setHasOverlayUi(true);
- session.onWindowSurfaceVisibilityChanged(winSurface, false /* visible */,
- LayoutParams.TYPE_PHONE);
+ session.onWindowSurfaceVisibilityChanged(window, false /* visible */);
verify(session).setHasOverlayUi(false);
}
@Test
public void testRelayoutExitingWindow() {
final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, "appWin");
- final WindowSurfaceController surfaceController = mock(WindowSurfaceController.class);
- win.mWinAnimator.mSurfaceController = surfaceController;
win.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
- doReturn(true).when(surfaceController).hasSurface();
+ win.mWinAnimator.mSurfaceControl = mock(SurfaceControl.class);
spyOn(win.mTransitionController);
doReturn(true).when(win.mTransitionController).isShellTransitionsEnabled();
doReturn(true).when(win.mTransitionController).inTransition(
@@ -306,7 +302,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
// and WMS#tryStartExitingAnimation() will destroy the surface directly.
assertFalse(win.mAnimatingExit);
assertFalse(win.mHasSurface);
- assertNull(win.mWinAnimator.mSurfaceController);
+ assertNull(win.mWinAnimator.mSurfaceControl);
// Invisible requested activity should not get the last config even if its view is visible.
mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0,
@@ -1294,8 +1290,6 @@ public class WindowManagerServiceTests extends WindowTestsBase {
@Test
public void testRelayout_appWindowSendActivityWindowInfo() {
- mSetFlagsRule.enableFlags(Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG);
-
// Skip unnecessary operations of relayout.
spyOn(mWm.mWindowPlacerLocked);
doNothing().when(mWm.mWindowPlacerLocked).performSurfacePlacement(anyBoolean());
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index ab4decacf0ca..fb81a52bce85 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -30,6 +30,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
+import static android.view.InsetsSource.FLAG_FORCE_CONSUMING;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
@@ -75,10 +76,12 @@ import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.util.ArrayMap;
import android.util.Rational;
import android.view.Display;
+import android.view.InsetsSource;
import android.view.SurfaceControl;
import android.view.WindowInsets;
import android.window.ITaskFragmentOrganizer;
@@ -904,7 +907,8 @@ public class WindowOrganizerTests extends WindowTestsBase {
0 /* index */,
WindowInsets.Type.systemOverlays(),
new Rect(0, 0, 1080, 200),
- null /* boundingRects */);
+ null /* boundingRects */,
+ 0 /* flags */);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
assertThat(navigationBarInsetsReceiverTask.mLocalInsetsSources
@@ -930,7 +934,8 @@ public class WindowOrganizerTests extends WindowTestsBase {
0 /* index */,
WindowInsets.Type.systemOverlays(),
new Rect(0, 0, 1080, 200),
- boundingRects);
+ boundingRects,
+ 0 /* flags */);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
assertArrayEquals(boundingRects, navigationBarInsetsReceiverTask.mLocalInsetsSources
@@ -938,6 +943,30 @@ public class WindowOrganizerTests extends WindowTestsBase {
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION)
+ public void testAddInsetsSource_withFlags() {
+ final Task rootTask = createTask(mDisplayContent);
+
+ final Task insetsReceiverTask = createTaskInRootTask(rootTask, 0);
+ insetsReceiverTask.getConfiguration().windowConfiguration
+ .setBounds(new Rect(0, 200, 1080, 700));
+
+ final @InsetsSource.Flags int flags = FLAG_FORCE_CONSUMING;
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ wct.addInsetsSource(
+ insetsReceiverTask.mRemoteToken.toWindowContainerToken(),
+ new Binder(),
+ 0 /* index */,
+ WindowInsets.Type.systemOverlays(),
+ new Rect(0, 0, 1080, 200),
+ null /* boundingRects */,
+ flags);
+ mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
+
+ assertEquals(flags, insetsReceiverTask.mLocalInsetsSources.valueAt(0).getFlags());
+ }
+
+ @Test
public void testRemoveInsetsSource() {
final Task rootTask = createTask(mDisplayContent);
@@ -952,7 +981,8 @@ public class WindowOrganizerTests extends WindowTestsBase {
0 /* index */,
WindowInsets.Type.systemOverlays(),
new Rect(0, 0, 1080, 200),
- null /* boundingRects */);
+ null /* boundingRects */,
+ 0 /* flags */);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
final WindowContainerTransaction wct2 = new WindowContainerTransaction();
@@ -1725,26 +1755,41 @@ public class WindowOrganizerTests extends WindowTestsBase {
assertTrue(optionsCaptor.getValue().getOriginalOptions().getTransientLaunch());
}
+ @SuppressWarnings("GuardedBy")
@Test
public void testResumeTopsWhenLeavingPinned() {
- final ActivityRecord record = makePipableActivity();
- final Task rootTask = record.getRootTask();
+ final ActivityRecord home = new ActivityBuilder(mAtm).setTask(
+ mRootWindowContainer.getDefaultTaskDisplayArea().getRootHomeTask()).build();
+ final Task homeTask = home.getTask();
+ final ActivityRecord pipActivity = makePipableActivity();
- clearInvocations(mWm.mAtmService.mRootWindowContainer);
final WindowContainerTransaction t = new WindowContainerTransaction();
- WindowContainerToken wct = rootTask.mRemoteToken.toWindowContainerToken();
- t.setWindowingMode(wct, WINDOWING_MODE_PINNED);
+ t.setWindowingMode(pipActivity.getTask().mRemoteToken.toWindowContainerToken(),
+ WINDOWING_MODE_PINNED);
+ clearInvocations(homeTask);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
- verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
+ if (WindowOrganizerController.shouldApplyLifecycleEffectOnPipChange()) {
+ verify(homeTask).resumeTopActivityUncheckedLocked(any(), any(), anyBoolean());
+ } else {
+ verify(homeTask, never()).resumeTopActivityUncheckedLocked(any(), any(), anyBoolean());
+ }
+
+ // Undo the effect of legacy logic in RootWindowContainer#moveActivityToPinnedRootTask.
+ if (pipActivity.mWaitForEnteringPinnedMode) {
+ pipActivity.mWaitForEnteringPinnedMode = false;
+ pipActivity.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+ }
+ assertFalse(pipActivity.isFocusable());
- clearInvocations(mWm.mAtmService.mRootWindowContainer);
// The token for the PIP root task may have changed when the task entered PIP mode, so do
// not reuse the one from above.
- final WindowContainerToken newToken =
- record.getRootTask().mRemoteToken.toWindowContainerToken();
+ final Task pipTask = pipActivity.getTask();
+ final WindowContainerToken newToken = pipTask.mRemoteToken.toWindowContainerToken();
t.setWindowingMode(newToken, WINDOWING_MODE_FULLSCREEN);
+ clearInvocations(pipTask);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
- verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
+ assertTrue(pipActivity.isFocusable());
+ verify(pipTask).resumeTopActivityUncheckedLocked(any(), any(), anyBoolean());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index e6648dad4bbe..0cb22ad47355 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.content.pm.ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED;
import static android.content.res.Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -86,6 +87,7 @@ public class WindowProcessControllerTests extends WindowTestsBase {
ApplicationInfo info = mock(ApplicationInfo.class);
info.packageName = "test.package.name";
+ doReturn(true).when(info).isChangeEnabled(INSETS_DECOUPLED_CONFIGURATION_ENFORCED);
mWpc = new WindowProcessController(
mAtm, info, null, 0, -1, null, mMockListener);
mWpc.setThread(mock(IApplicationThread.class));
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTracingLegacyTest.java
index c1834037f791..48a8d5502c64 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTracingLegacyTest.java
@@ -63,7 +63,7 @@ import java.nio.charset.StandardCharsets;
*/
@SmallTest
@Presubmit
-public class WindowTracingTest {
+public class WindowTracingLegacyTest {
private static final byte[] MAGIC_HEADER = new byte[]{
0x9, 0x57, 0x49, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x45,
@@ -88,7 +88,7 @@ public class WindowTracingTest {
mFile = testContext.getFileStreamPath("tracing_test.dat");
mFile.delete();
- mWindowTracing = new WindowTracing(mFile, mWmMock, mChoreographer,
+ mWindowTracing = new WindowTracingLegacy(mFile, mWmMock, mChoreographer,
new WindowManagerGlobalLock(), 1024);
}
diff --git a/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java
index 49e9232ad535..14c9ea51c618 100644
--- a/telecomm/java/android/telecom/CallAudioState.java
+++ b/telecomm/java/android/telecom/CallAudioState.java
@@ -159,7 +159,7 @@ public final class CallAudioState implements Parcelable {
@Override
public String toString() {
String bluetoothDeviceList = supportedBluetoothDevices.stream()
- .map(BluetoothDevice::getAddress).collect(Collectors.joining(", "));
+ .map(BluetoothDevice::toString).collect(Collectors.joining(", "));
return String.format(Locale.US,
"[AudioState isMuted: %b, route: %s, supportedRouteMask: %s, " +
diff --git a/telephony/common/android/telephony/LocationAccessPolicy.java b/telephony/common/android/telephony/LocationAccessPolicy.java
index d4b6c91eb7a0..feea55bff125 100644
--- a/telephony/common/android/telephony/LocationAccessPolicy.java
+++ b/telephony/common/android/telephony/LocationAccessPolicy.java
@@ -32,6 +32,8 @@ import android.os.UserHandle;
import android.util.Log;
import android.widget.Toast;
+import com.android.internal.telephony.TelephonyPermissions;
+import com.android.internal.telephony.flags.Flags;
import com.android.internal.telephony.util.TelephonyUtils;
/**
@@ -310,10 +312,18 @@ public final class LocationAccessPolicy {
// This avoid breaking legacy code that rely on public-facing APIs to access cell location,
// and it doesn't create an info leak risk because the cell location is stored in the phone
// process anyway, and the system server already has location access.
- if (query.callingUid == Process.PHONE_UID || query.callingUid == Process.SYSTEM_UID
- || query.callingUid == Process.NETWORK_STACK_UID
- || query.callingUid == Process.ROOT_UID) {
- return LocationPermissionResult.ALLOWED;
+ if (Flags.supportPhoneUidCheckForMultiuser()) {
+ if (TelephonyPermissions.isSystemOrPhone(query.callingUid)
+ || UserHandle.isSameApp(query.callingUid, Process.NETWORK_STACK_UID)
+ || UserHandle.isSameApp(query.callingUid, Process.ROOT_UID)) {
+ return LocationPermissionResult.ALLOWED;
+ }
+ } else {
+ if (query.callingUid == Process.PHONE_UID || query.callingUid == Process.SYSTEM_UID
+ || query.callingUid == Process.NETWORK_STACK_UID
+ || query.callingUid == Process.ROOT_UID) {
+ return LocationPermissionResult.ALLOWED;
+ }
}
// Check the system-wide requirements. If the location main switch is off and the caller is
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index 0ddc38a78b1e..7ed26fb549f9 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -35,6 +35,7 @@ import android.telephony.TelephonyManager;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.flags.Flags;
import java.util.HashMap;
import java.util.HashSet;
@@ -716,14 +717,15 @@ public final class TelephonyPermissions {
}
private static int getCarrierPrivilegeStatus(Context context, int subId, int uid) {
- if (uid == Process.SYSTEM_UID || uid == Process.PHONE_UID) {
+ if (isSystemOrPhone(uid)) {
// Skip the check if it's one of these special uids
return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
}
+
final long identity = Binder.clearCallingIdentity();
try {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE);
+ Context.TELEPHONY_SERVICE);
return telephonyManager.createForSubscriptionId(subId).getCarrierPrivilegeStatus(uid);
} finally {
Binder.restoreCallingIdentity(identity);
@@ -926,4 +928,30 @@ public final class TelephonyPermissions {
|| checkCallingOrSelfReadPhoneNumber(context, subId, callingPackage,
callingFeatureId, message));
}
+
+ /**
+ * @return true if the specified {@code uid} is for a system or phone process, no matter if runs
+ * as system user or not.
+ */
+ public static boolean isSystemOrPhone(int uid) {
+ if (Flags.supportPhoneUidCheckForMultiuser()) {
+ return UserHandle.isSameApp(uid, Process.SYSTEM_UID) || UserHandle.isSameApp(uid,
+ Process.PHONE_UID);
+ } else {
+ return uid == Process.SYSTEM_UID || uid == Process.PHONE_UID;
+ }
+ }
+
+ /**
+ * @return true if the specified {@code uid} is for a ROOT or SHELL process, no matter if runs
+ * as system user or not.
+ */
+ public static boolean isRootOrShell(int uid) {
+ if (Flags.supportPhoneUidCheckForMultiuser()) {
+ return UserHandle.isSameApp(uid, Process.ROOT_UID) || UserHandle.isSameApp(uid,
+ Process.SHELL_UID);
+ } else {
+ return uid == Process.ROOT_UID || uid == Process.SHELL_UID;
+ }
+ }
}
diff --git a/telephony/java/android/telephony/satellite/ProvisionSubscriberId.java b/telephony/java/android/telephony/satellite/ProvisionSubscriberId.java
index 796c82dd4af7..3e6f743e8a93 100644
--- a/telephony/java/android/telephony/satellite/ProvisionSubscriberId.java
+++ b/telephony/java/android/telephony/satellite/ProvisionSubscriberId.java
@@ -43,12 +43,17 @@ public final class ProvisionSubscriberId implements Parcelable {
/** carrier id */
private int mCarrierId;
+ /** apn */
+ private String mNiddApn;
+
/**
* @hide
*/
- public ProvisionSubscriberId(@NonNull String subscriberId, @NonNull int carrierId) {
+ public ProvisionSubscriberId(@NonNull String subscriberId, @NonNull int carrierId,
+ @NonNull String niddApn) {
this.mCarrierId = carrierId;
this.mSubscriberId = subscriberId;
+ this.mNiddApn = niddApn;
}
private ProvisionSubscriberId(Parcel in) {
@@ -63,6 +68,7 @@ public final class ProvisionSubscriberId implements Parcelable {
public void writeToParcel(@NonNull Parcel out, int flags) {
out.writeString(mSubscriberId);
out.writeInt(mCarrierId);
+ out.writeString(mNiddApn);
}
@FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@@ -89,7 +95,7 @@ public final class ProvisionSubscriberId implements Parcelable {
}
/**
- * @return token.
+ * @return provision subscriberId.
* @hide
*/
@FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@@ -106,6 +112,15 @@ public final class ProvisionSubscriberId implements Parcelable {
return mCarrierId;
}
+ /**
+ * @return niddApn.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public String getNiddApn() {
+ return mNiddApn;
+ }
+
@NonNull
@Override
public String toString() {
@@ -117,12 +132,16 @@ public final class ProvisionSubscriberId implements Parcelable {
sb.append("CarrierId:");
sb.append(mCarrierId);
+ sb.append(",");
+
+ sb.append("NiddApn:");
+ sb.append(mNiddApn);
return sb.toString();
}
@Override
public int hashCode() {
- return Objects.hash(mSubscriberId, mCarrierId);
+ return Objects.hash(mSubscriberId, mCarrierId, mNiddApn);
}
@Override
@@ -131,11 +150,12 @@ public final class ProvisionSubscriberId implements Parcelable {
if (o == null || getClass() != o.getClass()) return false;
ProvisionSubscriberId that = (ProvisionSubscriberId) o;
return mSubscriberId.equals(that.mSubscriberId) && mCarrierId
- == that.mCarrierId;
+ == that.mCarrierId && mNiddApn.equals(that.mNiddApn);
}
private void readFromParcel(Parcel in) {
mSubscriberId = in.readString();
mCarrierId = in.readInt();
+ mNiddApn = in.readString();
}
}
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index b518c60d09fd..4b83b65e435a 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -50,7 +50,6 @@ import java.lang.annotation.RetentionPolicy;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@@ -1079,6 +1078,11 @@ public final class SatelliteManager {
* @hide
*/
public static final int DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED = 5;
+ /**
+ * Datagram type indicating that the message to be sent or received is of type SMS.
+ * @hide
+ */
+ public static final int DATAGRAM_TYPE_SMS = 6;
/** @hide */
@IntDef(prefix = "DATAGRAM_TYPE_", value = {
@@ -1087,7 +1091,8 @@ public final class SatelliteManager {
DATAGRAM_TYPE_LOCATION_SHARING,
DATAGRAM_TYPE_KEEP_ALIVE,
DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP,
- DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED
+ DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED,
+ DATAGRAM_TYPE_SMS
})
@Retention(RetentionPolicy.SOURCE)
public @interface DatagramType {}
@@ -2636,9 +2641,9 @@ public final class SatelliteManager {
if (resultCode == SATELLITE_RESULT_SUCCESS) {
if (resultData.containsKey(KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN)) {
List<ProvisionSubscriberId> list =
- Collections.singletonList(resultData.getParcelable(
+ resultData.getParcelableArrayList(
KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN,
- ProvisionSubscriberId.class));
+ ProvisionSubscriberId.class);
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
callback.onResult(list)));
} else {
@@ -2692,13 +2697,13 @@ public final class SatelliteManager {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (resultCode == SATELLITE_RESULT_SUCCESS) {
- if (resultData.containsKey(KEY_SATELLITE_PROVISIONED)) {
+ if (resultData.containsKey(KEY_IS_SATELLITE_PROVISIONED)) {
boolean isIsProvisioned =
- resultData.getBoolean(KEY_SATELLITE_PROVISIONED);
+ resultData.getBoolean(KEY_IS_SATELLITE_PROVISIONED);
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
callback.onResult(isIsProvisioned)));
} else {
- loge("KEY_REQUEST_PROVISION_TOKENS does not exist.");
+ loge("KEY_IS_SATELLITE_PROVISIONED does not exist.");
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
callback.onError(new SatelliteException(
SATELLITE_RESULT_REQUEST_FAILED))));
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 7be52ea62758..3dbda7ae10a3 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -3411,7 +3411,7 @@ interface ITelephony {
*/
@JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ "android.Manifest.permission.SATELLITE_COMMUNICATION)")
- void requestProvisionSubscriberIds(in ResultReceiver receiver);
+ void requestProvisionSubscriberIds(in ResultReceiver result);
/**
* Request to get provisioned status for given a satellite subscriber id.
diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java
index cf38bea55f2c..6bf7ff501217 100644
--- a/test-mock/src/android/test/mock/MockContext.java
+++ b/test-mock/src/android/test/mock/MockContext.java
@@ -479,6 +479,15 @@ public class MockContext extends Context {
throw new UnsupportedOperationException();
}
+ /** @hide */
+ @Override
+ public void sendOrderedBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
+ String[] receiverPermissions, int appOp, Bundle options,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public void sendOrderedBroadcast(Intent intent, String receiverPermission,
String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
diff --git a/tests/FlickerTests/IME/Android.bp b/tests/FlickerTests/IME/Android.bp
index ccc3683f0b93..78d93e1cb32a 100644
--- a/tests/FlickerTests/IME/Android.bp
+++ b/tests/FlickerTests/IME/Android.bp
@@ -34,6 +34,11 @@ filegroup {
srcs: ["src/**/Close*"],
}
+filegroup {
+ name: "FlickerTestsIme2-src",
+ srcs: ["src/**/ShowImeOnAppStart*"],
+}
+
android_test {
name: "FlickerTestsIme",
defaults: ["FlickerTestsDefault"],
@@ -77,9 +82,23 @@ android_test {
defaults: ["FlickerTestsDefault"],
manifest: "AndroidManifest.xml",
test_config_template: "AndroidTestTemplate.xml",
+ srcs: [":FlickerTestsIme2-src"],
+ static_libs: [
+ "FlickerTestsBase",
+ "FlickerTestsImeCommon",
+ ],
+ data: ["trace_config/*"],
+}
+
+android_test {
+ name: "FlickerTestsIme3",
+ defaults: ["FlickerTestsDefault"],
+ manifest: "AndroidManifest.xml",
+ test_config_template: "AndroidTestTemplate.xml",
srcs: ["src/**/*"],
exclude_srcs: [
":FlickerTestsIme1-src",
+ ":FlickerTestsIme2-src",
":FlickerTestsImeCommon-src",
],
static_libs: [
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
index 9a5e88becf1e..5121f6677cea 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
@@ -119,7 +119,7 @@ open class DesktopModeAppHelper(private val innerHelper: IStandardAppHelper) :
): UiObject2? {
if (
wmHelper.getWindow(innerHelper)?.windowingMode !=
- WindowingMode.WINDOWING_MODE_FREEFORM.value
+ WindowingMode.WINDOWING_MODE_FREEFORM.value
)
error("expected a freeform window with caption but window is not in freeform mode")
val captions =
@@ -147,7 +147,17 @@ open class DesktopModeAppHelper(private val innerHelper: IStandardAppHelper) :
val endX = startX + horizontalChange
// drag the specified corner of the window to the end coordinate.
- device.drag(startX, startY, endX, endY, 100)
+ dragWindow(startX, startY, endX, endY, wmHelper, device)
+ }
+
+ /** Drag a window from a source coordinate to a destination coordinate. */
+ fun dragWindow(
+ startX: Int, startY: Int,
+ endX: Int, endY: Int,
+ wmHelper: WindowManagerStateHelper,
+ device: UiDevice
+ ) {
+ device.drag(startX, startY, endX, endY, /* steps= */ 100)
wmHelper
.StateSyncBuilder()
.withAppTransitionIdle()
@@ -165,4 +175,37 @@ open class DesktopModeAppHelper(private val innerHelper: IStandardAppHelper) :
Corners.RIGHT_BOTTOM -> Pair(windowRect.right, windowRect.bottom)
}
}
+
+ /** Exit desktop mode by dragging the app handle to the top drag zone. */
+ fun exitDesktopWithDragToTopDragZone(
+ wmHelper: WindowManagerStateHelper,
+ device: UiDevice,
+ ) {
+ dragAppWindowToTopDragZone(wmHelper, device)
+ waitForTransitionToFullscreen(wmHelper)
+ }
+
+ private fun dragAppWindowToTopDragZone(wmHelper: WindowManagerStateHelper, device: UiDevice) {
+ val windowRect = wmHelper.getWindowRegion(innerHelper).bounds
+ val displayRect =
+ wmHelper.currentState.wmState.getDefaultDisplay()?.displayRect
+ ?: throw IllegalStateException("Default display is null")
+
+ val startX = windowRect.centerX()
+ val endX = displayRect.centerX()
+ val startY = windowRect.top
+ val endY = 0 // top of the screen
+
+ // drag the app window to top drag zone
+ device.drag(startX, startY, endX, endY, 100)
+ }
+
+ /** Wait for transition to full screen to finish. */
+ private fun waitForTransitionToFullscreen(wmHelper: WindowManagerStateHelper) {
+ wmHelper
+ .StateSyncBuilder()
+ .withFullScreenApp(innerHelper)
+ .withAppTransitionIdle()
+ .waitForAndVerify()
+ }
}
diff --git a/tests/Input/AndroidTest.xml b/tests/Input/AndroidTest.xml
index 8db37058af2b..4a99bd4f1801 100644
--- a/tests/Input/AndroidTest.xml
+++ b/tests/Input/AndroidTest.xml
@@ -31,7 +31,7 @@
<metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
<option name="pull-pattern-keys" value="input_.*" />
<!-- Pull files created by tests, like the output of screenshot tests -->
- <option name="directory-keys" value="/storage/emulated/0/InputTests" />
+ <option name="directory-keys" value="/sdcard/Download/InputTests" />
<option name="collect-on-run-ended-only" value="false" />
</metrics_collector>
</configuration>
diff --git a/tests/Input/assets/testPointerStrokeStyle.png b/tests/Input/assets/testPointerStrokeStyle.png
new file mode 100644
index 000000000000..4ddde70b2f0a
--- /dev/null
+++ b/tests/Input/assets/testPointerStrokeStyle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/hub_handle.xml b/tests/Input/res/drawable/test_key_drawable.xml
index 8bc276ffed9e..2addf8fcf0bd 100644
--- a/packages/SystemUI/res/drawable/hub_handle.xml
+++ b/tests/Input/res/drawable/test_key_drawable.xml
@@ -1,5 +1,6 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2024 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 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.
@@ -16,5 +17,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="4dp" />
- <solid android:color="#FFFFFF" />
+ <solid android:color="#ffffffff"/>
</shape> \ No newline at end of file
diff --git a/tests/Input/res/drawable/test_modifier_drawable.xml b/tests/Input/res/drawable/test_modifier_drawable.xml
new file mode 100644
index 000000000000..2addf8fcf0bd
--- /dev/null
+++ b/tests/Input/res/drawable/test_modifier_drawable.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 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.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <corners android:radius="4dp" />
+ <solid android:color="#ffffffff"/>
+</shape> \ No newline at end of file
diff --git a/tests/Input/res/xml/keyboard_glyph_maps.xml b/tests/Input/res/xml/keyboard_glyph_maps.xml
new file mode 100644
index 000000000000..d0616ff5ccaa
--- /dev/null
+++ b/tests/Input/res/xml/keyboard_glyph_maps.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 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.
+ -->
+<keyboard-glyph-maps xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <keyboard-glyph-map
+ androidprv:glyphMap="@xml/test_glyph_map"
+ androidprv:vendorId="0x1234"
+ androidprv:productId="0x3456" />
+</keyboard-glyph-maps> \ No newline at end of file
diff --git a/tests/Input/res/xml/test_glyph_map.xml b/tests/Input/res/xml/test_glyph_map.xml
new file mode 100644
index 000000000000..7a7c1accb7fd
--- /dev/null
+++ b/tests/Input/res/xml/test_glyph_map.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 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.
+ -->
+<keyboard-glyph-map xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <key-glyph
+ androidprv:keycode="KEYCODE_BACK"
+ androidprv:glyphDrawable="@drawable/test_key_drawable" />
+ <modifier-glyph
+ androidprv:modifier="META"
+ androidprv:glyphDrawable="@drawable/test_modifier_drawable" />
+ <function-row-key androidprv:keycode="KEYCODE_EMOJI_PICKER" />
+ <hardware-defined-shortcut
+ androidprv:keycode="KEYCODE_1"
+ androidprv:modifierState="FUNCTION"
+ androidprv:outKeycode="KEYCODE_BACK" />
+ <hardware-defined-shortcut
+ androidprv:keycode="KEYCODE_2"
+ androidprv:modifierState="FUNCTION|META"
+ androidprv:outKeycode="KEYCODE_HOME" />
+</keyboard-glyph-map> \ No newline at end of file
diff --git a/tests/Input/src/com/android/server/input/KeyboardGlyphManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardGlyphManagerTests.kt
new file mode 100644
index 000000000000..c073c7aae678
--- /dev/null
+++ b/tests/Input/src/com/android/server/input/KeyboardGlyphManagerTests.kt
@@ -0,0 +1,197 @@
+/*
+ * Copyright 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.input
+
+import android.content.Context
+import android.content.ContextWrapper
+import android.content.pm.ActivityInfo
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import android.content.pm.ResolveInfo
+import android.content.pm.ServiceInfo
+import android.hardware.input.IInputManager
+import android.hardware.input.InputManager
+import android.hardware.input.InputManagerGlobal
+import android.hardware.input.KeyGlyphMap.KeyCombination
+import android.os.Bundle
+import android.os.test.TestLooper
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.annotations.Presubmit
+import android.platform.test.flag.junit.SetFlagsRule
+import android.view.InputDevice
+import android.view.KeyEvent
+import androidx.test.core.app.ApplicationProvider
+import com.android.hardware.input.Flags
+import com.android.test.input.R
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.junit.MockitoJUnit
+
+/**
+ * Tests for custom keyboard glyph map configuration.
+ *
+ * Build/Install/Run:
+ * atest InputTests:KeyboardGlyphManagerTests
+ */
+@Presubmit
+class KeyboardGlyphManagerTests {
+
+ companion object {
+ const val DEVICE_ID = 1
+ const val VENDOR_ID = 0x1234
+ const val PRODUCT_ID = 0x3456
+ const val PACKAGE_NAME = "KeyboardLayoutManagerTests"
+ const val RECEIVER_NAME = "DummyReceiver"
+ }
+
+ @JvmField
+ @Rule(order = 0)
+ val setFlagsRule = SetFlagsRule()
+
+ @JvmField
+ @Rule(order = 1)
+ val mockitoRule = MockitoJUnit.rule()!!
+
+ @Mock
+ private lateinit var packageManager: PackageManager
+
+ @Mock
+ private lateinit var iInputManager: IInputManager
+
+ private lateinit var keyboardGlyphManager: KeyboardGlyphManager
+ private lateinit var context: Context
+ private lateinit var testLooper: TestLooper
+ private lateinit var inputManagerGlobalSession: InputManagerGlobal.TestSession
+ private lateinit var keyboardDevice: InputDevice
+
+ @Before
+ fun setup() {
+ context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
+ inputManagerGlobalSession = InputManagerGlobal.createTestSession(iInputManager)
+ testLooper = TestLooper()
+ keyboardGlyphManager = KeyboardGlyphManager(context, testLooper.looper)
+
+ setupInputDevices()
+ setupBroadcastReceiver()
+ keyboardGlyphManager.systemRunning()
+ testLooper.dispatchAll()
+ }
+
+ @After
+ fun tearDown() {
+ if (this::inputManagerGlobalSession.isInitialized) {
+ inputManagerGlobalSession.close()
+ }
+ }
+
+ private fun setupInputDevices() {
+ val inputManager = InputManager(context)
+ Mockito.`when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
+ .thenReturn(inputManager)
+
+ keyboardDevice = createKeyboard(DEVICE_ID, VENDOR_ID, PRODUCT_ID, 0, "", "")
+ Mockito.`when`(iInputManager.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID))
+ Mockito.`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardDevice)
+ }
+
+ private fun setupBroadcastReceiver() {
+ Mockito.`when`(context.packageManager).thenReturn(packageManager)
+
+ val info = createMockReceiver()
+ Mockito.`when`(packageManager.queryBroadcastReceiversAsUser(Mockito.any(), Mockito.anyInt(),
+ Mockito.anyInt())).thenReturn(listOf(info))
+ Mockito.`when`(packageManager.getReceiverInfo(Mockito.any(), Mockito.anyInt()))
+ .thenReturn(info.activityInfo)
+
+ val resources = context.resources
+ Mockito.`when`(
+ packageManager.getResourcesForApplication(
+ Mockito.any(
+ ApplicationInfo::class.java
+ )
+ )
+ ).thenReturn(resources)
+ }
+
+ private fun createMockReceiver(): ResolveInfo {
+ val info = ResolveInfo()
+ info.activityInfo = ActivityInfo()
+ info.activityInfo.packageName = PACKAGE_NAME
+ info.activityInfo.name = RECEIVER_NAME
+ info.activityInfo.applicationInfo = ApplicationInfo()
+ info.activityInfo.metaData = Bundle()
+ info.activityInfo.metaData.putInt(
+ InputManager.META_DATA_KEYBOARD_GLYPH_MAPS,
+ R.xml.keyboard_glyph_maps
+ )
+ info.serviceInfo = ServiceInfo()
+ info.serviceInfo.packageName = PACKAGE_NAME
+ info.serviceInfo.name = RECEIVER_NAME
+ return info
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYBOARD_GLYPH_MAP)
+ fun testGlyphMapsLoaded() {
+ assertNotNull(
+ "Glyph map for test keyboard(deviceId=$DEVICE_ID) must exist",
+ keyboardGlyphManager.getKeyGlyphMap(DEVICE_ID)
+ )
+ assertNull(
+ "Glyph map for non-existing keyboard must be null",
+ keyboardGlyphManager.getKeyGlyphMap(-2)
+ )
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYBOARD_GLYPH_MAP)
+ fun testGlyphMapCorrectlyLoaded() {
+ val glyphMap = keyboardGlyphManager.getKeyGlyphMap(DEVICE_ID)
+ // Test glyph map used in this test: {@see test_glyph_map.xml}
+ assertNotNull(glyphMap!!.getDrawableForKeycode(context, KeyEvent.KEYCODE_BACK))
+
+ assertNotNull(glyphMap.getDrawableForModifier(context, KeyEvent.KEYCODE_META_LEFT))
+ assertNotNull(glyphMap.getDrawableForModifier(context, KeyEvent.KEYCODE_META_RIGHT))
+
+ val functionRowKeys = glyphMap.functionRowKeys
+ assertEquals(1, functionRowKeys.size)
+ assertEquals(KeyEvent.KEYCODE_EMOJI_PICKER, functionRowKeys[0])
+
+ val hardwareShortcuts = glyphMap.hardwareShortcuts
+ assertEquals(2, hardwareShortcuts.size)
+ assertEquals(
+ KeyEvent.KEYCODE_BACK,
+ hardwareShortcuts[KeyCombination(KeyEvent.META_FUNCTION_ON, KeyEvent.KEYCODE_1)]
+ )
+ assertEquals(
+ KeyEvent.KEYCODE_HOME,
+ hardwareShortcuts[
+ KeyCombination(
+ KeyEvent.META_FUNCTION_ON or KeyEvent.META_META_ON,
+ KeyEvent.KEYCODE_2
+ )
+ ]
+ )
+ }
+}
diff --git a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
index 93f97cb4a7ee..301c0e6a159f 100644
--- a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
@@ -58,7 +58,7 @@ import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
-private fun createKeyboard(
+fun createKeyboard(
deviceId: Int,
vendorId: Int,
productId: Int,
diff --git a/tests/Input/src/com/android/test/input/PointerIconLoadingTest.kt b/tests/Input/src/com/android/test/input/PointerIconLoadingTest.kt
index d196b85a7466..abfe549f3d22 100644
--- a/tests/Input/src/com/android/test/input/PointerIconLoadingTest.kt
+++ b/tests/Input/src/com/android/test/input/PointerIconLoadingTest.kt
@@ -19,7 +19,6 @@ package com.android.test.input
import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
-import android.os.Environment
import android.view.ContextThemeWrapper
import android.view.PointerIcon
import android.view.flags.Flags.enableVectorCursorA11ySettings
@@ -88,6 +87,35 @@ class PointerIconLoadingTest {
theme.applyStyle(
PointerIcon.vectorFillStyleToResource(PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_GREEN),
/* force= */ true)
+ theme.applyStyle(PointerIcon.vectorStrokeStyleToResource(
+ PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_WHITE), /* force= */ true)
+
+ val pointerIcon =
+ PointerIcon.getLoadedSystemIcon(
+ ContextThemeWrapper(context, theme),
+ PointerIcon.TYPE_ARROW,
+ /* useLargeIcons= */ false,
+ /* pointerScale= */ 1f)
+
+ pointerIcon.getBitmap().assertAgainstGolden(
+ screenshotRule,
+ testName.methodName,
+ exactScreenshotMatcher
+ )
+ }
+
+ @Test
+ fun testPointerStrokeStyle() {
+ assumeTrue(enableVectorCursors())
+ assumeTrue(enableVectorCursorA11ySettings())
+
+ val theme: Resources.Theme = context.getResources().newTheme()
+ theme.setTo(context.getTheme())
+ theme.applyStyle(
+ PointerIcon.vectorFillStyleToResource(PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_BLACK),
+ /* force= */ true)
+ theme.applyStyle(PointerIcon.vectorStrokeStyleToResource(
+ PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_BLACK), /* force= */ true)
val pointerIcon =
PointerIcon.getLoadedSystemIcon(
@@ -108,11 +136,20 @@ class PointerIconLoadingTest {
assumeTrue(enableVectorCursors())
assumeTrue(enableVectorCursorA11ySettings())
+ val theme: Resources.Theme = context.getResources().newTheme()
+ theme.setTo(context.getTheme())
+ theme.applyStyle(
+ PointerIcon.vectorFillStyleToResource(PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_BLACK),
+ /* force= */ true)
+ theme.applyStyle(
+ PointerIcon.vectorStrokeStyleToResource(
+ PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_WHITE),
+ /* force= */ true)
val pointerScale = 2f
val pointerIcon =
PointerIcon.getLoadedSystemIcon(
- context,
+ ContextThemeWrapper(context, theme),
PointerIcon.TYPE_ARROW,
/* useLargeIcons= */ false,
pointerScale)
@@ -129,8 +166,7 @@ class PointerIconLoadingTest {
const val SCREEN_WIDTH_DP = 480
const val SCREEN_HEIGHT_DP = 800
const val ASSETS_PATH = "tests/input/assets"
- val TEST_OUTPUT_PATH = Environment.getExternalStorageDirectory().absolutePath +
- "/InputTests/" +
- PointerIconLoadingTest::class.java.simpleName
+ val TEST_OUTPUT_PATH =
+ "/sdcard/Download/InputTests/" + PointerIconLoadingTest::class.java.simpleName
}
}
diff --git a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
index 5a27593c7a36..5a48327e7576 100644
--- a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
@@ -59,7 +59,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.LinkedList;
-import java.util.TreeMap;
/**
* Test class for {@link ProtoLogImpl}.
@@ -90,7 +89,7 @@ public class LegacyProtoLogImplTest {
//noinspection ResultOfMethodCallIgnored
mFile.delete();
mProtoLog = new LegacyProtoLogImpl(mFile, mViewerConfigFilename,
- 1024 * 1024, mReader, 1024, new TreeMap<>(), () -> {});
+ 1024 * 1024, mReader, 1024, () -> {});
}
@After
@@ -142,7 +141,7 @@ public class LegacyProtoLogImplTest {
TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
implSpy.log(
- LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+ LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
new Object[]{true, 10000, 30000, "test", 0.000003});
verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
@@ -159,7 +158,7 @@ public class LegacyProtoLogImplTest {
TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
implSpy.log(
- LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+ LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
new Object[]{true, 10000, 0.0001, 0.00002, "test"});
verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
@@ -176,7 +175,7 @@ public class LegacyProtoLogImplTest {
TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
implSpy.log(
- LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d",
+ LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
new Object[]{5});
verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
@@ -192,7 +191,7 @@ public class LegacyProtoLogImplTest {
TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
implSpy.log(
- LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+ LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
new Object[]{5});
verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
@@ -208,7 +207,7 @@ public class LegacyProtoLogImplTest {
TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
implSpy.log(
- LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d",
+ LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
new Object[]{5});
verify(implSpy, never()).passToLogcat(any(), any(), any());
@@ -277,7 +276,7 @@ public class LegacyProtoLogImplTest {
long before = SystemClock.elapsedRealtimeNanos();
mProtoLog.log(
LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234,
- 0b1110101001010100, null,
+ 0b1110101001010100,
new Object[]{"test", 1, 2, 3, 0.4, 0.5, 0.6, true});
long after = SystemClock.elapsedRealtimeNanos();
mProtoLog.stopProtoLog(mock(PrintWriter.class), true);
@@ -302,7 +301,7 @@ public class LegacyProtoLogImplTest {
long before = SystemClock.elapsedRealtimeNanos();
mProtoLog.log(
LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234,
- 0b01100100, null,
+ 0b01100100,
new Object[]{"test", 1, 0.1, true});
long after = SystemClock.elapsedRealtimeNanos();
mProtoLog.stopProtoLog(mock(PrintWriter.class), true);
@@ -326,7 +325,7 @@ public class LegacyProtoLogImplTest {
TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
mProtoLog.startProtoLog(mock(PrintWriter.class));
mProtoLog.log(LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234,
- 0b11, null, new Object[]{true});
+ 0b11, new Object[]{true});
mProtoLog.stopProtoLog(mock(PrintWriter.class), true);
try (InputStream is = new FileInputStream(mFile)) {
ProtoInputStream ip = new ProtoInputStream(is);
diff --git a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogViewerConfigReaderTest.java b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogViewerConfigReaderTest.java
new file mode 100644
index 000000000000..253965337824
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogViewerConfigReaderTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.protolog;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.zip.GZIPOutputStream;
+
+@SmallTest
+@Presubmit
+@RunWith(JUnit4.class)
+public class LegacyProtoLogViewerConfigReaderTest {
+ private static final String TEST_VIEWER_CONFIG = "{\n"
+ + " \"version\": \"1.0.0\",\n"
+ + " \"messages\": {\n"
+ + " \"70933285\": {\n"
+ + " \"message\": \"Test completed successfully: %b\",\n"
+ + " \"level\": \"ERROR\",\n"
+ + " \"group\": \"GENERIC_WM\"\n"
+ + " },\n"
+ + " \"1792430067\": {\n"
+ + " \"message\": \"Attempted to add window to a display that does not exist: %d."
+ + " Aborting.\",\n"
+ + " \"level\": \"WARN\",\n"
+ + " \"group\": \"GENERIC_WM\"\n"
+ + " },\n"
+ + " \"1352021864\": {\n"
+ + " \"message\": \"Test 2\",\n"
+ + " \"level\": \"WARN\",\n"
+ + " \"group\": \"GENERIC_WM\"\n"
+ + " },\n"
+ + " \"409412266\": {\n"
+ + " \"message\": \"Window %s is already added\",\n"
+ + " \"level\": \"WARN\",\n"
+ + " \"group\": \"GENERIC_WM\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"groups\": {\n"
+ + " \"GENERIC_WM\": {\n"
+ + " \"tag\": \"WindowManager\"\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+
+
+ private LegacyProtoLogViewerConfigReader
+ mConfig = new LegacyProtoLogViewerConfigReader();
+ private File mTestViewerConfig;
+
+ @Before
+ public void setUp() throws IOException {
+ mTestViewerConfig = File.createTempFile("testConfig", ".json.gz");
+ OutputStreamWriter writer = new OutputStreamWriter(
+ new GZIPOutputStream(new FileOutputStream(mTestViewerConfig)));
+ writer.write(TEST_VIEWER_CONFIG);
+ writer.close();
+ }
+
+ @After
+ public void tearDown() {
+ //noinspection ResultOfMethodCallIgnored
+ mTestViewerConfig.delete();
+ }
+
+ @Test
+ public void getViewerString_notLoaded() {
+ assertNull(mConfig.getViewerString(1));
+ }
+
+ @Test
+ public void loadViewerConfig() {
+ mConfig.loadViewerConfig(msg -> {}, mTestViewerConfig.getAbsolutePath());
+ assertEquals("Test completed successfully: %b", mConfig.getViewerString(70933285));
+ assertEquals("Test 2", mConfig.getViewerString(1352021864));
+ assertEquals("Window %s is already added", mConfig.getViewerString(409412266));
+ assertNull(mConfig.getViewerString(1));
+ }
+
+ @Test
+ public void loadViewerConfig_invalidFile() {
+ mConfig.loadViewerConfig(msg -> {}, "/tmp/unknown/file/does/not/exist");
+ // No exception is thrown.
+ assertNull(mConfig.getViewerString(1));
+ }
+}
diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
index 1d7b6b348e10..b6672a0e2f4b 100644
--- a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
@@ -60,6 +60,9 @@ import org.junit.runners.JUnit4;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import perfetto.protos.Protolog;
+import perfetto.protos.ProtologCommon;
+
import java.io.File;
import java.io.IOException;
import java.util.List;
@@ -67,9 +70,6 @@ import java.util.Random;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
-import perfetto.protos.Protolog;
-import perfetto.protos.ProtologCommon;
-
/**
* Test class for {@link ProtoLogImpl}.
*/
@@ -111,6 +111,9 @@ public class PerfettoProtoLogImplTest {
//noinspection ResultOfMethodCallIgnored
mFile.delete();
+ TestProtoLogGroup.TEST_GROUP.setLogToLogcat(false);
+ TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
+
mViewerConfigBuilder = Protolog.ProtoLogViewerConfig.newBuilder()
.addGroups(
Protolog.ProtoLogViewerConfig.Group.newBuilder()
@@ -157,8 +160,9 @@ public class PerfettoProtoLogImplTest {
mCacheUpdater = () -> {};
mReader = Mockito.spy(new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider));
mProtoLog = new PerfettoProtoLogImpl(
- viewerConfigInputStreamProvider, mReader, new TreeMap<>(),
+ viewerConfigInputStreamProvider, mReader,
() -> mCacheUpdater.run());
+ mProtoLog.registerGroups(TestProtoLogGroup.values());
}
@After
@@ -210,15 +214,15 @@ public class PerfettoProtoLogImplTest {
// Shouldn't be logging anything except WTF unless explicitly requested in the group
// override.
mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.VERBOSE, TestProtoLogGroup.TEST_GROUP, 2,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.WARN, TestProtoLogGroup.TEST_GROUP, 3,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.ERROR, TestProtoLogGroup.TEST_GROUP, 4,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.WTF, TestProtoLogGroup.TEST_GROUP, 5,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
} finally {
traceMonitor.stop(mWriter);
}
@@ -240,15 +244,15 @@ public class PerfettoProtoLogImplTest {
try {
traceMonitor.start();
mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.VERBOSE, TestProtoLogGroup.TEST_GROUP, 2,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.WARN, TestProtoLogGroup.TEST_GROUP, 3,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.ERROR, TestProtoLogGroup.TEST_GROUP, 4,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.WTF, TestProtoLogGroup.TEST_GROUP, 5,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
} finally {
traceMonitor.stop(mWriter);
}
@@ -274,15 +278,15 @@ public class PerfettoProtoLogImplTest {
try {
traceMonitor.start();
mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.VERBOSE, TestProtoLogGroup.TEST_GROUP, 2,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.WARN, TestProtoLogGroup.TEST_GROUP, 3,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.ERROR, TestProtoLogGroup.TEST_GROUP, 4,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.WTF, TestProtoLogGroup.TEST_GROUP, 5,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
} finally {
traceMonitor.stop(mWriter);
}
@@ -304,15 +308,15 @@ public class PerfettoProtoLogImplTest {
try {
traceMonitor.start();
mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.VERBOSE, TestProtoLogGroup.TEST_GROUP, 2,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.WARN, TestProtoLogGroup.TEST_GROUP, 3,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.ERROR, TestProtoLogGroup.TEST_GROUP, 4,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
mProtoLog.log(LogLevel.WTF, TestProtoLogGroup.TEST_GROUP, 5,
- LogDataType.BOOLEAN, null, new Object[]{true});
+ LogDataType.BOOLEAN, new Object[]{true});
} finally {
traceMonitor.stop(mWriter);
}
@@ -329,14 +333,14 @@ public class PerfettoProtoLogImplTest {
}
@Test
- public void log_logcatEnabledExternalMessage() {
+ public void log_logcatEnabled() {
when(mReader.getViewerString(anyLong())).thenReturn("test %b %d %% 0x%x %s %f");
PerfettoProtoLogImpl implSpy = Mockito.spy(mProtoLog);
TestProtoLogGroup.TEST_GROUP.setLogToLogcat(true);
TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
implSpy.log(
- LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+ LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
new Object[]{true, 10000, 30000, "test", 0.000003});
verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
@@ -353,32 +357,17 @@ public class PerfettoProtoLogImplTest {
TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
implSpy.log(
- LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+ LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
new Object[]{true, 10000, 0.0001, 0.00002, "test"});
verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
LogLevel.INFO),
- eq("UNKNOWN MESSAGE (1234) true 10000 1.0E-4 2.0E-5 test"));
+ eq("FORMAT_ERROR \"test %b %d %% %x %s %f\", "
+ + "args=(true, 10000, 1.0E-4, 2.0E-5, test)"));
verify(mReader).getViewerString(eq(1234L));
}
@Test
- public void log_logcatEnabledInlineMessage() {
- when(mReader.getViewerString(anyLong())).thenReturn("test %d");
- PerfettoProtoLogImpl implSpy = Mockito.spy(mProtoLog);
- TestProtoLogGroup.TEST_GROUP.setLogToLogcat(true);
- TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
-
- implSpy.log(
- LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d",
- new Object[]{5});
-
- verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
- LogLevel.INFO), eq("test 5"));
- verify(mReader, never()).getViewerString(anyLong());
- }
-
- @Test
public void log_logcatEnabledNoMessage() {
when(mReader.getViewerString(anyLong())).thenReturn(null);
PerfettoProtoLogImpl implSpy = Mockito.spy(mProtoLog);
@@ -386,11 +375,11 @@ public class PerfettoProtoLogImplTest {
TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
implSpy.log(
- LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+ LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
new Object[]{5});
verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
- LogLevel.INFO), eq("UNKNOWN MESSAGE (1234) 5"));
+ LogLevel.INFO), eq("UNKNOWN MESSAGE#1234 (5)"));
verify(mReader).getViewerString(eq(1234L));
}
@@ -401,7 +390,7 @@ public class PerfettoProtoLogImplTest {
TestProtoLogGroup.TEST_GROUP.setLogToLogcat(false);
implSpy.log(
- LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d",
+ LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
new Object[]{5});
verify(implSpy, never()).passToLogcat(any(), any(), any());
@@ -425,7 +414,7 @@ public class PerfettoProtoLogImplTest {
before = SystemClock.elapsedRealtimeNanos();
mProtoLog.log(
LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, messageHash,
- 0b1110101001010100, null,
+ 0b1110101001010100,
new Object[]{"test", 1, 2, 3, 0.4, 0.5, 0.6, true});
after = SystemClock.elapsedRealtimeNanos();
} finally {
@@ -444,6 +433,38 @@ public class PerfettoProtoLogImplTest {
.isEqualTo("My test message :: test, 2, 4, 6, 0.400000, 5.000000e-01, 0.6, true");
}
+ @Test
+ public void log_noProcessing() throws IOException {
+ PerfettoTraceMonitor traceMonitor =
+ PerfettoTraceMonitor.newBuilder().enableProtoLog().build();
+ long before;
+ long after;
+ try {
+ traceMonitor.start();
+ assertTrue(mProtoLog.isProtoEnabled());
+
+ before = SystemClock.elapsedRealtimeNanos();
+ mProtoLog.log(
+ LogLevel.INFO, TestProtoLogGroup.TEST_GROUP,
+ "My test message :: %s, %d, %o, %x, %f, %b",
+ "test", 1, 2, 3, 0.4, true);
+ after = SystemClock.elapsedRealtimeNanos();
+ } finally {
+ traceMonitor.stop(mWriter);
+ }
+
+ final ResultReader reader = new ResultReader(mWriter.write(), mTraceConfig);
+ final ProtoLogTrace protolog = reader.readProtoLogTrace();
+
+ Truth.assertThat(protolog.messages).hasSize(1);
+ Truth.assertThat(protolog.messages.getFirst().getTimestamp().getElapsedNanos())
+ .isAtLeast(before);
+ Truth.assertThat(protolog.messages.getFirst().getTimestamp().getElapsedNanos())
+ .isAtMost(after);
+ Truth.assertThat(protolog.messages.getFirst().getMessage())
+ .isEqualTo("My test message :: test, 2, 4, 6, 0.400000, true");
+ }
+
private long addMessageToConfig(ProtologCommon.ProtoLogLevel logLevel, String message) {
final long messageId = new Random().nextLong();
mViewerConfigBuilder.addMessages(Protolog.ProtoLogViewerConfig.MessageData.newBuilder()
@@ -470,7 +491,7 @@ public class PerfettoProtoLogImplTest {
before = SystemClock.elapsedRealtimeNanos();
mProtoLog.log(
LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, messageHash,
- 0b01100100, null,
+ 0b01100100,
new Object[]{"test", 1, 0.1, true});
after = SystemClock.elapsedRealtimeNanos();
} finally {
@@ -488,7 +509,7 @@ public class PerfettoProtoLogImplTest {
try {
traceMonitor.start();
mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1,
- 0b11, null, new Object[]{true});
+ 0b11, new Object[]{true});
} finally {
traceMonitor.stop(mWriter);
}
@@ -512,7 +533,7 @@ public class PerfettoProtoLogImplTest {
ProtoLogImpl.setSingleInstance(mProtoLog);
ProtoLogImpl.d(TestProtoLogGroup.TEST_GROUP, 1,
- 0b11, null, true);
+ 0b11, true);
} finally {
traceMonitor.stop(mWriter);
}
@@ -586,7 +607,7 @@ public class PerfettoProtoLogImplTest {
.isFalse();
Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
.isFalse();
- Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF)).isTrue();
+ Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF)).isFalse();
PerfettoTraceMonitor traceMonitor1 =
PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
@@ -664,7 +685,53 @@ public class PerfettoProtoLogImplTest {
Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
.isFalse();
Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF))
- .isTrue();
+ .isFalse();
+ }
+
+ @Test
+ public void supportsNullString() throws IOException {
+ PerfettoTraceMonitor traceMonitor =
+ PerfettoTraceMonitor.newBuilder().enableProtoLog(true)
+ .build();
+
+ try {
+ traceMonitor.start();
+
+ mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP,
+ "My test null string: %s", null);
+ } finally {
+ traceMonitor.stop(mWriter);
+ }
+
+ final ResultReader reader = new ResultReader(mWriter.write(), mTraceConfig);
+ final ProtoLogTrace protolog = reader.readProtoLogTrace();
+
+ Truth.assertThat(protolog.messages).hasSize(1);
+ Truth.assertThat(protolog.messages.get(0).getMessage())
+ .isEqualTo("My test null string: null");
+ }
+
+ @Test
+ public void supportNullParams() throws IOException {
+ PerfettoTraceMonitor traceMonitor =
+ PerfettoTraceMonitor.newBuilder().enableProtoLog(true)
+ .build();
+
+ try {
+ traceMonitor.start();
+
+ mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP,
+ "My null args: %d, %f, %b", null, null, null);
+ } finally {
+ traceMonitor.stop(mWriter);
+ }
+
+ final ResultReader reader = new ResultReader(mWriter.write(), mTraceConfig);
+ final ProtoLogTrace protolog = reader.readProtoLogTrace();
+
+ Truth.assertThat(protolog.messages).hasSize(1);
+ Truth.assertThat(protolog.messages.get(0).getMessage())
+ .isEqualTo("My null args: 0, 0, false");
}
private enum TestProtoLogGroup implements IProtoLogGroup {
diff --git a/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
index 60456f9ea10f..0496240f01e4 100644
--- a/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
@@ -58,51 +58,50 @@ public class ProtoLogImplTest {
public void d_logCalled() {
IProtoLog mockedProtoLog = mock(IProtoLog.class);
ProtoLogImpl.setSingleInstance(mockedProtoLog);
- ProtoLogImpl.d(TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d");
+ ProtoLogImpl.d(TestProtoLogGroup.TEST_GROUP, 1234, 4321);
verify(mockedProtoLog).log(eq(LogLevel.DEBUG), eq(
TestProtoLogGroup.TEST_GROUP),
- eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+ eq(1234L), eq(4321), eq(new Object[]{}));
}
@Test
public void v_logCalled() {
IProtoLog mockedProtoLog = mock(IProtoLog.class);
ProtoLogImpl.setSingleInstance(mockedProtoLog);
- ProtoLogImpl.v(TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d");
+ ProtoLogImpl.v(TestProtoLogGroup.TEST_GROUP, 1234, 4321);
verify(mockedProtoLog).log(eq(LogLevel.VERBOSE), eq(
TestProtoLogGroup.TEST_GROUP),
- eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+ eq(1234L), eq(4321), eq(new Object[]{}));
}
@Test
public void i_logCalled() {
IProtoLog mockedProtoLog = mock(IProtoLog.class);
ProtoLogImpl.setSingleInstance(mockedProtoLog);
- ProtoLogImpl.i(TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d");
+ ProtoLogImpl.i(TestProtoLogGroup.TEST_GROUP, 1234, 4321);
verify(mockedProtoLog).log(eq(LogLevel.INFO), eq(
TestProtoLogGroup.TEST_GROUP),
- eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+ eq(1234L), eq(4321), eq(new Object[]{}));
}
@Test
public void w_logCalled() {
IProtoLog mockedProtoLog = mock(IProtoLog.class);
ProtoLogImpl.setSingleInstance(mockedProtoLog);
- ProtoLogImpl.w(TestProtoLogGroup.TEST_GROUP, 1234,
- 4321, "test %d");
+ ProtoLogImpl.w(TestProtoLogGroup.TEST_GROUP, 1234, 4321);
verify(mockedProtoLog).log(eq(LogLevel.WARN), eq(
TestProtoLogGroup.TEST_GROUP),
- eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+ eq(1234L), eq(4321), eq(new Object[]{}));
}
@Test
public void e_logCalled() {
IProtoLog mockedProtoLog = mock(IProtoLog.class);
ProtoLogImpl.setSingleInstance(mockedProtoLog);
- ProtoLogImpl.e(TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d");
+ ProtoLogImpl.e(TestProtoLogGroup.TEST_GROUP, 1234, 4321);
verify(mockedProtoLog).log(eq(LogLevel.ERROR), eq(
TestProtoLogGroup.TEST_GROUP),
- eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+ eq(1234L), eq(4321), eq(new Object[]{}));
}
@Test
@@ -110,10 +109,10 @@ public class ProtoLogImplTest {
IProtoLog mockedProtoLog = mock(IProtoLog.class);
ProtoLogImpl.setSingleInstance(mockedProtoLog);
ProtoLogImpl.wtf(TestProtoLogGroup.TEST_GROUP,
- 1234, 4321, "test %d");
+ 1234, 4321);
verify(mockedProtoLog).log(eq(LogLevel.WTF), eq(
TestProtoLogGroup.TEST_GROUP),
- eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+ eq(1234L), eq(4321), eq(new Object[]{}));
}
private enum TestProtoLogGroup implements IProtoLogGroup {
diff --git a/tests/Internal/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java b/tests/Internal/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java
index dbd85d38b7f2..be0e8bc0fc07 100644
--- a/tests/Internal/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java
@@ -20,75 +20,77 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import android.platform.test.annotations.Presubmit;
+import android.util.proto.ProtoInputStream;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.util.zip.GZIPOutputStream;
+import perfetto.protos.Protolog;
+import perfetto.protos.ProtologCommon;
-@SmallTest
@Presubmit
@RunWith(JUnit4.class)
public class ProtoLogViewerConfigReaderTest {
- private static final String TEST_VIEWER_CONFIG = "{\n"
- + " \"version\": \"1.0.0\",\n"
- + " \"messages\": {\n"
- + " \"70933285\": {\n"
- + " \"message\": \"Test completed successfully: %b\",\n"
- + " \"level\": \"ERROR\",\n"
- + " \"group\": \"GENERIC_WM\"\n"
- + " },\n"
- + " \"1792430067\": {\n"
- + " \"message\": \"Attempted to add window to a display that does not exist: %d."
- + " Aborting.\",\n"
- + " \"level\": \"WARN\",\n"
- + " \"group\": \"GENERIC_WM\"\n"
- + " },\n"
- + " \"1352021864\": {\n"
- + " \"message\": \"Test 2\",\n"
- + " \"level\": \"WARN\",\n"
- + " \"group\": \"GENERIC_WM\"\n"
- + " },\n"
- + " \"409412266\": {\n"
- + " \"message\": \"Window %s is already added\",\n"
- + " \"level\": \"WARN\",\n"
- + " \"group\": \"GENERIC_WM\"\n"
- + " }\n"
- + " },\n"
- + " \"groups\": {\n"
- + " \"GENERIC_WM\": {\n"
- + " \"tag\": \"WindowManager\"\n"
- + " }\n"
- + " }\n"
- + "}\n";
+ private static final String TEST_GROUP_NAME = "MY_TEST_GROUP";
+ private static final String TEST_GROUP_TAG = "TEST";
+ private static final String OTHER_TEST_GROUP_NAME = "MY_OTHER_TEST_GROUP";
+ private static final String OTHER_TEST_GROUP_TAG = "OTHER_TEST";
- private LegacyProtoLogViewerConfigReader
- mConfig = new LegacyProtoLogViewerConfigReader();
- private File mTestViewerConfig;
+ private static final byte[] TEST_VIEWER_CONFIG =
+ perfetto.protos.Protolog.ProtoLogViewerConfig.newBuilder()
+ .addGroups(
+ perfetto.protos.Protolog.ProtoLogViewerConfig.Group.newBuilder()
+ .setId(1)
+ .setName(TEST_GROUP_NAME)
+ .setTag(TEST_GROUP_TAG)
+ ).addGroups(
+ perfetto.protos.Protolog.ProtoLogViewerConfig.Group.newBuilder()
+ .setId(1)
+ .setName(OTHER_TEST_GROUP_NAME)
+ .setTag(OTHER_TEST_GROUP_TAG)
+ ).addMessages(
+ perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.newBuilder()
+ .setMessageId(1)
+ .setMessage("My Test Log Message 1 %b")
+ .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_DEBUG)
+ .setGroupId(1)
+ ).addMessages(
+ perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.newBuilder()
+ .setMessageId(2)
+ .setMessage("My Test Log Message 2 %b")
+ .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_VERBOSE)
+ .setGroupId(1)
+ ).addMessages(
+ perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.newBuilder()
+ .setMessageId(3)
+ .setMessage("My Test Log Message 3 %b")
+ .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_WARN)
+ .setGroupId(1)
+ ).addMessages(
+ perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.newBuilder()
+ .setMessageId(4)
+ .setMessage("My Test Log Message 4 %b")
+ .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_ERROR)
+ .setGroupId(2)
+ ).addMessages(
+ perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.newBuilder()
+ .setMessageId(5)
+ .setMessage("My Test Log Message 5 %b")
+ .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_WTF)
+ .setGroupId(2)
+ ).build().toByteArray();
- @Before
- public void setUp() throws IOException {
- mTestViewerConfig = File.createTempFile("testConfig", ".json.gz");
- OutputStreamWriter writer = new OutputStreamWriter(
- new GZIPOutputStream(new FileOutputStream(mTestViewerConfig)));
- writer.write(TEST_VIEWER_CONFIG);
- writer.close();
- }
+ private final ViewerConfigInputStreamProvider mViewerConfigInputStreamProvider =
+ () -> new ProtoInputStream(TEST_VIEWER_CONFIG);
+
+ private ProtoLogViewerConfigReader mConfig;
- @After
- public void tearDown() {
- //noinspection ResultOfMethodCallIgnored
- mTestViewerConfig.delete();
+ @Before
+ public void before() {
+ mConfig = new ProtoLogViewerConfigReader(mViewerConfigInputStreamProvider);
}
@Test
@@ -98,17 +100,26 @@ public class ProtoLogViewerConfigReaderTest {
@Test
public void loadViewerConfig() {
- mConfig.loadViewerConfig(msg -> {}, mTestViewerConfig.getAbsolutePath());
- assertEquals("Test completed successfully: %b", mConfig.getViewerString(70933285));
- assertEquals("Test 2", mConfig.getViewerString(1352021864));
- assertEquals("Window %s is already added", mConfig.getViewerString(409412266));
- assertNull(mConfig.getViewerString(1));
+ mConfig.loadViewerConfig(new String[] { TEST_GROUP_NAME });
+ assertEquals("My Test Log Message 1 %b", mConfig.getViewerString(1));
+ assertEquals("My Test Log Message 2 %b", mConfig.getViewerString(2));
+ assertEquals("My Test Log Message 3 %b", mConfig.getViewerString(3));
+ assertNull(mConfig.getViewerString(4));
+ assertNull(mConfig.getViewerString(5));
}
@Test
- public void loadViewerConfig_invalidFile() {
- mConfig.loadViewerConfig(msg -> {}, "/tmp/unknown/file/does/not/exist");
- // No exception is thrown.
+ public void unloadViewerConfig() {
+ mConfig.loadViewerConfig(new String[] { TEST_GROUP_NAME, OTHER_TEST_GROUP_NAME });
+ mConfig.unloadViewerConfig(new String[] { TEST_GROUP_NAME });
assertNull(mConfig.getViewerString(1));
+ assertNull(mConfig.getViewerString(2));
+ assertNull(mConfig.getViewerString(3));
+ assertEquals("My Test Log Message 4 %b", mConfig.getViewerString(4));
+ assertEquals("My Test Log Message 5 %b", mConfig.getViewerString(5));
+
+ mConfig.unloadViewerConfig(new String[] { OTHER_TEST_GROUP_NAME });
+ assertNull(mConfig.getViewerString(4));
+ assertNull(mConfig.getViewerString(5));
}
}
diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
index 489ef4444e1d..3722fefb12ad 100644
--- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
@@ -47,6 +47,8 @@ import android.net.ConnectivityModuleConnector.ConnectivityModuleHealthListener;
import android.os.Handler;
import android.os.SystemProperties;
import android.os.test.TestLooper;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.DeviceConfig;
import android.util.AtomicFile;
@@ -288,7 +290,8 @@ public class CrashRecoveryTest {
}
@Test
- public void testBootLoopWithRescuePartyAndRollbackPackageHealthObserver() throws Exception {
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testBootLoopWithRescuePartyAndRollbackObserver() throws Exception {
PackageWatchdog watchdog = createWatchdog();
RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
RollbackPackageHealthObserver rollbackObserver =
@@ -360,6 +363,56 @@ public class CrashRecoveryTest {
verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
}
+ @Test
+ @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testBootLoopWithRescuePartyAndRollbackObserverNoFlags() throws Exception {
+ PackageWatchdog watchdog = createWatchdog();
+ RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
+ RollbackPackageHealthObserver rollbackObserver =
+ setUpRollbackPackageHealthObserver(watchdog);
+
+ verify(rescuePartyObserver, never()).executeBootLoopMitigation(1);
+ verify(rollbackObserver, never()).executeBootLoopMitigation(1);
+ for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
+ watchdog.noteBoot();
+ }
+ verify(rescuePartyObserver).executeBootLoopMitigation(1);
+ verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
+ verify(rollbackObserver, never()).executeBootLoopMitigation(1);
+
+ watchdog.noteBoot();
+
+ verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
+ verify(rollbackObserver).executeBootLoopMitigation(1);
+ verify(rollbackObserver, never()).executeBootLoopMitigation(2);
+ // Update the list of available rollbacks after executing bootloop mitigation once
+ when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_HIGH,
+ ROLLBACK_INFO_MANUAL));
+
+ watchdog.noteBoot();
+
+ verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
+ verify(rollbackObserver).executeBootLoopMitigation(2);
+ verify(rollbackObserver, never()).executeBootLoopMitigation(3);
+ // Update the list of available rollbacks after executing bootloop mitigation
+ when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_MANUAL));
+
+ watchdog.noteBoot();
+
+ verify(rescuePartyObserver).executeBootLoopMitigation(2);
+ verify(rescuePartyObserver, never()).executeBootLoopMitigation(3);
+ verify(rollbackObserver, never()).executeBootLoopMitigation(3);
+
+ moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1);
+ Mockito.reset(rescuePartyObserver);
+
+ for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
+ watchdog.noteBoot();
+ }
+ verify(rescuePartyObserver).executeBootLoopMitigation(1);
+ verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
+ }
+
RollbackPackageHealthObserver setUpRollbackPackageHealthObserver(PackageWatchdog watchdog) {
RollbackPackageHealthObserver rollbackObserver =
spy(new RollbackPackageHealthObserver(mSpyContext, mApexManager));
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index a8b383cd4274..ab406ef4632e 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -23,9 +23,12 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -33,6 +36,7 @@ import static org.mockito.Mockito.when;
import android.Manifest;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
@@ -116,6 +120,7 @@ public class PackageWatchdogTest {
private ConnectivityModuleConnector mConnectivityModuleConnector;
@Mock
private PackageManager mMockPackageManager;
+ @Mock Intent mMockIntent;
// Mock only sysprop apis
private PackageWatchdog.BootThreshold mSpyBootThreshold;
@Captor
@@ -1669,6 +1674,19 @@ public class PackageWatchdogTest {
PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS);
}
+ /**
+ * Tests device config changes are propagated correctly.
+ */
+ @Test
+ public void testRegisterShutdownBroadcastReceiver() {
+ PackageWatchdog watchdog = createWatchdog();
+ doReturn(mMockIntent).when(mSpyContext)
+ .registerReceiverForAllUsers(any(), any(), any(), any());
+
+ watchdog.registerShutdownBroadcastReceiver();
+ verify(mSpyContext).registerReceiverForAllUsers(any(), any(), eq(null), eq(null));
+ }
+
private void adoptShellPermissions(String... permissions) {
InstrumentationRegistry
.getInstrumentation()
diff --git a/tests/TrustTests/src/android/trust/test/UnlockAttemptTest.kt b/tests/TrustTests/src/android/trust/test/UnlockAttemptTest.kt
index 2c9361df63fd..f9e004bcd29e 100644
--- a/tests/TrustTests/src/android/trust/test/UnlockAttemptTest.kt
+++ b/tests/TrustTests/src/android/trust/test/UnlockAttemptTest.kt
@@ -17,6 +17,7 @@ package android.trust.test
import android.app.trust.TrustManager
import android.content.Context
+import android.security.Flags.shouldTrustManagerListenForPrimaryAuth
import android.trust.BaseTrustAgentService
import android.trust.TrustTestActivity
import android.trust.test.lib.LockStateTrackingRule
@@ -154,13 +155,17 @@ class UnlockAttemptTest {
private fun triggerSuccessfulUnlock() {
screenLockRule.successfulScreenLockAttempt()
- trustAgentRule.reportSuccessfulUnlock()
+ if (!shouldTrustManagerListenForPrimaryAuth()) {
+ trustAgentRule.reportSuccessfulUnlock()
+ }
await()
}
private fun triggerFailedUnlock() {
screenLockRule.failedScreenLockAttempt()
- trustAgentRule.reportFailedUnlock()
+ if (!shouldTrustManagerListenForPrimaryAuth()) {
+ trustAgentRule.reportFailedUnlock()
+ }
await()
}
diff --git a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java
index ed9c956c1aed..5f9a710c5f78 100644
--- a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java
+++ b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java
@@ -23,10 +23,15 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import static com.android.compatibility.common.util.concurrentuser.ConcurrentUserActivityUtils.getResponderUserId;
import static com.android.compatibility.common.util.concurrentuser.ConcurrentUserActivityUtils.launchActivityAsUserSync;
import static com.android.compatibility.common.util.concurrentuser.ConcurrentUserActivityUtils.sendBundleAndWaitForReply;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_DISPLAY_ID;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_EDITTEXT_CENTER;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_IME_SHOWN;
import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_REQUEST_CODE;
-import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_RESULT_CODE;
-import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REPLY_IME_HIDDEN;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_DISPLAY_ID;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_EDITTEXT_POSITION;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_HIDE_IME;
import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_IME_STATUS;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_SHOW_IME;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -96,9 +101,8 @@ public final class ConcurrentMultiUserTest {
}
}
- @Ignore("b/345557347")
@Test
- public void driverShowImeNotAffectPassenger() {
+ public void driverShowImeNotAffectPassenger() throws Exception {
assertDriverImeHidden();
assertPassengerImeHidden();
@@ -107,6 +111,34 @@ public final class ConcurrentMultiUserTest {
}
@Test
+ @Ignore("b/352823913")
+ public void passengerShowImeNotAffectDriver() throws Exception {
+ assertDriverImeHidden();
+ assertPassengerImeHidden();
+
+ showPassengerImeAndAssert();
+ assertDriverImeHidden();
+ }
+
+ @Test
+ public void driverHideImeNotAffectPassenger() throws Exception {
+ showDriverImeAndAssert();
+ showPassengerImeAndAssert();
+
+ hideDriverImeAndAssert();
+ assertPassengerImeShown();
+ }
+
+ @Test
+ public void passengerHideImeNotAffectDriver() throws Exception {
+ showDriverImeAndAssert();
+ showPassengerImeAndAssert();
+
+ hidePassengerImeAndAssert();
+ assertDriverImeShown();
+ }
+
+ @Test
public void imeListNotEmpty() {
List<InputMethodInfo> driverImeList = mInputMethodManager.getInputMethodList();
assertWithMessage("Driver IME list shouldn't be empty")
@@ -158,6 +190,11 @@ public final class ConcurrentMultiUserTest {
setImeForUser(passenger, driver);
}
+ private void assertDriverImeShown() {
+ assertWithMessage("Driver IME should be shown")
+ .that(mActivity.isMyImeVisible()).isTrue();
+ }
+
private void assertDriverImeHidden() {
assertWithMessage("Driver IME should be hidden")
.that(mActivity.isMyImeVisible()).isFalse();
@@ -169,13 +206,75 @@ public final class ConcurrentMultiUserTest {
Bundle receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
mPeerUserId, bundleToSend);
assertWithMessage("Passenger IME should be hidden")
- .that(receivedBundle.getInt(KEY_RESULT_CODE)).isEqualTo(REPLY_IME_HIDDEN);
+ .that(receivedBundle.getBoolean(KEY_IME_SHOWN, /* defaultValue= */ true)).isFalse();
+ }
+
+ private void assertPassengerImeShown() {
+ final Bundle bundleToSend = new Bundle();
+ bundleToSend.putInt(KEY_REQUEST_CODE, REQUEST_IME_STATUS);
+ Bundle receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
+ mPeerUserId, bundleToSend);
+ assertWithMessage("Passenger IME should be shown")
+ .that(receivedBundle.getBoolean(KEY_IME_SHOWN)).isTrue();
}
- private void showDriverImeAndAssert() {
+ private void showDriverImeAndAssert() throws Exception {
+ // WindowManagerInternal only allows the top focused display to show IME, so this method
+ // taps the driver display in case it is not the top focused display.
+ moveDriverDisplayToTop();
+
mActivity.showMyImeAndWait();
}
+ private void hideDriverImeAndAssert() {
+ mActivity.hideMyImeAndWait();
+ }
+
+ private void showPassengerImeAndAssert() throws Exception {
+ // WindowManagerInternal only allows the top focused display to show IME, so this method
+ // taps the passenger display in case it is not the top focused display.
+ movePassengerDisplayToTop();
+
+ Bundle bundleToSend = new Bundle();
+ bundleToSend.putInt(KEY_REQUEST_CODE, REQUEST_SHOW_IME);
+ Bundle receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
+ mPeerUserId, bundleToSend);
+
+ assertWithMessage("Passenger IME should be shown")
+ .that(receivedBundle.getBoolean(KEY_IME_SHOWN)).isTrue();
+ }
+
+ private void hidePassengerImeAndAssert() {
+ Bundle bundleToSend = new Bundle();
+ bundleToSend.putInt(KEY_REQUEST_CODE, REQUEST_HIDE_IME);
+ Bundle receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
+ mPeerUserId, bundleToSend);
+
+ assertWithMessage("Passenger IME should be hidden")
+ .that(receivedBundle.getBoolean(KEY_IME_SHOWN, /* defaultValue= */ true)).isFalse();
+ }
+
+ private void moveDriverDisplayToTop() throws Exception {
+ float[] driverEditTextCenter = mActivity.getEditTextCenter();
+ SystemUtil.runShellCommand(mUiAutomation, String.format("input tap %f %f",
+ driverEditTextCenter[0], driverEditTextCenter[1]));
+ }
+
+ private void movePassengerDisplayToTop() throws Exception {
+ final Bundle bundleToSend = new Bundle();
+ bundleToSend.putInt(KEY_REQUEST_CODE, REQUEST_EDITTEXT_POSITION);
+ Bundle receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
+ mPeerUserId, bundleToSend);
+ final float[] passengerEditTextCenter = receivedBundle.getFloatArray(KEY_EDITTEXT_CENTER);
+
+ bundleToSend.putInt(KEY_REQUEST_CODE, REQUEST_DISPLAY_ID);
+ receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
+ mPeerUserId, bundleToSend);
+ final int passengerDisplayId = receivedBundle.getInt(KEY_DISPLAY_ID);
+ SystemUtil.runShellCommand(mUiAutomation, String.format("input -d %d tap %f %f",
+ passengerDisplayId, passengerEditTextCenter[0], passengerEditTextCenter[1]));
+ }
+
/**
* Disables/enables IME for {@code user1}, then verifies that the IME settings for {@code user1}
* has changed as expected and {@code user2} stays the same.
diff --git a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java
index 3c97b79b83c1..fa0aa19a8822 100644
--- a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java
+++ b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java
@@ -16,20 +16,25 @@
package com.android.server.inputmethod.multisessiontest;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_DISPLAY_ID;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_EDITTEXT_CENTER;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_IME_SHOWN;
import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_REQUEST_CODE;
-import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_RESULT_CODE;
-import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REPLY_IME_HIDDEN;
-import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REPLY_IME_SHOWN;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_DISPLAY_ID;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_EDITTEXT_POSITION;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_HIDE_IME;
import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_IME_STATUS;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_SHOW_IME;
import android.app.Activity;
import android.os.Bundle;
import android.os.Process;
import android.util.Log;
-import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
+import androidx.annotation.WorkerThread;
import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import com.android.compatibility.common.util.PollingCheck;
@@ -43,7 +48,6 @@ public final class MainActivity extends ConcurrentUserActivityBase {
private static final long WAIT_IME_TIMEOUT_MS = 3000;
private EditText mEditor;
- private InputMethodManager mImm;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -52,19 +56,56 @@ public final class MainActivity extends ConcurrentUserActivityBase {
+ Process.myUserHandle().getIdentifier() + " on display "
+ getDisplay().getDisplayId());
setContentView(R.layout.main_activity);
- mImm = getSystemService(InputMethodManager.class);
mEditor = requireViewById(R.id.edit_text);
}
@Override
+ protected void onResume() {
+ super.onResume();
+ Log.v(TAG, "onResume");
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ Log.v(TAG, "onPause");
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ Log.v(TAG, "onResume");
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ Log.v(TAG, "onWindowFocusChanged " + hasFocus);
+ }
+
+ @Override
+ @WorkerThread
protected Bundle onBundleReceived(Bundle receivedBundle) {
final int requestCode = receivedBundle.getInt(KEY_REQUEST_CODE);
Log.v(TAG, "onBundleReceived() with request code:" + requestCode);
final Bundle replyBundle = new Bundle();
switch (requestCode) {
case REQUEST_IME_STATUS:
- replyBundle.putInt(KEY_RESULT_CODE,
- isMyImeVisible() ? REPLY_IME_SHOWN : REPLY_IME_HIDDEN);
+ replyBundle.putBoolean(KEY_IME_SHOWN, isMyImeVisible());
+ break;
+ case REQUEST_SHOW_IME:
+ showMyImeAndWait();
+ replyBundle.putBoolean(KEY_IME_SHOWN, isMyImeVisible());
+ break;
+ case REQUEST_HIDE_IME:
+ hideMyImeAndWait();
+ replyBundle.putBoolean(KEY_IME_SHOWN, isMyImeVisible());
+ break;
+ case REQUEST_EDITTEXT_POSITION:
+ replyBundle.putFloatArray(KEY_EDITTEXT_CENTER, getEditTextCenter());
+ break;
+ case REQUEST_DISPLAY_ID:
+ replyBundle.putInt(KEY_DISPLAY_ID, getDisplay().getDisplayId());
break;
default:
throw new RuntimeException("Received undefined request code:" + requestCode);
@@ -77,23 +118,41 @@ public final class MainActivity extends ConcurrentUserActivityBase {
return insets == null ? false : insets.isVisible(WindowInsetsCompat.Type.ime());
}
+ float[] getEditTextCenter() {
+ final float editTextCenterX = mEditor.getX() + 0.5f * mEditor.getWidth();
+ final float editTextCenterY = mEditor.getY() + 0.5f * mEditor.getHeight();
+ return new float[]{editTextCenterX, editTextCenterY};
+ }
+
+ @WorkerThread
void showMyImeAndWait() {
- Log.v(TAG, "showSoftInput");
runOnUiThread(() -> {
- // requestFocus() must run on UI thread.
+ // View#requestFocus() and WindowInsetsControllerCompat#show() must run on UI thread.
if (!mEditor.requestFocus()) {
Log.e(TAG, "Failed to focus on mEditor");
return;
}
- if (!mImm.showSoftInput(mEditor, /* flags= */ 0)) {
- Log.e(TAG, String.format("Failed to show my IME as user %d, "
- + "mEditor:focused=%b,hasWindowFocus=%b",
- Process.myUserHandle().getIdentifier(),
- mEditor.isFocused(), mEditor.hasWindowFocus()));
- }
+ // Compared to mImm.showSoftInput(), the call below is the recommended way to show the
+ // keyboard because it is guaranteed to be scheduled after the window is focused.
+ Log.v(TAG, "showSoftInput");
+ WindowCompat.getInsetsController(getWindow(), mEditor).show(
+ WindowInsetsCompat.Type.ime());
});
PollingCheck.waitFor(WAIT_IME_TIMEOUT_MS, () -> isMyImeVisible(),
- String.format("My IME (user %d) didn't show up",
+ String.format("%s: My IME (user %d) didn't show up", TAG,
+ Process.myUserHandle().getIdentifier()));
+ }
+
+ @WorkerThread
+ void hideMyImeAndWait() {
+ runOnUiThread(() -> {
+ Log.v(TAG, "hideSoftInput");
+ // WindowInsetsControllerCompat#hide() must run on UI thread.
+ WindowCompat.getInsetsController(getWindow(), mEditor)
+ .hide(WindowInsetsCompat.Type.ime());
+ });
+ PollingCheck.waitFor(WAIT_IME_TIMEOUT_MS, () -> !isMyImeVisible(),
+ String.format("%s: My IME (user %d) is still shown", TAG,
Process.myUserHandle().getIdentifier()));
}
}
diff --git a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/TestRequestConstants.java b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/TestRequestConstants.java
index 1501bfb69c92..68c9d5403c0b 100644
--- a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/TestRequestConstants.java
+++ b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/TestRequestConstants.java
@@ -21,9 +21,13 @@ final class TestRequestConstants {
}
public static final String KEY_REQUEST_CODE = "key_request_code";
- public static final String KEY_RESULT_CODE = "key_result_code";
+ public static final String KEY_EDITTEXT_CENTER = "key_edittext_center";
+ public static final String KEY_DISPLAY_ID = "key_display_id";
+ public static final String KEY_IME_SHOWN = "key_ime_shown";
public static final int REQUEST_IME_STATUS = 1;
- public static final int REPLY_IME_SHOWN = 2;
- public static final int REPLY_IME_HIDDEN = 3;
+ public static final int REQUEST_SHOW_IME = 2;
+ public static final int REQUEST_HIDE_IME = 3;
+ public static final int REQUEST_EDITTEXT_POSITION = 4;
+ public static final int REQUEST_DISPLAY_ID = 5;
}
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index 6a17ef85a755..df1d51e37660 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -763,10 +763,35 @@ class ChunkPrinter {
pool->setTo(chunk, android::util::DeviceToHost32(
(reinterpret_cast<const ResChunk_header*>(chunk))->size));
- printer_->Print("\n");
+ printer_->Print(StringPrintf(" strings: %zd styles %zd flags: %s|%s\n", pool->size(),
+ pool->styleCount(), pool->isUTF8() ? "UTF-8" : "UTF-16",
+ pool->isSorted() ? "SORTED" : "NON-SORTED"));
for (size_t i = 0; i < pool->size(); i++) {
printer_->Print(StringPrintf("#%zd : %s\n", i, android::util::GetString(*pool, i).c_str()));
+ if (i < pool->styleCount()) {
+ printer_->Print(" [Style] ");
+ auto maybe_style = pool->styleAt(i);
+ if (!maybe_style) {
+ printer_->Print("??? missing\n");
+ } else {
+ std::vector<const ResStringPool_span*> spans;
+ for (auto style = maybe_style.value().unsafe_ptr();
+ style->name.index != android::ResStringPool_span::END; ++style) {
+ spans.push_back(style);
+ }
+ printer_->Print(StringPrintf("(%zd)", spans.size()));
+ if (!spans.empty()) {
+ printer_->Print(" :");
+ for (const auto& span : spans) {
+ printer_->Print(StringPrintf(
+ " %s:%u,%u", android::util::GetString(*pool, span->name.index).c_str(),
+ span->firstChar, span->lastChar));
+ }
+ printer_->Print("\n");
+ }
+ }
+ }
}
}
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
index 7ba3277d2093..a274f047586c 100644
--- a/tools/aapt2/Resource.h
+++ b/tools/aapt2/Resource.h
@@ -69,6 +69,8 @@ enum class ResourceType {
kXml,
};
+enum class FlagStatus { NoFlag = 0, Disabled = 1, Enabled = 2 };
+
android::StringPiece to_string(ResourceType type);
/**
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 6af39b739e9b..2df941834063 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#include "ResourceParser.h"
#include <functional>
@@ -108,6 +107,7 @@ struct ParsedResource {
Visibility::Level visibility_level = Visibility::Level::kUndefined;
bool staged_api = false;
bool allow_new = false;
+ FlagStatus flag_status;
std::optional<OverlayableItem> overlayable_item;
std::optional<StagedId> staged_alias;
@@ -161,6 +161,8 @@ static bool AddResourcesToTable(ResourceTable* table, android::IDiagnostics* dia
res_builder.SetStagedId(res->staged_alias.value());
}
+ res_builder.SetFlagStatus(res->flag_status);
+
bool error = false;
if (!res->name.entry.empty()) {
if (!table->AddResource(res_builder.Build(), diag)) {
@@ -544,6 +546,30 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
});
std::string resource_type = parser->element_name();
+ std::optional<StringPiece> flag =
+ xml::FindAttribute(parser, "http://schemas.android.com/apk/res/android", "featureFlag");
+ out_resource->flag_status = FlagStatus::NoFlag;
+ if (flag) {
+ auto flag_it = options_.feature_flag_values.find(flag.value());
+ if (flag_it == options_.feature_flag_values.end()) {
+ diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
+ << "Resource flag value undefined");
+ return false;
+ }
+ const auto& flag_properties = flag_it->second;
+ if (!flag_properties.read_only) {
+ diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
+ << "Only read only flags may be used with resources");
+ return false;
+ }
+ if (!flag_properties.enabled.has_value()) {
+ diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
+ << "Only flags with a value may be used with resources");
+ return false;
+ }
+ out_resource->flag_status =
+ flag_properties.enabled.value() ? FlagStatus::Enabled : FlagStatus::Disabled;
+ }
// The value format accepted for this resource.
uint32_t resource_format = 0u;
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
index 012a056dccf3..45d41c193cb4 100644
--- a/tools/aapt2/ResourceParser.h
+++ b/tools/aapt2/ResourceParser.h
@@ -27,6 +27,7 @@
#include "androidfw/IDiagnostics.h"
#include "androidfw/StringPiece.h"
#include "androidfw/StringPool.h"
+#include "cmd/Util.h"
#include "xml/XmlPullParser.h"
namespace aapt {
@@ -54,6 +55,8 @@ struct ResourceParserOptions {
// If visibility was forced, we need to use it when creating a new resource and also error if we
// try to parse the <public>, <public-group>, <java-symbol> or <symbol> tags.
std::optional<Visibility::Level> visibility;
+
+ FeatureFlagValues feature_flag_values;
};
struct FlattenedXmlSubTree {
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index a3b0b45df5c3..1cdb71551d5d 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -231,6 +231,47 @@ bool ResourceEntry::HasDefaultValue() const {
return false;
}
+ResourceTable::CollisionResult ResourceTable::ResolveFlagCollision(FlagStatus existing,
+ FlagStatus incoming) {
+ switch (existing) {
+ case FlagStatus::NoFlag:
+ switch (incoming) {
+ case FlagStatus::NoFlag:
+ return CollisionResult::kConflict;
+ case FlagStatus::Disabled:
+ return CollisionResult::kKeepOriginal;
+ case FlagStatus::Enabled:
+ return CollisionResult::kTakeNew;
+ default:
+ return CollisionResult::kConflict;
+ }
+ case FlagStatus::Disabled:
+ switch (incoming) {
+ case FlagStatus::NoFlag:
+ return CollisionResult::kTakeNew;
+ case FlagStatus::Disabled:
+ return CollisionResult::kKeepOriginal;
+ case FlagStatus::Enabled:
+ return CollisionResult::kTakeNew;
+ default:
+ return CollisionResult::kConflict;
+ }
+ case FlagStatus::Enabled:
+ switch (incoming) {
+ case FlagStatus::NoFlag:
+ return CollisionResult::kKeepOriginal;
+ case FlagStatus::Disabled:
+ return CollisionResult::kKeepOriginal;
+ case FlagStatus::Enabled:
+ return CollisionResult::kConflict;
+ default:
+ return CollisionResult::kConflict;
+ }
+ default:
+ return CollisionResult::kConflict;
+ }
+}
+
// The default handler for collisions.
//
// Typically, a weak value will be overridden by a strong value. An existing weak
@@ -564,16 +605,21 @@ bool ResourceTable::AddResource(NewResource&& res, android::IDiagnostics* diag)
if (!config_value->value) {
// Resource does not exist, add it now.
config_value->value = std::move(res.value);
+ config_value->flag_status = res.flag_status;
} else {
// When validation is enabled, ensure that a resource cannot have multiple values defined for
- // the same configuration.
- auto result = validate ? ResolveValueCollision(config_value->value.get(), res.value.get())
+ // the same configuration unless protected by flags.
+ auto result = validate ? ResolveFlagCollision(config_value->flag_status, res.flag_status)
: CollisionResult::kKeepBoth;
+ if (result == CollisionResult::kConflict) {
+ result = ResolveValueCollision(config_value->value.get(), res.value.get());
+ }
switch (result) {
case CollisionResult::kKeepBoth:
// Insert the value ignoring for duplicate configurations
entry->values.push_back(util::make_unique<ResourceConfigValue>(res.config, res.product));
entry->values.back()->value = std::move(res.value);
+ entry->values.back()->flag_status = res.flag_status;
break;
case CollisionResult::kTakeNew:
@@ -735,6 +781,11 @@ NewResourceBuilder& NewResourceBuilder::SetAllowMangled(bool allow_mangled) {
return *this;
}
+NewResourceBuilder& NewResourceBuilder::SetFlagStatus(FlagStatus flag_status) {
+ res_.flag_status = flag_status;
+ return *this;
+}
+
NewResource NewResourceBuilder::Build() {
return std::move(res_);
}
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 61e399c7ab68..9530c1750c79 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -104,6 +104,8 @@ class ResourceConfigValue {
// The actual Value.
std::unique_ptr<Value> value;
+ FlagStatus flag_status;
+
ResourceConfigValue(const android::ConfigDescription& config, android::StringPiece product)
: config(config), product(product) {
}
@@ -269,6 +271,7 @@ struct NewResource {
std::optional<AllowNew> allow_new;
std::optional<StagedId> staged_id;
bool allow_mangled = false;
+ FlagStatus flag_status;
};
struct NewResourceBuilder {
@@ -282,6 +285,7 @@ struct NewResourceBuilder {
NewResourceBuilder& SetAllowNew(AllowNew allow_new);
NewResourceBuilder& SetStagedId(StagedId id);
NewResourceBuilder& SetAllowMangled(bool allow_mangled);
+ NewResourceBuilder& SetFlagStatus(FlagStatus flag_status);
NewResource Build();
private:
@@ -330,7 +334,8 @@ class ResourceTable {
std::unique_ptr<ResourceTable> Clone() const;
- // When a collision of resources occurs, this method decides which value to keep.
+ // When a collision of resources occurs, these methods decide which value to keep.
+ static CollisionResult ResolveFlagCollision(FlagStatus existing, FlagStatus incoming);
static CollisionResult ResolveValueCollision(Value* existing, Value* incoming);
// The string pool used by this resource table. Values that reference strings must use
diff --git a/tools/aapt2/ResourceValues_test.cpp b/tools/aapt2/ResourceValues_test.cpp
index d788e3fd5fc7..b30348ddd4b4 100644
--- a/tools/aapt2/ResourceValues_test.cpp
+++ b/tools/aapt2/ResourceValues_test.cpp
@@ -184,6 +184,35 @@ TEST(ResourcesValuesTest, StringClones) {
EXPECT_THAT(pool_b.strings()[0]->value, StrEq("hello"));
}
+TEST(ResourcesValuesTest, StringEquals) {
+ android::StringPool pool;
+
+ String str(pool.MakeRef("hello", android::StringPool::Context(test::ParseConfigOrDie("en"))));
+ String str2(pool.MakeRef("hello"));
+ EXPECT_TRUE(str.Equals(&str2));
+ EXPECT_TRUE(str2.Equals(&str));
+
+ String str3(pool.MakeRef("how are you"));
+ EXPECT_FALSE(str.Equals(&str3));
+}
+
+TEST(ResourcesValuesTest, StyledStringEquals) {
+ android::StringPool pool;
+
+ StyledString ss(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"u", 2, 4}}}));
+ StyledString ss2(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"u", 2, 4}}}));
+ StyledString ss3(pool.MakeRef(android::StyleString{"hi", {{"b", 0, 1}, {"u", 2, 4}}}));
+ StyledString ss4(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}}}));
+ StyledString ss5(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"u", 3, 4}}}));
+ StyledString ss6(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"s", 2, 4}}}));
+ EXPECT_TRUE(ss.Equals(&ss2));
+ EXPECT_TRUE(ss2.Equals(&ss));
+ EXPECT_FALSE(ss.Equals(&ss3));
+ EXPECT_FALSE(ss.Equals(&ss4));
+ EXPECT_FALSE(ss.Equals(&ss5));
+ EXPECT_FALSE(ss.Equals(&ss6));
+}
+
TEST(ResourceValuesTest, StyleMerges) {
android::StringPool pool_a;
android::StringPool pool_b;
diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto
index 1d7fd1d17dcd..2ecc82ae4792 100644
--- a/tools/aapt2/Resources.proto
+++ b/tools/aapt2/Resources.proto
@@ -246,6 +246,7 @@ message Entry {
message ConfigValue {
Configuration config = 1;
Value value = 2;
+ uint32 flag_status = 3;
}
// The generic meta-data for every value in a resource table.
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 9b8c3b3d549c..2a978a5153ca 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -171,6 +171,7 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,
parser_options.error_on_positional_arguments = !options.legacy_mode;
parser_options.preserve_visibility_of_styleables = options.preserve_visibility_of_styleables;
parser_options.translatable = translatable_file;
+ parser_options.feature_flag_values = options.feature_flag_values;
// If visibility was forced, we need to use it when creating a new resource and also error if
// we try to parse the <public>, <public-group>, <java-symbol> or <symbol> tags.
diff --git a/tools/aapt2/cmd/Diff.cpp b/tools/aapt2/cmd/Diff.cpp
index 5bfc73233bfe..6da3176b2bee 100644
--- a/tools/aapt2/cmd/Diff.cpp
+++ b/tools/aapt2/cmd/Diff.cpp
@@ -106,7 +106,7 @@ static bool EmitResourceConfigValueDiff(
if (!value_a->Equals(value_b)) {
std::stringstream str_stream;
str_stream << "value " << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
- << " config=" << config_value_a->config << " does not match:\n";
+ << " config='" << config_value_a->config << "' does not match:\n";
value_a->Print(&str_stream);
str_stream << "\n vs \n";
value_b->Print(&str_stream);
diff --git a/tools/aapt2/cmd/Optimize.h b/tools/aapt2/cmd/Optimize.h
index ee53af107b17..012b0f230ca2 100644
--- a/tools/aapt2/cmd/Optimize.h
+++ b/tools/aapt2/cmd/Optimize.h
@@ -116,6 +116,10 @@ class OptimizeCommand : public Command {
"This decreases APK size at the cost of resource retrieval performance.\n"
"Applies sparse encoding to all resources regardless of minSdk.",
&options_.force_sparse_encoding);
+ AddOptionalSwitch(
+ "--enable-compact-entries",
+ "This decreases APK size by using compact resource entries for simple data types.",
+ &options_.table_flattener_options.use_compact_entries);
AddOptionalSwitch("--collapse-resource-names",
"Collapses resource names to a single value in the key string pool. Resources can \n"
"be exempted using the \"no_collapse\" directive in a file specified by "
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index e1a3013c07bb..aaab3158f61e 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -16,6 +16,7 @@
#include "format/proto/ProtoDeserialize.h"
+#include "Resource.h"
#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
@@ -533,6 +534,8 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr
return false;
}
+ config_value->flag_status = (FlagStatus)pb_config_value.flag_status();
+
config_value->value = DeserializeValueFromPb(pb_config_value.value(), src_pool, config,
&out_table->string_pool, files, out_error);
if (config_value->value == nullptr) {
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index 0903205b5eb2..c1e15bcf9f70 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -426,6 +426,7 @@ void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table
pb_config_value->mutable_config()->set_product(config_value->product);
SerializeValueToPb(*config_value->value, pb_config_value->mutable_value(),
source_pool.get());
+ pb_config_value->set_flag_status((uint32_t)config_value->flag_status);
}
}
}
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 669cddb9af5a..382b088e4bba 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -18,9 +18,9 @@
#include <unordered_set>
-#include "android-base/logging.h"
-
#include "ResourceUtils.h"
+#include "android-base/logging.h"
+#include "process/SymbolTable.h"
#include "trace/TraceBuffer.h"
#include "util/Util.h"
#include "xml/XmlActionExecutor.h"
@@ -172,6 +172,59 @@ static bool RequiredNameIsJavaClassName(xml::Element* el, android::SourcePathDia
return NameIsJavaClassName(el, attr, diag);
}
+static bool UpdateConfigChangesIfNeeded(xml::Element* el, IAaptContext* context) {
+ xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "configChanges");
+ if (attr == nullptr) {
+ return true;
+ }
+
+ if (attr->value != "allKnown" && attr->value.find("allKnown") != std::string::npos) {
+ context->GetDiagnostics()->Error(
+ android::DiagMessage(el->line_number)
+ << "If you want to declare 'allKnown' in attribute 'android:configChanges' in <" << el->name
+ << ">, " << attr->value << " is not allowed', allKnown has to be used "
+ << "by itself, for example: 'android:configChanges=allKnown', it cannot be combined with "
+ << "the other flags");
+ return false;
+ }
+
+ if (attr->value == "allKnown") {
+ SymbolTable* symbol_table = context->GetExternalSymbols();
+ const SymbolTable::Symbol* symbol =
+ symbol_table->FindByName(ResourceName("android", ResourceType::kAttr, "configChanges"));
+
+ if (symbol == nullptr) {
+ context->GetDiagnostics()->Error(
+ android::DiagMessage(el->line_number)
+ << "Cannot find symbol for android:configChanges with min sdk: "
+ << context->GetMinSdkVersion());
+ return false;
+ }
+
+ std::stringstream new_value;
+
+ const auto& symbols = symbol->attribute->symbols;
+ for (auto it = symbols.begin(); it != symbols.end(); ++it) {
+ // Skip 'resourcesUnused' which is the flag to fully disable activity restart specifically
+ // for games.
+ if (it->symbol.name.value().entry == "resourcesUnused") {
+ continue;
+ }
+ if (it != symbols.begin()) {
+ new_value << "|";
+ }
+ new_value << it->symbol.name.value().entry;
+ }
+ const auto& old_value = attr->value;
+ auto new_value_str = new_value.str();
+ context->GetDiagnostics()->Note(android::DiagMessage(el->line_number)
+ << "Updating value of 'android:configChanges' from "
+ << old_value << " to " << new_value_str);
+ attr->value = std::move(new_value_str);
+ }
+ return true;
+}
+
static bool RequiredNameIsJavaPackage(xml::Element* el, android::SourcePathDiagnostics* diag) {
xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name");
if (attr == nullptr) {
@@ -382,8 +435,9 @@ static void EnsureNamespaceIsDeclared(const std::string& prefix, const std::stri
}
}
-bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, android::IDiagnostics* diag) {
+bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, IAaptContext* context) {
// First verify some options.
+ android::IDiagnostics* diag = context->GetDiagnostics();
if (options_.rename_manifest_package) {
if (!util::IsJavaPackageName(options_.rename_manifest_package.value())) {
diag->Error(android::DiagMessage() << "invalid manifest package override '"
@@ -432,6 +486,8 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, android::IDiagn
// Common component actions.
xml::XmlNodeAction component_action;
component_action.Action(RequiredNameIsJavaClassName);
+ component_action.Action(
+ [context](xml::Element* el) -> bool { return UpdateConfigChangesIfNeeded(el, context); });
component_action["intent-filter"] = intent_filter_action;
component_action["preferred"] = intent_filter_action;
component_action["meta-data"] = meta_data_action;
@@ -778,7 +834,7 @@ bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) {
}
xml::XmlActionExecutor executor;
- if (!BuildRules(&executor, context->GetDiagnostics())) {
+ if (!BuildRules(&executor, context)) {
return false;
}
diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h
index df0ece6fe24a..748a82858175 100644
--- a/tools/aapt2/link/ManifestFixer.h
+++ b/tools/aapt2/link/ManifestFixer.h
@@ -110,7 +110,7 @@ class ManifestFixer : public IXmlResourceConsumer {
private:
DISALLOW_COPY_AND_ASSIGN(ManifestFixer);
- bool BuildRules(xml::XmlActionExecutor* executor, android::IDiagnostics* diag);
+ bool BuildRules(xml::XmlActionExecutor* executor, IAaptContext* context);
ManifestFixerOptions options_;
};
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 3cfdf7832801..50086273a819 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -37,27 +37,30 @@ struct ManifestFixerTest : public ::testing::Test {
.SetCompilationPackage("android")
.SetPackageId(0x01)
.SetNameManglerPolicy(NameManglerPolicy{"android"})
- .AddSymbolSource(
- test::StaticSymbolSourceBuilder()
- .AddSymbol(
- "android:attr/package", ResourceId(0x01010000),
- test::AttributeBuilder()
- .SetTypeMask(android::ResTable_map::TYPE_STRING)
- .Build())
- .AddSymbol(
- "android:attr/minSdkVersion", ResourceId(0x01010001),
- test::AttributeBuilder()
- .SetTypeMask(android::ResTable_map::TYPE_STRING |
- android::ResTable_map::TYPE_INTEGER)
- .Build())
- .AddSymbol(
- "android:attr/targetSdkVersion", ResourceId(0x01010002),
- test::AttributeBuilder()
- .SetTypeMask(android::ResTable_map::TYPE_STRING |
- android::ResTable_map::TYPE_INTEGER)
- .Build())
- .AddSymbol("android:string/str", ResourceId(0x01060000))
- .Build())
+ .AddSymbolSource(test::StaticSymbolSourceBuilder()
+ .AddSymbol("android:attr/package", ResourceId(0x01010000),
+ test::AttributeBuilder()
+ .SetTypeMask(android::ResTable_map::TYPE_STRING)
+ .Build())
+ .AddSymbol("android:attr/minSdkVersion", ResourceId(0x01010001),
+ test::AttributeBuilder()
+ .SetTypeMask(android::ResTable_map::TYPE_STRING |
+ android::ResTable_map::TYPE_INTEGER)
+ .Build())
+ .AddSymbol("android:attr/targetSdkVersion", ResourceId(0x01010002),
+ test::AttributeBuilder()
+ .SetTypeMask(android::ResTable_map::TYPE_STRING |
+ android::ResTable_map::TYPE_INTEGER)
+ .Build())
+ .AddSymbol("android:string/str", ResourceId(0x01060000))
+ .AddSymbol("android:attr/configChanges", ResourceId(0x01010003),
+ test::AttributeBuilder()
+ .AddItem("testConfigChange1", 1)
+ .AddItem("testConfigChange2", 2)
+ .AddItem("resourcesUnused", 4)
+ .SetTypeMask(android::ResTable_map::TYPE_STRING)
+ .Build())
+ .Build())
.Build();
}
@@ -1591,4 +1594,72 @@ TEST_F(ManifestFixerTest, IntentFilterPathMustStartWithLeadingSlashOnDeepLinks)
</manifest>)";
EXPECT_THAT(Verify(input), NotNull());
}
+
+TEST_F(ManifestFixerTest, AllKnownNotDeclaredProperly) {
+ std::string input = R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <application>
+ <activity android:name=".MainActivity"
+ android:configChanges="allKnown|testConfigChange1">
+ </activity>
+ </application>
+ </manifest>)";
+ auto doc = Verify(input);
+ EXPECT_THAT(doc, IsNull());
+}
+
+TEST_F(ManifestFixerTest, ModifyAttributeValueForAllKnown) {
+ std::string input = R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <application>
+ <activity android:name=".MainActivity"
+ android:configChanges="allKnown">
+ </activity>
+ </application>
+ </manifest>)";
+ auto doc = Verify(input);
+ EXPECT_THAT(doc, NotNull());
+
+ xml::Element* el;
+ xml::Attribute* attr;
+
+ el = doc->root.get();
+ ASSERT_THAT(el, NotNull());
+ el = el->FindChild({}, "application");
+ ASSERT_THAT(el, NotNull());
+ el = el->FindChild({}, "activity");
+ ASSERT_THAT(el, NotNull());
+
+ attr = el->FindAttribute(xml::kSchemaAndroid, "configChanges");
+ ASSERT_THAT(attr->value, "testConfigChange1|testConfigChange2");
+}
+
+TEST_F(ManifestFixerTest, DoNothingForOtherConfigChanges) {
+ std::string input = R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <application>
+ <activity android:name=".MainActivity"
+ android:configChanges="testConfigChange2">
+ </activity>
+ </application>
+ </manifest>)";
+ auto doc = Verify(input);
+ EXPECT_THAT(doc, NotNull());
+
+ xml::Element* el;
+ xml::Attribute* attr;
+
+ el = doc->root.get();
+ ASSERT_THAT(el, NotNull());
+ el = el->FindChild({}, "application");
+ ASSERT_THAT(el, NotNull());
+ el = el->FindChild({}, "activity");
+ ASSERT_THAT(el, NotNull());
+
+ attr = el->FindAttribute(xml::kSchemaAndroid, "configChanges");
+ ASSERT_THAT(attr->value, "testConfigChange2");
+}
} // namespace aapt
diff --git a/tools/aapt2/test/Fixture.h b/tools/aapt2/test/Fixture.h
index ba4a734e03bb..14298d1678f0 100644
--- a/tools/aapt2/test/Fixture.h
+++ b/tools/aapt2/test/Fixture.h
@@ -127,4 +127,4 @@ struct LinkCommandBuilder {
} // namespace aapt
-#endif // AAPT_TEST_FIXTURE_H \ No newline at end of file
+#endif // AAPT_TEST_FIXTURE_H
diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp
index 02e4beaed949..8ae55b8868c3 100644
--- a/tools/aapt2/util/Files.cpp
+++ b/tools/aapt2/util/Files.cpp
@@ -189,7 +189,7 @@ void AppendPath(std::string* base, StringPiece part) {
base->append(part.data(), part.size());
}
-std::string BuildPath(std::vector<const StringPiece>&& args) {
+std::string BuildPath(const std::vector<StringPiece>& args) {
if (args.empty()) {
return "";
}
diff --git a/tools/aapt2/util/Files.h b/tools/aapt2/util/Files.h
index 42eeaf2d2e2a..c1a42446ec3b 100644
--- a/tools/aapt2/util/Files.h
+++ b/tools/aapt2/util/Files.h
@@ -60,7 +60,7 @@ FileType GetFileType(const std::string& path);
void AppendPath(std::string* base, android::StringPiece part);
// Concatenates the list of paths and separates each part with the directory separator.
-std::string BuildPath(std::vector<const android::StringPiece>&& args);
+std::string BuildPath(const std::vector<android::StringPiece>& args);
// Makes all the directories in `path`. The last element in the path is interpreted as a directory.
bool mkdirs(const std::string& path);
diff --git a/tools/aapt2/xml/XmlPullParser.cpp b/tools/aapt2/xml/XmlPullParser.cpp
index 203832d2dbe8..1527d68a6c3b 100644
--- a/tools/aapt2/xml/XmlPullParser.cpp
+++ b/tools/aapt2/xml/XmlPullParser.cpp
@@ -14,11 +14,13 @@
* limitations under the License.
*/
-#include <iostream>
+#include "xml/XmlPullParser.h"
+
+#include <algorithm>
#include <string>
+#include <tuple>
#include "util/Util.h"
-#include "xml/XmlPullParser.h"
#include "xml/XmlUtil.h"
using ::android::InputStream;
@@ -307,7 +309,14 @@ void XMLCALL XmlPullParser::EndCdataSectionHandler(void* user_data) {
}
std::optional<StringPiece> FindAttribute(const XmlPullParser* parser, StringPiece name) {
- auto iter = parser->FindAttribute("", name);
+ return FindAttribute(parser, "", name);
+}
+
+std::optional<android::StringPiece> FindAttribute(const XmlPullParser* parser,
+ android::StringPiece namespace_uri,
+ android::StringPiece name) {
+ auto iter = parser->FindAttribute(namespace_uri, name);
+
if (iter != parser->end_attributes()) {
return StringPiece(util::TrimWhitespace(iter->value));
}
@@ -325,5 +334,18 @@ std::optional<StringPiece> FindNonEmptyAttribute(const XmlPullParser* parser, St
return {};
}
+XmlPullParser::const_iterator XmlPullParser::FindAttribute(android::StringPiece namespace_uri,
+ android::StringPiece name) const {
+ const auto end_iter = end_attributes();
+ const auto iter = std::lower_bound(begin_attributes(), end_iter, std::tuple(namespace_uri, name),
+ [](const Attribute& attr, const auto& rhs) {
+ return std::tie(attr.namespace_uri, attr.name) < rhs;
+ });
+ if (iter != end_iter && namespace_uri == iter->namespace_uri && name == iter->name) {
+ return iter;
+ }
+ return end_iter;
+}
+
} // namespace xml
} // namespace aapt
diff --git a/tools/aapt2/xml/XmlPullParser.h b/tools/aapt2/xml/XmlPullParser.h
index 655e6dc93e75..d65ba6fb56e3 100644
--- a/tools/aapt2/xml/XmlPullParser.h
+++ b/tools/aapt2/xml/XmlPullParser.h
@@ -19,8 +19,7 @@
#include <expat.h>
-#include <algorithm>
-#include <istream>
+#include <optional>
#include <ostream>
#include <queue>
#include <stack>
@@ -195,6 +194,13 @@ std::optional<android::StringPiece> FindAttribute(const XmlPullParser* parser,
android::StringPiece name);
/**
+ * Finds the attribute in the current element within the given namespace.
+ */
+std::optional<android::StringPiece> FindAttribute(const XmlPullParser* parser,
+ android::StringPiece namespace_uri,
+ android::StringPiece name);
+
+/**
* Finds the attribute in the current element within the global namespace. The
* attribute's value
* must not be the empty string.
@@ -302,31 +308,6 @@ inline bool XmlPullParser::Attribute::operator!=(const Attribute& rhs) const {
return compare(rhs) != 0;
}
-inline XmlPullParser::const_iterator XmlPullParser::FindAttribute(
- android::StringPiece namespace_uri, android::StringPiece name) const {
- const auto end_iter = end_attributes();
- const auto iter = std::lower_bound(
- begin_attributes(), end_iter,
- std::pair<android::StringPiece, android::StringPiece>(namespace_uri, name),
- [](const Attribute& attr,
- const std::pair<android::StringPiece, android::StringPiece>& rhs) -> bool {
- int cmp = attr.namespace_uri.compare(
- 0, attr.namespace_uri.size(), rhs.first.data(), rhs.first.size());
- if (cmp < 0) return true;
- if (cmp > 0) return false;
- cmp = attr.name.compare(0, attr.name.size(), rhs.second.data(),
- rhs.second.size());
- if (cmp < 0) return true;
- return false;
- });
-
- if (iter != end_iter && namespace_uri == iter->namespace_uri &&
- name == iter->name) {
- return iter;
- }
- return end_iter;
-}
-
} // namespace xml
} // namespace aapt
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java
index 191f38d3df80..718d8987c13b 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java
@@ -62,13 +62,11 @@ public class AslConverter {
XmlUtils.getSingleChildElement(
document, XmlUtils.HR_TAG_APP_METADATA_BUNDLES, true);
- return new AndroidSafetyLabelFactory()
- .createFromHrElements(XmlUtils.listOf(appMetadataBundles));
+ return new AndroidSafetyLabelFactory().createFromHrElement(appMetadataBundles);
case ON_DEVICE:
Element bundleEle =
XmlUtils.getSingleChildElement(document, XmlUtils.OD_TAG_BUNDLE, true);
- return new AndroidSafetyLabelFactory()
- .createFromOdElements(XmlUtils.listOf(bundleEle));
+ return new AndroidSafetyLabelFactory().createFromOdElement(bundleEle);
default:
throw new IllegalStateException("Unrecognized input format.");
}
@@ -91,14 +89,10 @@ public class AslConverter {
switch (format) {
case HUMAN_READABLE:
- for (var child : asl.toHrDomElements(document)) {
- document.appendChild(child);
- }
+ document.appendChild(asl.toHrDomElement(document));
break;
case ON_DEVICE:
- for (var child : asl.toOdDomElements(document)) {
- document.appendChild(child);
- }
+ document.appendChild(asl.toOdDomElement(document));
break;
default:
throw new IllegalStateException("Unrecognized input format.");
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java
index 72140a17297c..8b2fd93df889 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java
@@ -21,8 +21,6 @@ import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import java.util.List;
-
public class AndroidSafetyLabel implements AslMarshallable {
private final Long mVersion;
@@ -46,36 +44,34 @@ public class AndroidSafetyLabel implements AslMarshallable {
}
/** Creates an on-device DOM element from an {@link AndroidSafetyLabel} */
- @Override
- public List<Element> toOdDomElements(Document doc) {
+ public Element toOdDomElement(Document doc) {
Element aslEle = doc.createElement(XmlUtils.OD_TAG_BUNDLE);
aslEle.appendChild(XmlUtils.createOdLongEle(doc, XmlUtils.OD_NAME_VERSION, mVersion));
if (mSafetyLabels != null) {
- XmlUtils.appendChildren(aslEle, mSafetyLabels.toOdDomElements(doc));
+ aslEle.appendChild(mSafetyLabels.toOdDomElement(doc));
}
if (mSystemAppSafetyLabel != null) {
- XmlUtils.appendChildren(aslEle, mSystemAppSafetyLabel.toOdDomElements(doc));
+ aslEle.appendChild(mSystemAppSafetyLabel.toOdDomElement(doc));
}
if (mTransparencyInfo != null) {
- XmlUtils.appendChildren(aslEle, mTransparencyInfo.toOdDomElements(doc));
+ aslEle.appendChild(mTransparencyInfo.toOdDomElement(doc));
}
- return XmlUtils.listOf(aslEle);
+ return aslEle;
}
/** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
- @Override
- public List<Element> toHrDomElements(Document doc) {
+ public Element toHrDomElement(Document doc) {
Element aslEle = doc.createElement(XmlUtils.HR_TAG_APP_METADATA_BUNDLES);
aslEle.setAttribute(XmlUtils.HR_ATTR_VERSION, String.valueOf(mVersion));
if (mSafetyLabels != null) {
- XmlUtils.appendChildren(aslEle, mSafetyLabels.toHrDomElements(doc));
+ aslEle.appendChild(mSafetyLabels.toHrDomElement(doc));
}
if (mSystemAppSafetyLabel != null) {
- XmlUtils.appendChildren(aslEle, mSystemAppSafetyLabel.toHrDomElements(doc));
+ aslEle.appendChild(mSystemAppSafetyLabel.toHrDomElement(doc));
}
if (mTransparencyInfo != null) {
- XmlUtils.appendChildren(aslEle, mTransparencyInfo.toHrDomElements(doc));
+ aslEle.appendChild(mTransparencyInfo.toHrDomElement(doc));
}
- return XmlUtils.listOf(aslEle);
+ return aslEle;
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java
index c53cbbf99a46..b9eb2a35e63b 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java
@@ -21,65 +21,117 @@ import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Element;
-import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class AndroidSafetyLabelFactory implements AslMarshallableFactory<AndroidSafetyLabel> {
+ private final Map<Long, Set<String>> mRecognizedHrAttrs =
+ Map.ofEntries(Map.entry(1L, Set.of(XmlUtils.HR_ATTR_VERSION)));
+ private final Map<Long, Set<String>> mRequiredHrAttrs =
+ Map.ofEntries(Map.entry(1L, Set.of(XmlUtils.HR_ATTR_VERSION)));
+ private final Map<Long, Set<String>> mRecognizedHrEles =
+ Map.ofEntries(
+ Map.entry(
+ 1L,
+ Set.of(
+ XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL,
+ XmlUtils.HR_TAG_SAFETY_LABELS,
+ XmlUtils.HR_TAG_TRANSPARENCY_INFO)));
+ private final Map<Long, Set<String>> mRequiredHrEles =
+ Map.ofEntries(
+ Map.entry(1L, Set.of()),
+ Map.entry(
+ 2L,
+ Set.of(
+ XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL,
+ XmlUtils.HR_TAG_TRANSPARENCY_INFO)));
+ private final Map<Long, Set<String>> mRecognizedOdEleNames =
+ Map.ofEntries(
+ Map.entry(
+ 1L,
+ Set.of(
+ XmlUtils.OD_NAME_VERSION,
+ XmlUtils.OD_NAME_SAFETY_LABELS,
+ XmlUtils.OD_NAME_SYSTEM_APP_SAFETY_LABEL,
+ XmlUtils.OD_NAME_TRANSPARENCY_INFO)));
+ private final Map<Long, Set<String>> mRequiredOdEleNames =
+ Map.ofEntries(
+ Map.entry(1L, Set.of(XmlUtils.OD_NAME_VERSION)),
+ Map.entry(
+ 2L,
+ Set.of(
+ XmlUtils.OD_NAME_VERSION,
+ XmlUtils.OD_NAME_SYSTEM_APP_SAFETY_LABEL,
+ XmlUtils.OD_NAME_TRANSPARENCY_INFO)));
/** Creates an {@link AndroidSafetyLabel} from human-readable DOM element */
- @Override
- public AndroidSafetyLabel createFromHrElements(List<Element> appMetadataBundles)
+ public AndroidSafetyLabel createFromHrElement(Element appMetadataBundlesEle)
throws MalformedXmlException {
- Element appMetadataBundlesEle = XmlUtils.getSingleElement(appMetadataBundles);
long version = XmlUtils.tryGetVersion(appMetadataBundlesEle);
+ XmlUtils.throwIfExtraneousAttributes(
+ appMetadataBundlesEle, XmlUtils.getMostRecentVersion(mRecognizedHrAttrs, version));
+ XmlUtils.throwIfExtraneousChildrenHr(
+ appMetadataBundlesEle, XmlUtils.getMostRecentVersion(mRecognizedHrEles, version));
Element safetyLabelsEle =
XmlUtils.getSingleChildElement(
- appMetadataBundlesEle, XmlUtils.HR_TAG_SAFETY_LABELS, false);
+ appMetadataBundlesEle,
+ XmlUtils.HR_TAG_SAFETY_LABELS,
+ XmlUtils.getMostRecentVersion(mRequiredHrEles, version));
SafetyLabels safetyLabels =
- new SafetyLabelsFactory().createFromHrElements(XmlUtils.listOf(safetyLabelsEle));
+ new SafetyLabelsFactory().createFromHrElement(safetyLabelsEle, version);
Element systemAppSafetyLabelEle =
XmlUtils.getSingleChildElement(
- appMetadataBundlesEle, XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL, false);
+ appMetadataBundlesEle,
+ XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL,
+ XmlUtils.getMostRecentVersion(mRequiredHrEles, version));
SystemAppSafetyLabel systemAppSafetyLabel =
new SystemAppSafetyLabelFactory()
- .createFromHrElements(XmlUtils.listOf(systemAppSafetyLabelEle));
+ .createFromHrElement(systemAppSafetyLabelEle, version);
Element transparencyInfoEle =
XmlUtils.getSingleChildElement(
- appMetadataBundlesEle, XmlUtils.HR_TAG_TRANSPARENCY_INFO, false);
+ appMetadataBundlesEle,
+ XmlUtils.HR_TAG_TRANSPARENCY_INFO,
+ XmlUtils.getMostRecentVersion(mRequiredHrEles, version));
TransparencyInfo transparencyInfo =
- new TransparencyInfoFactory()
- .createFromHrElements(XmlUtils.listOf(transparencyInfoEle));
+ new TransparencyInfoFactory().createFromHrElement(transparencyInfoEle, version);
return new AndroidSafetyLabel(
version, systemAppSafetyLabel, safetyLabels, transparencyInfo);
}
/** Creates an {@link AndroidSafetyLabel} from on-device DOM elements */
- @Override
- public AndroidSafetyLabel createFromOdElements(List<Element> elements)
- throws MalformedXmlException {
- Element bundleEle = XmlUtils.getSingleElement(elements);
+ public AndroidSafetyLabel createFromOdElement(Element bundleEle) throws MalformedXmlException {
Long version = XmlUtils.getOdLongEle(bundleEle, XmlUtils.OD_NAME_VERSION, true);
+ XmlUtils.throwIfExtraneousChildrenOd(
+ bundleEle, XmlUtils.getMostRecentVersion(mRecognizedOdEleNames, version));
Element safetyLabelsEle =
- XmlUtils.getOdPbundleWithName(bundleEle, XmlUtils.OD_NAME_SAFETY_LABELS, false);
+ XmlUtils.getOdPbundleWithName(
+ bundleEle,
+ XmlUtils.OD_NAME_SAFETY_LABELS,
+ XmlUtils.getMostRecentVersion(mRequiredOdEleNames, version));
SafetyLabels safetyLabels =
- new SafetyLabelsFactory().createFromOdElements(XmlUtils.listOf(safetyLabelsEle));
+ new SafetyLabelsFactory().createFromOdElement(safetyLabelsEle, version);
Element systemAppSafetyLabelEle =
XmlUtils.getOdPbundleWithName(
- bundleEle, XmlUtils.OD_NAME_SYSTEM_APP_SAFETY_LABEL, false);
+ bundleEle,
+ XmlUtils.OD_NAME_SYSTEM_APP_SAFETY_LABEL,
+ XmlUtils.getMostRecentVersion(mRequiredOdEleNames, version));
SystemAppSafetyLabel systemAppSafetyLabel =
new SystemAppSafetyLabelFactory()
- .createFromOdElements(XmlUtils.listOf(systemAppSafetyLabelEle));
+ .createFromOdElement(systemAppSafetyLabelEle, version);
Element transparencyInfoEle =
- XmlUtils.getOdPbundleWithName(bundleEle, XmlUtils.OD_NAME_TRANSPARENCY_INFO, false);
+ XmlUtils.getOdPbundleWithName(
+ bundleEle,
+ XmlUtils.OD_NAME_TRANSPARENCY_INFO,
+ XmlUtils.getMostRecentVersion(mRequiredOdEleNames, version));
TransparencyInfo transparencyInfo =
- new TransparencyInfoFactory()
- .createFromOdElements(XmlUtils.listOf(transparencyInfoEle));
+ new TransparencyInfoFactory().createFromOdElement(transparencyInfoEle, version);
return new AndroidSafetyLabel(
version, systemAppSafetyLabel, safetyLabels, transparencyInfo);
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java
index f39722589a96..d2557aec5f82 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java
@@ -25,36 +25,107 @@ import java.util.List;
/** AppInfo representation */
public class AppInfo implements AslMarshallable {
- private final Boolean mApsCompliant;
+ private final String mTitle;
+ private final String mDescription;
+ private final Boolean mContainsAds;
+ private final Boolean mObeyAps;
+ private final Boolean mAdsFingerprinting;
+ private final Boolean mSecurityFingerprinting;
private final String mPrivacyPolicy;
+ private final List<String> mSecurityEndpoints;
private final List<String> mFirstPartyEndpoints;
private final List<String> mServiceProviderEndpoints;
+ private final String mCategory;
+ private final String mEmail;
+ private final String mWebsite;
+
+ private final Boolean mApsCompliant;
+ private final String mDeveloperId;
+ private final String mApplicationId;
+
+ // private final String mPrivacyPolicy;
+ // private final List<String> mFirstPartyEndpoints;
+ // private final List<String> mServiceProviderEndpoints;
public AppInfo(
- Boolean apsCompliant,
+ String title,
+ String description,
+ Boolean containsAds,
+ Boolean obeyAps,
+ Boolean adsFingerprinting,
+ Boolean securityFingerprinting,
String privacyPolicy,
+ List<String> securityEndpoints,
List<String> firstPartyEndpoints,
- List<String> serviceProviderEndpoints) {
- this.mApsCompliant = apsCompliant;
+ List<String> serviceProviderEndpoints,
+ String category,
+ String email,
+ String website,
+ Boolean apsCompliant,
+ String developerId,
+ String applicationId) {
+ this.mTitle = title;
+ this.mDescription = description;
+ this.mContainsAds = containsAds;
+ this.mObeyAps = obeyAps;
+ this.mAdsFingerprinting = adsFingerprinting;
+ this.mSecurityFingerprinting = securityFingerprinting;
this.mPrivacyPolicy = privacyPolicy;
+ this.mSecurityEndpoints = securityEndpoints;
this.mFirstPartyEndpoints = firstPartyEndpoints;
this.mServiceProviderEndpoints = serviceProviderEndpoints;
+ this.mCategory = category;
+ this.mEmail = email;
+ this.mWebsite = website;
+ this.mApsCompliant = apsCompliant;
+ this.mDeveloperId = developerId;
+ this.mApplicationId = applicationId;
}
/** Creates an on-device DOM element from the {@link SafetyLabels}. */
- @Override
- public List<Element> toOdDomElements(Document doc) {
+ public Element toOdDomElement(Document doc) {
Element appInfoEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_APP_INFO);
- if (this.mApsCompliant != null) {
+
+ if (this.mTitle != null) {
+ appInfoEle.appendChild(XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_TITLE, mTitle));
+ }
+ if (this.mDescription != null) {
+ appInfoEle.appendChild(
+ XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_DESCRIPTION, mDescription));
+ }
+ if (this.mContainsAds != null) {
+ appInfoEle.appendChild(
+ XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_CONTAINS_ADS, mContainsAds));
+ }
+ if (this.mObeyAps != null) {
+ appInfoEle.appendChild(
+ XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_OBEY_APS, mObeyAps));
+ }
+ if (this.mAdsFingerprinting != null) {
appInfoEle.appendChild(
XmlUtils.createOdBooleanEle(
- doc, XmlUtils.OD_NAME_APS_COMPLIANT, mApsCompliant));
+ doc, XmlUtils.OD_NAME_ADS_FINGERPRINTING, mAdsFingerprinting));
+ }
+ if (this.mSecurityFingerprinting != null) {
+ appInfoEle.appendChild(
+ XmlUtils.createOdBooleanEle(
+ doc,
+ XmlUtils.OD_NAME_SECURITY_FINGERPRINTING,
+ mSecurityFingerprinting));
}
if (this.mPrivacyPolicy != null) {
appInfoEle.appendChild(
XmlUtils.createOdStringEle(
doc, XmlUtils.OD_NAME_PRIVACY_POLICY, mPrivacyPolicy));
}
+ if (this.mSecurityEndpoints != null) {
+ appInfoEle.appendChild(
+ XmlUtils.createOdArray(
+ doc,
+ XmlUtils.OD_TAG_STRING_ARRAY,
+ XmlUtils.OD_NAME_SECURITY_ENDPOINTS,
+ mSecurityEndpoints));
+ }
if (this.mFirstPartyEndpoints != null) {
appInfoEle.appendChild(
XmlUtils.createOdArray(
@@ -71,27 +142,88 @@ public class AppInfo implements AslMarshallable {
XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS,
mServiceProviderEndpoints));
}
- return XmlUtils.listOf(appInfoEle);
+ if (this.mCategory != null) {
+ appInfoEle.appendChild(
+ XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_CATEGORY, this.mCategory));
+ }
+ if (this.mEmail != null) {
+ appInfoEle.appendChild(
+ XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_EMAIL, this.mEmail));
+ }
+ if (this.mWebsite != null) {
+ appInfoEle.appendChild(
+ XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_WEBSITE, this.mWebsite));
+ }
+
+ if (this.mApsCompliant != null) {
+ appInfoEle.appendChild(
+ XmlUtils.createOdBooleanEle(
+ doc, XmlUtils.OD_NAME_APS_COMPLIANT, mApsCompliant));
+ }
+ if (this.mDeveloperId != null) {
+ appInfoEle.appendChild(
+ XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_DEVELOPER_ID, mDeveloperId));
+ }
+ if (this.mApplicationId != null) {
+ appInfoEle.appendChild(
+ XmlUtils.createOdStringEle(
+ doc, XmlUtils.OD_NAME_APPLICATION_ID, mApplicationId));
+ }
+ return appInfoEle;
}
/** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
- @Override
- public List<Element> toHrDomElements(Document doc) {
+ public Element toHrDomElement(Document doc) {
Element appInfoEle = doc.createElement(XmlUtils.HR_TAG_APP_INFO);
- if (this.mApsCompliant != null) {
+
+ if (this.mTitle != null) {
+ appInfoEle.setAttribute(XmlUtils.HR_ATTR_TITLE, this.mTitle);
+ }
+ if (this.mDescription != null) {
+ appInfoEle.setAttribute(XmlUtils.HR_ATTR_DESCRIPTION, this.mDescription);
+ }
+ if (this.mContainsAds != null) {
appInfoEle.setAttribute(
- XmlUtils.HR_ATTR_APS_COMPLIANT, String.valueOf(this.mApsCompliant));
+ XmlUtils.HR_ATTR_CONTAINS_ADS, String.valueOf(this.mContainsAds));
+ }
+ if (this.mObeyAps != null) {
+ appInfoEle.setAttribute(XmlUtils.HR_ATTR_OBEY_APS, String.valueOf(this.mObeyAps));
+ }
+ if (this.mAdsFingerprinting != null) {
+ appInfoEle.setAttribute(
+ XmlUtils.HR_ATTR_ADS_FINGERPRINTING, String.valueOf(this.mAdsFingerprinting));
+ }
+ if (this.mSecurityFingerprinting != null) {
+ appInfoEle.setAttribute(
+ XmlUtils.HR_ATTR_SECURITY_FINGERPRINTING,
+ String.valueOf(this.mSecurityFingerprinting));
}
if (this.mPrivacyPolicy != null) {
appInfoEle.setAttribute(XmlUtils.HR_ATTR_PRIVACY_POLICY, this.mPrivacyPolicy);
}
+ if (this.mSecurityEndpoints != null) {
+ appInfoEle.setAttribute(
+ XmlUtils.HR_ATTR_SECURITY_ENDPOINTS, String.join("|", this.mSecurityEndpoints));
+ }
+ if (this.mCategory != null) {
+ appInfoEle.setAttribute(XmlUtils.HR_ATTR_CATEGORY, this.mCategory);
+ }
+ if (this.mEmail != null) {
+ appInfoEle.setAttribute(XmlUtils.HR_ATTR_EMAIL, this.mEmail);
+ }
+ if (this.mWebsite != null) {
+ appInfoEle.setAttribute(XmlUtils.HR_ATTR_WEBSITE, this.mWebsite);
+ }
+ if (this.mApsCompliant != null) {
+ appInfoEle.setAttribute(
+ XmlUtils.HR_ATTR_APS_COMPLIANT, String.valueOf(this.mApsCompliant));
+ }
if (this.mFirstPartyEndpoints != null) {
appInfoEle.appendChild(
XmlUtils.createHrArray(
doc, XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS, mFirstPartyEndpoints));
}
-
if (this.mServiceProviderEndpoints != null) {
appInfoEle.appendChild(
XmlUtils.createHrArray(
@@ -99,7 +231,13 @@ public class AppInfo implements AslMarshallable {
XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS,
mServiceProviderEndpoints));
}
+ if (this.mDeveloperId != null) {
+ appInfoEle.setAttribute(XmlUtils.HR_ATTR_DEVELOPER_ID, this.mDeveloperId);
+ }
+ if (this.mApplicationId != null) {
+ appInfoEle.setAttribute(XmlUtils.HR_ATTR_APPLICATION_ID, this.mApplicationId);
+ }
- return XmlUtils.listOf(appInfoEle);
+ return appInfoEle;
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java
index 6ad202765218..277a508ced57 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java
@@ -16,60 +16,233 @@
package com.android.asllib.marshallable;
-import com.android.asllib.util.AslgenUtil;
import com.android.asllib.util.MalformedXmlException;
import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Element;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class AppInfoFactory implements AslMarshallableFactory<AppInfo> {
+ // We don't need to support V1 for HR.
+ private final Map<Long, Set<String>> mRecognizedHrAttrs =
+ Map.ofEntries(
+ Map.entry(
+ 2L,
+ Set.of(
+ XmlUtils.HR_ATTR_APS_COMPLIANT,
+ XmlUtils.HR_ATTR_PRIVACY_POLICY,
+ XmlUtils.HR_ATTR_DEVELOPER_ID,
+ XmlUtils.HR_ATTR_APPLICATION_ID)));
+ private final Map<Long, Set<String>> mRequiredHrAttrs =
+ Map.ofEntries(
+ Map.entry(
+ 2L,
+ Set.of(
+ XmlUtils.HR_ATTR_APS_COMPLIANT,
+ XmlUtils.HR_ATTR_PRIVACY_POLICY,
+ XmlUtils.HR_ATTR_DEVELOPER_ID,
+ XmlUtils.HR_ATTR_APPLICATION_ID)));
+ private final Map<Long, Set<String>> mRecognizedHrEles =
+ Map.ofEntries(
+ Map.entry(
+ 2L,
+ Set.of(
+ XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS,
+ XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS)));
+ private final Map<Long, Set<String>> mRequiredHrEles =
+ Map.ofEntries(
+ Map.entry(
+ 2L,
+ Set.of(
+ XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS,
+ XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS)));
+ private final Map<Long, Set<String>> mRecognizedOdEleNames =
+ Map.ofEntries(
+ Map.entry(
+ 1L,
+ Set.of(
+ XmlUtils.OD_NAME_TITLE,
+ XmlUtils.OD_NAME_DESCRIPTION,
+ XmlUtils.OD_NAME_CONTAINS_ADS,
+ XmlUtils.OD_NAME_OBEY_APS,
+ XmlUtils.OD_NAME_ADS_FINGERPRINTING,
+ XmlUtils.OD_NAME_SECURITY_FINGERPRINTING,
+ XmlUtils.OD_NAME_PRIVACY_POLICY,
+ XmlUtils.OD_NAME_SECURITY_ENDPOINTS,
+ XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS,
+ XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS,
+ XmlUtils.OD_NAME_CATEGORY,
+ XmlUtils.OD_NAME_EMAIL,
+ XmlUtils.OD_NAME_WEBSITE)),
+ Map.entry(
+ 2L,
+ Set.of(
+ XmlUtils.OD_NAME_APS_COMPLIANT,
+ XmlUtils.OD_NAME_PRIVACY_POLICY,
+ XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS,
+ XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS,
+ XmlUtils.OD_NAME_DEVELOPER_ID,
+ XmlUtils.OD_NAME_APPLICATION_ID)));
+ private final Map<Long, Set<String>> mRequiredOdEles =
+ Map.ofEntries(
+ Map.entry(
+ 1L,
+ Set.of(
+ XmlUtils.OD_NAME_TITLE,
+ XmlUtils.OD_NAME_DESCRIPTION,
+ XmlUtils.OD_NAME_CONTAINS_ADS,
+ XmlUtils.OD_NAME_OBEY_APS,
+ XmlUtils.OD_NAME_ADS_FINGERPRINTING,
+ XmlUtils.OD_NAME_SECURITY_FINGERPRINTING,
+ XmlUtils.OD_NAME_PRIVACY_POLICY,
+ XmlUtils.OD_NAME_SECURITY_ENDPOINTS,
+ XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS,
+ XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS,
+ XmlUtils.OD_NAME_CATEGORY)),
+ Map.entry(
+ 2L,
+ Set.of(
+ XmlUtils.OD_NAME_APS_COMPLIANT,
+ XmlUtils.OD_NAME_PRIVACY_POLICY,
+ XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS,
+ XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS,
+ XmlUtils.OD_NAME_DEVELOPER_ID,
+ XmlUtils.OD_NAME_APPLICATION_ID)));
/** Creates a {@link AppInfo} from the human-readable DOM element. */
- @Override
- public AppInfo createFromHrElements(List<Element> elements) throws MalformedXmlException {
- Element appInfoEle = XmlUtils.getSingleElement(elements);
- if (appInfoEle == null) {
- AslgenUtil.logI("No AppInfo found in hr format.");
- return null;
- }
+ public AppInfo createFromHrElement(Element appInfoEle, long version)
+ throws MalformedXmlException {
+ XmlUtils.throwIfExtraneousAttributes(
+ appInfoEle, XmlUtils.getMostRecentVersion(mRecognizedHrAttrs, version));
+ XmlUtils.throwIfExtraneousChildrenHr(
+ appInfoEle, XmlUtils.getMostRecentVersion(mRecognizedHrEles, version));
- Boolean apsCompliant =
- XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_APS_COMPLIANT, true);
+ var requiredHrAttrs = XmlUtils.getMostRecentVersion(mRequiredHrAttrs, version);
+ var requiredHrEles = XmlUtils.getMostRecentVersion(mRequiredHrEles, version);
+
+ String title = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_TITLE, requiredHrAttrs);
+ String description =
+ XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_DESCRIPTION, requiredHrAttrs);
+ Boolean containsAds =
+ XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_CONTAINS_ADS, requiredHrAttrs);
+ Boolean obeyAps =
+ XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_OBEY_APS, requiredHrAttrs);
+ Boolean adsFingerprinting =
+ XmlUtils.getBoolAttr(
+ appInfoEle, XmlUtils.HR_ATTR_ADS_FINGERPRINTING, requiredHrAttrs);
+ Boolean securityFingerprinting =
+ XmlUtils.getBoolAttr(
+ appInfoEle, XmlUtils.HR_ATTR_SECURITY_FINGERPRINTING, requiredHrAttrs);
String privacyPolicy =
- XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_PRIVACY_POLICY, true);
+ XmlUtils.getStringAttr(
+ appInfoEle, XmlUtils.HR_ATTR_PRIVACY_POLICY, requiredHrAttrs);
+ List<String> securityEndpoints =
+ XmlUtils.getPipelineSplitAttr(
+ appInfoEle, XmlUtils.HR_ATTR_SECURITY_ENDPOINTS, requiredHrAttrs);
+ String category =
+ XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_CATEGORY, requiredHrAttrs);
+ String email = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_EMAIL, requiredHrAttrs);
+ String website =
+ XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_WEBSITE, requiredHrAttrs);
+ String developerId =
+ XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_DEVELOPER_ID, requiredHrAttrs);
+ String applicationId =
+ XmlUtils.getStringAttr(
+ appInfoEle, XmlUtils.HR_ATTR_APPLICATION_ID, requiredHrAttrs);
+
+ Boolean apsCompliant =
+ XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_APS_COMPLIANT, requiredHrAttrs);
List<String> firstPartyEndpoints =
XmlUtils.getHrItemsAsStrings(
- appInfoEle, XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS, true);
+ appInfoEle, XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS, requiredHrEles);
List<String> serviceProviderEndpoints =
XmlUtils.getHrItemsAsStrings(
- appInfoEle, XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS, true);
+ appInfoEle, XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS, requiredHrEles);
return new AppInfo(
- apsCompliant, privacyPolicy, firstPartyEndpoints, serviceProviderEndpoints);
+ title,
+ description,
+ containsAds,
+ obeyAps,
+ adsFingerprinting,
+ securityFingerprinting,
+ privacyPolicy,
+ securityEndpoints,
+ firstPartyEndpoints,
+ serviceProviderEndpoints,
+ category,
+ email,
+ website,
+ apsCompliant,
+ developerId,
+ applicationId);
}
/** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
- @Override
- public AppInfo createFromOdElements(List<Element> elements) throws MalformedXmlException {
- Element appInfoEle = XmlUtils.getSingleElement(elements);
- if (appInfoEle == null) {
- AslgenUtil.logI("No AppInfo found in od format.");
- return null;
- }
+ public AppInfo createFromOdElement(Element appInfoEle, long version)
+ throws MalformedXmlException {
+ XmlUtils.throwIfExtraneousChildrenOd(
+ appInfoEle, XmlUtils.getMostRecentVersion(mRecognizedOdEleNames, version));
+ var requiredOdEles = XmlUtils.getMostRecentVersion(mRequiredOdEles, version);
- Boolean apsCompliant =
- XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_APS_COMPLIANT, true);
+ String title = XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_TITLE, requiredOdEles);
+ String description =
+ XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_DESCRIPTION, requiredOdEles);
+ Boolean containsAds =
+ XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_CONTAINS_ADS, requiredOdEles);
+ Boolean obeyAps =
+ XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_OBEY_APS, requiredOdEles);
+ Boolean adsFingerprinting =
+ XmlUtils.getOdBoolEle(
+ appInfoEle, XmlUtils.OD_NAME_ADS_FINGERPRINTING, requiredOdEles);
+ Boolean securityFingerprinting =
+ XmlUtils.getOdBoolEle(
+ appInfoEle, XmlUtils.OD_NAME_SECURITY_FINGERPRINTING, requiredOdEles);
String privacyPolicy =
- XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_PRIVACY_POLICY, true);
+ XmlUtils.getOdStringEle(
+ appInfoEle, XmlUtils.OD_NAME_PRIVACY_POLICY, requiredOdEles);
+ List<String> securityEndpoints =
+ XmlUtils.getOdStringArray(
+ appInfoEle, XmlUtils.OD_NAME_SECURITY_ENDPOINTS, requiredOdEles);
+ String category =
+ XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_CATEGORY, requiredOdEles);
+ String email = XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_EMAIL, requiredOdEles);
+ String website =
+ XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_WEBSITE, requiredOdEles);
+ String developerId =
+ XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_DEVELOPER_ID, requiredOdEles);
+ String applicationId =
+ XmlUtils.getOdStringEle(
+ appInfoEle, XmlUtils.OD_NAME_APPLICATION_ID, requiredOdEles);
+
+ Boolean apsCompliant =
+ XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_APS_COMPLIANT, requiredOdEles);
List<String> firstPartyEndpoints =
- XmlUtils.getOdStringArray(appInfoEle, XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS, true);
+ XmlUtils.getOdStringArray(
+ appInfoEle, XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS, requiredOdEles);
List<String> serviceProviderEndpoints =
XmlUtils.getOdStringArray(
- appInfoEle, XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS, true);
+ appInfoEle, XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS, requiredOdEles);
return new AppInfo(
- apsCompliant, privacyPolicy, firstPartyEndpoints, serviceProviderEndpoints);
+ title,
+ description,
+ containsAds,
+ obeyAps,
+ adsFingerprinting,
+ securityFingerprinting,
+ privacyPolicy,
+ securityEndpoints,
+ firstPartyEndpoints,
+ serviceProviderEndpoints,
+ category,
+ email,
+ website,
+ apsCompliant,
+ developerId,
+ applicationId);
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java
index 0a70e7d0d74b..b6c789dc5ec7 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java
@@ -16,16 +16,11 @@
package com.android.asllib.marshallable;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import java.util.List;
-
public interface AslMarshallable {
/** Creates the on-device DOM elements from the AslMarshallable Java Object. */
- List<Element> toOdDomElements(Document doc);
+ // List<Element> toOdDomElements(Document doc);
/** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
- List<Element> toHrDomElements(Document doc);
+ // List<Element> toHrDomElements(Document doc);
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java
index 39582900f3a0..67f106948e79 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java
@@ -16,17 +16,11 @@
package com.android.asllib.marshallable;
-import com.android.asllib.util.MalformedXmlException;
-
-import org.w3c.dom.Element;
-
-import java.util.List;
-
public interface AslMarshallableFactory<T extends AslMarshallable> {
/** Creates an {@link AslMarshallableFactory} from human-readable DOM elements */
- T createFromHrElements(List<Element> elements) throws MalformedXmlException;
+ // T createFromHrElements(List<Element> elements) throws MalformedXmlException;
/** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
- T createFromOdElements(List<Element> elements) throws MalformedXmlException;
+ // T createFromOdElements(List<Element> elements) throws MalformedXmlException;
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java
index c16d18b34360..501f170ad317 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java
@@ -57,18 +57,16 @@ public class DataCategory implements AslMarshallable {
}
/** Creates on-device DOM element(s) from the {@link DataCategory}. */
- @Override
- public List<Element> toOdDomElements(Document doc) {
+ public Element toOdDomElement(Document doc) {
Element dataCategoryEle = XmlUtils.createPbundleEleWithName(doc, this.getCategoryName());
for (DataType dataType : mDataTypes.values()) {
- XmlUtils.appendChildren(dataCategoryEle, dataType.toOdDomElements(doc));
+ dataCategoryEle.appendChild(dataType.toOdDomElement(doc));
}
- return XmlUtils.listOf(dataCategoryEle);
+ return dataCategoryEle;
}
/** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
- @Override
- public List<Element> toHrDomElements(Document doc) {
+ public List<Element> toHrDomElement(Document doc) {
throw new IllegalStateException(
"Turning DataCategory or DataType into human-readable DOM elements requires"
+ " visibility into parent elements. The logic resides in DataLabels.");
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java
index 724416285acd..fb84e508ff7f 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java
@@ -23,13 +23,11 @@ import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Element;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
public class DataCategoryFactory {
/** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
- public DataCategory createFromOdElements(List<Element> elements) throws MalformedXmlException {
- Element dataCategoryEle = XmlUtils.getSingleElement(elements);
+ public DataCategory createFromOdElement(Element dataCategoryEle) throws MalformedXmlException {
Map<String, DataType> dataTypeMap = new LinkedHashMap<String, DataType>();
String categoryName = dataCategoryEle.getAttribute(XmlUtils.OD_ATTR_NAME);
var odDataTypes = XmlUtils.asElementList(dataCategoryEle.getChildNodes());
@@ -45,9 +43,7 @@ public class DataCategoryFactory {
"Unrecognized data type name %s for category %s",
dataTypeName, categoryName));
}
- dataTypeMap.put(
- dataTypeName,
- new DataTypeFactory().createFromOdElements(XmlUtils.listOf(odDataTypeEle)));
+ dataTypeMap.put(dataTypeName, new DataTypeFactory().createFromOdElement(odDataTypeEle));
}
return new DataCategory(categoryName, dataTypeMap);
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java
index 3c93c88cd060..2cf7c82fdb3e 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java
@@ -22,7 +22,6 @@ import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -57,20 +56,18 @@ public class DataLabels implements AslMarshallable {
}
/** Gets the on-device DOM element for the {@link DataLabels}. */
- @Override
- public List<Element> toOdDomElements(Document doc) {
+ public Element toOdDomElement(Document doc) {
Element dataLabelsEle =
XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_DATA_LABELS);
maybeAppendDataUsages(doc, dataLabelsEle, mDataCollected, XmlUtils.OD_NAME_DATA_COLLECTED);
maybeAppendDataUsages(doc, dataLabelsEle, mDataShared, XmlUtils.OD_NAME_DATA_SHARED);
- return XmlUtils.listOf(dataLabelsEle);
+ return dataLabelsEle;
}
/** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
- @Override
- public List<Element> toHrDomElements(Document doc) {
+ public Element toHrDomElement(Document doc) {
Element dataLabelsEle = doc.createElement(XmlUtils.HR_TAG_DATA_LABELS);
maybeAppendHrDataUsages(
doc, dataLabelsEle, mDataCollected, XmlUtils.HR_TAG_DATA_COLLECTED, false);
@@ -78,7 +75,7 @@ public class DataLabels implements AslMarshallable {
doc, dataLabelsEle, mDataCollected, XmlUtils.HR_TAG_DATA_COLLECTED_EPHEMERAL, true);
maybeAppendHrDataUsages(
doc, dataLabelsEle, mDataShared, XmlUtils.HR_TAG_DATA_SHARED, false);
- return XmlUtils.listOf(dataLabelsEle);
+ return dataLabelsEle;
}
private void maybeAppendDataUsages(
@@ -96,7 +93,7 @@ public class DataLabels implements AslMarshallable {
DataCategory dataCategory = dataCategoriesMap.get(dataCategoryName);
for (String dataTypeName : dataCategory.getDataTypes().keySet()) {
DataType dataType = dataCategory.getDataTypes().get(dataTypeName);
- XmlUtils.appendChildren(dataCategoryEle, dataType.toOdDomElements(doc));
+ dataCategoryEle.appendChild(dataType.toOdDomElement(doc));
}
dataUsageEle.appendChild(dataCategoryEle);
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java
index c4d88761835a..b1cf3ea0d39a 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java
@@ -31,9 +31,7 @@ import java.util.Map;
public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> {
/** Creates a {@link DataLabels} from the human-readable DOM element. */
- @Override
- public DataLabels createFromHrElements(List<Element> elements) throws MalformedXmlException {
- Element ele = XmlUtils.getSingleElement(elements);
+ public DataLabels createFromHrElement(Element ele) throws MalformedXmlException {
if (ele == null) {
AslgenUtil.logI("Found no DataLabels in hr format.");
return null;
@@ -83,9 +81,7 @@ public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> {
}
/** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
- @Override
- public DataLabels createFromOdElements(List<Element> elements) throws MalformedXmlException {
- Element dataLabelsEle = XmlUtils.getSingleElement(elements);
+ public DataLabels createFromOdElement(Element dataLabelsEle) throws MalformedXmlException {
if (dataLabelsEle == null) {
AslgenUtil.logI("Found no DataLabels in od format.");
return null;
@@ -111,7 +107,7 @@ public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> {
for (Element dataCategoryEle : dataCategoryEles) {
String dataCategoryName = dataCategoryEle.getAttribute(XmlUtils.OD_ATTR_NAME);
DataCategory dataCategory =
- new DataCategoryFactory().createFromOdElements(List.of(dataCategoryEle));
+ new DataCategoryFactory().createFromOdElement(dataCategoryEle);
dataCategoryMap.put(dataCategoryName, dataCategory);
}
return dataCategoryMap;
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
index 284a4b804435..83bb61144efa 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
@@ -172,8 +172,8 @@ public class DataType implements AslMarshallable {
return mEphemeral;
}
- @Override
- public List<Element> toOdDomElements(Document doc) {
+ /** Gets the on-device dom element */
+ public Element toOdDomElement(Document doc) {
Element dataTypeEle = XmlUtils.createPbundleEleWithName(doc, this.getDataTypeName());
if (!this.getPurposes().isEmpty()) {
dataTypeEle.appendChild(
@@ -197,11 +197,10 @@ public class DataType implements AslMarshallable {
this.getIsSharingOptional(),
XmlUtils.OD_NAME_IS_SHARING_OPTIONAL);
maybeAddBoolToOdElement(doc, dataTypeEle, this.getEphemeral(), XmlUtils.OD_NAME_EPHEMERAL);
- return XmlUtils.listOf(dataTypeEle);
+ return dataTypeEle;
}
/** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
- @Override
public List<Element> toHrDomElements(Document doc) {
throw new IllegalStateException(
"Turning DataCategory or DataType into human-readable DOM elements requires"
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java
index a5559d801349..96a58fa34707 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java
@@ -64,8 +64,7 @@ public class DataTypeFactory {
}
/** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
- public DataType createFromOdElements(List<Element> elements) throws MalformedXmlException {
- Element odDataTypeEle = XmlUtils.getSingleElement(elements);
+ public DataType createFromOdElement(Element odDataTypeEle) throws MalformedXmlException {
String dataTypeName = odDataTypeEle.getAttribute(XmlUtils.OD_ATTR_NAME);
List<Integer> purposeInts =
XmlUtils.getOdIntArray(odDataTypeEle, XmlUtils.OD_NAME_PURPOSES, true);
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java
new file mode 100644
index 000000000000..96a64dc29526
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java
@@ -0,0 +1,167 @@
+/*
+ * 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.asllib.marshallable;
+
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/** DeveloperInfo representation */
+public class DeveloperInfo implements AslMarshallable {
+ public enum DeveloperRelationship {
+ OEM(0),
+ ODM(1),
+ SOC(2),
+ OTA(3),
+ CARRIER(4),
+ AOSP(5),
+ OTHER(6);
+
+ private final int mValue;
+
+ DeveloperRelationship(int value) {
+ this.mValue = value;
+ }
+
+ /** Get the int value associated with the DeveloperRelationship. */
+ public int getValue() {
+ return mValue;
+ }
+
+ /** Get the DeveloperRelationship associated with the int value. */
+ public static DeveloperInfo.DeveloperRelationship forValue(int value) {
+ for (DeveloperInfo.DeveloperRelationship e : values()) {
+ if (e.getValue() == value) {
+ return e;
+ }
+ }
+ throw new IllegalArgumentException("No DeveloperRelationship enum for value: " + value);
+ }
+
+ /** Get the DeveloperRelationship associated with the human-readable String. */
+ public static DeveloperInfo.DeveloperRelationship forString(String s) {
+ for (DeveloperInfo.DeveloperRelationship e : values()) {
+ if (e.toString().equals(s)) {
+ return e;
+ }
+ }
+ throw new IllegalArgumentException("No DeveloperRelationship enum for str: " + s);
+ }
+
+ /** Human-readable String representation of DeveloperRelationship. */
+ public String toString() {
+ return this.name().toLowerCase();
+ }
+ }
+
+ private final String mName;
+ private final String mEmail;
+ private final String mAddress;
+ private final String mCountryRegion;
+ private final DeveloperRelationship mDeveloperRelationship;
+ private final String mWebsite;
+ private final String mAppDeveloperRegistryId;
+
+ public DeveloperInfo(
+ String name,
+ String email,
+ String address,
+ String countryRegion,
+ DeveloperRelationship developerRelationship,
+ String website,
+ String appDeveloperRegistryId) {
+ this.mName = name;
+ this.mEmail = email;
+ this.mAddress = address;
+ this.mCountryRegion = countryRegion;
+ this.mDeveloperRelationship = developerRelationship;
+ this.mWebsite = website;
+ this.mAppDeveloperRegistryId = appDeveloperRegistryId;
+ }
+
+ /** Creates an on-device DOM element from the {@link SafetyLabels}. */
+ public Element toOdDomElement(Document doc) {
+ Element developerInfoEle =
+ XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_DEVELOPER_INFO);
+ if (mName != null) {
+ developerInfoEle.appendChild(
+ XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_NAME, mName));
+ }
+ if (mEmail != null) {
+ developerInfoEle.appendChild(
+ XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_EMAIL, mEmail));
+ }
+ if (mAddress != null) {
+ developerInfoEle.appendChild(
+ XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_ADDRESS, mAddress));
+ }
+ if (mCountryRegion != null) {
+ developerInfoEle.appendChild(
+ XmlUtils.createOdStringEle(
+ doc, XmlUtils.OD_NAME_COUNTRY_REGION, mCountryRegion));
+ }
+ if (mDeveloperRelationship != null) {
+ developerInfoEle.appendChild(
+ XmlUtils.createOdLongEle(
+ doc,
+ XmlUtils.OD_NAME_DEVELOPER_RELATIONSHIP,
+ mDeveloperRelationship.getValue()));
+ }
+ if (mWebsite != null) {
+ developerInfoEle.appendChild(
+ XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_WEBSITE, mWebsite));
+ }
+ if (mAppDeveloperRegistryId != null) {
+ developerInfoEle.appendChild(
+ XmlUtils.createOdStringEle(
+ doc,
+ XmlUtils.OD_NAME_APP_DEVELOPER_REGISTRY_ID,
+ mAppDeveloperRegistryId));
+ }
+ return developerInfoEle;
+ }
+
+ /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
+ public Element toHrDomElement(Document doc) {
+ Element developerInfoEle = doc.createElement(XmlUtils.HR_TAG_DEVELOPER_INFO);
+ if (mName != null) {
+ developerInfoEle.setAttribute(XmlUtils.HR_ATTR_NAME, mName);
+ }
+ if (mEmail != null) {
+ developerInfoEle.setAttribute(XmlUtils.HR_ATTR_EMAIL, mEmail);
+ }
+ if (mAddress != null) {
+ developerInfoEle.setAttribute(XmlUtils.HR_ATTR_ADDRESS, mAddress);
+ }
+ if (mCountryRegion != null) {
+ developerInfoEle.setAttribute(XmlUtils.HR_ATTR_COUNTRY_REGION, mCountryRegion);
+ }
+ if (mDeveloperRelationship != null) {
+ developerInfoEle.setAttribute(
+ XmlUtils.HR_ATTR_DEVELOPER_RELATIONSHIP, mDeveloperRelationship.toString());
+ }
+ if (mWebsite != null) {
+ developerInfoEle.setAttribute(XmlUtils.HR_ATTR_WEBSITE, mWebsite);
+ }
+ if (mAppDeveloperRegistryId != null) {
+ developerInfoEle.setAttribute(
+ XmlUtils.HR_ATTR_APP_DEVELOPER_REGISTRY_ID, mAppDeveloperRegistryId);
+ }
+ return developerInfoEle;
+ }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java
new file mode 100644
index 000000000000..e82a53a53b25
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java
@@ -0,0 +1,89 @@
+/*
+ * 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.asllib.marshallable;
+
+import com.android.asllib.util.AslgenUtil;
+import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Element;
+
+public class DeveloperInfoFactory implements AslMarshallableFactory<DeveloperInfo> {
+ /** Creates a {@link DeveloperInfo} from the human-readable DOM element. */
+ public DeveloperInfo createFromHrElement(Element developerInfoEle)
+ throws MalformedXmlException {
+ if (developerInfoEle == null) {
+ AslgenUtil.logI("No DeveloperInfo found in hr format.");
+ return null;
+ }
+ String name = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_NAME, true);
+ String email = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_EMAIL, true);
+ String address = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_ADDRESS, true);
+ String countryRegion =
+ XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_COUNTRY_REGION, true);
+ DeveloperInfo.DeveloperRelationship developerRelationship =
+ DeveloperInfo.DeveloperRelationship.forString(
+ XmlUtils.getStringAttr(
+ developerInfoEle, XmlUtils.HR_ATTR_DEVELOPER_RELATIONSHIP, true));
+ String website = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_WEBSITE, false);
+ String appDeveloperRegistryId =
+ XmlUtils.getStringAttr(
+ developerInfoEle, XmlUtils.HR_ATTR_APP_DEVELOPER_REGISTRY_ID, false);
+ return new DeveloperInfo(
+ name,
+ email,
+ address,
+ countryRegion,
+ developerRelationship,
+ website,
+ appDeveloperRegistryId);
+ }
+
+ /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
+ public DeveloperInfo createFromOdElement(Element developerInfoEle)
+ throws MalformedXmlException {
+ if (developerInfoEle == null) {
+ AslgenUtil.logI("No DeveloperInfo found in od format.");
+ return null;
+ }
+ String name = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_NAME, true);
+ String email = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_EMAIL, true);
+ String address = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_ADDRESS, true);
+ String countryRegion =
+ XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_COUNTRY_REGION, true);
+ DeveloperInfo.DeveloperRelationship developerRelationship =
+ DeveloperInfo.DeveloperRelationship.forValue(
+ (int)
+ (long)
+ XmlUtils.getOdLongEle(
+ developerInfoEle,
+ XmlUtils.OD_NAME_DEVELOPER_RELATIONSHIP,
+ true));
+ String website = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_WEBSITE, false);
+ String appDeveloperRegistryId =
+ XmlUtils.getOdStringEle(
+ developerInfoEle, XmlUtils.OD_NAME_APP_DEVELOPER_REGISTRY_ID, false);
+ return new DeveloperInfo(
+ name,
+ email,
+ address,
+ countryRegion,
+ developerRelationship,
+ website,
+ appDeveloperRegistryId);
+ }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
index 2a4e130981af..1a83c02de3e4 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
@@ -21,40 +21,50 @@ import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import java.util.List;
-
/** Safety Label representation containing zero or more {@link DataCategory} for data shared */
public class SafetyLabels implements AslMarshallable {
private final DataLabels mDataLabels;
+ private final SecurityLabels mSecurityLabels;
+ private final ThirdPartyVerification mThirdPartyVerification;
- public SafetyLabels(DataLabels dataLabels) {
+ public SafetyLabels(
+ DataLabels dataLabels,
+ SecurityLabels securityLabels,
+ ThirdPartyVerification thirdPartyVerification) {
this.mDataLabels = dataLabels;
- }
-
- /** Returns the data label for the safety label */
- public DataLabels getDataLabel() {
- return mDataLabels;
+ this.mSecurityLabels = securityLabels;
+ this.mThirdPartyVerification = thirdPartyVerification;
}
/** Creates an on-device DOM element from the {@link SafetyLabels}. */
- @Override
- public List<Element> toOdDomElements(Document doc) {
+ public Element toOdDomElement(Document doc) {
Element safetyLabelsEle =
XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_SAFETY_LABELS);
if (mDataLabels != null) {
- XmlUtils.appendChildren(safetyLabelsEle, mDataLabels.toOdDomElements(doc));
+ safetyLabelsEle.appendChild(mDataLabels.toOdDomElement(doc));
+ }
+ if (mSecurityLabels != null) {
+ safetyLabelsEle.appendChild(mSecurityLabels.toOdDomElement(doc));
}
- return XmlUtils.listOf(safetyLabelsEle);
+ if (mThirdPartyVerification != null) {
+ safetyLabelsEle.appendChild(mThirdPartyVerification.toOdDomElement(doc));
+ }
+ return safetyLabelsEle;
}
/** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
- @Override
- public List<Element> toHrDomElements(Document doc) {
+ public Element toHrDomElement(Document doc) {
Element safetyLabelsEle = doc.createElement(XmlUtils.HR_TAG_SAFETY_LABELS);
if (mDataLabels != null) {
- XmlUtils.appendChildren(safetyLabelsEle, mDataLabels.toHrDomElements(doc));
+ safetyLabelsEle.appendChild(mDataLabels.toHrDomElement(doc));
+ }
+ if (mSecurityLabels != null) {
+ safetyLabelsEle.appendChild(mSecurityLabels.toHrDomElement(doc));
+ }
+ if (mThirdPartyVerification != null) {
+ safetyLabelsEle.appendChild(mThirdPartyVerification.toHrDomElement(doc));
}
- return XmlUtils.listOf(safetyLabelsEle);
+ return safetyLabelsEle;
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
index 2738337b7080..35804d9351b4 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
@@ -16,54 +16,109 @@
package com.android.asllib.marshallable;
-import com.android.asllib.util.AslgenUtil;
import com.android.asllib.util.MalformedXmlException;
import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Element;
-import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class SafetyLabelsFactory implements AslMarshallableFactory<SafetyLabels> {
+ private final Map<Long, Set<String>> mRecognizedHrAttrs =
+ Map.ofEntries(Map.entry(1L, Set.of()));
+ private final Map<Long, Set<String>> mRequiredHrAttrs = Map.ofEntries(Map.entry(1L, Set.of()));
+ private final Map<Long, Set<String>> mRecognizedHrEles =
+ Map.ofEntries(
+ Map.entry(
+ 1L,
+ Set.of(
+ XmlUtils.HR_TAG_DATA_LABELS,
+ XmlUtils.HR_TAG_SECURITY_LABELS,
+ XmlUtils.HR_TAG_THIRD_PARTY_VERIFICATION)),
+ Map.entry(2L, Set.of(XmlUtils.HR_TAG_DATA_LABELS)));
+ private final Map<Long, Set<String>> mRequiredHrEles = Map.ofEntries(Map.entry(1L, Set.of()));
+ private final Map<Long, Set<String>> mRecognizedOdEleNames =
+ Map.ofEntries(
+ Map.entry(
+ 1L,
+ Set.of(
+ XmlUtils.OD_NAME_DATA_LABELS,
+ XmlUtils.OD_NAME_SECURITY_LABELS,
+ XmlUtils.OD_NAME_THIRD_PARTY_VERIFICATION)),
+ Map.entry(2L, Set.of(XmlUtils.OD_NAME_DATA_LABELS)));
+ private final Map<Long, Set<String>> mRequiredOdEles = Map.ofEntries(Map.entry(1L, Set.of()));
/** Creates a {@link SafetyLabels} from the human-readable DOM element. */
- @Override
- public SafetyLabels createFromHrElements(List<Element> elements) throws MalformedXmlException {
- Element safetyLabelsEle = XmlUtils.getSingleElement(elements);
+ public SafetyLabels createFromHrElement(Element safetyLabelsEle, long version)
+ throws MalformedXmlException {
if (safetyLabelsEle == null) {
- AslgenUtil.logI("No SafetyLabels found in hr format.");
return null;
}
+ XmlUtils.throwIfExtraneousAttributes(
+ safetyLabelsEle, XmlUtils.getMostRecentVersion(mRecognizedHrAttrs, version));
+ XmlUtils.throwIfExtraneousChildrenHr(
+ safetyLabelsEle, XmlUtils.getMostRecentVersion(mRecognizedHrEles, version));
+
+ var requiredHrEles = XmlUtils.getMostRecentVersion(mRequiredHrEles, version);
+
DataLabels dataLabels =
new DataLabelsFactory()
- .createFromHrElements(
- XmlUtils.listOf(
- XmlUtils.getSingleChildElement(
- safetyLabelsEle,
- XmlUtils.HR_TAG_DATA_LABELS,
- false)));
- return new SafetyLabels(dataLabels);
+ .createFromHrElement(
+ XmlUtils.getSingleChildElement(
+ safetyLabelsEle,
+ XmlUtils.HR_TAG_DATA_LABELS,
+ requiredHrEles));
+ SecurityLabels securityLabels =
+ new SecurityLabelsFactory()
+ .createFromHrElement(
+ XmlUtils.getSingleChildElement(
+ safetyLabelsEle,
+ XmlUtils.HR_TAG_SECURITY_LABELS,
+ requiredHrEles));
+ ThirdPartyVerification thirdPartyVerification =
+ new ThirdPartyVerificationFactory()
+ .createFromHrElement(
+ XmlUtils.getSingleChildElement(
+ safetyLabelsEle,
+ XmlUtils.HR_TAG_THIRD_PARTY_VERIFICATION,
+ requiredHrEles));
+ return new SafetyLabels(dataLabels, securityLabels, thirdPartyVerification);
}
/** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
- @Override
- public SafetyLabels createFromOdElements(List<Element> elements) throws MalformedXmlException {
- Element safetyLabelsEle = XmlUtils.getSingleElement(elements);
+ public SafetyLabels createFromOdElement(Element safetyLabelsEle, long version)
+ throws MalformedXmlException {
if (safetyLabelsEle == null) {
- AslgenUtil.logI("No SafetyLabels found in od format.");
return null;
}
+ XmlUtils.throwIfExtraneousChildrenOd(
+ safetyLabelsEle, XmlUtils.getMostRecentVersion(mRecognizedOdEleNames, version));
+ var requiredOdEles = XmlUtils.getMostRecentVersion(mRequiredOdEles, version);
+
DataLabels dataLabels =
new DataLabelsFactory()
- .createFromOdElements(
- XmlUtils.listOf(
- XmlUtils.getOdPbundleWithName(
- safetyLabelsEle,
- XmlUtils.OD_NAME_DATA_LABELS,
- false)));
-
- return new SafetyLabels(dataLabels);
+ .createFromOdElement(
+ XmlUtils.getOdPbundleWithName(
+ safetyLabelsEle,
+ XmlUtils.OD_NAME_DATA_LABELS,
+ requiredOdEles));
+ SecurityLabels securityLabels =
+ new SecurityLabelsFactory()
+ .createFromOdElement(
+ XmlUtils.getOdPbundleWithName(
+ safetyLabelsEle,
+ XmlUtils.OD_NAME_SECURITY_LABELS,
+ requiredOdEles));
+ ThirdPartyVerification thirdPartyVerification =
+ new ThirdPartyVerificationFactory()
+ .createFromOdElement(
+ XmlUtils.getOdPbundleWithName(
+ safetyLabelsEle,
+ XmlUtils.OD_NAME_THIRD_PARTY_VERIFICATION,
+ requiredOdEles));
+ return new SafetyLabels(dataLabels, securityLabels, thirdPartyVerification);
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java
index 48643ba0e3ab..ccb84451c96f 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java
@@ -21,8 +21,6 @@ import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import java.util.List;
-
/** Security Labels representation */
public class SecurityLabels implements AslMarshallable {
@@ -35,8 +33,7 @@ public class SecurityLabels implements AslMarshallable {
}
/** Creates an on-device DOM element from the {@link SecurityLabels}. */
- @Override
- public List<Element> toOdDomElements(Document doc) {
+ public Element toOdDomElement(Document doc) {
Element ele = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_SECURITY_LABELS);
if (mIsDataDeletable != null) {
ele.appendChild(
@@ -48,12 +45,11 @@ public class SecurityLabels implements AslMarshallable {
XmlUtils.createOdBooleanEle(
doc, XmlUtils.OD_NAME_IS_DATA_ENCRYPTED, mIsDataEncrypted));
}
- return XmlUtils.listOf(ele);
+ return ele;
}
/** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
- @Override
- public List<Element> toHrDomElements(Document doc) {
+ public Element toHrDomElement(Document doc) {
Element ele = doc.createElement(XmlUtils.HR_TAG_SECURITY_LABELS);
if (mIsDataDeletable != null) {
ele.setAttribute(XmlUtils.HR_ATTR_IS_DATA_DELETABLE, String.valueOf(mIsDataDeletable));
@@ -61,6 +57,6 @@ public class SecurityLabels implements AslMarshallable {
if (mIsDataEncrypted != null) {
ele.setAttribute(XmlUtils.HR_ATTR_IS_DATA_ENCRYPTED, String.valueOf(mIsDataEncrypted));
}
- return XmlUtils.listOf(ele);
+ return ele;
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java
index 525a80388261..da98a4291b4a 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java
@@ -22,15 +22,10 @@ import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Element;
-import java.util.List;
-
public class SecurityLabelsFactory implements AslMarshallableFactory<SecurityLabels> {
/** Creates a {@link SecurityLabels} from the human-readable DOM element. */
- @Override
- public SecurityLabels createFromHrElements(List<Element> elements)
- throws MalformedXmlException {
- Element ele = XmlUtils.getSingleElement(elements);
+ public SecurityLabels createFromHrElement(Element ele) throws MalformedXmlException {
if (ele == null) {
AslgenUtil.logI("No SecurityLabels found in hr format.");
return null;
@@ -43,10 +38,7 @@ public class SecurityLabelsFactory implements AslMarshallableFactory<SecurityLab
}
/** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
- @Override
- public SecurityLabels createFromOdElements(List<Element> elements)
- throws MalformedXmlException {
- Element ele = XmlUtils.getSingleElement(elements);
+ public SecurityLabels createFromOdElement(Element ele) throws MalformedXmlException {
if (ele == null) {
AslgenUtil.logI("No SecurityLabels found in od format.");
return null;
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java
index 242e7be66d76..10d6e1aaac7d 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java
@@ -21,34 +21,43 @@ import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import java.util.List;
-
/** Safety Label representation containing zero or more {@link DataCategory} for data shared */
public class SystemAppSafetyLabel implements AslMarshallable {
+ private final String mUrl;
private final Boolean mDeclaration;
- public SystemAppSafetyLabel(Boolean d) {
+ public SystemAppSafetyLabel(String url, Boolean d) {
this.mDeclaration = d;
+ this.mUrl = null;
}
/** Creates an on-device DOM element from the {@link SystemAppSafetyLabel}. */
- @Override
- public List<Element> toOdDomElements(Document doc) {
+ public Element toOdDomElement(Document doc) {
Element systemAppSafetyLabelEle =
XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_SYSTEM_APP_SAFETY_LABEL);
- systemAppSafetyLabelEle.appendChild(
- XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_DECLARATION, mDeclaration));
- return XmlUtils.listOf(systemAppSafetyLabelEle);
+ if (mUrl != null) {
+ systemAppSafetyLabelEle.appendChild(
+ XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_URL, mUrl));
+ }
+ if (mDeclaration != null) {
+ systemAppSafetyLabelEle.appendChild(
+ XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_DECLARATION, mDeclaration));
+ }
+ return systemAppSafetyLabelEle;
}
/** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
- @Override
- public List<Element> toHrDomElements(Document doc) {
+ public Element toHrDomElement(Document doc) {
Element systemAppSafetyLabelEle =
doc.createElement(XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL);
- XmlUtils.maybeSetHrBoolAttr(
- systemAppSafetyLabelEle, XmlUtils.HR_ATTR_DECLARATION, mDeclaration);
- return XmlUtils.listOf(systemAppSafetyLabelEle);
+ if (mUrl != null) {
+ systemAppSafetyLabelEle.setAttribute(XmlUtils.HR_ATTR_URL, mUrl);
+ }
+ if (mDeclaration != null) {
+ systemAppSafetyLabelEle.setAttribute(
+ XmlUtils.HR_ATTR_DECLARATION, String.valueOf(mDeclaration));
+ }
+ return systemAppSafetyLabelEle;
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java
index 7f4aa7a3b690..971ae9296eb8 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java
@@ -16,42 +16,77 @@
package com.android.asllib.marshallable;
-import com.android.asllib.util.AslgenUtil;
import com.android.asllib.util.MalformedXmlException;
import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Element;
-import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class SystemAppSafetyLabelFactory implements AslMarshallableFactory<SystemAppSafetyLabel> {
+ private final Map<Long, Set<String>> mRecognizedHrAttrs =
+ Map.ofEntries(
+ Map.entry(1L, Set.of(XmlUtils.HR_ATTR_URL)),
+ Map.entry(2L, Set.of(XmlUtils.HR_ATTR_DECLARATION)));
+ private final Map<Long, Set<String>> mRequiredHrAttrs =
+ Map.ofEntries(
+ Map.entry(1L, Set.of(XmlUtils.HR_ATTR_URL)),
+ Map.entry(2L, Set.of(XmlUtils.HR_ATTR_DECLARATION)));
+ private final Map<Long, Set<String>> mRecognizedHrEles = Map.ofEntries(Map.entry(1L, Set.of()));
+ private final Map<Long, Set<String>> mRecognizedOdEleNames =
+ Map.ofEntries(
+ Map.entry(1L, Set.of(XmlUtils.OD_NAME_URL)),
+ Map.entry(2L, Set.of(XmlUtils.OD_NAME_DECLARATION)));
+ private final Map<Long, Set<String>> mRequiredOdEleNames =
+ Map.ofEntries(
+ Map.entry(1L, Set.of(XmlUtils.OD_NAME_URL)),
+ Map.entry(2L, Set.of(XmlUtils.OD_NAME_DECLARATION)));
/** Creates a {@link SystemAppSafetyLabel} from the human-readable DOM element. */
- @Override
- public SystemAppSafetyLabel createFromHrElements(List<Element> elements)
+ public SystemAppSafetyLabel createFromHrElement(Element systemAppSafetyLabelEle, long version)
throws MalformedXmlException {
- Element systemAppSafetyLabelEle = XmlUtils.getSingleElement(elements);
if (systemAppSafetyLabelEle == null) {
- AslgenUtil.logI("No SystemAppSafetyLabel found in hr format.");
return null;
}
+ XmlUtils.throwIfExtraneousAttributes(
+ systemAppSafetyLabelEle,
+ XmlUtils.getMostRecentVersion(mRecognizedHrAttrs, version));
+ XmlUtils.throwIfExtraneousChildrenHr(
+ systemAppSafetyLabelEle, XmlUtils.getMostRecentVersion(mRecognizedHrEles, version));
+ String url =
+ XmlUtils.getStringAttr(
+ systemAppSafetyLabelEle,
+ XmlUtils.HR_ATTR_URL,
+ XmlUtils.getMostRecentVersion(mRequiredHrAttrs, version));
Boolean declaration =
- XmlUtils.getBoolAttr(systemAppSafetyLabelEle, XmlUtils.HR_ATTR_DECLARATION, true);
- return new SystemAppSafetyLabel(declaration);
+ XmlUtils.getBoolAttr(
+ systemAppSafetyLabelEle,
+ XmlUtils.HR_ATTR_DECLARATION,
+ XmlUtils.getMostRecentVersion(mRequiredHrAttrs, version));
+ return new SystemAppSafetyLabel(url, declaration);
}
/** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
- @Override
- public SystemAppSafetyLabel createFromOdElements(List<Element> elements)
+ public SystemAppSafetyLabel createFromOdElement(Element systemAppSafetyLabelEle, long version)
throws MalformedXmlException {
- Element systemAppSafetyLabelEle = XmlUtils.getSingleElement(elements);
if (systemAppSafetyLabelEle == null) {
- AslgenUtil.logI("No SystemAppSafetyLabel found in od format.");
return null;
}
+ XmlUtils.throwIfExtraneousChildrenOd(
+ systemAppSafetyLabelEle,
+ XmlUtils.getMostRecentVersion(mRecognizedOdEleNames, version));
+ String url =
+ XmlUtils.getOdStringEle(
+ systemAppSafetyLabelEle,
+ XmlUtils.OD_NAME_URL,
+ XmlUtils.getMostRecentVersion(mRequiredOdEleNames, version));
Boolean declaration =
- XmlUtils.getOdBoolEle(systemAppSafetyLabelEle, XmlUtils.OD_NAME_DECLARATION, true);
- return new SystemAppSafetyLabel(declaration);
+ XmlUtils.getOdBoolEle(
+ systemAppSafetyLabelEle,
+ XmlUtils.OD_NAME_DECLARATION,
+ XmlUtils.getMostRecentVersion(mRequiredOdEleNames, version));
+ return new SystemAppSafetyLabel(url, declaration);
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java
index d74f3f062513..151cdb1e2f51 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java
@@ -21,8 +21,6 @@ import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import java.util.List;
-
/** ThirdPartyVerification representation. */
public class ThirdPartyVerification implements AslMarshallable {
@@ -33,19 +31,17 @@ public class ThirdPartyVerification implements AslMarshallable {
}
/** Creates an on-device DOM element from the {@link ThirdPartyVerification}. */
- @Override
- public List<Element> toOdDomElements(Document doc) {
+ public Element toOdDomElement(Document doc) {
Element ele =
XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_THIRD_PARTY_VERIFICATION);
ele.appendChild(XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_URL, mUrl));
- return XmlUtils.listOf(ele);
+ return ele;
}
/** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
- @Override
- public List<Element> toHrDomElements(Document doc) {
+ public Element toHrDomElement(Document doc) {
Element ele = doc.createElement(XmlUtils.HR_TAG_THIRD_PARTY_VERIFICATION);
ele.setAttribute(XmlUtils.HR_ATTR_URL, mUrl);
- return XmlUtils.listOf(ele);
+ return ele;
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java
index 197e7aa77743..f229ad6c861f 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java
@@ -22,16 +22,11 @@ import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Element;
-import java.util.List;
-
public class ThirdPartyVerificationFactory
implements AslMarshallableFactory<ThirdPartyVerification> {
/** Creates a {@link ThirdPartyVerification} from the human-readable DOM element. */
- @Override
- public ThirdPartyVerification createFromHrElements(List<Element> elements)
- throws MalformedXmlException {
- Element ele = XmlUtils.getSingleElement(elements);
+ public ThirdPartyVerification createFromHrElement(Element ele) throws MalformedXmlException {
if (ele == null) {
AslgenUtil.logI("No ThirdPartyVerification found in hr format.");
return null;
@@ -42,10 +37,7 @@ public class ThirdPartyVerificationFactory
}
/** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
- @Override
- public ThirdPartyVerification createFromOdElements(List<Element> elements)
- throws MalformedXmlException {
- Element ele = XmlUtils.getSingleElement(elements);
+ public ThirdPartyVerification createFromOdElement(Element ele) throws MalformedXmlException {
if (ele == null) {
AslgenUtil.logI("No ThirdPartyVerification found in od format.");
return null;
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java
index 9f789f0b9c1c..f24e6bf58efb 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java
@@ -21,39 +21,39 @@ import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import java.util.List;
-
/** TransparencyInfo representation containing {@link AppInfo} */
public class TransparencyInfo implements AslMarshallable {
+
+ private final DeveloperInfo mDeveloperInfo;
private final AppInfo mAppInfo;
- public TransparencyInfo(AppInfo appInfo) {
+ public TransparencyInfo(DeveloperInfo developerInfo, AppInfo appInfo) {
+ this.mDeveloperInfo = developerInfo;
this.mAppInfo = appInfo;
}
- /** Gets the {@link AppInfo} of the {@link TransparencyInfo}. */
- public AppInfo getAppInfo() {
- return mAppInfo;
- }
-
/** Creates an on-device DOM element from the {@link TransparencyInfo}. */
- @Override
- public List<Element> toOdDomElements(Document doc) {
+ public Element toOdDomElement(Document doc) {
Element transparencyInfoEle =
XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_TRANSPARENCY_INFO);
+ if (mDeveloperInfo != null) {
+ transparencyInfoEle.appendChild(mDeveloperInfo.toOdDomElement(doc));
+ }
if (mAppInfo != null) {
- XmlUtils.appendChildren(transparencyInfoEle, mAppInfo.toOdDomElements(doc));
+ transparencyInfoEle.appendChild(mAppInfo.toOdDomElement(doc));
}
- return XmlUtils.listOf(transparencyInfoEle);
+ return transparencyInfoEle;
}
/** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
- @Override
- public List<Element> toHrDomElements(Document doc) {
+ public Element toHrDomElement(Document doc) {
Element transparencyInfoEle = doc.createElement(XmlUtils.HR_TAG_TRANSPARENCY_INFO);
+ if (mDeveloperInfo != null) {
+ transparencyInfoEle.appendChild(mDeveloperInfo.toHrDomElement(doc));
+ }
if (mAppInfo != null) {
- XmlUtils.appendChildren(transparencyInfoEle, mAppInfo.toHrDomElements(doc));
+ transparencyInfoEle.appendChild(mAppInfo.toHrDomElement(doc));
}
- return XmlUtils.listOf(transparencyInfoEle);
+ return transparencyInfoEle;
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java
index 40f2872e4380..9e98941e0d6d 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java
@@ -16,47 +16,84 @@
package com.android.asllib.marshallable;
-import com.android.asllib.util.AslgenUtil;
import com.android.asllib.util.MalformedXmlException;
import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Element;
-import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class TransparencyInfoFactory implements AslMarshallableFactory<TransparencyInfo> {
+ private final Map<Long, Set<String>> mRecognizedHrAttrs =
+ Map.ofEntries(Map.entry(1L, Set.of()));
+ private final Map<Long, Set<String>> mRequiredHrAttrs = Map.ofEntries(Map.entry(1L, Set.of()));
+ private final Map<Long, Set<String>> mRecognizedHrEles =
+ Map.ofEntries(
+ Map.entry(1L, Set.of(XmlUtils.HR_TAG_DEVELOPER_INFO, XmlUtils.HR_TAG_APP_INFO)),
+ Map.entry(2L, Set.of(XmlUtils.HR_TAG_APP_INFO)));
+ private final Map<Long, Set<String>> mRequiredHrEles =
+ Map.ofEntries(Map.entry(1L, Set.of()), Map.entry(2L, Set.of(XmlUtils.HR_TAG_APP_INFO)));
+ private final Map<Long, Set<String>> mRecognizedOdEleNames =
+ Map.ofEntries(
+ Map.entry(
+ 1L, Set.of(XmlUtils.OD_NAME_DEVELOPER_INFO, XmlUtils.OD_NAME_APP_INFO)),
+ Map.entry(2L, Set.of(XmlUtils.OD_NAME_APP_INFO)));
+ private final Map<Long, Set<String>> mRequiredOdEles =
+ Map.ofEntries(
+ Map.entry(1L, Set.of()), Map.entry(2L, Set.of(XmlUtils.OD_NAME_APP_INFO)));
/** Creates a {@link TransparencyInfo} from the human-readable DOM element. */
- @Override
- public TransparencyInfo createFromHrElements(List<Element> elements)
+ public TransparencyInfo createFromHrElement(Element transparencyInfoEle, long version)
throws MalformedXmlException {
- Element transparencyInfoEle = XmlUtils.getSingleElement(elements);
if (transparencyInfoEle == null) {
- AslgenUtil.logI("No TransparencyInfo found in hr format.");
return null;
}
+ XmlUtils.throwIfExtraneousAttributes(
+ transparencyInfoEle, XmlUtils.getMostRecentVersion(mRecognizedHrAttrs, version));
+ XmlUtils.throwIfExtraneousChildrenHr(
+ transparencyInfoEle, XmlUtils.getMostRecentVersion(mRecognizedHrEles, version));
+ Element developerInfoEle =
+ XmlUtils.getSingleChildElement(
+ transparencyInfoEle,
+ XmlUtils.HR_TAG_DEVELOPER_INFO,
+ XmlUtils.getMostRecentVersion(mRequiredHrEles, version));
+ DeveloperInfo developerInfo =
+ new DeveloperInfoFactory().createFromHrElement(developerInfoEle);
Element appInfoEle =
- XmlUtils.getSingleChildElement(transparencyInfoEle, XmlUtils.HR_TAG_APP_INFO, true);
- AppInfo appInfo = new AppInfoFactory().createFromHrElements(XmlUtils.listOf(appInfoEle));
+ XmlUtils.getSingleChildElement(
+ transparencyInfoEle,
+ XmlUtils.HR_TAG_APP_INFO,
+ XmlUtils.getMostRecentVersion(mRequiredHrEles, version));
+ AppInfo appInfo = new AppInfoFactory().createFromHrElement(appInfoEle, version);
- return new TransparencyInfo(appInfo);
+ return new TransparencyInfo(developerInfo, appInfo);
}
/** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
- @Override
- public TransparencyInfo createFromOdElements(List<Element> elements)
+ public TransparencyInfo createFromOdElement(Element transparencyInfoEle, long version)
throws MalformedXmlException {
- Element transparencyInfoEle = XmlUtils.getSingleElement(elements);
if (transparencyInfoEle == null) {
- AslgenUtil.logI("No TransparencyInfo found in od format.");
return null;
}
+ XmlUtils.throwIfExtraneousChildrenOd(
+ transparencyInfoEle, XmlUtils.getMostRecentVersion(mRecognizedOdEleNames, version));
+ Element developerInfoEle =
+ XmlUtils.getOdPbundleWithName(
+ transparencyInfoEle,
+ XmlUtils.OD_NAME_DEVELOPER_INFO,
+ XmlUtils.getMostRecentVersion(mRequiredOdEles, version));
+ DeveloperInfo developerInfo =
+ new DeveloperInfoFactory().createFromOdElement(developerInfoEle);
Element appInfoEle =
- XmlUtils.getOdPbundleWithName(transparencyInfoEle, XmlUtils.OD_NAME_APP_INFO, true);
- AppInfo appInfo = new AppInfoFactory().createFromOdElements(XmlUtils.listOf(appInfoEle));
+ XmlUtils.getOdPbundleWithName(
+ transparencyInfoEle,
+ XmlUtils.OD_NAME_APP_INFO,
+ XmlUtils.getMostRecentVersion(mRequiredOdEles, version));
+ AppInfo appInfo = new AppInfoFactory().createFromOdElement(appInfoEle, version);
- return new TransparencyInfo(appInfo);
+ return new TransparencyInfo(developerInfo, appInfo);
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java
index 2c1517bdf8ab..52c4390036f3 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java
@@ -25,6 +25,8 @@ import org.w3c.dom.NodeList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
public class XmlUtils {
@@ -70,6 +72,8 @@ public class XmlUtils {
public static final String HR_ATTR_ADS_FINGERPRINTING = "adsFingerprinting";
public static final String HR_ATTR_SECURITY_FINGERPRINTING = "securityFingerprinting";
public static final String HR_ATTR_PRIVACY_POLICY = "privacyPolicy";
+ public static final String HR_ATTR_DEVELOPER_ID = "developerId";
+ public static final String HR_ATTR_APPLICATION_ID = "applicationId";
public static final String HR_ATTR_SECURITY_ENDPOINTS = "securityEndpoints";
public static final String HR_TAG_FIRST_PARTY_ENDPOINTS = "first-party-endpoints";
public static final String HR_TAG_SERVICE_PROVIDER_ENDPOINTS = "service-provider-endpoints";
@@ -102,10 +106,12 @@ public class XmlUtils {
public static final String OD_NAME_CONTAINS_ADS = "contains_ads";
public static final String OD_NAME_OBEY_APS = "obey_aps";
public static final String OD_NAME_APS_COMPLIANT = "aps_compliant";
+ public static final String OD_NAME_DEVELOPER_ID = "developer_id";
+ public static final String OD_NAME_APPLICATION_ID = "application_id";
public static final String OD_NAME_ADS_FINGERPRINTING = "ads_fingerprinting";
public static final String OD_NAME_SECURITY_FINGERPRINTING = "security_fingerprinting";
public static final String OD_NAME_PRIVACY_POLICY = "privacy_policy";
- public static final String OD_NAME_SECURITY_ENDPOINT = "security_endpoints";
+ public static final String OD_NAME_SECURITY_ENDPOINTS = "security_endpoints";
public static final String OD_NAME_FIRST_PARTY_ENDPOINTS = "first_party_endpoints";
public static final String OD_NAME_SERVICE_PROVIDER_ENDPOINTS = "service_provider_endpoints";
public static final String OD_NAME_CATEGORY = "category";
@@ -140,6 +146,15 @@ public class XmlUtils {
/**
* Gets the single {@link Element} within {@param parentEle} and having the {@param tagName}.
*/
+ public static Element getSingleChildElement(
+ Node parentEle, String tagName, Set<String> requiredStrings)
+ throws MalformedXmlException {
+ return getSingleChildElement(parentEle, tagName, requiredStrings.contains(tagName));
+ }
+
+ /**
+ * Gets the single {@link Element} within {@param parentEle} and having the {@param tagName}.
+ */
public static Element getSingleChildElement(Node parentEle, String tagName, boolean required)
throws MalformedXmlException {
String parentTagNameForErrorMsg =
@@ -287,19 +302,36 @@ public class XmlUtils {
}
/** Gets a pipeline-split attribute. */
+ public static List<String> getPipelineSplitAttr(
+ Element ele, String attrName, Set<String> requiredNames) throws MalformedXmlException {
+ return getPipelineSplitAttr(ele, attrName, requiredNames.contains(attrName));
+ }
+
+ /** Gets a pipeline-split attribute. */
public static List<String> getPipelineSplitAttr(Element ele, String attrName, boolean required)
throws MalformedXmlException {
List<String> list =
Arrays.stream(ele.getAttribute(attrName).split("\\|")).collect(Collectors.toList());
- if ((list.isEmpty() || list.get(0).isEmpty()) && required) {
- throw new MalformedXmlException(
- String.format(
- "Delimited string %s was required but missing, in %s.",
- attrName, ele.getTagName()));
+ if ((list.isEmpty() || list.get(0).isEmpty())) {
+ if (required) {
+ throw new MalformedXmlException(
+ String.format(
+ "Delimited string %s was required but missing, in %s.",
+ attrName, ele.getTagName()));
+ }
+ return null;
}
return list;
}
+ /**
+ * Gets the single {@link Element} within {@param parentEle} and having the {@param tagName}.
+ */
+ public static Boolean getBoolAttr(Element ele, String attrName, Set<String> requiredStrings)
+ throws MalformedXmlException {
+ return getBoolAttr(ele, attrName, requiredStrings.contains(attrName));
+ }
+
/** Gets a Boolean attribute. */
public static Boolean getBoolAttr(Element ele, String attrName, boolean required)
throws MalformedXmlException {
@@ -314,6 +346,12 @@ public class XmlUtils {
}
/** Gets a Boolean attribute. */
+ public static Boolean getOdBoolEle(Element ele, String nameName, Set<String> requiredNames)
+ throws MalformedXmlException {
+ return getOdBoolEle(ele, nameName, requiredNames.contains(nameName));
+ }
+
+ /** Gets a Boolean attribute. */
public static Boolean getOdBoolEle(Element ele, String nameName, boolean required)
throws MalformedXmlException {
List<Element> boolEles =
@@ -376,6 +414,12 @@ public class XmlUtils {
}
/** Gets an on-device String attribute. */
+ public static String getOdStringEle(Element ele, String nameName, Set<String> requiredNames)
+ throws MalformedXmlException {
+ return getOdStringEle(ele, nameName, requiredNames.contains(nameName));
+ }
+
+ /** Gets an on-device String attribute. */
public static String getOdStringEle(Element ele, String nameName, boolean required)
throws MalformedXmlException {
List<Element> eles =
@@ -404,6 +448,13 @@ public class XmlUtils {
}
/** Gets a OD Pbundle Element attribute with the specified name. */
+ public static Element getOdPbundleWithName(
+ Element ele, String nameName, Set<String> requiredStrings)
+ throws MalformedXmlException {
+ return getOdPbundleWithName(ele, nameName, requiredStrings.contains(nameName));
+ }
+
+ /** Gets a OD Pbundle Element attribute with the specified name. */
public static Element getOdPbundleWithName(Element ele, String nameName, boolean required)
throws MalformedXmlException {
List<Element> eles =
@@ -425,6 +476,14 @@ public class XmlUtils {
return eles.get(0);
}
+ /**
+ * Gets the single {@link Element} within {@param parentEle} and having the {@param tagName}.
+ */
+ public static String getStringAttr(Element ele, String attrName, Set<String> requiredStrings)
+ throws MalformedXmlException {
+ return getStringAttr(ele, attrName, requiredStrings.contains(attrName));
+ }
+
/** Gets a required String attribute. */
public static String getStringAttr(Element ele, String attrName) throws MalformedXmlException {
return getStringAttr(ele, attrName, true);
@@ -476,6 +535,13 @@ public class XmlUtils {
/** Gets human-readable style String array. */
public static List<String> getHrItemsAsStrings(
+ Element parent, String elementName, Set<String> requiredNames)
+ throws MalformedXmlException {
+ return getHrItemsAsStrings(parent, elementName, requiredNames.contains(elementName));
+ }
+
+ /** Gets human-readable style String array. */
+ public static List<String> getHrItemsAsStrings(
Element parent, String elementName, boolean required) throws MalformedXmlException {
List<Element> arrayEles = XmlUtils.getChildrenByTagName(parent, elementName);
@@ -501,6 +567,12 @@ public class XmlUtils {
}
/** Gets on-device style String array. */
+ public static List<String> getOdStringArray(
+ Element ele, String nameName, Set<String> requiredNames) throws MalformedXmlException {
+ return getOdStringArray(ele, nameName, requiredNames.contains(nameName));
+ }
+
+ /** Gets on-device style String array. */
public static List<String> getOdStringArray(Element ele, String nameName, boolean required)
throws MalformedXmlException {
List<Element> arrayEles =
@@ -530,6 +602,73 @@ public class XmlUtils {
return strs;
}
+ /** Throws if extraneous child elements detected */
+ public static void throwIfExtraneousChildrenHr(Element ele, Set<String> expectedChildNames)
+ throws MalformedXmlException {
+ var childEles = XmlUtils.asElementList(ele.getChildNodes());
+ List<Element> extraneousEles =
+ childEles.stream()
+ .filter(e -> !expectedChildNames.contains(e.getTagName()))
+ .collect(Collectors.toList());
+ if (!extraneousEles.isEmpty()) {
+ throw new MalformedXmlException(
+ String.format(
+ "Unexpected element(s) %s in %s.",
+ extraneousEles.stream()
+ .map(Element::getTagName)
+ .collect(Collectors.joining(",")),
+ ele.getTagName()));
+ }
+ }
+
+ /** Throws if extraneous child elements detected */
+ public static void throwIfExtraneousChildrenOd(Element ele, Set<String> expectedChildNames)
+ throws MalformedXmlException {
+ var allChildElements = XmlUtils.asElementList(ele.getChildNodes());
+ List<Element> extraneousEles =
+ allChildElements.stream()
+ .filter(
+ e ->
+ !e.getAttribute(XmlUtils.OD_ATTR_NAME).isEmpty()
+ && !expectedChildNames.contains(
+ e.getAttribute(XmlUtils.OD_ATTR_NAME)))
+ .collect(Collectors.toList());
+ if (!extraneousEles.isEmpty()) {
+ throw new MalformedXmlException(
+ String.format(
+ "Unexpected element(s) in %s: %s",
+ ele.getTagName(),
+ extraneousEles.stream()
+ .map(
+ e ->
+ String.format(
+ "%s name=%s",
+ e.getTagName(),
+ e.getAttribute(XmlUtils.OD_ATTR_NAME)))
+ .collect(Collectors.joining(","))));
+ }
+ }
+
+ /** Throws if extraneous attributes detected */
+ public static void throwIfExtraneousAttributes(Element ele, Set<String> expectedAttrNames)
+ throws MalformedXmlException {
+ var attrs = ele.getAttributes();
+ List<String> attrNames = new ArrayList<>();
+ for (int i = 0; i < attrs.getLength(); i++) {
+ attrNames.add(attrs.item(i).getNodeName());
+ }
+ List<String> extraneousAttrs =
+ attrNames.stream()
+ .filter(s -> !expectedAttrNames.contains(s))
+ .collect(Collectors.toList());
+ if (!extraneousAttrs.isEmpty()) {
+ throw new MalformedXmlException(
+ String.format(
+ "Unexpected attr(s) %s in %s.",
+ String.join(",", extraneousAttrs), ele.getTagName()));
+ }
+ }
+
/**
* Utility method for making a List from one element, to support easier refactoring if needed.
* For example, List.of() doesn't support null elements.
@@ -537,4 +676,26 @@ public class XmlUtils {
public static List<Element> listOf(Element e) {
return Arrays.asList(e);
}
+
+ /**
+ * Gets the most recent version of fields in the mapping. This way when a new version is
+ * released, we only need to update the mappings that were modified. The rest will fall back to
+ * the most recent previous version.
+ */
+ public static Set<String> getMostRecentVersion(
+ Map<Long, Set<String>> versionToFieldsMapping, long version)
+ throws MalformedXmlException {
+ long bestVersion = 0;
+ Set<String> bestSet = null;
+ for (Map.Entry<Long, Set<String>> entry : versionToFieldsMapping.entrySet()) {
+ if (entry.getKey() > bestVersion && entry.getKey() <= version) {
+ bestVersion = entry.getKey();
+ bestSet = entry.getValue();
+ }
+ }
+ if (bestSet == null) {
+ throw new MalformedXmlException("Unexpected version: " + version);
+ }
+ return bestSet;
+ }
}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java
index 5d1d45a9a29b..262f76d52c90 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java
@@ -41,6 +41,18 @@ public class AslgenTests {
/** Logic for setting up tests (empty if not yet needed). */
public static void main(String[] params) throws Exception {}
+ @Test
+ public void testValidOd() throws Exception {
+ System.out.println("start testing valid od.");
+ Path odPath = Paths.get(VALID_MAPPINGS_PATH, "general-v1", OD_XML_FILENAME);
+ InputStream odStream = getClass().getClassLoader().getResourceAsStream(odPath.toString());
+ String odContents =
+ TestUtils.getFormattedXml(
+ new String(odStream.readAllBytes(), StandardCharsets.UTF_8), false);
+ AndroidSafetyLabel unusedAsl =
+ AslConverter.readFromString(odContents, AslConverter.Format.ON_DEVICE);
+ }
+
/** Tests valid mappings between HR and OD. */
@Test
public void testValidMappings() throws Exception {
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java
index 61a78232801c..283ccbc44791 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java
@@ -16,12 +16,18 @@
package com.android.asllib.marshallable;
+import static org.junit.Assert.assertThrows;
+
import com.android.asllib.testutils.TestUtils;
+import com.android.asllib.util.MalformedXmlException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.w3c.dom.Element;
+
+import java.nio.file.Paths;
@RunWith(JUnit4.class)
public class AndroidSafetyLabelTest {
@@ -66,47 +72,49 @@ public class AndroidSafetyLabelTest {
testOdToHrAndroidSafetyLabel(WITH_SAFETY_LABELS_FILE_NAME);
}
- /** Test for android safety label with system app safety label. */
- @Test
- public void testAndroidSafetyLabelWithSystemAppSafetyLabel() throws Exception {
- System.out.println("starting testAndroidSafetyLabelWithSystemAppSafetyLabel.");
- testHrToOdAndroidSafetyLabel(WITH_SYSTEM_APP_SAFETY_LABEL_FILE_NAME);
- testOdToHrAndroidSafetyLabel(WITH_SYSTEM_APP_SAFETY_LABEL_FILE_NAME);
- }
-
- /** Test for android safety label with transparency info. */
- @Test
- public void testAndroidSafetyLabelWithTransparencyInfo() throws Exception {
- System.out.println("starting testAndroidSafetyLabelWithTransparencyInfo.");
- testHrToOdAndroidSafetyLabel(WITH_TRANSPARENCY_INFO_FILE_NAME);
- testOdToHrAndroidSafetyLabel(WITH_TRANSPARENCY_INFO_FILE_NAME);
- }
-
private void hrToOdExpectException(String fileName) {
- TestUtils.hrToOdExpectException(
- new AndroidSafetyLabelFactory(), ANDROID_SAFETY_LABEL_HR_PATH, fileName);
+ assertThrows(
+ MalformedXmlException.class,
+ () -> {
+ new AndroidSafetyLabelFactory()
+ .createFromHrElement(
+ TestUtils.getElementFromResource(
+ Paths.get(ANDROID_SAFETY_LABEL_HR_PATH, fileName)));
+ });
}
private void odToHrExpectException(String fileName) {
- TestUtils.odToHrExpectException(
- new AndroidSafetyLabelFactory(), ANDROID_SAFETY_LABEL_OD_PATH, fileName);
+ assertThrows(
+ MalformedXmlException.class,
+ () -> {
+ new AndroidSafetyLabelFactory()
+ .createFromOdElement(
+ TestUtils.getElementFromResource(
+ Paths.get(ANDROID_SAFETY_LABEL_OD_PATH, fileName)));
+ });
}
private void testHrToOdAndroidSafetyLabel(String fileName) throws Exception {
- TestUtils.testHrToOd(
- TestUtils.document(),
- new AndroidSafetyLabelFactory(),
- ANDROID_SAFETY_LABEL_HR_PATH,
- ANDROID_SAFETY_LABEL_OD_PATH,
- fileName);
+ var doc = TestUtils.document();
+ AndroidSafetyLabel asl =
+ new AndroidSafetyLabelFactory()
+ .createFromHrElement(
+ TestUtils.getElementFromResource(
+ Paths.get(ANDROID_SAFETY_LABEL_HR_PATH, fileName)));
+ Element aslEle = asl.toOdDomElement(doc);
+ doc.appendChild(aslEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(ANDROID_SAFETY_LABEL_OD_PATH, fileName));
}
private void testOdToHrAndroidSafetyLabel(String fileName) throws Exception {
- TestUtils.testOdToHr(
- TestUtils.document(),
- new AndroidSafetyLabelFactory(),
- ANDROID_SAFETY_LABEL_OD_PATH,
- ANDROID_SAFETY_LABEL_HR_PATH,
- fileName);
+ var doc = TestUtils.document();
+ AndroidSafetyLabel asl =
+ new AndroidSafetyLabelFactory()
+ .createFromOdElement(
+ TestUtils.getElementFromResource(
+ Paths.get(ANDROID_SAFETY_LABEL_OD_PATH, fileName)));
+ Element aslEle = asl.toHrDomElement(doc);
+ doc.appendChild(aslEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(ANDROID_SAFETY_LABEL_HR_PATH, fileName));
}
}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java
index d823c482adfe..7806061f00bb 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java
@@ -26,12 +26,14 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.w3c.dom.Element;
import java.nio.file.Paths;
import java.util.List;
@RunWith(JUnit4.class)
public class AppInfoTest {
+ private static final long DEFAULT_VERSION = 2L;
private static final String APP_INFO_HR_PATH = "com/android/asllib/appinfo/hr";
private static final String APP_INFO_OD_PATH = "com/android/asllib/appinfo/od";
public static final List<String> REQUIRED_FIELD_NAMES =
@@ -45,7 +47,24 @@ public class AppInfoTest {
public static final List<String> OPTIONAL_FIELD_NAMES = List.of();
public static final List<String> OPTIONAL_FIELD_NAMES_OD = List.of();
+ public static final List<String> REQUIRED_FIELD_NAMES_OD_V1 =
+ List.of(
+ "title",
+ "description",
+ "contains_ads",
+ "obey_aps",
+ "ads_fingerprinting",
+ "security_fingerprinting",
+ "privacy_policy",
+ "security_endpoints",
+ "first_party_endpoints",
+ "service_provider_endpoints",
+ "category");
+ public static final List<String> OPTIONAL_FIELD_NAMES_OD_V1 = List.of("website", "email");
+
private static final String ALL_FIELDS_VALID_FILE_NAME = "all-fields-valid.xml";
+ private static final String ALL_FIELDS_VALID_V1_FILE_NAME = "all-fields-valid-v1.xml";
+ public static final String UNRECOGNIZED_V1_FILE_NAME = "unrecognized-v1.xml";
/** Logic for setting up tests (empty if not yet needed). */
public static void main(String[] params) throws Exception {}
@@ -63,6 +82,61 @@ public class AppInfoTest {
testOdToHrAppInfo(ALL_FIELDS_VALID_FILE_NAME);
}
+ /** Test for all fields valid v1. */
+ @Test
+ public void testAllFieldsValidV1() throws Exception {
+ System.out.println("starting testAllFieldsValidV1.");
+ new AppInfoFactory()
+ .createFromOdElement(
+ TestUtils.getElementFromResource(
+ Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_V1_FILE_NAME)),
+ 1L);
+ }
+
+ /** Test for unrecognized field v1. */
+ @Test
+ public void testUnrecognizedFieldV1() throws Exception {
+ System.out.println("starting testUnrecognizedFieldV1.");
+ assertThrows(
+ MalformedXmlException.class,
+ () ->
+ new AppInfoFactory()
+ .createFromOdElement(
+ TestUtils.getElementFromResource(
+ Paths.get(
+ APP_INFO_OD_PATH,
+ UNRECOGNIZED_V1_FILE_NAME)),
+ 1L));
+ }
+
+ /** Tests missing required fields fails, V1. */
+ @Test
+ public void testMissingRequiredFieldsOdV1() throws Exception {
+ for (String reqField : REQUIRED_FIELD_NAMES_OD_V1) {
+ System.out.println("testing missing required field od v1: " + reqField);
+ var appInfoEle =
+ TestUtils.getElementFromResource(
+ Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_V1_FILE_NAME));
+ TestUtils.removeOdChildEleWithName(appInfoEle, reqField);
+ assertThrows(
+ MalformedXmlException.class,
+ () -> new AppInfoFactory().createFromOdElement(appInfoEle, 1L));
+ }
+ }
+
+ /** Tests missing optional fields passes, V1. */
+ @Test
+ public void testMissingOptionalFieldsOdV1() throws Exception {
+ for (String optField : OPTIONAL_FIELD_NAMES_OD_V1) {
+ System.out.println("testing missing optional field od v1: " + optField);
+ var appInfoEle =
+ TestUtils.getElementFromResource(
+ Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_V1_FILE_NAME));
+ TestUtils.removeOdChildEleWithName(appInfoEle, optField);
+ new AppInfoFactory().createFromOdElement(appInfoEle, 1L);
+ }
+ }
+
/** Tests missing required fields fails. */
@Test
public void testMissingRequiredFields() throws Exception {
@@ -70,24 +144,24 @@ public class AppInfoTest {
for (String reqField : REQUIRED_FIELD_NAMES) {
System.out.println("testing missing required field hr: " + reqField);
var appInfoEle =
- TestUtils.getElementsFromResource(
+ TestUtils.getElementFromResource(
Paths.get(APP_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
- appInfoEle.get(0).removeAttribute(reqField);
+ appInfoEle.removeAttribute(reqField);
assertThrows(
MalformedXmlException.class,
- () -> new AppInfoFactory().createFromHrElements(appInfoEle));
+ () -> new AppInfoFactory().createFromHrElement(appInfoEle, DEFAULT_VERSION));
}
for (String reqField : REQUIRED_FIELD_NAMES_OD) {
System.out.println("testing missing required field od: " + reqField);
var appInfoEle =
- TestUtils.getElementsFromResource(
+ TestUtils.getElementFromResource(
Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_FILE_NAME));
- TestUtils.removeOdChildEleWithName(appInfoEle.get(0), reqField);
+ TestUtils.removeOdChildEleWithName(appInfoEle, reqField);
assertThrows(
MalformedXmlException.class,
- () -> new AppInfoFactory().createFromOdElements(appInfoEle));
+ () -> new AppInfoFactory().createFromOdElement(appInfoEle, DEFAULT_VERSION));
}
}
@@ -98,24 +172,24 @@ public class AppInfoTest {
for (String reqChildName : REQUIRED_CHILD_NAMES) {
System.out.println("testing missing required child hr: " + reqChildName);
var appInfoEle =
- TestUtils.getElementsFromResource(
+ TestUtils.getElementFromResource(
Paths.get(APP_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
- var child = XmlUtils.getChildrenByTagName(appInfoEle.get(0), reqChildName).get(0);
- appInfoEle.get(0).removeChild(child);
+ var child = XmlUtils.getChildrenByTagName(appInfoEle, reqChildName).get(0);
+ appInfoEle.removeChild(child);
assertThrows(
MalformedXmlException.class,
- () -> new AppInfoFactory().createFromHrElements(appInfoEle));
+ () -> new AppInfoFactory().createFromHrElement(appInfoEle, DEFAULT_VERSION));
}
for (String reqField : REQUIRED_CHILD_NAMES_OD) {
System.out.println("testing missing required child od: " + reqField);
var appInfoEle =
- TestUtils.getElementsFromResource(
+ TestUtils.getElementFromResource(
Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_FILE_NAME));
- TestUtils.removeOdChildEleWithName(appInfoEle.get(0), reqField);
+ TestUtils.removeOdChildEleWithName(appInfoEle, reqField);
assertThrows(
MalformedXmlException.class,
- () -> new AppInfoFactory().createFromOdElements(appInfoEle));
+ () -> new AppInfoFactory().createFromOdElement(appInfoEle, DEFAULT_VERSION));
}
}
@@ -124,38 +198,51 @@ public class AppInfoTest {
public void testMissingOptionalFields() throws Exception {
for (String optField : OPTIONAL_FIELD_NAMES) {
var ele =
- TestUtils.getElementsFromResource(
+ TestUtils.getElementFromResource(
Paths.get(APP_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
- ele.get(0).removeAttribute(optField);
- AppInfo appInfo = new AppInfoFactory().createFromHrElements(ele);
- appInfo.toOdDomElements(TestUtils.document());
+ ele.removeAttribute(optField);
+ AppInfo appInfo = new AppInfoFactory().createFromHrElement(ele, DEFAULT_VERSION);
+ appInfo.toOdDomElement(TestUtils.document());
}
for (String optField : OPTIONAL_FIELD_NAMES_OD) {
var ele =
- TestUtils.getElementsFromResource(
+ TestUtils.getElementFromResource(
Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_FILE_NAME));
- TestUtils.removeOdChildEleWithName(ele.get(0), optField);
- AppInfo appInfo = new AppInfoFactory().createFromOdElements(ele);
- appInfo.toHrDomElements(TestUtils.document());
+ TestUtils.removeOdChildEleWithName(ele, optField);
+ AppInfo appInfo = new AppInfoFactory().createFromOdElement(ele, DEFAULT_VERSION);
+ appInfo.toHrDomElement(TestUtils.document());
}
}
private void testHrToOdAppInfo(String fileName) throws Exception {
- TestUtils.testHrToOd(
- TestUtils.document(),
- new AppInfoFactory(),
- APP_INFO_HR_PATH,
- APP_INFO_OD_PATH,
- fileName);
+ var doc = TestUtils.document();
+ AppInfo appInfo =
+ new AppInfoFactory()
+ .createFromHrElement(
+ TestUtils.getElementFromResource(
+ Paths.get(APP_INFO_HR_PATH, fileName)),
+ DEFAULT_VERSION);
+ Element appInfoEle = appInfo.toOdDomElement(doc);
+ doc.appendChild(appInfoEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(APP_INFO_OD_PATH, fileName));
}
+
private void testOdToHrAppInfo(String fileName) throws Exception {
- TestUtils.testOdToHr(
- TestUtils.document(),
- new AppInfoFactory(),
- APP_INFO_OD_PATH,
- APP_INFO_HR_PATH,
- fileName);
+ testOdToHrAppInfo(fileName, DEFAULT_VERSION);
+ }
+
+ private void testOdToHrAppInfo(String fileName, long version) throws Exception {
+ var doc = TestUtils.document();
+ AppInfo appInfo =
+ new AppInfoFactory()
+ .createFromOdElement(
+ TestUtils.getElementFromResource(
+ Paths.get(APP_INFO_OD_PATH, fileName)),
+ version);
+ Element appInfoEle = appInfo.toHrDomElement(doc);
+ doc.appendChild(appInfoEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(APP_INFO_HR_PATH, fileName));
}
}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java
index ff4374166dd3..b557fea9572b 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java
@@ -16,15 +16,27 @@
package com.android.asllib.marshallable;
+import static org.junit.Assert.assertThrows;
+
import com.android.asllib.testutils.TestUtils;
+import com.android.asllib.util.MalformedXmlException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+
+import javax.xml.parsers.ParserConfigurationException;
@RunWith(JUnit4.class)
public class DataLabelsTest {
+ private static final long DEFAULT_VERSION = 2L;
+
private static final String DATA_LABELS_HR_PATH = "com/android/asllib/datalabels/hr";
private static final String DATA_LABELS_OD_PATH = "com/android/asllib/datalabels/od";
@@ -297,29 +309,43 @@ public class DataLabelsTest {
odToHrExpectException(PERSONAL_EMPTY_PURPOSE_FILE_NAME);
}
- private void hrToOdExpectException(String fileName) {
- TestUtils.hrToOdExpectException(new DataLabelsFactory(), DATA_LABELS_HR_PATH, fileName);
+ private void hrToOdExpectException(String fileName)
+ throws ParserConfigurationException, IOException, SAXException {
+ var ele = TestUtils.getElementFromResource(Paths.get(DATA_LABELS_HR_PATH, fileName));
+ assertThrows(
+ MalformedXmlException.class,
+ () -> new DataLabelsFactory().createFromHrElement(ele));
}
- private void odToHrExpectException(String fileName) {
- TestUtils.odToHrExpectException(new DataLabelsFactory(), DATA_LABELS_OD_PATH, fileName);
+ private void odToHrExpectException(String fileName)
+ throws ParserConfigurationException, IOException, SAXException {
+ var ele = TestUtils.getElementFromResource(Paths.get(DATA_LABELS_OD_PATH, fileName));
+ assertThrows(
+ MalformedXmlException.class,
+ () -> new DataLabelsFactory().createFromOdElement(ele));
}
private void testHrToOdDataLabels(String fileName) throws Exception {
- TestUtils.testHrToOd(
- TestUtils.document(),
- new DataLabelsFactory(),
- DATA_LABELS_HR_PATH,
- DATA_LABELS_OD_PATH,
- fileName);
+ var doc = TestUtils.document();
+ DataLabels dataLabels =
+ new DataLabelsFactory()
+ .createFromHrElement(
+ TestUtils.getElementFromResource(
+ Paths.get(DATA_LABELS_HR_PATH, fileName)));
+ Element resultingEle = dataLabels.toOdDomElement(doc);
+ doc.appendChild(resultingEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(DATA_LABELS_OD_PATH, fileName));
}
private void testOdToHrDataLabels(String fileName) throws Exception {
- TestUtils.testOdToHr(
- TestUtils.document(),
- new DataLabelsFactory(),
- DATA_LABELS_OD_PATH,
- DATA_LABELS_HR_PATH,
- fileName);
+ var doc = TestUtils.document();
+ DataLabels dataLabels =
+ new DataLabelsFactory()
+ .createFromOdElement(
+ TestUtils.getElementFromResource(
+ Paths.get(DATA_LABELS_OD_PATH, fileName)));
+ Element resultingEle = dataLabels.toHrDomElement(doc);
+ doc.appendChild(resultingEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(DATA_LABELS_HR_PATH, fileName));
}
}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java
index 19d1626f7054..7cd510f0ddfc 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java
@@ -16,15 +16,27 @@
package com.android.asllib.marshallable;
+import static org.junit.Assert.assertThrows;
+
import com.android.asllib.testutils.TestUtils;
+import com.android.asllib.util.MalformedXmlException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+
+import javax.xml.parsers.ParserConfigurationException;
@RunWith(JUnit4.class)
public class SafetyLabelsTest {
+ private static final long DEFAULT_VERSION = 2L;
+
private static final String SAFETY_LABELS_HR_PATH = "com/android/asllib/safetylabels/hr";
private static final String SAFETY_LABELS_OD_PATH = "com/android/asllib/safetylabels/od";
@@ -52,29 +64,51 @@ public class SafetyLabelsTest {
testOdToHrSafetyLabels(WITH_DATA_LABELS_FILE_NAME);
}
- private void hrToOdExpectException(String fileName) {
- TestUtils.hrToOdExpectException(new SafetyLabelsFactory(), SAFETY_LABELS_HR_PATH, fileName);
+ private void hrToOdExpectException(String fileName)
+ throws ParserConfigurationException, IOException, SAXException {
+ var safetyLabelsEle =
+ TestUtils.getElementFromResource(Paths.get(SAFETY_LABELS_HR_PATH, fileName));
+ assertThrows(
+ MalformedXmlException.class,
+ () ->
+ new SafetyLabelsFactory()
+ .createFromHrElement(safetyLabelsEle, DEFAULT_VERSION));
}
- private void odToHrExpectException(String fileName) {
- TestUtils.odToHrExpectException(new SafetyLabelsFactory(), SAFETY_LABELS_OD_PATH, fileName);
+ private void odToHrExpectException(String fileName)
+ throws ParserConfigurationException, IOException, SAXException {
+ var safetyLabelsEle =
+ TestUtils.getElementFromResource(Paths.get(SAFETY_LABELS_OD_PATH, fileName));
+ assertThrows(
+ MalformedXmlException.class,
+ () ->
+ new SafetyLabelsFactory()
+ .createFromOdElement(safetyLabelsEle, DEFAULT_VERSION));
}
private void testHrToOdSafetyLabels(String fileName) throws Exception {
- TestUtils.testHrToOd(
- TestUtils.document(),
- new SafetyLabelsFactory(),
- SAFETY_LABELS_HR_PATH,
- SAFETY_LABELS_OD_PATH,
- fileName);
+ var doc = TestUtils.document();
+ SafetyLabels safetyLabels =
+ new SafetyLabelsFactory()
+ .createFromHrElement(
+ TestUtils.getElementFromResource(
+ Paths.get(SAFETY_LABELS_HR_PATH, fileName)),
+ DEFAULT_VERSION);
+ Element appInfoEle = safetyLabels.toOdDomElement(doc);
+ doc.appendChild(appInfoEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(SAFETY_LABELS_OD_PATH, fileName));
}
private void testOdToHrSafetyLabels(String fileName) throws Exception {
- TestUtils.testOdToHr(
- TestUtils.document(),
- new SafetyLabelsFactory(),
- SAFETY_LABELS_OD_PATH,
- SAFETY_LABELS_HR_PATH,
- fileName);
+ var doc = TestUtils.document();
+ SafetyLabels safetyLabels =
+ new SafetyLabelsFactory()
+ .createFromOdElement(
+ TestUtils.getElementFromResource(
+ Paths.get(SAFETY_LABELS_OD_PATH, fileName)),
+ DEFAULT_VERSION);
+ Element appInfoEle = safetyLabels.toHrDomElement(doc);
+ doc.appendChild(appInfoEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(SAFETY_LABELS_HR_PATH, fileName));
}
}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java
index 87d3e4499f5c..9dcc6529969e 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java
@@ -16,15 +16,27 @@
package com.android.asllib.marshallable;
+import static org.junit.Assert.assertThrows;
+
import com.android.asllib.testutils.TestUtils;
+import com.android.asllib.util.MalformedXmlException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+
+import javax.xml.parsers.ParserConfigurationException;
@RunWith(JUnit4.class)
public class SystemAppSafetyLabelTest {
+ private static final long DEFAULT_VERSION = 2L;
+
private static final String SYSTEM_APP_SAFETY_LABEL_HR_PATH =
"com/android/asllib/systemappsafetylabel/hr";
private static final String SYSTEM_APP_SAFETY_LABEL_OD_PATH =
@@ -57,31 +69,49 @@ public class SystemAppSafetyLabelTest {
odToHrExpectException(MISSING_BOOL_FILE_NAME);
}
- private void hrToOdExpectException(String fileName) {
- TestUtils.hrToOdExpectException(
- new SystemAppSafetyLabelFactory(), SYSTEM_APP_SAFETY_LABEL_HR_PATH, fileName);
+ private void hrToOdExpectException(String fileName)
+ throws ParserConfigurationException, IOException, SAXException {
+ var ele =
+ TestUtils.getElementFromResource(
+ Paths.get(SYSTEM_APP_SAFETY_LABEL_HR_PATH, fileName));
+ assertThrows(
+ MalformedXmlException.class,
+ () -> new SystemAppSafetyLabelFactory().createFromHrElement(ele, DEFAULT_VERSION));
}
- private void odToHrExpectException(String fileName) {
- TestUtils.odToHrExpectException(
- new SystemAppSafetyLabelFactory(), SYSTEM_APP_SAFETY_LABEL_OD_PATH, fileName);
+ private void odToHrExpectException(String fileName)
+ throws ParserConfigurationException, IOException, SAXException {
+ var ele =
+ TestUtils.getElementFromResource(
+ Paths.get(SYSTEM_APP_SAFETY_LABEL_OD_PATH, fileName));
+ assertThrows(
+ MalformedXmlException.class,
+ () -> new SystemAppSafetyLabelFactory().createFromOdElement(ele, DEFAULT_VERSION));
}
private void testHrToOdSystemAppSafetyLabel(String fileName) throws Exception {
- TestUtils.testHrToOd(
- TestUtils.document(),
- new SystemAppSafetyLabelFactory(),
- SYSTEM_APP_SAFETY_LABEL_HR_PATH,
- SYSTEM_APP_SAFETY_LABEL_OD_PATH,
- fileName);
+ var doc = TestUtils.document();
+ SystemAppSafetyLabel systemAppSafetyLabel =
+ new SystemAppSafetyLabelFactory()
+ .createFromHrElement(
+ TestUtils.getElementFromResource(
+ Paths.get(SYSTEM_APP_SAFETY_LABEL_HR_PATH, fileName)),
+ DEFAULT_VERSION);
+ Element resultingEle = systemAppSafetyLabel.toOdDomElement(doc);
+ doc.appendChild(resultingEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(SYSTEM_APP_SAFETY_LABEL_OD_PATH, fileName));
}
private void testOdToHrSystemAppSafetyLabel(String fileName) throws Exception {
- TestUtils.testOdToHr(
- TestUtils.document(),
- new SystemAppSafetyLabelFactory(),
- SYSTEM_APP_SAFETY_LABEL_OD_PATH,
- SYSTEM_APP_SAFETY_LABEL_HR_PATH,
- fileName);
+ var doc = TestUtils.document();
+ SystemAppSafetyLabel systemAppSafetyLabel =
+ new SystemAppSafetyLabelFactory()
+ .createFromOdElement(
+ TestUtils.getElementFromResource(
+ Paths.get(SYSTEM_APP_SAFETY_LABEL_OD_PATH, fileName)),
+ DEFAULT_VERSION);
+ Element resultingEle = systemAppSafetyLabel.toHrDomElement(doc);
+ doc.appendChild(resultingEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(SYSTEM_APP_SAFETY_LABEL_HR_PATH, fileName));
}
}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java
index 8a0b35eac7c8..6547fb952944 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java
@@ -22,9 +22,14 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.w3c.dom.Element;
+
+import java.nio.file.Paths;
@RunWith(JUnit4.class)
public class TransparencyInfoTest {
+ private static final long DEFAULT_VERSION = 2L;
+
private static final String TRANSPARENCY_INFO_HR_PATH =
"com/android/asllib/transparencyinfo/hr";
private static final String TRANSPARENCY_INFO_OD_PATH =
@@ -45,20 +50,28 @@ public class TransparencyInfoTest {
}
private void testHrToOdTransparencyInfo(String fileName) throws Exception {
- TestUtils.testHrToOd(
- TestUtils.document(),
- new TransparencyInfoFactory(),
- TRANSPARENCY_INFO_HR_PATH,
- TRANSPARENCY_INFO_OD_PATH,
- fileName);
+ var doc = TestUtils.document();
+ TransparencyInfo transparencyInfo =
+ new TransparencyInfoFactory()
+ .createFromHrElement(
+ TestUtils.getElementFromResource(
+ Paths.get(TRANSPARENCY_INFO_HR_PATH, fileName)),
+ DEFAULT_VERSION);
+ Element resultingEle = transparencyInfo.toOdDomElement(doc);
+ doc.appendChild(resultingEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(TRANSPARENCY_INFO_OD_PATH, fileName));
}
private void testOdToHrTransparencyInfo(String fileName) throws Exception {
- TestUtils.testOdToHr(
- TestUtils.document(),
- new TransparencyInfoFactory(),
- TRANSPARENCY_INFO_OD_PATH,
- TRANSPARENCY_INFO_HR_PATH,
- fileName);
+ var doc = TestUtils.document();
+ TransparencyInfo transparencyInfo =
+ new TransparencyInfoFactory()
+ .createFromOdElement(
+ TestUtils.getElementFromResource(
+ Paths.get(TRANSPARENCY_INFO_OD_PATH, fileName)),
+ DEFAULT_VERSION);
+ Element resultingEle = transparencyInfo.toHrDomElement(doc);
+ doc.appendChild(resultingEle);
+ TestUtils.testFormatToFormat(doc, Paths.get(TRANSPARENCY_INFO_HR_PATH, fileName));
}
}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java
index ea90993e0785..f8ef40a9c509 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java
@@ -17,11 +17,8 @@
package com.android.asllib.testutils;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThrows;
import com.android.asllib.marshallable.AslMarshallable;
-import com.android.asllib.marshallable.AslMarshallableFactory;
-import com.android.asllib.util.MalformedXmlException;
import com.android.asllib.util.XmlUtils;
import org.w3c.dom.Document;
@@ -36,7 +33,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.List;
import java.util.Optional;
@@ -60,7 +56,19 @@ public class TestUtils {
}
/** Gets List of Element from a path to an existing Resource. */
- public static List<Element> getElementsFromResource(Path filePath)
+ public static Element getElementFromResource(Path filePath)
+ throws ParserConfigurationException, IOException, SAXException {
+ String str = readStrFromResource(filePath);
+ InputStream stream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
+
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ Document document = factory.newDocumentBuilder().parse(stream);
+ return document.getDocumentElement();
+ }
+
+ /** Gets List of Element from a path to an existing Resource. */
+ public static List<Element> getChildElementsFromResource(Path filePath)
throws ParserConfigurationException, IOException, SAXException {
String str = readStrFromResource(filePath);
InputStream stream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
@@ -69,16 +77,13 @@ public class TestUtils {
factory.setNamespaceAware(true);
Document document = factory.newDocumentBuilder().parse(stream);
Element root = document.getDocumentElement();
- if (root.getTagName().equals(HOLDER_TAG_NAME)) {
- String tagName =
- XmlUtils.asElementList(root.getChildNodes()).stream()
- .findFirst()
- .get()
- .getTagName();
- return XmlUtils.getChildrenByTagName(root, tagName);
- } else {
- return List.of(root);
- }
+
+ String tagName =
+ XmlUtils.asElementList(root.getChildNodes()).stream()
+ .findFirst()
+ .get()
+ .getTagName();
+ return XmlUtils.getChildrenByTagName(root, tagName);
}
/** Reads a Document into a String. */
@@ -130,86 +135,13 @@ public class TestUtils {
return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
}
- /** Helper for testing human-readable to on-device conversion expecting exception */
- public static <T extends AslMarshallable> void hrToOdExpectException(
- AslMarshallableFactory<T> factory, String hrFolderPath, String fileName) {
- assertThrows(
- MalformedXmlException.class,
- () -> {
- factory.createFromHrElements(
- TestUtils.getElementsFromResource(Paths.get(hrFolderPath, fileName)));
- });
- }
-
- /** Helper for testing on-device to human-readable conversion expecting exception */
- public static <T extends AslMarshallable> void odToHrExpectException(
- AslMarshallableFactory<T> factory, String odFolderPath, String fileName) {
- assertThrows(
- MalformedXmlException.class,
- () -> {
- factory.createFromOdElements(
- TestUtils.getElementsFromResource(Paths.get(odFolderPath, fileName)));
- });
- }
-
- /** Helper for testing human-readable to on-device conversion */
- public static <T extends AslMarshallable> void testHrToOd(
- Document doc,
- AslMarshallableFactory<T> factory,
- String hrFolderPath,
- String odFolderPath,
- String fileName)
- throws Exception {
- testFormatToFormat(doc, factory, hrFolderPath, odFolderPath, fileName, true);
- }
-
- /** Helper for testing on-device to human-readable conversion */
- public static <T extends AslMarshallable> void testOdToHr(
- Document doc,
- AslMarshallableFactory<T> factory,
- String odFolderPath,
- String hrFolderPath,
- String fileName)
- throws Exception {
- testFormatToFormat(doc, factory, odFolderPath, hrFolderPath, fileName, false);
- }
-
/** Helper for testing format to format conversion */
- private static <T extends AslMarshallable> void testFormatToFormat(
- Document doc,
- AslMarshallableFactory<T> factory,
- String inFolderPath,
- String outFolderPath,
- String fileName,
- boolean hrToOd)
- throws Exception {
- AslMarshallable marshallable =
- hrToOd
- ? factory.createFromHrElements(
- TestUtils.getElementsFromResource(
- Paths.get(inFolderPath, fileName)))
- : factory.createFromOdElements(
- TestUtils.getElementsFromResource(
- Paths.get(inFolderPath, fileName)));
-
- List<Element> elements =
- hrToOd ? marshallable.toOdDomElements(doc) : marshallable.toHrDomElements(doc);
- if (elements.isEmpty()) {
- throw new IllegalStateException("elements was empty.");
- } else if (elements.size() == 1) {
- doc.appendChild(elements.get(0));
- } else {
- Element root = doc.createElement(TestUtils.HOLDER_TAG_NAME);
- for (var child : elements) {
- root.appendChild(child);
- }
- doc.appendChild(root);
- }
+ public static <T extends AslMarshallable> void testFormatToFormat(
+ Document doc, Path expectedOutPath) throws Exception {
String converted = TestUtils.getFormattedXml(TestUtils.docToStr(doc, true), true);
System.out.println("Converted: " + converted);
String expectedOutContents =
- TestUtils.getFormattedXml(
- TestUtils.readStrFromResource(Paths.get(outFolderPath, fileName)), true);
+ TestUtils.getFormattedXml(TestUtils.readStrFromResource(expectedOutPath), true);
System.out.println("Expected: " + expectedOutContents);
assertEquals(expectedOutContents, converted);
}
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml
index ec0cd702fd43..7478e39ce366 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml
@@ -1,3 +1,17 @@
<app-metadata-bundles>
-
+ <system-app-safety-label declaration="true">
+ </system-app-safety-label>
+ <transparency-info>
+ <app-info
+ apsCompliant="false"
+ privacyPolicy="www.example.com" developerId="dev1" applicationId="app1">
+ <first-party-endpoints>
+ <item>url1</item>
+ </first-party-endpoints>
+ <service-provider-endpoints>
+ <item>url55</item>
+ <item>url56</item>
+ </service-provider-endpoints>
+ </app-info>
+ </transparency-info>
</app-metadata-bundles> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml
index 19bfd826f770..587c49add47e 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml
@@ -1 +1,17 @@
-<app-metadata-bundles version="123456"></app-metadata-bundles> \ No newline at end of file
+<app-metadata-bundles version="2">
+ <system-app-safety-label declaration="true">
+ </system-app-safety-label>
+ <transparency-info>
+ <app-info
+ apsCompliant="false"
+ privacyPolicy="www.example.com" developerId="dev1" applicationId="app1">
+ <first-party-endpoints>
+ <item>url1</item>
+ </first-party-endpoints>
+ <service-provider-endpoints>
+ <item>url55</item>
+ <item>url56</item>
+ </service-provider-endpoints>
+ </app-info>
+ </transparency-info>
+</app-metadata-bundles> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml
index 03e71d28f4cc..9cfb8bc4d5da 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml
@@ -1,4 +1,19 @@
-<app-metadata-bundles version="123456">
+<app-metadata-bundles version="2">
<safety-labels>
</safety-labels>
+ <system-app-safety-label declaration="true">
+ </system-app-safety-label>
+ <transparency-info>
+ <app-info
+ apsCompliant="false"
+ privacyPolicy="www.example.com" developerId="dev1" applicationId="app1">
+ <first-party-endpoints>
+ <item>url1</item>
+ </first-party-endpoints>
+ <service-provider-endpoints>
+ <item>url55</item>
+ <item>url56</item>
+ </service-provider-endpoints>
+ </app-info>
+ </transparency-info>
</app-metadata-bundles> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-system-app-safety-label.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-system-app-safety-label.xml
deleted file mode 100644
index afb048632bc6..000000000000
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-system-app-safety-label.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<app-metadata-bundles version="123456">
-<system-app-safety-label declaration="true">
-</system-app-safety-label>
-</app-metadata-bundles> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml
deleted file mode 100644
index a00ef6565cf4..000000000000
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<app-metadata-bundles version="123456">
- <transparency-info>
- <app-info
- apsCompliant="false"
- privacyPolicy="www.example.com">
- <first-party-endpoints>
- <item>url1</item>
- </first-party-endpoints>
- <service-provider-endpoints>
- <item>url55</item>
- <item>url56</item>
- </service-provider-endpoints>
- </app-info>
- </transparency-info>
-</app-metadata-bundles> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/missing-version.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/missing-version.xml
index 1aa3aa94ca6d..9adfa98f05a3 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/missing-version.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/missing-version.xml
@@ -1,2 +1,20 @@
<bundle>
+ <pbundle_as_map name="system_app_safety_label">
+ <boolean name="declaration" value="true"/>
+ </pbundle_as_map>
+ <pbundle_as_map name="transparency_info">
+ <pbundle_as_map name="app_info">
+ <boolean name="aps_compliant" value="false"/>
+ <string name="privacy_policy" value="www.example.com"/>
+ <string-array name="first_party_endpoints" num="1">
+ <item value="url1"/>
+ </string-array>
+ <string-array name="service_provider_endpoints" num="2">
+ <item value="url55"/>
+ <item value="url56"/>
+ </string-array>
+ <string name="developer_id" value="dev1"/>
+ <string name="application_id" value="app1"/>
+ </pbundle_as_map>
+ </pbundle_as_map>
</bundle> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml
index 37bdfad4065f..7a4c82a9e65f 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml
@@ -1,3 +1,21 @@
<bundle>
- <long name="version" value="123456"/>
+ <long name="version" value="2"/>
+ <pbundle_as_map name="system_app_safety_label">
+ <boolean name="declaration" value="true"/>
+ </pbundle_as_map>
+ <pbundle_as_map name="transparency_info">
+ <pbundle_as_map name="app_info">
+ <string name="privacy_policy" value="www.example.com"/>
+ <string-array name="first_party_endpoints" num="1">
+ <item value="url1"/>
+ </string-array>
+ <string-array name="service_provider_endpoints" num="2">
+ <item value="url55"/>
+ <item value="url56"/>
+ </string-array>
+ <boolean name="aps_compliant" value="false"/>
+ <string name="developer_id" value="dev1"/>
+ <string name="application_id" value="app1"/>
+ </pbundle_as_map>
+ </pbundle_as_map>
</bundle> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml
index f00fb26bf1ee..3a3e5d383ca9 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml
@@ -1,5 +1,22 @@
<bundle>
- <long name="version" value="123456"/>
- <pbundle_as_map name="safety_labels">
+ <long name="version" value="2"/>
+ <pbundle_as_map name="safety_labels"/>
+ <pbundle_as_map name="system_app_safety_label">
+ <boolean name="declaration" value="true"/>
</pbundle_as_map>
-</bundle>
+ <pbundle_as_map name="transparency_info">
+ <pbundle_as_map name="app_info">
+ <string name="privacy_policy" value="www.example.com"/>
+ <string-array name="first_party_endpoints" num="1">
+ <item value="url1"/>
+ </string-array>
+ <string-array name="service_provider_endpoints" num="2">
+ <item value="url55"/>
+ <item value="url56"/>
+ </string-array>
+ <boolean name="aps_compliant" value="false"/>
+ <string name="developer_id" value="dev1"/>
+ <string name="application_id" value="app1"/>
+ </pbundle_as_map>
+ </pbundle_as_map>
+</bundle> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-system-app-safety-label.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-system-app-safety-label.xml
deleted file mode 100644
index e8640c4f0934..000000000000
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-system-app-safety-label.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<bundle>
- <long name="version" value="123456"/>
- <pbundle_as_map name="system_app_safety_label">
- <boolean name="declaration" value="true"/>
- </pbundle_as_map>
-</bundle> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml
deleted file mode 100644
index d0c8668564bd..000000000000
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<bundle>
- <long name="version" value="123456"/>
- <pbundle_as_map name="transparency_info">
- <pbundle_as_map name="app_info">
- <boolean name="aps_compliant" value="false"/>
- <string name="privacy_policy" value="www.example.com"/>
- <string-array name="first_party_endpoints" num="1">
- <item value="url1"/>
- </string-array>
- <string-array name="service_provider_endpoints" num="2">
- <item value="url55"/>
- <item value="url56"/>
- </string-array>
- </pbundle_as_map>
- </pbundle_as_map>
-</bundle> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml
index 0d15efc4eac3..306e01533731 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml
@@ -1,6 +1,6 @@
<app-info
apsCompliant="false"
- privacyPolicy="www.example.com">
+ privacyPolicy="www.example.com" developerId="dev1" applicationId="app1">
<first-party-endpoints>
<item>url1</item>
</first-party-endpoints>
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid-v1.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid-v1.xml
new file mode 100644
index 000000000000..b026cf33e5f0
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid-v1.xml
@@ -0,0 +1,24 @@
+<pbundle_as_map name="app_info">
+ <string name="title" value="beervision"/>
+ <string name="description" value="a beer app"/>
+ <boolean name="contains_ads" value="true"/>
+ <boolean name="obey_aps" value="false"/>
+ <boolean name="ads_fingerprinting" value="false"/>
+ <boolean name="security_fingerprinting" value="false"/>
+ <string name="privacy_policy" value="www.example.com"/>
+ <string-array name="security_endpoints" num="3">
+ <item value="url1"/>
+ <item value="url2"/>
+ <item value="url3"/>
+ </string-array>
+ <string-array name="first_party_endpoints" num="1">
+ <item value="url1"/>
+ </string-array>
+ <string-array name="service_provider_endpoints" num="2">
+ <item value="url55"/>
+ <item value="url56"/>
+ </string-array>
+ <string name="category" value="Food and drink"/>
+ <string name="email" value="max@maxloh.com"/>
+ <string name="website" value="www.example.com"/>
+</pbundle_as_map>
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml
index bce51799c7ff..7aae4a715b79 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml
@@ -1,6 +1,5 @@
<pbundle_as_map name="app_info">
- <boolean name="aps_compliant" value="false"/>
<string name="privacy_policy" value="www.example.com"/>
<string-array name="first_party_endpoints" num="1">
<item value="url1"/>
@@ -9,4 +8,7 @@
<item value="url55"/>
<item value="url56"/>
</string-array>
+ <boolean name="aps_compliant" value="false"/>
+ <string name="developer_id" value="dev1"/>
+ <string name="application_id" value="app1"/>
</pbundle_as_map> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/unrecognized-v1.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/unrecognized-v1.xml
new file mode 100644
index 000000000000..810078e777fb
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/unrecognized-v1.xml
@@ -0,0 +1,25 @@
+<pbundle_as_map name="app_info">
+ <string name="title" value="beervision"/>
+ <string name="description" value="a beer app"/>
+ <boolean name="contains_ads" value="true"/>
+ <boolean name="obey_aps" value="false"/>
+ <boolean name="ads_fingerprinting" value="false"/>
+ <boolean name="security_fingerprinting" value="false"/>
+ <string name="privacy_policy" value="www.example.com"/>
+ <string-array name="security_endpoints" num="3">
+ <item value="url1"/>
+ <item value="url2"/>
+ <item value="url3"/>
+ </string-array>
+ <string-array name="first_party_endpoints" num="1">
+ <item value="url1"/>
+ </string-array>
+ <string-array name="service_provider_endpoints" num="2">
+ <item value="url55"/>
+ <item value="url56"/>
+ </string-array>
+ <string name="category" value="Food and drink"/>
+ <string name="email" value="max@maxloh.com"/>
+ <string name="website" value="www.example.com"/>
+ <string name="unrecognized" value="www.example.com"/>
+</pbundle_as_map>
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml
index 2512ca415d55..2c5cf866547a 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml
@@ -2,7 +2,7 @@
<transparency-info>
<app-info
apsCompliant="false"
- privacyPolicy="www.example.com">
+ privacyPolicy="www.example.com" developerId="dev1" applicationId="app1">
<first-party-endpoints>
<item>url1</item>
</first-party-endpoints>
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml
index d16caaea320f..29c88d23abad 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml
@@ -1,5 +1,16 @@
<transparency-info>
+ <app-info
+ apsCompliant="false"
+ privacyPolicy="www.example.com" developerId="dev1" applicationId="app1">
+ <first-party-endpoints>
+ <item>url1</item>
+ </first-party-endpoints>
+ <service-provider-endpoints>
+ <item>url55</item>
+ <item>url56</item>
+ </service-provider-endpoints>
+ </app-info>
<developer-info
name="max"
email="max@example.com"
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml
index c7bdd97a356c..c46cec1da336 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml
@@ -1,7 +1,6 @@
<pbundle_as_map name="transparency_info">
<pbundle_as_map name="app_info">
- <boolean name="aps_compliant" value="false"/>
<string name="privacy_policy" value="www.example.com"/>
<string-array name="first_party_endpoints" num="1">
<item value="url1"/>
@@ -10,5 +9,8 @@
<item value="url55"/>
<item value="url56"/>
</string-array>
+ <boolean name="aps_compliant" value="false"/>
+ <string name="developer_id" value="dev1"/>
+ <string name="application_id" value="app1"/>
</pbundle_as_map>
</pbundle_as_map> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml
index d7a4e1a959b7..b5e64b925ca5 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml
@@ -1,5 +1,18 @@
<pbundle_as_map name="transparency_info">
+ <pbundle_as_map name="app_info">
+ <string name="privacy_policy" value="www.example.com"/>
+ <string-array name="first_party_endpoints" num="1">
+ <item value="url1"/>
+ </string-array>
+ <string-array name="service_provider_endpoints" num="2">
+ <item value="url55"/>
+ <item value="url56"/>
+ </string-array>
+ <boolean name="aps_compliant" value="false"/>
+ <string name="developer_id" value="dev1"/>
+ <string name="application_id" value="app1"/>
+ </pbundle_as_map>
<pbundle_as_map name="developer_info">
<string name="name" value="max"/>
<string name="email" value="max@example.com"/>
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general-v1/od.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general-v1/od.xml
new file mode 100644
index 000000000000..e8b0c17ecada
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general-v1/od.xml
@@ -0,0 +1,70 @@
+<bundle>
+ <long name="version" value="1"/>
+ <pbundle_as_map name="safety_labels">
+ <pbundle_as_map name="data_labels">
+ <pbundle_as_map name="data_shared">
+ <pbundle_as_map name="location">
+ <pbundle_as_map name="approx_location">
+ <int-array name="purposes" num="1">
+ <item value="1"/>
+ </int-array>
+ <boolean name="is_sharing_optional" value="false"/>
+ <boolean name="ephemeral" value="false"/>
+ </pbundle_as_map>
+ <pbundle_as_map name="precise_location">
+ <int-array name="purposes" num="2">
+ <item value="1"/>
+ <item value="2"/>
+ </int-array>
+ <boolean name="is_sharing_optional" value="true"/>
+ <boolean name="ephemeral" value="true"/>
+ </pbundle_as_map>
+ </pbundle_as_map>
+ </pbundle_as_map>
+ </pbundle_as_map>
+ <pbundle_as_map name="security_labels">
+ <boolean name="is_data_deletable" value="true"/>
+ <boolean name="is_data_encrypted" value="false"/>
+ </pbundle_as_map>
+ <pbundle_as_map name="third_party_verification">
+ <string name="url" value="www.example.com"/>
+ </pbundle_as_map>
+ </pbundle_as_map>
+ <pbundle_as_map name="system_app_safety_label">
+ <string name="url" value="www.example.com"/>
+ </pbundle_as_map>
+ <pbundle_as_map name="transparency_info">
+ <pbundle_as_map name="developer_info">
+ <string name="name" value="max"/>
+ <string name="email" value="max@example.com"/>
+ <string name="address" value="111 blah lane"/>
+ <string name="country_region" value="US"/>
+ <long name="relationship" value="5"/>
+ <string name="website" value="example.com"/>
+ <string name="app_developer_registry_id" value="registry_id"/>
+ </pbundle_as_map>
+ <pbundle_as_map name="app_info">
+ <string name="title" value="beervision"/>
+ <string name="description" value="a beer app"/>
+ <boolean name="contains_ads" value="true"/>
+ <boolean name="obey_aps" value="false"/>
+ <boolean name="ads_fingerprinting" value="false"/>
+ <boolean name="security_fingerprinting" value="false"/>
+ <string name="privacy_policy" value="www.example.com"/>
+ <string-array name="security_endpoints" num="3">
+ <item value="url1"/>
+ <item value="url2"/>
+ <item value="url3"/>
+ </string-array>
+ <string-array name="first_party_endpoints" num="1">
+ <item value="url1"/>
+ </string-array>
+ <string-array name="service_provider_endpoints" num="2">
+ <item value="url55"/>
+ <item value="url56"/>
+ </string-array>
+ <string name="category" value="Food and drink"/>
+ <string name="email" value="max@maxloh.com"/>
+ </pbundle_as_map>
+ </pbundle_as_map>
+</bundle> \ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml
index 592307937896..f93298286944 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml
@@ -1,20 +1,13 @@
-<app-metadata-bundles version="123">
+<app-metadata-bundles version="2">
<safety-labels>
<data-labels>
- <data-shared
- dataType="location_data_type_approx_location"
- isSharingOptional="false"
- purposes="app_functionality" />
- <data-shared
- dataType="location_data_type_precise_location"
- isSharingOptional="true"
- purposes="app_functionality|analytics" />
+ <data-shared dataType="location_data_type_approx_location" isSharingOptional="false" purposes="app_functionality"/>
+ <data-shared dataType="location_data_type_precise_location" isSharingOptional="true" purposes="app_functionality|analytics"/>
</data-labels>
</safety-labels>
- <system-app-safety-label declaration="true">
- </system-app-safety-label>
+ <system-app-safety-label declaration="true"/>
<transparency-info>
- <app-info apsCompliant="false" privacyPolicy="www.example.com">
+ <app-info applicationId="app1" apsCompliant="false" developerId="dev1" privacyPolicy="www.example.com">
<first-party-endpoints>
<item>url1</item>
</first-party-endpoints>
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml
index c24087e483b6..c7def7227a34 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml
@@ -1,5 +1,5 @@
<bundle>
- <long name="version" value="123"/>
+ <long name="version" value="2"/>
<pbundle_as_map name="safety_labels">
<pbundle_as_map name="data_labels">
<pbundle_as_map name="data_shared">
@@ -26,7 +26,6 @@
</pbundle_as_map>
<pbundle_as_map name="transparency_info">
<pbundle_as_map name="app_info">
- <boolean name="aps_compliant" value="false"/>
<string name="privacy_policy" value="www.example.com"/>
<string-array name="first_party_endpoints" num="1">
<item value="url1"/>
@@ -35,6 +34,9 @@
<item value="url55"/>
<item value="url56"/>
</string-array>
+ <boolean name="aps_compliant" value="false"/>
+ <string name="developer_id" value="dev1"/>
+ <string name="application_id" value="app1"/>
</pbundle_as_map>
</pbundle_as_map>
</bundle> \ No newline at end of file
diff --git a/tools/lint/fix/README.md b/tools/lint/fix/README.md
index a5ac2be1c18a..18bda9287a50 100644
--- a/tools/lint/fix/README.md
+++ b/tools/lint/fix/README.md
@@ -6,7 +6,7 @@ Inspiration: go/refactor-the-platform-with-lint\
It's a python script that runs the framework linter,
and then (optionally) copies modified files back into the source tree.\
-Why python, you ask? Because python is cool ¯\_(ツ)_/¯.
+Why python, you ask? Because python is cool ¯\\\_(ツ)\_/¯.
Incidentally, this exposes a much simpler way to run individual lint checks
against individual modules, so it's useful beyond applying fixes.
@@ -15,7 +15,7 @@ against individual modules, so it's useful beyond applying fixes.
Lint is not allowed to modify source files directly via lint's `--apply-suggestions` flag.
As a compromise, soong zips up the (potentially) modified sources and leaves them in an intermediate
-directory. This script runs the lint, unpacks those files, and copies them back into the tree.
+directory. This script runs the lint, unpacks those files, and copies them back into the tree.
## How do I run it?
**WARNING: You probably want to commit/stash any changes to your working tree before doing this...**
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
index 1087ae6ee41d..3c99e68cd6a0 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
@@ -120,6 +120,8 @@ class ProtoLogCallProcessorImpl(
logCallVisitor?.processCall(call, messageString, getLevelForMethodName(
call.name.toString(), call, context), groupMap.getValue(groupName))
+ } else if (call.name.id == "initialize") {
+ // No processing
} else {
// Process non-log message calls
otherCallVisitor?.processCall(call)
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 2d5b50b528a3..aa530050741b 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -443,10 +443,10 @@ object ProtoLogTool {
val command = CommandOptions(args)
invoke(command)
} catch (ex: InvalidCommandException) {
- println("\n${ex.message}\n")
+ println("InvalidCommandException: \n${ex.message}\n")
showHelpAndExit()
} catch (ex: CodeProcessingException) {
- println("\n${ex.message}\n")
+ println("CodeProcessingException: \n${ex.message}\n")
exitProcess(1)
}
}
diff --git a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
index 6a8a0717b2f1..c478f5844de6 100644
--- a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
@@ -130,28 +130,27 @@ class SourceTransformer(
val hash = CodeUtils.hash(packagePath, messageString, level, group)
val newCall = call.clone()
- if (!group.textEnabled) {
- // Remove message string if text logging is not enabled by default.
- // Out: ProtoLog.e(GROUP, null, arg)
- newCall.arguments[1].replace(NameExpr("null"))
- }
+ // Remove message string.
+ // Out: ProtoLog.e(GROUP, args)
+ newCall.arguments.removeAt(1)
// Insert message string hash as a second argument.
- // Out: ProtoLog.e(GROUP, 1234, null, arg)
+ // Out: ProtoLog.e(GROUP, 1234, args)
newCall.arguments.add(1, LongLiteralExpr("" + hash + "L"))
val argTypes = LogDataType.parseFormatString(messageString)
val typeMask = LogDataType.logDataTypesToBitMask(argTypes)
// Insert bitmap representing which Number parameters are to be considered as
// floating point numbers.
- // Out: ProtoLog.e(GROUP, 1234, 0, null, arg)
+ // Out: ProtoLog.e(GROUP, 1234, 0, args)
newCall.arguments.add(2, IntegerLiteralExpr(typeMask))
// Replace call to a stub method with an actual implementation.
- // Out: ProtoLogImpl.e(GROUP, 1234, null, arg)
+ // Out: ProtoLogImpl.e(GROUP, 1234, 0, args)
newCall.setScope(protoLogImplClassNode)
if (argTypes.size != call.arguments.size - 2) {
throw InvalidProtoLogCallException(
"Number of arguments (${argTypes.size} does not match format" +
" string in: $call", ParsingContext(path, call))
}
+ val argsOffset = 3
val blockStmt = BlockStmt()
if (argTypes.isNotEmpty()) {
// Assign every argument to a variable to check its type in compile time
@@ -160,9 +159,9 @@ class SourceTransformer(
argTypes.forEachIndexed { idx, type ->
val varName = "protoLogParam$idx"
val declaration = VariableDeclarator(getASTTypeForDataType(type), varName,
- getConversionForType(type)(newCall.arguments[idx + 4].clone()))
+ getConversionForType(type)(newCall.arguments[idx + argsOffset].clone()))
blockStmt.addStatement(ExpressionStmt(VariableDeclarationExpr(declaration)))
- newCall.setArgument(idx + 4, NameExpr(SimpleName(varName)))
+ newCall.setArgument(idx + argsOffset, NameExpr(SimpleName(varName)))
}
} else {
// Assign (Object[])null as the vararg parameter to prevent allocating an empty
diff --git a/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt b/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt
index 2a8367787ba1..0cbbd483fe59 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt
@@ -60,7 +60,7 @@ class EndToEndTest {
.containsMatch(Pattern.compile("\\{ String protoLogParam0 = " +
"String\\.valueOf\\(argString\\); long protoLogParam1 = argInt; " +
"com\\.android\\.internal\\.protolog.ProtoLogImpl_.*\\.d\\(" +
- "GROUP, -6872339441335321086L, 4, null, protoLogParam0, protoLogParam1" +
+ "GROUP, -6872339441335321086L, 4, protoLogParam0, protoLogParam1" +
"\\); \\}"))
}
diff --git a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
index 82aa93da613b..6cde7a72db53 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
@@ -76,7 +76,7 @@ class SourceTransformerTest {
class Test {
void test() {
- if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, protoLogParam0, protoLogParam1); }
}
}
""".trimIndent()
@@ -86,7 +86,7 @@ class SourceTransformerTest {
class Test {
void test() {
- if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, "test %d %f " + "abc %s\n test", protoLogParam0, protoLogParam1, protoLogParam2);
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, protoLogParam0, protoLogParam1, protoLogParam2);
}
}
@@ -98,8 +98,8 @@ class SourceTransformerTest {
class Test {
void test() {
- if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); } /* ProtoLog.w(TEST_GROUP, "test %d %f", 100, 0.1); */ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
- if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, protoLogParam0, protoLogParam1); } /* ProtoLog.w(TEST_GROUP, "test %d %f", 100, 0.1); */ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, protoLogParam0, protoLogParam1); }
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, protoLogParam0, protoLogParam1); }
}
}
""".trimIndent()
@@ -109,7 +109,7 @@ class SourceTransformerTest {
class Test {
void test() {
- if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { org.example.ProtoLogImpl.w(TEST_GROUP, 3218600869538902408L, 0, "test", (Object[]) null); }
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { org.example.ProtoLogImpl.w(TEST_GROUP, 3218600869538902408L, 0, (Object[]) null); }
}
}
""".trimIndent()
@@ -119,7 +119,7 @@ class SourceTransformerTest {
class Test {
void test() {
- if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, null, protoLogParam0, protoLogParam1); }
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, protoLogParam0, protoLogParam1); }
}
}
""".trimIndent()
@@ -129,7 +129,7 @@ class SourceTransformerTest {
class Test {
void test() {
- if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, null, protoLogParam0, protoLogParam1, protoLogParam2);
+ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, protoLogParam0, protoLogParam1, protoLogParam2);
}
}
@@ -172,13 +172,12 @@ class SourceTransformerTest {
Truth.assertThat(protoLogCalls).hasSize(1)
val methodCall = protoLogCalls[0] as MethodCallExpr
assertEquals("w", methodCall.name.asString())
- assertEquals(6, methodCall.arguments.size)
+ assertEquals(5, methodCall.arguments.size)
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
assertEquals("-1473209266730422156L", methodCall.arguments[1].toString())
assertEquals(0b1001.toString(), methodCall.arguments[2].toString())
- assertEquals("\"test %d %f\"", methodCall.arguments[3].toString())
- assertEquals("protoLogParam0", methodCall.arguments[4].toString())
- assertEquals("protoLogParam1", methodCall.arguments[5].toString())
+ assertEquals("protoLogParam0", methodCall.arguments[3].toString())
+ assertEquals("protoLogParam1", methodCall.arguments[4].toString())
assertEquals(TRANSFORMED_CODE_TEXT_ENABLED, out)
}
@@ -214,13 +213,12 @@ class SourceTransformerTest {
Truth.assertThat(protoLogCalls).hasSize(3)
val methodCall = protoLogCalls[0] as MethodCallExpr
assertEquals("w", methodCall.name.asString())
- assertEquals(6, methodCall.arguments.size)
+ assertEquals(5, methodCall.arguments.size)
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
assertEquals("-1473209266730422156L", methodCall.arguments[1].toString())
assertEquals(0b1001.toString(), methodCall.arguments[2].toString())
- assertEquals("\"test %d %f\"", methodCall.arguments[3].toString())
- assertEquals("protoLogParam0", methodCall.arguments[4].toString())
- assertEquals("protoLogParam1", methodCall.arguments[5].toString())
+ assertEquals("protoLogParam0", methodCall.arguments[3].toString())
+ assertEquals("protoLogParam1", methodCall.arguments[4].toString())
assertEquals(TRANSFORMED_CODE_MULTICALL_TEXT, out)
}
@@ -252,13 +250,13 @@ class SourceTransformerTest {
Truth.assertThat(protoLogCalls).hasSize(1)
val methodCall = protoLogCalls[0] as MethodCallExpr
assertEquals("w", methodCall.name.asString())
- assertEquals(7, methodCall.arguments.size)
+ assertEquals(6, methodCall.arguments.size)
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
assertEquals("-4447034859795564700L", methodCall.arguments[1].toString())
assertEquals(0b001001.toString(), methodCall.arguments[2].toString())
- assertEquals("protoLogParam0", methodCall.arguments[4].toString())
- assertEquals("protoLogParam1", methodCall.arguments[5].toString())
- assertEquals("protoLogParam2", methodCall.arguments[6].toString())
+ assertEquals("protoLogParam0", methodCall.arguments[3].toString())
+ assertEquals("protoLogParam1", methodCall.arguments[4].toString())
+ assertEquals("protoLogParam2", methodCall.arguments[5].toString())
assertEquals(TRANSFORMED_CODE_MULTILINE_TEXT_ENABLED, out)
}
@@ -289,7 +287,7 @@ class SourceTransformerTest {
Truth.assertThat(protoLogCalls).hasSize(1)
val methodCall = protoLogCalls[0] as MethodCallExpr
assertEquals("w", methodCall.name.asString())
- assertEquals(5, methodCall.arguments.size)
+ assertEquals(4, methodCall.arguments.size)
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
assertEquals("3218600869538902408L", methodCall.arguments[1].toString())
assertEquals(0.toString(), methodCall.arguments[2].toString())
@@ -323,13 +321,12 @@ class SourceTransformerTest {
Truth.assertThat(protoLogCalls).hasSize(1)
val methodCall = protoLogCalls[0] as MethodCallExpr
assertEquals("w", methodCall.name.asString())
- assertEquals(6, methodCall.arguments.size)
+ assertEquals(5, methodCall.arguments.size)
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
assertEquals("-1473209266730422156L", methodCall.arguments[1].toString())
assertEquals(0b1001.toString(), methodCall.arguments[2].toString())
- assertEquals("null", methodCall.arguments[3].toString())
- assertEquals("protoLogParam0", methodCall.arguments[4].toString())
- assertEquals("protoLogParam1", methodCall.arguments[5].toString())
+ assertEquals("protoLogParam0", methodCall.arguments[3].toString())
+ assertEquals("protoLogParam1", methodCall.arguments[4].toString())
assertEquals(TRANSFORMED_CODE_TEXT_DISABLED, out)
}
@@ -361,14 +358,13 @@ class SourceTransformerTest {
Truth.assertThat(protoLogCalls).hasSize(1)
val methodCall = protoLogCalls[0] as MethodCallExpr
assertEquals("w", methodCall.name.asString())
- assertEquals(7, methodCall.arguments.size)
+ assertEquals(6, methodCall.arguments.size)
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
assertEquals("-4447034859795564700L", methodCall.arguments[1].toString())
assertEquals(0b001001.toString(), methodCall.arguments[2].toString())
- assertEquals("null", methodCall.arguments[3].toString())
- assertEquals("protoLogParam0", methodCall.arguments[4].toString())
- assertEquals("protoLogParam1", methodCall.arguments[5].toString())
- assertEquals("protoLogParam2", methodCall.arguments[6].toString())
+ assertEquals("protoLogParam0", methodCall.arguments[3].toString())
+ assertEquals("protoLogParam1", methodCall.arguments[4].toString())
+ assertEquals("protoLogParam2", methodCall.arguments[5].toString())
assertEquals(TRANSFORMED_CODE_MULTILINE_TEXT_DISABLED, out)
}
}